aboutsummaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
Diffstat (limited to 'ld')
-rw-r--r--ld/ChangeLog7
-rw-r--r--ld/emultempl/aix.em102
2 files changed, 58 insertions, 51 deletions
diff --git a/ld/ChangeLog b/ld/ChangeLog
index 4f01c88..3f6c7fe 100644
--- a/ld/ChangeLog
+++ b/ld/ChangeLog
@@ -1,3 +1,10 @@
+2001-12-21 Tom Rix <trix@redhat.com>
+
+ (gld*_create_output_section_statements): New function.
+ For -binitfini support.
+ * emultempl/aix.em (gld*_before_parse): Fix comment.
+ * emultempl/aix.em (gld*_parse_args): Fix comment.
+
2001-12-20 Jason Thorpe <thorpej@wasabisystems.com>
* configure.tgt (mips*-dec-netbsd*): Delete alias for
diff --git a/ld/emultempl/aix.em b/ld/emultempl/aix.em
index 1bc643b..e5db1b9 100644
--- a/ld/emultempl/aix.em
+++ b/ld/emultempl/aix.em
@@ -67,6 +67,8 @@ static void gld${EMULATION_NAME}_find_exp_assignment PARAMS ((etree_type *));
static char *gld${EMULATION_NAME}_get_script PARAMS ((int *isfile));
static boolean gld${EMULATION_NAME}_unrecognized_file
PARAMS ((lang_input_statement_type *));
+static void gld${EMULATION_NAME}_create_output_section_statements
+ PARAMS((void));
static int is_syscall PARAMS ((char *, unsigned int *));
static int change_symbol_mode PARAMS ((char *));
@@ -126,6 +128,9 @@ static int is_64bit = 0;
/* Which syscalls from import file are valid */
static unsigned int syscall_mask = 0x77;
+/* fake file for -binitfini support */
+static lang_input_statement_type *initfini_file;
+
/* This routine is called before anything else is done. */
static void
@@ -144,11 +149,10 @@ gld${EMULATION_NAME}_before_parse ()
#endif /* not TARGET_ */
config.has_shared = true;
- /*
- * The link_info.[init|fini]_functions are initialized in ld/lexsup.c.
- * Override them here so we can use the link_info.init_function as a
- * state flag that lets the backend know that -binitfini has been done.
- */
+ /* The link_info.[init|fini]_functions are initialized in ld/lexsup.c.
+ Override them here so we can use the link_info.init_function as a
+ state flag that lets the backend know that -binitfini has been done. */
+
link_info.init_function = NULL;
link_info.fini_function = NULL;
@@ -192,51 +196,14 @@ gld${EMULATION_NAME}_parse_args (argc, argv)
OPTION_64,
};
- /*
- binitfini has special handling in the linker backend. The native linker
- uses the arguemnts to generate a table of init and fini functions for
- the executable. The important use for this option is to support aix 4.2+
- c++ constructors and destructors. This is tied into gcc via collect2.c.
- The function table is accessed by the runtime linker/loader by checking if
- the first symbol in the loader symbol table is "__rtinit". The native
- linker generates this table and the loader symbol. The gnu linker looks
- for the symbol "__rtinit" and makes it the first loader symbol. It is the
- responsiblity of the user to define the __rtinit symbol. The format for
- __rtinit is given by the aix system file /usr/include/rtinit.h. You can
- look at collect2.c to see an example of how this is done for 32 and 64 bit.
- Below is an exmaple of a 32 bit assembly file that defines __rtinit.
-
- .file "my_rtinit.s"
-
- .csect .data[RW],3
- .globl __rtinit
- .extern init_function
- .extern fini_function
-
- __rtinit:
- .long 0
- .long f1i - __rtinit
- .long f1f - __rtinit
- .long f2i - f1i
- .align 3
- f1i: .long init_function
- .long s1i - __rtinit
- .long 0
- f2i: .long 0
- .long 0
- .long 0
- f1f: .long fini_function
- .long s1f - __rtinit
- .long 0
- f2f: .long 0
- .long 0
- .long 0
- .align 3
- s1i: .string "init_function"
- .align 3
- s1f: .string "fini_function"
-
- */
+ /* -binitfini has special handling in the linker backend. The native linker
+ uses the arguemnts to generate a table of init and fini functions for
+ the executable. The important use for this option is to support aix 4.2+
+ c++ constructors and destructors. This is tied into gcc via collect2.c.
+
+ The function table is accessed by the runtime linker/loader by checking if
+ the first symbol in the loader symbol table is __rtinit. The gnu linker
+ generates this symbol and makes it the first loader symbol. */
static const struct option longopts[] = {
{"basis", no_argument, NULL, OPTION_IGNORE},
@@ -1319,6 +1286,39 @@ fi
cat >>e${EMULATION_NAME}.c <<EOF
+static void
+gld${EMULATION_NAME}_create_output_section_statements()
+{
+ /* __rtinit */
+ if ((bfd_get_flavour (output_bfd) == bfd_target_xcoff_flavour)
+ && (link_info.init_function != NULL || link_info.fini_function != NULL))
+ {
+
+ initfini_file = lang_add_input_file ("initfini",
+ lang_input_file_is_file_enum,
+ NULL);
+
+ initfini_file->the_bfd = bfd_create ("initfini", output_bfd);
+ if (initfini_file->the_bfd == NULL
+ || ! bfd_set_arch_mach (initfini_file->the_bfd,
+ bfd_get_arch (output_bfd),
+ bfd_get_mach (output_bfd)))
+ {
+ einfo ("%X%P: can not create BFD %E\n");
+ return;
+ }
+
+ /* Call backend to fill in the rest */
+ if (false == bfd_xcoff_link_generate_rtinit (initfini_file->the_bfd,
+ link_info.init_function,
+ link_info.fini_function))
+ {
+ einfo ("%X%P: can not create BFD %E\n");
+ return;
+ }
+ }
+}
+
struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = {
gld${EMULATION_NAME}_before_parse,
syslib_default,
@@ -1333,7 +1333,7 @@ struct ld_emulation_xfer_struct ld_${EMULATION_NAME}_emulation = {
"${EMULATION_NAME}",
"${OUTPUT_FORMAT}",
0, /* finish */
- 0, /* create_output_section_statements */
+ gld${EMULATION_NAME}_create_output_section_statements,
0, /* open_dynamic_archive */
0, /* place_orphan */
0, /* set_symbols */