diff options
Diffstat (limited to 'bfd')
49 files changed, 4121 insertions, 4259 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 0a7755f..9cbc544 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,57 @@ 2004-03-27 Alan Modra <amodra@bigpond.net.au> + * Makefile.am: Remove all mention of elflink.h. + * Makefile.in: Regenerate. + * bfd-in.h (bfd_elf_discard_info): Declare. + (bfd_elf32_discard_info, bfd_elf64_discard_info): Delete. + * bfd-in2.h: Regenerate. + * elf-bfd.h (bfd_elf32_print_symbol, bfd_elf64_print_symbol, + bfd_elf32_link_record_dynamic_symbol, + bfd_elf64_link_record_dynamic_symbol, + _bfd_elf_link_record_dynamic_symbol, bfd_elf32_bfd_final_link, + bfd_elf64_bfd_final_link, elf_link_record_local_dynamic_symbol, + _bfd_elf32_link_record_local_dynamic_symbol, + _bfd_elf64_link_record_local_dynamic_symbol, + _bfd_elf32_gc_sections, _bfd_elf32_gc_common_finalize_got_offsets, + _bfd_elf32_gc_common_final_link, _bfd_elf64_gc_common_final_link, + _bfd_elf32_gc_record_vtinherit, _bfd_elf32_gc_record_vtentry, + _bfd_elf64_gc_sections, _bfd_elf64_gc_common_finalize_got_offsets, + _bfd_elf64_gc_record_vtinherit, _bfd_elf64_gc_record_vtentry, + _bfd_elf32_reloc_symbol_deleted_p, + _bfd_elf64_reloc_symbol_deleted_p): Delete. + (bfd_elf_link_record_dynamic_symbol, + bfd_elf_link_record_local_dynamic_symbol, + bfd_elf_final_link, bfd_elf_gc_sections, + bfd_elf_gc_record_vtinherit, bfd_elf_gc_record_vtentry, + bfd_elf_gc_common_finalize_got_offsets, bfd_elf_gc_common_final_link, + bfd_elf_reloc_symbol_deleted_p): Declare. + (WILL_CALL_FINISH_DYNAMIC_SYMBOL): Define. + * elf32-arm.h: Update for changed function names. Remove local + WILL_CALL_FINISH_DYNAMIC_SECTION define. + * elf-hppa.h, elf-m10300.c, elf32-cris.c, elf32-d10v.c, elf32-dlx.c, + * elf32-fr30.c, elf32-frv.c, elf32-h8300.c, elf32-hppa.c, elf32-i386.c, + * elf32-iq2000.c, elf32-m32r.c, elf32-m68hc1x.c, elf32-m68k.c, + * elf32-mcore.c, elf32-openrisc.c, elf32-ppc.c, elf32-s390.c, + * elf32-sh.c, elf32-sparc.c, elf32-v850.c, elf32-vax.c, + * elf32-xstormy16.c, elf32-xtensa.c, elf64-alpha.c, elf64-hppa.c, + * elf64-mmix.c, elf64-ppc.c, elf64-s390.c, elf64-sh64.c, elf64-sparc.c, + * elf64-x86-64.c, elfxx-ia64.c, elfxx-mips.c, elfxx-target.h: Likewise. + * elfxx-target.h (bfd_elfNN_bfd_final_link): Define. + (bfd_elfNN_print_symbol): Define. + * elfcode.h: Don't include elflink.h. + (elf_bfd_discard_info, elf_reloc_symbol_deleted_p, + elf_link_record_dynamic_symbol, elf_bfd_final_link, elf_gc_sections, + elf_gc_common_finalize_got_offsets, elf_gc_common_final_link, + elf_gc_record_vtinherit, elf_gc_record_vtentry, + elf_link_record_local_dynamic_symbol): Don't define. + * elflink.c: Update for changed function names. Move elflink.h + code here. + * elflink.h: Delete file. + * po/SRC-POTFILES.in: Regenerate. + * po/bfd.pot: Regenerate. + +2004-03-27 Alan Modra <amodra@bigpond.net.au> + * elf64-mmix.c (mmix_elf_relocate_section): Restore code setting "name" for global syms accidentally removed in 2004-03-20 change. @@ -109,7 +161,7 @@ * elflink.h (elf_link_add_object_symbols): Add DT_NEEDED for as-needed and chained shared libs only if dynsym. Clear dynsym on forced-local. - + * elf-bfd.h (_bfd_elf_add_dynamic_entry): Declare. (bfd_elf32_add_dynamic_entry, bfd_elf64_add_dynamic_entry): Delete. (_bfd_elf_add_dt_needed_tag): Declare. @@ -170,7 +222,7 @@ (elf_xtensa_size_dynamic_sections): Don't add DT_TEXTREL entry. (elf_xtensa_relocate_section): Read literal tables and check for dynamic relocations in read-only sections and not in literal pools. - + 2004-03-23 Alan Modra <amodra@bigpond.net.au> PR 51. diff --git a/bfd/Makefile.am b/bfd/Makefile.am index 315ede0..a0516a2 100644 --- a/bfd/Makefile.am +++ b/bfd/Makefile.am @@ -588,7 +588,7 @@ CFILES = $(SOURCE_CFILES) $(BUILD_CFILES) SOURCE_HFILES = \ aout-target.h aoutf1.h aoutx.h coffcode.h coffswap.h ecoffswap.h \ elf-bfd.h elf-hppa.h elf32-arm.h elf32-hppa.h \ - elf64-hppa.h elfcode.h elfcore.h elflink.h \ + elf64-hppa.h elfcode.h elfcore.h \ freebsd.h genlink.h go32stub.h \ libaout.h libbfd.h libcoff.h libecoff.h libhppa.h libieee.h \ libnlm.h liboasys.h libpei.h libxcoff.h mach-o.h \ @@ -1310,7 +1310,7 @@ elf32-xtensa.lo: elf32-xtensa.c $(INCDIR)/filenames.h \ elf32.lo: elf32.c elfcode.h $(INCDIR)/filenames.h $(INCDIR)/libiberty.h \ $(INCDIR)/bfdlink.h elf-bfd.h $(INCDIR)/elf/common.h \ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h elfcore.h \ - elflink.h $(INCDIR)/safe-ctype.h + $(INCDIR)/safe-ctype.h elflink.lo: elflink.c $(INCDIR)/filenames.h $(INCDIR)/bfdlink.h \ elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \ $(INCDIR)/elf/external.h @@ -1592,7 +1592,7 @@ elf64-sparc.lo: elf64-sparc.c $(INCDIR)/filenames.h \ elf64.lo: elf64.c elfcode.h $(INCDIR)/filenames.h $(INCDIR)/libiberty.h \ $(INCDIR)/bfdlink.h elf-bfd.h $(INCDIR)/elf/common.h \ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h elfcore.h \ - elflink.h $(INCDIR)/safe-ctype.h + $(INCDIR)/safe-ctype.h mmo.lo: mmo.c $(INCDIR)/filenames.h $(INCDIR)/libiberty.h \ $(INCDIR)/elf/mmix.h $(INCDIR)/elf/reloc-macros.h $(INCDIR)/opcode/mmix.h nlm32-alpha.lo: nlm32-alpha.c $(INCDIR)/filenames.h \ diff --git a/bfd/Makefile.in b/bfd/Makefile.in index 2aef7e4..51dc85a 100644 --- a/bfd/Makefile.in +++ b/bfd/Makefile.in @@ -725,7 +725,7 @@ CFILES = $(SOURCE_CFILES) $(BUILD_CFILES) SOURCE_HFILES = \ aout-target.h aoutf1.h aoutx.h coffcode.h coffswap.h ecoffswap.h \ elf-bfd.h elf-hppa.h elf32-arm.h elf32-hppa.h \ - elf64-hppa.h elfcode.h elfcore.h elflink.h \ + elf64-hppa.h elfcode.h elfcore.h \ freebsd.h genlink.h go32stub.h \ libaout.h libbfd.h libcoff.h libecoff.h libhppa.h libieee.h \ libnlm.h liboasys.h libpei.h libxcoff.h mach-o.h \ @@ -1847,7 +1847,7 @@ elf32-xtensa.lo: elf32-xtensa.c $(INCDIR)/filenames.h \ elf32.lo: elf32.c elfcode.h $(INCDIR)/filenames.h $(INCDIR)/libiberty.h \ $(INCDIR)/bfdlink.h elf-bfd.h $(INCDIR)/elf/common.h \ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h elfcore.h \ - elflink.h $(INCDIR)/safe-ctype.h + $(INCDIR)/safe-ctype.h elflink.lo: elflink.c $(INCDIR)/filenames.h $(INCDIR)/bfdlink.h \ elf-bfd.h $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h \ $(INCDIR)/elf/external.h @@ -2129,7 +2129,7 @@ elf64-sparc.lo: elf64-sparc.c $(INCDIR)/filenames.h \ elf64.lo: elf64.c elfcode.h $(INCDIR)/filenames.h $(INCDIR)/libiberty.h \ $(INCDIR)/bfdlink.h elf-bfd.h $(INCDIR)/elf/common.h \ $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h elfcore.h \ - elflink.h $(INCDIR)/safe-ctype.h + $(INCDIR)/safe-ctype.h mmo.lo: mmo.c $(INCDIR)/filenames.h $(INCDIR)/libiberty.h \ $(INCDIR)/elf/mmix.h $(INCDIR)/elf/reloc-macros.h $(INCDIR)/opcode/mmix.h nlm32-alpha.lo: nlm32-alpha.c $(INCDIR)/filenames.h \ diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h index ff585fd..1a5d1ea 100644 --- a/bfd/bfd-in.h +++ b/bfd/bfd-in.h @@ -622,9 +622,7 @@ extern void bfd_elf_set_dyn_lib_class (bfd *, int); extern struct bfd_link_needed_list *bfd_elf_get_runpath_list (bfd *, struct bfd_link_info *); -extern bfd_boolean bfd_elf32_discard_info - (bfd *, struct bfd_link_info *); -extern bfd_boolean bfd_elf64_discard_info +extern bfd_boolean bfd_elf_discard_info (bfd *, struct bfd_link_info *); /* Return an upper bound on the number of bytes required to store a diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 060dcc6..f774264 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -629,9 +629,7 @@ extern void bfd_elf_set_dyn_lib_class (bfd *, int); extern struct bfd_link_needed_list *bfd_elf_get_runpath_list (bfd *, struct bfd_link_info *); -extern bfd_boolean bfd_elf32_discard_info - (bfd *, struct bfd_link_info *); -extern bfd_boolean bfd_elf64_discard_info +extern bfd_boolean bfd_elf_discard_info (bfd *, struct bfd_link_info *); /* Return an upper bound on the number of bytes required to store a diff --git a/bfd/doc/ChangeLog b/bfd/doc/ChangeLog index c2ab8aa..cc57b2b 100644 --- a/bfd/doc/ChangeLog +++ b/bfd/doc/ChangeLog @@ -1,3 +1,7 @@ +2004-03-27 Alan Modra <amodra@bigpond.net.au> + + * bfdint.texi: Remove all mention of elflink.h. + 2004-03-19 Alan Modra <amodra@bigpond.net.au> * Makefile.in: Regenerate. diff --git a/bfd/doc/bfdint.texi b/bfd/doc/bfdint.texi index cd29ae8..95c0096 100644 --- a/bfd/doc/bfdint.texi +++ b/bfd/doc/bfdint.texi @@ -1073,11 +1073,6 @@ sizes. Like @file{elfcode.h}, but for functions that are specific to ELF core files. This is included only by @file{elfcode.h}. -@item elflink.h -@cindex @file{elflink.h} -Like @file{elfcode.h}, but for functions used by the ELF linker. This -is included only by @file{elfcode.h}. - @item elfxx-target.h @cindex @file{elfxx-target.h} This file is the source for the generated files @file{elf32-target.h} @@ -1482,8 +1477,7 @@ external data. @file{elfcode.h} is compiled twice, once via @file{elfcode.h} includes functions to swap the ELF structures in and out of external form, as well as a few more complex functions. -Linker support is found in @file{elflink.c} and @file{elflink.h}. The -latter file is compiled twice, for both 32 and 64 bit support. The +Linker support is found in @file{elflink.c}. The linker support is only used if the processor specific file defines @samp{elf_backend_relocate_section}, which is required to relocate the section contents. If that macro is not defined, the generic linker code diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 70f498d..110dd69 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1309,9 +1309,6 @@ extern void bfd_elf_print_symbol bfd_elf_string_from_elf_section (abfd, elf_elfheader(abfd)->e_shstrndx, \ strindex) -#define bfd_elf32_print_symbol bfd_elf_print_symbol -#define bfd_elf64_print_symbol bfd_elf_print_symbol - extern void _bfd_elf_sprintf_vma (bfd *, char *, bfd_vma); extern void _bfd_elf_fprintf_vma @@ -1493,8 +1490,6 @@ extern bfd_boolean _bfd_elf_link_find_version_dependencies extern bfd_boolean _bfd_elf_link_assign_sym_version (struct elf_link_hash_entry *, void *); -extern bfd_boolean _bfd_elf_link_record_dynamic_symbol - (struct bfd_link_info *, struct elf_link_hash_entry *); extern long _bfd_elf_link_lookup_local_dynindx (struct bfd_link_info *, bfd *, long); extern bfd_boolean _bfd_elf_compute_section_file_positions @@ -1556,9 +1551,6 @@ extern int bfd_elf32_core_file_failing_signal extern bfd_boolean bfd_elf32_core_file_matches_executable_p (bfd *, bfd *); -extern bfd_boolean bfd_elf32_bfd_final_link - (bfd *, struct bfd_link_info *); - extern void bfd_elf32_swap_symbol_in (bfd *, const void *, const void *, Elf_Internal_Sym *); extern void bfd_elf32_swap_symbol_out @@ -1600,8 +1592,6 @@ extern int bfd_elf64_core_file_failing_signal (bfd *); extern bfd_boolean bfd_elf64_core_file_matches_executable_p (bfd *, bfd *); -extern bfd_boolean bfd_elf64_bfd_final_link - (bfd *, struct bfd_link_info *); extern void bfd_elf64_swap_symbol_in (bfd *, const void *, const void *, Elf_Internal_Sym *); @@ -1639,17 +1629,11 @@ extern bfd_boolean bfd_elf_link_add_symbols extern bfd_boolean _bfd_elf_add_dynamic_entry (struct bfd_link_info *, bfd_vma, bfd_vma); -#define bfd_elf32_link_record_dynamic_symbol \ - _bfd_elf_link_record_dynamic_symbol -#define bfd_elf64_link_record_dynamic_symbol \ - _bfd_elf_link_record_dynamic_symbol +extern bfd_boolean bfd_elf_link_record_dynamic_symbol + (struct bfd_link_info *, struct elf_link_hash_entry *); -extern int elf_link_record_local_dynamic_symbol +extern int bfd_elf_link_record_local_dynamic_symbol (struct bfd_link_info *, bfd *, long); -#define _bfd_elf32_link_record_local_dynamic_symbol \ - elf_link_record_local_dynamic_symbol -#define _bfd_elf64_link_record_local_dynamic_symbol \ - elf_link_record_local_dynamic_symbol extern bfd_boolean _bfd_elf_close_and_cleanup (bfd *); @@ -1657,31 +1641,25 @@ extern bfd_reloc_status_type _bfd_elf_rel_vtable_reloc_fn (bfd *, arelent *, struct bfd_symbol *, void *, asection *, bfd *, char **); -extern bfd_boolean _bfd_elf32_gc_sections +extern bfd_boolean bfd_elf_final_link (bfd *, struct bfd_link_info *); -extern bfd_boolean _bfd_elf32_gc_common_finalize_got_offsets - (bfd *, struct bfd_link_info *); -extern bfd_boolean _bfd_elf32_gc_common_final_link + +extern bfd_boolean bfd_elf_gc_sections (bfd *, struct bfd_link_info *); -extern bfd_boolean _bfd_elf32_gc_record_vtinherit + +extern bfd_boolean bfd_elf_gc_record_vtinherit (bfd *, asection *, struct elf_link_hash_entry *, bfd_vma); -extern bfd_boolean _bfd_elf32_gc_record_vtentry + +extern bfd_boolean bfd_elf_gc_record_vtentry (bfd *, asection *, struct elf_link_hash_entry *, bfd_vma); -extern bfd_boolean _bfd_elf64_gc_sections +extern bfd_boolean bfd_elf_gc_common_finalize_got_offsets (bfd *, struct bfd_link_info *); -extern bfd_boolean _bfd_elf64_gc_common_finalize_got_offsets - (bfd *, struct bfd_link_info *); -extern bfd_boolean _bfd_elf64_gc_common_final_link + +extern bfd_boolean bfd_elf_gc_common_final_link (bfd *, struct bfd_link_info *); -extern bfd_boolean _bfd_elf64_gc_record_vtinherit - (bfd *, asection *, struct elf_link_hash_entry *, bfd_vma); -extern bfd_boolean _bfd_elf64_gc_record_vtentry - (bfd *, asection *, struct elf_link_hash_entry *, bfd_vma); -extern bfd_boolean _bfd_elf32_reloc_symbol_deleted_p - (bfd_vma, void *); -extern bfd_boolean _bfd_elf64_reloc_symbol_deleted_p +extern bfd_boolean bfd_elf_reloc_symbol_deleted_p (bfd_vma, void *); /* Exported interface for writing elf corefile notes. */ @@ -1712,6 +1690,16 @@ extern bfd *_bfd_elf64_bfd_from_remote_memory extern bfd_boolean _sh_elf_set_mach_from_flags (bfd *); +/* This is the condition under which finish_dynamic_symbol will be called. + If our finish_dynamic_symbol isn't called, we'll need to do something + about initializing any .plt and .got entries in relocate_section. */ +#define WILL_CALL_FINISH_DYNAMIC_SYMBOL(DYN, SHARED, H) \ + ((DYN) \ + && ((SHARED) \ + || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) \ + && ((H)->dynindx != -1 \ + || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)) + /* This macro is to avoid lots of duplicated code in the body of xxx_relocate_section() in the various elfxx-xxxx.c files. */ #define RELOC_FOR_GLOBAL_SYMBOL(info, input_bfd, input_section, rel, \ diff --git a/bfd/elf-hppa.h b/bfd/elf-hppa.h index 534dd11..1f79147 100644 --- a/bfd/elf-hppa.h +++ b/bfd/elf-hppa.h @@ -32,7 +32,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define elf_hppa_reloc_final_type elf64_hppa_reloc_final_type #define _bfd_elf_hppa_gen_reloc_type _bfd_elf64_hppa_gen_reloc_type #define elf_hppa_relocate_section elf64_hppa_relocate_section -#define bfd_elf_bfd_final_link bfd_elf64_bfd_final_link #define elf_hppa_final_link elf64_hppa_final_link #endif #if ARCH_SIZE == 32 @@ -41,7 +40,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define elf_hppa_reloc_final_type elf32_hppa_reloc_final_type #define _bfd_elf_hppa_gen_reloc_type _bfd_elf32_hppa_gen_reloc_type #define elf_hppa_relocate_section elf32_hppa_relocate_section -#define bfd_elf_bfd_final_link bfd_elf32_bfd_final_link #define elf_hppa_final_link elf32_hppa_final_link #endif @@ -1295,7 +1293,7 @@ elf_hppa_final_link (bfd *abfd, struct bfd_link_info *info) info); /* Invoke the regular ELF backend linker to do all the work. */ - retval = bfd_elf_bfd_final_link (abfd, info); + retval = bfd_elf_final_link (abfd, info); elf_link_hash_traverse (elf_hash_table (info), elf_hppa_remark_useless_dynamic_symbols, diff --git a/bfd/elf-m10300.c b/bfd/elf-m10300.c index 8277bae..c64d34f 100644 --- a/bfd/elf-m10300.c +++ b/bfd/elf-m10300.c @@ -616,7 +616,7 @@ _bfd_mn10300_elf_create_got_section (abfd, info) h->type = STT_OBJECT; if (info->shared - && ! _bfd_elf_link_record_dynamic_symbol (info, h)) + && ! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -650,7 +650,7 @@ _bfd_mn10300_elf_create_got_section (abfd, info) h->type = STT_OBJECT; if (info->shared - && ! _bfd_elf_link_record_dynamic_symbol (info, h)) + && ! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; elf_hash_table (info)->hgot = h; @@ -770,14 +770,14 @@ mn10300_elf_check_relocs (abfd, info, sec, relocs) /* This relocation describes the C++ object vtable hierarchy. Reconstruct it for later use during GC. */ case R_MN10300_GNU_VTINHERIT: - if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) + if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) return FALSE; break; /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_MN10300_GNU_VTENTRY: - if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend)) + if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) return FALSE; break; case R_MN10300_GOT32: @@ -822,7 +822,7 @@ mn10300_elf_check_relocs (abfd, info, sec, relocs) /* Make sure this symbol is output as a dynamic symbol. */ if (h->dynindx == -1) { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -4186,7 +4186,7 @@ _bfd_mn10300_elf_adjust_dynamic_symbol (info, h) /* Make sure this symbol is output as a dynamic symbol. */ if (h->dynindx == -1) { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } diff --git a/bfd/elf32-arm.h b/bfd/elf32-arm.h index 89540f0..97753a8 100644 --- a/bfd/elf32-arm.h +++ b/bfd/elf32-arm.h @@ -1209,18 +1209,6 @@ elf32_arm_to_thumb_stub (info, name, input_bfd, output_bfd, input_section, return TRUE; } -/* This is the condition under which elf32_arm_finish_dynamic_symbol - will be called from elflink.h. If elflink.h doesn't call our - finish_dynamic_symbol routine, we'll need to do something about - initializing any .plt and .got entries in elf32_arm_relocate_section - and elf32_arm_final_link_relocate. */ -#define WILL_CALL_FINISH_DYNAMIC_SYMBOL(DYN, SHARED, H) \ - ((DYN) \ - && ((SHARED) \ - || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) \ - && ((H)->dynindx != -1 \ - || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)) - /* Perform a relocation as part of a final link. */ static bfd_reloc_status_type @@ -3080,14 +3068,14 @@ elf32_arm_check_relocs (abfd, info, sec, relocs) /* This relocation describes the C++ object vtable hierarchy. Reconstruct it for later use during GC. */ case R_ARM_GNU_VTINHERIT: - if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) + if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) return FALSE; break; /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_ARM_GNU_VTENTRY: - if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_offset)) + if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset)) return FALSE; break; } @@ -3343,7 +3331,7 @@ allocate_dynrelocs (h, inf) if (h->dynindx == -1 && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -3403,7 +3391,7 @@ allocate_dynrelocs (h, inf) if (h->dynindx == -1 && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -3456,7 +3444,7 @@ allocate_dynrelocs (h, inf) if (h->dynindx == -1 && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } diff --git a/bfd/elf32-cris.c b/bfd/elf32-cris.c index b405d9e..775fd0e 100644 --- a/bfd/elf32-cris.c +++ b/bfd/elf32-cris.c @@ -1442,7 +1442,7 @@ elf_cris_finish_dynamic_symbol (output_bfd, info, h, sym) to this function. Note that we embed knowledge that "incoming" .got goes after .got.plt in the output without padding (pointer aligned). However, that knowledge is present in several other - places too, here and in elflink.h at least. */ + places too. */ bfd_vma got_offset = (has_gotplt ? gotplt_offset @@ -2095,7 +2095,7 @@ elf_cris_adjust_dynamic_symbol (info, h) /* Make sure this symbol is output as a dynamic symbol. */ if (h->dynindx == -1) { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -2422,7 +2422,7 @@ cris_elf_check_relocs (abfd, info, sec, relocs) /* Make sure this symbol is output as a dynamic symbol. */ if (h->dynindx == -1) { - if (!bfd_elf32_link_record_dynamic_symbol (info, h)) + if (!bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -2639,14 +2639,14 @@ cris_elf_check_relocs (abfd, info, sec, relocs) /* This relocation describes the C++ object vtable hierarchy. Reconstruct it for later use during GC. */ case R_CRIS_GNU_VTINHERIT: - if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) + if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) return FALSE; break; /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_CRIS_GNU_VTENTRY: - if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend)) + if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) return FALSE; break; @@ -3090,7 +3090,7 @@ elf_cris_reloc_type_class (rela) #define elf_backend_create_dynamic_sections \ _bfd_elf_create_dynamic_sections #define bfd_elf32_bfd_final_link \ - _bfd_elf32_gc_common_final_link + bfd_elf_gc_common_final_link #define elf_backend_hide_symbol elf_cris_hide_symbol #define elf_backend_reloc_type_class elf_cris_reloc_type_class diff --git a/bfd/elf32-d10v.c b/bfd/elf32-d10v.c index 4bdaffc..e845a25 100644 --- a/bfd/elf32-d10v.c +++ b/bfd/elf32-d10v.c @@ -334,14 +334,14 @@ elf32_d10v_check_relocs (abfd, info, sec, relocs) /* This relocation describes the C++ object vtable hierarchy. Reconstruct it for later use during GC. */ case R_D10V_GNU_VTINHERIT: - if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) + if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) return FALSE; break; /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_D10V_GNU_VTENTRY: - if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_offset)) + if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset)) return FALSE; break; } diff --git a/bfd/elf32-dlx.c b/bfd/elf32-dlx.c index 6ccb9f5..7fb6d0c 100644 --- a/bfd/elf32-dlx.c +++ b/bfd/elf32-dlx.c @@ -558,14 +558,14 @@ elf32_dlx_check_relocs (abfd, info, sec, relocs) /* This relocation describes the C++ object vtable hierarchy. Reconstruct it for later use during GC. */ case R_DLX_GNU_VTINHERIT: - if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) + if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) return FALSE; break; /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_DLX_GNU_VTENTRY: - if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend)) + if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) return FALSE; break; } diff --git a/bfd/elf32-fr30.c b/bfd/elf32-fr30.c index 80408fa..5f70e3f 100644 --- a/bfd/elf32-fr30.c +++ b/bfd/elf32-fr30.c @@ -718,14 +718,14 @@ fr30_elf_check_relocs (abfd, info, sec, relocs) /* This relocation describes the C++ object vtable hierarchy. Reconstruct it for later use during GC. */ case R_FR30_GNU_VTINHERIT: - if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) + if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) return FALSE; break; /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_FR30_GNU_VTENTRY: - if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend)) + if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) return FALSE; break; } diff --git a/bfd/elf32-frv.c b/bfd/elf32-frv.c index 039b4a3..6412acd 100644 --- a/bfd/elf32-frv.c +++ b/bfd/elf32-frv.c @@ -2676,7 +2676,7 @@ _frv_create_got_section (bfd *abfd, struct bfd_link_info *info) /* Machine-specific: we want the symbol for executables as well. */ - if (! _bfd_elf_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; elf_hash_table (info)->hgot = h; @@ -2724,7 +2724,7 @@ _frv_create_got_section (bfd *abfd, struct bfd_link_info *info) h->type = STT_OBJECT; /* Machine-specific: we want the symbol for executables as well. */ - if (! _bfd_elf_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; return TRUE; @@ -2779,7 +2779,7 @@ elf32_frv_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) h->type = STT_OBJECT; if (! info->executable - && ! _bfd_elf_link_record_dynamic_symbol (info, h)) + && ! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -4028,7 +4028,7 @@ elf32_frv_check_relocs (abfd, info, sec, relocs) case STV_HIDDEN: break; default: - bfd_elf32_link_record_dynamic_symbol (info, h); + bfd_elf_link_record_dynamic_symbol (info, h); break; } picrel @@ -4107,14 +4107,14 @@ elf32_frv_check_relocs (abfd, info, sec, relocs) /* This relocation describes the C++ object vtable hierarchy. Reconstruct it for later use during GC. */ case R_FRV_GNU_VTINHERIT: - if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) + if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) return FALSE; break; /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_FRV_GNU_VTENTRY: - if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend)) + if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) return FALSE; break; } diff --git a/bfd/elf32-h8300.c b/bfd/elf32-h8300.c index 6943391..877da8a 100644 --- a/bfd/elf32-h8300.c +++ b/bfd/elf32-h8300.c @@ -1558,7 +1558,7 @@ elf32_h8_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED, /* ??? when elf_backend_relocate_section is not defined, elf32-target.h defaults to using _bfd_generic_link_hash_table_create, but - elflink.h:bfd_elf32_size_dynamic_sections uses + bfd_elf_size_dynamic_sections uses dynobj = elf_hash_table (info)->dynobj; and thus requires an elf hash table. */ #define bfd_elf32_bfd_link_hash_table_create _bfd_elf_link_hash_table_create diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c index cffd194..54dbb9a 100644 --- a/bfd/elf32-hppa.c +++ b/bfd/elf32-hppa.c @@ -1199,16 +1199,14 @@ elf32_hppa_check_relocs (bfd *abfd, /* This relocation describes the C++ object vtable hierarchy. Reconstruct it for later use during GC. */ case R_PARISC_GNU_VTINHERIT: - if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, - &h->elf, rel->r_offset)) + if (!bfd_elf_gc_record_vtinherit (abfd, sec, &h->elf, rel->r_offset)) return FALSE; continue; /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_PARISC_GNU_VTENTRY: - if (!_bfd_elf32_gc_record_vtentry (abfd, sec, - &h->elf, rel->r_addend)) + if (!bfd_elf_gc_record_vtentry (abfd, sec, &h->elf, rel->r_addend)) return FALSE; continue; @@ -1621,17 +1619,6 @@ elf32_hppa_hide_symbol (struct bfd_link_info *info, } } -/* This is the condition under which elf32_hppa_finish_dynamic_symbol - will be called from elflink.h. If elflink.h doesn't call our - finish_dynamic_symbol routine, we'll need to do something about - initializing any .plt and .got entries in elf32_hppa_relocate_section. */ -#define WILL_CALL_FINISH_DYNAMIC_SYMBOL(DYN, INFO, H) \ - ((DYN) \ - && ((INFO)->shared \ - || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) \ - && ((H)->dynindx != -1 \ - || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)) - /* Adjust a symbol defined by a dynamic object and referenced by a regular object. The current definition is in some section of the dynamic object, but we're not including those sections. We have to @@ -1803,11 +1790,11 @@ allocate_plt_static (struct elf_link_hash_entry *h, void *inf) && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0 && h->type != STT_PARISC_MILLI) { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } - if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info, h)) + if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, h)) { /* Allocate these later. From this point on, h->plabel means that the plt entry is only used by a plabel. @@ -1881,7 +1868,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0 && h->type != STT_PARISC_MILLI) { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -1952,7 +1939,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0 && h->type != STT_PARISC_MILLI) { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -3005,7 +2992,7 @@ static bfd_boolean elf32_hppa_final_link (bfd *abfd, struct bfd_link_info *info) { /* Invoke the regular ELF linker to do all the work. */ - if (!bfd_elf32_bfd_final_link (abfd, info)) + if (!bfd_elf_final_link (abfd, info)) return FALSE; /* If we're producing a final executable, sort the contents of the @@ -3479,7 +3466,8 @@ elf32_hppa_relocate_section (bfd *output_bfd, off = h->elf.got.offset; dyn = htab->elf.dynamic_sections_created; - if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, &h->elf)) + if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, + &h->elf)) { /* If we aren't going to call finish_dynamic_symbol, then we need to handle initialisation of the .got @@ -3571,7 +3559,8 @@ elf32_hppa_relocate_section (bfd *output_bfd, if (h != NULL) { off = h->elf.plt.offset; - if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info, &h->elf)) + if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, + &h->elf)) { /* In a non-shared link, adjust_dynamic_symbols isn't called for symbols forced local. We diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index f1c27d0..7b173e4 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -1157,14 +1157,14 @@ elf_i386_check_relocs (bfd *abfd, /* This relocation describes the C++ object vtable hierarchy. Reconstruct it for later use during GC. */ case R_386_GNU_VTINHERIT: - if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) + if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) return FALSE; break; /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_386_GNU_VTENTRY: - if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_offset)) + if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset)) return FALSE; break; @@ -1458,17 +1458,6 @@ elf_i386_adjust_dynamic_symbol (struct bfd_link_info *info, return TRUE; } -/* This is the condition under which elf_i386_finish_dynamic_symbol - will be called from elflink.h. If elflink.h doesn't call our - finish_dynamic_symbol routine, we'll need to do something about - initializing any .plt and .got entries in elf_i386_relocate_section. */ -#define WILL_CALL_FINISH_DYNAMIC_SYMBOL(DYN, SHARED, H) \ - ((DYN) \ - && ((SHARED) \ - || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) \ - && ((H)->dynindx != -1 \ - || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)) - /* Allocate space in .plt, .got and associated reloc sections for dynamic relocs. */ @@ -1500,7 +1489,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) if (h->dynindx == -1 && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -1568,7 +1557,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) if (h->dynindx == -1 && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -1657,7 +1646,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) if (h->dynindx == -1 && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } diff --git a/bfd/elf32-iq2000.c b/bfd/elf32-iq2000.c index 67be175..60dab34 100644 --- a/bfd/elf32-iq2000.c +++ b/bfd/elf32-iq2000.c @@ -484,14 +484,14 @@ iq2000_elf_check_relocs (abfd, info, sec, relocs) /* This relocation describes the C++ object vtable hierarchy. Reconstruct it for later use during GC. */ case R_IQ2000_GNU_VTINHERIT: - if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) + if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) return FALSE; break; /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_IQ2000_GNU_VTENTRY: - if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend)) + if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) return FALSE; break; diff --git a/bfd/elf32-m32r.c b/bfd/elf32-m32r.c index 812b3ca..21d37b1 100644 --- a/bfd/elf32-m32r.c +++ b/bfd/elf32-m32r.c @@ -1742,7 +1742,7 @@ m32r_elf_create_dynamic_sections (abfd, info) h->type = STT_OBJECT; if (info->shared - && ! _bfd_elf_link_record_dynamic_symbol (info, h)) + && ! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -2049,17 +2049,6 @@ printf("m32r_elf_adjust_dynamic_symbol()\n"); return TRUE; } -/* This is the condition under which finish_dynamic_symbol will be called - from elflink.h. If elflink.h doesn't call our finish_dynamic_symbol - routine, we'll need to do something about initializing any .plt and .got - entries in relocate_section. */ -#define WILL_CALL_FINISH_DYNAMIC_SYMBOL(DYN, INFO, H) \ - ((DYN) \ - && ((INFO)->shared \ - || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) \ - && ((H)->dynindx != -1 \ - || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)) - /* Allocate space in .plt, .got and associated reloc sections for dynamic relocs. */ @@ -2105,11 +2094,11 @@ allocate_dynrelocs (h, inf) if (h->dynindx == -1 && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } - if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info, h)) + if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, h)) { asection *s = htab->splt; @@ -2164,7 +2153,7 @@ allocate_dynrelocs (h, inf) if (h->dynindx == -1 && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -2173,7 +2162,7 @@ allocate_dynrelocs (h, inf) h->got.offset = s->_raw_size; s->_raw_size += 4; dyn = htab->root.dynamic_sections_created; - if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h)) + if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)) htab->srelgot->_raw_size += sizeof (Elf32_External_Rela); } else @@ -2224,7 +2213,7 @@ allocate_dynrelocs (h, inf) if (h->dynindx == -1 && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -2723,7 +2712,8 @@ m32r_elf_relocate_section (output_bfd, info, input_bfd, input_section, || r_type == R_M32R_GOT16_HI_ULO || r_type == R_M32R_GOT16_HI_SLO || r_type == R_M32R_GOT16_LO) - && WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h) + && WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, + info->shared, h) && (! info->shared || (! info->symbolic && h->dynindx != -1) || (h->elf_link_hash_flags @@ -2845,7 +2835,7 @@ m32r_elf_relocate_section (output_bfd, info, input_bfd, input_section, BFD_ASSERT (off != (bfd_vma) -1); dyn = htab->root.dynamic_sections_created; - if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h) + if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h) || (info->shared && (info->symbolic || h->dynindx == -1 @@ -4656,18 +4646,18 @@ m32r_elf_check_relocs (abfd, info, sec, relocs) Reconstruct it for later use during GC. */ case R_M32R_RELA_GNU_VTINHERIT: case R_M32R_GNU_VTINHERIT: - if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) + if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) return FALSE; break; /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_M32R_GNU_VTENTRY: - if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_offset)) + if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset)) return FALSE; break; case R_M32R_RELA_GNU_VTENTRY: - if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend)) + if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) return FALSE; break; } diff --git a/bfd/elf32-m68hc1x.c b/bfd/elf32-m68hc1x.c index 9de2f8b..2a139a4 100644 --- a/bfd/elf32-m68hc1x.c +++ b/bfd/elf32-m68hc1x.c @@ -893,14 +893,14 @@ elf32_m68hc11_check_relocs (bfd *abfd, struct bfd_link_info *info, /* This relocation describes the C++ object vtable hierarchy. Reconstruct it for later use during GC. */ case R_M68HC11_GNU_VTINHERIT: - if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) + if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) return FALSE; break; /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_M68HC11_GNU_VTENTRY: - if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend)) + if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) return FALSE; break; } diff --git a/bfd/elf32-m68k.c b/bfd/elf32-m68k.c index 9864ef2..39832be 100644 --- a/bfd/elf32-m68k.c +++ b/bfd/elf32-m68k.c @@ -508,7 +508,7 @@ elf_m68k_check_relocs (abfd, info, sec, relocs) if (h->dynindx == -1 && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { - if (!bfd_elf32_link_record_dynamic_symbol (info, h)) + if (!bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -586,7 +586,7 @@ elf_m68k_check_relocs (abfd, info, sec, relocs) if (h->dynindx == -1 && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { - if (!bfd_elf32_link_record_dynamic_symbol (info, h)) + if (!bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -745,14 +745,14 @@ elf_m68k_check_relocs (abfd, info, sec, relocs) /* This relocation describes the C++ object vtable hierarchy. Reconstruct it for later use during GC. */ case R_68K_GNU_VTINHERIT: - if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) + if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) return FALSE; break; /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_68K_GNU_VTENTRY: - if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend)) + if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) return FALSE; break; @@ -970,7 +970,7 @@ elf_m68k_adjust_dynamic_symbol (info, h) if (h->dynindx == -1 && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -1099,17 +1099,6 @@ elf_m68k_adjust_dynamic_symbol (info, h) return TRUE; } -/* This is the condition under which elf_m68k_finish_dynamic_symbol - will be called from elflink.h. If elflink.h doesn't call our - finish_dynamic_symbol routine, we'll need to do something about - initializing any .plt and .got entries in elf_m68k_relocate_section. */ -#define WILL_CALL_FINISH_DYNAMIC_SYMBOL(DYN, SHARED, H) \ - ((DYN) \ - && ((SHARED) \ - || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) \ - && ((H)->dynindx != -1 \ - || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)) - /* Set the sizes of the dynamic sections. */ static bfd_boolean @@ -2242,7 +2231,7 @@ elf32_m68k_reloc_type_class (rela) _bfd_elf_create_dynamic_sections #define bfd_elf32_bfd_link_hash_table_create \ elf_m68k_link_hash_table_create -#define bfd_elf32_bfd_final_link _bfd_elf32_gc_common_final_link +#define bfd_elf32_bfd_final_link bfd_elf_gc_common_final_link #define elf_backend_check_relocs elf_m68k_check_relocs #define elf_backend_adjust_dynamic_symbol \ diff --git a/bfd/elf32-mcore.c b/bfd/elf32-mcore.c index fd13ea8..e6aa666 100644 --- a/bfd/elf32-mcore.c +++ b/bfd/elf32-mcore.c @@ -647,14 +647,14 @@ mcore_elf_check_relocs (abfd, info, sec, relocs) /* This relocation describes the C++ object vtable hierarchy. Reconstruct it for later use during GC. */ case R_MCORE_GNU_VTINHERIT: - if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) + if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) return FALSE; break; /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_MCORE_GNU_VTENTRY: - if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend)) + if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) return FALSE; break; } diff --git a/bfd/elf32-openrisc.c b/bfd/elf32-openrisc.c index 5513ad6..af1c222 100644 --- a/bfd/elf32-openrisc.c +++ b/bfd/elf32-openrisc.c @@ -535,14 +535,14 @@ openrisc_elf_check_relocs (abfd, info, sec, relocs) /* This relocation describes the C++ object vtable hierarchy. Reconstruct it for later use during GC. */ case R_OPENRISC_GNU_VTINHERIT: - if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) + if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) return FALSE; break; /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_OPENRISC_GNU_VTENTRY: - if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend)) + if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) return FALSE; break; } diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index 515a929..4eb08ad 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -2392,7 +2392,7 @@ elf_create_pointer_linker_section (bfd *abfd, /* Make sure this symbol is output as a dynamic symbol. */ if (h->dynindx == -1) { - if (! _bfd_elf_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -2685,7 +2685,7 @@ ppc_elf_create_linker_section (bfd *abfd, lsect->sym_hash = h; if (info->shared - && ! _bfd_elf_link_record_dynamic_symbol (info, h)) + && ! bfd_elf_link_record_dynamic_symbol (info, h)) return NULL; } @@ -2993,17 +2993,6 @@ ppc_elf_adjust_dynamic_symbol (struct bfd_link_info *info, return TRUE; } -/* This is the condition under which finish_dynamic_symbol will be - called from elflink.h. If elflink.h doesn't call our - finish_dynamic_symbol routine, we'll need to do something about - initializing any .plt and .got entries in relocate_section. */ -#define WILL_CALL_FINISH_DYNAMIC_SYMBOL(DYN, SHARED, H) \ - ((DYN) \ - && ((SHARED) \ - || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) \ - && ((H)->dynindx != -1 \ - || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)) - /* Of those relocs that might be copied as dynamic relocs, this macro selects those that must be copied when linking a shared library, even when the symbol is local. */ @@ -3042,7 +3031,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) if (h->dynindx == -1 && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -3105,7 +3094,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) if (eh->elf.dynindx == -1 && (eh->elf.elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { - if (!bfd_elf32_link_record_dynamic_symbol (info, &eh->elf)) + if (!bfd_elf_link_record_dynamic_symbol (info, &eh->elf)) return FALSE; } @@ -3195,7 +3184,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) && h->root.type == bfd_link_hash_undefweak && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } } @@ -3214,7 +3203,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) if (h->dynindx == -1 && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { - if (! bfd_elf64_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -3806,14 +3795,14 @@ ppc_elf_check_relocs (bfd *abfd, /* This relocation describes the C++ object vtable hierarchy. Reconstruct it for later use during GC. */ case R_PPC_GNU_VTINHERIT: - if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) + if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) return FALSE; break; /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_PPC_GNU_VTENTRY: - if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend)) + if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) return FALSE; break; diff --git a/bfd/elf32-s390.c b/bfd/elf32-s390.c index eabd070..074c108 100644 --- a/bfd/elf32-s390.c +++ b/bfd/elf32-s390.c @@ -1345,14 +1345,14 @@ elf_s390_check_relocs (abfd, info, sec, relocs) /* This relocation describes the C++ object vtable hierarchy. Reconstruct it for later use during GC. */ case R_390_GNU_VTINHERIT: - if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) + if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) return FALSE; break; /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_390_GNU_VTENTRY: - if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend)) + if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) return FALSE; break; @@ -1716,17 +1716,6 @@ elf_s390_adjust_dynamic_symbol (info, h) return TRUE; } -/* This is the condition under which elf_s390_finish_dynamic_symbol - will be called from elflink.h. If elflink.h doesn't call our - finish_dynamic_symbol routine, we'll need to do something about - initializing any .plt and .got entries in elf_s390_relocate_section. */ -#define WILL_CALL_FINISH_DYNAMIC_SYMBOL(DYN, SHARED, H) \ - ((DYN) \ - && ((SHARED) \ - || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) \ - && ((H)->dynindx != -1 \ - || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)) - /* Allocate space in .plt, .got and associated reloc sections for dynamic relocs. */ @@ -1762,7 +1751,7 @@ allocate_dynrelocs (h, inf) if (h->dynindx == -1 && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -1845,7 +1834,7 @@ allocate_dynrelocs (h, inf) if (h->dynindx == -1 && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -1923,7 +1912,7 @@ allocate_dynrelocs (h, inf) if (h->dynindx == -1 && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c index 3ec6638..1070957 100644 --- a/bfd/elf32-sh.c +++ b/bfd/elf32-sh.c @@ -3924,7 +3924,7 @@ sh_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) h->type = STT_OBJECT; if (info->shared - && ! _bfd_elf_link_record_dynamic_symbol (info, h)) + && ! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -4167,17 +4167,6 @@ sh_elf_adjust_dynamic_symbol (struct bfd_link_info *info, return TRUE; } -/* This is the condition under which sh_elf_finish_dynamic_symbol - will be called from elflink.h. If elflink.h doesn't call our - finish_dynamic_symbol routine, we'll need to do something about - initializing any .plt and .got entries in sh_elf_relocate_section. */ -#define WILL_CALL_FINISH_DYNAMIC_SYMBOL(DYN, SHARED, H) \ - ((DYN) \ - && ((SHARED) \ - || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) \ - && ((H)->dynindx != -1 \ - || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)) - /* Allocate space in .plt, .got and associated reloc sections for dynamic relocs. */ @@ -4223,7 +4212,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) if (h->dynindx == -1 && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -4284,7 +4273,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) if (h->dynindx == -1 && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -4322,7 +4311,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) if (h->dynindx == -1 && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -4387,7 +4376,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) if (h->dynindx == -1 && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -6490,14 +6479,14 @@ sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, /* This relocation describes the C++ object vtable hierarchy. Reconstruct it for later use during GC. */ case R_SH_GNU_VTINHERIT: - if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) + if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) return FALSE; break; /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_SH_GNU_VTENTRY: - if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend)) + if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) return FALSE; break; diff --git a/bfd/elf32-sparc.c b/bfd/elf32-sparc.c index 9f8f9ab..3016652 100644 --- a/bfd/elf32-sparc.c +++ b/bfd/elf32-sparc.c @@ -1267,12 +1267,12 @@ elf32_sparc_check_relocs (abfd, info, sec, relocs) break; case R_SPARC_GNU_VTINHERIT: - if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) + if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) return FALSE; break; case R_SPARC_GNU_VTENTRY: - if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend)) + if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) return FALSE; break; @@ -1592,17 +1592,6 @@ elf32_sparc_adjust_dynamic_symbol (info, h) return TRUE; } -/* This is the condition under which finish_dynamic_symbol will be called - from elflink.h. If elflink.h doesn't call our finish_dynamic_symbol - routine, we'll need to do something about initializing any .plt and .got - entries in relocate_section. */ -#define WILL_CALL_FINISH_DYNAMIC_SYMBOL(DYN, INFO, H) \ - ((DYN) \ - && ((INFO)->shared \ - || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) \ - && ((H)->dynindx != -1 \ - || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)) - /* Allocate space in .plt, .got and associated reloc sections for dynamic relocs. */ @@ -1636,11 +1625,11 @@ allocate_dynrelocs (h, inf) if (h->dynindx == -1 && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } - if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info, h)) + if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, h)) { asection *s = htab->splt; @@ -1705,7 +1694,7 @@ allocate_dynrelocs (h, inf) if (h->dynindx == -1 && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -1724,7 +1713,7 @@ allocate_dynrelocs (h, inf) htab->srelgot->_raw_size += sizeof (Elf32_External_Rela); else if (tls_type == GOT_TLS_GD) htab->srelgot->_raw_size += 2 * sizeof (Elf32_External_Rela); - else if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h)) + else if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)) htab->srelgot->_raw_size += sizeof (Elf32_External_Rela); } else @@ -1777,7 +1766,7 @@ allocate_dynrelocs (h, inf) if (h->dynindx == -1 && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -2239,7 +2228,7 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section, BFD_ASSERT (off != (bfd_vma) -1); dyn = elf_hash_table (info)->dynamic_sections_created; - if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h) + if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h) || (info->shared && (info->symbolic || h->dynindx == -1 diff --git a/bfd/elf32-v850.c b/bfd/elf32-v850.c index 2aba9cd..b9dcf3c 100644 --- a/bfd/elf32-v850.c +++ b/bfd/elf32-v850.c @@ -699,14 +699,14 @@ v850_elf_check_relocs (abfd, info, sec, relocs) /* This relocation describes the C++ object vtable hierarchy. Reconstruct it for later use during GC. */ case R_V850_GNU_VTINHERIT: - if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) + if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) return FALSE; break; /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_V850_GNU_VTENTRY: - if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend)) + if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) return FALSE; break; diff --git a/bfd/elf32-vax.c b/bfd/elf32-vax.c index e6dc4a0..8ce4678 100644 --- a/bfd/elf32-vax.c +++ b/bfd/elf32-vax.c @@ -821,14 +821,14 @@ elf_vax_check_relocs (abfd, info, sec, relocs) /* This relocation describes the C++ object vtable hierarchy. Reconstruct it for later use during GC. */ case R_VAX_GNU_VTINHERIT: - if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) + if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) return FALSE; break; /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_VAX_GNU_VTENTRY: - if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend)) + if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) return FALSE; break; @@ -1006,7 +1006,7 @@ elf_vax_adjust_dynamic_symbol (info, h) /* Make sure this symbol is output as a dynamic symbol. */ if (h->dynindx == -1) { - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -1400,7 +1400,7 @@ elf_vax_instantiate_got_entries (h, infoptr) /* Make sure this symbol is output as a dynamic symbol. */ if (h->dynindx == -1) { - if (!bfd_elf32_link_record_dynamic_symbol (info, h)) + if (!bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -2133,7 +2133,7 @@ elf_vax_finish_dynamic_sections (output_bfd, info) _bfd_elf_create_dynamic_sections #define bfd_elf32_bfd_link_hash_table_create \ elf_vax_link_hash_table_create -#define bfd_elf32_bfd_final_link _bfd_elf32_gc_common_final_link +#define bfd_elf32_bfd_final_link bfd_elf_gc_common_final_link #define elf_backend_check_relocs elf_vax_check_relocs #define elf_backend_adjust_dynamic_symbol \ diff --git a/bfd/elf32-xstormy16.c b/bfd/elf32-xstormy16.c index 985a43a..bbf6ee0 100644 --- a/bfd/elf32-xstormy16.c +++ b/bfd/elf32-xstormy16.c @@ -516,14 +516,14 @@ xstormy16_elf_check_relocs (abfd, info, sec, relocs) /* This relocation describes the C++ object vtable hierarchy. Reconstruct it for later use during GC. */ case R_XSTORMY16_GNU_VTINHERIT: - if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) + if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) return FALSE; break; /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_XSTORMY16_GNU_VTENTRY: - if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend)) + if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) return FALSE; break; } diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c index 6cb987c..e897777 100644 --- a/bfd/elf32-xtensa.c +++ b/bfd/elf32-xtensa.c @@ -733,14 +733,14 @@ elf_xtensa_check_relocs (abfd, info, sec, relocs) case R_XTENSA_GNU_VTINHERIT: /* This relocation describes the C++ object vtable hierarchy. Reconstruct it for later use during GC. */ - if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) + if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) return FALSE; break; case R_XTENSA_GNU_VTENTRY: /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ - if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend)) + if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) return FALSE; break; @@ -2720,7 +2720,7 @@ elf_xtensa_discard_info_for_section (abfd, cookie, info, sec) while (cookie->rel < cookie->relend && cookie->rel->r_offset == offset) { - if (_bfd_elf32_reloc_symbol_deleted_p (offset, cookie)) + if (bfd_elf_reloc_symbol_deleted_p (offset, cookie)) { /* Remove the table entry. (If the reloc type is NONE, then the entry has already been merged with another and deleted @@ -5815,7 +5815,6 @@ static struct bfd_elf_special_section const elf_xtensa_special_sections[]= #define elf_info_to_howto elf_xtensa_info_to_howto_rela -#define bfd_elf32_bfd_final_link bfd_elf32_bfd_final_link #define bfd_elf32_bfd_merge_private_bfd_data elf_xtensa_merge_private_bfd_data #define bfd_elf32_new_section_hook elf_xtensa_new_section_hook #define bfd_elf32_bfd_print_private_bfd_data elf_xtensa_print_private_bfd_data diff --git a/bfd/elf64-alpha.c b/bfd/elf64-alpha.c index 1683683..2d4715b 100644 --- a/bfd/elf64-alpha.c +++ b/bfd/elf64-alpha.c @@ -2462,7 +2462,7 @@ elf64_alpha_create_dynamic_sections (abfd, info) h->type = STT_OBJECT; if (info->shared - && ! _bfd_elf_link_record_dynamic_symbol (info, h)) + && ! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; s = bfd_make_section (abfd, ".rela.plt"); @@ -2506,7 +2506,7 @@ elf64_alpha_create_dynamic_sections (abfd, info) h->type = STT_OBJECT; if (info->shared - && ! _bfd_elf_link_record_dynamic_symbol (info, h)) + && ! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; elf_hash_table (info)->hgot = h; @@ -5335,7 +5335,7 @@ elf64_alpha_final_link (abfd, info) } /* Invoke the regular ELF backend linker to do all the work. */ - if (! bfd_elf64_bfd_final_link (abfd, info)) + if (! bfd_elf_final_link (abfd, info)) return FALSE; /* Now write out the computed sections. */ diff --git a/bfd/elf64-hppa.c b/bfd/elf64-hppa.c index d64eca2..76dcc18 100644 --- a/bfd/elf64-hppa.c +++ b/bfd/elf64-hppa.c @@ -933,7 +933,7 @@ elf64_hppa_check_relocs (abfd, info, sec, relocs) section symbol for this section ends up in the dynamic symbol table. */ if (info->shared && dynrel_type == R_PARISC_FPTR64 - && ! (_bfd_elf64_link_record_local_dynamic_symbol + && ! (bfd_elf_link_record_local_dynamic_symbol (info, abfd, sec_symndx))) return FALSE; } @@ -1044,7 +1044,7 @@ allocate_global_data_dlt (dyn_h, data) bfd *owner; owner = (h ? h->root.u.def.section->owner : dyn_h->owner); - if (! (_bfd_elf64_link_record_local_dynamic_symbol + if (! (bfd_elf_link_record_local_dynamic_symbol (x->info, owner, dyn_h->sym_indx))) return FALSE; } @@ -1148,7 +1148,7 @@ allocate_global_data_opd (dyn_h, data) bfd *owner; owner = (h ? h->root.u.def.section->owner : dyn_h->owner); - if (!_bfd_elf64_link_record_local_dynamic_symbol + if (!bfd_elf_link_record_local_dynamic_symbol (x->info, owner, dyn_h->sym_indx)) return FALSE; } @@ -1174,7 +1174,7 @@ allocate_global_data_opd (dyn_h, data) nh->root.u.def.value = h->root.u.def.value; nh->root.u.def.section = h->root.u.def.section; - if (! bfd_elf64_link_record_dynamic_symbol (x->info, nh)) + if (! bfd_elf_link_record_dynamic_symbol (x->info, nh)) return FALSE; } @@ -1510,7 +1510,7 @@ allocate_dynrel_entries (dyn_h, data) the symbol need only be added once. */ if (dyn_h->h == 0 || (dyn_h->h->dynindx == -1 && dyn_h->h->type != STT_PARISC_MILLI)) - if (!_bfd_elf64_link_record_local_dynamic_symbol + if (!bfd_elf_link_record_local_dynamic_symbol (x->info, rent->sec->owner, dyn_h->sym_indx)) return FALSE; } diff --git a/bfd/elf64-mmix.c b/bfd/elf64-mmix.c index dda7086..4b78681 100644 --- a/bfd/elf64-mmix.c +++ b/bfd/elf64-mmix.c @@ -2027,14 +2027,14 @@ mmix_elf_check_relocs (abfd, info, sec, relocs) /* This relocation describes the C++ object vtable hierarchy. Reconstruct it for later use during GC. */ case R_MMIX_GNU_VTINHERIT: - if (!_bfd_elf64_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) + if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) return FALSE; break; /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_MMIX_GNU_VTENTRY: - if (!_bfd_elf64_gc_record_vtentry (abfd, sec, h, rel->r_addend)) + if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) return FALSE; break; } @@ -2272,7 +2272,7 @@ mmix_elf_final_link (abfd, info) --abfd->section_count; } - if (! bfd_elf64_bfd_final_link (abfd, info)) + if (! bfd_elf_final_link (abfd, info)) return FALSE; /* Since this section is marked SEC_LINKER_CREATED, it isn't output by diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index a2aebfe..a0d81d0 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -3808,14 +3808,14 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, /* This relocation describes the C++ object vtable hierarchy. Reconstruct it for later use during GC. */ case R_PPC64_GNU_VTINHERIT: - if (!_bfd_elf64_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) + if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) return FALSE; break; /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_PPC64_GNU_VTENTRY: - if (!_bfd_elf64_gc_record_vtentry (abfd, sec, h, rel->r_addend)) + if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) return FALSE; break; @@ -4404,7 +4404,7 @@ func_desc_adjust (struct elf_link_hash_entry *h, void *inf) && ELF_ST_VISIBILITY (fdh->elf.other) == STV_DEFAULT))) { if (fdh->elf.dynindx == -1) - if (! bfd_elf64_link_record_dynamic_symbol (info, &fdh->elf)) + if (! bfd_elf_link_record_dynamic_symbol (info, &fdh->elf)) return FALSE; fdh->elf.elf_link_hash_flags |= (fh->elf.elf_link_hash_flags & (ELF_LINK_HASH_REF_REGULAR @@ -5574,17 +5574,6 @@ ppc64_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED, struct bfd_link_info *info) return TRUE; } -/* This is the condition under which ppc64_elf_finish_dynamic_symbol - will be called from elflink.h. If elflink.h doesn't call our - finish_dynamic_symbol routine, we'll need to do something about - initializing any .plt and .got entries in ppc64_elf_relocate_section. */ -#define WILL_CALL_FINISH_DYNAMIC_SYMBOL(DYN, SHARED, H) \ - ((DYN) \ - && ((SHARED) \ - || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) \ - && ((H)->dynindx != -1 \ - || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)) - /* Allocate space in .plt, .got and associated reloc sections for dynamic relocs. */ @@ -5694,7 +5683,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) if (h->dynindx == -1 && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { - if (! bfd_elf64_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -5775,7 +5764,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf) if (h->dynindx == -1 && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { - if (! bfd_elf64_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c index c35c0a9..63a261a 100644 --- a/bfd/elf64-s390.c +++ b/bfd/elf64-s390.c @@ -1309,14 +1309,14 @@ elf_s390_check_relocs (abfd, info, sec, relocs) /* This relocation describes the C++ object vtable hierarchy. Reconstruct it for later use during GC. */ case R_390_GNU_VTINHERIT: - if (!_bfd_elf64_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) + if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) return FALSE; break; /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_390_GNU_VTENTRY: - if (!_bfd_elf64_gc_record_vtentry (abfd, sec, h, rel->r_addend)) + if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) return FALSE; break; @@ -1687,17 +1687,6 @@ elf_s390_adjust_dynamic_symbol (info, h) return TRUE; } -/* This is the condition under which elf_s390_finish_dynamic_symbol - will be called from elflink.h. If elflink.h doesn't call our - finish_dynamic_symbol routine, we'll need to do something about - initializing any .plt and .got entries in elf_s390_relocate_section. */ -#define WILL_CALL_FINISH_DYNAMIC_SYMBOL(DYN, SHARED, H) \ - ((DYN) \ - && ((SHARED) \ - || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) \ - && ((H)->dynindx != -1 \ - || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)) - /* Allocate space in .plt, .got and associated reloc sections for dynamic relocs. */ @@ -1733,7 +1722,7 @@ allocate_dynrelocs (h, inf) if (h->dynindx == -1 && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { - if (! bfd_elf64_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -1816,7 +1805,7 @@ allocate_dynrelocs (h, inf) if (h->dynindx == -1 && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { - if (! bfd_elf64_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -1894,7 +1883,7 @@ allocate_dynrelocs (h, inf) if (h->dynindx == -1 && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { - if (! bfd_elf64_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } diff --git a/bfd/elf64-sh64.c b/bfd/elf64-sh64.c index 87b754e..ad6ca1c 100644 --- a/bfd/elf64-sh64.c +++ b/bfd/elf64-sh64.c @@ -2562,14 +2562,14 @@ sh_elf64_check_relocs (bfd *abfd, struct bfd_link_info *info, /* This relocation describes the C++ object vtable hierarchy. Reconstruct it for later use during GC. */ case R_SH_GNU_VTINHERIT: - if (!_bfd_elf64_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) + if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) return FALSE; break; /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_SH_GNU_VTENTRY: - if (!_bfd_elf64_gc_record_vtentry (abfd, sec, h, rel->r_addend)) + if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) return FALSE; break; @@ -2634,7 +2634,7 @@ sh_elf64_check_relocs (bfd *abfd, struct bfd_link_info *info, /* Make sure this symbol is output as a dynamic symbol. */ if (h->dynindx == -1) { - if (! bfd_elf64_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -2717,7 +2717,7 @@ sh_elf64_check_relocs (bfd *abfd, struct bfd_link_info *info, /* Make sure this symbol is output as a dynamic symbol. */ if (h->dynindx == -1) { - if (! bfd_elf64_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -3299,7 +3299,7 @@ sh64_elf64_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) h->type = STT_OBJECT; if (info->shared - && ! _bfd_elf_link_record_dynamic_symbol (info, h)) + && ! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -3425,7 +3425,7 @@ sh64_elf64_adjust_dynamic_symbol (struct bfd_link_info *info, /* Make sure this symbol is output as a dynamic symbol. */ if (h->dynindx == -1) { - if (! bfd_elf64_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } diff --git a/bfd/elf64-sparc.c b/bfd/elf64-sparc.c index 6c9d302..dd3e496 100644 --- a/bfd/elf64-sparc.c +++ b/bfd/elf64-sparc.c @@ -1178,7 +1178,7 @@ sparc64_elf_check_relocs (abfd, info, sec, relocs) /* Make sure this symbol is output as a dynamic symbol. */ if (h->dynindx == -1) { - if (! bfd_elf64_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -1261,7 +1261,7 @@ sparc64_elf_check_relocs (abfd, info, sec, relocs) /* Make sure this symbol is output as a dynamic symbol. */ if (h->dynindx == -1) { - if (! bfd_elf64_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -1989,17 +1989,6 @@ sparc64_elf_relax_section (abfd, section, link_info, again) return TRUE; } -/* This is the condition under which finish_dynamic_symbol will be called - from elflink.h. If elflink.h doesn't call our finish_dynamic_symbol - routine, we'll need to do something about initializing any .plt and - .got entries in relocate_section. */ -#define WILL_CALL_FINISH_DYNAMIC_SYMBOL(DYN, INFO, H) \ - ((DYN) \ - && ((INFO)->shared \ - || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) \ - && ((H)->dynindx != -1 \ - || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)) - /* Relocate a SPARC64 ELF section. */ static bfd_boolean @@ -2327,7 +2316,7 @@ sparc64_elf_relocate_section (output_bfd, info, input_bfd, input_section, BFD_ASSERT (off != (bfd_vma) -1); dyn = elf_hash_table (info)->dynamic_sections_created; - if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info, h) + if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h) || (info->shared && (info->symbolic || h->dynindx == -1 diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 1aadfe5..a1d6250 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -951,14 +951,14 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, /* This relocation describes the C++ object vtable hierarchy. Reconstruct it for later use during GC. */ case R_X86_64_GNU_VTINHERIT: - if (!_bfd_elf64_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) + if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) return FALSE; break; /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_X86_64_GNU_VTENTRY: - if (!_bfd_elf64_gc_record_vtentry (abfd, sec, h, rel->r_addend)) + if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend)) return FALSE; break; @@ -1258,17 +1258,6 @@ elf64_x86_64_adjust_dynamic_symbol (struct bfd_link_info *info, return TRUE; } -/* This is the condition under which elf64_x86_64_finish_dynamic_symbol - will be called from elflink.h. If elflink.h doesn't call our - finish_dynamic_symbol routine, we'll need to do something about - initializing any .plt and .got entries in elf64_x86_64_relocate_section. */ -#define WILL_CALL_FINISH_DYNAMIC_SYMBOL(DYN, SHARED, H) \ - ((DYN) \ - && ((SHARED) \ - || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) \ - && ((H)->dynindx != -1 \ - || ((H)->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0)) - /* Allocate space in .plt, .got and associated reloc sections for dynamic relocs. */ @@ -1297,7 +1286,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) if (h->dynindx == -1 && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { - if (! bfd_elf64_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -1365,7 +1354,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) if (h->dynindx == -1 && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { - if (! bfd_elf64_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -1450,7 +1439,7 @@ allocate_dynrelocs (struct elf_link_hash_entry *h, void * inf) if (h->dynindx == -1 && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) { - if (! bfd_elf64_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } diff --git a/bfd/elfcode.h b/bfd/elfcode.h index 86836b9..bc69d48 100644 --- a/bfd/elfcode.h +++ b/bfd/elfcode.h @@ -119,18 +119,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define elf_write_out_phdrs NAME(bfd_elf,write_out_phdrs) #define elf_write_relocs NAME(bfd_elf,write_relocs) #define elf_slurp_reloc_table NAME(bfd_elf,slurp_reloc_table) -#define elf_bfd_discard_info NAME(bfd_elf,discard_info) -#define elf_reloc_symbol_deleted_p NAME(_bfd_elf,reloc_symbol_deleted_p) -#define elf_link_record_dynamic_symbol _bfd_elf_link_record_dynamic_symbol -#define elf_bfd_final_link NAME(bfd_elf,bfd_final_link) -#define elf_gc_sections NAME(_bfd_elf,gc_sections) -#define elf_gc_common_finalize_got_offsets \ - NAME(_bfd_elf,gc_common_finalize_got_offsets) -#define elf_gc_common_final_link NAME(_bfd_elf,gc_common_final_link) -#define elf_gc_record_vtinherit NAME(_bfd_elf,gc_record_vtinherit) -#define elf_gc_record_vtentry NAME(_bfd_elf,gc_record_vtentry) -#define elf_link_record_local_dynamic_symbol \ - NAME(_bfd_elf,link_record_local_dynamic_symbol) #if ARCH_SIZE == 64 #define ELF_R_INFO(X,Y) ELF64_R_INFO(X,Y) @@ -1731,7 +1719,6 @@ NAME(_bfd_elf,bfd_from_remote_memory) } #include "elfcore.h" -#include "elflink.h" /* Size-dependent data and functions. */ const struct elf_size_info NAME(_bfd_elf,size_info) = { diff --git a/bfd/elflink.c b/bfd/elflink.c index a11e7cd..5c8072a 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -90,7 +90,7 @@ _bfd_elf_create_got_section (bfd *abfd, struct bfd_link_info *info) h->type = STT_OBJECT; if (! info->executable - && ! _bfd_elf_link_record_dynamic_symbol (info, h)) + && ! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; elf_hash_table (info)->hgot = h; @@ -220,7 +220,7 @@ _bfd_elf_link_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) h->type = STT_OBJECT; if (! info->executable - && ! _bfd_elf_link_record_dynamic_symbol (info, h)) + && ! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; s = bfd_make_section (abfd, ".hash"); @@ -285,7 +285,7 @@ _bfd_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) h->type = STT_OBJECT; if (! info->executable - && ! _bfd_elf_link_record_dynamic_symbol (info, h)) + && ! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -347,8 +347,8 @@ _bfd_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) one. */ bfd_boolean -_bfd_elf_link_record_dynamic_symbol (struct bfd_link_info *info, - struct elf_link_hash_entry *h) +bfd_elf_link_record_dynamic_symbol (struct bfd_link_info *info, + struct elf_link_hash_entry *h) { if (h->dynindx == -1) { @@ -466,7 +466,7 @@ bfd_elf_record_link_assignment (bfd *output_bfd ATTRIBUTE_UNUSED, || info->shared) && h->dynindx == -1) { - if (! _bfd_elf_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; /* If this is a weak defined symbol, and we know a corresponding @@ -475,7 +475,7 @@ bfd_elf_record_link_assignment (bfd *output_bfd ATTRIBUTE_UNUSED, if (h->weakdef != NULL && h->weakdef->dynindx == -1) { - if (! _bfd_elf_link_record_dynamic_symbol (info, h->weakdef)) + if (! bfd_elf_link_record_dynamic_symbol (info, h->weakdef)) return FALSE; } } @@ -488,9 +488,9 @@ bfd_elf_record_link_assignment (bfd *output_bfd ATTRIBUTE_UNUSED, in a discarded section, eg. a discarded link-once section symbol. */ int -elf_link_record_local_dynamic_symbol (struct bfd_link_info *info, - bfd *input_bfd, - long input_indx) +bfd_elf_link_record_local_dynamic_symbol (struct bfd_link_info *info, + bfd *input_bfd, + long input_indx) { bfd_size_type amt; struct elf_link_local_dynamic_entry *entry; @@ -836,7 +836,7 @@ _bfd_elf_merge_symbol (bfd *abfd, FIXME: Should we check type and size for protected symbol? */ if (ELF_ST_VISIBILITY (h->other) == STV_PROTECTED) - return _bfd_elf_link_record_dynamic_symbol (info, h); + return bfd_elf_link_record_dynamic_symbol (info, h); else return TRUE; } @@ -1275,7 +1275,7 @@ _bfd_elf_add_default_symbol (bfd *abfd, & (ELF_LINK_HASH_REF_REGULAR | ELF_LINK_HASH_DEF_REGULAR)) { - if (! _bfd_elf_link_record_dynamic_symbol (info, hi)) + if (! bfd_elf_link_record_dynamic_symbol (info, hi)) return FALSE; } } @@ -1433,7 +1433,7 @@ _bfd_elf_export_symbol (struct elf_link_hash_entry *h, void *data) if (!eif->verdefs) { doit: - if (! _bfd_elf_link_record_dynamic_symbol (eif->info, h)) + if (! bfd_elf_link_record_dynamic_symbol (eif->info, h)) { eif->failed = TRUE; return FALSE; @@ -2077,7 +2077,7 @@ _bfd_elf_fix_symbol_flags (struct elf_link_hash_entry *h, && ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0 || (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0)) { - if (! _bfd_elf_link_record_dynamic_symbol (eif->info, h)) + if (! bfd_elf_link_record_dynamic_symbol (eif->info, h)) { eif->failed = TRUE; return FALSE; @@ -3762,13 +3762,13 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) if (dynsym && h->dynindx == -1) { - if (! _bfd_elf_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) goto error_free_vers; if (h->weakdef != NULL && ! new_weakdef && h->weakdef->dynindx == -1) { - if (! _bfd_elf_link_record_dynamic_symbol (info, h->weakdef)) + if (! bfd_elf_link_record_dynamic_symbol (info, h->weakdef)) goto error_free_vers; } } @@ -3983,8 +3983,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) there as well. */ if (hlook->dynindx != -1 && h->dynindx == -1) { - if (! _bfd_elf_link_record_dynamic_symbol (info, - h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) goto error_return; } @@ -3995,8 +3994,7 @@ elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info) real definition and the weak definition. */ if (h->dynindx != -1 && hlook->dynindx == -1) { - if (! _bfd_elf_link_record_dynamic_symbol (info, - hlook)) + if (! bfd_elf_link_record_dynamic_symbol (info, hlook)) goto error_return; } break; @@ -5075,7 +5073,7 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, h->type = STT_OBJECT; h->verinfo.vertree = t; - if (! _bfd_elf_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; def.vd_version = VER_DEF_CURRENT; @@ -5358,3 +5356,3548 @@ bfd_elf_size_dynamic_sections (bfd *output_bfd, return TRUE; } + +/* Final phase of ELF linker. */ + +/* A structure we use to avoid passing large numbers of arguments. */ + +struct elf_final_link_info +{ + /* General link information. */ + struct bfd_link_info *info; + /* Output BFD. */ + bfd *output_bfd; + /* Symbol string table. */ + struct bfd_strtab_hash *symstrtab; + /* .dynsym section. */ + asection *dynsym_sec; + /* .hash section. */ + asection *hash_sec; + /* symbol version section (.gnu.version). */ + asection *symver_sec; + /* Buffer large enough to hold contents of any section. */ + bfd_byte *contents; + /* Buffer large enough to hold external relocs of any section. */ + void *external_relocs; + /* Buffer large enough to hold internal relocs of any section. */ + Elf_Internal_Rela *internal_relocs; + /* Buffer large enough to hold external local symbols of any input + BFD. */ + bfd_byte *external_syms; + /* And a buffer for symbol section indices. */ + Elf_External_Sym_Shndx *locsym_shndx; + /* Buffer large enough to hold internal local symbols of any input + BFD. */ + Elf_Internal_Sym *internal_syms; + /* Array large enough to hold a symbol index for each local symbol + of any input BFD. */ + long *indices; + /* Array large enough to hold a section pointer for each local + symbol of any input BFD. */ + asection **sections; + /* Buffer to hold swapped out symbols. */ + bfd_byte *symbuf; + /* And one for symbol section indices. */ + Elf_External_Sym_Shndx *symshndxbuf; + /* Number of swapped out symbols in buffer. */ + size_t symbuf_count; + /* Number of symbols which fit in symbuf. */ + size_t symbuf_size; + /* And same for symshndxbuf. */ + size_t shndxbuf_size; +}; + +/* This struct is used to pass information to elf_link_output_extsym. */ + +struct elf_outext_info +{ + bfd_boolean failed; + bfd_boolean localsyms; + struct elf_final_link_info *finfo; +}; + +/* When performing a relocatable link, the input relocations are + preserved. But, if they reference global symbols, the indices + referenced must be updated. Update all the relocations in + REL_HDR (there are COUNT of them), using the data in REL_HASH. */ + +static void +elf_link_adjust_relocs (bfd *abfd, + Elf_Internal_Shdr *rel_hdr, + unsigned int count, + struct elf_link_hash_entry **rel_hash) +{ + unsigned int i; + const struct elf_backend_data *bed = get_elf_backend_data (abfd); + bfd_byte *erela; + void (*swap_in) (bfd *, const bfd_byte *, Elf_Internal_Rela *); + void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *); + bfd_vma r_type_mask; + int r_sym_shift; + + if (rel_hdr->sh_entsize == bed->s->sizeof_rel) + { + swap_in = bed->s->swap_reloc_in; + swap_out = bed->s->swap_reloc_out; + } + else if (rel_hdr->sh_entsize == bed->s->sizeof_rela) + { + swap_in = bed->s->swap_reloca_in; + swap_out = bed->s->swap_reloca_out; + } + else + abort (); + + if (bed->s->int_rels_per_ext_rel > MAX_INT_RELS_PER_EXT_REL) + abort (); + + if (bed->s->arch_size == 32) + { + r_type_mask = 0xff; + r_sym_shift = 8; + } + else + { + r_type_mask = 0xffffffff; + r_sym_shift = 32; + } + + erela = rel_hdr->contents; + for (i = 0; i < count; i++, rel_hash++, erela += rel_hdr->sh_entsize) + { + Elf_Internal_Rela irela[MAX_INT_RELS_PER_EXT_REL]; + unsigned int j; + + if (*rel_hash == NULL) + continue; + + BFD_ASSERT ((*rel_hash)->indx >= 0); + + (*swap_in) (abfd, erela, irela); + for (j = 0; j < bed->s->int_rels_per_ext_rel; j++) + irela[j].r_info = ((bfd_vma) (*rel_hash)->indx << r_sym_shift + | (irela[j].r_info & r_type_mask)); + (*swap_out) (abfd, irela, erela); + } +} + +struct elf_link_sort_rela +{ + union { + bfd_vma offset; + bfd_vma sym_mask; + } u; + enum elf_reloc_type_class type; + /* We use this as an array of size int_rels_per_ext_rel. */ + Elf_Internal_Rela rela[1]; +}; + +static int +elf_link_sort_cmp1 (const void *A, const void *B) +{ + const struct elf_link_sort_rela *a = A; + const struct elf_link_sort_rela *b = B; + int relativea, relativeb; + + relativea = a->type == reloc_class_relative; + relativeb = b->type == reloc_class_relative; + + if (relativea < relativeb) + return 1; + if (relativea > relativeb) + return -1; + if ((a->rela->r_info & a->u.sym_mask) < (b->rela->r_info & b->u.sym_mask)) + return -1; + if ((a->rela->r_info & a->u.sym_mask) > (b->rela->r_info & b->u.sym_mask)) + return 1; + if (a->rela->r_offset < b->rela->r_offset) + return -1; + if (a->rela->r_offset > b->rela->r_offset) + return 1; + return 0; +} + +static int +elf_link_sort_cmp2 (const void *A, const void *B) +{ + const struct elf_link_sort_rela *a = A; + const struct elf_link_sort_rela *b = B; + int copya, copyb; + + if (a->u.offset < b->u.offset) + return -1; + if (a->u.offset > b->u.offset) + return 1; + copya = (a->type == reloc_class_copy) * 2 + (a->type == reloc_class_plt); + copyb = (b->type == reloc_class_copy) * 2 + (b->type == reloc_class_plt); + if (copya < copyb) + return -1; + if (copya > copyb) + return 1; + if (a->rela->r_offset < b->rela->r_offset) + return -1; + if (a->rela->r_offset > b->rela->r_offset) + return 1; + return 0; +} + +static size_t +elf_link_sort_relocs (bfd *abfd, struct bfd_link_info *info, asection **psec) +{ + asection *reldyn; + bfd_size_type count, size; + size_t i, ret, sort_elt, ext_size; + bfd_byte *sort, *s_non_relative, *p; + struct elf_link_sort_rela *sq; + const struct elf_backend_data *bed = get_elf_backend_data (abfd); + int i2e = bed->s->int_rels_per_ext_rel; + void (*swap_in) (bfd *, const bfd_byte *, Elf_Internal_Rela *); + void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *); + struct bfd_link_order *lo; + bfd_vma r_sym_mask; + + reldyn = bfd_get_section_by_name (abfd, ".rela.dyn"); + if (reldyn == NULL || reldyn->_raw_size == 0) + { + reldyn = bfd_get_section_by_name (abfd, ".rel.dyn"); + if (reldyn == NULL || reldyn->_raw_size == 0) + return 0; + ext_size = bed->s->sizeof_rel; + swap_in = bed->s->swap_reloc_in; + swap_out = bed->s->swap_reloc_out; + } + else + { + ext_size = bed->s->sizeof_rela; + swap_in = bed->s->swap_reloca_in; + swap_out = bed->s->swap_reloca_out; + } + count = reldyn->_raw_size / ext_size; + + size = 0; + for (lo = reldyn->link_order_head; lo != NULL; lo = lo->next) + if (lo->type == bfd_indirect_link_order) + { + asection *o = lo->u.indirect.section; + size += o->_raw_size; + } + + if (size != reldyn->_raw_size) + return 0; + + sort_elt = (sizeof (struct elf_link_sort_rela) + + (i2e - 1) * sizeof (Elf_Internal_Rela)); + sort = bfd_zmalloc (sort_elt * count); + if (sort == NULL) + { + (*info->callbacks->warning) + (info, _("Not enough memory to sort relocations"), 0, abfd, 0, 0); + return 0; + } + + if (bed->s->arch_size == 32) + r_sym_mask = ~(bfd_vma) 0xff; + else + r_sym_mask = ~(bfd_vma) 0xffffffff; + + for (lo = reldyn->link_order_head; lo != NULL; lo = lo->next) + if (lo->type == bfd_indirect_link_order) + { + bfd_byte *erel, *erelend; + asection *o = lo->u.indirect.section; + + erel = o->contents; + erelend = o->contents + o->_raw_size; + p = sort + o->output_offset / ext_size * sort_elt; + while (erel < erelend) + { + struct elf_link_sort_rela *s = (struct elf_link_sort_rela *) p; + (*swap_in) (abfd, erel, s->rela); + s->type = (*bed->elf_backend_reloc_type_class) (s->rela); + s->u.sym_mask = r_sym_mask; + p += sort_elt; + erel += ext_size; + } + } + + qsort (sort, count, sort_elt, elf_link_sort_cmp1); + + for (i = 0, p = sort; i < count; i++, p += sort_elt) + { + struct elf_link_sort_rela *s = (struct elf_link_sort_rela *) p; + if (s->type != reloc_class_relative) + break; + } + ret = i; + s_non_relative = p; + + sq = (struct elf_link_sort_rela *) s_non_relative; + for (; i < count; i++, p += sort_elt) + { + struct elf_link_sort_rela *sp = (struct elf_link_sort_rela *) p; + if (((sp->rela->r_info ^ sq->rela->r_info) & r_sym_mask) != 0) + sq = sp; + sp->u.offset = sq->rela->r_offset; + } + + qsort (s_non_relative, count - ret, sort_elt, elf_link_sort_cmp2); + + for (lo = reldyn->link_order_head; lo != NULL; lo = lo->next) + if (lo->type == bfd_indirect_link_order) + { + bfd_byte *erel, *erelend; + asection *o = lo->u.indirect.section; + + erel = o->contents; + erelend = o->contents + o->_raw_size; + p = sort + o->output_offset / ext_size * sort_elt; + while (erel < erelend) + { + struct elf_link_sort_rela *s = (struct elf_link_sort_rela *) p; + (*swap_out) (abfd, s->rela, erel); + p += sort_elt; + erel += ext_size; + } + } + + free (sort); + *psec = reldyn; + return ret; +} + +/* Flush the output symbols to the file. */ + +static bfd_boolean +elf_link_flush_output_syms (struct elf_final_link_info *finfo, + const struct elf_backend_data *bed) +{ + if (finfo->symbuf_count > 0) + { + Elf_Internal_Shdr *hdr; + file_ptr pos; + bfd_size_type amt; + + hdr = &elf_tdata (finfo->output_bfd)->symtab_hdr; + pos = hdr->sh_offset + hdr->sh_size; + amt = finfo->symbuf_count * bed->s->sizeof_sym; + if (bfd_seek (finfo->output_bfd, pos, SEEK_SET) != 0 + || bfd_bwrite (finfo->symbuf, amt, finfo->output_bfd) != amt) + return FALSE; + + hdr->sh_size += amt; + finfo->symbuf_count = 0; + } + + return TRUE; +} + +/* Add a symbol to the output symbol table. */ + +static bfd_boolean +elf_link_output_sym (struct elf_final_link_info *finfo, + const char *name, + Elf_Internal_Sym *elfsym, + asection *input_sec, + struct elf_link_hash_entry *h) +{ + bfd_byte *dest; + Elf_External_Sym_Shndx *destshndx; + bfd_boolean (*output_symbol_hook) + (struct bfd_link_info *, const char *, Elf_Internal_Sym *, asection *, + struct elf_link_hash_entry *); + const struct elf_backend_data *bed; + + bed = get_elf_backend_data (finfo->output_bfd); + output_symbol_hook = bed->elf_backend_link_output_symbol_hook; + if (output_symbol_hook != NULL) + { + if (! (*output_symbol_hook) (finfo->info, name, elfsym, input_sec, h)) + return FALSE; + } + + if (name == NULL || *name == '\0') + elfsym->st_name = 0; + else if (input_sec->flags & SEC_EXCLUDE) + elfsym->st_name = 0; + else + { + elfsym->st_name = (unsigned long) _bfd_stringtab_add (finfo->symstrtab, + name, TRUE, FALSE); + if (elfsym->st_name == (unsigned long) -1) + return FALSE; + } + + if (finfo->symbuf_count >= finfo->symbuf_size) + { + if (! elf_link_flush_output_syms (finfo, bed)) + return FALSE; + } + + dest = finfo->symbuf + finfo->symbuf_count * bed->s->sizeof_sym; + destshndx = finfo->symshndxbuf; + if (destshndx != NULL) + { + if (bfd_get_symcount (finfo->output_bfd) >= finfo->shndxbuf_size) + { + bfd_size_type amt; + + amt = finfo->shndxbuf_size * sizeof (Elf_External_Sym_Shndx); + finfo->symshndxbuf = destshndx = bfd_realloc (destshndx, amt * 2); + if (destshndx == NULL) + return FALSE; + memset ((char *) destshndx + amt, 0, amt); + finfo->shndxbuf_size *= 2; + } + destshndx += bfd_get_symcount (finfo->output_bfd); + } + + bed->s->swap_symbol_out (finfo->output_bfd, elfsym, dest, destshndx); + finfo->symbuf_count += 1; + bfd_get_symcount (finfo->output_bfd) += 1; + + return TRUE; +} + +/* For DSOs loaded in via a DT_NEEDED entry, emulate ld.so in + allowing an unsatisfied unversioned symbol in the DSO to match a + versioned symbol that would normally require an explicit version. + We also handle the case that a DSO references a hidden symbol + which may be satisfied by a versioned symbol in another DSO. */ + +static bfd_boolean +elf_link_check_versioned_symbol (struct bfd_link_info *info, + const struct elf_backend_data *bed, + struct elf_link_hash_entry *h) +{ + bfd *abfd; + struct elf_link_loaded_list *loaded; + + if (!is_elf_hash_table (info->hash)) + return FALSE; + + switch (h->root.type) + { + default: + abfd = NULL; + break; + + case bfd_link_hash_undefined: + case bfd_link_hash_undefweak: + abfd = h->root.u.undef.abfd; + if ((abfd->flags & DYNAMIC) == 0 + || elf_dyn_lib_class (abfd) != DYN_DT_NEEDED) + return FALSE; + break; + + case bfd_link_hash_defined: + case bfd_link_hash_defweak: + abfd = h->root.u.def.section->owner; + break; + + case bfd_link_hash_common: + abfd = h->root.u.c.p->section->owner; + break; + } + BFD_ASSERT (abfd != NULL); + + for (loaded = elf_hash_table (info)->loaded; + loaded != NULL; + loaded = loaded->next) + { + bfd *input; + Elf_Internal_Shdr *hdr; + bfd_size_type symcount; + bfd_size_type extsymcount; + bfd_size_type extsymoff; + Elf_Internal_Shdr *versymhdr; + Elf_Internal_Sym *isym; + Elf_Internal_Sym *isymend; + Elf_Internal_Sym *isymbuf; + Elf_External_Versym *ever; + Elf_External_Versym *extversym; + + input = loaded->abfd; + + /* We check each DSO for a possible hidden versioned definition. */ + if (input == abfd + || (input->flags & DYNAMIC) == 0 + || elf_dynversym (input) == 0) + continue; + + hdr = &elf_tdata (input)->dynsymtab_hdr; + + symcount = hdr->sh_size / bed->s->sizeof_sym; + if (elf_bad_symtab (input)) + { + extsymcount = symcount; + extsymoff = 0; + } + else + { + extsymcount = symcount - hdr->sh_info; + extsymoff = hdr->sh_info; + } + + if (extsymcount == 0) + continue; + + isymbuf = bfd_elf_get_elf_syms (input, hdr, extsymcount, extsymoff, + NULL, NULL, NULL); + if (isymbuf == NULL) + return FALSE; + + /* Read in any version definitions. */ + versymhdr = &elf_tdata (input)->dynversym_hdr; + extversym = bfd_malloc (versymhdr->sh_size); + if (extversym == NULL) + goto error_ret; + + if (bfd_seek (input, versymhdr->sh_offset, SEEK_SET) != 0 + || (bfd_bread (extversym, versymhdr->sh_size, input) + != versymhdr->sh_size)) + { + free (extversym); + error_ret: + free (isymbuf); + return FALSE; + } + + ever = extversym + extsymoff; + isymend = isymbuf + extsymcount; + for (isym = isymbuf; isym < isymend; isym++, ever++) + { + const char *name; + Elf_Internal_Versym iver; + unsigned short version_index; + + if (ELF_ST_BIND (isym->st_info) == STB_LOCAL + || isym->st_shndx == SHN_UNDEF) + continue; + + name = bfd_elf_string_from_elf_section (input, + hdr->sh_link, + isym->st_name); + if (strcmp (name, h->root.root.string) != 0) + continue; + + _bfd_elf_swap_versym_in (input, ever, &iver); + + if ((iver.vs_vers & VERSYM_HIDDEN) == 0) + { + /* If we have a non-hidden versioned sym, then it should + have provided a definition for the undefined sym. */ + abort (); + } + + version_index = iver.vs_vers & VERSYM_VERSION; + if (version_index == 1 || version_index == 2) + { + /* This is the base or first version. We can use it. */ + free (extversym); + free (isymbuf); + return TRUE; + } + } + + free (extversym); + free (isymbuf); + } + + return FALSE; +} + +/* Add an external symbol to the symbol table. This is called from + the hash table traversal routine. When generating a shared object, + we go through the symbol table twice. The first time we output + anything that might have been forced to local scope in a version + script. The second time we output the symbols that are still + global symbols. */ + +static bfd_boolean +elf_link_output_extsym (struct elf_link_hash_entry *h, void *data) +{ + struct elf_outext_info *eoinfo = data; + struct elf_final_link_info *finfo = eoinfo->finfo; + bfd_boolean strip; + Elf_Internal_Sym sym; + asection *input_sec; + const struct elf_backend_data *bed; + + if (h->root.type == bfd_link_hash_warning) + { + h = (struct elf_link_hash_entry *) h->root.u.i.link; + if (h->root.type == bfd_link_hash_new) + return TRUE; + } + + /* Decide whether to output this symbol in this pass. */ + if (eoinfo->localsyms) + { + if ((h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) + return TRUE; + } + else + { + if ((h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0) + return TRUE; + } + + bed = get_elf_backend_data (finfo->output_bfd); + + /* If we have an undefined symbol reference here then it must have + come from a shared library that is being linked in. (Undefined + references in regular files have already been handled). If we + are reporting errors for this situation then do so now. */ + if (h->root.type == bfd_link_hash_undefined + && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0 + && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0 + && ! elf_link_check_versioned_symbol (finfo->info, bed, h) + && finfo->info->unresolved_syms_in_shared_libs != RM_IGNORE) + { + if (! ((*finfo->info->callbacks->undefined_symbol) + (finfo->info, h->root.root.string, h->root.u.undef.abfd, + NULL, 0, finfo->info->unresolved_syms_in_shared_libs == RM_GENERATE_ERROR))) + { + eoinfo->failed = TRUE; + return FALSE; + } + } + + /* We should also warn if a forced local symbol is referenced from + shared libraries. */ + if (! finfo->info->relocatable + && (! finfo->info->shared) + && (h->elf_link_hash_flags + & (ELF_LINK_FORCED_LOCAL | ELF_LINK_HASH_REF_DYNAMIC | ELF_LINK_DYNAMIC_DEF | ELF_LINK_DYNAMIC_WEAK)) + == (ELF_LINK_FORCED_LOCAL | ELF_LINK_HASH_REF_DYNAMIC) + && ! elf_link_check_versioned_symbol (finfo->info, bed, h)) + { + (*_bfd_error_handler) + (_("%s: %s symbol `%s' in %s is referenced by DSO"), + bfd_get_filename (finfo->output_bfd), + ELF_ST_VISIBILITY (h->other) == STV_INTERNAL + ? "internal" + : ELF_ST_VISIBILITY (h->other) == STV_HIDDEN + ? "hidden" : "local", + h->root.root.string, + bfd_archive_filename (h->root.u.def.section->owner)); + eoinfo->failed = TRUE; + return FALSE; + } + + /* We don't want to output symbols that have never been mentioned by + a regular file, or that we have been told to strip. However, if + h->indx is set to -2, the symbol is used by a reloc and we must + output it. */ + if (h->indx == -2) + strip = FALSE; + else if (((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0 + || (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0) + && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0 + && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0) + strip = TRUE; + else if (finfo->info->strip == strip_all) + strip = TRUE; + else if (finfo->info->strip == strip_some + && bfd_hash_lookup (finfo->info->keep_hash, + h->root.root.string, FALSE, FALSE) == NULL) + strip = TRUE; + else if (finfo->info->strip_discarded + && (h->root.type == bfd_link_hash_defined + || h->root.type == bfd_link_hash_defweak) + && elf_discarded_section (h->root.u.def.section)) + strip = TRUE; + else + strip = FALSE; + + /* If we're stripping it, and it's not a dynamic symbol, there's + nothing else to do unless it is a forced local symbol. */ + if (strip + && h->dynindx == -1 + && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) + return TRUE; + + sym.st_value = 0; + sym.st_size = h->size; + sym.st_other = h->other; + if ((h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0) + sym.st_info = ELF_ST_INFO (STB_LOCAL, h->type); + else if (h->root.type == bfd_link_hash_undefweak + || h->root.type == bfd_link_hash_defweak) + sym.st_info = ELF_ST_INFO (STB_WEAK, h->type); + else + sym.st_info = ELF_ST_INFO (STB_GLOBAL, h->type); + + switch (h->root.type) + { + default: + case bfd_link_hash_new: + case bfd_link_hash_warning: + abort (); + return FALSE; + + case bfd_link_hash_undefined: + case bfd_link_hash_undefweak: + input_sec = bfd_und_section_ptr; + sym.st_shndx = SHN_UNDEF; + break; + + case bfd_link_hash_defined: + case bfd_link_hash_defweak: + { + input_sec = h->root.u.def.section; + if (input_sec->output_section != NULL) + { + sym.st_shndx = + _bfd_elf_section_from_bfd_section (finfo->output_bfd, + input_sec->output_section); + if (sym.st_shndx == SHN_BAD) + { + (*_bfd_error_handler) + (_("%s: could not find output section %s for input section %s"), + bfd_get_filename (finfo->output_bfd), + input_sec->output_section->name, + input_sec->name); + eoinfo->failed = TRUE; + return FALSE; + } + + /* ELF symbols in relocatable files are section relative, + but in nonrelocatable files they are virtual + addresses. */ + sym.st_value = h->root.u.def.value + input_sec->output_offset; + if (! finfo->info->relocatable) + { + sym.st_value += input_sec->output_section->vma; + if (h->type == STT_TLS) + { + /* STT_TLS symbols are relative to PT_TLS segment + base. */ + BFD_ASSERT (elf_hash_table (finfo->info)->tls_sec != NULL); + sym.st_value -= elf_hash_table (finfo->info)->tls_sec->vma; + } + } + } + else + { + BFD_ASSERT (input_sec->owner == NULL + || (input_sec->owner->flags & DYNAMIC) != 0); + sym.st_shndx = SHN_UNDEF; + input_sec = bfd_und_section_ptr; + } + } + break; + + case bfd_link_hash_common: + input_sec = h->root.u.c.p->section; + sym.st_shndx = SHN_COMMON; + sym.st_value = 1 << h->root.u.c.p->alignment_power; + break; + + case bfd_link_hash_indirect: + /* These symbols are created by symbol versioning. They point + to the decorated version of the name. For example, if the + symbol foo@@GNU_1.2 is the default, which should be used when + foo is used with no version, then we add an indirect symbol + foo which points to foo@@GNU_1.2. We ignore these symbols, + since the indirected symbol is already in the hash table. */ + return TRUE; + } + + /* Give the processor backend a chance to tweak the symbol value, + and also to finish up anything that needs to be done for this + symbol. FIXME: Not calling elf_backend_finish_dynamic_symbol for + forced local syms when non-shared is due to a historical quirk. */ + if ((h->dynindx != -1 + || (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0) + && ((finfo->info->shared + && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT + || h->root.type != bfd_link_hash_undefweak)) + || (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) + && elf_hash_table (finfo->info)->dynamic_sections_created) + { + if (! ((*bed->elf_backend_finish_dynamic_symbol) + (finfo->output_bfd, finfo->info, h, &sym))) + { + eoinfo->failed = TRUE; + return FALSE; + } + } + + /* If we are marking the symbol as undefined, and there are no + non-weak references to this symbol from a regular object, then + mark the symbol as weak undefined; if there are non-weak + references, mark the symbol as strong. We can't do this earlier, + because it might not be marked as undefined until the + finish_dynamic_symbol routine gets through with it. */ + if (sym.st_shndx == SHN_UNDEF + && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) != 0 + && (ELF_ST_BIND (sym.st_info) == STB_GLOBAL + || ELF_ST_BIND (sym.st_info) == STB_WEAK)) + { + int bindtype; + + if ((h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR_NONWEAK) != 0) + bindtype = STB_GLOBAL; + else + bindtype = STB_WEAK; + sym.st_info = ELF_ST_INFO (bindtype, ELF_ST_TYPE (sym.st_info)); + } + + /* If a non-weak symbol with non-default visibility is not defined + locally, it is a fatal error. */ + if (! finfo->info->relocatable + && ELF_ST_VISIBILITY (sym.st_other) != STV_DEFAULT + && ELF_ST_BIND (sym.st_info) != STB_WEAK + && h->root.type == bfd_link_hash_undefined + && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) + { + (*_bfd_error_handler) + (_("%s: %s symbol `%s' isn't defined"), + bfd_get_filename (finfo->output_bfd), + ELF_ST_VISIBILITY (sym.st_other) == STV_PROTECTED + ? "protected" + : ELF_ST_VISIBILITY (sym.st_other) == STV_INTERNAL + ? "internal" : "hidden", + h->root.root.string); + eoinfo->failed = TRUE; + return FALSE; + } + + /* If this symbol should be put in the .dynsym section, then put it + there now. We already know the symbol index. We also fill in + the entry in the .hash section. */ + if (h->dynindx != -1 + && elf_hash_table (finfo->info)->dynamic_sections_created) + { + size_t bucketcount; + size_t bucket; + size_t hash_entry_size; + bfd_byte *bucketpos; + bfd_vma chain; + bfd_byte *esym; + + sym.st_name = h->dynstr_index; + esym = finfo->dynsym_sec->contents + h->dynindx * bed->s->sizeof_sym; + bed->s->swap_symbol_out (finfo->output_bfd, &sym, esym, 0); + + bucketcount = elf_hash_table (finfo->info)->bucketcount; + bucket = h->elf_hash_value % bucketcount; + hash_entry_size + = elf_section_data (finfo->hash_sec)->this_hdr.sh_entsize; + bucketpos = ((bfd_byte *) finfo->hash_sec->contents + + (bucket + 2) * hash_entry_size); + chain = bfd_get (8 * hash_entry_size, finfo->output_bfd, bucketpos); + bfd_put (8 * hash_entry_size, finfo->output_bfd, h->dynindx, bucketpos); + bfd_put (8 * hash_entry_size, finfo->output_bfd, chain, + ((bfd_byte *) finfo->hash_sec->contents + + (bucketcount + 2 + h->dynindx) * hash_entry_size)); + + if (finfo->symver_sec != NULL && finfo->symver_sec->contents != NULL) + { + Elf_Internal_Versym iversym; + Elf_External_Versym *eversym; + + if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) + { + if (h->verinfo.verdef == NULL) + iversym.vs_vers = 0; + else + iversym.vs_vers = h->verinfo.verdef->vd_exp_refno + 1; + } + else + { + if (h->verinfo.vertree == NULL) + iversym.vs_vers = 1; + else + iversym.vs_vers = h->verinfo.vertree->vernum + 1; + } + + if ((h->elf_link_hash_flags & ELF_LINK_HIDDEN) != 0) + iversym.vs_vers |= VERSYM_HIDDEN; + + eversym = (Elf_External_Versym *) finfo->symver_sec->contents; + eversym += h->dynindx; + _bfd_elf_swap_versym_out (finfo->output_bfd, &iversym, eversym); + } + } + + /* If we're stripping it, then it was just a dynamic symbol, and + there's nothing else to do. */ + if (strip || (input_sec->flags & SEC_EXCLUDE) != 0) + return TRUE; + + h->indx = bfd_get_symcount (finfo->output_bfd); + + if (! elf_link_output_sym (finfo, h->root.root.string, &sym, input_sec, h)) + { + eoinfo->failed = TRUE; + return FALSE; + } + + return TRUE; +} + +static bfd_boolean +elf_section_ignore_discarded_relocs (asection *sec) +{ + const struct elf_backend_data *bed; + + switch (sec->sec_info_type) + { + case ELF_INFO_TYPE_STABS: + case ELF_INFO_TYPE_EH_FRAME: + return TRUE; + default: + break; + } + + bed = get_elf_backend_data (sec->owner); + if (bed->elf_backend_ignore_discarded_relocs != NULL + && (*bed->elf_backend_ignore_discarded_relocs) (sec)) + return TRUE; + + return FALSE; +} + +/* Link an input file into the linker output file. This function + handles all the sections and relocations of the input file at once. + This is so that we only have to read the local symbols once, and + don't have to keep them in memory. */ + +static bfd_boolean +elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd) +{ + bfd_boolean (*relocate_section) + (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, + Elf_Internal_Rela *, Elf_Internal_Sym *, asection **); + bfd *output_bfd; + Elf_Internal_Shdr *symtab_hdr; + size_t locsymcount; + size_t extsymoff; + Elf_Internal_Sym *isymbuf; + Elf_Internal_Sym *isym; + Elf_Internal_Sym *isymend; + long *pindex; + asection **ppsection; + asection *o; + const struct elf_backend_data *bed; + bfd_boolean emit_relocs; + struct elf_link_hash_entry **sym_hashes; + + output_bfd = finfo->output_bfd; + bed = get_elf_backend_data (output_bfd); + relocate_section = bed->elf_backend_relocate_section; + + /* If this is a dynamic object, we don't want to do anything here: + we don't want the local symbols, and we don't want the section + contents. */ + if ((input_bfd->flags & DYNAMIC) != 0) + return TRUE; + + emit_relocs = (finfo->info->relocatable + || finfo->info->emitrelocations + || bed->elf_backend_emit_relocs); + + symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; + if (elf_bad_symtab (input_bfd)) + { + locsymcount = symtab_hdr->sh_size / bed->s->sizeof_sym; + extsymoff = 0; + } + else + { + locsymcount = symtab_hdr->sh_info; + extsymoff = symtab_hdr->sh_info; + } + + /* Read the local symbols. */ + isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; + if (isymbuf == NULL && locsymcount != 0) + { + isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, locsymcount, 0, + finfo->internal_syms, + finfo->external_syms, + finfo->locsym_shndx); + if (isymbuf == NULL) + return FALSE; + } + + /* Find local symbol sections and adjust values of symbols in + SEC_MERGE sections. Write out those local symbols we know are + going into the output file. */ + isymend = isymbuf + locsymcount; + for (isym = isymbuf, pindex = finfo->indices, ppsection = finfo->sections; + isym < isymend; + isym++, pindex++, ppsection++) + { + asection *isec; + const char *name; + Elf_Internal_Sym osym; + + *pindex = -1; + + if (elf_bad_symtab (input_bfd)) + { + if (ELF_ST_BIND (isym->st_info) != STB_LOCAL) + { + *ppsection = NULL; + continue; + } + } + + if (isym->st_shndx == SHN_UNDEF) + isec = bfd_und_section_ptr; + else if (isym->st_shndx < SHN_LORESERVE + || isym->st_shndx > SHN_HIRESERVE) + { + isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx); + if (isec + && isec->sec_info_type == ELF_INFO_TYPE_MERGE + && ELF_ST_TYPE (isym->st_info) != STT_SECTION) + isym->st_value = + _bfd_merged_section_offset (output_bfd, &isec, + elf_section_data (isec)->sec_info, + isym->st_value, 0); + } + else if (isym->st_shndx == SHN_ABS) + isec = bfd_abs_section_ptr; + else if (isym->st_shndx == SHN_COMMON) + isec = bfd_com_section_ptr; + else + { + /* Who knows? */ + isec = NULL; + } + + *ppsection = isec; + + /* Don't output the first, undefined, symbol. */ + if (ppsection == finfo->sections) + continue; + + if (ELF_ST_TYPE (isym->st_info) == STT_SECTION) + { + /* We never output section symbols. Instead, we use the + section symbol of the corresponding section in the output + file. */ + continue; + } + + /* If we are stripping all symbols, we don't want to output this + one. */ + if (finfo->info->strip == strip_all) + continue; + + /* If we are discarding all local symbols, we don't want to + output this one. If we are generating a relocatable output + file, then some of the local symbols may be required by + relocs; we output them below as we discover that they are + needed. */ + if (finfo->info->discard == discard_all) + continue; + + /* If this symbol is defined in a section which we are + discarding, we don't need to keep it, but note that + linker_mark is only reliable for sections that have contents. + For the benefit of the MIPS ELF linker, we check SEC_EXCLUDE + as well as linker_mark. */ + if ((isym->st_shndx < SHN_LORESERVE || isym->st_shndx > SHN_HIRESERVE) + && isec != NULL + && ((! isec->linker_mark && (isec->flags & SEC_HAS_CONTENTS) != 0) + || (! finfo->info->relocatable + && (isec->flags & SEC_EXCLUDE) != 0))) + continue; + + /* Get the name of the symbol. */ + name = bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, + isym->st_name); + if (name == NULL) + return FALSE; + + /* See if we are discarding symbols with this name. */ + if ((finfo->info->strip == strip_some + && (bfd_hash_lookup (finfo->info->keep_hash, name, FALSE, FALSE) + == NULL)) + || (((finfo->info->discard == discard_sec_merge + && (isec->flags & SEC_MERGE) && ! finfo->info->relocatable) + || finfo->info->discard == discard_l) + && bfd_is_local_label_name (input_bfd, name))) + continue; + + /* If we get here, we are going to output this symbol. */ + + osym = *isym; + + /* Adjust the section index for the output file. */ + osym.st_shndx = _bfd_elf_section_from_bfd_section (output_bfd, + isec->output_section); + if (osym.st_shndx == SHN_BAD) + return FALSE; + + *pindex = bfd_get_symcount (output_bfd); + + /* ELF symbols in relocatable files are section relative, but + in executable files they are virtual addresses. Note that + this code assumes that all ELF sections have an associated + BFD section with a reasonable value for output_offset; below + we assume that they also have a reasonable value for + output_section. Any special sections must be set up to meet + these requirements. */ + osym.st_value += isec->output_offset; + if (! finfo->info->relocatable) + { + osym.st_value += isec->output_section->vma; + if (ELF_ST_TYPE (osym.st_info) == STT_TLS) + { + /* STT_TLS symbols are relative to PT_TLS segment base. */ + BFD_ASSERT (elf_hash_table (finfo->info)->tls_sec != NULL); + osym.st_value -= elf_hash_table (finfo->info)->tls_sec->vma; + } + } + + if (! elf_link_output_sym (finfo, name, &osym, isec, NULL)) + return FALSE; + } + + /* Relocate the contents of each section. */ + sym_hashes = elf_sym_hashes (input_bfd); + for (o = input_bfd->sections; o != NULL; o = o->next) + { + bfd_byte *contents; + + if (! o->linker_mark) + { + /* This section was omitted from the link. */ + continue; + } + + if ((o->flags & SEC_HAS_CONTENTS) == 0 + || (o->_raw_size == 0 && (o->flags & SEC_RELOC) == 0)) + continue; + + if ((o->flags & SEC_LINKER_CREATED) != 0) + { + /* Section was created by _bfd_elf_link_create_dynamic_sections + or somesuch. */ + continue; + } + + /* Get the contents of the section. They have been cached by a + relaxation routine. Note that o is a section in an input + file, so the contents field will not have been set by any of + the routines which work on output files. */ + if (elf_section_data (o)->this_hdr.contents != NULL) + contents = elf_section_data (o)->this_hdr.contents; + else + { + contents = finfo->contents; + if (! bfd_get_section_contents (input_bfd, o, contents, 0, + o->_raw_size)) + return FALSE; + } + + if ((o->flags & SEC_RELOC) != 0) + { + Elf_Internal_Rela *internal_relocs; + bfd_vma r_type_mask; + int r_sym_shift; + + /* Get the swapped relocs. */ + internal_relocs + = _bfd_elf_link_read_relocs (input_bfd, o, finfo->external_relocs, + finfo->internal_relocs, FALSE); + if (internal_relocs == NULL + && o->reloc_count > 0) + return FALSE; + + if (bed->s->arch_size == 32) + { + r_type_mask = 0xff; + r_sym_shift = 8; + } + else + { + r_type_mask = 0xffffffff; + r_sym_shift = 32; + } + + /* Run through the relocs looking for any against symbols + from discarded sections and section symbols from + removed link-once sections. Complain about relocs + against discarded sections. Zero relocs against removed + link-once sections. Preserve debug information as much + as we can. */ + if (!elf_section_ignore_discarded_relocs (o)) + { + Elf_Internal_Rela *rel, *relend; + + rel = internal_relocs; + relend = rel + o->reloc_count * bed->s->int_rels_per_ext_rel; + for ( ; rel < relend; rel++) + { + unsigned long r_symndx = rel->r_info >> r_sym_shift; + asection *sec; + + if (r_symndx >= locsymcount + || (elf_bad_symtab (input_bfd) + && finfo->sections[r_symndx] == NULL)) + { + struct elf_link_hash_entry *h; + + h = sym_hashes[r_symndx - extsymoff]; + while (h->root.type == bfd_link_hash_indirect + || h->root.type == bfd_link_hash_warning) + h = (struct elf_link_hash_entry *) h->root.u.i.link; + + /* Complain if the definition comes from a + discarded section. */ + sec = h->root.u.def.section; + if ((h->root.type == bfd_link_hash_defined + || h->root.type == bfd_link_hash_defweak) + && elf_discarded_section (sec)) + { + if ((o->flags & SEC_DEBUGGING) != 0) + { + BFD_ASSERT (r_symndx != 0); + /* Try to preserve debug information. */ + if ((o->flags & SEC_DEBUGGING) != 0 + && sec->kept_section != NULL + && sec->_raw_size == sec->kept_section->_raw_size) + h->root.u.def.section + = sec->kept_section; + else + memset (rel, 0, sizeof (*rel)); + } + else + finfo->info->callbacks->error_handler + (LD_DEFINITION_IN_DISCARDED_SECTION, + _("%T: discarded in section `%s' from %s\n"), + h->root.root.string, + h->root.root.string, + h->root.u.def.section->name, + bfd_archive_filename (h->root.u.def.section->owner)); + } + } + else + { + sec = finfo->sections[r_symndx]; + + if (sec != NULL && elf_discarded_section (sec)) + { + if ((o->flags & SEC_DEBUGGING) != 0 + || (sec->flags & SEC_LINK_ONCE) != 0) + { + BFD_ASSERT (r_symndx != 0); + /* Try to preserve debug information. */ + if ((o->flags & SEC_DEBUGGING) != 0 + && sec->kept_section != NULL + && sec->_raw_size == sec->kept_section->_raw_size) + finfo->sections[r_symndx] + = sec->kept_section; + else + { + rel->r_info &= r_type_mask; + rel->r_addend = 0; + } + } + else + { + static int count; + int ok; + char *buf; + + ok = asprintf (&buf, "local symbol %d", + count++); + if (ok <= 0) + buf = (char *) "local symbol"; + finfo->info->callbacks->error_handler + (LD_DEFINITION_IN_DISCARDED_SECTION, + _("%T: discarded in section `%s' from %s\n"), + buf, buf, sec->name, + bfd_archive_filename (input_bfd)); + if (ok != -1) + free (buf); + } + } + } + } + } + + /* Relocate the section by invoking a back end routine. + + The back end routine is responsible for adjusting the + section contents as necessary, and (if using Rela relocs + and generating a relocatable output file) adjusting the + reloc addend as necessary. + + The back end routine does not have to worry about setting + the reloc address or the reloc symbol index. + + The back end routine is given a pointer to the swapped in + internal symbols, and can access the hash table entries + for the external symbols via elf_sym_hashes (input_bfd). + + When generating relocatable output, the back end routine + must handle STB_LOCAL/STT_SECTION symbols specially. The + output symbol is going to be a section symbol + corresponding to the output section, which will require + the addend to be adjusted. */ + + if (! (*relocate_section) (output_bfd, finfo->info, + input_bfd, o, contents, + internal_relocs, + isymbuf, + finfo->sections)) + return FALSE; + + if (emit_relocs) + { + Elf_Internal_Rela *irela; + Elf_Internal_Rela *irelaend; + bfd_vma last_offset; + struct elf_link_hash_entry **rel_hash; + Elf_Internal_Shdr *input_rel_hdr, *input_rel_hdr2; + unsigned int next_erel; + bfd_boolean (*reloc_emitter) + (bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *); + bfd_boolean rela_normal; + + input_rel_hdr = &elf_section_data (o)->rel_hdr; + rela_normal = (bed->rela_normal + && (input_rel_hdr->sh_entsize + == bed->s->sizeof_rela)); + + /* Adjust the reloc addresses and symbol indices. */ + + irela = internal_relocs; + irelaend = irela + o->reloc_count * bed->s->int_rels_per_ext_rel; + rel_hash = (elf_section_data (o->output_section)->rel_hashes + + elf_section_data (o->output_section)->rel_count + + elf_section_data (o->output_section)->rel_count2); + last_offset = o->output_offset; + if (!finfo->info->relocatable) + last_offset += o->output_section->vma; + for (next_erel = 0; irela < irelaend; irela++, next_erel++) + { + unsigned long r_symndx; + asection *sec; + Elf_Internal_Sym sym; + + if (next_erel == bed->s->int_rels_per_ext_rel) + { + rel_hash++; + next_erel = 0; + } + + irela->r_offset = _bfd_elf_section_offset (output_bfd, + finfo->info, o, + irela->r_offset); + if (irela->r_offset >= (bfd_vma) -2) + { + /* This is a reloc for a deleted entry or somesuch. + Turn it into an R_*_NONE reloc, at the same + offset as the last reloc. elf_eh_frame.c and + elf_bfd_discard_info rely on reloc offsets + being ordered. */ + irela->r_offset = last_offset; + irela->r_info = 0; + irela->r_addend = 0; + continue; + } + + irela->r_offset += o->output_offset; + + /* Relocs in an executable have to be virtual addresses. */ + if (!finfo->info->relocatable) + irela->r_offset += o->output_section->vma; + + last_offset = irela->r_offset; + + r_symndx = irela->r_info >> r_sym_shift; + if (r_symndx == STN_UNDEF) + continue; + + if (r_symndx >= locsymcount + || (elf_bad_symtab (input_bfd) + && finfo->sections[r_symndx] == NULL)) + { + struct elf_link_hash_entry *rh; + unsigned long indx; + + /* This is a reloc against a global symbol. We + have not yet output all the local symbols, so + we do not know the symbol index of any global + symbol. We set the rel_hash entry for this + reloc to point to the global hash table entry + for this symbol. The symbol index is then + set at the end of elf_bfd_final_link. */ + indx = r_symndx - extsymoff; + rh = elf_sym_hashes (input_bfd)[indx]; + while (rh->root.type == bfd_link_hash_indirect + || rh->root.type == bfd_link_hash_warning) + rh = (struct elf_link_hash_entry *) rh->root.u.i.link; + + /* Setting the index to -2 tells + elf_link_output_extsym that this symbol is + used by a reloc. */ + BFD_ASSERT (rh->indx < 0); + rh->indx = -2; + + *rel_hash = rh; + + continue; + } + + /* This is a reloc against a local symbol. */ + + *rel_hash = NULL; + sym = isymbuf[r_symndx]; + sec = finfo->sections[r_symndx]; + if (ELF_ST_TYPE (sym.st_info) == STT_SECTION) + { + /* I suppose the backend ought to fill in the + section of any STT_SECTION symbol against a + processor specific section. If we have + discarded a section, the output_section will + be the absolute section. */ + if (bfd_is_abs_section (sec) + || (sec != NULL + && bfd_is_abs_section (sec->output_section))) + r_symndx = 0; + else if (sec == NULL || sec->owner == NULL) + { + bfd_set_error (bfd_error_bad_value); + return FALSE; + } + else + { + r_symndx = sec->output_section->target_index; + BFD_ASSERT (r_symndx != 0); + } + + /* Adjust the addend according to where the + section winds up in the output section. */ + if (rela_normal) + irela->r_addend += sec->output_offset; + } + else + { + if (finfo->indices[r_symndx] == -1) + { + unsigned long shlink; + const char *name; + asection *osec; + + if (finfo->info->strip == strip_all) + { + /* You can't do ld -r -s. */ + bfd_set_error (bfd_error_invalid_operation); + return FALSE; + } + + /* This symbol was skipped earlier, but + since it is needed by a reloc, we + must output it now. */ + shlink = symtab_hdr->sh_link; + name = (bfd_elf_string_from_elf_section + (input_bfd, shlink, sym.st_name)); + if (name == NULL) + return FALSE; + + osec = sec->output_section; + sym.st_shndx = + _bfd_elf_section_from_bfd_section (output_bfd, + osec); + if (sym.st_shndx == SHN_BAD) + return FALSE; + + sym.st_value += sec->output_offset; + if (! finfo->info->relocatable) + { + sym.st_value += osec->vma; + if (ELF_ST_TYPE (sym.st_info) == STT_TLS) + { + /* STT_TLS symbols are relative to PT_TLS + segment base. */ + BFD_ASSERT (elf_hash_table (finfo->info) + ->tls_sec != NULL); + sym.st_value -= (elf_hash_table (finfo->info) + ->tls_sec->vma); + } + } + + finfo->indices[r_symndx] + = bfd_get_symcount (output_bfd); + + if (! elf_link_output_sym (finfo, name, &sym, sec, + NULL)) + return FALSE; + } + + r_symndx = finfo->indices[r_symndx]; + } + + irela->r_info = ((bfd_vma) r_symndx << r_sym_shift + | (irela->r_info & r_type_mask)); + } + + /* Swap out the relocs. */ + if (bed->elf_backend_emit_relocs + && !(finfo->info->relocatable + || finfo->info->emitrelocations)) + reloc_emitter = bed->elf_backend_emit_relocs; + else + reloc_emitter = _bfd_elf_link_output_relocs; + + if (input_rel_hdr->sh_size != 0 + && ! (*reloc_emitter) (output_bfd, o, input_rel_hdr, + internal_relocs)) + return FALSE; + + input_rel_hdr2 = elf_section_data (o)->rel_hdr2; + if (input_rel_hdr2 && input_rel_hdr2->sh_size != 0) + { + internal_relocs += (NUM_SHDR_ENTRIES (input_rel_hdr) + * bed->s->int_rels_per_ext_rel); + if (! (*reloc_emitter) (output_bfd, o, input_rel_hdr2, + internal_relocs)) + return FALSE; + } + } + } + + /* Write out the modified section contents. */ + if (bed->elf_backend_write_section + && (*bed->elf_backend_write_section) (output_bfd, o, contents)) + { + /* Section written out. */ + } + else switch (o->sec_info_type) + { + case ELF_INFO_TYPE_STABS: + if (! (_bfd_write_section_stabs + (output_bfd, + &elf_hash_table (finfo->info)->stab_info, + o, &elf_section_data (o)->sec_info, contents))) + return FALSE; + break; + case ELF_INFO_TYPE_MERGE: + if (! _bfd_write_merged_section (output_bfd, o, + elf_section_data (o)->sec_info)) + return FALSE; + break; + case ELF_INFO_TYPE_EH_FRAME: + { + if (! _bfd_elf_write_section_eh_frame (output_bfd, finfo->info, + o, contents)) + return FALSE; + } + break; + default: + { + bfd_size_type sec_size; + + sec_size = (o->_cooked_size != 0 ? o->_cooked_size : o->_raw_size); + if (! (o->flags & SEC_EXCLUDE) + && ! bfd_set_section_contents (output_bfd, o->output_section, + contents, + (file_ptr) o->output_offset, + sec_size)) + return FALSE; + } + break; + } + } + + return TRUE; +} + +/* Generate a reloc when linking an ELF file. This is a reloc + requested by the linker, and does come from any input file. This + is used to build constructor and destructor tables when linking + with -Ur. */ + +static bfd_boolean +elf_reloc_link_order (bfd *output_bfd, + struct bfd_link_info *info, + asection *output_section, + struct bfd_link_order *link_order) +{ + reloc_howto_type *howto; + long indx; + bfd_vma offset; + bfd_vma addend; + struct elf_link_hash_entry **rel_hash_ptr; + Elf_Internal_Shdr *rel_hdr; + const struct elf_backend_data *bed = get_elf_backend_data (output_bfd); + Elf_Internal_Rela irel[MAX_INT_RELS_PER_EXT_REL]; + bfd_byte *erel; + unsigned int i; + + howto = bfd_reloc_type_lookup (output_bfd, link_order->u.reloc.p->reloc); + if (howto == NULL) + { + bfd_set_error (bfd_error_bad_value); + return FALSE; + } + + addend = link_order->u.reloc.p->addend; + + /* Figure out the symbol index. */ + rel_hash_ptr = (elf_section_data (output_section)->rel_hashes + + elf_section_data (output_section)->rel_count + + elf_section_data (output_section)->rel_count2); + if (link_order->type == bfd_section_reloc_link_order) + { + indx = link_order->u.reloc.p->u.section->target_index; + BFD_ASSERT (indx != 0); + *rel_hash_ptr = NULL; + } + else + { + struct elf_link_hash_entry *h; + + /* Treat a reloc against a defined symbol as though it were + actually against the section. */ + h = ((struct elf_link_hash_entry *) + bfd_wrapped_link_hash_lookup (output_bfd, info, + link_order->u.reloc.p->u.name, + FALSE, FALSE, TRUE)); + if (h != NULL + && (h->root.type == bfd_link_hash_defined + || h->root.type == bfd_link_hash_defweak)) + { + asection *section; + + section = h->root.u.def.section; + indx = section->output_section->target_index; + *rel_hash_ptr = NULL; + /* It seems that we ought to add the symbol value to the + addend here, but in practice it has already been added + because it was passed to constructor_callback. */ + addend += section->output_section->vma + section->output_offset; + } + else if (h != NULL) + { + /* Setting the index to -2 tells elf_link_output_extsym that + this symbol is used by a reloc. */ + h->indx = -2; + *rel_hash_ptr = h; + indx = 0; + } + else + { + if (! ((*info->callbacks->unattached_reloc) + (info, link_order->u.reloc.p->u.name, NULL, NULL, 0))) + return FALSE; + indx = 0; + } + } + + /* If this is an inplace reloc, we must write the addend into the + object file. */ + if (howto->partial_inplace && addend != 0) + { + bfd_size_type size; + bfd_reloc_status_type rstat; + bfd_byte *buf; + bfd_boolean ok; + const char *sym_name; + + size = bfd_get_reloc_size (howto); + buf = bfd_zmalloc (size); + if (buf == NULL) + return FALSE; + rstat = _bfd_relocate_contents (howto, output_bfd, addend, buf); + switch (rstat) + { + case bfd_reloc_ok: + break; + + default: + case bfd_reloc_outofrange: + abort (); + + case bfd_reloc_overflow: + if (link_order->type == bfd_section_reloc_link_order) + sym_name = bfd_section_name (output_bfd, + link_order->u.reloc.p->u.section); + else + sym_name = link_order->u.reloc.p->u.name; + if (! ((*info->callbacks->reloc_overflow) + (info, sym_name, howto->name, addend, NULL, NULL, 0))) + { + free (buf); + return FALSE; + } + break; + } + ok = bfd_set_section_contents (output_bfd, output_section, buf, + link_order->offset, size); + free (buf); + if (! ok) + return FALSE; + } + + /* The address of a reloc is relative to the section in a + relocatable file, and is a virtual address in an executable + file. */ + offset = link_order->offset; + if (! info->relocatable) + offset += output_section->vma; + + for (i = 0; i < bed->s->int_rels_per_ext_rel; i++) + { + irel[i].r_offset = offset; + irel[i].r_info = 0; + irel[i].r_addend = 0; + } + if (bed->s->arch_size == 32) + irel[0].r_info = ELF32_R_INFO (indx, howto->type); + else + irel[0].r_info = ELF64_R_INFO (indx, howto->type); + + rel_hdr = &elf_section_data (output_section)->rel_hdr; + erel = rel_hdr->contents; + if (rel_hdr->sh_type == SHT_REL) + { + erel += (elf_section_data (output_section)->rel_count + * bed->s->sizeof_rel); + (*bed->s->swap_reloc_out) (output_bfd, irel, erel); + } + else + { + irel[0].r_addend = addend; + erel += (elf_section_data (output_section)->rel_count + * bed->s->sizeof_rela); + (*bed->s->swap_reloca_out) (output_bfd, irel, erel); + } + + ++elf_section_data (output_section)->rel_count; + + return TRUE; +} + +/* Do the final step of an ELF link. */ + +bfd_boolean +bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info) +{ + bfd_boolean dynamic; + bfd_boolean emit_relocs; + bfd *dynobj; + struct elf_final_link_info finfo; + register asection *o; + register struct bfd_link_order *p; + register bfd *sub; + bfd_size_type max_contents_size; + bfd_size_type max_external_reloc_size; + bfd_size_type max_internal_reloc_count; + bfd_size_type max_sym_count; + bfd_size_type max_sym_shndx_count; + file_ptr off; + Elf_Internal_Sym elfsym; + unsigned int i; + Elf_Internal_Shdr *symtab_hdr; + Elf_Internal_Shdr *symtab_shndx_hdr; + Elf_Internal_Shdr *symstrtab_hdr; + const struct elf_backend_data *bed = get_elf_backend_data (abfd); + struct elf_outext_info eoinfo; + bfd_boolean merged; + size_t relativecount = 0; + asection *reldyn = 0; + bfd_size_type amt; + + if (! is_elf_hash_table (info->hash)) + return FALSE; + + if (info->shared) + abfd->flags |= DYNAMIC; + + dynamic = elf_hash_table (info)->dynamic_sections_created; + dynobj = elf_hash_table (info)->dynobj; + + emit_relocs = (info->relocatable + || info->emitrelocations + || bed->elf_backend_emit_relocs); + + finfo.info = info; + finfo.output_bfd = abfd; + finfo.symstrtab = _bfd_elf_stringtab_init (); + if (finfo.symstrtab == NULL) + return FALSE; + + if (! dynamic) + { + finfo.dynsym_sec = NULL; + finfo.hash_sec = NULL; + finfo.symver_sec = NULL; + } + else + { + finfo.dynsym_sec = bfd_get_section_by_name (dynobj, ".dynsym"); + finfo.hash_sec = bfd_get_section_by_name (dynobj, ".hash"); + BFD_ASSERT (finfo.dynsym_sec != NULL && finfo.hash_sec != NULL); + finfo.symver_sec = bfd_get_section_by_name (dynobj, ".gnu.version"); + /* Note that it is OK if symver_sec is NULL. */ + } + + finfo.contents = NULL; + finfo.external_relocs = NULL; + finfo.internal_relocs = NULL; + finfo.external_syms = NULL; + finfo.locsym_shndx = NULL; + finfo.internal_syms = NULL; + finfo.indices = NULL; + finfo.sections = NULL; + finfo.symbuf = NULL; + finfo.symshndxbuf = NULL; + finfo.symbuf_count = 0; + finfo.shndxbuf_size = 0; + + /* Count up the number of relocations we will output for each output + section, so that we know the sizes of the reloc sections. We + also figure out some maximum sizes. */ + max_contents_size = 0; + max_external_reloc_size = 0; + max_internal_reloc_count = 0; + max_sym_count = 0; + max_sym_shndx_count = 0; + merged = FALSE; + for (o = abfd->sections; o != NULL; o = o->next) + { + struct bfd_elf_section_data *esdo = elf_section_data (o); + o->reloc_count = 0; + + for (p = o->link_order_head; p != NULL; p = p->next) + { + unsigned int reloc_count = 0; + struct bfd_elf_section_data *esdi = NULL; + unsigned int *rel_count1; + + if (p->type == bfd_section_reloc_link_order + || p->type == bfd_symbol_reloc_link_order) + reloc_count = 1; + else if (p->type == bfd_indirect_link_order) + { + asection *sec; + + sec = p->u.indirect.section; + esdi = elf_section_data (sec); + + /* Mark all sections which are to be included in the + link. This will normally be every section. We need + to do this so that we can identify any sections which + the linker has decided to not include. */ + sec->linker_mark = TRUE; + + if (sec->flags & SEC_MERGE) + merged = TRUE; + + if (info->relocatable || info->emitrelocations) + reloc_count = sec->reloc_count; + else if (bed->elf_backend_count_relocs) + { + Elf_Internal_Rela * relocs; + + relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, + info->keep_memory); + + reloc_count = (*bed->elf_backend_count_relocs) (sec, relocs); + + if (elf_section_data (o)->relocs != relocs) + free (relocs); + } + + if (sec->_raw_size > max_contents_size) + max_contents_size = sec->_raw_size; + if (sec->_cooked_size > max_contents_size) + max_contents_size = sec->_cooked_size; + + /* We are interested in just local symbols, not all + symbols. */ + if (bfd_get_flavour (sec->owner) == bfd_target_elf_flavour + && (sec->owner->flags & DYNAMIC) == 0) + { + size_t sym_count; + + if (elf_bad_symtab (sec->owner)) + sym_count = (elf_tdata (sec->owner)->symtab_hdr.sh_size + / bed->s->sizeof_sym); + else + sym_count = elf_tdata (sec->owner)->symtab_hdr.sh_info; + + if (sym_count > max_sym_count) + max_sym_count = sym_count; + + if (sym_count > max_sym_shndx_count + && elf_symtab_shndx (sec->owner) != 0) + max_sym_shndx_count = sym_count; + + if ((sec->flags & SEC_RELOC) != 0) + { + size_t ext_size; + + ext_size = elf_section_data (sec)->rel_hdr.sh_size; + if (ext_size > max_external_reloc_size) + max_external_reloc_size = ext_size; + if (sec->reloc_count > max_internal_reloc_count) + max_internal_reloc_count = sec->reloc_count; + } + } + } + + if (reloc_count == 0) + continue; + + o->reloc_count += reloc_count; + + /* MIPS may have a mix of REL and RELA relocs on sections. + To support this curious ABI we keep reloc counts in + elf_section_data too. We must be careful to add the + relocations from the input section to the right output + count. FIXME: Get rid of one count. We have + o->reloc_count == esdo->rel_count + esdo->rel_count2. */ + rel_count1 = &esdo->rel_count; + if (esdi != NULL) + { + bfd_boolean same_size; + bfd_size_type entsize1; + + entsize1 = esdi->rel_hdr.sh_entsize; + BFD_ASSERT (entsize1 == bed->s->sizeof_rel + || entsize1 == bed->s->sizeof_rela); + same_size = !o->use_rela_p == (entsize1 == bed->s->sizeof_rel); + + if (!same_size) + rel_count1 = &esdo->rel_count2; + + if (esdi->rel_hdr2 != NULL) + { + bfd_size_type entsize2 = esdi->rel_hdr2->sh_entsize; + unsigned int alt_count; + unsigned int *rel_count2; + + BFD_ASSERT (entsize2 != entsize1 + && (entsize2 == bed->s->sizeof_rel + || entsize2 == bed->s->sizeof_rela)); + + rel_count2 = &esdo->rel_count2; + if (!same_size) + rel_count2 = &esdo->rel_count; + + /* The following is probably too simplistic if the + backend counts output relocs unusually. */ + BFD_ASSERT (bed->elf_backend_count_relocs == NULL); + alt_count = NUM_SHDR_ENTRIES (esdi->rel_hdr2); + *rel_count2 += alt_count; + reloc_count -= alt_count; + } + } + *rel_count1 += reloc_count; + } + + if (o->reloc_count > 0) + o->flags |= SEC_RELOC; + else + { + /* Explicitly clear the SEC_RELOC flag. The linker tends to + set it (this is probably a bug) and if it is set + assign_section_numbers will create a reloc section. */ + o->flags &=~ SEC_RELOC; + } + + /* If the SEC_ALLOC flag is not set, force the section VMA to + zero. This is done in elf_fake_sections as well, but forcing + the VMA to 0 here will ensure that relocs against these + sections are handled correctly. */ + if ((o->flags & SEC_ALLOC) == 0 + && ! o->user_set_vma) + o->vma = 0; + } + + if (! info->relocatable && merged) + elf_link_hash_traverse (elf_hash_table (info), + _bfd_elf_link_sec_merge_syms, abfd); + + /* Figure out the file positions for everything but the symbol table + and the relocs. We set symcount to force assign_section_numbers + to create a symbol table. */ + bfd_get_symcount (abfd) = info->strip == strip_all ? 0 : 1; + BFD_ASSERT (! abfd->output_has_begun); + if (! _bfd_elf_compute_section_file_positions (abfd, info)) + goto error_return; + + /* That created the reloc sections. Set their sizes, and assign + them file positions, and allocate some buffers. */ + for (o = abfd->sections; o != NULL; o = o->next) + { + if ((o->flags & SEC_RELOC) != 0) + { + if (!(_bfd_elf_link_size_reloc_section + (abfd, &elf_section_data (o)->rel_hdr, o))) + goto error_return; + + if (elf_section_data (o)->rel_hdr2 + && !(_bfd_elf_link_size_reloc_section + (abfd, elf_section_data (o)->rel_hdr2, o))) + goto error_return; + } + + /* Now, reset REL_COUNT and REL_COUNT2 so that we can use them + to count upwards while actually outputting the relocations. */ + elf_section_data (o)->rel_count = 0; + elf_section_data (o)->rel_count2 = 0; + } + + _bfd_elf_assign_file_positions_for_relocs (abfd); + + /* We have now assigned file positions for all the sections except + .symtab and .strtab. We start the .symtab section at the current + file position, and write directly to it. We build the .strtab + section in memory. */ + bfd_get_symcount (abfd) = 0; + symtab_hdr = &elf_tdata (abfd)->symtab_hdr; + /* sh_name is set in prep_headers. */ + symtab_hdr->sh_type = SHT_SYMTAB; + /* sh_flags, sh_addr and sh_size all start off zero. */ + symtab_hdr->sh_entsize = bed->s->sizeof_sym; + /* sh_link is set in assign_section_numbers. */ + /* sh_info is set below. */ + /* sh_offset is set just below. */ + symtab_hdr->sh_addralign = 1 << bed->s->log_file_align; + + off = elf_tdata (abfd)->next_file_pos; + off = _bfd_elf_assign_file_position_for_section (symtab_hdr, off, TRUE); + + /* Note that at this point elf_tdata (abfd)->next_file_pos is + incorrect. We do not yet know the size of the .symtab section. + We correct next_file_pos below, after we do know the size. */ + + /* Allocate a buffer to hold swapped out symbols. This is to avoid + continuously seeking to the right position in the file. */ + if (! info->keep_memory || max_sym_count < 20) + finfo.symbuf_size = 20; + else + finfo.symbuf_size = max_sym_count; + amt = finfo.symbuf_size; + amt *= bed->s->sizeof_sym; + finfo.symbuf = bfd_malloc (amt); + if (finfo.symbuf == NULL) + goto error_return; + if (elf_numsections (abfd) > SHN_LORESERVE) + { + /* Wild guess at number of output symbols. realloc'd as needed. */ + amt = 2 * max_sym_count + elf_numsections (abfd) + 1000; + finfo.shndxbuf_size = amt; + amt *= sizeof (Elf_External_Sym_Shndx); + finfo.symshndxbuf = bfd_zmalloc (amt); + if (finfo.symshndxbuf == NULL) + goto error_return; + } + + /* Start writing out the symbol table. The first symbol is always a + dummy symbol. */ + if (info->strip != strip_all + || emit_relocs) + { + elfsym.st_value = 0; + elfsym.st_size = 0; + elfsym.st_info = 0; + elfsym.st_other = 0; + elfsym.st_shndx = SHN_UNDEF; + if (! elf_link_output_sym (&finfo, NULL, &elfsym, bfd_und_section_ptr, + NULL)) + goto error_return; + } + +#if 0 + /* Some standard ELF linkers do this, but we don't because it causes + bootstrap comparison failures. */ + /* Output a file symbol for the output file as the second symbol. + We output this even if we are discarding local symbols, although + I'm not sure if this is correct. */ + elfsym.st_value = 0; + elfsym.st_size = 0; + elfsym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE); + elfsym.st_other = 0; + elfsym.st_shndx = SHN_ABS; + if (! elf_link_output_sym (&finfo, bfd_get_filename (abfd), + &elfsym, bfd_abs_section_ptr, NULL)) + goto error_return; +#endif + + /* Output a symbol for each section. We output these even if we are + discarding local symbols, since they are used for relocs. These + symbols have no names. We store the index of each one in the + index field of the section, so that we can find it again when + outputting relocs. */ + if (info->strip != strip_all + || emit_relocs) + { + elfsym.st_size = 0; + elfsym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION); + elfsym.st_other = 0; + for (i = 1; i < elf_numsections (abfd); i++) + { + o = bfd_section_from_elf_index (abfd, i); + if (o != NULL) + o->target_index = bfd_get_symcount (abfd); + elfsym.st_shndx = i; + if (info->relocatable || o == NULL) + elfsym.st_value = 0; + else + elfsym.st_value = o->vma; + if (! elf_link_output_sym (&finfo, NULL, &elfsym, o, NULL)) + goto error_return; + if (i == SHN_LORESERVE - 1) + i += SHN_HIRESERVE + 1 - SHN_LORESERVE; + } + } + + /* Allocate some memory to hold information read in from the input + files. */ + if (max_contents_size != 0) + { + finfo.contents = bfd_malloc (max_contents_size); + if (finfo.contents == NULL) + goto error_return; + } + + if (max_external_reloc_size != 0) + { + finfo.external_relocs = bfd_malloc (max_external_reloc_size); + if (finfo.external_relocs == NULL) + goto error_return; + } + + if (max_internal_reloc_count != 0) + { + amt = max_internal_reloc_count * bed->s->int_rels_per_ext_rel; + amt *= sizeof (Elf_Internal_Rela); + finfo.internal_relocs = bfd_malloc (amt); + if (finfo.internal_relocs == NULL) + goto error_return; + } + + if (max_sym_count != 0) + { + amt = max_sym_count * bed->s->sizeof_sym; + finfo.external_syms = bfd_malloc (amt); + if (finfo.external_syms == NULL) + goto error_return; + + amt = max_sym_count * sizeof (Elf_Internal_Sym); + finfo.internal_syms = bfd_malloc (amt); + if (finfo.internal_syms == NULL) + goto error_return; + + amt = max_sym_count * sizeof (long); + finfo.indices = bfd_malloc (amt); + if (finfo.indices == NULL) + goto error_return; + + amt = max_sym_count * sizeof (asection *); + finfo.sections = bfd_malloc (amt); + if (finfo.sections == NULL) + goto error_return; + } + + if (max_sym_shndx_count != 0) + { + amt = max_sym_shndx_count * sizeof (Elf_External_Sym_Shndx); + finfo.locsym_shndx = bfd_malloc (amt); + if (finfo.locsym_shndx == NULL) + goto error_return; + } + + if (elf_hash_table (info)->tls_sec) + { + bfd_vma base, end = 0; + asection *sec; + + for (sec = elf_hash_table (info)->tls_sec; + sec && (sec->flags & SEC_THREAD_LOCAL); + sec = sec->next) + { + bfd_vma size = sec->_raw_size; + + if (size == 0 && (sec->flags & SEC_HAS_CONTENTS) == 0) + { + struct bfd_link_order *o; + + for (o = sec->link_order_head; o != NULL; o = o->next) + if (size < o->offset + o->size) + size = o->offset + o->size; + } + end = sec->vma + size; + } + base = elf_hash_table (info)->tls_sec->vma; + end = align_power (end, elf_hash_table (info)->tls_sec->alignment_power); + elf_hash_table (info)->tls_size = end - base; + } + + /* Since ELF permits relocations to be against local symbols, we + must have the local symbols available when we do the relocations. + Since we would rather only read the local symbols once, and we + would rather not keep them in memory, we handle all the + relocations for a single input file at the same time. + + Unfortunately, there is no way to know the total number of local + symbols until we have seen all of them, and the local symbol + indices precede the global symbol indices. This means that when + we are generating relocatable output, and we see a reloc against + a global symbol, we can not know the symbol index until we have + finished examining all the local symbols to see which ones we are + going to output. To deal with this, we keep the relocations in + memory, and don't output them until the end of the link. This is + an unfortunate waste of memory, but I don't see a good way around + it. Fortunately, it only happens when performing a relocatable + link, which is not the common case. FIXME: If keep_memory is set + we could write the relocs out and then read them again; I don't + know how bad the memory loss will be. */ + + for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) + sub->output_has_begun = FALSE; + for (o = abfd->sections; o != NULL; o = o->next) + { + for (p = o->link_order_head; p != NULL; p = p->next) + { + if (p->type == bfd_indirect_link_order + && (bfd_get_flavour ((sub = p->u.indirect.section->owner)) + == bfd_target_elf_flavour) + && elf_elfheader (sub)->e_ident[EI_CLASS] == bed->s->elfclass) + { + if (! sub->output_has_begun) + { + if (! elf_link_input_bfd (&finfo, sub)) + goto error_return; + sub->output_has_begun = TRUE; + } + } + else if (p->type == bfd_section_reloc_link_order + || p->type == bfd_symbol_reloc_link_order) + { + if (! elf_reloc_link_order (abfd, info, o, p)) + goto error_return; + } + else + { + if (! _bfd_default_link_order (abfd, info, o, p)) + goto error_return; + } + } + } + + /* Output any global symbols that got converted to local in a + version script or due to symbol visibility. We do this in a + separate step since ELF requires all local symbols to appear + prior to any global symbols. FIXME: We should only do this if + some global symbols were, in fact, converted to become local. + FIXME: Will this work correctly with the Irix 5 linker? */ + eoinfo.failed = FALSE; + eoinfo.finfo = &finfo; + eoinfo.localsyms = TRUE; + elf_link_hash_traverse (elf_hash_table (info), elf_link_output_extsym, + &eoinfo); + if (eoinfo.failed) + return FALSE; + + /* That wrote out all the local symbols. Finish up the symbol table + with the global symbols. Even if we want to strip everything we + can, we still need to deal with those global symbols that got + converted to local in a version script. */ + + /* The sh_info field records the index of the first non local symbol. */ + symtab_hdr->sh_info = bfd_get_symcount (abfd); + + if (dynamic + && finfo.dynsym_sec->output_section != bfd_abs_section_ptr) + { + Elf_Internal_Sym sym; + bfd_byte *dynsym = finfo.dynsym_sec->contents; + long last_local = 0; + + /* Write out the section symbols for the output sections. */ + if (info->shared) + { + asection *s; + + sym.st_size = 0; + sym.st_name = 0; + sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION); + sym.st_other = 0; + + for (s = abfd->sections; s != NULL; s = s->next) + { + int indx; + bfd_byte *dest; + long dynindx; + + indx = elf_section_data (s)->this_idx; + dynindx = elf_section_data (s)->dynindx; + BFD_ASSERT (indx > 0); + sym.st_shndx = indx; + sym.st_value = s->vma; + dest = dynsym + dynindx * bed->s->sizeof_sym; + bed->s->swap_symbol_out (abfd, &sym, dest, 0); + } + + last_local = bfd_count_sections (abfd); + } + + /* Write out the local dynsyms. */ + if (elf_hash_table (info)->dynlocal) + { + struct elf_link_local_dynamic_entry *e; + for (e = elf_hash_table (info)->dynlocal; e ; e = e->next) + { + asection *s; + bfd_byte *dest; + + sym.st_size = e->isym.st_size; + sym.st_other = e->isym.st_other; + + /* Copy the internal symbol as is. + Note that we saved a word of storage and overwrote + the original st_name with the dynstr_index. */ + sym = e->isym; + + if (e->isym.st_shndx != SHN_UNDEF + && (e->isym.st_shndx < SHN_LORESERVE + || e->isym.st_shndx > SHN_HIRESERVE)) + { + s = bfd_section_from_elf_index (e->input_bfd, + e->isym.st_shndx); + + sym.st_shndx = + elf_section_data (s->output_section)->this_idx; + sym.st_value = (s->output_section->vma + + s->output_offset + + e->isym.st_value); + } + + if (last_local < e->dynindx) + last_local = e->dynindx; + + dest = dynsym + e->dynindx * bed->s->sizeof_sym; + bed->s->swap_symbol_out (abfd, &sym, dest, 0); + } + } + + elf_section_data (finfo.dynsym_sec->output_section)->this_hdr.sh_info = + last_local + 1; + } + + /* We get the global symbols from the hash table. */ + eoinfo.failed = FALSE; + eoinfo.localsyms = FALSE; + eoinfo.finfo = &finfo; + elf_link_hash_traverse (elf_hash_table (info), elf_link_output_extsym, + &eoinfo); + if (eoinfo.failed) + return FALSE; + + /* If backend needs to output some symbols not present in the hash + table, do it now. */ + if (bed->elf_backend_output_arch_syms) + { + typedef bfd_boolean (*out_sym_func) + (void *, const char *, Elf_Internal_Sym *, asection *, + struct elf_link_hash_entry *); + + if (! ((*bed->elf_backend_output_arch_syms) + (abfd, info, &finfo, (out_sym_func) elf_link_output_sym))) + return FALSE; + } + + /* Flush all symbols to the file. */ + if (! elf_link_flush_output_syms (&finfo, bed)) + return FALSE; + + /* Now we know the size of the symtab section. */ + off += symtab_hdr->sh_size; + + symtab_shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr; + if (symtab_shndx_hdr->sh_name != 0) + { + symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX; + symtab_shndx_hdr->sh_entsize = sizeof (Elf_External_Sym_Shndx); + symtab_shndx_hdr->sh_addralign = sizeof (Elf_External_Sym_Shndx); + amt = bfd_get_symcount (abfd) * sizeof (Elf_External_Sym_Shndx); + symtab_shndx_hdr->sh_size = amt; + + off = _bfd_elf_assign_file_position_for_section (symtab_shndx_hdr, + off, TRUE); + + if (bfd_seek (abfd, symtab_shndx_hdr->sh_offset, SEEK_SET) != 0 + || (bfd_bwrite (finfo.symshndxbuf, amt, abfd) != amt)) + return FALSE; + } + + + /* Finish up and write out the symbol string table (.strtab) + section. */ + symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr; + /* sh_name was set in prep_headers. */ + symstrtab_hdr->sh_type = SHT_STRTAB; + symstrtab_hdr->sh_flags = 0; + symstrtab_hdr->sh_addr = 0; + symstrtab_hdr->sh_size = _bfd_stringtab_size (finfo.symstrtab); + symstrtab_hdr->sh_entsize = 0; + symstrtab_hdr->sh_link = 0; + symstrtab_hdr->sh_info = 0; + /* sh_offset is set just below. */ + symstrtab_hdr->sh_addralign = 1; + + off = _bfd_elf_assign_file_position_for_section (symstrtab_hdr, off, TRUE); + elf_tdata (abfd)->next_file_pos = off; + + if (bfd_get_symcount (abfd) > 0) + { + if (bfd_seek (abfd, symstrtab_hdr->sh_offset, SEEK_SET) != 0 + || ! _bfd_stringtab_emit (abfd, finfo.symstrtab)) + return FALSE; + } + + /* Adjust the relocs to have the correct symbol indices. */ + for (o = abfd->sections; o != NULL; o = o->next) + { + if ((o->flags & SEC_RELOC) == 0) + continue; + + elf_link_adjust_relocs (abfd, &elf_section_data (o)->rel_hdr, + elf_section_data (o)->rel_count, + elf_section_data (o)->rel_hashes); + if (elf_section_data (o)->rel_hdr2 != NULL) + elf_link_adjust_relocs (abfd, elf_section_data (o)->rel_hdr2, + elf_section_data (o)->rel_count2, + (elf_section_data (o)->rel_hashes + + elf_section_data (o)->rel_count)); + + /* Set the reloc_count field to 0 to prevent write_relocs from + trying to swap the relocs out itself. */ + o->reloc_count = 0; + } + + if (dynamic && info->combreloc && dynobj != NULL) + relativecount = elf_link_sort_relocs (abfd, info, &reldyn); + + /* If we are linking against a dynamic object, or generating a + shared library, finish up the dynamic linking information. */ + if (dynamic) + { + bfd_byte *dyncon, *dynconend; + + /* Fix up .dynamic entries. */ + o = bfd_get_section_by_name (dynobj, ".dynamic"); + BFD_ASSERT (o != NULL); + + dyncon = o->contents; + dynconend = o->contents + o->_raw_size; + for (; dyncon < dynconend; dyncon += bed->s->sizeof_dyn) + { + Elf_Internal_Dyn dyn; + const char *name; + unsigned int type; + + bed->s->swap_dyn_in (dynobj, dyncon, &dyn); + + switch (dyn.d_tag) + { + default: + continue; + case DT_NULL: + if (relativecount > 0 && dyncon + bed->s->sizeof_dyn < dynconend) + { + switch (elf_section_data (reldyn)->this_hdr.sh_type) + { + case SHT_REL: dyn.d_tag = DT_RELCOUNT; break; + case SHT_RELA: dyn.d_tag = DT_RELACOUNT; break; + default: continue; + } + dyn.d_un.d_val = relativecount; + relativecount = 0; + break; + } + continue; + + case DT_INIT: + name = info->init_function; + goto get_sym; + case DT_FINI: + name = info->fini_function; + get_sym: + { + struct elf_link_hash_entry *h; + + h = elf_link_hash_lookup (elf_hash_table (info), name, + FALSE, FALSE, TRUE); + if (h != NULL + && (h->root.type == bfd_link_hash_defined + || h->root.type == bfd_link_hash_defweak)) + { + dyn.d_un.d_val = h->root.u.def.value; + o = h->root.u.def.section; + if (o->output_section != NULL) + dyn.d_un.d_val += (o->output_section->vma + + o->output_offset); + else + { + /* The symbol is imported from another shared + library and does not apply to this one. */ + dyn.d_un.d_val = 0; + } + break; + } + } + continue; + + case DT_PREINIT_ARRAYSZ: + name = ".preinit_array"; + goto get_size; + case DT_INIT_ARRAYSZ: + name = ".init_array"; + goto get_size; + case DT_FINI_ARRAYSZ: + name = ".fini_array"; + get_size: + o = bfd_get_section_by_name (abfd, name); + if (o == NULL) + { + (*_bfd_error_handler) + (_("%s: could not find output section %s"), + bfd_get_filename (abfd), name); + goto error_return; + } + if (o->_raw_size == 0) + (*_bfd_error_handler) + (_("warning: %s section has zero size"), name); + dyn.d_un.d_val = o->_raw_size; + break; + + case DT_PREINIT_ARRAY: + name = ".preinit_array"; + goto get_vma; + case DT_INIT_ARRAY: + name = ".init_array"; + goto get_vma; + case DT_FINI_ARRAY: + name = ".fini_array"; + goto get_vma; + + case DT_HASH: + name = ".hash"; + goto get_vma; + case DT_STRTAB: + name = ".dynstr"; + goto get_vma; + case DT_SYMTAB: + name = ".dynsym"; + goto get_vma; + case DT_VERDEF: + name = ".gnu.version_d"; + goto get_vma; + case DT_VERNEED: + name = ".gnu.version_r"; + goto get_vma; + case DT_VERSYM: + name = ".gnu.version"; + get_vma: + o = bfd_get_section_by_name (abfd, name); + if (o == NULL) + { + (*_bfd_error_handler) + (_("%s: could not find output section %s"), + bfd_get_filename (abfd), name); + goto error_return; + } + dyn.d_un.d_ptr = o->vma; + break; + + case DT_REL: + case DT_RELA: + case DT_RELSZ: + case DT_RELASZ: + if (dyn.d_tag == DT_REL || dyn.d_tag == DT_RELSZ) + type = SHT_REL; + else + type = SHT_RELA; + dyn.d_un.d_val = 0; + for (i = 1; i < elf_numsections (abfd); i++) + { + Elf_Internal_Shdr *hdr; + + hdr = elf_elfsections (abfd)[i]; + if (hdr->sh_type == type + && (hdr->sh_flags & SHF_ALLOC) != 0) + { + if (dyn.d_tag == DT_RELSZ || dyn.d_tag == DT_RELASZ) + dyn.d_un.d_val += hdr->sh_size; + else + { + if (dyn.d_un.d_val == 0 + || hdr->sh_addr < dyn.d_un.d_val) + dyn.d_un.d_val = hdr->sh_addr; + } + } + } + break; + } + bed->s->swap_dyn_out (dynobj, &dyn, dyncon); + } + } + + /* If we have created any dynamic sections, then output them. */ + if (dynobj != NULL) + { + if (! (*bed->elf_backend_finish_dynamic_sections) (abfd, info)) + goto error_return; + + for (o = dynobj->sections; o != NULL; o = o->next) + { + if ((o->flags & SEC_HAS_CONTENTS) == 0 + || o->_raw_size == 0 + || o->output_section == bfd_abs_section_ptr) + continue; + if ((o->flags & SEC_LINKER_CREATED) == 0) + { + /* At this point, we are only interested in sections + created by _bfd_elf_link_create_dynamic_sections. */ + continue; + } + if ((elf_section_data (o->output_section)->this_hdr.sh_type + != SHT_STRTAB) + || strcmp (bfd_get_section_name (abfd, o), ".dynstr") != 0) + { + if (! bfd_set_section_contents (abfd, o->output_section, + o->contents, + (file_ptr) o->output_offset, + o->_raw_size)) + goto error_return; + } + else + { + /* The contents of the .dynstr section are actually in a + stringtab. */ + off = elf_section_data (o->output_section)->this_hdr.sh_offset; + if (bfd_seek (abfd, off, SEEK_SET) != 0 + || ! _bfd_elf_strtab_emit (abfd, + elf_hash_table (info)->dynstr)) + goto error_return; + } + } + } + + if (info->relocatable) + { + bfd_boolean failed = FALSE; + + bfd_map_over_sections (abfd, bfd_elf_set_group_contents, &failed); + if (failed) + goto error_return; + } + + /* If we have optimized stabs strings, output them. */ + if (elf_hash_table (info)->stab_info != NULL) + { + if (! _bfd_write_stab_strings (abfd, &elf_hash_table (info)->stab_info)) + goto error_return; + } + + if (info->eh_frame_hdr) + { + if (! _bfd_elf_write_section_eh_frame_hdr (abfd, info)) + goto error_return; + } + + if (finfo.symstrtab != NULL) + _bfd_stringtab_free (finfo.symstrtab); + if (finfo.contents != NULL) + free (finfo.contents); + if (finfo.external_relocs != NULL) + free (finfo.external_relocs); + if (finfo.internal_relocs != NULL) + free (finfo.internal_relocs); + if (finfo.external_syms != NULL) + free (finfo.external_syms); + if (finfo.locsym_shndx != NULL) + free (finfo.locsym_shndx); + if (finfo.internal_syms != NULL) + free (finfo.internal_syms); + if (finfo.indices != NULL) + free (finfo.indices); + if (finfo.sections != NULL) + free (finfo.sections); + if (finfo.symbuf != NULL) + free (finfo.symbuf); + if (finfo.symshndxbuf != NULL) + free (finfo.symshndxbuf); + for (o = abfd->sections; o != NULL; o = o->next) + { + if ((o->flags & SEC_RELOC) != 0 + && elf_section_data (o)->rel_hashes != NULL) + free (elf_section_data (o)->rel_hashes); + } + + elf_tdata (abfd)->linker = TRUE; + + return TRUE; + + error_return: + if (finfo.symstrtab != NULL) + _bfd_stringtab_free (finfo.symstrtab); + if (finfo.contents != NULL) + free (finfo.contents); + if (finfo.external_relocs != NULL) + free (finfo.external_relocs); + if (finfo.internal_relocs != NULL) + free (finfo.internal_relocs); + if (finfo.external_syms != NULL) + free (finfo.external_syms); + if (finfo.locsym_shndx != NULL) + free (finfo.locsym_shndx); + if (finfo.internal_syms != NULL) + free (finfo.internal_syms); + if (finfo.indices != NULL) + free (finfo.indices); + if (finfo.sections != NULL) + free (finfo.sections); + if (finfo.symbuf != NULL) + free (finfo.symbuf); + if (finfo.symshndxbuf != NULL) + free (finfo.symshndxbuf); + for (o = abfd->sections; o != NULL; o = o->next) + { + if ((o->flags & SEC_RELOC) != 0 + && elf_section_data (o)->rel_hashes != NULL) + free (elf_section_data (o)->rel_hashes); + } + + return FALSE; +} + +/* Garbage collect unused sections. */ + +/* The mark phase of garbage collection. For a given section, mark + it and any sections in this section's group, and all the sections + which define symbols to which it refers. */ + +typedef asection * (*gc_mark_hook_fn) + (asection *, struct bfd_link_info *, Elf_Internal_Rela *, + struct elf_link_hash_entry *, Elf_Internal_Sym *); + +static bfd_boolean +elf_gc_mark (struct bfd_link_info *info, + asection *sec, + gc_mark_hook_fn gc_mark_hook) +{ + bfd_boolean ret; + asection *group_sec; + + sec->gc_mark = 1; + + /* Mark all the sections in the group. */ + group_sec = elf_section_data (sec)->next_in_group; + if (group_sec && !group_sec->gc_mark) + if (!elf_gc_mark (info, group_sec, gc_mark_hook)) + return FALSE; + + /* Look through the section relocs. */ + ret = TRUE; + if ((sec->flags & SEC_RELOC) != 0 && sec->reloc_count > 0) + { + Elf_Internal_Rela *relstart, *rel, *relend; + Elf_Internal_Shdr *symtab_hdr; + struct elf_link_hash_entry **sym_hashes; + size_t nlocsyms; + size_t extsymoff; + bfd *input_bfd = sec->owner; + const struct elf_backend_data *bed = get_elf_backend_data (input_bfd); + Elf_Internal_Sym *isym = NULL; + int r_sym_shift; + + symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; + sym_hashes = elf_sym_hashes (input_bfd); + + /* Read the local symbols. */ + if (elf_bad_symtab (input_bfd)) + { + nlocsyms = symtab_hdr->sh_size / bed->s->sizeof_sym; + extsymoff = 0; + } + else + extsymoff = nlocsyms = symtab_hdr->sh_info; + + isym = (Elf_Internal_Sym *) symtab_hdr->contents; + if (isym == NULL && nlocsyms != 0) + { + isym = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, nlocsyms, 0, + NULL, NULL, NULL); + if (isym == NULL) + return FALSE; + } + + /* Read the relocations. */ + relstart = _bfd_elf_link_read_relocs (input_bfd, sec, NULL, NULL, + info->keep_memory); + if (relstart == NULL) + { + ret = FALSE; + goto out1; + } + relend = relstart + sec->reloc_count * bed->s->int_rels_per_ext_rel; + + if (bed->s->arch_size == 32) + r_sym_shift = 8; + else + r_sym_shift = 32; + + for (rel = relstart; rel < relend; rel++) + { + unsigned long r_symndx; + asection *rsec; + struct elf_link_hash_entry *h; + + r_symndx = rel->r_info >> r_sym_shift; + if (r_symndx == 0) + continue; + + if (r_symndx >= nlocsyms + || ELF_ST_BIND (isym[r_symndx].st_info) != STB_LOCAL) + { + h = sym_hashes[r_symndx - extsymoff]; + rsec = (*gc_mark_hook) (sec, info, rel, h, NULL); + } + else + { + rsec = (*gc_mark_hook) (sec, info, rel, NULL, &isym[r_symndx]); + } + + if (rsec && !rsec->gc_mark) + { + if (bfd_get_flavour (rsec->owner) != bfd_target_elf_flavour) + rsec->gc_mark = 1; + else if (!elf_gc_mark (info, rsec, gc_mark_hook)) + { + ret = FALSE; + goto out2; + } + } + } + + out2: + if (elf_section_data (sec)->relocs != relstart) + free (relstart); + out1: + if (isym != NULL && symtab_hdr->contents != (unsigned char *) isym) + { + if (! info->keep_memory) + free (isym); + else + symtab_hdr->contents = (unsigned char *) isym; + } + } + + return ret; +} + +/* Sweep symbols in swept sections. Called via elf_link_hash_traverse. */ + +static bfd_boolean +elf_gc_sweep_symbol (struct elf_link_hash_entry *h, void *idxptr) +{ + int *idx = idxptr; + + if (h->root.type == bfd_link_hash_warning) + h = (struct elf_link_hash_entry *) h->root.u.i.link; + + if (h->dynindx != -1 + && ((h->root.type != bfd_link_hash_defined + && h->root.type != bfd_link_hash_defweak) + || h->root.u.def.section->gc_mark)) + h->dynindx = (*idx)++; + + return TRUE; +} + +/* The sweep phase of garbage collection. Remove all garbage sections. */ + +typedef bfd_boolean (*gc_sweep_hook_fn) + (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *); + +static bfd_boolean +elf_gc_sweep (struct bfd_link_info *info, gc_sweep_hook_fn gc_sweep_hook) +{ + bfd *sub; + + for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) + { + asection *o; + + if (bfd_get_flavour (sub) != bfd_target_elf_flavour) + continue; + + for (o = sub->sections; o != NULL; o = o->next) + { + /* Keep special sections. Keep .debug sections. */ + if ((o->flags & SEC_LINKER_CREATED) + || (o->flags & SEC_DEBUGGING)) + o->gc_mark = 1; + + if (o->gc_mark) + continue; + + /* Skip sweeping sections already excluded. */ + if (o->flags & SEC_EXCLUDE) + continue; + + /* Since this is early in the link process, it is simple + to remove a section from the output. */ + o->flags |= SEC_EXCLUDE; + + /* But we also have to update some of the relocation + info we collected before. */ + if (gc_sweep_hook + && (o->flags & SEC_RELOC) && o->reloc_count > 0) + { + Elf_Internal_Rela *internal_relocs; + bfd_boolean r; + + internal_relocs + = _bfd_elf_link_read_relocs (o->owner, o, NULL, NULL, + info->keep_memory); + if (internal_relocs == NULL) + return FALSE; + + r = (*gc_sweep_hook) (o->owner, info, o, internal_relocs); + + if (elf_section_data (o)->relocs != internal_relocs) + free (internal_relocs); + + if (!r) + return FALSE; + } + } + } + + /* Remove the symbols that were in the swept sections from the dynamic + symbol table. GCFIXME: Anyone know how to get them out of the + static symbol table as well? */ + { + int i = 0; + + elf_link_hash_traverse (elf_hash_table (info), elf_gc_sweep_symbol, &i); + + elf_hash_table (info)->dynsymcount = i; + } + + return TRUE; +} + +/* Propagate collected vtable information. This is called through + elf_link_hash_traverse. */ + +static bfd_boolean +elf_gc_propagate_vtable_entries_used (struct elf_link_hash_entry *h, void *okp) +{ + if (h->root.type == bfd_link_hash_warning) + h = (struct elf_link_hash_entry *) h->root.u.i.link; + + /* Those that are not vtables. */ + if (h->vtable_parent == NULL) + return TRUE; + + /* Those vtables that do not have parents, we cannot merge. */ + if (h->vtable_parent == (struct elf_link_hash_entry *) -1) + return TRUE; + + /* If we've already been done, exit. */ + if (h->vtable_entries_used && h->vtable_entries_used[-1]) + return TRUE; + + /* Make sure the parent's table is up to date. */ + elf_gc_propagate_vtable_entries_used (h->vtable_parent, okp); + + if (h->vtable_entries_used == NULL) + { + /* None of this table's entries were referenced. Re-use the + parent's table. */ + h->vtable_entries_used = h->vtable_parent->vtable_entries_used; + h->vtable_entries_size = h->vtable_parent->vtable_entries_size; + } + else + { + size_t n; + bfd_boolean *cu, *pu; + + /* Or the parent's entries into ours. */ + cu = h->vtable_entries_used; + cu[-1] = TRUE; + pu = h->vtable_parent->vtable_entries_used; + if (pu != NULL) + { + const struct elf_backend_data *bed; + unsigned int log_file_align; + + bed = get_elf_backend_data (h->root.u.def.section->owner); + log_file_align = bed->s->log_file_align; + n = h->vtable_parent->vtable_entries_size >> log_file_align; + while (n--) + { + if (*pu) + *cu = TRUE; + pu++; + cu++; + } + } + } + + return TRUE; +} + +static bfd_boolean +elf_gc_smash_unused_vtentry_relocs (struct elf_link_hash_entry *h, void *okp) +{ + asection *sec; + bfd_vma hstart, hend; + Elf_Internal_Rela *relstart, *relend, *rel; + const struct elf_backend_data *bed; + unsigned int log_file_align; + + if (h->root.type == bfd_link_hash_warning) + h = (struct elf_link_hash_entry *) h->root.u.i.link; + + /* Take care of both those symbols that do not describe vtables as + well as those that are not loaded. */ + if (h->vtable_parent == NULL) + return TRUE; + + BFD_ASSERT (h->root.type == bfd_link_hash_defined + || h->root.type == bfd_link_hash_defweak); + + sec = h->root.u.def.section; + hstart = h->root.u.def.value; + hend = hstart + h->size; + + relstart = _bfd_elf_link_read_relocs (sec->owner, sec, NULL, NULL, TRUE); + if (!relstart) + return *(bfd_boolean *) okp = FALSE; + bed = get_elf_backend_data (sec->owner); + log_file_align = bed->s->log_file_align; + + relend = relstart + sec->reloc_count * bed->s->int_rels_per_ext_rel; + + for (rel = relstart; rel < relend; ++rel) + if (rel->r_offset >= hstart && rel->r_offset < hend) + { + /* If the entry is in use, do nothing. */ + if (h->vtable_entries_used + && (rel->r_offset - hstart) < h->vtable_entries_size) + { + bfd_vma entry = (rel->r_offset - hstart) >> log_file_align; + if (h->vtable_entries_used[entry]) + continue; + } + /* Otherwise, kill it. */ + rel->r_offset = rel->r_info = rel->r_addend = 0; + } + + return TRUE; +} + +/* Do mark and sweep of unused sections. */ + +bfd_boolean +bfd_elf_gc_sections (bfd *abfd, struct bfd_link_info *info) +{ + bfd_boolean ok = TRUE; + bfd *sub; + asection * (*gc_mark_hook) + (asection *, struct bfd_link_info *, Elf_Internal_Rela *, + struct elf_link_hash_entry *h, Elf_Internal_Sym *); + + if (!get_elf_backend_data (abfd)->can_gc_sections + || info->relocatable + || info->emitrelocations + || !is_elf_hash_table (info->hash) + || elf_hash_table (info)->dynamic_sections_created) + { + (*_bfd_error_handler)(_("Warning: gc-sections option ignored")); + return TRUE; + } + + /* Apply transitive closure to the vtable entry usage info. */ + elf_link_hash_traverse (elf_hash_table (info), + elf_gc_propagate_vtable_entries_used, + &ok); + if (!ok) + return FALSE; + + /* Kill the vtable relocations that were not used. */ + elf_link_hash_traverse (elf_hash_table (info), + elf_gc_smash_unused_vtentry_relocs, + &ok); + if (!ok) + return FALSE; + + /* Grovel through relocs to find out who stays ... */ + + gc_mark_hook = get_elf_backend_data (abfd)->gc_mark_hook; + for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) + { + asection *o; + + if (bfd_get_flavour (sub) != bfd_target_elf_flavour) + continue; + + for (o = sub->sections; o != NULL; o = o->next) + { + if (o->flags & SEC_KEEP) + if (!elf_gc_mark (info, o, gc_mark_hook)) + return FALSE; + } + } + + /* ... and mark SEC_EXCLUDE for those that go. */ + if (!elf_gc_sweep (info, get_elf_backend_data (abfd)->gc_sweep_hook)) + return FALSE; + + return TRUE; +} + +/* Called from check_relocs to record the existence of a VTINHERIT reloc. */ + +bfd_boolean +bfd_elf_gc_record_vtinherit (bfd *abfd, + asection *sec, + struct elf_link_hash_entry *h, + bfd_vma offset) +{ + struct elf_link_hash_entry **sym_hashes, **sym_hashes_end; + struct elf_link_hash_entry **search, *child; + bfd_size_type extsymcount; + const struct elf_backend_data *bed = get_elf_backend_data (abfd); + + /* The sh_info field of the symtab header tells us where the + external symbols start. We don't care about the local symbols at + this point. */ + extsymcount = elf_tdata (abfd)->symtab_hdr.sh_size / bed->s->sizeof_sym; + if (!elf_bad_symtab (abfd)) + extsymcount -= elf_tdata (abfd)->symtab_hdr.sh_info; + + sym_hashes = elf_sym_hashes (abfd); + sym_hashes_end = sym_hashes + extsymcount; + + /* Hunt down the child symbol, which is in this section at the same + offset as the relocation. */ + for (search = sym_hashes; search != sym_hashes_end; ++search) + { + if ((child = *search) != NULL + && (child->root.type == bfd_link_hash_defined + || child->root.type == bfd_link_hash_defweak) + && child->root.u.def.section == sec + && child->root.u.def.value == offset) + goto win; + } + + (*_bfd_error_handler) ("%s: %s+%lu: No symbol found for INHERIT", + bfd_archive_filename (abfd), sec->name, + (unsigned long) offset); + bfd_set_error (bfd_error_invalid_operation); + return FALSE; + + win: + if (!h) + { + /* This *should* only be the absolute section. It could potentially + be that someone has defined a non-global vtable though, which + would be bad. It isn't worth paging in the local symbols to be + sure though; that case should simply be handled by the assembler. */ + + child->vtable_parent = (struct elf_link_hash_entry *) -1; + } + else + child->vtable_parent = h; + + return TRUE; +} + +/* Called from check_relocs to record the existence of a VTENTRY reloc. */ + +bfd_boolean +bfd_elf_gc_record_vtentry (bfd *abfd ATTRIBUTE_UNUSED, + asection *sec ATTRIBUTE_UNUSED, + struct elf_link_hash_entry *h, + bfd_vma addend) +{ + const struct elf_backend_data *bed = get_elf_backend_data (abfd); + unsigned int log_file_align = bed->s->log_file_align; + + if (addend >= h->vtable_entries_size) + { + size_t size, bytes, file_align; + bfd_boolean *ptr = h->vtable_entries_used; + + /* While the symbol is undefined, we have to be prepared to handle + a zero size. */ + file_align = 1 << log_file_align; + if (h->root.type == bfd_link_hash_undefined) + size = addend + file_align; + else + { + size = h->size; + if (addend >= size) + { + /* Oops! We've got a reference past the defined end of + the table. This is probably a bug -- shall we warn? */ + size = addend + file_align; + } + } + size = (size + file_align - 1) & -file_align; + + /* Allocate one extra entry for use as a "done" flag for the + consolidation pass. */ + bytes = ((size >> log_file_align) + 1) * sizeof (bfd_boolean); + + if (ptr) + { + ptr = bfd_realloc (ptr - 1, bytes); + + if (ptr != NULL) + { + size_t oldbytes; + + oldbytes = (((h->vtable_entries_size >> log_file_align) + 1) + * sizeof (bfd_boolean)); + memset (((char *) ptr) + oldbytes, 0, bytes - oldbytes); + } + } + else + ptr = bfd_zmalloc (bytes); + + if (ptr == NULL) + return FALSE; + + /* And arrange for that done flag to be at index -1. */ + h->vtable_entries_used = ptr + 1; + h->vtable_entries_size = size; + } + + h->vtable_entries_used[addend >> log_file_align] = TRUE; + + return TRUE; +} + +struct alloc_got_off_arg { + bfd_vma gotoff; + unsigned int got_elt_size; +}; + +/* We need a special top-level link routine to convert got reference counts + to real got offsets. */ + +static bfd_boolean +elf_gc_allocate_got_offsets (struct elf_link_hash_entry *h, void *arg) +{ + struct alloc_got_off_arg *gofarg = arg; + + if (h->root.type == bfd_link_hash_warning) + h = (struct elf_link_hash_entry *) h->root.u.i.link; + + if (h->got.refcount > 0) + { + h->got.offset = gofarg->gotoff; + gofarg->gotoff += gofarg->got_elt_size; + } + else + h->got.offset = (bfd_vma) -1; + + return TRUE; +} + +/* And an accompanying bit to work out final got entry offsets once + we're done. Should be called from final_link. */ + +bfd_boolean +bfd_elf_gc_common_finalize_got_offsets (bfd *abfd, + struct bfd_link_info *info) +{ + bfd *i; + const struct elf_backend_data *bed = get_elf_backend_data (abfd); + bfd_vma gotoff; + unsigned int got_elt_size = bed->s->arch_size / 8; + struct alloc_got_off_arg gofarg; + + if (! is_elf_hash_table (info->hash)) + return FALSE; + + /* The GOT offset is relative to the .got section, but the GOT header is + put into the .got.plt section, if the backend uses it. */ + if (bed->want_got_plt) + gotoff = 0; + else + gotoff = bed->got_header_size; + + /* Do the local .got entries first. */ + for (i = info->input_bfds; i; i = i->link_next) + { + bfd_signed_vma *local_got; + bfd_size_type j, locsymcount; + Elf_Internal_Shdr *symtab_hdr; + + if (bfd_get_flavour (i) != bfd_target_elf_flavour) + continue; + + local_got = elf_local_got_refcounts (i); + if (!local_got) + continue; + + symtab_hdr = &elf_tdata (i)->symtab_hdr; + if (elf_bad_symtab (i)) + locsymcount = symtab_hdr->sh_size / bed->s->sizeof_sym; + else + locsymcount = symtab_hdr->sh_info; + + for (j = 0; j < locsymcount; ++j) + { + if (local_got[j] > 0) + { + local_got[j] = gotoff; + gotoff += got_elt_size; + } + else + local_got[j] = (bfd_vma) -1; + } + } + + /* Then the global .got entries. .plt refcounts are handled by + adjust_dynamic_symbol */ + gofarg.gotoff = gotoff; + gofarg.got_elt_size = got_elt_size; + elf_link_hash_traverse (elf_hash_table (info), + elf_gc_allocate_got_offsets, + &gofarg); + return TRUE; +} + +/* Many folk need no more in the way of final link than this, once + got entry reference counting is enabled. */ + +bfd_boolean +bfd_elf_gc_common_final_link (bfd *abfd, struct bfd_link_info *info) +{ + if (!bfd_elf_gc_common_finalize_got_offsets (abfd, info)) + return FALSE; + + /* Invoke the regular ELF backend linker to do all the work. */ + return bfd_elf_final_link (abfd, info); +} + +bfd_boolean +bfd_elf_reloc_symbol_deleted_p (bfd_vma offset, void *cookie) +{ + struct elf_reloc_cookie *rcookie = cookie; + + if (rcookie->bad_symtab) + rcookie->rel = rcookie->rels; + + for (; rcookie->rel < rcookie->relend; rcookie->rel++) + { + unsigned long r_symndx; + + if (! rcookie->bad_symtab) + if (rcookie->rel->r_offset > offset) + return FALSE; + if (rcookie->rel->r_offset != offset) + continue; + + r_symndx = rcookie->rel->r_info >> rcookie->r_sym_shift; + if (r_symndx == SHN_UNDEF) + return TRUE; + + if (r_symndx >= rcookie->locsymcount + || ELF_ST_BIND (rcookie->locsyms[r_symndx].st_info) != STB_LOCAL) + { + struct elf_link_hash_entry *h; + + h = rcookie->sym_hashes[r_symndx - rcookie->extsymoff]; + + while (h->root.type == bfd_link_hash_indirect + || h->root.type == bfd_link_hash_warning) + h = (struct elf_link_hash_entry *) h->root.u.i.link; + + if ((h->root.type == bfd_link_hash_defined + || h->root.type == bfd_link_hash_defweak) + && elf_discarded_section (h->root.u.def.section)) + return TRUE; + else + return FALSE; + } + else + { + /* It's not a relocation against a global symbol, + but it could be a relocation against a local + symbol for a discarded section. */ + asection *isec; + Elf_Internal_Sym *isym; + + /* Need to: get the symbol; get the section. */ + isym = &rcookie->locsyms[r_symndx]; + if (isym->st_shndx < SHN_LORESERVE || isym->st_shndx > SHN_HIRESERVE) + { + isec = bfd_section_from_elf_index (rcookie->abfd, isym->st_shndx); + if (isec != NULL && elf_discarded_section (isec)) + return TRUE; + } + } + return FALSE; + } + return FALSE; +} + +/* Discard unneeded references to discarded sections. + Returns TRUE if any section's size was changed. */ +/* This function assumes that the relocations are in sorted order, + which is true for all known assemblers. */ + +bfd_boolean +bfd_elf_discard_info (bfd *output_bfd, struct bfd_link_info *info) +{ + struct elf_reloc_cookie cookie; + asection *stab, *eh; + Elf_Internal_Shdr *symtab_hdr; + const struct elf_backend_data *bed; + bfd *abfd; + unsigned int count; + bfd_boolean ret = FALSE; + + if (info->traditional_format + || !is_elf_hash_table (info->hash)) + return FALSE; + + for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next) + { + if (bfd_get_flavour (abfd) != bfd_target_elf_flavour) + continue; + + bed = get_elf_backend_data (abfd); + + if ((abfd->flags & DYNAMIC) != 0) + continue; + + eh = bfd_get_section_by_name (abfd, ".eh_frame"); + if (info->relocatable + || (eh != NULL + && (eh->_raw_size == 0 + || bfd_is_abs_section (eh->output_section)))) + eh = NULL; + + stab = bfd_get_section_by_name (abfd, ".stab"); + if (stab != NULL + && (stab->_raw_size == 0 + || bfd_is_abs_section (stab->output_section) + || stab->sec_info_type != ELF_INFO_TYPE_STABS)) + stab = NULL; + + if (stab == NULL + && eh == NULL + && bed->elf_backend_discard_info == NULL) + continue; + + symtab_hdr = &elf_tdata (abfd)->symtab_hdr; + cookie.abfd = abfd; + cookie.sym_hashes = elf_sym_hashes (abfd); + cookie.bad_symtab = elf_bad_symtab (abfd); + if (cookie.bad_symtab) + { + cookie.locsymcount = symtab_hdr->sh_size / bed->s->sizeof_sym; + cookie.extsymoff = 0; + } + else + { + cookie.locsymcount = symtab_hdr->sh_info; + cookie.extsymoff = symtab_hdr->sh_info; + } + + if (bed->s->arch_size == 32) + cookie.r_sym_shift = 8; + else + cookie.r_sym_shift = 32; + + cookie.locsyms = (Elf_Internal_Sym *) symtab_hdr->contents; + if (cookie.locsyms == NULL && cookie.locsymcount != 0) + { + cookie.locsyms = bfd_elf_get_elf_syms (abfd, symtab_hdr, + cookie.locsymcount, 0, + NULL, NULL, NULL); + if (cookie.locsyms == NULL) + return FALSE; + } + + if (stab != NULL) + { + cookie.rels = NULL; + count = stab->reloc_count; + if (count != 0) + cookie.rels = _bfd_elf_link_read_relocs (abfd, stab, NULL, NULL, + info->keep_memory); + if (cookie.rels != NULL) + { + cookie.rel = cookie.rels; + cookie.relend = cookie.rels; + cookie.relend += count * bed->s->int_rels_per_ext_rel; + if (_bfd_discard_section_stabs (abfd, stab, + elf_section_data (stab)->sec_info, + bfd_elf_reloc_symbol_deleted_p, + &cookie)) + ret = TRUE; + if (elf_section_data (stab)->relocs != cookie.rels) + free (cookie.rels); + } + } + + if (eh != NULL) + { + cookie.rels = NULL; + count = eh->reloc_count; + if (count != 0) + cookie.rels = _bfd_elf_link_read_relocs (abfd, eh, NULL, NULL, + info->keep_memory); + cookie.rel = cookie.rels; + cookie.relend = cookie.rels; + if (cookie.rels != NULL) + cookie.relend += count * bed->s->int_rels_per_ext_rel; + + if (_bfd_elf_discard_section_eh_frame (abfd, info, eh, + bfd_elf_reloc_symbol_deleted_p, + &cookie)) + ret = TRUE; + + if (cookie.rels != NULL + && elf_section_data (eh)->relocs != cookie.rels) + free (cookie.rels); + } + + if (bed->elf_backend_discard_info != NULL + && (*bed->elf_backend_discard_info) (abfd, &cookie, info)) + ret = TRUE; + + if (cookie.locsyms != NULL + && symtab_hdr->contents != (unsigned char *) cookie.locsyms) + { + if (! info->keep_memory) + free (cookie.locsyms); + else + symtab_hdr->contents = (unsigned char *) cookie.locsyms; + } + } + + if (info->eh_frame_hdr + && !info->relocatable + && _bfd_elf_discard_section_eh_frame_hdr (output_bfd, info)) + ret = TRUE; + + return ret; +} diff --git a/bfd/elflink.h b/bfd/elflink.h deleted file mode 100644 index e9bbd2b..0000000 --- a/bfd/elflink.h +++ /dev/null @@ -1,3586 +0,0 @@ -/* ELF linker support. - Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 - Free Software Foundation, Inc. - - This file is part of BFD, the Binary File Descriptor library. - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* ELF linker code. */ - -static bfd_boolean elf_section_ignore_discarded_relocs (asection *); - -/* Final phase of ELF linker. */ - -/* A structure we use to avoid passing large numbers of arguments. */ - -struct elf_final_link_info -{ - /* General link information. */ - struct bfd_link_info *info; - /* Output BFD. */ - bfd *output_bfd; - /* Symbol string table. */ - struct bfd_strtab_hash *symstrtab; - /* .dynsym section. */ - asection *dynsym_sec; - /* .hash section. */ - asection *hash_sec; - /* symbol version section (.gnu.version). */ - asection *symver_sec; - /* Buffer large enough to hold contents of any section. */ - bfd_byte *contents; - /* Buffer large enough to hold external relocs of any section. */ - void *external_relocs; - /* Buffer large enough to hold internal relocs of any section. */ - Elf_Internal_Rela *internal_relocs; - /* Buffer large enough to hold external local symbols of any input - BFD. */ - bfd_byte *external_syms; - /* And a buffer for symbol section indices. */ - Elf_External_Sym_Shndx *locsym_shndx; - /* Buffer large enough to hold internal local symbols of any input - BFD. */ - Elf_Internal_Sym *internal_syms; - /* Array large enough to hold a symbol index for each local symbol - of any input BFD. */ - long *indices; - /* Array large enough to hold a section pointer for each local - symbol of any input BFD. */ - asection **sections; - /* Buffer to hold swapped out symbols. */ - bfd_byte *symbuf; - /* And one for symbol section indices. */ - Elf_External_Sym_Shndx *symshndxbuf; - /* Number of swapped out symbols in buffer. */ - size_t symbuf_count; - /* Number of symbols which fit in symbuf. */ - size_t symbuf_size; - /* And same for symshndxbuf. */ - size_t shndxbuf_size; -}; - -static bfd_boolean elf_link_output_sym - (struct elf_final_link_info *, const char *, Elf_Internal_Sym *, asection *, - struct elf_link_hash_entry *); -static bfd_boolean elf_link_flush_output_syms - (struct elf_final_link_info *, const struct elf_backend_data *); -static bfd_boolean elf_link_output_extsym - (struct elf_link_hash_entry *, void *); -static bfd_boolean elf_link_input_bfd - (struct elf_final_link_info *, bfd *); -static bfd_boolean elf_reloc_link_order - (bfd *, struct bfd_link_info *, asection *, struct bfd_link_order *); - -/* This struct is used to pass information to elf_link_output_extsym. */ - -struct elf_outext_info -{ - bfd_boolean failed; - bfd_boolean localsyms; - struct elf_final_link_info *finfo; -}; - -/* When performing a relocatable link, the input relocations are - preserved. But, if they reference global symbols, the indices - referenced must be updated. Update all the relocations in - REL_HDR (there are COUNT of them), using the data in REL_HASH. */ - -static void -elf_link_adjust_relocs (bfd *abfd, - Elf_Internal_Shdr *rel_hdr, - unsigned int count, - struct elf_link_hash_entry **rel_hash) -{ - unsigned int i; - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - bfd_byte *erela; - void (*swap_in) (bfd *, const bfd_byte *, Elf_Internal_Rela *); - void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *); - bfd_vma r_type_mask; - int r_sym_shift; - - if (rel_hdr->sh_entsize == bed->s->sizeof_rel) - { - swap_in = bed->s->swap_reloc_in; - swap_out = bed->s->swap_reloc_out; - } - else if (rel_hdr->sh_entsize == bed->s->sizeof_rela) - { - swap_in = bed->s->swap_reloca_in; - swap_out = bed->s->swap_reloca_out; - } - else - abort (); - - if (bed->s->int_rels_per_ext_rel > MAX_INT_RELS_PER_EXT_REL) - abort (); - - if (bed->s->arch_size == 32) - { - r_type_mask = 0xff; - r_sym_shift = 8; - } - else - { - r_type_mask = 0xffffffff; - r_sym_shift = 32; - } - - erela = rel_hdr->contents; - for (i = 0; i < count; i++, rel_hash++, erela += rel_hdr->sh_entsize) - { - Elf_Internal_Rela irela[MAX_INT_RELS_PER_EXT_REL]; - unsigned int j; - - if (*rel_hash == NULL) - continue; - - BFD_ASSERT ((*rel_hash)->indx >= 0); - - (*swap_in) (abfd, erela, irela); - for (j = 0; j < bed->s->int_rels_per_ext_rel; j++) - irela[j].r_info = ((bfd_vma) (*rel_hash)->indx << r_sym_shift - | (irela[j].r_info & r_type_mask)); - (*swap_out) (abfd, irela, erela); - } -} - -struct elf_link_sort_rela -{ - union { - bfd_vma offset; - bfd_vma sym_mask; - } u; - enum elf_reloc_type_class type; - /* We use this as an array of size int_rels_per_ext_rel. */ - Elf_Internal_Rela rela[1]; -}; - -static int -elf_link_sort_cmp1 (const void *A, const void *B) -{ - const struct elf_link_sort_rela *a = A; - const struct elf_link_sort_rela *b = B; - int relativea, relativeb; - - relativea = a->type == reloc_class_relative; - relativeb = b->type == reloc_class_relative; - - if (relativea < relativeb) - return 1; - if (relativea > relativeb) - return -1; - if ((a->rela->r_info & a->u.sym_mask) < (b->rela->r_info & b->u.sym_mask)) - return -1; - if ((a->rela->r_info & a->u.sym_mask) > (b->rela->r_info & b->u.sym_mask)) - return 1; - if (a->rela->r_offset < b->rela->r_offset) - return -1; - if (a->rela->r_offset > b->rela->r_offset) - return 1; - return 0; -} - -static int -elf_link_sort_cmp2 (const void *A, const void *B) -{ - const struct elf_link_sort_rela *a = A; - const struct elf_link_sort_rela *b = B; - int copya, copyb; - - if (a->u.offset < b->u.offset) - return -1; - if (a->u.offset > b->u.offset) - return 1; - copya = (a->type == reloc_class_copy) * 2 + (a->type == reloc_class_plt); - copyb = (b->type == reloc_class_copy) * 2 + (b->type == reloc_class_plt); - if (copya < copyb) - return -1; - if (copya > copyb) - return 1; - if (a->rela->r_offset < b->rela->r_offset) - return -1; - if (a->rela->r_offset > b->rela->r_offset) - return 1; - return 0; -} - -static size_t -elf_link_sort_relocs (bfd *abfd, struct bfd_link_info *info, asection **psec) -{ - asection *reldyn; - bfd_size_type count, size; - size_t i, ret, sort_elt, ext_size; - bfd_byte *sort, *s_non_relative, *p; - struct elf_link_sort_rela *sq; - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - int i2e = bed->s->int_rels_per_ext_rel; - void (*swap_in) (bfd *, const bfd_byte *, Elf_Internal_Rela *); - void (*swap_out) (bfd *, const Elf_Internal_Rela *, bfd_byte *); - struct bfd_link_order *lo; - bfd_vma r_sym_mask; - - reldyn = bfd_get_section_by_name (abfd, ".rela.dyn"); - if (reldyn == NULL || reldyn->_raw_size == 0) - { - reldyn = bfd_get_section_by_name (abfd, ".rel.dyn"); - if (reldyn == NULL || reldyn->_raw_size == 0) - return 0; - ext_size = bed->s->sizeof_rel; - swap_in = bed->s->swap_reloc_in; - swap_out = bed->s->swap_reloc_out; - } - else - { - ext_size = bed->s->sizeof_rela; - swap_in = bed->s->swap_reloca_in; - swap_out = bed->s->swap_reloca_out; - } - count = reldyn->_raw_size / ext_size; - - size = 0; - for (lo = reldyn->link_order_head; lo != NULL; lo = lo->next) - if (lo->type == bfd_indirect_link_order) - { - asection *o = lo->u.indirect.section; - size += o->_raw_size; - } - - if (size != reldyn->_raw_size) - return 0; - - sort_elt = (sizeof (struct elf_link_sort_rela) - + (i2e - 1) * sizeof (Elf_Internal_Rela)); - sort = bfd_zmalloc (sort_elt * count); - if (sort == NULL) - { - (*info->callbacks->warning) - (info, _("Not enough memory to sort relocations"), 0, abfd, 0, 0); - return 0; - } - - if (bed->s->arch_size == 32) - r_sym_mask = ~(bfd_vma) 0xff; - else - r_sym_mask = ~(bfd_vma) 0xffffffff; - - for (lo = reldyn->link_order_head; lo != NULL; lo = lo->next) - if (lo->type == bfd_indirect_link_order) - { - bfd_byte *erel, *erelend; - asection *o = lo->u.indirect.section; - - erel = o->contents; - erelend = o->contents + o->_raw_size; - p = sort + o->output_offset / ext_size * sort_elt; - while (erel < erelend) - { - struct elf_link_sort_rela *s = (struct elf_link_sort_rela *) p; - (*swap_in) (abfd, erel, s->rela); - s->type = (*bed->elf_backend_reloc_type_class) (s->rela); - s->u.sym_mask = r_sym_mask; - p += sort_elt; - erel += ext_size; - } - } - - qsort (sort, count, sort_elt, elf_link_sort_cmp1); - - for (i = 0, p = sort; i < count; i++, p += sort_elt) - { - struct elf_link_sort_rela *s = (struct elf_link_sort_rela *) p; - if (s->type != reloc_class_relative) - break; - } - ret = i; - s_non_relative = p; - - sq = (struct elf_link_sort_rela *) s_non_relative; - for (; i < count; i++, p += sort_elt) - { - struct elf_link_sort_rela *sp = (struct elf_link_sort_rela *) p; - if (((sp->rela->r_info ^ sq->rela->r_info) & r_sym_mask) != 0) - sq = sp; - sp->u.offset = sq->rela->r_offset; - } - - qsort (s_non_relative, count - ret, sort_elt, elf_link_sort_cmp2); - - for (lo = reldyn->link_order_head; lo != NULL; lo = lo->next) - if (lo->type == bfd_indirect_link_order) - { - bfd_byte *erel, *erelend; - asection *o = lo->u.indirect.section; - - erel = o->contents; - erelend = o->contents + o->_raw_size; - p = sort + o->output_offset / ext_size * sort_elt; - while (erel < erelend) - { - struct elf_link_sort_rela *s = (struct elf_link_sort_rela *) p; - (*swap_out) (abfd, s->rela, erel); - p += sort_elt; - erel += ext_size; - } - } - - free (sort); - *psec = reldyn; - return ret; -} - -/* Do the final step of an ELF link. */ - -bfd_boolean -elf_bfd_final_link (bfd *abfd, struct bfd_link_info *info) -{ - bfd_boolean dynamic; - bfd_boolean emit_relocs; - bfd *dynobj; - struct elf_final_link_info finfo; - register asection *o; - register struct bfd_link_order *p; - register bfd *sub; - bfd_size_type max_contents_size; - bfd_size_type max_external_reloc_size; - bfd_size_type max_internal_reloc_count; - bfd_size_type max_sym_count; - bfd_size_type max_sym_shndx_count; - file_ptr off; - Elf_Internal_Sym elfsym; - unsigned int i; - Elf_Internal_Shdr *symtab_hdr; - Elf_Internal_Shdr *symtab_shndx_hdr; - Elf_Internal_Shdr *symstrtab_hdr; - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - struct elf_outext_info eoinfo; - bfd_boolean merged; - size_t relativecount = 0; - asection *reldyn = 0; - bfd_size_type amt; - - if (! is_elf_hash_table (info->hash)) - return FALSE; - - if (info->shared) - abfd->flags |= DYNAMIC; - - dynamic = elf_hash_table (info)->dynamic_sections_created; - dynobj = elf_hash_table (info)->dynobj; - - emit_relocs = (info->relocatable - || info->emitrelocations - || bed->elf_backend_emit_relocs); - - finfo.info = info; - finfo.output_bfd = abfd; - finfo.symstrtab = _bfd_elf_stringtab_init (); - if (finfo.symstrtab == NULL) - return FALSE; - - if (! dynamic) - { - finfo.dynsym_sec = NULL; - finfo.hash_sec = NULL; - finfo.symver_sec = NULL; - } - else - { - finfo.dynsym_sec = bfd_get_section_by_name (dynobj, ".dynsym"); - finfo.hash_sec = bfd_get_section_by_name (dynobj, ".hash"); - BFD_ASSERT (finfo.dynsym_sec != NULL && finfo.hash_sec != NULL); - finfo.symver_sec = bfd_get_section_by_name (dynobj, ".gnu.version"); - /* Note that it is OK if symver_sec is NULL. */ - } - - finfo.contents = NULL; - finfo.external_relocs = NULL; - finfo.internal_relocs = NULL; - finfo.external_syms = NULL; - finfo.locsym_shndx = NULL; - finfo.internal_syms = NULL; - finfo.indices = NULL; - finfo.sections = NULL; - finfo.symbuf = NULL; - finfo.symshndxbuf = NULL; - finfo.symbuf_count = 0; - finfo.shndxbuf_size = 0; - - /* Count up the number of relocations we will output for each output - section, so that we know the sizes of the reloc sections. We - also figure out some maximum sizes. */ - max_contents_size = 0; - max_external_reloc_size = 0; - max_internal_reloc_count = 0; - max_sym_count = 0; - max_sym_shndx_count = 0; - merged = FALSE; - for (o = abfd->sections; o != NULL; o = o->next) - { - struct bfd_elf_section_data *esdo = elf_section_data (o); - o->reloc_count = 0; - - for (p = o->link_order_head; p != NULL; p = p->next) - { - unsigned int reloc_count = 0; - struct bfd_elf_section_data *esdi = NULL; - unsigned int *rel_count1; - - if (p->type == bfd_section_reloc_link_order - || p->type == bfd_symbol_reloc_link_order) - reloc_count = 1; - else if (p->type == bfd_indirect_link_order) - { - asection *sec; - - sec = p->u.indirect.section; - esdi = elf_section_data (sec); - - /* Mark all sections which are to be included in the - link. This will normally be every section. We need - to do this so that we can identify any sections which - the linker has decided to not include. */ - sec->linker_mark = TRUE; - - if (sec->flags & SEC_MERGE) - merged = TRUE; - - if (info->relocatable || info->emitrelocations) - reloc_count = sec->reloc_count; - else if (bed->elf_backend_count_relocs) - { - Elf_Internal_Rela * relocs; - - relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, - info->keep_memory); - - reloc_count = (*bed->elf_backend_count_relocs) (sec, relocs); - - if (elf_section_data (o)->relocs != relocs) - free (relocs); - } - - if (sec->_raw_size > max_contents_size) - max_contents_size = sec->_raw_size; - if (sec->_cooked_size > max_contents_size) - max_contents_size = sec->_cooked_size; - - /* We are interested in just local symbols, not all - symbols. */ - if (bfd_get_flavour (sec->owner) == bfd_target_elf_flavour - && (sec->owner->flags & DYNAMIC) == 0) - { - size_t sym_count; - - if (elf_bad_symtab (sec->owner)) - sym_count = (elf_tdata (sec->owner)->symtab_hdr.sh_size - / bed->s->sizeof_sym); - else - sym_count = elf_tdata (sec->owner)->symtab_hdr.sh_info; - - if (sym_count > max_sym_count) - max_sym_count = sym_count; - - if (sym_count > max_sym_shndx_count - && elf_symtab_shndx (sec->owner) != 0) - max_sym_shndx_count = sym_count; - - if ((sec->flags & SEC_RELOC) != 0) - { - size_t ext_size; - - ext_size = elf_section_data (sec)->rel_hdr.sh_size; - if (ext_size > max_external_reloc_size) - max_external_reloc_size = ext_size; - if (sec->reloc_count > max_internal_reloc_count) - max_internal_reloc_count = sec->reloc_count; - } - } - } - - if (reloc_count == 0) - continue; - - o->reloc_count += reloc_count; - - /* MIPS may have a mix of REL and RELA relocs on sections. - To support this curious ABI we keep reloc counts in - elf_section_data too. We must be careful to add the - relocations from the input section to the right output - count. FIXME: Get rid of one count. We have - o->reloc_count == esdo->rel_count + esdo->rel_count2. */ - rel_count1 = &esdo->rel_count; - if (esdi != NULL) - { - bfd_boolean same_size; - bfd_size_type entsize1; - - entsize1 = esdi->rel_hdr.sh_entsize; - BFD_ASSERT (entsize1 == bed->s->sizeof_rel - || entsize1 == bed->s->sizeof_rela); - same_size = !o->use_rela_p == (entsize1 == bed->s->sizeof_rel); - - if (!same_size) - rel_count1 = &esdo->rel_count2; - - if (esdi->rel_hdr2 != NULL) - { - bfd_size_type entsize2 = esdi->rel_hdr2->sh_entsize; - unsigned int alt_count; - unsigned int *rel_count2; - - BFD_ASSERT (entsize2 != entsize1 - && (entsize2 == bed->s->sizeof_rel - || entsize2 == bed->s->sizeof_rela)); - - rel_count2 = &esdo->rel_count2; - if (!same_size) - rel_count2 = &esdo->rel_count; - - /* The following is probably too simplistic if the - backend counts output relocs unusually. */ - BFD_ASSERT (bed->elf_backend_count_relocs == NULL); - alt_count = NUM_SHDR_ENTRIES (esdi->rel_hdr2); - *rel_count2 += alt_count; - reloc_count -= alt_count; - } - } - *rel_count1 += reloc_count; - } - - if (o->reloc_count > 0) - o->flags |= SEC_RELOC; - else - { - /* Explicitly clear the SEC_RELOC flag. The linker tends to - set it (this is probably a bug) and if it is set - assign_section_numbers will create a reloc section. */ - o->flags &=~ SEC_RELOC; - } - - /* If the SEC_ALLOC flag is not set, force the section VMA to - zero. This is done in elf_fake_sections as well, but forcing - the VMA to 0 here will ensure that relocs against these - sections are handled correctly. */ - if ((o->flags & SEC_ALLOC) == 0 - && ! o->user_set_vma) - o->vma = 0; - } - - if (! info->relocatable && merged) - elf_link_hash_traverse (elf_hash_table (info), - _bfd_elf_link_sec_merge_syms, abfd); - - /* Figure out the file positions for everything but the symbol table - and the relocs. We set symcount to force assign_section_numbers - to create a symbol table. */ - bfd_get_symcount (abfd) = info->strip == strip_all ? 0 : 1; - BFD_ASSERT (! abfd->output_has_begun); - if (! _bfd_elf_compute_section_file_positions (abfd, info)) - goto error_return; - - /* That created the reloc sections. Set their sizes, and assign - them file positions, and allocate some buffers. */ - for (o = abfd->sections; o != NULL; o = o->next) - { - if ((o->flags & SEC_RELOC) != 0) - { - if (!(_bfd_elf_link_size_reloc_section - (abfd, &elf_section_data (o)->rel_hdr, o))) - goto error_return; - - if (elf_section_data (o)->rel_hdr2 - && !(_bfd_elf_link_size_reloc_section - (abfd, elf_section_data (o)->rel_hdr2, o))) - goto error_return; - } - - /* Now, reset REL_COUNT and REL_COUNT2 so that we can use them - to count upwards while actually outputting the relocations. */ - elf_section_data (o)->rel_count = 0; - elf_section_data (o)->rel_count2 = 0; - } - - _bfd_elf_assign_file_positions_for_relocs (abfd); - - /* We have now assigned file positions for all the sections except - .symtab and .strtab. We start the .symtab section at the current - file position, and write directly to it. We build the .strtab - section in memory. */ - bfd_get_symcount (abfd) = 0; - symtab_hdr = &elf_tdata (abfd)->symtab_hdr; - /* sh_name is set in prep_headers. */ - symtab_hdr->sh_type = SHT_SYMTAB; - /* sh_flags, sh_addr and sh_size all start off zero. */ - symtab_hdr->sh_entsize = bed->s->sizeof_sym; - /* sh_link is set in assign_section_numbers. */ - /* sh_info is set below. */ - /* sh_offset is set just below. */ - symtab_hdr->sh_addralign = 1 << bed->s->log_file_align; - - off = elf_tdata (abfd)->next_file_pos; - off = _bfd_elf_assign_file_position_for_section (symtab_hdr, off, TRUE); - - /* Note that at this point elf_tdata (abfd)->next_file_pos is - incorrect. We do not yet know the size of the .symtab section. - We correct next_file_pos below, after we do know the size. */ - - /* Allocate a buffer to hold swapped out symbols. This is to avoid - continuously seeking to the right position in the file. */ - if (! info->keep_memory || max_sym_count < 20) - finfo.symbuf_size = 20; - else - finfo.symbuf_size = max_sym_count; - amt = finfo.symbuf_size; - amt *= bed->s->sizeof_sym; - finfo.symbuf = bfd_malloc (amt); - if (finfo.symbuf == NULL) - goto error_return; - if (elf_numsections (abfd) > SHN_LORESERVE) - { - /* Wild guess at number of output symbols. realloc'd as needed. */ - amt = 2 * max_sym_count + elf_numsections (abfd) + 1000; - finfo.shndxbuf_size = amt; - amt *= sizeof (Elf_External_Sym_Shndx); - finfo.symshndxbuf = bfd_zmalloc (amt); - if (finfo.symshndxbuf == NULL) - goto error_return; - } - - /* Start writing out the symbol table. The first symbol is always a - dummy symbol. */ - if (info->strip != strip_all - || emit_relocs) - { - elfsym.st_value = 0; - elfsym.st_size = 0; - elfsym.st_info = 0; - elfsym.st_other = 0; - elfsym.st_shndx = SHN_UNDEF; - if (! elf_link_output_sym (&finfo, NULL, &elfsym, bfd_und_section_ptr, - NULL)) - goto error_return; - } - -#if 0 - /* Some standard ELF linkers do this, but we don't because it causes - bootstrap comparison failures. */ - /* Output a file symbol for the output file as the second symbol. - We output this even if we are discarding local symbols, although - I'm not sure if this is correct. */ - elfsym.st_value = 0; - elfsym.st_size = 0; - elfsym.st_info = ELF_ST_INFO (STB_LOCAL, STT_FILE); - elfsym.st_other = 0; - elfsym.st_shndx = SHN_ABS; - if (! elf_link_output_sym (&finfo, bfd_get_filename (abfd), - &elfsym, bfd_abs_section_ptr, NULL)) - goto error_return; -#endif - - /* Output a symbol for each section. We output these even if we are - discarding local symbols, since they are used for relocs. These - symbols have no names. We store the index of each one in the - index field of the section, so that we can find it again when - outputting relocs. */ - if (info->strip != strip_all - || emit_relocs) - { - elfsym.st_size = 0; - elfsym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION); - elfsym.st_other = 0; - for (i = 1; i < elf_numsections (abfd); i++) - { - o = bfd_section_from_elf_index (abfd, i); - if (o != NULL) - o->target_index = bfd_get_symcount (abfd); - elfsym.st_shndx = i; - if (info->relocatable || o == NULL) - elfsym.st_value = 0; - else - elfsym.st_value = o->vma; - if (! elf_link_output_sym (&finfo, NULL, &elfsym, o, NULL)) - goto error_return; - if (i == SHN_LORESERVE - 1) - i += SHN_HIRESERVE + 1 - SHN_LORESERVE; - } - } - - /* Allocate some memory to hold information read in from the input - files. */ - if (max_contents_size != 0) - { - finfo.contents = bfd_malloc (max_contents_size); - if (finfo.contents == NULL) - goto error_return; - } - - if (max_external_reloc_size != 0) - { - finfo.external_relocs = bfd_malloc (max_external_reloc_size); - if (finfo.external_relocs == NULL) - goto error_return; - } - - if (max_internal_reloc_count != 0) - { - amt = max_internal_reloc_count * bed->s->int_rels_per_ext_rel; - amt *= sizeof (Elf_Internal_Rela); - finfo.internal_relocs = bfd_malloc (amt); - if (finfo.internal_relocs == NULL) - goto error_return; - } - - if (max_sym_count != 0) - { - amt = max_sym_count * bed->s->sizeof_sym; - finfo.external_syms = bfd_malloc (amt); - if (finfo.external_syms == NULL) - goto error_return; - - amt = max_sym_count * sizeof (Elf_Internal_Sym); - finfo.internal_syms = bfd_malloc (amt); - if (finfo.internal_syms == NULL) - goto error_return; - - amt = max_sym_count * sizeof (long); - finfo.indices = bfd_malloc (amt); - if (finfo.indices == NULL) - goto error_return; - - amt = max_sym_count * sizeof (asection *); - finfo.sections = bfd_malloc (amt); - if (finfo.sections == NULL) - goto error_return; - } - - if (max_sym_shndx_count != 0) - { - amt = max_sym_shndx_count * sizeof (Elf_External_Sym_Shndx); - finfo.locsym_shndx = bfd_malloc (amt); - if (finfo.locsym_shndx == NULL) - goto error_return; - } - - if (elf_hash_table (info)->tls_sec) - { - bfd_vma base, end = 0; - asection *sec; - - for (sec = elf_hash_table (info)->tls_sec; - sec && (sec->flags & SEC_THREAD_LOCAL); - sec = sec->next) - { - bfd_vma size = sec->_raw_size; - - if (size == 0 && (sec->flags & SEC_HAS_CONTENTS) == 0) - { - struct bfd_link_order *o; - - for (o = sec->link_order_head; o != NULL; o = o->next) - if (size < o->offset + o->size) - size = o->offset + o->size; - } - end = sec->vma + size; - } - base = elf_hash_table (info)->tls_sec->vma; - end = align_power (end, elf_hash_table (info)->tls_sec->alignment_power); - elf_hash_table (info)->tls_size = end - base; - } - - /* Since ELF permits relocations to be against local symbols, we - must have the local symbols available when we do the relocations. - Since we would rather only read the local symbols once, and we - would rather not keep them in memory, we handle all the - relocations for a single input file at the same time. - - Unfortunately, there is no way to know the total number of local - symbols until we have seen all of them, and the local symbol - indices precede the global symbol indices. This means that when - we are generating relocatable output, and we see a reloc against - a global symbol, we can not know the symbol index until we have - finished examining all the local symbols to see which ones we are - going to output. To deal with this, we keep the relocations in - memory, and don't output them until the end of the link. This is - an unfortunate waste of memory, but I don't see a good way around - it. Fortunately, it only happens when performing a relocatable - link, which is not the common case. FIXME: If keep_memory is set - we could write the relocs out and then read them again; I don't - know how bad the memory loss will be. */ - - for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) - sub->output_has_begun = FALSE; - for (o = abfd->sections; o != NULL; o = o->next) - { - for (p = o->link_order_head; p != NULL; p = p->next) - { - if (p->type == bfd_indirect_link_order - && (bfd_get_flavour ((sub = p->u.indirect.section->owner)) - == bfd_target_elf_flavour) - && elf_elfheader (sub)->e_ident[EI_CLASS] == bed->s->elfclass) - { - if (! sub->output_has_begun) - { - if (! elf_link_input_bfd (&finfo, sub)) - goto error_return; - sub->output_has_begun = TRUE; - } - } - else if (p->type == bfd_section_reloc_link_order - || p->type == bfd_symbol_reloc_link_order) - { - if (! elf_reloc_link_order (abfd, info, o, p)) - goto error_return; - } - else - { - if (! _bfd_default_link_order (abfd, info, o, p)) - goto error_return; - } - } - } - - /* Output any global symbols that got converted to local in a - version script or due to symbol visibility. We do this in a - separate step since ELF requires all local symbols to appear - prior to any global symbols. FIXME: We should only do this if - some global symbols were, in fact, converted to become local. - FIXME: Will this work correctly with the Irix 5 linker? */ - eoinfo.failed = FALSE; - eoinfo.finfo = &finfo; - eoinfo.localsyms = TRUE; - elf_link_hash_traverse (elf_hash_table (info), elf_link_output_extsym, - &eoinfo); - if (eoinfo.failed) - return FALSE; - - /* That wrote out all the local symbols. Finish up the symbol table - with the global symbols. Even if we want to strip everything we - can, we still need to deal with those global symbols that got - converted to local in a version script. */ - - /* The sh_info field records the index of the first non local symbol. */ - symtab_hdr->sh_info = bfd_get_symcount (abfd); - - if (dynamic - && finfo.dynsym_sec->output_section != bfd_abs_section_ptr) - { - Elf_Internal_Sym sym; - bfd_byte *dynsym = finfo.dynsym_sec->contents; - long last_local = 0; - - /* Write out the section symbols for the output sections. */ - if (info->shared) - { - asection *s; - - sym.st_size = 0; - sym.st_name = 0; - sym.st_info = ELF_ST_INFO (STB_LOCAL, STT_SECTION); - sym.st_other = 0; - - for (s = abfd->sections; s != NULL; s = s->next) - { - int indx; - bfd_byte *dest; - long dynindx; - - indx = elf_section_data (s)->this_idx; - dynindx = elf_section_data (s)->dynindx; - BFD_ASSERT (indx > 0); - sym.st_shndx = indx; - sym.st_value = s->vma; - dest = dynsym + dynindx * bed->s->sizeof_sym; - bed->s->swap_symbol_out (abfd, &sym, dest, 0); - } - - last_local = bfd_count_sections (abfd); - } - - /* Write out the local dynsyms. */ - if (elf_hash_table (info)->dynlocal) - { - struct elf_link_local_dynamic_entry *e; - for (e = elf_hash_table (info)->dynlocal; e ; e = e->next) - { - asection *s; - bfd_byte *dest; - - sym.st_size = e->isym.st_size; - sym.st_other = e->isym.st_other; - - /* Copy the internal symbol as is. - Note that we saved a word of storage and overwrote - the original st_name with the dynstr_index. */ - sym = e->isym; - - if (e->isym.st_shndx != SHN_UNDEF - && (e->isym.st_shndx < SHN_LORESERVE - || e->isym.st_shndx > SHN_HIRESERVE)) - { - s = bfd_section_from_elf_index (e->input_bfd, - e->isym.st_shndx); - - sym.st_shndx = - elf_section_data (s->output_section)->this_idx; - sym.st_value = (s->output_section->vma - + s->output_offset - + e->isym.st_value); - } - - if (last_local < e->dynindx) - last_local = e->dynindx; - - dest = dynsym + e->dynindx * bed->s->sizeof_sym; - bed->s->swap_symbol_out (abfd, &sym, dest, 0); - } - } - - elf_section_data (finfo.dynsym_sec->output_section)->this_hdr.sh_info = - last_local + 1; - } - - /* We get the global symbols from the hash table. */ - eoinfo.failed = FALSE; - eoinfo.localsyms = FALSE; - eoinfo.finfo = &finfo; - elf_link_hash_traverse (elf_hash_table (info), elf_link_output_extsym, - &eoinfo); - if (eoinfo.failed) - return FALSE; - - /* If backend needs to output some symbols not present in the hash - table, do it now. */ - if (bed->elf_backend_output_arch_syms) - { - typedef bfd_boolean (*out_sym_func) - (void *, const char *, Elf_Internal_Sym *, asection *, - struct elf_link_hash_entry *); - - if (! ((*bed->elf_backend_output_arch_syms) - (abfd, info, &finfo, (out_sym_func) elf_link_output_sym))) - return FALSE; - } - - /* Flush all symbols to the file. */ - if (! elf_link_flush_output_syms (&finfo, bed)) - return FALSE; - - /* Now we know the size of the symtab section. */ - off += symtab_hdr->sh_size; - - symtab_shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr; - if (symtab_shndx_hdr->sh_name != 0) - { - symtab_shndx_hdr->sh_type = SHT_SYMTAB_SHNDX; - symtab_shndx_hdr->sh_entsize = sizeof (Elf_External_Sym_Shndx); - symtab_shndx_hdr->sh_addralign = sizeof (Elf_External_Sym_Shndx); - amt = bfd_get_symcount (abfd) * sizeof (Elf_External_Sym_Shndx); - symtab_shndx_hdr->sh_size = amt; - - off = _bfd_elf_assign_file_position_for_section (symtab_shndx_hdr, - off, TRUE); - - if (bfd_seek (abfd, symtab_shndx_hdr->sh_offset, SEEK_SET) != 0 - || (bfd_bwrite (finfo.symshndxbuf, amt, abfd) != amt)) - return FALSE; - } - - - /* Finish up and write out the symbol string table (.strtab) - section. */ - symstrtab_hdr = &elf_tdata (abfd)->strtab_hdr; - /* sh_name was set in prep_headers. */ - symstrtab_hdr->sh_type = SHT_STRTAB; - symstrtab_hdr->sh_flags = 0; - symstrtab_hdr->sh_addr = 0; - symstrtab_hdr->sh_size = _bfd_stringtab_size (finfo.symstrtab); - symstrtab_hdr->sh_entsize = 0; - symstrtab_hdr->sh_link = 0; - symstrtab_hdr->sh_info = 0; - /* sh_offset is set just below. */ - symstrtab_hdr->sh_addralign = 1; - - off = _bfd_elf_assign_file_position_for_section (symstrtab_hdr, off, TRUE); - elf_tdata (abfd)->next_file_pos = off; - - if (bfd_get_symcount (abfd) > 0) - { - if (bfd_seek (abfd, symstrtab_hdr->sh_offset, SEEK_SET) != 0 - || ! _bfd_stringtab_emit (abfd, finfo.symstrtab)) - return FALSE; - } - - /* Adjust the relocs to have the correct symbol indices. */ - for (o = abfd->sections; o != NULL; o = o->next) - { - if ((o->flags & SEC_RELOC) == 0) - continue; - - elf_link_adjust_relocs (abfd, &elf_section_data (o)->rel_hdr, - elf_section_data (o)->rel_count, - elf_section_data (o)->rel_hashes); - if (elf_section_data (o)->rel_hdr2 != NULL) - elf_link_adjust_relocs (abfd, elf_section_data (o)->rel_hdr2, - elf_section_data (o)->rel_count2, - (elf_section_data (o)->rel_hashes - + elf_section_data (o)->rel_count)); - - /* Set the reloc_count field to 0 to prevent write_relocs from - trying to swap the relocs out itself. */ - o->reloc_count = 0; - } - - if (dynamic && info->combreloc && dynobj != NULL) - relativecount = elf_link_sort_relocs (abfd, info, &reldyn); - - /* If we are linking against a dynamic object, or generating a - shared library, finish up the dynamic linking information. */ - if (dynamic) - { - bfd_byte *dyncon, *dynconend; - - /* Fix up .dynamic entries. */ - o = bfd_get_section_by_name (dynobj, ".dynamic"); - BFD_ASSERT (o != NULL); - - dyncon = o->contents; - dynconend = o->contents + o->_raw_size; - for (; dyncon < dynconend; dyncon += bed->s->sizeof_dyn) - { - Elf_Internal_Dyn dyn; - const char *name; - unsigned int type; - - bed->s->swap_dyn_in (dynobj, dyncon, &dyn); - - switch (dyn.d_tag) - { - default: - continue; - case DT_NULL: - if (relativecount > 0 && dyncon + bed->s->sizeof_dyn < dynconend) - { - switch (elf_section_data (reldyn)->this_hdr.sh_type) - { - case SHT_REL: dyn.d_tag = DT_RELCOUNT; break; - case SHT_RELA: dyn.d_tag = DT_RELACOUNT; break; - default: continue; - } - dyn.d_un.d_val = relativecount; - relativecount = 0; - break; - } - continue; - - case DT_INIT: - name = info->init_function; - goto get_sym; - case DT_FINI: - name = info->fini_function; - get_sym: - { - struct elf_link_hash_entry *h; - - h = elf_link_hash_lookup (elf_hash_table (info), name, - FALSE, FALSE, TRUE); - if (h != NULL - && (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak)) - { - dyn.d_un.d_val = h->root.u.def.value; - o = h->root.u.def.section; - if (o->output_section != NULL) - dyn.d_un.d_val += (o->output_section->vma - + o->output_offset); - else - { - /* The symbol is imported from another shared - library and does not apply to this one. */ - dyn.d_un.d_val = 0; - } - break; - } - } - continue; - - case DT_PREINIT_ARRAYSZ: - name = ".preinit_array"; - goto get_size; - case DT_INIT_ARRAYSZ: - name = ".init_array"; - goto get_size; - case DT_FINI_ARRAYSZ: - name = ".fini_array"; - get_size: - o = bfd_get_section_by_name (abfd, name); - if (o == NULL) - { - (*_bfd_error_handler) - (_("%s: could not find output section %s"), - bfd_get_filename (abfd), name); - goto error_return; - } - if (o->_raw_size == 0) - (*_bfd_error_handler) - (_("warning: %s section has zero size"), name); - dyn.d_un.d_val = o->_raw_size; - break; - - case DT_PREINIT_ARRAY: - name = ".preinit_array"; - goto get_vma; - case DT_INIT_ARRAY: - name = ".init_array"; - goto get_vma; - case DT_FINI_ARRAY: - name = ".fini_array"; - goto get_vma; - - case DT_HASH: - name = ".hash"; - goto get_vma; - case DT_STRTAB: - name = ".dynstr"; - goto get_vma; - case DT_SYMTAB: - name = ".dynsym"; - goto get_vma; - case DT_VERDEF: - name = ".gnu.version_d"; - goto get_vma; - case DT_VERNEED: - name = ".gnu.version_r"; - goto get_vma; - case DT_VERSYM: - name = ".gnu.version"; - get_vma: - o = bfd_get_section_by_name (abfd, name); - if (o == NULL) - { - (*_bfd_error_handler) - (_("%s: could not find output section %s"), - bfd_get_filename (abfd), name); - goto error_return; - } - dyn.d_un.d_ptr = o->vma; - break; - - case DT_REL: - case DT_RELA: - case DT_RELSZ: - case DT_RELASZ: - if (dyn.d_tag == DT_REL || dyn.d_tag == DT_RELSZ) - type = SHT_REL; - else - type = SHT_RELA; - dyn.d_un.d_val = 0; - for (i = 1; i < elf_numsections (abfd); i++) - { - Elf_Internal_Shdr *hdr; - - hdr = elf_elfsections (abfd)[i]; - if (hdr->sh_type == type - && (hdr->sh_flags & SHF_ALLOC) != 0) - { - if (dyn.d_tag == DT_RELSZ || dyn.d_tag == DT_RELASZ) - dyn.d_un.d_val += hdr->sh_size; - else - { - if (dyn.d_un.d_val == 0 - || hdr->sh_addr < dyn.d_un.d_val) - dyn.d_un.d_val = hdr->sh_addr; - } - } - } - break; - } - bed->s->swap_dyn_out (dynobj, &dyn, dyncon); - } - } - - /* If we have created any dynamic sections, then output them. */ - if (dynobj != NULL) - { - if (! (*bed->elf_backend_finish_dynamic_sections) (abfd, info)) - goto error_return; - - for (o = dynobj->sections; o != NULL; o = o->next) - { - if ((o->flags & SEC_HAS_CONTENTS) == 0 - || o->_raw_size == 0 - || o->output_section == bfd_abs_section_ptr) - continue; - if ((o->flags & SEC_LINKER_CREATED) == 0) - { - /* At this point, we are only interested in sections - created by _bfd_elf_link_create_dynamic_sections. */ - continue; - } - if ((elf_section_data (o->output_section)->this_hdr.sh_type - != SHT_STRTAB) - || strcmp (bfd_get_section_name (abfd, o), ".dynstr") != 0) - { - if (! bfd_set_section_contents (abfd, o->output_section, - o->contents, - (file_ptr) o->output_offset, - o->_raw_size)) - goto error_return; - } - else - { - /* The contents of the .dynstr section are actually in a - stringtab. */ - off = elf_section_data (o->output_section)->this_hdr.sh_offset; - if (bfd_seek (abfd, off, SEEK_SET) != 0 - || ! _bfd_elf_strtab_emit (abfd, - elf_hash_table (info)->dynstr)) - goto error_return; - } - } - } - - if (info->relocatable) - { - bfd_boolean failed = FALSE; - - bfd_map_over_sections (abfd, bfd_elf_set_group_contents, &failed); - if (failed) - goto error_return; - } - - /* If we have optimized stabs strings, output them. */ - if (elf_hash_table (info)->stab_info != NULL) - { - if (! _bfd_write_stab_strings (abfd, &elf_hash_table (info)->stab_info)) - goto error_return; - } - - if (info->eh_frame_hdr) - { - if (! _bfd_elf_write_section_eh_frame_hdr (abfd, info)) - goto error_return; - } - - if (finfo.symstrtab != NULL) - _bfd_stringtab_free (finfo.symstrtab); - if (finfo.contents != NULL) - free (finfo.contents); - if (finfo.external_relocs != NULL) - free (finfo.external_relocs); - if (finfo.internal_relocs != NULL) - free (finfo.internal_relocs); - if (finfo.external_syms != NULL) - free (finfo.external_syms); - if (finfo.locsym_shndx != NULL) - free (finfo.locsym_shndx); - if (finfo.internal_syms != NULL) - free (finfo.internal_syms); - if (finfo.indices != NULL) - free (finfo.indices); - if (finfo.sections != NULL) - free (finfo.sections); - if (finfo.symbuf != NULL) - free (finfo.symbuf); - if (finfo.symshndxbuf != NULL) - free (finfo.symshndxbuf); - for (o = abfd->sections; o != NULL; o = o->next) - { - if ((o->flags & SEC_RELOC) != 0 - && elf_section_data (o)->rel_hashes != NULL) - free (elf_section_data (o)->rel_hashes); - } - - elf_tdata (abfd)->linker = TRUE; - - return TRUE; - - error_return: - if (finfo.symstrtab != NULL) - _bfd_stringtab_free (finfo.symstrtab); - if (finfo.contents != NULL) - free (finfo.contents); - if (finfo.external_relocs != NULL) - free (finfo.external_relocs); - if (finfo.internal_relocs != NULL) - free (finfo.internal_relocs); - if (finfo.external_syms != NULL) - free (finfo.external_syms); - if (finfo.locsym_shndx != NULL) - free (finfo.locsym_shndx); - if (finfo.internal_syms != NULL) - free (finfo.internal_syms); - if (finfo.indices != NULL) - free (finfo.indices); - if (finfo.sections != NULL) - free (finfo.sections); - if (finfo.symbuf != NULL) - free (finfo.symbuf); - if (finfo.symshndxbuf != NULL) - free (finfo.symshndxbuf); - for (o = abfd->sections; o != NULL; o = o->next) - { - if ((o->flags & SEC_RELOC) != 0 - && elf_section_data (o)->rel_hashes != NULL) - free (elf_section_data (o)->rel_hashes); - } - - return FALSE; -} - -/* Add a symbol to the output symbol table. */ - -static bfd_boolean -elf_link_output_sym (struct elf_final_link_info *finfo, - const char *name, - Elf_Internal_Sym *elfsym, - asection *input_sec, - struct elf_link_hash_entry *h) -{ - bfd_byte *dest; - Elf_External_Sym_Shndx *destshndx; - bfd_boolean (*output_symbol_hook) - (struct bfd_link_info *, const char *, Elf_Internal_Sym *, asection *, - struct elf_link_hash_entry *); - const struct elf_backend_data *bed; - - bed = get_elf_backend_data (finfo->output_bfd); - output_symbol_hook = bed->elf_backend_link_output_symbol_hook; - if (output_symbol_hook != NULL) - { - if (! (*output_symbol_hook) (finfo->info, name, elfsym, input_sec, h)) - return FALSE; - } - - if (name == NULL || *name == '\0') - elfsym->st_name = 0; - else if (input_sec->flags & SEC_EXCLUDE) - elfsym->st_name = 0; - else - { - elfsym->st_name = (unsigned long) _bfd_stringtab_add (finfo->symstrtab, - name, TRUE, FALSE); - if (elfsym->st_name == (unsigned long) -1) - return FALSE; - } - - if (finfo->symbuf_count >= finfo->symbuf_size) - { - if (! elf_link_flush_output_syms (finfo, bed)) - return FALSE; - } - - dest = finfo->symbuf + finfo->symbuf_count * bed->s->sizeof_sym; - destshndx = finfo->symshndxbuf; - if (destshndx != NULL) - { - if (bfd_get_symcount (finfo->output_bfd) >= finfo->shndxbuf_size) - { - bfd_size_type amt; - - amt = finfo->shndxbuf_size * sizeof (Elf_External_Sym_Shndx); - finfo->symshndxbuf = destshndx = bfd_realloc (destshndx, amt * 2); - if (destshndx == NULL) - return FALSE; - memset ((char *) destshndx + amt, 0, amt); - finfo->shndxbuf_size *= 2; - } - destshndx += bfd_get_symcount (finfo->output_bfd); - } - - bed->s->swap_symbol_out (finfo->output_bfd, elfsym, dest, destshndx); - finfo->symbuf_count += 1; - bfd_get_symcount (finfo->output_bfd) += 1; - - return TRUE; -} - -/* Flush the output symbols to the file. */ - -static bfd_boolean -elf_link_flush_output_syms (struct elf_final_link_info *finfo, - const struct elf_backend_data *bed) -{ - if (finfo->symbuf_count > 0) - { - Elf_Internal_Shdr *hdr; - file_ptr pos; - bfd_size_type amt; - - hdr = &elf_tdata (finfo->output_bfd)->symtab_hdr; - pos = hdr->sh_offset + hdr->sh_size; - amt = finfo->symbuf_count * bed->s->sizeof_sym; - if (bfd_seek (finfo->output_bfd, pos, SEEK_SET) != 0 - || bfd_bwrite (finfo->symbuf, amt, finfo->output_bfd) != amt) - return FALSE; - - hdr->sh_size += amt; - finfo->symbuf_count = 0; - } - - return TRUE; -} - -/* For DSOs loaded in via a DT_NEEDED entry, emulate ld.so in - allowing an unsatisfied unversioned symbol in the DSO to match a - versioned symbol that would normally require an explicit version. - We also handle the case that a DSO references a hidden symbol - which may be satisfied by a versioned symbol in another DSO. */ - -static bfd_boolean -elf_link_check_versioned_symbol (struct bfd_link_info *info, - const struct elf_backend_data *bed, - struct elf_link_hash_entry *h) -{ - bfd *abfd; - struct elf_link_loaded_list *loaded; - - if (!is_elf_hash_table (info->hash)) - return FALSE; - - switch (h->root.type) - { - default: - abfd = NULL; - break; - - case bfd_link_hash_undefined: - case bfd_link_hash_undefweak: - abfd = h->root.u.undef.abfd; - if ((abfd->flags & DYNAMIC) == 0 - || elf_dyn_lib_class (abfd) != DYN_DT_NEEDED) - return FALSE; - break; - - case bfd_link_hash_defined: - case bfd_link_hash_defweak: - abfd = h->root.u.def.section->owner; - break; - - case bfd_link_hash_common: - abfd = h->root.u.c.p->section->owner; - break; - } - BFD_ASSERT (abfd != NULL); - - for (loaded = elf_hash_table (info)->loaded; - loaded != NULL; - loaded = loaded->next) - { - bfd *input; - Elf_Internal_Shdr *hdr; - bfd_size_type symcount; - bfd_size_type extsymcount; - bfd_size_type extsymoff; - Elf_Internal_Shdr *versymhdr; - Elf_Internal_Sym *isym; - Elf_Internal_Sym *isymend; - Elf_Internal_Sym *isymbuf; - Elf_External_Versym *ever; - Elf_External_Versym *extversym; - - input = loaded->abfd; - - /* We check each DSO for a possible hidden versioned definition. */ - if (input == abfd - || (input->flags & DYNAMIC) == 0 - || elf_dynversym (input) == 0) - continue; - - hdr = &elf_tdata (input)->dynsymtab_hdr; - - symcount = hdr->sh_size / bed->s->sizeof_sym; - if (elf_bad_symtab (input)) - { - extsymcount = symcount; - extsymoff = 0; - } - else - { - extsymcount = symcount - hdr->sh_info; - extsymoff = hdr->sh_info; - } - - if (extsymcount == 0) - continue; - - isymbuf = bfd_elf_get_elf_syms (input, hdr, extsymcount, extsymoff, - NULL, NULL, NULL); - if (isymbuf == NULL) - return FALSE; - - /* Read in any version definitions. */ - versymhdr = &elf_tdata (input)->dynversym_hdr; - extversym = bfd_malloc (versymhdr->sh_size); - if (extversym == NULL) - goto error_ret; - - if (bfd_seek (input, versymhdr->sh_offset, SEEK_SET) != 0 - || (bfd_bread (extversym, versymhdr->sh_size, input) - != versymhdr->sh_size)) - { - free (extversym); - error_ret: - free (isymbuf); - return FALSE; - } - - ever = extversym + extsymoff; - isymend = isymbuf + extsymcount; - for (isym = isymbuf; isym < isymend; isym++, ever++) - { - const char *name; - Elf_Internal_Versym iver; - unsigned short version_index; - - if (ELF_ST_BIND (isym->st_info) == STB_LOCAL - || isym->st_shndx == SHN_UNDEF) - continue; - - name = bfd_elf_string_from_elf_section (input, - hdr->sh_link, - isym->st_name); - if (strcmp (name, h->root.root.string) != 0) - continue; - - _bfd_elf_swap_versym_in (input, ever, &iver); - - if ((iver.vs_vers & VERSYM_HIDDEN) == 0) - { - /* If we have a non-hidden versioned sym, then it should - have provided a definition for the undefined sym. */ - abort (); - } - - version_index = iver.vs_vers & VERSYM_VERSION; - if (version_index == 1 || version_index == 2) - { - /* This is the base or first version. We can use it. */ - free (extversym); - free (isymbuf); - return TRUE; - } - } - - free (extversym); - free (isymbuf); - } - - return FALSE; -} - -/* Add an external symbol to the symbol table. This is called from - the hash table traversal routine. When generating a shared object, - we go through the symbol table twice. The first time we output - anything that might have been forced to local scope in a version - script. The second time we output the symbols that are still - global symbols. */ - -static bfd_boolean -elf_link_output_extsym (struct elf_link_hash_entry *h, void *data) -{ - struct elf_outext_info *eoinfo = data; - struct elf_final_link_info *finfo = eoinfo->finfo; - bfd_boolean strip; - Elf_Internal_Sym sym; - asection *input_sec; - const struct elf_backend_data *bed; - - if (h->root.type == bfd_link_hash_warning) - { - h = (struct elf_link_hash_entry *) h->root.u.i.link; - if (h->root.type == bfd_link_hash_new) - return TRUE; - } - - /* Decide whether to output this symbol in this pass. */ - if (eoinfo->localsyms) - { - if ((h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) - return TRUE; - } - else - { - if ((h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0) - return TRUE; - } - - bed = get_elf_backend_data (finfo->output_bfd); - - /* If we have an undefined symbol reference here then it must have - come from a shared library that is being linked in. (Undefined - references in regular files have already been handled). If we - are reporting errors for this situation then do so now. */ - if (h->root.type == bfd_link_hash_undefined - && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0 - && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0 - && ! elf_link_check_versioned_symbol (finfo->info, bed, h) - && finfo->info->unresolved_syms_in_shared_libs != RM_IGNORE) - { - if (! ((*finfo->info->callbacks->undefined_symbol) - (finfo->info, h->root.root.string, h->root.u.undef.abfd, - NULL, 0, finfo->info->unresolved_syms_in_shared_libs == RM_GENERATE_ERROR))) - { - eoinfo->failed = TRUE; - return FALSE; - } - } - - /* We should also warn if a forced local symbol is referenced from - shared libraries. */ - if (! finfo->info->relocatable - && (! finfo->info->shared) - && (h->elf_link_hash_flags - & (ELF_LINK_FORCED_LOCAL | ELF_LINK_HASH_REF_DYNAMIC | ELF_LINK_DYNAMIC_DEF | ELF_LINK_DYNAMIC_WEAK)) - == (ELF_LINK_FORCED_LOCAL | ELF_LINK_HASH_REF_DYNAMIC) - && ! elf_link_check_versioned_symbol (finfo->info, bed, h)) - { - (*_bfd_error_handler) - (_("%s: %s symbol `%s' in %s is referenced by DSO"), - bfd_get_filename (finfo->output_bfd), - ELF_ST_VISIBILITY (h->other) == STV_INTERNAL - ? "internal" - : ELF_ST_VISIBILITY (h->other) == STV_HIDDEN - ? "hidden" : "local", - h->root.root.string, - bfd_archive_filename (h->root.u.def.section->owner)); - eoinfo->failed = TRUE; - return FALSE; - } - - /* We don't want to output symbols that have never been mentioned by - a regular file, or that we have been told to strip. However, if - h->indx is set to -2, the symbol is used by a reloc and we must - output it. */ - if (h->indx == -2) - strip = FALSE; - else if (((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0 - || (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) != 0) - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0 - && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) == 0) - strip = TRUE; - else if (finfo->info->strip == strip_all) - strip = TRUE; - else if (finfo->info->strip == strip_some - && bfd_hash_lookup (finfo->info->keep_hash, - h->root.root.string, FALSE, FALSE) == NULL) - strip = TRUE; - else if (finfo->info->strip_discarded - && (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - && elf_discarded_section (h->root.u.def.section)) - strip = TRUE; - else - strip = FALSE; - - /* If we're stripping it, and it's not a dynamic symbol, there's - nothing else to do unless it is a forced local symbol. */ - if (strip - && h->dynindx == -1 - && (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) - return TRUE; - - sym.st_value = 0; - sym.st_size = h->size; - sym.st_other = h->other; - if ((h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0) - sym.st_info = ELF_ST_INFO (STB_LOCAL, h->type); - else if (h->root.type == bfd_link_hash_undefweak - || h->root.type == bfd_link_hash_defweak) - sym.st_info = ELF_ST_INFO (STB_WEAK, h->type); - else - sym.st_info = ELF_ST_INFO (STB_GLOBAL, h->type); - - switch (h->root.type) - { - default: - case bfd_link_hash_new: - case bfd_link_hash_warning: - abort (); - return FALSE; - - case bfd_link_hash_undefined: - case bfd_link_hash_undefweak: - input_sec = bfd_und_section_ptr; - sym.st_shndx = SHN_UNDEF; - break; - - case bfd_link_hash_defined: - case bfd_link_hash_defweak: - { - input_sec = h->root.u.def.section; - if (input_sec->output_section != NULL) - { - sym.st_shndx = - _bfd_elf_section_from_bfd_section (finfo->output_bfd, - input_sec->output_section); - if (sym.st_shndx == SHN_BAD) - { - (*_bfd_error_handler) - (_("%s: could not find output section %s for input section %s"), - bfd_get_filename (finfo->output_bfd), - input_sec->output_section->name, - input_sec->name); - eoinfo->failed = TRUE; - return FALSE; - } - - /* ELF symbols in relocatable files are section relative, - but in nonrelocatable files they are virtual - addresses. */ - sym.st_value = h->root.u.def.value + input_sec->output_offset; - if (! finfo->info->relocatable) - { - sym.st_value += input_sec->output_section->vma; - if (h->type == STT_TLS) - { - /* STT_TLS symbols are relative to PT_TLS segment - base. */ - BFD_ASSERT (elf_hash_table (finfo->info)->tls_sec != NULL); - sym.st_value -= elf_hash_table (finfo->info)->tls_sec->vma; - } - } - } - else - { - BFD_ASSERT (input_sec->owner == NULL - || (input_sec->owner->flags & DYNAMIC) != 0); - sym.st_shndx = SHN_UNDEF; - input_sec = bfd_und_section_ptr; - } - } - break; - - case bfd_link_hash_common: - input_sec = h->root.u.c.p->section; - sym.st_shndx = SHN_COMMON; - sym.st_value = 1 << h->root.u.c.p->alignment_power; - break; - - case bfd_link_hash_indirect: - /* These symbols are created by symbol versioning. They point - to the decorated version of the name. For example, if the - symbol foo@@GNU_1.2 is the default, which should be used when - foo is used with no version, then we add an indirect symbol - foo which points to foo@@GNU_1.2. We ignore these symbols, - since the indirected symbol is already in the hash table. */ - return TRUE; - } - - /* Give the processor backend a chance to tweak the symbol value, - and also to finish up anything that needs to be done for this - symbol. FIXME: Not calling elf_backend_finish_dynamic_symbol for - forced local syms when non-shared is due to a historical quirk. */ - if ((h->dynindx != -1 - || (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0) - && ((finfo->info->shared - && (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT - || h->root.type != bfd_link_hash_undefweak)) - || (h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) == 0) - && elf_hash_table (finfo->info)->dynamic_sections_created) - { - if (! ((*bed->elf_backend_finish_dynamic_symbol) - (finfo->output_bfd, finfo->info, h, &sym))) - { - eoinfo->failed = TRUE; - return FALSE; - } - } - - /* If we are marking the symbol as undefined, and there are no - non-weak references to this symbol from a regular object, then - mark the symbol as weak undefined; if there are non-weak - references, mark the symbol as strong. We can't do this earlier, - because it might not be marked as undefined until the - finish_dynamic_symbol routine gets through with it. */ - if (sym.st_shndx == SHN_UNDEF - && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR) != 0 - && (ELF_ST_BIND (sym.st_info) == STB_GLOBAL - || ELF_ST_BIND (sym.st_info) == STB_WEAK)) - { - int bindtype; - - if ((h->elf_link_hash_flags & ELF_LINK_HASH_REF_REGULAR_NONWEAK) != 0) - bindtype = STB_GLOBAL; - else - bindtype = STB_WEAK; - sym.st_info = ELF_ST_INFO (bindtype, ELF_ST_TYPE (sym.st_info)); - } - - /* If a non-weak symbol with non-default visibility is not defined - locally, it is a fatal error. */ - if (! finfo->info->relocatable - && ELF_ST_VISIBILITY (sym.st_other) != STV_DEFAULT - && ELF_ST_BIND (sym.st_info) != STB_WEAK - && h->root.type == bfd_link_hash_undefined - && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) - { - (*_bfd_error_handler) - (_("%s: %s symbol `%s' isn't defined"), - bfd_get_filename (finfo->output_bfd), - ELF_ST_VISIBILITY (sym.st_other) == STV_PROTECTED - ? "protected" - : ELF_ST_VISIBILITY (sym.st_other) == STV_INTERNAL - ? "internal" : "hidden", - h->root.root.string); - eoinfo->failed = TRUE; - return FALSE; - } - - /* If this symbol should be put in the .dynsym section, then put it - there now. We already know the symbol index. We also fill in - the entry in the .hash section. */ - if (h->dynindx != -1 - && elf_hash_table (finfo->info)->dynamic_sections_created) - { - size_t bucketcount; - size_t bucket; - size_t hash_entry_size; - bfd_byte *bucketpos; - bfd_vma chain; - bfd_byte *esym; - - sym.st_name = h->dynstr_index; - esym = finfo->dynsym_sec->contents + h->dynindx * bed->s->sizeof_sym; - bed->s->swap_symbol_out (finfo->output_bfd, &sym, esym, 0); - - bucketcount = elf_hash_table (finfo->info)->bucketcount; - bucket = h->elf_hash_value % bucketcount; - hash_entry_size - = elf_section_data (finfo->hash_sec)->this_hdr.sh_entsize; - bucketpos = ((bfd_byte *) finfo->hash_sec->contents - + (bucket + 2) * hash_entry_size); - chain = bfd_get (8 * hash_entry_size, finfo->output_bfd, bucketpos); - bfd_put (8 * hash_entry_size, finfo->output_bfd, h->dynindx, bucketpos); - bfd_put (8 * hash_entry_size, finfo->output_bfd, chain, - ((bfd_byte *) finfo->hash_sec->contents - + (bucketcount + 2 + h->dynindx) * hash_entry_size)); - - if (finfo->symver_sec != NULL && finfo->symver_sec->contents != NULL) - { - Elf_Internal_Versym iversym; - Elf_External_Versym *eversym; - - if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) - { - if (h->verinfo.verdef == NULL) - iversym.vs_vers = 0; - else - iversym.vs_vers = h->verinfo.verdef->vd_exp_refno + 1; - } - else - { - if (h->verinfo.vertree == NULL) - iversym.vs_vers = 1; - else - iversym.vs_vers = h->verinfo.vertree->vernum + 1; - } - - if ((h->elf_link_hash_flags & ELF_LINK_HIDDEN) != 0) - iversym.vs_vers |= VERSYM_HIDDEN; - - eversym = (Elf_External_Versym *) finfo->symver_sec->contents; - eversym += h->dynindx; - _bfd_elf_swap_versym_out (finfo->output_bfd, &iversym, eversym); - } - } - - /* If we're stripping it, then it was just a dynamic symbol, and - there's nothing else to do. */ - if (strip || (input_sec->flags & SEC_EXCLUDE) != 0) - return TRUE; - - h->indx = bfd_get_symcount (finfo->output_bfd); - - if (! elf_link_output_sym (finfo, h->root.root.string, &sym, input_sec, h)) - { - eoinfo->failed = TRUE; - return FALSE; - } - - return TRUE; -} - -/* Link an input file into the linker output file. This function - handles all the sections and relocations of the input file at once. - This is so that we only have to read the local symbols once, and - don't have to keep them in memory. */ - -static bfd_boolean -elf_link_input_bfd (struct elf_final_link_info *finfo, bfd *input_bfd) -{ - bfd_boolean (*relocate_section) - (bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, - Elf_Internal_Rela *, Elf_Internal_Sym *, asection **); - bfd *output_bfd; - Elf_Internal_Shdr *symtab_hdr; - size_t locsymcount; - size_t extsymoff; - Elf_Internal_Sym *isymbuf; - Elf_Internal_Sym *isym; - Elf_Internal_Sym *isymend; - long *pindex; - asection **ppsection; - asection *o; - const struct elf_backend_data *bed; - bfd_boolean emit_relocs; - struct elf_link_hash_entry **sym_hashes; - - output_bfd = finfo->output_bfd; - bed = get_elf_backend_data (output_bfd); - relocate_section = bed->elf_backend_relocate_section; - - /* If this is a dynamic object, we don't want to do anything here: - we don't want the local symbols, and we don't want the section - contents. */ - if ((input_bfd->flags & DYNAMIC) != 0) - return TRUE; - - emit_relocs = (finfo->info->relocatable - || finfo->info->emitrelocations - || bed->elf_backend_emit_relocs); - - symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; - if (elf_bad_symtab (input_bfd)) - { - locsymcount = symtab_hdr->sh_size / bed->s->sizeof_sym; - extsymoff = 0; - } - else - { - locsymcount = symtab_hdr->sh_info; - extsymoff = symtab_hdr->sh_info; - } - - /* Read the local symbols. */ - isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents; - if (isymbuf == NULL && locsymcount != 0) - { - isymbuf = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, locsymcount, 0, - finfo->internal_syms, - finfo->external_syms, - finfo->locsym_shndx); - if (isymbuf == NULL) - return FALSE; - } - - /* Find local symbol sections and adjust values of symbols in - SEC_MERGE sections. Write out those local symbols we know are - going into the output file. */ - isymend = isymbuf + locsymcount; - for (isym = isymbuf, pindex = finfo->indices, ppsection = finfo->sections; - isym < isymend; - isym++, pindex++, ppsection++) - { - asection *isec; - const char *name; - Elf_Internal_Sym osym; - - *pindex = -1; - - if (elf_bad_symtab (input_bfd)) - { - if (ELF_ST_BIND (isym->st_info) != STB_LOCAL) - { - *ppsection = NULL; - continue; - } - } - - if (isym->st_shndx == SHN_UNDEF) - isec = bfd_und_section_ptr; - else if (isym->st_shndx < SHN_LORESERVE - || isym->st_shndx > SHN_HIRESERVE) - { - isec = bfd_section_from_elf_index (input_bfd, isym->st_shndx); - if (isec - && isec->sec_info_type == ELF_INFO_TYPE_MERGE - && ELF_ST_TYPE (isym->st_info) != STT_SECTION) - isym->st_value = - _bfd_merged_section_offset (output_bfd, &isec, - elf_section_data (isec)->sec_info, - isym->st_value, 0); - } - else if (isym->st_shndx == SHN_ABS) - isec = bfd_abs_section_ptr; - else if (isym->st_shndx == SHN_COMMON) - isec = bfd_com_section_ptr; - else - { - /* Who knows? */ - isec = NULL; - } - - *ppsection = isec; - - /* Don't output the first, undefined, symbol. */ - if (ppsection == finfo->sections) - continue; - - if (ELF_ST_TYPE (isym->st_info) == STT_SECTION) - { - /* We never output section symbols. Instead, we use the - section symbol of the corresponding section in the output - file. */ - continue; - } - - /* If we are stripping all symbols, we don't want to output this - one. */ - if (finfo->info->strip == strip_all) - continue; - - /* If we are discarding all local symbols, we don't want to - output this one. If we are generating a relocatable output - file, then some of the local symbols may be required by - relocs; we output them below as we discover that they are - needed. */ - if (finfo->info->discard == discard_all) - continue; - - /* If this symbol is defined in a section which we are - discarding, we don't need to keep it, but note that - linker_mark is only reliable for sections that have contents. - For the benefit of the MIPS ELF linker, we check SEC_EXCLUDE - as well as linker_mark. */ - if ((isym->st_shndx < SHN_LORESERVE || isym->st_shndx > SHN_HIRESERVE) - && isec != NULL - && ((! isec->linker_mark && (isec->flags & SEC_HAS_CONTENTS) != 0) - || (! finfo->info->relocatable - && (isec->flags & SEC_EXCLUDE) != 0))) - continue; - - /* Get the name of the symbol. */ - name = bfd_elf_string_from_elf_section (input_bfd, symtab_hdr->sh_link, - isym->st_name); - if (name == NULL) - return FALSE; - - /* See if we are discarding symbols with this name. */ - if ((finfo->info->strip == strip_some - && (bfd_hash_lookup (finfo->info->keep_hash, name, FALSE, FALSE) - == NULL)) - || (((finfo->info->discard == discard_sec_merge - && (isec->flags & SEC_MERGE) && ! finfo->info->relocatable) - || finfo->info->discard == discard_l) - && bfd_is_local_label_name (input_bfd, name))) - continue; - - /* If we get here, we are going to output this symbol. */ - - osym = *isym; - - /* Adjust the section index for the output file. */ - osym.st_shndx = _bfd_elf_section_from_bfd_section (output_bfd, - isec->output_section); - if (osym.st_shndx == SHN_BAD) - return FALSE; - - *pindex = bfd_get_symcount (output_bfd); - - /* ELF symbols in relocatable files are section relative, but - in executable files they are virtual addresses. Note that - this code assumes that all ELF sections have an associated - BFD section with a reasonable value for output_offset; below - we assume that they also have a reasonable value for - output_section. Any special sections must be set up to meet - these requirements. */ - osym.st_value += isec->output_offset; - if (! finfo->info->relocatable) - { - osym.st_value += isec->output_section->vma; - if (ELF_ST_TYPE (osym.st_info) == STT_TLS) - { - /* STT_TLS symbols are relative to PT_TLS segment base. */ - BFD_ASSERT (elf_hash_table (finfo->info)->tls_sec != NULL); - osym.st_value -= elf_hash_table (finfo->info)->tls_sec->vma; - } - } - - if (! elf_link_output_sym (finfo, name, &osym, isec, NULL)) - return FALSE; - } - - /* Relocate the contents of each section. */ - sym_hashes = elf_sym_hashes (input_bfd); - for (o = input_bfd->sections; o != NULL; o = o->next) - { - bfd_byte *contents; - - if (! o->linker_mark) - { - /* This section was omitted from the link. */ - continue; - } - - if ((o->flags & SEC_HAS_CONTENTS) == 0 - || (o->_raw_size == 0 && (o->flags & SEC_RELOC) == 0)) - continue; - - if ((o->flags & SEC_LINKER_CREATED) != 0) - { - /* Section was created by _bfd_elf_link_create_dynamic_sections - or somesuch. */ - continue; - } - - /* Get the contents of the section. They have been cached by a - relaxation routine. Note that o is a section in an input - file, so the contents field will not have been set by any of - the routines which work on output files. */ - if (elf_section_data (o)->this_hdr.contents != NULL) - contents = elf_section_data (o)->this_hdr.contents; - else - { - contents = finfo->contents; - if (! bfd_get_section_contents (input_bfd, o, contents, 0, - o->_raw_size)) - return FALSE; - } - - if ((o->flags & SEC_RELOC) != 0) - { - Elf_Internal_Rela *internal_relocs; - bfd_vma r_type_mask; - int r_sym_shift; - - /* Get the swapped relocs. */ - internal_relocs - = _bfd_elf_link_read_relocs (input_bfd, o, finfo->external_relocs, - finfo->internal_relocs, FALSE); - if (internal_relocs == NULL - && o->reloc_count > 0) - return FALSE; - - if (bed->s->arch_size == 32) - { - r_type_mask = 0xff; - r_sym_shift = 8; - } - else - { - r_type_mask = 0xffffffff; - r_sym_shift = 32; - } - - /* Run through the relocs looking for any against symbols - from discarded sections and section symbols from - removed link-once sections. Complain about relocs - against discarded sections. Zero relocs against removed - link-once sections. Preserve debug information as much - as we can. */ - if (!elf_section_ignore_discarded_relocs (o)) - { - Elf_Internal_Rela *rel, *relend; - - rel = internal_relocs; - relend = rel + o->reloc_count * bed->s->int_rels_per_ext_rel; - for ( ; rel < relend; rel++) - { - unsigned long r_symndx = rel->r_info >> r_sym_shift; - asection *sec; - - if (r_symndx >= locsymcount - || (elf_bad_symtab (input_bfd) - && finfo->sections[r_symndx] == NULL)) - { - struct elf_link_hash_entry *h; - - h = sym_hashes[r_symndx - extsymoff]; - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - - /* Complain if the definition comes from a - discarded section. */ - sec = h->root.u.def.section; - if ((h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - && elf_discarded_section (sec)) - { - if ((o->flags & SEC_DEBUGGING) != 0) - { - BFD_ASSERT (r_symndx != 0); - /* Try to preserve debug information. */ - if ((o->flags & SEC_DEBUGGING) != 0 - && sec->kept_section != NULL - && sec->_raw_size == sec->kept_section->_raw_size) - h->root.u.def.section - = sec->kept_section; - else - memset (rel, 0, sizeof (*rel)); - } - else - finfo->info->callbacks->error_handler - (LD_DEFINITION_IN_DISCARDED_SECTION, - _("%T: discarded in section `%s' from %s\n"), - h->root.root.string, - h->root.root.string, - h->root.u.def.section->name, - bfd_archive_filename (h->root.u.def.section->owner)); - } - } - else - { - sec = finfo->sections[r_symndx]; - - if (sec != NULL && elf_discarded_section (sec)) - { - if ((o->flags & SEC_DEBUGGING) != 0 - || (sec->flags & SEC_LINK_ONCE) != 0) - { - BFD_ASSERT (r_symndx != 0); - /* Try to preserve debug information. */ - if ((o->flags & SEC_DEBUGGING) != 0 - && sec->kept_section != NULL - && sec->_raw_size == sec->kept_section->_raw_size) - finfo->sections[r_symndx] - = sec->kept_section; - else - { - rel->r_info &= r_type_mask; - rel->r_addend = 0; - } - } - else - { - static int count; - int ok; - char *buf; - - ok = asprintf (&buf, "local symbol %d", - count++); - if (ok <= 0) - buf = (char *) "local symbol"; - finfo->info->callbacks->error_handler - (LD_DEFINITION_IN_DISCARDED_SECTION, - _("%T: discarded in section `%s' from %s\n"), - buf, buf, sec->name, - bfd_archive_filename (input_bfd)); - if (ok != -1) - free (buf); - } - } - } - } - } - - /* Relocate the section by invoking a back end routine. - - The back end routine is responsible for adjusting the - section contents as necessary, and (if using Rela relocs - and generating a relocatable output file) adjusting the - reloc addend as necessary. - - The back end routine does not have to worry about setting - the reloc address or the reloc symbol index. - - The back end routine is given a pointer to the swapped in - internal symbols, and can access the hash table entries - for the external symbols via elf_sym_hashes (input_bfd). - - When generating relocatable output, the back end routine - must handle STB_LOCAL/STT_SECTION symbols specially. The - output symbol is going to be a section symbol - corresponding to the output section, which will require - the addend to be adjusted. */ - - if (! (*relocate_section) (output_bfd, finfo->info, - input_bfd, o, contents, - internal_relocs, - isymbuf, - finfo->sections)) - return FALSE; - - if (emit_relocs) - { - Elf_Internal_Rela *irela; - Elf_Internal_Rela *irelaend; - bfd_vma last_offset; - struct elf_link_hash_entry **rel_hash; - Elf_Internal_Shdr *input_rel_hdr, *input_rel_hdr2; - unsigned int next_erel; - bfd_boolean (*reloc_emitter) - (bfd *, asection *, Elf_Internal_Shdr *, Elf_Internal_Rela *); - bfd_boolean rela_normal; - - input_rel_hdr = &elf_section_data (o)->rel_hdr; - rela_normal = (bed->rela_normal - && (input_rel_hdr->sh_entsize - == bed->s->sizeof_rela)); - - /* Adjust the reloc addresses and symbol indices. */ - - irela = internal_relocs; - irelaend = irela + o->reloc_count * bed->s->int_rels_per_ext_rel; - rel_hash = (elf_section_data (o->output_section)->rel_hashes - + elf_section_data (o->output_section)->rel_count - + elf_section_data (o->output_section)->rel_count2); - last_offset = o->output_offset; - if (!finfo->info->relocatable) - last_offset += o->output_section->vma; - for (next_erel = 0; irela < irelaend; irela++, next_erel++) - { - unsigned long r_symndx; - asection *sec; - Elf_Internal_Sym sym; - - if (next_erel == bed->s->int_rels_per_ext_rel) - { - rel_hash++; - next_erel = 0; - } - - irela->r_offset = _bfd_elf_section_offset (output_bfd, - finfo->info, o, - irela->r_offset); - if (irela->r_offset >= (bfd_vma) -2) - { - /* This is a reloc for a deleted entry or somesuch. - Turn it into an R_*_NONE reloc, at the same - offset as the last reloc. elf_eh_frame.c and - elf_bfd_discard_info rely on reloc offsets - being ordered. */ - irela->r_offset = last_offset; - irela->r_info = 0; - irela->r_addend = 0; - continue; - } - - irela->r_offset += o->output_offset; - - /* Relocs in an executable have to be virtual addresses. */ - if (!finfo->info->relocatable) - irela->r_offset += o->output_section->vma; - - last_offset = irela->r_offset; - - r_symndx = irela->r_info >> r_sym_shift; - if (r_symndx == STN_UNDEF) - continue; - - if (r_symndx >= locsymcount - || (elf_bad_symtab (input_bfd) - && finfo->sections[r_symndx] == NULL)) - { - struct elf_link_hash_entry *rh; - unsigned long indx; - - /* This is a reloc against a global symbol. We - have not yet output all the local symbols, so - we do not know the symbol index of any global - symbol. We set the rel_hash entry for this - reloc to point to the global hash table entry - for this symbol. The symbol index is then - set at the end of elf_bfd_final_link. */ - indx = r_symndx - extsymoff; - rh = elf_sym_hashes (input_bfd)[indx]; - while (rh->root.type == bfd_link_hash_indirect - || rh->root.type == bfd_link_hash_warning) - rh = (struct elf_link_hash_entry *) rh->root.u.i.link; - - /* Setting the index to -2 tells - elf_link_output_extsym that this symbol is - used by a reloc. */ - BFD_ASSERT (rh->indx < 0); - rh->indx = -2; - - *rel_hash = rh; - - continue; - } - - /* This is a reloc against a local symbol. */ - - *rel_hash = NULL; - sym = isymbuf[r_symndx]; - sec = finfo->sections[r_symndx]; - if (ELF_ST_TYPE (sym.st_info) == STT_SECTION) - { - /* I suppose the backend ought to fill in the - section of any STT_SECTION symbol against a - processor specific section. If we have - discarded a section, the output_section will - be the absolute section. */ - if (bfd_is_abs_section (sec) - || (sec != NULL - && bfd_is_abs_section (sec->output_section))) - r_symndx = 0; - else if (sec == NULL || sec->owner == NULL) - { - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - else - { - r_symndx = sec->output_section->target_index; - BFD_ASSERT (r_symndx != 0); - } - - /* Adjust the addend according to where the - section winds up in the output section. */ - if (rela_normal) - irela->r_addend += sec->output_offset; - } - else - { - if (finfo->indices[r_symndx] == -1) - { - unsigned long shlink; - const char *name; - asection *osec; - - if (finfo->info->strip == strip_all) - { - /* You can't do ld -r -s. */ - bfd_set_error (bfd_error_invalid_operation); - return FALSE; - } - - /* This symbol was skipped earlier, but - since it is needed by a reloc, we - must output it now. */ - shlink = symtab_hdr->sh_link; - name = (bfd_elf_string_from_elf_section - (input_bfd, shlink, sym.st_name)); - if (name == NULL) - return FALSE; - - osec = sec->output_section; - sym.st_shndx = - _bfd_elf_section_from_bfd_section (output_bfd, - osec); - if (sym.st_shndx == SHN_BAD) - return FALSE; - - sym.st_value += sec->output_offset; - if (! finfo->info->relocatable) - { - sym.st_value += osec->vma; - if (ELF_ST_TYPE (sym.st_info) == STT_TLS) - { - /* STT_TLS symbols are relative to PT_TLS - segment base. */ - BFD_ASSERT (elf_hash_table (finfo->info) - ->tls_sec != NULL); - sym.st_value -= (elf_hash_table (finfo->info) - ->tls_sec->vma); - } - } - - finfo->indices[r_symndx] - = bfd_get_symcount (output_bfd); - - if (! elf_link_output_sym (finfo, name, &sym, sec, - NULL)) - return FALSE; - } - - r_symndx = finfo->indices[r_symndx]; - } - - irela->r_info = ((bfd_vma) r_symndx << r_sym_shift - | (irela->r_info & r_type_mask)); - } - - /* Swap out the relocs. */ - if (bed->elf_backend_emit_relocs - && !(finfo->info->relocatable - || finfo->info->emitrelocations)) - reloc_emitter = bed->elf_backend_emit_relocs; - else - reloc_emitter = _bfd_elf_link_output_relocs; - - if (input_rel_hdr->sh_size != 0 - && ! (*reloc_emitter) (output_bfd, o, input_rel_hdr, - internal_relocs)) - return FALSE; - - input_rel_hdr2 = elf_section_data (o)->rel_hdr2; - if (input_rel_hdr2 && input_rel_hdr2->sh_size != 0) - { - internal_relocs += (NUM_SHDR_ENTRIES (input_rel_hdr) - * bed->s->int_rels_per_ext_rel); - if (! (*reloc_emitter) (output_bfd, o, input_rel_hdr2, - internal_relocs)) - return FALSE; - } - } - } - - /* Write out the modified section contents. */ - if (bed->elf_backend_write_section - && (*bed->elf_backend_write_section) (output_bfd, o, contents)) - { - /* Section written out. */ - } - else switch (o->sec_info_type) - { - case ELF_INFO_TYPE_STABS: - if (! (_bfd_write_section_stabs - (output_bfd, - &elf_hash_table (finfo->info)->stab_info, - o, &elf_section_data (o)->sec_info, contents))) - return FALSE; - break; - case ELF_INFO_TYPE_MERGE: - if (! _bfd_write_merged_section (output_bfd, o, - elf_section_data (o)->sec_info)) - return FALSE; - break; - case ELF_INFO_TYPE_EH_FRAME: - { - if (! _bfd_elf_write_section_eh_frame (output_bfd, finfo->info, - o, contents)) - return FALSE; - } - break; - default: - { - bfd_size_type sec_size; - - sec_size = (o->_cooked_size != 0 ? o->_cooked_size : o->_raw_size); - if (! (o->flags & SEC_EXCLUDE) - && ! bfd_set_section_contents (output_bfd, o->output_section, - contents, - (file_ptr) o->output_offset, - sec_size)) - return FALSE; - } - break; - } - } - - return TRUE; -} - -/* Generate a reloc when linking an ELF file. This is a reloc - requested by the linker, and does come from any input file. This - is used to build constructor and destructor tables when linking - with -Ur. */ - -static bfd_boolean -elf_reloc_link_order (bfd *output_bfd, - struct bfd_link_info *info, - asection *output_section, - struct bfd_link_order *link_order) -{ - reloc_howto_type *howto; - long indx; - bfd_vma offset; - bfd_vma addend; - struct elf_link_hash_entry **rel_hash_ptr; - Elf_Internal_Shdr *rel_hdr; - const struct elf_backend_data *bed = get_elf_backend_data (output_bfd); - Elf_Internal_Rela irel[MAX_INT_RELS_PER_EXT_REL]; - bfd_byte *erel; - unsigned int i; - - howto = bfd_reloc_type_lookup (output_bfd, link_order->u.reloc.p->reloc); - if (howto == NULL) - { - bfd_set_error (bfd_error_bad_value); - return FALSE; - } - - addend = link_order->u.reloc.p->addend; - - /* Figure out the symbol index. */ - rel_hash_ptr = (elf_section_data (output_section)->rel_hashes - + elf_section_data (output_section)->rel_count - + elf_section_data (output_section)->rel_count2); - if (link_order->type == bfd_section_reloc_link_order) - { - indx = link_order->u.reloc.p->u.section->target_index; - BFD_ASSERT (indx != 0); - *rel_hash_ptr = NULL; - } - else - { - struct elf_link_hash_entry *h; - - /* Treat a reloc against a defined symbol as though it were - actually against the section. */ - h = ((struct elf_link_hash_entry *) - bfd_wrapped_link_hash_lookup (output_bfd, info, - link_order->u.reloc.p->u.name, - FALSE, FALSE, TRUE)); - if (h != NULL - && (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak)) - { - asection *section; - - section = h->root.u.def.section; - indx = section->output_section->target_index; - *rel_hash_ptr = NULL; - /* It seems that we ought to add the symbol value to the - addend here, but in practice it has already been added - because it was passed to constructor_callback. */ - addend += section->output_section->vma + section->output_offset; - } - else if (h != NULL) - { - /* Setting the index to -2 tells elf_link_output_extsym that - this symbol is used by a reloc. */ - h->indx = -2; - *rel_hash_ptr = h; - indx = 0; - } - else - { - if (! ((*info->callbacks->unattached_reloc) - (info, link_order->u.reloc.p->u.name, NULL, NULL, 0))) - return FALSE; - indx = 0; - } - } - - /* If this is an inplace reloc, we must write the addend into the - object file. */ - if (howto->partial_inplace && addend != 0) - { - bfd_size_type size; - bfd_reloc_status_type rstat; - bfd_byte *buf; - bfd_boolean ok; - const char *sym_name; - - size = bfd_get_reloc_size (howto); - buf = bfd_zmalloc (size); - if (buf == NULL) - return FALSE; - rstat = _bfd_relocate_contents (howto, output_bfd, addend, buf); - switch (rstat) - { - case bfd_reloc_ok: - break; - - default: - case bfd_reloc_outofrange: - abort (); - - case bfd_reloc_overflow: - if (link_order->type == bfd_section_reloc_link_order) - sym_name = bfd_section_name (output_bfd, - link_order->u.reloc.p->u.section); - else - sym_name = link_order->u.reloc.p->u.name; - if (! ((*info->callbacks->reloc_overflow) - (info, sym_name, howto->name, addend, NULL, NULL, 0))) - { - free (buf); - return FALSE; - } - break; - } - ok = bfd_set_section_contents (output_bfd, output_section, buf, - link_order->offset, size); - free (buf); - if (! ok) - return FALSE; - } - - /* The address of a reloc is relative to the section in a - relocatable file, and is a virtual address in an executable - file. */ - offset = link_order->offset; - if (! info->relocatable) - offset += output_section->vma; - - for (i = 0; i < bed->s->int_rels_per_ext_rel; i++) - { - irel[i].r_offset = offset; - irel[i].r_info = 0; - irel[i].r_addend = 0; - } - if (bed->s->arch_size == 32) - irel[0].r_info = ELF32_R_INFO (indx, howto->type); - else - irel[0].r_info = ELF64_R_INFO (indx, howto->type); - - rel_hdr = &elf_section_data (output_section)->rel_hdr; - erel = rel_hdr->contents; - if (rel_hdr->sh_type == SHT_REL) - { - erel += (elf_section_data (output_section)->rel_count - * bed->s->sizeof_rel); - (*bed->s->swap_reloc_out) (output_bfd, irel, erel); - } - else - { - irel[0].r_addend = addend; - erel += (elf_section_data (output_section)->rel_count - * bed->s->sizeof_rela); - (*bed->s->swap_reloca_out) (output_bfd, irel, erel); - } - - ++elf_section_data (output_section)->rel_count; - - return TRUE; -} - -/* Garbage collect unused sections. */ - -static bfd_boolean elf_gc_sweep_symbol - (struct elf_link_hash_entry *, void *); - -static bfd_boolean elf_gc_allocate_got_offsets - (struct elf_link_hash_entry *, void *); - -/* The mark phase of garbage collection. For a given section, mark - it and any sections in this section's group, and all the sections - which define symbols to which it refers. */ - -typedef asection * (*gc_mark_hook_fn) - (asection *, struct bfd_link_info *, Elf_Internal_Rela *, - struct elf_link_hash_entry *, Elf_Internal_Sym *); - -static bfd_boolean -elf_gc_mark (struct bfd_link_info *info, - asection *sec, - gc_mark_hook_fn gc_mark_hook) -{ - bfd_boolean ret; - asection *group_sec; - - sec->gc_mark = 1; - - /* Mark all the sections in the group. */ - group_sec = elf_section_data (sec)->next_in_group; - if (group_sec && !group_sec->gc_mark) - if (!elf_gc_mark (info, group_sec, gc_mark_hook)) - return FALSE; - - /* Look through the section relocs. */ - ret = TRUE; - if ((sec->flags & SEC_RELOC) != 0 && sec->reloc_count > 0) - { - Elf_Internal_Rela *relstart, *rel, *relend; - Elf_Internal_Shdr *symtab_hdr; - struct elf_link_hash_entry **sym_hashes; - size_t nlocsyms; - size_t extsymoff; - bfd *input_bfd = sec->owner; - const struct elf_backend_data *bed = get_elf_backend_data (input_bfd); - Elf_Internal_Sym *isym = NULL; - int r_sym_shift; - - symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; - sym_hashes = elf_sym_hashes (input_bfd); - - /* Read the local symbols. */ - if (elf_bad_symtab (input_bfd)) - { - nlocsyms = symtab_hdr->sh_size / bed->s->sizeof_sym; - extsymoff = 0; - } - else - extsymoff = nlocsyms = symtab_hdr->sh_info; - - isym = (Elf_Internal_Sym *) symtab_hdr->contents; - if (isym == NULL && nlocsyms != 0) - { - isym = bfd_elf_get_elf_syms (input_bfd, symtab_hdr, nlocsyms, 0, - NULL, NULL, NULL); - if (isym == NULL) - return FALSE; - } - - /* Read the relocations. */ - relstart = _bfd_elf_link_read_relocs (input_bfd, sec, NULL, NULL, - info->keep_memory); - if (relstart == NULL) - { - ret = FALSE; - goto out1; - } - relend = relstart + sec->reloc_count * bed->s->int_rels_per_ext_rel; - - if (bed->s->arch_size == 32) - r_sym_shift = 8; - else - r_sym_shift = 32; - - for (rel = relstart; rel < relend; rel++) - { - unsigned long r_symndx; - asection *rsec; - struct elf_link_hash_entry *h; - - r_symndx = rel->r_info >> r_sym_shift; - if (r_symndx == 0) - continue; - - if (r_symndx >= nlocsyms - || ELF_ST_BIND (isym[r_symndx].st_info) != STB_LOCAL) - { - h = sym_hashes[r_symndx - extsymoff]; - rsec = (*gc_mark_hook) (sec, info, rel, h, NULL); - } - else - { - rsec = (*gc_mark_hook) (sec, info, rel, NULL, &isym[r_symndx]); - } - - if (rsec && !rsec->gc_mark) - { - if (bfd_get_flavour (rsec->owner) != bfd_target_elf_flavour) - rsec->gc_mark = 1; - else if (!elf_gc_mark (info, rsec, gc_mark_hook)) - { - ret = FALSE; - goto out2; - } - } - } - - out2: - if (elf_section_data (sec)->relocs != relstart) - free (relstart); - out1: - if (isym != NULL && symtab_hdr->contents != (unsigned char *) isym) - { - if (! info->keep_memory) - free (isym); - else - symtab_hdr->contents = (unsigned char *) isym; - } - } - - return ret; -} - -/* The sweep phase of garbage collection. Remove all garbage sections. */ - -typedef bfd_boolean (*gc_sweep_hook_fn) - (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *); - -static bfd_boolean -elf_gc_sweep (struct bfd_link_info *info, gc_sweep_hook_fn gc_sweep_hook) -{ - bfd *sub; - - for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) - { - asection *o; - - if (bfd_get_flavour (sub) != bfd_target_elf_flavour) - continue; - - for (o = sub->sections; o != NULL; o = o->next) - { - /* Keep special sections. Keep .debug sections. */ - if ((o->flags & SEC_LINKER_CREATED) - || (o->flags & SEC_DEBUGGING)) - o->gc_mark = 1; - - if (o->gc_mark) - continue; - - /* Skip sweeping sections already excluded. */ - if (o->flags & SEC_EXCLUDE) - continue; - - /* Since this is early in the link process, it is simple - to remove a section from the output. */ - o->flags |= SEC_EXCLUDE; - - /* But we also have to update some of the relocation - info we collected before. */ - if (gc_sweep_hook - && (o->flags & SEC_RELOC) && o->reloc_count > 0) - { - Elf_Internal_Rela *internal_relocs; - bfd_boolean r; - - internal_relocs - = _bfd_elf_link_read_relocs (o->owner, o, NULL, NULL, - info->keep_memory); - if (internal_relocs == NULL) - return FALSE; - - r = (*gc_sweep_hook) (o->owner, info, o, internal_relocs); - - if (elf_section_data (o)->relocs != internal_relocs) - free (internal_relocs); - - if (!r) - return FALSE; - } - } - } - - /* Remove the symbols that were in the swept sections from the dynamic - symbol table. GCFIXME: Anyone know how to get them out of the - static symbol table as well? */ - { - int i = 0; - - elf_link_hash_traverse (elf_hash_table (info), elf_gc_sweep_symbol, &i); - - elf_hash_table (info)->dynsymcount = i; - } - - return TRUE; -} - -/* Sweep symbols in swept sections. Called via elf_link_hash_traverse. */ - -static bfd_boolean -elf_gc_sweep_symbol (struct elf_link_hash_entry *h, void *idxptr) -{ - int *idx = idxptr; - - if (h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - - if (h->dynindx != -1 - && ((h->root.type != bfd_link_hash_defined - && h->root.type != bfd_link_hash_defweak) - || h->root.u.def.section->gc_mark)) - h->dynindx = (*idx)++; - - return TRUE; -} - -/* Propagate collected vtable information. This is called through - elf_link_hash_traverse. */ - -static bfd_boolean -elf_gc_propagate_vtable_entries_used (struct elf_link_hash_entry *h, void *okp) -{ - if (h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - - /* Those that are not vtables. */ - if (h->vtable_parent == NULL) - return TRUE; - - /* Those vtables that do not have parents, we cannot merge. */ - if (h->vtable_parent == (struct elf_link_hash_entry *) -1) - return TRUE; - - /* If we've already been done, exit. */ - if (h->vtable_entries_used && h->vtable_entries_used[-1]) - return TRUE; - - /* Make sure the parent's table is up to date. */ - elf_gc_propagate_vtable_entries_used (h->vtable_parent, okp); - - if (h->vtable_entries_used == NULL) - { - /* None of this table's entries were referenced. Re-use the - parent's table. */ - h->vtable_entries_used = h->vtable_parent->vtable_entries_used; - h->vtable_entries_size = h->vtable_parent->vtable_entries_size; - } - else - { - size_t n; - bfd_boolean *cu, *pu; - - /* Or the parent's entries into ours. */ - cu = h->vtable_entries_used; - cu[-1] = TRUE; - pu = h->vtable_parent->vtable_entries_used; - if (pu != NULL) - { - const struct elf_backend_data *bed; - unsigned int log_file_align; - - bed = get_elf_backend_data (h->root.u.def.section->owner); - log_file_align = bed->s->log_file_align; - n = h->vtable_parent->vtable_entries_size >> log_file_align; - while (n--) - { - if (*pu) - *cu = TRUE; - pu++; - cu++; - } - } - } - - return TRUE; -} - -static bfd_boolean -elf_gc_smash_unused_vtentry_relocs (struct elf_link_hash_entry *h, void *okp) -{ - asection *sec; - bfd_vma hstart, hend; - Elf_Internal_Rela *relstart, *relend, *rel; - const struct elf_backend_data *bed; - unsigned int log_file_align; - - if (h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - - /* Take care of both those symbols that do not describe vtables as - well as those that are not loaded. */ - if (h->vtable_parent == NULL) - return TRUE; - - BFD_ASSERT (h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak); - - sec = h->root.u.def.section; - hstart = h->root.u.def.value; - hend = hstart + h->size; - - relstart = _bfd_elf_link_read_relocs (sec->owner, sec, NULL, NULL, TRUE); - if (!relstart) - return *(bfd_boolean *) okp = FALSE; - bed = get_elf_backend_data (sec->owner); - log_file_align = bed->s->log_file_align; - - relend = relstart + sec->reloc_count * bed->s->int_rels_per_ext_rel; - - for (rel = relstart; rel < relend; ++rel) - if (rel->r_offset >= hstart && rel->r_offset < hend) - { - /* If the entry is in use, do nothing. */ - if (h->vtable_entries_used - && (rel->r_offset - hstart) < h->vtable_entries_size) - { - bfd_vma entry = (rel->r_offset - hstart) >> log_file_align; - if (h->vtable_entries_used[entry]) - continue; - } - /* Otherwise, kill it. */ - rel->r_offset = rel->r_info = rel->r_addend = 0; - } - - return TRUE; -} - -/* Do mark and sweep of unused sections. */ - -bfd_boolean -elf_gc_sections (bfd *abfd, struct bfd_link_info *info) -{ - bfd_boolean ok = TRUE; - bfd *sub; - asection * (*gc_mark_hook) - (asection *, struct bfd_link_info *, Elf_Internal_Rela *, - struct elf_link_hash_entry *h, Elf_Internal_Sym *); - - if (!get_elf_backend_data (abfd)->can_gc_sections - || info->relocatable - || info->emitrelocations - || !is_elf_hash_table (info->hash) - || elf_hash_table (info)->dynamic_sections_created) - { - (*_bfd_error_handler)(_("Warning: gc-sections option ignored")); - return TRUE; - } - - /* Apply transitive closure to the vtable entry usage info. */ - elf_link_hash_traverse (elf_hash_table (info), - elf_gc_propagate_vtable_entries_used, - &ok); - if (!ok) - return FALSE; - - /* Kill the vtable relocations that were not used. */ - elf_link_hash_traverse (elf_hash_table (info), - elf_gc_smash_unused_vtentry_relocs, - &ok); - if (!ok) - return FALSE; - - /* Grovel through relocs to find out who stays ... */ - - gc_mark_hook = get_elf_backend_data (abfd)->gc_mark_hook; - for (sub = info->input_bfds; sub != NULL; sub = sub->link_next) - { - asection *o; - - if (bfd_get_flavour (sub) != bfd_target_elf_flavour) - continue; - - for (o = sub->sections; o != NULL; o = o->next) - { - if (o->flags & SEC_KEEP) - if (!elf_gc_mark (info, o, gc_mark_hook)) - return FALSE; - } - } - - /* ... and mark SEC_EXCLUDE for those that go. */ - if (!elf_gc_sweep (info, get_elf_backend_data (abfd)->gc_sweep_hook)) - return FALSE; - - return TRUE; -} - -/* Called from check_relocs to record the existence of a VTINHERIT reloc. */ - -bfd_boolean -elf_gc_record_vtinherit (bfd *abfd, - asection *sec, - struct elf_link_hash_entry *h, - bfd_vma offset) -{ - struct elf_link_hash_entry **sym_hashes, **sym_hashes_end; - struct elf_link_hash_entry **search, *child; - bfd_size_type extsymcount; - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - - /* The sh_info field of the symtab header tells us where the - external symbols start. We don't care about the local symbols at - this point. */ - extsymcount = elf_tdata (abfd)->symtab_hdr.sh_size / bed->s->sizeof_sym; - if (!elf_bad_symtab (abfd)) - extsymcount -= elf_tdata (abfd)->symtab_hdr.sh_info; - - sym_hashes = elf_sym_hashes (abfd); - sym_hashes_end = sym_hashes + extsymcount; - - /* Hunt down the child symbol, which is in this section at the same - offset as the relocation. */ - for (search = sym_hashes; search != sym_hashes_end; ++search) - { - if ((child = *search) != NULL - && (child->root.type == bfd_link_hash_defined - || child->root.type == bfd_link_hash_defweak) - && child->root.u.def.section == sec - && child->root.u.def.value == offset) - goto win; - } - - (*_bfd_error_handler) ("%s: %s+%lu: No symbol found for INHERIT", - bfd_archive_filename (abfd), sec->name, - (unsigned long) offset); - bfd_set_error (bfd_error_invalid_operation); - return FALSE; - - win: - if (!h) - { - /* This *should* only be the absolute section. It could potentially - be that someone has defined a non-global vtable though, which - would be bad. It isn't worth paging in the local symbols to be - sure though; that case should simply be handled by the assembler. */ - - child->vtable_parent = (struct elf_link_hash_entry *) -1; - } - else - child->vtable_parent = h; - - return TRUE; -} - -/* Called from check_relocs to record the existence of a VTENTRY reloc. */ - -bfd_boolean -elf_gc_record_vtentry (bfd *abfd ATTRIBUTE_UNUSED, - asection *sec ATTRIBUTE_UNUSED, - struct elf_link_hash_entry *h, - bfd_vma addend) -{ - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - unsigned int log_file_align = bed->s->log_file_align; - - if (addend >= h->vtable_entries_size) - { - size_t size, bytes, file_align; - bfd_boolean *ptr = h->vtable_entries_used; - - /* While the symbol is undefined, we have to be prepared to handle - a zero size. */ - file_align = 1 << log_file_align; - if (h->root.type == bfd_link_hash_undefined) - size = addend + file_align; - else - { - size = h->size; - if (addend >= size) - { - /* Oops! We've got a reference past the defined end of - the table. This is probably a bug -- shall we warn? */ - size = addend + file_align; - } - } - size = (size + file_align - 1) & -file_align; - - /* Allocate one extra entry for use as a "done" flag for the - consolidation pass. */ - bytes = ((size >> log_file_align) + 1) * sizeof (bfd_boolean); - - if (ptr) - { - ptr = bfd_realloc (ptr - 1, bytes); - - if (ptr != NULL) - { - size_t oldbytes; - - oldbytes = (((h->vtable_entries_size >> log_file_align) + 1) - * sizeof (bfd_boolean)); - memset (((char *) ptr) + oldbytes, 0, bytes - oldbytes); - } - } - else - ptr = bfd_zmalloc (bytes); - - if (ptr == NULL) - return FALSE; - - /* And arrange for that done flag to be at index -1. */ - h->vtable_entries_used = ptr + 1; - h->vtable_entries_size = size; - } - - h->vtable_entries_used[addend >> log_file_align] = TRUE; - - return TRUE; -} - -struct alloc_got_off_arg { - bfd_vma gotoff; - unsigned int got_elt_size; -}; - -/* And an accompanying bit to work out final got entry offsets once - we're done. Should be called from final_link. */ - -bfd_boolean -elf_gc_common_finalize_got_offsets (bfd *abfd, - struct bfd_link_info *info) -{ - bfd *i; - const struct elf_backend_data *bed = get_elf_backend_data (abfd); - bfd_vma gotoff; - unsigned int got_elt_size = bed->s->arch_size / 8; - struct alloc_got_off_arg gofarg; - - if (! is_elf_hash_table (info->hash)) - return FALSE; - - /* The GOT offset is relative to the .got section, but the GOT header is - put into the .got.plt section, if the backend uses it. */ - if (bed->want_got_plt) - gotoff = 0; - else - gotoff = bed->got_header_size; - - /* Do the local .got entries first. */ - for (i = info->input_bfds; i; i = i->link_next) - { - bfd_signed_vma *local_got; - bfd_size_type j, locsymcount; - Elf_Internal_Shdr *symtab_hdr; - - if (bfd_get_flavour (i) != bfd_target_elf_flavour) - continue; - - local_got = elf_local_got_refcounts (i); - if (!local_got) - continue; - - symtab_hdr = &elf_tdata (i)->symtab_hdr; - if (elf_bad_symtab (i)) - locsymcount = symtab_hdr->sh_size / bed->s->sizeof_sym; - else - locsymcount = symtab_hdr->sh_info; - - for (j = 0; j < locsymcount; ++j) - { - if (local_got[j] > 0) - { - local_got[j] = gotoff; - gotoff += got_elt_size; - } - else - local_got[j] = (bfd_vma) -1; - } - } - - /* Then the global .got entries. .plt refcounts are handled by - adjust_dynamic_symbol */ - gofarg.gotoff = gotoff; - gofarg.got_elt_size = got_elt_size; - elf_link_hash_traverse (elf_hash_table (info), - elf_gc_allocate_got_offsets, - &gofarg); - return TRUE; -} - -/* We need a special top-level link routine to convert got reference counts - to real got offsets. */ - -static bfd_boolean -elf_gc_allocate_got_offsets (struct elf_link_hash_entry *h, void *arg) -{ - struct alloc_got_off_arg *gofarg = arg; - - if (h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - - if (h->got.refcount > 0) - { - h->got.offset = gofarg->gotoff; - gofarg->gotoff += gofarg->got_elt_size; - } - else - h->got.offset = (bfd_vma) -1; - - return TRUE; -} - -/* Many folk need no more in the way of final link than this, once - got entry reference counting is enabled. */ - -bfd_boolean -elf_gc_common_final_link (bfd *abfd, struct bfd_link_info *info) -{ - if (!elf_gc_common_finalize_got_offsets (abfd, info)) - return FALSE; - - /* Invoke the regular ELF backend linker to do all the work. */ - return elf_bfd_final_link (abfd, info); -} - -bfd_boolean -elf_reloc_symbol_deleted_p (bfd_vma offset, void *cookie) -{ - struct elf_reloc_cookie *rcookie = cookie; - - if (rcookie->bad_symtab) - rcookie->rel = rcookie->rels; - - for (; rcookie->rel < rcookie->relend; rcookie->rel++) - { - unsigned long r_symndx; - - if (! rcookie->bad_symtab) - if (rcookie->rel->r_offset > offset) - return FALSE; - if (rcookie->rel->r_offset != offset) - continue; - - r_symndx = rcookie->rel->r_info >> rcookie->r_sym_shift; - if (r_symndx == SHN_UNDEF) - return TRUE; - - if (r_symndx >= rcookie->locsymcount - || ELF_ST_BIND (rcookie->locsyms[r_symndx].st_info) != STB_LOCAL) - { - struct elf_link_hash_entry *h; - - h = rcookie->sym_hashes[r_symndx - rcookie->extsymoff]; - - while (h->root.type == bfd_link_hash_indirect - || h->root.type == bfd_link_hash_warning) - h = (struct elf_link_hash_entry *) h->root.u.i.link; - - if ((h->root.type == bfd_link_hash_defined - || h->root.type == bfd_link_hash_defweak) - && elf_discarded_section (h->root.u.def.section)) - return TRUE; - else - return FALSE; - } - else - { - /* It's not a relocation against a global symbol, - but it could be a relocation against a local - symbol for a discarded section. */ - asection *isec; - Elf_Internal_Sym *isym; - - /* Need to: get the symbol; get the section. */ - isym = &rcookie->locsyms[r_symndx]; - if (isym->st_shndx < SHN_LORESERVE || isym->st_shndx > SHN_HIRESERVE) - { - isec = bfd_section_from_elf_index (rcookie->abfd, isym->st_shndx); - if (isec != NULL && elf_discarded_section (isec)) - return TRUE; - } - } - return FALSE; - } - return FALSE; -} - -/* Discard unneeded references to discarded sections. - Returns TRUE if any section's size was changed. */ -/* This function assumes that the relocations are in sorted order, - which is true for all known assemblers. */ - -bfd_boolean -elf_bfd_discard_info (bfd *output_bfd, struct bfd_link_info *info) -{ - struct elf_reloc_cookie cookie; - asection *stab, *eh; - Elf_Internal_Shdr *symtab_hdr; - const struct elf_backend_data *bed; - bfd *abfd; - unsigned int count; - bfd_boolean ret = FALSE; - - if (info->traditional_format - || !is_elf_hash_table (info->hash)) - return FALSE; - - for (abfd = info->input_bfds; abfd != NULL; abfd = abfd->link_next) - { - if (bfd_get_flavour (abfd) != bfd_target_elf_flavour) - continue; - - bed = get_elf_backend_data (abfd); - - if ((abfd->flags & DYNAMIC) != 0) - continue; - - eh = bfd_get_section_by_name (abfd, ".eh_frame"); - if (info->relocatable - || (eh != NULL - && (eh->_raw_size == 0 - || bfd_is_abs_section (eh->output_section)))) - eh = NULL; - - stab = bfd_get_section_by_name (abfd, ".stab"); - if (stab != NULL - && (stab->_raw_size == 0 - || bfd_is_abs_section (stab->output_section) - || stab->sec_info_type != ELF_INFO_TYPE_STABS)) - stab = NULL; - - if (stab == NULL - && eh == NULL - && bed->elf_backend_discard_info == NULL) - continue; - - symtab_hdr = &elf_tdata (abfd)->symtab_hdr; - cookie.abfd = abfd; - cookie.sym_hashes = elf_sym_hashes (abfd); - cookie.bad_symtab = elf_bad_symtab (abfd); - if (cookie.bad_symtab) - { - cookie.locsymcount = symtab_hdr->sh_size / bed->s->sizeof_sym; - cookie.extsymoff = 0; - } - else - { - cookie.locsymcount = symtab_hdr->sh_info; - cookie.extsymoff = symtab_hdr->sh_info; - } - - if (bed->s->arch_size == 32) - cookie.r_sym_shift = 8; - else - cookie.r_sym_shift = 32; - - cookie.locsyms = (Elf_Internal_Sym *) symtab_hdr->contents; - if (cookie.locsyms == NULL && cookie.locsymcount != 0) - { - cookie.locsyms = bfd_elf_get_elf_syms (abfd, symtab_hdr, - cookie.locsymcount, 0, - NULL, NULL, NULL); - if (cookie.locsyms == NULL) - return FALSE; - } - - if (stab != NULL) - { - cookie.rels = NULL; - count = stab->reloc_count; - if (count != 0) - cookie.rels = _bfd_elf_link_read_relocs (abfd, stab, NULL, NULL, - info->keep_memory); - if (cookie.rels != NULL) - { - cookie.rel = cookie.rels; - cookie.relend = cookie.rels; - cookie.relend += count * bed->s->int_rels_per_ext_rel; - if (_bfd_discard_section_stabs (abfd, stab, - elf_section_data (stab)->sec_info, - elf_reloc_symbol_deleted_p, - &cookie)) - ret = TRUE; - if (elf_section_data (stab)->relocs != cookie.rels) - free (cookie.rels); - } - } - - if (eh != NULL) - { - cookie.rels = NULL; - count = eh->reloc_count; - if (count != 0) - cookie.rels = _bfd_elf_link_read_relocs (abfd, eh, NULL, NULL, - info->keep_memory); - cookie.rel = cookie.rels; - cookie.relend = cookie.rels; - if (cookie.rels != NULL) - cookie.relend += count * bed->s->int_rels_per_ext_rel; - - if (_bfd_elf_discard_section_eh_frame (abfd, info, eh, - elf_reloc_symbol_deleted_p, - &cookie)) - ret = TRUE; - - if (cookie.rels != NULL - && elf_section_data (eh)->relocs != cookie.rels) - free (cookie.rels); - } - - if (bed->elf_backend_discard_info != NULL - && (*bed->elf_backend_discard_info) (abfd, &cookie, info)) - ret = TRUE; - - if (cookie.locsyms != NULL - && symtab_hdr->contents != (unsigned char *) cookie.locsyms) - { - if (! info->keep_memory) - free (cookie.locsyms); - else - symtab_hdr->contents = (unsigned char *) cookie.locsyms; - } - } - - if (info->eh_frame_hdr - && !info->relocatable - && _bfd_elf_discard_section_eh_frame_hdr (output_bfd, info)) - ret = TRUE; - - return ret; -} - -static bfd_boolean -elf_section_ignore_discarded_relocs (asection *sec) -{ - const struct elf_backend_data *bed; - - switch (sec->sec_info_type) - { - case ELF_INFO_TYPE_STABS: - case ELF_INFO_TYPE_EH_FRAME: - return TRUE; - default: - break; - } - - bed = get_elf_backend_data (sec->owner); - if (bed->elf_backend_ignore_discarded_relocs != NULL - && (*bed->elf_backend_ignore_discarded_relocs) (sec)) - return TRUE; - - return FALSE; -} diff --git a/bfd/elfxx-ia64.c b/bfd/elfxx-ia64.c index c1d6622..b8527a9 100644 --- a/bfd/elfxx-ia64.c +++ b/bfd/elfxx-ia64.c @@ -2459,7 +2459,7 @@ elfNN_ia64_check_relocs (abfd, info, sec, relocs) dynamic symbol table. */ if (!h && info->shared) { - if (! (_bfd_elfNN_link_record_local_dynamic_symbol + if (! (bfd_elf_link_record_local_dynamic_symbol (info, abfd, (long) r_symndx))) return FALSE; } @@ -2631,7 +2631,7 @@ allocate_fptr (dyn_i, data) BFD_ASSERT ((h->root.type == bfd_link_hash_defined) || (h->root.type == bfd_link_hash_defweak)); - if (!_bfd_elfNN_link_record_local_dynamic_symbol + if (!bfd_elf_link_record_local_dynamic_symbol (x->info, h->root.u.def.section->owner, global_sym_index (h))) return FALSE; @@ -3838,7 +3838,7 @@ elfNN_ia64_final_link (abfd, info) } /* Invoke the regular ELF backend linker to do all the work. */ - if (!bfd_elfNN_bfd_final_link (abfd, info)) + if (!bfd_elf_final_link (abfd, info)) return FALSE; if (unwind_output_sec) @@ -4596,7 +4596,7 @@ elfNN_ia64_finish_dynamic_symbol (output_bfd, info, h, sym) /* Mark the symbol as undefined, rather than as defined in the plt section. Leave the value alone. */ /* ??? We didn't redefine it in adjust_dynamic_symbol in the - first place. But perhaps elflink.h did some for us. */ + first place. But perhaps elflink.c did some for us. */ if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0) sym->st_shndx = SHN_UNDEF; } diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c index 12eb566..faa2ecc 100644 --- a/bfd/elfxx-mips.c +++ b/bfd/elfxx-mips.c @@ -2144,7 +2144,7 @@ mips_elf_record_global_got_symbol (struct elf_link_hash_entry *h, _bfd_mips_elf_hide_symbol (info, h, TRUE); break; } - if (!bfd_elf32_link_record_dynamic_symbol (info, h)) + if (!bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -2956,7 +2956,7 @@ mips_elf_create_got_section (bfd *abfd, struct bfd_link_info *info, h->type = STT_OBJECT; if (info->shared - && ! bfd_elf32_link_record_dynamic_symbol (info, h)) + && ! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; amt = sizeof (struct mips_got_info); @@ -4848,7 +4848,7 @@ _bfd_mips_elf_add_symbol_hook (bfd *abfd, struct bfd_link_info *info, h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; h->type = STT_OBJECT; - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; mips_elf_hash_table (info)->use_rld_obj_head = TRUE; @@ -4960,7 +4960,7 @@ _bfd_mips_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; h->type = STT_SECTION; - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } @@ -5005,7 +5005,7 @@ _bfd_mips_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; h->type = STT_SECTION; - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; if (! mips_elf_hash_table (info)->use_rld_obj_head) @@ -5029,7 +5029,7 @@ _bfd_mips_elf_create_dynamic_sections (bfd *abfd, struct bfd_link_info *info) h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR; h->type = STT_OBJECT; - if (! bfd_elf32_link_record_dynamic_symbol (info, h)) + if (! bfd_elf_link_record_dynamic_symbol (info, h)) return FALSE; } } @@ -5348,7 +5348,7 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, /* We need a stub, not a plt entry for the undefined function. But we record it as if it needs plt. See - elf_adjust_dynamic_symbol in elflink.h. */ + _bfd_elf_adjust_dynamic_symbol. */ h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT; h->type = STT_FUNC; } @@ -5460,14 +5460,14 @@ _bfd_mips_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, /* This relocation describes the C++ object vtable hierarchy. Reconstruct it for later use during GC. */ case R_MIPS_GNU_VTINHERIT: - if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) + if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset)) return FALSE; break; /* This relocation describes which C++ vtable entries are actually used. Record for later use during GC. */ case R_MIPS_GNU_VTENTRY: - if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_offset)) + if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_offset)) return FALSE; break; @@ -7731,7 +7731,7 @@ _bfd_mips_elf_discard_info (bfd *abfd, struct elf_reloc_cookie *cookie, for (i = 0, skip = 0; i < o->_raw_size / PDR_SIZE; i ++) { - if (MNAME(abfd,_bfd_elf,reloc_symbol_deleted_p) (i * PDR_SIZE, cookie)) + if (bfd_elf_reloc_symbol_deleted_p (i * PDR_SIZE, cookie)) { tdata[i] = 1; skip ++; @@ -8788,7 +8788,7 @@ _bfd_mips_elf_final_link (bfd *abfd, struct bfd_link_info *info) } /* Invoke the regular ELF backend linker to do all the work. */ - if (!MNAME(abfd,bfd_elf,bfd_final_link) (abfd, info)) + if (!bfd_elf_final_link (abfd, info)) return FALSE; /* Now write out the computed sections. */ diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h index 8dfd56a..e250a97 100644 --- a/bfd/elfxx-target.h +++ b/bfd/elfxx-target.h @@ -126,7 +126,7 @@ #define elf_backend_gc_sweep_hook NULL #endif #ifndef bfd_elfNN_bfd_gc_sections -#define bfd_elfNN_bfd_gc_sections _bfd_elfNN_gc_sections +#define bfd_elfNN_bfd_gc_sections bfd_elf_gc_sections #endif #ifndef bfd_elfNN_bfd_merge_sections @@ -192,6 +192,9 @@ #ifndef bfd_elfNN_bfd_link_add_symbols #define bfd_elfNN_bfd_link_add_symbols bfd_elf_link_add_symbols #endif +#ifndef bfd_elfNN_bfd_final_link +#define bfd_elfNN_bfd_final_link bfd_elf_final_link +#endif #else /* ! defined (elf_backend_relocate_section) */ /* If no backend relocate_section routine, use the generic linker. Note - this will prevent the port from being able to use some of @@ -238,6 +241,10 @@ #define bfd_elfNN_mkarchive _bfd_generic_mkarchive #endif +#ifndef bfd_elfNN_print_symbol +#define bfd_elfNN_print_symbol bfd_elf_print_symbol +#endif + #ifndef elf_symbol_leading_char #define elf_symbol_leading_char 0 #endif diff --git a/bfd/po/SRC-POTFILES.in b/bfd/po/SRC-POTFILES.in index 07742dd..d29593d 100644 --- a/bfd/po/SRC-POTFILES.in +++ b/bfd/po/SRC-POTFILES.in @@ -185,7 +185,6 @@ elfcore.h elf-eh-frame.c elf-hppa.h elflink.c -elflink.h elf-m10200.c elf-m10300.c elfn32-mips.c diff --git a/bfd/po/bfd.pot b/bfd/po/bfd.pot index 3396c4f..dd37e15 100644 --- a/bfd/po/bfd.pot +++ b/bfd/po/bfd.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2004-03-19 14:59+1030\n" +"POT-Creation-Date: 2004-03-27 15:34+1030\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -259,14 +259,14 @@ msgstr "" msgid "ERROR: %s is compiled for APCS-%d, whereas %s is compiled for APCS-%d" msgstr "" -#: coff-arm.c:2289 elf32-arm.h:2494 +#: coff-arm.c:2289 elf32-arm.h:2482 #, c-format msgid "" "ERROR: %s passes floats in float registers, whereas %s passes them in " "integer registers" msgstr "" -#: coff-arm.c:2292 elf32-arm.h:2499 +#: coff-arm.c:2292 elf32-arm.h:2487 #, c-format msgid "" "ERROR: %s passes floats in integer registers, whereas %s passes them in " @@ -287,12 +287,12 @@ msgid "" "position independent" msgstr "" -#: coff-arm.c:2339 elf32-arm.h:2571 +#: coff-arm.c:2339 elf32-arm.h:2559 #, c-format msgid "Warning: %s supports interworking, whereas %s does not" msgstr "" -#: coff-arm.c:2342 elf32-arm.h:2578 +#: coff-arm.c:2342 elf32-arm.h:2566 #, c-format msgid "Warning: %s does not support interworking, whereas %s does" msgstr "" @@ -302,7 +302,7 @@ msgstr "" msgid "private flags = %x:" msgstr "" -#: coff-arm.c:2377 elf32-arm.h:2633 +#: coff-arm.c:2377 elf32-arm.h:2621 #, c-format msgid " [floats passed in float registers]" msgstr "" @@ -312,7 +312,7 @@ msgstr "" msgid " [floats passed in integer registers]" msgstr "" -#: coff-arm.c:2382 elf32-arm.h:2636 +#: coff-arm.c:2382 elf32-arm.h:2624 #, c-format msgid " [position independent]" msgstr "" @@ -337,14 +337,14 @@ msgstr "" msgid " [interworking not supported]" msgstr "" -#: coff-arm.c:2440 elf32-arm.h:2298 +#: coff-arm.c:2440 elf32-arm.h:2286 #, c-format msgid "" "Warning: Not setting interworking flag of %s since it has already been " "specified as non-interworking" msgstr "" -#: coff-arm.c:2444 elf32-arm.h:2302 +#: coff-arm.c:2444 elf32-arm.h:2290 #, c-format msgid "Warning: Clearing the interworking flag of %s due to outside request" msgstr "" @@ -413,7 +413,7 @@ msgstr "" msgid "uncertain calling convention for non-COFF symbol" msgstr "" -#: cofflink.c:506 elflink.h:945 +#: cofflink.c:506 elflink.c:3665 #, c-format msgid "Warning: type of symbol `%s' changed from %d to %d in %s" msgstr "" @@ -433,7 +433,7 @@ msgstr "" msgid "%s: warning: %s: line number overflow: 0x%lx > 0xffff" msgstr "" -#: coff-m68k.c:482 coff-mips.c:2394 elf32-m68k.c:2153 elf32-mips.c:1405 +#: coff-m68k.c:482 coff-mips.c:2394 elf32-m68k.c:2145 elf32-mips.c:1405 msgid "unsupported reloc type" msgstr "" @@ -612,102 +612,102 @@ msgid "" " Type: %s" msgstr "" -#: elf32-arm.h:1428 +#: elf32-arm.h:1416 #, c-format msgid "%s: Warning: Arm BLX instruction targets Arm function '%s'." msgstr "" -#: elf32-arm.h:1624 +#: elf32-arm.h:1612 #, c-format msgid "%s: Warning: Thumb BLX instruction targets thumb function '%s'." msgstr "" -#: elf32-arm.h:2092 elf32-sh.c:4819 elf64-sh64.c:1596 +#: elf32-arm.h:2080 elf32-sh.c:4808 elf64-sh64.c:1596 #, c-format msgid "%s(%s+0x%lx): %s relocation against SEC_MERGE section" msgstr "" -#: elf32-arm.h:2184 +#: elf32-arm.h:2172 #, c-format msgid "" "%s: warning: unresolvable relocation %d against symbol `%s' from %s section" msgstr "" -#: elf32-arm.h:2236 elf32-avr.c:812 elf32-cris.c:1352 elf32-d10v.c:579 -#: elf32-fr30.c:634 elf32-frv.c:2499 elf32-h8300.c:509 elf32-i860.c:1218 -#: elf32-ip2k.c:1565 elf32-iq2000.c:665 elf32-m32r.c:3202 elf32-m68hc1x.c:1214 -#: elf32-msp430.c:510 elf32-openrisc.c:436 elf32-v850.c:1777 -#: elf32-xstormy16.c:976 elf64-mmix.c:1545 elf-m10200.c:442 elf-m10300.c:1677 +#: elf32-arm.h:2224 elf32-avr.c:791 elf32-cris.c:1376 elf32-d10v.c:563 +#: elf32-fr30.c:599 elf32-frv.c:2499 elf32-h8300.c:493 elf32-i860.c:1196 +#: elf32-ip2k.c:1568 elf32-iq2000.c:666 elf32-m32r.c:3191 elf32-m68hc1x.c:1190 +#: elf32-msp430.c:489 elf32-openrisc.c:415 elf32-v850.c:1746 +#: elf32-xstormy16.c:954 elf64-mmix.c:1518 elf-m10200.c:426 elf-m10300.c:1676 msgid "internal error: out of range error" msgstr "" -#: elf32-arm.h:2240 elf32-avr.c:816 elf32-cris.c:1356 elf32-d10v.c:583 -#: elf32-fr30.c:638 elf32-frv.c:2503 elf32-h8300.c:513 elf32-i860.c:1222 -#: elf32-iq2000.c:669 elf32-m32r.c:3206 elf32-m68hc1x.c:1218 -#: elf32-msp430.c:514 elf32-openrisc.c:440 elf32-v850.c:1781 -#: elf32-xstormy16.c:980 elf64-mmix.c:1549 elf-m10200.c:446 elf-m10300.c:1681 -#: elfxx-mips.c:6470 +#: elf32-arm.h:2228 elf32-avr.c:795 elf32-cris.c:1380 elf32-d10v.c:567 +#: elf32-fr30.c:603 elf32-frv.c:2503 elf32-h8300.c:497 elf32-i860.c:1200 +#: elf32-iq2000.c:670 elf32-m32r.c:3195 elf32-m68hc1x.c:1194 +#: elf32-msp430.c:493 elf32-openrisc.c:419 elf32-v850.c:1750 +#: elf32-xstormy16.c:958 elf64-mmix.c:1522 elf-m10200.c:430 elf-m10300.c:1680 +#: elfxx-mips.c:6459 msgid "internal error: unsupported relocation error" msgstr "" -#: elf32-arm.h:2244 elf32-d10v.c:587 elf32-h8300.c:517 elf32-m32r.c:3210 -#: elf32-m68hc1x.c:1222 elf-m10200.c:450 elf-m10300.c:1685 +#: elf32-arm.h:2232 elf32-d10v.c:571 elf32-h8300.c:501 elf32-m32r.c:3199 +#: elf32-m68hc1x.c:1198 elf-m10200.c:434 elf-m10300.c:1684 msgid "internal error: dangerous error" msgstr "" -#: elf32-arm.h:2248 elf32-avr.c:824 elf32-cris.c:1364 elf32-d10v.c:591 -#: elf32-fr30.c:646 elf32-frv.c:2511 elf32-h8300.c:521 elf32-i860.c:1230 -#: elf32-ip2k.c:1580 elf32-iq2000.c:677 elf32-m32r.c:3214 elf32-m68hc1x.c:1226 -#: elf32-msp430.c:522 elf32-openrisc.c:448 elf32-v850.c:1801 -#: elf32-xstormy16.c:988 elf64-mmix.c:1557 elf-m10200.c:454 elf-m10300.c:1689 +#: elf32-arm.h:2236 elf32-avr.c:803 elf32-cris.c:1388 elf32-d10v.c:575 +#: elf32-fr30.c:611 elf32-frv.c:2511 elf32-h8300.c:505 elf32-i860.c:1208 +#: elf32-ip2k.c:1583 elf32-iq2000.c:678 elf32-m32r.c:3203 elf32-m68hc1x.c:1202 +#: elf32-msp430.c:501 elf32-openrisc.c:427 elf32-v850.c:1770 +#: elf32-xstormy16.c:966 elf64-mmix.c:1530 elf-m10200.c:438 elf-m10300.c:1688 msgid "internal error: unknown error" msgstr "" -#: elf32-arm.h:2350 +#: elf32-arm.h:2338 #, c-format msgid "" "Warning: Clearing the interworking flag of %s because non-interworking code " "in %s has been linked with it" msgstr "" -#: elf32-arm.h:2468 +#: elf32-arm.h:2456 #, c-format msgid "" "ERROR: %s is compiled for EABI version %d, whereas %s is compiled for " "version %d" msgstr "" -#: elf32-arm.h:2482 +#: elf32-arm.h:2470 #, c-format msgid "ERROR: %s is compiled for APCS-%d, whereas target %s uses APCS-%d" msgstr "" -#: elf32-arm.h:2510 +#: elf32-arm.h:2498 #, c-format msgid "ERROR: %s uses VFP instructions, whereas %s does not" msgstr "" -#: elf32-arm.h:2515 +#: elf32-arm.h:2503 #, c-format msgid "ERROR: %s uses FPA instructions, whereas %s does not" msgstr "" -#: elf32-arm.h:2526 +#: elf32-arm.h:2514 #, c-format msgid "ERROR: %s uses Maverick instructions, whereas %s does not" msgstr "" -#: elf32-arm.h:2531 +#: elf32-arm.h:2519 #, c-format msgid "ERROR: %s does not use Maverick instructions, whereas %s does" msgstr "" -#: elf32-arm.h:2551 +#: elf32-arm.h:2539 #, c-format msgid "ERROR: %s uses software FP, whereas %s uses hardware FP" msgstr "" -#: elf32-arm.h:2556 +#: elf32-arm.h:2544 #, c-format msgid "ERROR: %s uses hardware FP, whereas %s uses software FP" msgstr "" @@ -715,77 +715,92 @@ msgstr "" #. Ignore init flag - it may not be set, despite the flags field #. containing valid data. #. Ignore init flag - it may not be set, despite the flags field containing valid data. -#: elf32-arm.h:2609 elf32-cris.c:2938 elf32-m68hc1x.c:1362 elf32-m68k.c:397 -#: elf32-vax.c:546 elfxx-mips.c:9179 +#: elf32-arm.h:2597 elf32-cris.c:2980 elf32-m68hc1x.c:1338 elf32-m68k.c:397 +#: elf32-vax.c:546 elfxx-mips.c:9168 #, c-format msgid "private flags = %lx:" msgstr "" -#: elf32-arm.h:2618 +#: elf32-arm.h:2606 #, c-format msgid " [interworking enabled]" msgstr "" -#: elf32-arm.h:2626 +#: elf32-arm.h:2614 #, c-format msgid " [VFP float format]" msgstr "" -#: elf32-arm.h:2628 +#: elf32-arm.h:2616 #, c-format msgid " [Maverick float format]" msgstr "" -#: elf32-arm.h:2630 +#: elf32-arm.h:2618 #, c-format msgid " [FPA float format]" msgstr "" -#: elf32-arm.h:2639 +#: elf32-arm.h:2627 #, c-format msgid " [new ABI]" msgstr "" -#: elf32-arm.h:2642 +#: elf32-arm.h:2630 #, c-format msgid " [old ABI]" msgstr "" -#: elf32-arm.h:2645 +#: elf32-arm.h:2633 #, c-format msgid " [software FP]" msgstr "" -#: elf32-arm.h:2654 +#: elf32-arm.h:2642 #, c-format msgid " [Version1 EABI]" msgstr "" -#: elf32-arm.h:2657 elf32-arm.h:2668 +#: elf32-arm.h:2645 elf32-arm.h:2656 #, c-format msgid " [sorted symbol table]" msgstr "" -#: elf32-arm.h:2659 elf32-arm.h:2670 +#: elf32-arm.h:2647 elf32-arm.h:2658 #, c-format msgid " [unsorted symbol table]" msgstr "" -#: elf32-arm.h:2665 +#: elf32-arm.h:2653 #, c-format msgid " [Version2 EABI]" msgstr "" -#: elf32-arm.h:2673 +#: elf32-arm.h:2661 #, c-format msgid " [dynamic symbols use segment index]" msgstr "" -#: elf32-arm.h:2676 +#: elf32-arm.h:2664 #, c-format msgid " [mapping symbols precede others]" msgstr "" +#: elf32-arm.h:2671 +#, c-format +msgid " [Version3 EABI]" +msgstr "" + +#: elf32-arm.h:2674 +#, c-format +msgid " [BE8]" +msgstr "" + +#: elf32-arm.h:2677 +#, c-format +msgid " [LE8]" +msgstr "" + #: elf32-arm.h:2683 #, c-format msgid " <EABI version unrecognised>" @@ -806,75 +821,80 @@ msgstr "" msgid "<Unrecognised flag bits set>" msgstr "" -#: elf32-avr.c:820 elf32-cris.c:1360 elf32-fr30.c:642 elf32-frv.c:2507 -#: elf32-i860.c:1226 elf32-ip2k.c:1576 elf32-iq2000.c:673 elf32-msp430.c:518 -#: elf32-openrisc.c:444 elf32-v850.c:1785 elf32-xstormy16.c:984 -#: elf64-mmix.c:1553 +#: elf32-avr.c:799 elf32-cris.c:1384 elf32-fr30.c:607 elf32-frv.c:2507 +#: elf32-i860.c:1204 elf32-ip2k.c:1579 elf32-iq2000.c:674 elf32-msp430.c:497 +#: elf32-openrisc.c:423 elf32-v850.c:1754 elf32-xstormy16.c:962 +#: elf64-mmix.c:1526 msgid "internal error: dangerous relocation" msgstr "" -#: elf32-cris.c:918 +#: elf32-cris.c:921 #, c-format msgid "%s: unresolvable relocation %s against symbol `%s' from %s section" msgstr "" -#: elf32-cris.c:964 +#: elf32-cris.c:978 #, c-format msgid "" "%s: No PLT nor GOT for relocation %s against symbol `%s' from %s section" msgstr "" -#: elf32-cris.c:967 elf32-cris.c:1093 +#: elf32-cris.c:980 +#, c-format +msgid "%s: No PLT for relocation %s against symbol `%s' from %s section" +msgstr "" + +#: elf32-cris.c:984 elf32-cris.c:1117 msgid "[whose name is lost]" msgstr "" -#: elf32-cris.c:1082 +#: elf32-cris.c:1106 #, c-format msgid "" "%s: relocation %s with non-zero addend %d against local symbol from %s " "section" msgstr "" -#: elf32-cris.c:1089 +#: elf32-cris.c:1113 #, c-format msgid "" "%s: relocation %s with non-zero addend %d against symbol `%s' from %s section" msgstr "" -#: elf32-cris.c:1114 +#: elf32-cris.c:1138 #, c-format msgid "" "%s: relocation %s is not allowed for global symbol: `%s' from %s section" msgstr "" -#: elf32-cris.c:1129 +#: elf32-cris.c:1153 #, c-format msgid "%s: relocation %s in section %s with no GOT created" msgstr "" -#: elf32-cris.c:1248 +#: elf32-cris.c:1272 #, c-format msgid "%s: Internal inconsistency; no relocation section %s" msgstr "" -#: elf32-cris.c:2463 +#: elf32-cris.c:2502 #, c-format msgid "" "%s, section %s:\n" " relocation %s should not be used in a shared object; recompile with -fPIC" msgstr "" -#: elf32-cris.c:2941 +#: elf32-cris.c:2983 #, c-format msgid " [symbols have a _ prefix]" msgstr "" -#: elf32-cris.c:2980 +#: elf32-cris.c:3022 #, c-format msgid "%s: uses _-prefixed symbols, but writing file with non-prefixed symbols" msgstr "" -#: elf32-cris.c:2981 +#: elf32-cris.c:3023 #, c-format msgid "%s: uses non-prefixed symbols, but writing file with _-prefixed symbols" msgstr "" @@ -917,7 +937,7 @@ msgid "" "%s: compiled with %s and linked with modules that use non-pic relocations" msgstr "" -#: elf32-frv.c:4443 elf32-iq2000.c:861 +#: elf32-frv.c:4443 elf32-iq2000.c:862 #, c-format msgid "%s: compiled with %s and linked with modules compiled with %s" msgstr "" @@ -929,67 +949,67 @@ msgid "" "lx)" msgstr "" -#: elf32-frv.c:4491 elf32-iq2000.c:899 +#: elf32-frv.c:4491 elf32-iq2000.c:900 #, c-format msgid "private flags = 0x%lx:" msgstr "" -#: elf32-gen.c:83 elf64-gen.c:82 +#: elf32-gen.c:83 elf64-gen.c:83 #, c-format msgid "%s: Relocations in generic ELF (EM: %d)" msgstr "" -#: elf32-hppa.c:542 elf32-m68hc1x.c:170 elf64-ppc.c:3186 +#: elf32-hppa.c:542 elf32-m68hc1x.c:161 elf64-ppc.c:3188 #, c-format msgid "%s: cannot create stub entry %s" msgstr "" -#: elf32-hppa.c:795 elf32-hppa.c:3326 +#: elf32-hppa.c:795 elf32-hppa.c:3315 #, c-format msgid "%s(%s+0x%lx): cannot reach %s, recompile with -ffunction-sections" msgstr "" -#: elf32-hppa.c:1166 elf64-x86-64.c:665 elf64-x86-64.c:790 +#: elf32-hppa.c:1167 elf64-x86-64.c:665 elf64-x86-64.c:790 #, c-format msgid "" "%s: relocation %s can not be used when making a shared object; recompile " "with -fPIC" msgstr "" -#: elf32-hppa.c:1186 +#: elf32-hppa.c:1187 #, c-format msgid "" "%s: relocation %s should not be used when making a shared object; recompile " "with -fPIC" msgstr "" -#: elf32-hppa.c:1378 +#: elf32-hppa.c:1377 #, c-format msgid "Could not find relocation section for %s" msgstr "" -#: elf32-hppa.c:2584 +#: elf32-hppa.c:2572 #, c-format msgid "%s: duplicate export stub %s" msgstr "" -#: elf32-hppa.c:3174 +#: elf32-hppa.c:3162 #, c-format msgid "" "%s(%s+0x%lx): %s fixup for insn 0x%x is not supported in a non-shared link" msgstr "" -#: elf32-hppa.c:3204 +#: elf32-hppa.c:3192 #, c-format msgid "%s(%s+0x%lx): fixing %s" msgstr "" -#: elf32-hppa.c:3820 +#: elf32-hppa.c:3810 #, c-format msgid "%s(%s+0x%lx): cannot handle %s for %s" msgstr "" -#: elf32-hppa.c:4113 +#: elf32-hppa.c:4103 msgid ".got section not immediately after .plt section" msgstr "" @@ -998,33 +1018,33 @@ msgstr "" msgid "%s: invalid relocation type %d" msgstr "" -#: elf32-i386.c:864 elf32-s390.c:983 elf32-sparc.c:916 elf32-xtensa.c:648 +#: elf32-i386.c:864 elf32-s390.c:983 elf32-sparc.c:916 elf32-xtensa.c:641 #: elf64-s390.c:936 elf64-x86-64.c:643 #, c-format msgid "%s: bad symbol index: %d" msgstr "" -#: elf32-i386.c:972 elf32-s390.c:1161 elf32-sh.c:6603 elf32-sparc.c:1040 +#: elf32-i386.c:972 elf32-s390.c:1161 elf32-sh.c:6590 elf32-sparc.c:1040 #: elf64-s390.c:1122 #, c-format msgid "%s: `%s' accessed both as normal and thread local symbol" msgstr "" -#: elf32-i386.c:1089 elf32-s390.c:1272 elf64-ppc.c:4018 elf64-s390.c:1236 +#: elf32-i386.c:1089 elf32-s390.c:1272 elf64-ppc.c:4036 elf64-s390.c:1236 #: elf64-x86-64.c:879 #, c-format msgid "%s: bad relocation section name `%s'" msgstr "" -#: elf32-i386.c:2897 elf32-m68k.c:1717 elf32-s390.c:3007 elf32-sparc.c:2868 -#: elf32-xtensa.c:2119 elf64-s390.c:3003 elf64-sparc.c:2631 -#: elf64-x86-64.c:2400 +#: elf32-i386.c:2889 elf32-m68k.c:1709 elf32-s390.c:2996 elf32-sparc.c:2857 +#: elf32-xtensa.c:2106 elf64-s390.c:2992 elf64-sparc.c:2620 +#: elf64-x86-64.c:2389 #, c-format msgid "%s(%s+0x%lx): unresolvable relocation against symbol `%s'" msgstr "" -#: elf32-i386.c:2936 elf32-m68k.c:1756 elf32-s390.c:3057 elf64-s390.c:3053 -#: elf64-x86-64.c:2438 +#: elf32-i386.c:2928 elf32-m68k.c:1748 elf32-s390.c:3046 elf64-s390.c:3042 +#: elf64-x86-64.c:2427 #, c-format msgid "%s(%s+0x%lx): reloc against `%s': error %d" msgstr "" @@ -1049,12 +1069,12 @@ msgid "ip2k linker: redundant page instruction at 0x%08lx (dest = 0x%08lx)." msgstr "" #. Only if it's not an unresolved symbol. -#: elf32-ip2k.c:1572 +#: elf32-ip2k.c:1575 msgid "unsupported relocation between data/insn address spaces" msgstr "" -#: elf32-iq2000.c:873 elf32-m68hc1x.c:1336 elf32-ppc.c:2293 elf64-sparc.c:3039 -#: elfxx-mips.c:9140 +#: elf32-iq2000.c:874 elf32-m68hc1x.c:1312 elf32-ppc.c:2293 elf64-sparc.c:3028 +#: elfxx-mips.c:9129 #, c-format msgid "%s: uses different e_flags (0x%lx) fields than previous modules (0x%lx)" msgstr "" @@ -1063,130 +1083,130 @@ msgstr "" msgid "SDA relocation when _SDA_BASE_ not defined" msgstr "" -#: elf32-m32r.c:2575 elf64-alpha.c:4199 elf64-alpha.c:4325 elf32-ia64.c:3920 -#: elf64-ia64.c:3920 +#: elf32-m32r.c:2564 elf64-alpha.c:4199 elf64-alpha.c:4325 elf32-ia64.c:3921 +#: elf64-ia64.c:3921 #, c-format msgid "%s: unknown relocation type %d" msgstr "" -#: elf32-m32r.c:2763 elf64-sh64.c:1689 elf-hppa.h:1387 elf-hppa.h:1421 -#: elf-hppa.h:1437 elf-m10300.c:1632 +#: elf32-m32r.c:2753 elf64-sh64.c:1689 elf-hppa.h:1406 elf-hppa.h:1433 +#: elf-hppa.h:1449 elf-m10300.c:1631 #, c-format msgid "" "%s: warning: unresolvable relocation against symbol `%s' from %s section" msgstr "" -#: elf32-m32r.c:3139 +#: elf32-m32r.c:3128 #, c-format msgid "%s: The target (%s) of an %s relocation is in the wrong section (%s)" msgstr "" -#: elf32-m32r.c:4222 +#: elf32-m32r.c:4211 #, c-format msgid "%s: Instruction set mismatch with previous modules" msgstr "" -#: elf32-m32r.c:4245 +#: elf32-m32r.c:4234 #, c-format msgid "private flags = %lx" msgstr "" -#: elf32-m32r.c:4250 +#: elf32-m32r.c:4239 #, c-format msgid ": m32r instructions" msgstr "" -#: elf32-m32r.c:4251 +#: elf32-m32r.c:4240 #, c-format msgid ": m32rx instructions" msgstr "" -#: elf32-m32r.c:4252 +#: elf32-m32r.c:4241 #, c-format msgid ": m32r2 instructions" msgstr "" -#: elf32-m68hc1x.c:1126 +#: elf32-m68hc1x.c:1102 #, c-format msgid "" "Reference to the far symbol `%s' using a wrong relocation may result in " "incorrect execution" msgstr "" -#: elf32-m68hc1x.c:1149 +#: elf32-m68hc1x.c:1125 #, c-format msgid "" "banked address [%lx:%04lx] (%lx) is not in the same bank as current banked " "address [%lx:%04lx] (%lx)" msgstr "" -#: elf32-m68hc1x.c:1168 +#: elf32-m68hc1x.c:1144 #, c-format msgid "" "reference to a banked address [%lx:%04lx] in the normal address space at %" "04lx" msgstr "" -#: elf32-m68hc1x.c:1301 +#: elf32-m68hc1x.c:1277 #, c-format msgid "" "%s: linking files compiled for 16-bit integers (-mshort) and others for 32-" "bit integers" msgstr "" -#: elf32-m68hc1x.c:1309 +#: elf32-m68hc1x.c:1285 #, c-format msgid "" "%s: linking files compiled for 32-bit double (-fshort-double) and others for " "64-bit double" msgstr "" -#: elf32-m68hc1x.c:1319 +#: elf32-m68hc1x.c:1295 #, c-format msgid "%s: linking files compiled for HCS12 with others compiled for HC12" msgstr "" -#: elf32-m68hc1x.c:1365 +#: elf32-m68hc1x.c:1341 #, c-format msgid "[abi=32-bit int, " msgstr "" -#: elf32-m68hc1x.c:1367 +#: elf32-m68hc1x.c:1343 #, c-format msgid "[abi=16-bit int, " msgstr "" -#: elf32-m68hc1x.c:1370 +#: elf32-m68hc1x.c:1346 #, c-format msgid "64-bit double, " msgstr "" -#: elf32-m68hc1x.c:1372 +#: elf32-m68hc1x.c:1348 #, c-format msgid "32-bit double, " msgstr "" -#: elf32-m68hc1x.c:1375 +#: elf32-m68hc1x.c:1351 #, c-format msgid "cpu=HC11]" msgstr "" -#: elf32-m68hc1x.c:1377 +#: elf32-m68hc1x.c:1353 #, c-format msgid "cpu=HCS12]" msgstr "" -#: elf32-m68hc1x.c:1379 +#: elf32-m68hc1x.c:1355 #, c-format msgid "cpu=HC12]" msgstr "" -#: elf32-m68hc1x.c:1382 +#: elf32-m68hc1x.c:1358 #, c-format msgid " [memory=bank-model]" msgstr "" -#: elf32-m68hc1x.c:1384 +#: elf32-m68hc1x.c:1360 #, c-format msgid " [memory=flat]" msgstr "" @@ -1233,100 +1253,100 @@ msgid "" "%s: compiled normally and linked with modules compiled with -mrelocatable" msgstr "" -#: elf32-ppc.c:3545 +#: elf32-ppc.c:3534 #, c-format msgid "%s: relocation %s cannot be used when making a shared object" msgstr "" -#: elf32-ppc.c:3751 +#: elf32-ppc.c:3740 #, c-format msgid "%s(%s+0x%lx): %s reloc against local symbol" msgstr "" -#: elf32-ppc.c:4956 elf64-ppc.c:8015 +#: elf32-ppc.c:4945 elf64-ppc.c:8022 #, c-format msgid "%s: unknown relocation type %d for symbol %s" msgstr "" -#: elf32-ppc.c:5207 +#: elf32-ppc.c:5196 #, c-format msgid "%s(%s+0x%lx): non-zero addend on %s reloc against `%s'" msgstr "" -#: elf32-ppc.c:5518 elf32-ppc.c:5544 elf32-ppc.c:5603 +#: elf32-ppc.c:5507 elf32-ppc.c:5533 elf32-ppc.c:5592 #, c-format msgid "" "%s: the target (%s) of a %s relocation is in the wrong output section (%s)" msgstr "" -#: elf32-ppc.c:5658 +#: elf32-ppc.c:5647 #, c-format msgid "%s: relocation %s is not yet supported for symbol %s." msgstr "" -#: elf32-ppc.c:5713 elf64-ppc.c:8687 +#: elf32-ppc.c:5702 elf64-ppc.c:8694 #, c-format msgid "%s(%s+0x%lx): unresolvable %s relocation against symbol `%s'" msgstr "" -#: elf32-ppc.c:5763 elf64-ppc.c:8733 +#: elf32-ppc.c:5752 elf64-ppc.c:8740 #, c-format msgid "%s(%s+0x%lx): %s reloc against `%s': error %d" msgstr "" -#: elf32-ppc.c:6007 +#: elf32-ppc.c:5996 #, c-format msgid "corrupt or empty %s section in %s" msgstr "" -#: elf32-ppc.c:6014 +#: elf32-ppc.c:6003 #, c-format msgid "unable to read in %s section from %s" msgstr "" -#: elf32-ppc.c:6020 +#: elf32-ppc.c:6009 #, c-format msgid "corrupt %s section in %s" msgstr "" -#: elf32-ppc.c:6063 +#: elf32-ppc.c:6052 #, c-format msgid "warning: unable to set size of %s section in %s" msgstr "" -#: elf32-ppc.c:6113 +#: elf32-ppc.c:6102 msgid "failed to allocate space for new APUinfo section." msgstr "" -#: elf32-ppc.c:6132 +#: elf32-ppc.c:6121 msgid "failed to compute new APUinfo section." msgstr "" -#: elf32-ppc.c:6135 +#: elf32-ppc.c:6124 msgid "failed to install new APUinfo section." msgstr "" -#: elf32-s390.c:2245 elf64-s390.c:2215 +#: elf32-s390.c:2234 elf64-s390.c:2204 #, c-format msgid "%s(%s+0x%lx): invalid instruction for TLS relocation %s" msgstr "" -#: elf32-sh64.c:215 elf64-sh64.c:2382 +#: elf32-sh64.c:215 elf64-sh64.c:2383 #, c-format msgid "%s: compiled as 32-bit object and %s is 64-bit" msgstr "" -#: elf32-sh64.c:218 elf64-sh64.c:2385 +#: elf32-sh64.c:218 elf64-sh64.c:2386 #, c-format msgid "%s: compiled as 64-bit object and %s is 32-bit" msgstr "" -#: elf32-sh64.c:220 elf64-sh64.c:2387 +#: elf32-sh64.c:220 elf64-sh64.c:2388 #, c-format msgid "%s: object size does not match that of target %s" msgstr "" -#: elf32-sh64.c:442 elf64-sh64.c:2954 +#: elf32-sh64.c:442 elf64-sh64.c:2955 #, c-format msgid "%s: encountered datalabel symbol in input" msgstr "" @@ -1344,7 +1364,7 @@ msgstr "" msgid "%s: GAS error: unexpected PTB insn with R_SH_PT_16" msgstr "" -#: elf32-sh64.c:589 elf64-sh64.c:1735 +#: elf32-sh64.c:589 elf64-sh64.c:1736 #, c-format msgid "%s: error: unaligned relocation type %d at %08x reloc %08x\n" msgstr "" @@ -1399,51 +1419,51 @@ msgstr "" msgid "%s: 0x%lx: fatal: reloc overflow while relaxing" msgstr "" -#: elf32-sh.c:4767 elf64-sh64.c:1568 +#: elf32-sh.c:4756 elf64-sh64.c:1568 msgid "Unexpected STO_SH5_ISA32 on local symbol is not handled" msgstr "" -#: elf32-sh.c:4924 +#: elf32-sh.c:4913 #, c-format msgid "%s: unresolvable relocation against symbol `%s' from %s section" msgstr "" -#: elf32-sh.c:4997 +#: elf32-sh.c:4984 #, c-format msgid "%s: 0x%lx: fatal: unaligned branch target for relax-support relocation" msgstr "" -#: elf32-sh.c:5030 elf32-sh.c:5045 +#: elf32-sh.c:5017 elf32-sh.c:5032 #, c-format msgid "%s: 0x%lx: fatal: unaligned %s relocation 0x%lx" msgstr "" -#: elf32-sh.c:5059 +#: elf32-sh.c:5046 #, c-format msgid "%s: 0x%lx: fatal: R_SH_PSHA relocation %d not in range -32..32" msgstr "" -#: elf32-sh.c:5073 +#: elf32-sh.c:5060 #, c-format msgid "%s: 0x%lx: fatal: R_SH_PSHL relocation %d not in range -32..32" msgstr "" -#: elf32-sh.c:6815 elf64-alpha.c:4744 +#: elf32-sh.c:6802 elf64-alpha.c:4744 #, c-format msgid "%s: TLS local exec code cannot be linked into shared objects" msgstr "" -#: elf32-sparc.c:2510 elf64-sparc.c:2281 +#: elf32-sparc.c:2499 elf64-sparc.c:2270 #, c-format msgid "%s: probably compiled without -fPIC?" msgstr "" -#: elf32-sparc.c:3336 +#: elf32-sparc.c:3325 #, c-format msgid "%s: compiled for a 64 bit system and target is 32 bit" msgstr "" -#: elf32-sparc.c:3350 +#: elf32-sparc.c:3339 #, c-format msgid "%s: linking little endian files with big endian files" msgstr "" @@ -1482,39 +1502,39 @@ msgstr "" msgid "FAILED to find previous HI16 reloc\n" msgstr "" -#: elf32-v850.c:1789 +#: elf32-v850.c:1758 msgid "could not locate special linker symbol __gp" msgstr "" -#: elf32-v850.c:1793 +#: elf32-v850.c:1762 msgid "could not locate special linker symbol __ep" msgstr "" -#: elf32-v850.c:1797 +#: elf32-v850.c:1766 msgid "could not locate special linker symbol __ctbp" msgstr "" -#: elf32-v850.c:1982 +#: elf32-v850.c:1951 #, c-format msgid "%s: Architecture mismatch with previous modules" msgstr "" -#: elf32-v850.c:2003 +#: elf32-v850.c:1972 #, c-format msgid "private flags = %lx: " msgstr "" -#: elf32-v850.c:2008 +#: elf32-v850.c:1977 #, c-format msgid "v850 architecture" msgstr "" -#: elf32-v850.c:2009 +#: elf32-v850.c:1978 #, c-format msgid "v850e architecture" msgstr "" -#: elf32-v850.c:2010 +#: elf32-v850.c:1979 #, c-format msgid "v850e1 architecture" msgstr "" @@ -1556,10 +1576,14 @@ msgstr "" msgid "%s: warning: %s relocation to 0x%x from %s section" msgstr "" -#: elf32-xstormy16.c:462 elf32-ia64.c:2417 elf64-ia64.c:2417 +#: elf32-xstormy16.c:462 elf32-ia64.c:2418 elf64-ia64.c:2418 msgid "non-zero addend in @fptr reloc" msgstr "" +#: elf32-xtensa.c:2051 +msgid "dynamic relocation in read-only section" +msgstr "" + #: elf64-alpha.c:1067 msgid "GPDISP relocation did not find ldah and lda instructions" msgstr "" @@ -1613,7 +1637,7 @@ msgstr "" msgid "%s: tp-relative relocation against dynamic symbol %s" msgstr "" -#: elf64-hppa.c:2082 +#: elf64-hppa.c:2083 #, c-format msgid "stub entry for %s cannot load .plt, dp offset = %ld" msgstr "" @@ -1630,113 +1654,113 @@ msgid "" "08lx\n" msgstr "" -#: elf64-mmix.c:1630 +#: elf64-mmix.c:1603 #, c-format msgid "" "%s: base-plus-offset relocation against register symbol: (unknown) in %s" msgstr "" -#: elf64-mmix.c:1635 +#: elf64-mmix.c:1608 #, c-format msgid "%s: base-plus-offset relocation against register symbol: %s in %s" msgstr "" -#: elf64-mmix.c:1679 +#: elf64-mmix.c:1652 #, c-format msgid "%s: register relocation against non-register symbol: (unknown) in %s" msgstr "" -#: elf64-mmix.c:1684 +#: elf64-mmix.c:1657 #, c-format msgid "%s: register relocation against non-register symbol: %s in %s" msgstr "" -#: elf64-mmix.c:1721 +#: elf64-mmix.c:1694 #, c-format msgid "%s: directive LOCAL valid only with a register or absolute value" msgstr "" -#: elf64-mmix.c:1749 +#: elf64-mmix.c:1722 #, c-format msgid "" "%s: LOCAL directive: Register $%ld is not a local register. First global " "register is $%ld." msgstr "" -#: elf64-mmix.c:2229 +#: elf64-mmix.c:2202 #, c-format msgid "" "%s: Error: multiple definition of `%s'; start of %s is set in a earlier " "linked file\n" msgstr "" -#: elf64-mmix.c:2288 +#: elf64-mmix.c:2261 msgid "Register section has contents\n" msgstr "" -#: elf64-mmix.c:2494 +#: elf64-mmix.c:2467 #, c-format msgid "" "Internal inconsistency: remaining %u != max %u.\n" " Please report this bug." msgstr "" -#: elf64-ppc.c:2431 libbfd.c:821 +#: elf64-ppc.c:2433 libbfd.c:821 #, c-format msgid "%s: compiled for a big endian system and target is little endian" msgstr "" -#: elf64-ppc.c:2434 libbfd.c:823 +#: elf64-ppc.c:2436 libbfd.c:823 #, c-format msgid "%s: compiled for a little endian system and target is big endian" msgstr "" -#: elf64-ppc.c:4638 +#: elf64-ppc.c:4656 #, c-format msgid "" "copy reloc against `%s' requires lazy plt linking; avoid setting " "LD_BIND_NOW=1 or upgrade gcc" msgstr "" -#: elf64-ppc.c:5009 +#: elf64-ppc.c:5027 #, c-format msgid "%s: .opd is not a regular array of opd entries" msgstr "" -#: elf64-ppc.c:5019 +#: elf64-ppc.c:5037 #, c-format msgid "%s: unexpected reloc type %u in .opd section" msgstr "" -#: elf64-ppc.c:5039 +#: elf64-ppc.c:5057 #, c-format msgid "%s: undefined sym `%s' in .opd section" msgstr "" -#: elf64-ppc.c:6265 +#: elf64-ppc.c:6272 #, c-format msgid "can't find branch stub `%s'" msgstr "" -#: elf64-ppc.c:6304 elf64-ppc.c:6379 +#: elf64-ppc.c:6311 elf64-ppc.c:6386 #, c-format msgid "linkage table error against `%s'" msgstr "" -#: elf64-ppc.c:6496 +#: elf64-ppc.c:6503 #, c-format msgid "can't build branch stub `%s'" msgstr "" -#: elf64-ppc.c:7215 +#: elf64-ppc.c:7222 msgid ".glink and .plt too far apart" msgstr "" -#: elf64-ppc.c:7327 +#: elf64-ppc.c:7334 msgid "stubs don't match calculated size" msgstr "" -#: elf64-ppc.c:7339 +#: elf64-ppc.c:7346 #, c-format msgid "" "linker stubs in %u groups\n" @@ -1747,24 +1771,24 @@ msgid "" " plt call %lu" msgstr "" -#: elf64-ppc.c:7537 +#: elf64-ppc.c:7544 #, c-format msgid "%s(%s+0x%lx): %s used with TLS symbol %s" msgstr "" -#: elf64-ppc.c:7538 +#: elf64-ppc.c:7545 #, c-format msgid "%s(%s+0x%lx): %s used with non-TLS symbol %s" msgstr "" -#: elf64-ppc.c:7949 +#: elf64-ppc.c:7956 #, c-format msgid "" "%s(%s+0x%lx): automatic multiple TOCs not supported using your crt files; " "recompile with -mminimal-toc or upgrade gcc" msgstr "" -#: elf64-ppc.c:7957 +#: elf64-ppc.c:7964 #, c-format msgid "" "%s(%s+0x%lx): sibling call optimization to `%s' does not allow automatic " @@ -1772,12 +1796,12 @@ msgid "" "or make `%s' extern" msgstr "" -#: elf64-ppc.c:8555 +#: elf64-ppc.c:8562 #, c-format msgid "%s: relocation %s is not supported for symbol %s." msgstr "" -#: elf64-ppc.c:8634 +#: elf64-ppc.c:8641 #, c-format msgid "%s: error: relocation %s not a multiple of %d" msgstr "" @@ -1807,7 +1831,7 @@ msgstr "" msgid "Symbol `%s' has differing types: %s in %s, previously REGISTER in %s" msgstr "" -#: elf64-sparc.c:3020 +#: elf64-sparc.c:3009 #, c-format msgid "%s: linking UltraSPARC specific with HAL specific code" msgstr "" @@ -1913,277 +1937,277 @@ msgstr "" msgid "%s: unsupported relocation type %s" msgstr "" -#: elfcode.h:1068 +#: elfcode.h:1050 #, c-format msgid "%s: version count (%ld) does not match symbol count (%ld)" msgstr "" -#: elfcode.h:1294 +#: elfcode.h:1276 #, c-format msgid "%s(%s): relocation %d has invalid symbol index %ld" msgstr "" -#: elflink.c:1349 +#: elflink.c:1350 #, c-format msgid "%s: warning: unexpected redefinition of indirect versioned symbol `%s'" msgstr "" -#: elflink.c:1668 +#: elflink.c:1669 #, c-format msgid "%s: undefined versioned symbol name %s" msgstr "" -#: elflink.c:1817 +#: elflink.c:1818 #, c-format msgid "" "%s: bad reloc symbol index (0x%lx >= 0x%lx) for offset 0x%lx in section `%s'" msgstr "" -#: elflink.c:2006 +#: elflink.c:2007 #, c-format msgid "%s: relocation size mismatch in %s section %s" msgstr "" -#: elflink.c:2295 +#: elflink.c:2296 #, c-format msgid "warning: type and size of dynamic symbol `%s' are not defined" msgstr "" -#: elflink.h:196 +#: elflink.c:2917 msgid "warning: " msgstr "" -#: elflink.h:691 +#: elflink.c:3411 #, c-format msgid "%s: %s: invalid version %u (max %d)" msgstr "" -#: elflink.h:732 +#: elflink.c:3452 #, c-format msgid "%s: %s: invalid needed version %d" msgstr "" -#: elflink.h:907 +#: elflink.c:3627 #, c-format msgid "Warning: alignment %u of symbol `%s' in %s is smaller than %u in %s" msgstr "" -#: elflink.h:921 +#: elflink.c:3641 #, c-format msgid "Warning: size of symbol `%s' changed from %lu in %s to %lu in %s" msgstr "" -#: elflink.h:1858 +#: elflink.c:4837 #, c-format msgid "%s: undefined version: %s" msgstr "" -#: elflink.h:1924 +#: elflink.c:4903 #, c-format msgid "%s: .preinit_array section is not allowed in DSO" msgstr "" -#: elflink.h:2750 +#: elflink.c:5594 msgid "Not enough memory to sort relocations" msgstr "" -#: elflink.h:3609 elflink.h:3652 +#: elflink.c:5976 #, c-format -msgid "%s: could not find output section %s" +msgid "%s: %s symbol `%s' in %s is referenced by DSO" msgstr "" -#: elflink.h:3615 +#: elflink.c:6057 #, c-format -msgid "warning: %s section has zero size" +msgid "%s: could not find output section %s for input section %s" msgstr "" -#: elflink.h:4124 +#: elflink.c:6156 #, c-format -msgid "%s: %s symbol `%s' in %s is referenced by DSO" +msgid "%s: %s symbol `%s' isn't defined" msgstr "" -#: elflink.h:4205 -#, c-format -msgid "%s: could not find output section %s for input section %s" +#: elflink.c:6575 elflink.c:6616 +msgid "%T: discarded in section `%s' from %s\n" msgstr "" -#: elflink.h:4307 +#: elflink.c:7870 elflink.c:7912 #, c-format -msgid "%s: %s symbol `%s' isn't defined" +msgid "%s: could not find output section %s" msgstr "" -#: elflink.h:4691 elflink.h:4733 -msgid "%T: discarded in section `%s' from %s\n" +#: elflink.c:7876 +#, c-format +msgid "warning: %s section has zero size" msgstr "" -#: elflink.h:5542 +#: elflink.c:8427 msgid "Warning: gc-sections option ignored" msgstr "" -#: elfxx-mips.c:899 +#: elfxx-mips.c:890 msgid "static procedure (no name)" msgstr "" -#: elfxx-mips.c:2037 +#: elfxx-mips.c:2028 msgid "not enough GOT space for local GOT entries" msgstr "" -#: elfxx-mips.c:3786 +#: elfxx-mips.c:3775 #, c-format msgid "%s: %s+0x%lx: jump to stub routine which is not jal" msgstr "" -#: elfxx-mips.c:5271 +#: elfxx-mips.c:5260 #, c-format msgid "%s: Malformed reloc detected for section %s" msgstr "" -#: elfxx-mips.c:5345 +#: elfxx-mips.c:5334 #, c-format msgid "%s: CALL16 reloc at 0x%lx not against global symbol" msgstr "" -#: elfxx-mips.c:8642 +#: elfxx-mips.c:8631 #, c-format msgid "%s: illegal section name `%s'" msgstr "" -#: elfxx-mips.c:8965 +#: elfxx-mips.c:8954 #, c-format msgid "%s: endianness incompatible with that of the selected emulation" msgstr "" -#: elfxx-mips.c:8977 +#: elfxx-mips.c:8966 #, c-format msgid "%s: ABI is incompatible with that of the selected emulation" msgstr "" -#: elfxx-mips.c:9049 +#: elfxx-mips.c:9038 #, c-format msgid "%s: warning: linking PIC files with non-PIC files" msgstr "" -#: elfxx-mips.c:9066 +#: elfxx-mips.c:9055 #, c-format msgid "%s: linking 32-bit code with 64-bit code" msgstr "" -#: elfxx-mips.c:9094 +#: elfxx-mips.c:9083 #, c-format msgid "%s: linking %s module with previous %s modules" msgstr "" -#: elfxx-mips.c:9117 +#: elfxx-mips.c:9106 #, c-format msgid "%s: ABI mismatch: linking %s module with previous %s modules" msgstr "" -#: elfxx-mips.c:9182 +#: elfxx-mips.c:9171 #, c-format msgid " [abi=O32]" msgstr "" -#: elfxx-mips.c:9184 +#: elfxx-mips.c:9173 #, c-format msgid " [abi=O64]" msgstr "" -#: elfxx-mips.c:9186 +#: elfxx-mips.c:9175 #, c-format msgid " [abi=EABI32]" msgstr "" -#: elfxx-mips.c:9188 +#: elfxx-mips.c:9177 #, c-format msgid " [abi=EABI64]" msgstr "" -#: elfxx-mips.c:9190 +#: elfxx-mips.c:9179 #, c-format msgid " [abi unknown]" msgstr "" -#: elfxx-mips.c:9192 +#: elfxx-mips.c:9181 #, c-format msgid " [abi=N32]" msgstr "" -#: elfxx-mips.c:9194 +#: elfxx-mips.c:9183 #, c-format msgid " [abi=64]" msgstr "" -#: elfxx-mips.c:9196 +#: elfxx-mips.c:9185 #, c-format msgid " [no abi set]" msgstr "" -#: elfxx-mips.c:9199 +#: elfxx-mips.c:9188 #, c-format msgid " [mips1]" msgstr "" -#: elfxx-mips.c:9201 +#: elfxx-mips.c:9190 #, c-format msgid " [mips2]" msgstr "" -#: elfxx-mips.c:9203 +#: elfxx-mips.c:9192 #, c-format msgid " [mips3]" msgstr "" -#: elfxx-mips.c:9205 +#: elfxx-mips.c:9194 #, c-format msgid " [mips4]" msgstr "" -#: elfxx-mips.c:9207 +#: elfxx-mips.c:9196 #, c-format msgid " [mips5]" msgstr "" -#: elfxx-mips.c:9209 +#: elfxx-mips.c:9198 #, c-format msgid " [mips32]" msgstr "" -#: elfxx-mips.c:9211 +#: elfxx-mips.c:9200 #, c-format msgid " [mips64]" msgstr "" -#: elfxx-mips.c:9213 +#: elfxx-mips.c:9202 #, c-format msgid " [mips32r2]" msgstr "" -#: elfxx-mips.c:9215 +#: elfxx-mips.c:9204 #, c-format msgid " [mips64r2]" msgstr "" -#: elfxx-mips.c:9217 +#: elfxx-mips.c:9206 #, c-format msgid " [unknown ISA]" msgstr "" -#: elfxx-mips.c:9220 +#: elfxx-mips.c:9209 #, c-format msgid " [mdmx]" msgstr "" -#: elfxx-mips.c:9223 +#: elfxx-mips.c:9212 #, c-format msgid " [mips16]" msgstr "" -#: elfxx-mips.c:9226 +#: elfxx-mips.c:9215 #, c-format msgid " [32bitmode]" msgstr "" -#: elfxx-mips.c:9228 +#: elfxx-mips.c:9217 #, c-format msgid " [not 32bitmode]" msgstr "" @@ -2293,12 +2317,12 @@ msgstr "" msgid "Deprecated %s called\n" msgstr "" -#: linker.c:1829 +#: linker.c:1831 #, c-format msgid "%s: indirect symbol `%s' to `%s' is a loop" msgstr "" -#: linker.c:2697 +#: linker.c:2699 #, c-format msgid "Attempt to do relocatable link with %s input and %s output" msgstr "" @@ -2833,75 +2857,75 @@ msgstr "" msgid "%s: loader reloc in read-only section %s" msgstr "" -#: elf32-ia64.c:2362 elf64-ia64.c:2362 +#: elf32-ia64.c:2363 elf64-ia64.c:2363 msgid "@pltoff reloc against local symbol" msgstr "" -#: elf32-ia64.c:3767 elf64-ia64.c:3767 +#: elf32-ia64.c:3768 elf64-ia64.c:3768 #, c-format msgid "%s: short data segment overflowed (0x%lx >= 0x400000)" msgstr "" -#: elf32-ia64.c:3778 elf64-ia64.c:3778 +#: elf32-ia64.c:3779 elf64-ia64.c:3779 #, c-format msgid "%s: __gp does not cover short data segment" msgstr "" -#: elf32-ia64.c:4026 elf64-ia64.c:4026 +#: elf32-ia64.c:4027 elf64-ia64.c:4027 #, c-format msgid "%s: non-pic code with imm relocation against dynamic symbol `%s'" msgstr "" -#: elf32-ia64.c:4091 elf64-ia64.c:4091 +#: elf32-ia64.c:4092 elf64-ia64.c:4092 #, c-format msgid "%s: @gprel relocation against dynamic symbol %s" msgstr "" -#: elf32-ia64.c:4151 elf64-ia64.c:4151 +#: elf32-ia64.c:4152 elf64-ia64.c:4152 #, c-format msgid "%s: linking non-pic code in a position independent executable" msgstr "" -#: elf32-ia64.c:4288 elf64-ia64.c:4288 +#: elf32-ia64.c:4289 elf64-ia64.c:4289 #, c-format msgid "%s: @internal branch to dynamic symbol %s" msgstr "" -#: elf32-ia64.c:4290 elf64-ia64.c:4290 +#: elf32-ia64.c:4291 elf64-ia64.c:4291 #, c-format msgid "%s: speculation fixup to dynamic symbol %s" msgstr "" -#: elf32-ia64.c:4292 elf64-ia64.c:4292 +#: elf32-ia64.c:4293 elf64-ia64.c:4293 #, c-format msgid "%s: @pcrel relocation against dynamic symbol %s" msgstr "" -#: elf32-ia64.c:4504 elf64-ia64.c:4504 +#: elf32-ia64.c:4505 elf64-ia64.c:4505 msgid "unsupported reloc" msgstr "" -#: elf32-ia64.c:4783 elf64-ia64.c:4783 +#: elf32-ia64.c:4784 elf64-ia64.c:4784 #, c-format msgid "%s: linking trap-on-NULL-dereference with non-trapping files" msgstr "" -#: elf32-ia64.c:4792 elf64-ia64.c:4792 +#: elf32-ia64.c:4793 elf64-ia64.c:4793 #, c-format msgid "%s: linking big-endian files with little-endian files" msgstr "" -#: elf32-ia64.c:4801 elf64-ia64.c:4801 +#: elf32-ia64.c:4802 elf64-ia64.c:4802 #, c-format msgid "%s: linking 64-bit files with 32-bit files" msgstr "" -#: elf32-ia64.c:4810 elf64-ia64.c:4810 +#: elf32-ia64.c:4811 elf64-ia64.c:4811 #, c-format msgid "%s: linking constant-gp files with non-constant-gp files" msgstr "" -#: elf32-ia64.c:4820 elf64-ia64.c:4820 +#: elf32-ia64.c:4821 elf64-ia64.c:4821 #, c-format msgid "%s: linking auto-pic files with non-auto-pic files" msgstr "" |