From: Tom Rix Date: Tue, 19 Feb 2002 05:01:40 +0000 (+0000) Subject: Add support for -brtl, run time linking, to AIX ld. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=69f284c74ed40f90e9358f9df122d46194ed91b3;p=binutils-gdb.git Add support for -brtl, run time linking, to AIX ld. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index ff86ca3e69a..bc5c02e2b51 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,15 @@ +2002-02-18 Tom Rix + + * xcofflink.c (bfd_xcoff_link_gernate_rtinit): Add -brtl support. + (bfd_xcoff_size_dynamic_sections): Same. + * bfd-in.h (bfd_xcoff_link_generate_rtinit): Same. + (bfd_xcoff_size_dynamic_sections): Same. + * coff-rs6000.c (xcoff_generate_rtinit): Same. + * coff-rs646000.c (xcoff64_generate_rtinit): Same. + * libxcoff.h (struct xcoff_backend_data_rec): Same. + * xcofflink.c (xcoff_build_ldsyms, xcoff_link_add_symbols): Clean. + * bfd-in2.h: Regenerate. + 2002-02-18 Alan Modra * elf64-ppc.c (STFD_FR0_0R1, LFD_FR0_0R1, BLR): Define. diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h index bd8a915976b..5c21e1debdb 100644 --- a/bfd/bfd-in.h +++ b/bfd/bfd-in.h @@ -745,9 +745,9 @@ extern boolean bfd_xcoff_record_link_assignment extern boolean bfd_xcoff_size_dynamic_sections PARAMS ((bfd *, struct bfd_link_info *, const char *, const char *, unsigned long, unsigned long, unsigned long, boolean, - int, boolean, boolean, struct sec **)); + int, boolean, boolean, struct sec **, boolean)); extern boolean bfd_xcoff_link_generate_rtinit - PARAMS ((bfd *, const char *, const char *)); + PARAMS ((bfd *, const char *, const char *, boolean)); /* Externally visible COFF routines. */ diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index ff4ba0d5c8e..83677e9d492 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -751,9 +751,9 @@ extern boolean bfd_xcoff_record_link_assignment extern boolean bfd_xcoff_size_dynamic_sections PARAMS ((bfd *, struct bfd_link_info *, const char *, const char *, unsigned long, unsigned long, unsigned long, boolean, - int, boolean, boolean, struct sec **)); + int, boolean, boolean, struct sec **, boolean)); extern boolean bfd_xcoff_link_generate_rtinit - PARAMS ((bfd *, const char *, const char *)); + PARAMS ((bfd *, const char *, const char *, boolean)); /* Externally visible COFF routines. */ diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c index 27729291f90..75ed122c4fa 100644 --- a/bfd/coff-rs6000.c +++ b/bfd/coff-rs6000.c @@ -81,8 +81,9 @@ void _bfd_xcoff_rtype2howto PARAMS ((arelent *, struct internal_reloc *)); #define coff_bfd_is_local_label_name _bfd_xcoff_is_local_label_name #define coff_bfd_reloc_type_lookup _bfd_xcoff_reloc_type_lookup #ifdef AIX_CORE -extern const bfd_target * rs6000coff_core_p (); -extern boolean rs6000coff_core_file_matches_executable_p (); +extern const bfd_target * rs6000coff_core_p PARAMS ((bfd *abfd)); +extern boolean rs6000coff_core_file_matches_executable_p + PARAMS ((bfd *cbfd, bfd *ebfd)); extern char *rs6000coff_core_file_failing_command PARAMS ((bfd *abfd)); extern int rs6000coff_core_file_failing_signal PARAMS ((bfd *abfd)); #define CORE_FILE_P rs6000coff_core_p @@ -144,8 +145,7 @@ static bfd_vma xcoff_loader_symbol_offset static bfd_vma xcoff_loader_reloc_offset PARAMS ((bfd *, struct internal_ldhdr *)); static boolean xcoff_generate_rtinit - PARAMS((bfd *, const char *, const char *)); - + PARAMS((bfd *, const char *, const char *, boolean)); /* We use our own tdata type. Its first field is the COFF tdata type, so the COFF routines are compatible. */ @@ -3051,15 +3051,16 @@ xcoff_loader_reloc_offset (abfd, ldhdr) } static boolean -xcoff_generate_rtinit (abfd, init, fini) +xcoff_generate_rtinit (abfd, init, fini, rtld) bfd *abfd; const char *init; const char *fini; + boolean rtld; { bfd_byte filehdr_ext[FILHSZ]; bfd_byte scnhdr_ext[SCNHSZ]; - bfd_byte syment_ext[SYMESZ * 8]; - bfd_byte reloc_ext[RELSZ * 2]; + bfd_byte syment_ext[SYMESZ * 10]; + bfd_byte reloc_ext[RELSZ * 3]; bfd_byte *data_buffer; bfd_size_type data_buffer_size; bfd_byte *string_table = NULL, *st_tmp = NULL; @@ -3074,9 +3075,9 @@ xcoff_generate_rtinit (abfd, init, fini) char *data_name = ".data"; char *rtinit_name = "__rtinit"; + char *rtld_name = "__rtld"; - if (! bfd_xcoff_rtinit_size (abfd) - || (init == NULL && fini == NULL)) + if (! bfd_xcoff_rtinit_size (abfd)) return false; initsz = (init == NULL ? 0 : 1 + strlen (init)); @@ -3088,7 +3089,7 @@ xcoff_generate_rtinit (abfd, init, fini) filehdr.f_magic = bfd_xcoff_magic_number (abfd); filehdr.f_nscns = 1; filehdr.f_timdat = 0; - filehdr.f_nsyms = 0; /* at least 6, no more than 8 */ + filehdr.f_nsyms = 0; /* at least 6, no more than 10 */ filehdr.f_symptr = 0; /* set below */ filehdr.f_opthdr = 0; filehdr.f_flags = 0; @@ -3179,9 +3180,10 @@ xcoff_generate_rtinit (abfd, init, fini) 0. .data csect 2. __rtinit 4. init function - 6. fini function */ - memset (syment_ext, 0, 8 * SYMESZ); - memset (reloc_ext, 0, 2 * RELSZ); + 6. fini function + 8. __rtld */ + memset (syment_ext, 0, 10 * SYMESZ); + memset (reloc_ext, 0, 3 * RELSZ); /* .data csect */ memset (&syment, 0, sizeof (struct internal_syment)); @@ -3287,6 +3289,32 @@ xcoff_generate_rtinit (abfd, init, fini) scnhdr.s_nreloc += 1; } + if (rtld) + { + memset (&syment, 0, sizeof (struct internal_syment)); + memset (&auxent, 0, sizeof (union internal_auxent)); + memcpy (syment._n._n_name, rtld_name, strlen (rtld_name)); + syment.n_sclass = C_EXT; + syment.n_numaux = 1; + bfd_coff_swap_sym_out (abfd, &syment, + &syment_ext[filehdr.f_nsyms * SYMESZ]); + bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0, + syment.n_numaux, + &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]); + + /* reloc */ + memset (&reloc, 0, sizeof (struct internal_reloc)); + reloc.r_vaddr = 0x0000; + reloc.r_symndx = filehdr.f_nsyms; + reloc.r_type = R_POS; + reloc.r_size = 31; + bfd_coff_swap_reloc_out (abfd, &reloc, + &reloc_ext[scnhdr.s_nreloc * RELSZ]); + + filehdr.f_nsyms += 2; + scnhdr.s_nreloc += 1; + } + scnhdr.s_relptr = scnhdr.s_scnptr + data_buffer_size; filehdr.f_symptr = scnhdr.s_relptr + scnhdr.s_nreloc * RELSZ; @@ -3696,7 +3724,6 @@ static const struct xcoff_backend_data_rec bfd_pmac_xcoff_backend_data = /* rtinit */ 0, /* _xcoff_rtinit_size */ xcoff_generate_rtinit, /* _xcoff_generate_rtinit */ - }; /* The transfer vector that leads the outside world to all of the above. */ diff --git a/bfd/coff64-rs6000.c b/bfd/coff64-rs6000.c index d66a70e7159..288f6209220 100644 --- a/bfd/coff64-rs6000.c +++ b/bfd/coff64-rs6000.c @@ -144,8 +144,7 @@ static bfd_vma xcoff64_loader_symbol_offset static bfd_vma xcoff64_loader_reloc_offset PARAMS ((bfd *, struct internal_ldhdr *)); static boolean xcoff64_generate_rtinit - PARAMS((bfd *, const char *, const char *)); - + PARAMS((bfd *, const char *, const char *, boolean)); /* coffcode.h needs these to be defined */ /* Internalcoff.h and coffcode.h modify themselves based on these flags. */ @@ -171,8 +170,9 @@ static boolean xcoff64_generate_rtinit #define coff_bfd_is_local_label_name _bfd_xcoff_is_local_label_name #define coff_bfd_reloc_type_lookup xcoff64_reloc_type_lookup #ifdef AIX_CORE -extern const bfd_target * rs6000coff_core_p (); -extern boolean rs6000coff_core_file_matches_executable_p (); +extern const bfd_target * rs6000coff_core_p PARAMS ((bfd *abfd)); +extern boolean rs6000coff_core_file_matches_executable_p + PARAMS((bfd *cbfd, bfd *ebfd)); extern char *rs6000coff_core_file_failing_command PARAMS ((bfd *abfd)); extern int rs6000coff_core_file_failing_signal PARAMS ((bfd *abfd)); #define CORE_FILE_P rs6000coff_core_p @@ -2098,15 +2098,16 @@ xcoff64_loader_reloc_offset (abfd, ldhdr) } static boolean -xcoff64_generate_rtinit (abfd, init, fini) +xcoff64_generate_rtinit (abfd, init, fini, rtld) bfd *abfd; const char *init; const char *fini; + boolean rtld; { bfd_byte filehdr_ext[FILHSZ]; - bfd_byte scnhdr_ext[SCNHSZ]; - bfd_byte syment_ext[SYMESZ * 8]; - bfd_byte reloc_ext[RELSZ * 2]; + bfd_byte scnhdr_ext[SCNHSZ * 3]; + bfd_byte syment_ext[SYMESZ * 10]; + bfd_byte reloc_ext[RELSZ * 3]; bfd_byte *data_buffer; bfd_size_type data_buffer_size; bfd_byte *string_table, *st_tmp; @@ -2114,16 +2115,20 @@ xcoff64_generate_rtinit (abfd, init, fini) bfd_vma val; size_t initsz, finisz; struct internal_filehdr filehdr; - struct internal_scnhdr scnhdr; + struct internal_scnhdr text_scnhdr; + struct internal_scnhdr data_scnhdr; + struct internal_scnhdr bss_scnhdr; struct internal_syment syment; union internal_auxent auxent; struct internal_reloc reloc; + char *text_name = ".text"; char *data_name = ".data"; + char *bss_name = ".bss"; char *rtinit_name = "__rtinit"; + char *rtld_name = "__rtld"; - if (! bfd_xcoff_rtinit_size (abfd) - || (init == NULL && fini == NULL)) + if (! bfd_xcoff_rtinit_size (abfd)) return false; initsz = (init == NULL ? 0 : 1 + strlen (init)); @@ -2133,26 +2138,54 @@ xcoff64_generate_rtinit (abfd, init, fini) memset (filehdr_ext, 0, FILHSZ); memset (&filehdr, 0, sizeof (struct internal_filehdr)); filehdr.f_magic = bfd_xcoff_magic_number (abfd); - filehdr.f_nscns = 1; + filehdr.f_nscns = 3; filehdr.f_timdat = 0; filehdr.f_nsyms = 0; /* at least 6, no more than 8 */ filehdr.f_symptr = 0; /* set below */ filehdr.f_opthdr = 0; filehdr.f_flags = 0; - /* section header */ - memset (scnhdr_ext, 0, SCNHSZ); - memset (&scnhdr, 0, sizeof (struct internal_scnhdr)); - memcpy (scnhdr.s_name, data_name, strlen (data_name)); - scnhdr.s_paddr = 0; - scnhdr.s_vaddr = 0; - scnhdr.s_size = 0; /* set below */ - scnhdr.s_scnptr = FILHSZ + SCNHSZ; - scnhdr.s_relptr = 0; /* set below */ - scnhdr.s_lnnoptr = 0; - scnhdr.s_nreloc = 0; /* either 1 or 2 */ - scnhdr.s_nlnno = 0; - scnhdr.s_flags = STYP_DATA; + /* section headers */ + memset (scnhdr_ext, 0, 3 * SCNHSZ); + + /* text */ + memset (&text_scnhdr, 0, sizeof (struct internal_scnhdr)); + memcpy (text_scnhdr.s_name, text_name, strlen (text_name)); + text_scnhdr.s_paddr = 0; + text_scnhdr.s_vaddr = 0; + text_scnhdr.s_size = 0; + text_scnhdr.s_scnptr = 0; + text_scnhdr.s_relptr = 0; + text_scnhdr.s_lnnoptr = 0; + text_scnhdr.s_nreloc = 0; + text_scnhdr.s_nlnno = 0; + text_scnhdr.s_flags = STYP_TEXT; + + /* data */ + memset (&data_scnhdr, 0, sizeof (struct internal_scnhdr)); + memcpy (data_scnhdr.s_name, data_name, strlen (data_name)); + data_scnhdr.s_paddr = 0; + data_scnhdr.s_vaddr = 0; + data_scnhdr.s_size = 0; /* set below */ + data_scnhdr.s_scnptr = FILHSZ + 3 * SCNHSZ; + data_scnhdr.s_relptr = 0; /* set below */ + data_scnhdr.s_lnnoptr = 0; + data_scnhdr.s_nreloc = 0; /* either 1 or 2 */ + data_scnhdr.s_nlnno = 0; + data_scnhdr.s_flags = STYP_DATA; + + /* bss */ + memset (&bss_scnhdr, 0, sizeof (struct internal_scnhdr)); + memcpy (bss_scnhdr.s_name, bss_name, strlen (bss_name)); + bss_scnhdr.s_paddr = 0; /* set below */ + bss_scnhdr.s_vaddr = 0; /* set below */ + bss_scnhdr.s_size = 0; /* set below */ + bss_scnhdr.s_scnptr = 0; + bss_scnhdr.s_relptr = 0; + bss_scnhdr.s_lnnoptr = 0; + bss_scnhdr.s_nreloc = 0; + bss_scnhdr.s_nlnno = 0; + bss_scnhdr.s_flags = STYP_BSS; /* .data 0x0000 0x00000000 : rtl @@ -2209,7 +2242,8 @@ xcoff64_generate_rtinit (abfd, init, fini) val = 0x10; bfd_put_32 (abfd, val, &data_buffer[0x10]); - scnhdr.s_size = data_buffer_size; + data_scnhdr.s_size = data_buffer_size; + bss_scnhdr.s_paddr = bss_scnhdr.s_vaddr = data_scnhdr.s_size; /* string table */ string_table_size = 4; @@ -2217,6 +2251,8 @@ xcoff64_generate_rtinit (abfd, init, fini) string_table_size += strlen (rtinit_name) + 1; string_table_size += initsz; string_table_size += finisz; + if (true == rtld) + string_table_size += strlen (rtld_name) + 1; string_table = (bfd_byte *)bfd_malloc (string_table_size); memset (string_table, 0, string_table_size); @@ -2228,9 +2264,10 @@ xcoff64_generate_rtinit (abfd, init, fini) 0. .data csect 2. __rtinit 4. init function - 6. fini function */ - memset (syment_ext, 0, 8 * SYMESZ); - memset (reloc_ext, 0, 2 * RELSZ); + 6. fini function + 8. __rtld */ + memset (syment_ext, 0, 10 * SYMESZ); + memset (reloc_ext, 0, 3 * RELSZ); /* .data csect */ memset (&syment, 0, sizeof (struct internal_syment)); @@ -2240,7 +2277,7 @@ xcoff64_generate_rtinit (abfd, init, fini) memcpy (st_tmp, data_name, strlen (data_name)); st_tmp += strlen (data_name) + 1; - syment.n_scnum = 1; + syment.n_scnum = 2; syment.n_sclass = C_HIDEXT; syment.n_numaux = 1; auxent.x_csect.x_scnlen.l = data_buffer_size; @@ -2260,7 +2297,7 @@ xcoff64_generate_rtinit (abfd, init, fini) memcpy (st_tmp, rtinit_name, strlen (rtinit_name)); st_tmp += strlen (rtinit_name) + 1; - syment.n_scnum = 1; + syment.n_scnum = 2; syment.n_sclass = C_EXT; syment.n_numaux = 1; auxent.x_csect.x_smtyp = XTY_LD; @@ -2298,7 +2335,7 @@ xcoff64_generate_rtinit (abfd, init, fini) bfd_coff_swap_reloc_out (abfd, &reloc, &reloc_ext[0]); filehdr.f_nsyms += 2; - scnhdr.s_nreloc += 1; + data_scnhdr.s_nreloc += 1; } /* finit */ @@ -2326,21 +2363,55 @@ xcoff64_generate_rtinit (abfd, init, fini) reloc.r_type = R_POS; reloc.r_size = 63; bfd_coff_swap_reloc_out (abfd, &reloc, - &reloc_ext[scnhdr.s_nreloc * RELSZ]); + &reloc_ext[data_scnhdr.s_nreloc * RELSZ]); filehdr.f_nsyms += 2; - scnhdr.s_nreloc += 1; + data_scnhdr.s_nreloc += 1; } - scnhdr.s_relptr = scnhdr.s_scnptr + data_buffer_size; - filehdr.f_symptr = scnhdr.s_relptr + scnhdr.s_nreloc * RELSZ; + if (rtld) + { + memset (&syment, 0, sizeof (struct internal_syment)); + memset (&auxent, 0, sizeof (union internal_auxent)); + + syment._n._n_n._n_offset = st_tmp - string_table; + memcpy (st_tmp, rtld_name, strlen (rtld_name)); + st_tmp += strlen (rtld_name) + 1; + + syment.n_sclass = C_EXT; + syment.n_numaux = 1; + bfd_coff_swap_sym_out (abfd, &syment, + &syment_ext[filehdr.f_nsyms * SYMESZ]); + bfd_coff_swap_aux_out (abfd, &auxent, syment.n_type, syment.n_sclass, 0, + syment.n_numaux, + &syment_ext[(filehdr.f_nsyms + 1) * SYMESZ]); + + /* reloc */ + memset (&reloc, 0, sizeof (struct internal_reloc)); + reloc.r_vaddr = 0x0000; + reloc.r_symndx = filehdr.f_nsyms; + reloc.r_type = R_POS; + reloc.r_size = 63; + bfd_coff_swap_reloc_out (abfd, &reloc, + &reloc_ext[data_scnhdr.s_nreloc * RELSZ]); + + filehdr.f_nsyms += 2; + data_scnhdr.s_nreloc += 1; + + bss_scnhdr.s_size = 0; + } + + data_scnhdr.s_relptr = data_scnhdr.s_scnptr + data_buffer_size; + filehdr.f_symptr = data_scnhdr.s_relptr + data_scnhdr.s_nreloc * RELSZ; bfd_coff_swap_filehdr_out (abfd, &filehdr, filehdr_ext); bfd_bwrite (filehdr_ext, FILHSZ, abfd); - bfd_coff_swap_scnhdr_out (abfd, &scnhdr, scnhdr_ext); - bfd_bwrite (scnhdr_ext, SCNHSZ, abfd); + bfd_coff_swap_scnhdr_out (abfd, &text_scnhdr, &scnhdr_ext[SCNHSZ * 0]); + bfd_coff_swap_scnhdr_out (abfd, &data_scnhdr, &scnhdr_ext[SCNHSZ * 1]); + bfd_coff_swap_scnhdr_out (abfd, &bss_scnhdr, &scnhdr_ext[SCNHSZ * 2]); + bfd_bwrite (scnhdr_ext, 3 * SCNHSZ, abfd); bfd_bwrite (data_buffer, data_buffer_size, abfd); - bfd_bwrite (reloc_ext, scnhdr.s_nreloc * RELSZ, abfd); + bfd_bwrite (reloc_ext, data_scnhdr.s_nreloc * RELSZ, abfd); bfd_bwrite (syment_ext, filehdr.f_nsyms * SYMESZ, abfd); bfd_bwrite (string_table, string_table_size, abfd); @@ -2478,7 +2549,6 @@ static const struct xcoff_backend_data_rec bfd_xcoff_backend_data = /* rtinit */ 88, /* _xcoff_rtinit_size */ xcoff64_generate_rtinit, /* _xcoff_generate_rtinit */ - }; /* The transfer vector that leads the outside world to all of the above. */ diff --git a/bfd/libxcoff.h b/bfd/libxcoff.h index ee72370c4cb..20c3c4a0ce7 100644 --- a/bfd/libxcoff.h +++ b/bfd/libxcoff.h @@ -95,7 +95,8 @@ struct xcoff_backend_data_rec /* rtinit */ unsigned int _xcoff_rtinit_size; - boolean (*_xcoff_generate_rtinit)(bfd *, const char *, const char *); + boolean (*_xcoff_generate_rtinit)(bfd *, const char *, const char *, + boolean); }; /* Look up an entry in an XCOFF link hash table. */ @@ -192,6 +193,6 @@ struct xcoff_backend_data_rec #define bfd_xcoff_is_xcoff32(a) (0x01DF == (bfd_xcoff_magic_number(a))) #define bfd_xcoff_rtinit_size(a) ((xcoff_backend(a)->_xcoff_rtinit_size)) -#define bfd_xcoff_generate_rtinit(a, b, c) ((xcoff_backend(a)->_xcoff_generate_rtinit ((a), (b), (c)))) +#define bfd_xcoff_generate_rtinit(a, b, c, d) ((xcoff_backend(a)->_xcoff_generate_rtinit ((a), (b), (c), (d)))) #endif /* LIBXCOFF_H */ diff --git a/bfd/xcofflink.c b/bfd/xcofflink.c index 84b8e52ccae..5b1ddcca71b 100644 --- a/bfd/xcofflink.c +++ b/bfd/xcofflink.c @@ -1046,16 +1046,12 @@ xcoff_link_add_symbols (abfd, info) && ! info->static_link) { if (! xcoff_link_add_dynamic_symbols (abfd, info)) - { - return false; - } + return false; } /* create the loader, toc, gl, ds and debug sections, if needed */ if (false == xcoff_link_create_extra_sections(abfd, info)) - { - goto error_return; - } + goto error_return; if ((abfd->flags & DYNAMIC) != 0 && ! info->static_link) @@ -1146,7 +1142,6 @@ xcoff_link_add_symbols (abfd, info) } } - /* Don't let the linker relocation routines discard the symbols. */ obj_coff_keep_syms (abfd) = true; @@ -2806,7 +2801,7 @@ boolean bfd_xcoff_size_dynamic_sections (output_bfd, info, libpath, entry, file_align, maxstack, maxdata, gc, modtype, textro, export_defineds, - special_sections) + special_sections, rtld) bfd *output_bfd; struct bfd_link_info *info; const char *libpath; @@ -2819,6 +2814,7 @@ bfd_xcoff_size_dynamic_sections (output_bfd, info, libpath, entry, boolean textro; boolean export_defineds; asection **special_sections; + boolean rtld; { struct xcoff_link_hash_entry *hentry; asection *lsec; @@ -2837,7 +2833,6 @@ bfd_xcoff_size_dynamic_sections (output_bfd, info, libpath, entry, if (bfd_get_flavour (output_bfd) != bfd_target_xcoff_flavour) { - for (i = 0; i < XCOFF_NUMBER_OF_SPECIAL_SECTIONS; i++) special_sections[i] = NULL; return true; @@ -2859,11 +2854,8 @@ bfd_xcoff_size_dynamic_sections (output_bfd, info, libpath, entry, xcoff_hash_table (info)->file_align = file_align; xcoff_hash_table (info)->textro = textro; - if (entry == NULL) - { - hentry = NULL; - } - else + hentry = NULL; + if (entry != NULL) { hentry = xcoff_link_hash_lookup (xcoff_hash_table (info), entry, false, false, true); @@ -2872,65 +2864,56 @@ bfd_xcoff_size_dynamic_sections (output_bfd, info, libpath, entry, } /* __rtinit */ - if (info->init_function || info->fini_function) { - struct xcoff_link_hash_entry *hrtinit; - struct internal_ldsym *ldsym; - - hrtinit = xcoff_link_hash_lookup (xcoff_hash_table (info), - "__rtinit", - false, false, true); - if (hrtinit != NULL) - { - xcoff_mark_symbol (info, hrtinit); - hrtinit->flags |= (XCOFF_DEF_REGULAR | XCOFF_RTINIT); - } - else - { - (*_bfd_error_handler) - (_("error: undefined symbol __rtinit")); - - return false; - } - - /* __rtinit initalized here - Some information, like the location of the .initfini seciton will - be filled in later. - - name or offset taken care of below with bfd_xcoff_put_ldsymbol_name. */ - amt = sizeof (struct internal_ldsym); - ldsym = (struct internal_ldsym *) bfd_malloc (amt); - - ldsym->l_value = 0; /* will be filled in later */ - ldsym->l_scnum = 2; /* data section */ - ldsym->l_smtype = XTY_SD; /* csect section definition */ - ldsym->l_smclas = 5; /* .rw */ - ldsym->l_ifile = 0; /* special system loader symbol */ - ldsym->l_parm = 0; /* NA */ - - /* Force __rtinit to be the first symbol in the loader symbol table - See xcoff_build_ldsyms - - The first 3 symbol table indices are reserved to indicate the data, - text and bss sections. */ - BFD_ASSERT (0 == ldinfo.ldsym_count); - - hrtinit->ldindx = 3; - ldinfo.ldsym_count = 1; - hrtinit->ldsym = ldsym; - - if (false == bfd_xcoff_put_ldsymbol_name (ldinfo.output_bfd, &ldinfo, - hrtinit->ldsym, - hrtinit->root.root.string)) - { + if (info->init_function || info->fini_function || rtld == true) + { + struct xcoff_link_hash_entry *hsym; + struct internal_ldsym *ldsym; + + hsym = xcoff_link_hash_lookup (xcoff_hash_table (info), + "__rtinit", false, false, true); + if (hsym == NULL) + { + (*_bfd_error_handler) + (_("error: undefined symbol __rtinit")); + return false; + } + + xcoff_mark_symbol (info, hsym); + hsym->flags |= (XCOFF_DEF_REGULAR | XCOFF_RTINIT); + + /* __rtinit initalized */ + amt = sizeof (struct internal_ldsym); + ldsym = (struct internal_ldsym *) bfd_malloc (amt); + + ldsym->l_value = 0; /* will be filled in later */ + ldsym->l_scnum = 2; /* data section */ + ldsym->l_smtype = XTY_SD; /* csect section definition */ + ldsym->l_smclas = 5; /* .rw */ + ldsym->l_ifile = 0; /* special system loader symbol */ + ldsym->l_parm = 0; /* NA */ + + /* Force __rtinit to be the first symbol in the loader symbol table + See xcoff_build_ldsyms + + The first 3 symbol table indices are reserved to indicate the data, + text and bss sections. */ + BFD_ASSERT (0 == ldinfo.ldsym_count); + + hsym->ldindx = 3; + ldinfo.ldsym_count = 1; + hsym->ldsym = ldsym; + + if (false == bfd_xcoff_put_ldsymbol_name (ldinfo.output_bfd, &ldinfo, + hsym->ldsym, + hsym->root.root.string)) return false; - } - - /* This symbol is written out by xcoff_write_global_symbol - Set stuff up so xcoff_write_global_symbol logic works. */ - hrtinit->flags |= XCOFF_DEF_REGULAR | XCOFF_MARK; - hrtinit->root.type = bfd_link_hash_defined; - hrtinit->root.u.def.value = 0; - } + + /* This symbol is written out by xcoff_write_global_symbol + Set stuff up so xcoff_write_global_symbol logic works. */ + hsym->flags |= XCOFF_DEF_REGULAR | XCOFF_MARK; + hsym->root.type = bfd_link_hash_defined; + hsym->root.u.def.value = 0; + } /* Garbage collect unused sections. */ if (info->relocateable @@ -3220,10 +3203,11 @@ bfd_xcoff_size_dynamic_sections (output_bfd, info, libpath, entry, } boolean -bfd_xcoff_link_generate_rtinit (abfd, init, fini) +bfd_xcoff_link_generate_rtinit (abfd, init, fini, rtld) bfd *abfd; const char *init; const char *fini; + boolean rtld; { struct bfd_in_memory *bim; @@ -3242,7 +3226,7 @@ bfd_xcoff_link_generate_rtinit (abfd, init, fini) abfd->direction = write_direction; abfd->where = 0; - if (false == bfd_xcoff_generate_rtinit (abfd, init, fini)) + if (false == bfd_xcoff_generate_rtinit (abfd, init, fini, rtld)) return false; /* need to reset to unknown or it will not be read back in correctly */ @@ -3264,14 +3248,9 @@ xcoff_build_ldsyms (h, p) struct xcoff_loader_info *ldinfo = (struct xcoff_loader_info *) p; bfd_size_type amt; - /* __rtinit - Special handling of this symbol to make is the first symbol in - the loader symbol table. Make sure this pass through does not - undo it. */ + /* __rtinit, this symbol has special handling. */ if (h->flags & XCOFF_RTINIT) - { return true; - } /* If this is a final link, and the symbol was defined as a common symbol in a regular object file, and there was no definition in @@ -3386,17 +3365,11 @@ xcoff_build_ldsyms (h, p) xcoff32 uses 4 bytes in the toc. xcoff64 uses 8 bytes in the toc. */ if (bfd_xcoff_is_xcoff64 (ldinfo->output_bfd)) - { - byte_size = 8; - } + byte_size = 8; else if (bfd_xcoff_is_xcoff32 (ldinfo->output_bfd)) - { - byte_size = 4; - } + byte_size = 4; else - { - return false; - } + return false; hds->toc_section = xcoff_hash_table (ldinfo->info)->toc_section; hds->u.toc_offset = hds->toc_section->_raw_size; diff --git a/ld/ChangeLog b/ld/ChangeLog index 2d388c48f53..3d705b4348e 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,11 @@ +2002-02-18 Tom Rix + + * emultempl/aix.em (gld*_parse_args): Add -brtl support. + (gld*_before_allocation): Same. + (gld*_create_output_section_statements): Generate + __rtinit if run time linking. Add librtl.a to the link. + (gld*_read_file): Clean. + 2002-02-18 Alan Modra * emulparams/elf64ppc.sh (OTHER_TEXT_SECTIONS): Define. diff --git a/ld/emultempl/aix.em b/ld/emultempl/aix.em index e5db1b9c36b..2d7b69fe737 100644 --- a/ld/emultempl/aix.em +++ b/ld/emultempl/aix.em @@ -130,7 +130,10 @@ static unsigned int syscall_mask = 0x77; /* fake file for -binitfini support */ static lang_input_statement_type *initfini_file; - + +/* Whether to do run time linking */ +static boolean rtld; + /* This routine is called before anything else is done. */ static void @@ -155,7 +158,6 @@ gld${EMULATION_NAME}_before_parse () link_info.init_function = NULL; link_info.fini_function = NULL; - } /* Handle AIX specific options. */ @@ -241,6 +243,7 @@ gld${EMULATION_NAME}_parse_args (argc, argv) {"bpD", required_argument, NULL, OPTION_PD}, {"bpT", required_argument, NULL, OPTION_PT}, {"bro", no_argument, &textro, 1}, + {"brtl", no_argument, &rtld, 1}, {"bS", required_argument, NULL, OPTION_MAXSTACK}, {"bso", no_argument, NULL, OPTION_AUTOIMP}, {"bstrcmpct", no_argument, NULL, OPTION_STRCMPCT}, @@ -663,13 +666,10 @@ gld${EMULATION_NAME}_before_allocation () } /* Let the XCOFF backend set up the .loader section. */ - if (!bfd_xcoff_size_dynamic_sections (output_bfd, &link_info, libpath, - entry_symbol, file_align, - maxstack, maxdata, - gc && !unix_ld ? true : false, - modtype, - textro ? true : false, - unix_ld, special_sections)) + if (!bfd_xcoff_size_dynamic_sections + (output_bfd, &link_info, libpath, entry_symbol, file_align, + maxstack, maxdata, gc && !unix_ld ? true : false, + modtype, textro ? true : false, unix_ld, special_sections, rtld)) einfo ("%P%F: failed to set dynamic section sizes: %E\n"); /* Look through the special sections, and put them in the right @@ -943,12 +943,11 @@ gld${EMULATION_NAME}_read_file (filename, import) lineno = 0; - /* - * default to 32 and 64 bit mode - * symbols at top of /lib/syscalls.exp do not have a mode modifier and they - * are not repeated, assume 64 bit routines also want to use them. - * See the routine change_symbol_mode for more information. - */ + /* Default to 32 and 64 bit mode + symbols at top of /lib/syscalls.exp do not have a mode modifier and they + are not repeated, assume 64 bit routines also want to use them. + See the routine change_symbol_mode for more information. */ + symbol_mode = 0x04; while ((c = getc (f)) != EOF) @@ -1291,9 +1290,10 @@ 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)) + && (link_info.init_function != NULL + || link_info.fini_function != NULL + || rtld == true)) { - initfini_file = lang_add_input_file ("initfini", lang_input_file_is_file_enum, NULL); @@ -1311,11 +1311,16 @@ gld${EMULATION_NAME}_create_output_section_statements() /* 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)) + link_info.fini_function, + rtld)) { einfo ("%X%P: can not create BFD %E\n"); return; } + + /* __rtld defined in /lib/librtl.a */ + if (true == rtld) + lang_add_input_file ("rtl", lang_input_file_is_l_enum, NULL); } }