diff options
author | Daniel Jacobowitz <dan@debian.org> | 2004-04-02 16:47:53 +0000 |
---|---|---|
committer | Daniel Jacobowitz <dan@debian.org> | 2004-04-02 16:47:53 +0000 |
commit | 0edbed049b92c72c243a5a0303a8d81e73ceeba9 (patch) | |
tree | b547da135ed2616b5767d76493cd897d2c0209ca | |
parent | 3f7fc95ea7426d00c1b85ed042d331b01d819477 (diff) | |
download | binutils-redhat-0edbed049b92c72c243a5a0303a8d81e73ceeba9.tar.gz |
Merge GDB mainline of 20040402 to intercu branch.
78 files changed, 6264 insertions, 4455 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 0b8b69cb01..6f6b14c27d 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,201 @@ +2004-04-01 Paul Brook <paul@codesourcery.com> + + * bfd-in.h (bfd_elf32_arm_process_before_allocation): Update. + * elf32-arm.h (struct elf32_elf_section_map): New. + (struct _arm_elf_section_data): New. + (elf32_arm_section_data): Define. + (struct elf32_arm_link_hash_table): Add byteswap_code. + (elf32_arm_link_hash_table_create): Initialize byteswap_code. + (bfd_elf32_arm_process_before_allocation): Add byteswap_code. + (elf32_arm_post_process_headers): Set EF_ARM_BE8. + (elf32_arm_output_symbol_hook, elf32_arm_new_section_hook, + elf32_arm_compare_mapping, elf32_arm_write_section): New functions. + (bfd_elf32_new_section_hook, elf_backend_write_section, + elf_backend_link_output_symbol_hook): Define. + +2004-04-01 Andy Chittenden <achittenden@bluearc.com> + + * stabs.c (struct stab_link_includes_totals): Add field 'symb' + that keeps the characters in a B_INCL..B_EINCL range. + (_bfd_link_section_stabs): When computing the sum of the + characters in a B_INCL..B_EINCL range also keep a copy of those + characters. Use this information to distinguish between + include sections that have the same sum and the same length + but which are nevertheless unique. + +2004-03-31 Paul Brook <paul@codesourcery.com> + + * elf32-arm.h (elf32_arm_final_link_relocate): Add R_ARM_ALU*. + * elfarm-nabi.c (elf32_arm_howto_table): Ditto. + +2004-03-31 Andy Chittenden <achittenden@bluearc.com> + + * stabs.c (struct stab_link_includes_totals): Rename field 'total' + to 'sum_chars' and add field 'num_chars'. + (_bfd_link_section_stabs): When computing the sum of the + characters in a B_INCL..B_EINCL range also keep a count of the + number of characters. Use this information to help distinguish + between include sections when have the same sum but which + nevertheless are still unique. + +2004-03-31 Mattias Engdegård <mattias@virtutech.se> + + * stabs.c (_bfd_link_section_stabs): Do not skip N_EXCL stabs. + +2004-03-30 Galit Heller <Galit.Heller@nsc.com> + Tomer Levi <Tomer.Levi@nsc.com> + + * Makefile.am (ALL_MACHINES): Add cpu-cr16c.lo. + (ALL_MACHINES_CFILES): Add cpu-cr16c.c. + (BFD32_BACKENDS): Add elf32-cr16c.lo. + (BFD32_BACKENDS_CFILES): Add elf32-cr16c.c. + (cpu-cr16c.lo): New target. + (elf32-cr16c.lo): Likewise. + * Makefile.in: Regenerate. + * archures.c (bfd_architecture): Add bfd_{arch,mach}_cr16c. + (bfd_archures_list): Add bfd_cr16c_arch. + * config.bfd: Handle cr16c-*-elf*. + * configure.in: Handle bfd_elf32_cr16c_vec. + * configure: Regenerate. + * reloc.c: Add BFD_RELOC_16C_NUM08, BFD_RELOC_16C_NUM08_C, + BFD_RELOC_16C_NUM16, BFD_RELOC_16C_NUM16_C, + BFD_RELOC_16C_NUM32, BFD_RELOC_16C_NUM32_C, + BFD_RELOC_16C_DISP04, BFD_RELOC_16C_DISP04_C, + BFD_RELOC_16C_DISP08, BFD_RELOC_16C_DISP08_C, + BFD_RELOC_16C_DISP16, BFD_RELOC_16C_DISP16_C, + BFD_RELOC_16C_DISP24, BFD_RELOC_16C_DISP24_C, + BFD_RELOC_16C_DISP24a, BFD_RELOC_16C_DISP24a_C, + BFD_RELOC_16C_REG04, BFD_RELOC_16C_REG04_C, + BFD_RELOC_16C_REG04a, BFD_RELOC_16C_REG04a_C, + BFD_RELOC_16C_REG14, BFD_RELOC_16C_REG14_C, + BFD_RELOC_16C_REG16, BFD_RELOC_16C_REG16_C, + BFD_RELOC_16C_REG20, BFD_RELOC_16C_REG20_C, + BFD_RELOC_16C_ABS20, BFD_RELOC_16C_ABS20_C, + BFD_RELOC_16C_ABS24, BFD_RELOC_16C_ABS24_C, + BFD_RELOC_16C_IMM04, BFD_RELOC_16C_IMM04_C, + BFD_RELOC_16C_IMM16, BFD_RELOC_16C_IMM16_C, + BFD_RELOC_16C_IMM20, BFD_RELOC_16C_IMM20_C, + BFD_RELOC_16C_IMM24, BFD_RELOC_16C_IMM24_C, + BFD_RELOC_16C_IMM32, BFD_RELOC_16C_IMM32_C. + * targets.c (bfd_elf32_cr16c_vec): Declare. + (bfd_target_vector): Add bfd_elf32_cr16c_vec. + * cpu-cr16c.c: New file. + * elf32-cr16c.c: Likewise. + * libbfd.h: Regenerate. + * bfd-in2.h: Likewise. + +2004-03-30 Jakub Jelinek <jakub@redhat.com> + + * elf.c (map_sections_to_segments): Fix handling of .tbss. + +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. + +2004-03-27 Alan Modra <amodra@bigpond.net.au> + + * elf-bfd.h (struct elf_reloc_cookie): Add r_sym_shift field. + * elflink.h: Replace all occurrences of sizeof (Elf_External_*) + where Elf_External_* is different for 64 and 32 bit, with + corresponding elf_size_info field. + (struct elf_final_link_info): Use "bfd_byte *" instead + of "Elf_External_Sym *" for external_syms and symbuf. + (elf_link_adjust_relocs): Set up r_type_mask and r_sym_shift local + vars and use instead of ELF_R_INFO and ELF_R_TYPE macros. + (struct elf_link_sort_rela): Add "sym_mask" alias for "offset". + (elf_link_sort_cmp1): Use sym_mask field instead of ELF_R_SYM. + (elf_link_sort_cmp2): Adjust. + (elf_link_sort_relocs): Set up r_sym_mask local var instead of + using ELF_R_SYM macro. Set u.sym_mask. + (elf_bfd_final_link): Call _bfd_elf_stringtab_init instead of macro + version, elf_stringtab_init. Ditto for bfd_section_from_elf_index + vs. section_from_elf_index. Adjust Elf_External_Sym pointer + arithmetic. Pass bed to elf_link_flush_output_syms. Adjust + Elf_External_Dyn pointer arithmentic. Use bed swap_dyn_in and + swap_syn_out functions. Rearrange dyn swap in/out switch. + (elf_link_output_sym): Adjust Elf_External_Sym pointer arithmentic. + Pass bed to elf_link_flush_output_syms. Use bed swap_symbol_out. + (elf_link_flush_output_syms): Add elf_backend_data arg. + (elf_link_check_versioned_symbol): Likewise. + (elf_link_output_extsym): Pass bed to elf_link_check_versioned_symbol. + Adjust Elf_External_Sym pointer arithmetic. Use bed swap_symbol_out. + (elf_link_input_bfd): Use bfd_section_from_elf_index. Set up + r_type_mask and r_sym_shift local vars and use instead of ELF_R_SYM, + ELF_R_TYPE and ELF_R_INFO macros. + (elf_reloc_link_order): Select ELF32_R_INFO or ELF64_R_INFO invocation + based on size rather than using ELF_R_INFO. + (elf_gc_mark): Set up r_sym_shift local var and use instead of + ELF_R_SYM macro. + (struct alloc_got_off_arg): New. + (elf_gc_common_finalize_got_offsets): Use elf_size_info instead of + ARCH_SIZE. Pass get entry size down to elf_gc_allocate_got_offsets. + (elf_gc_allocate_got_offsets): Adjust. + (elf_reloc_symbol_deleted_p): Usee cookie.r_sym_shift instead of + ELF_R_SYM. Use bfd_section_from_elf_index. + (elf_bfd_discard_info): Set cookie.r_sym_shift. + * elfcode.h (elf_stringtab_init, section_from_elf_index): Delete. + (elf_slurp_symbol_table): Use bfd_section_from_elf_index. + +2004-03-26 Stan Shebs <shebs@apple.com> + + Remove MPW support, no longer used. + * config.bfd (powerpc-*-mpw*): Remove configuration. + * mpw-config.in, mpw-make.sed: Remove files. + * ecoffswap.h [MPW_C]: Remove MPW-C-friendly version of code. + 2004-03-26 Alan Modra <amodra@bigpond.net.au> * elf64-ppc.c (elf_backend_add_symbol_hook): Define. @@ -53,7 +251,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. @@ -114,7 +312,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 315ede0999..bc2f64f94d 100644 --- a/bfd/Makefile.am +++ b/bfd/Makefile.am @@ -55,6 +55,7 @@ ALL_MACHINES = \ cpu-arc.lo \ cpu-arm.lo \ cpu-avr.lo \ + cpu-cr16c.lo \ cpu-cris.lo \ cpu-d10v.lo \ cpu-d30v.lo \ @@ -111,6 +112,7 @@ ALL_MACHINES_CFILES = \ cpu-arm.c \ cpu-avr.c \ cpu-cris.c \ + cpu-cr16c.c \ cpu-d10v.c \ cpu-d30v.c \ cpu-dlx.c \ @@ -213,6 +215,7 @@ BFD32_BACKENDS = \ elfarm-oabi.lo \ elfarm-nabi.lo \ elf32-avr.lo \ + elf32-cr16c.lo \ elf32-cris.lo \ elf32-d10v.lo \ elf32-d30v.lo \ @@ -378,6 +381,7 @@ BFD32_BACKENDS_CFILES = \ elfarm-oabi.c \ elfarm-nabi.c \ elf32-avr.c \ + elf32-cr16c.c \ elf32-cris.c \ elf32-d10v.c \ elf32-d30v.c \ @@ -588,7 +592,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 \ @@ -915,6 +919,7 @@ cpu-alpha.lo: cpu-alpha.c $(INCDIR)/filenames.h cpu-arc.lo: cpu-arc.c $(INCDIR)/filenames.h cpu-arm.lo: cpu-arm.c $(INCDIR)/filenames.h $(INCDIR)/libiberty.h cpu-avr.lo: cpu-avr.c $(INCDIR)/filenames.h +cpu-cr16c.lo: cpu-cr16c.c $(INCDIR)/filenames.h cpu-cris.lo: cpu-cris.c $(INCDIR)/filenames.h cpu-d10v.lo: cpu-d10v.c $(INCDIR)/filenames.h cpu-d30v.lo: cpu-d30v.c $(INCDIR)/filenames.h @@ -1137,6 +1142,10 @@ elf32-avr.lo: elf32-avr.c $(INCDIR)/filenames.h elf-bfd.h \ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \ $(INCDIR)/bfdlink.h $(INCDIR)/elf/avr.h $(INCDIR)/elf/reloc-macros.h \ elf32-target.h +elf32-cr16c.lo: elf32-cr16c.c $(INCDIR)/filenames.h elf-bfd.h \ + $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/elf/cr16c.h $(INCDIR)/elf/reloc-macros.h \ + elf32-target.h elf32-cris.lo: elf32-cris.c $(INCDIR)/filenames.h elf-bfd.h \ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \ $(INCDIR)/bfdlink.h $(INCDIR)/elf/cris.h $(INCDIR)/elf/reloc-macros.h \ @@ -1310,7 +1319,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 +1601,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 2aef7e4dce..aa60ce9fbb 100644 --- a/bfd/Makefile.in +++ b/bfd/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am +# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am # Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation @@ -183,6 +183,7 @@ ALL_MACHINES = \ cpu-arc.lo \ cpu-arm.lo \ cpu-avr.lo \ + cpu-cr16c.lo \ cpu-cris.lo \ cpu-d10v.lo \ cpu-d30v.lo \ @@ -240,6 +241,7 @@ ALL_MACHINES_CFILES = \ cpu-arm.c \ cpu-avr.c \ cpu-cris.c \ + cpu-cr16c.c \ cpu-d10v.c \ cpu-d30v.c \ cpu-dlx.c \ @@ -343,6 +345,7 @@ BFD32_BACKENDS = \ elfarm-oabi.lo \ elfarm-nabi.lo \ elf32-avr.lo \ + elf32-cr16c.lo \ elf32-cris.lo \ elf32-d10v.lo \ elf32-d30v.lo \ @@ -509,6 +512,7 @@ BFD32_BACKENDS_CFILES = \ elfarm-oabi.c \ elfarm-nabi.c \ elf32-avr.c \ + elf32-cr16c.c \ elf32-cris.c \ elf32-d10v.c \ elf32-d30v.c \ @@ -725,7 +729,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 \ @@ -814,7 +818,7 @@ configure.in version.h DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) -TAR = tar +TAR = gtar GZIP_ENV = --best SOURCES = $(libbfd_a_SOURCES) $(libbfd_la_SOURCES) OBJECTS = $(libbfd_a_OBJECTS) $(libbfd_la_OBJECTS) @@ -1452,6 +1456,7 @@ cpu-alpha.lo: cpu-alpha.c $(INCDIR)/filenames.h cpu-arc.lo: cpu-arc.c $(INCDIR)/filenames.h cpu-arm.lo: cpu-arm.c $(INCDIR)/filenames.h $(INCDIR)/libiberty.h cpu-avr.lo: cpu-avr.c $(INCDIR)/filenames.h +cpu-cr16c.lo: cpu-cr16c.c $(INCDIR)/filenames.h cpu-cris.lo: cpu-cris.c $(INCDIR)/filenames.h cpu-d10v.lo: cpu-d10v.c $(INCDIR)/filenames.h cpu-d30v.lo: cpu-d30v.c $(INCDIR)/filenames.h @@ -1674,6 +1679,10 @@ elf32-avr.lo: elf32-avr.c $(INCDIR)/filenames.h elf-bfd.h \ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \ $(INCDIR)/bfdlink.h $(INCDIR)/elf/avr.h $(INCDIR)/elf/reloc-macros.h \ elf32-target.h +elf32-cr16c.lo: elf32-cr16c.c $(INCDIR)/filenames.h elf-bfd.h \ + $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \ + $(INCDIR)/bfdlink.h $(INCDIR)/elf/cr16c.h $(INCDIR)/elf/reloc-macros.h \ + elf32-target.h elf32-cris.lo: elf32-cris.c $(INCDIR)/filenames.h elf-bfd.h \ $(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \ $(INCDIR)/bfdlink.h $(INCDIR)/elf/cris.h $(INCDIR)/elf/reloc-macros.h \ @@ -1847,7 +1856,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 +2138,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/archures.c b/bfd/archures.c index 0e2a08b831..f75be84386 100644 --- a/bfd/archures.c +++ b/bfd/archures.c @@ -307,6 +307,8 @@ DESCRIPTION .#define bfd_mach_avr3 3 .#define bfd_mach_avr4 4 .#define bfd_mach_avr5 5 +. bfd_arch_cr16c, {* National Semiconductor CompactRISC. *} +.#define bfd_mach_cr16c 1 . bfd_arch_cris, {* Axis CRIS *} . bfd_arch_s390, {* IBM s390 *} .#define bfd_mach_s390_31 31 @@ -375,6 +377,7 @@ extern const bfd_arch_info_type bfd_alpha_arch; extern const bfd_arch_info_type bfd_arc_arch; extern const bfd_arch_info_type bfd_arm_arch; extern const bfd_arch_info_type bfd_avr_arch; +extern const bfd_arch_info_type bfd_cr16c_arch; extern const bfd_arch_info_type bfd_cris_arch; extern const bfd_arch_info_type bfd_d10v_arch; extern const bfd_arch_info_type bfd_d30v_arch; @@ -435,6 +438,7 @@ static const bfd_arch_info_type * const bfd_archures_list[] = &bfd_arc_arch, &bfd_arm_arch, &bfd_avr_arch, + &bfd_cr16c_arch, &bfd_cris_arch, &bfd_d10v_arch, &bfd_d30v_arch, diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h index ff585fde0e..9ad727eda5 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 @@ -788,7 +786,7 @@ extern bfd_boolean bfd_elf32_arm_allocate_interworking_sections (struct bfd_link_info *); extern bfd_boolean bfd_elf32_arm_process_before_allocation - (bfd *, struct bfd_link_info *, int); + (bfd *, struct bfd_link_info *, int, int); extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking (bfd *, struct bfd_link_info *); diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index 060dcc6bef..c2e18194be 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 @@ -795,7 +793,7 @@ extern bfd_boolean bfd_elf32_arm_allocate_interworking_sections (struct bfd_link_info *); extern bfd_boolean bfd_elf32_arm_process_before_allocation - (bfd *, struct bfd_link_info *, int); + (bfd *, struct bfd_link_info *, int, int); extern bfd_boolean bfd_elf32_arm_get_bfd_for_interworking (bfd *, struct bfd_link_info *); @@ -1707,6 +1705,8 @@ enum bfd_architecture #define bfd_mach_avr3 3 #define bfd_mach_avr4 4 #define bfd_mach_avr5 5 + bfd_arch_cr16c, /* National Semiconductor CompactRISC. */ +#define bfd_mach_cr16c 1 bfd_arch_cris, /* Axis CRIS */ bfd_arch_s390, /* IBM s390 */ #define bfd_mach_s390_31 31 @@ -3345,6 +3345,48 @@ to follow the 16K memory bank of 68HC12 (seen as mapped in the window). */ This is the 5 bits of a value. */ BFD_RELOC_M68HC12_5B, +/* NS CR16C Relocations. */ + BFD_RELOC_16C_NUM08, + BFD_RELOC_16C_NUM08_C, + BFD_RELOC_16C_NUM16, + BFD_RELOC_16C_NUM16_C, + BFD_RELOC_16C_NUM32, + BFD_RELOC_16C_NUM32_C, + BFD_RELOC_16C_DISP04, + BFD_RELOC_16C_DISP04_C, + BFD_RELOC_16C_DISP08, + BFD_RELOC_16C_DISP08_C, + BFD_RELOC_16C_DISP16, + BFD_RELOC_16C_DISP16_C, + BFD_RELOC_16C_DISP24, + BFD_RELOC_16C_DISP24_C, + BFD_RELOC_16C_DISP24a, + BFD_RELOC_16C_DISP24a_C, + BFD_RELOC_16C_REG04, + BFD_RELOC_16C_REG04_C, + BFD_RELOC_16C_REG04a, + BFD_RELOC_16C_REG04a_C, + BFD_RELOC_16C_REG14, + BFD_RELOC_16C_REG14_C, + BFD_RELOC_16C_REG16, + BFD_RELOC_16C_REG16_C, + BFD_RELOC_16C_REG20, + BFD_RELOC_16C_REG20_C, + BFD_RELOC_16C_ABS20, + BFD_RELOC_16C_ABS20_C, + BFD_RELOC_16C_ABS24, + BFD_RELOC_16C_ABS24_C, + BFD_RELOC_16C_IMM04, + BFD_RELOC_16C_IMM04_C, + BFD_RELOC_16C_IMM16, + BFD_RELOC_16C_IMM16_C, + BFD_RELOC_16C_IMM20, + BFD_RELOC_16C_IMM20_C, + BFD_RELOC_16C_IMM24, + BFD_RELOC_16C_IMM24_C, + BFD_RELOC_16C_IMM32, + BFD_RELOC_16C_IMM32_C, + /* These relocs are only used within the CRIS assembler. They are not (at present) written to any object files. */ BFD_RELOC_CRIS_BDISP8, diff --git a/bfd/config.bfd b/bfd/config.bfd index 2f9c197a90..ec326cc271 100644 --- a/bfd/config.bfd +++ b/bfd/config.bfd @@ -306,6 +306,11 @@ case "${targ}" in targ_underscore=yes ;; + cr16c-*-elf*) + targ_defvec=bfd_elf32_cr16c_vec + targ_underscore=yes + ;; + cris-*-*) targ_defvec=cris_aout_vec targ_selvecs="bfd_elf32_us_cris_vec bfd_elf32_cris_vec ieee_vec" @@ -969,7 +974,7 @@ case "${targ}" in targ_selvecs="mach_o_be_vec mach_o_le_vec mach_o_fat_vec pef_vec pef_xlib_vec sym_vec" targ_archs="bfd_powerpc_arch bfd_rs6000_arch bfd_i386_arch" ;; - powerpc-*-macos* | powerpc-*-mpw*) + powerpc-*-macos*) targ_defvec=pmac_xcoff_vec ;; powerpc-*-netware*) diff --git a/bfd/configure b/bfd/configure index ab9049b058..cec4a8b929 100755 --- a/bfd/configure +++ b/bfd/configure @@ -6299,6 +6299,7 @@ do bfd_elf32_bigarm_oabi_vec) tb="$tb elfarm-oabi.lo elf32.lo $elf" ;; bfd_elf32_bigarm_vec) tb="$tb elfarm-nabi.lo elf32.lo $elf" ;; bfd_elf32_bigmips_vec) tb="$tb elf32-mips.lo elfxx-mips.lo elf32.lo $elf ecofflink.lo" ;; + bfd_elf32_cr16c_vec) tb="$tb elf32-cr16c.lo elf32.lo $elf" ;; bfd_elf32_cris_vec) tb="$tb elf32-cris.lo elf32.lo $elf" ;; bfd_elf32_d10v_vec) tb="$tb elf32-d10v.lo elf32.lo $elf" ;; bfd_elf32_d30v_vec) tb="$tb elf32-d30v.lo elf32.lo $elf" ;; @@ -6586,10 +6587,10 @@ case ${host64}-${target64}-${want64} in if test -n "$GCC" ; then bad_64bit_gcc=no; echo $ac_n "checking for gcc version with buggy 64-bit support""... $ac_c" 1>&6 -echo "configure:6590: checking for gcc version with buggy 64-bit support" >&5 +echo "configure:6591: checking for gcc version with buggy 64-bit support" >&5 # Add more tests for gcc versions with non-working 64-bit support here. cat > conftest.$ac_ext <<EOF -#line 6593 "configure" +#line 6594 "configure" #include "confdefs.h" :__GNUC__:__GNUC_MINOR__:__i386__: EOF @@ -6631,12 +6632,12 @@ esac for ac_func in ftello ftello64 fseeko fseeko64 do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6635: checking for $ac_func" >&5 +echo "configure:6636: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 6640 "configure" +#line 6641 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -6659,7 +6660,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:6663: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6664: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6685,13 +6686,13 @@ done if test x"$ac_cv_func_ftello" = xyes -a x"$ac_cv_func_fseeko" = xyes; then echo $ac_n "checking size of off_t""... $ac_c" 1>&6 -echo "configure:6689: checking size of off_t" >&5 +echo "configure:6690: checking size of off_t" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_off_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else for ac_size in 4 8 1 2 16 12 ; do # List sizes in rough order of prevalence. cat > conftest.$ac_ext <<EOF -#line 6695 "configure" +#line 6696 "configure" #include "confdefs.h" #include "confdefs.h" #include <sys/types.h> @@ -6701,7 +6702,7 @@ int main() { switch (0) case 0: case (sizeof (off_t) == $ac_size):; ; return 0; } EOF -if { (eval echo configure:6705: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:6706: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_sizeof_off_t=$ac_size else @@ -6725,7 +6726,7 @@ EOF fi echo $ac_n "checking file_ptr type""... $ac_c" 1>&6 -echo "configure:6729: checking file_ptr type" >&5 +echo "configure:6730: checking file_ptr type" >&5 bfd_file_ptr="long" bfd_ufile_ptr="unsigned long" if test x"$ac_cv_func_ftello64" = xyes -a x"$ac_cv_func_fseeko64" = xyes \ @@ -6750,17 +6751,17 @@ for ac_hdr in stdlib.h unistd.h sys/stat.h sys/types.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:6754: checking for $ac_hdr" >&5 +echo "configure:6755: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 6759 "configure" +#line 6760 "configure" #include "confdefs.h" #include <$ac_hdr> EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:6764: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:6765: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -6789,12 +6790,12 @@ done for ac_func in getpagesize do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:6793: checking for $ac_func" >&5 +echo "configure:6794: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 6798 "configure" +#line 6799 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -6817,7 +6818,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:6821: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:6822: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -6842,7 +6843,7 @@ fi done echo $ac_n "checking for working mmap""... $ac_c" 1>&6 -echo "configure:6846: checking for working mmap" >&5 +echo "configure:6847: checking for working mmap" >&5 if eval "test \"`echo '$''{'ac_cv_func_mmap_fixed_mapped'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -6850,7 +6851,7 @@ else ac_cv_func_mmap_fixed_mapped=no else cat > conftest.$ac_ext <<EOF -#line 6854 "configure" +#line 6855 "configure" #include "confdefs.h" /* Thanks to Mike Haertel and Jim Avera for this test. @@ -7003,7 +7004,7 @@ main() } EOF -if { (eval echo configure:7007: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:7008: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_func_mmap_fixed_mapped=yes else @@ -7028,12 +7029,12 @@ fi for ac_func in madvise mprotect do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:7032: checking for $ac_func" >&5 +echo "configure:7033: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <<EOF -#line 7037 "configure" +#line 7038 "configure" #include "confdefs.h" /* System header to define __stub macros and hopefully few prototypes, which can conflict with char $ac_func(); below. */ @@ -7056,7 +7057,7 @@ $ac_func(); ; return 0; } EOF -if { (eval echo configure:7060: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:7061: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else diff --git a/bfd/configure.in b/bfd/configure.in index e08a663dcd..d0aeca7621 100644 --- a/bfd/configure.in +++ b/bfd/configure.in @@ -608,6 +608,7 @@ do bfd_elf32_bigarm_oabi_vec) tb="$tb elfarm-oabi.lo elf32.lo $elf" ;; bfd_elf32_bigarm_vec) tb="$tb elfarm-nabi.lo elf32.lo $elf" ;; bfd_elf32_bigmips_vec) tb="$tb elf32-mips.lo elfxx-mips.lo elf32.lo $elf ecofflink.lo" ;; + bfd_elf32_cr16c_vec) tb="$tb elf32-cr16c.lo elf32.lo $elf" ;; bfd_elf32_cris_vec) tb="$tb elf32-cris.lo elf32.lo $elf" ;; bfd_elf32_d10v_vec) tb="$tb elf32-d10v.lo elf32.lo $elf" ;; bfd_elf32_d30v_vec) tb="$tb elf32-d30v.lo elf32.lo $elf" ;; diff --git a/bfd/cpu-cr16c.c b/bfd/cpu-cr16c.c new file mode 100644 index 0000000000..0773e08774 --- /dev/null +++ b/bfd/cpu-cr16c.c @@ -0,0 +1,38 @@ +/* BFD support for the CR16C processor. + Copyright 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. */ + +#include "bfd.h" +#include "sysdep.h" +#include "libbfd.h" + +const bfd_arch_info_type bfd_cr16c_arch = + { + 16, /* 16 bits in a word. */ + 32, /* 32 bits in an address. */ + 8, /* 8 bits in a byte. */ + bfd_arch_cr16c, + bfd_mach_cr16c, + "cr16c", + "cr16c", + 1, + TRUE, /* The one and only. */ + bfd_default_compatible, + bfd_default_scan , + 0, + }; diff --git a/bfd/doc/ChangeLog b/bfd/doc/ChangeLog index c2ab8aafec..cc57b2bb7a 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/Makefile.in b/bfd/doc/Makefile.in index 85d64277e3..136b42992a 100644 --- a/bfd/doc/Makefile.in +++ b/bfd/doc/Makefile.in @@ -1,4 +1,4 @@ -# Makefile.in generated automatically by automake 1.4-p6 from Makefile.am +# Makefile.in generated automatically by automake 1.4-p5 from Makefile.am # Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation @@ -257,7 +257,7 @@ DIST_COMMON = ChangeLog Makefile.am Makefile.in DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST) -TAR = tar +TAR = gtar GZIP_ENV = --best all: all-redirect .SUFFIXES: diff --git a/bfd/doc/bfdint.texi b/bfd/doc/bfdint.texi index cd29ae8dca..95c0096e46 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/ecoffswap.h b/bfd/ecoffswap.h index 7ea03943bb..0e77052602 100644 --- a/bfd/ecoffswap.h +++ b/bfd/ecoffswap.h @@ -324,8 +324,6 @@ ecoff_swap_fdr_out (abfd, intern_copy, ext_ptr) #endif } -#ifndef MPW_C - /* Swap in the procedure descriptor record. */ static void @@ -454,78 +452,6 @@ ecoff_swap_pdr_out (abfd, intern_copy, ext_ptr) #endif } -#else /* MPW_C */ -/* Same routines, but with ECOFF_64 code removed, so ^&%$#&! MPW C doesn't - corrupt itself and then freak out. */ -/* Swap in the procedure descriptor record. */ - -static void -ecoff_swap_pdr_in (abfd, ext_copy, intern) - bfd *abfd; - PTR ext_copy; - PDR *intern; -{ - struct pdr_ext ext[1]; - - *ext = *(struct pdr_ext *) ext_copy; - - intern->adr = ECOFF_GET_OFF (abfd, ext->p_adr); - intern->isym = H_GET_32 (abfd, ext->p_isym); - intern->iline = H_GET_32 (abfd, ext->p_iline); - intern->regmask = H_GET_32 (abfd, ext->p_regmask); - intern->regoffset = H_GET_S32 (abfd, ext->p_regoffset); - intern->iopt = H_GET_S32 (abfd, ext->p_iopt); - intern->fregmask = H_GET_32 (abfd, ext->p_fregmask); - intern->fregoffset = H_GET_S32 (abfd, ext->p_fregoffset); - intern->frameoffset = H_GET_S32 (abfd, ext->p_frameoffset); - intern->framereg = H_GET_16 (abfd, ext->p_framereg); - intern->pcreg = H_GET_16 (abfd, ext->p_pcreg); - intern->lnLow = H_GET_32 (abfd, ext->p_lnLow); - intern->lnHigh = H_GET_32 (abfd, ext->p_lnHigh); - intern->cbLineOffset = ECOFF_GET_OFF (abfd, ext->p_cbLineOffset); - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort (); -#endif -} - -/* Swap out the procedure descriptor record. */ - -static void -ecoff_swap_pdr_out (abfd, intern_copy, ext_ptr) - bfd *abfd; - const PDR *intern_copy; - PTR ext_ptr; -{ - struct pdr_ext *ext = (struct pdr_ext *) ext_ptr; - PDR intern[1]; - - /* Make it reasonable to do in-place. */ - *intern = *intern_copy; - - ECOFF_PUT_OFF (abfd, intern->adr, ext->p_adr); - H_PUT_32 (abfd, intern->isym, ext->p_isym); - H_PUT_32 (abfd, intern->iline, ext->p_iline); - H_PUT_32 (abfd, intern->regmask, ext->p_regmask); - H_PUT_32 (abfd, intern->regoffset, ext->p_regoffset); - H_PUT_32 (abfd, intern->iopt, ext->p_iopt); - H_PUT_32 (abfd, intern->fregmask, ext->p_fregmask); - H_PUT_32 (abfd, intern->fregoffset, ext->p_fregoffset); - H_PUT_32 (abfd, intern->frameoffset, ext->p_frameoffset); - H_PUT_16 (abfd, intern->framereg, ext->p_framereg); - H_PUT_16 (abfd, intern->pcreg, ext->p_pcreg); - H_PUT_32 (abfd, intern->lnLow, ext->p_lnLow); - H_PUT_32 (abfd, intern->lnHigh, ext->p_lnHigh); - ECOFF_PUT_OFF (abfd, intern->cbLineOffset, ext->p_cbLineOffset); - -#ifdef TEST - if (memcmp ((char *)ext, (char *)intern, sizeof (*intern)) != 0) - abort (); -#endif -} -#endif /* MPW_C */ - /* Swap in a symbol record. */ static void diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 484a4923e1..110dd696c5 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -492,6 +492,7 @@ struct elf_reloc_cookie size_t locsymcount; size_t extsymoff; struct elf_link_hash_entry **sym_hashes; + int r_sym_shift; bfd_boolean bad_symtab; }; @@ -1308,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 @@ -1492,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 @@ -1555,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 @@ -1599,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 *); @@ -1638,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 *); @@ -1656,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. */ @@ -1711,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 534dd11453..1f79147a88 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 8277bae301..c64d34f4e2 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; } @@ -3186,6 +3186,7 @@ map_sections_to_segments (bfd *abfd) struct elf_segment_map **pm; struct elf_segment_map *m; asection *last_hdr; + bfd_vma last_size; unsigned int phdr_index; bfd_vma maxpagesize; asection **hdrpp; @@ -3265,6 +3266,7 @@ map_sections_to_segments (bfd *abfd) segment when the start of the second section can be placed within a few bytes of the end of the first section. */ last_hdr = NULL; + last_size = 0; phdr_index = 0; maxpagesize = get_elf_backend_data (abfd)->maxpagesize; writable = FALSE; @@ -3313,18 +3315,19 @@ map_sections_to_segments (bfd *abfd) segment. */ new_segment = TRUE; } - else if (BFD_ALIGN (last_hdr->lma + last_hdr->_raw_size, maxpagesize) + else if (BFD_ALIGN (last_hdr->lma + last_size, maxpagesize) < BFD_ALIGN (hdr->lma, maxpagesize)) { /* If putting this section in this segment would force us to skip a page in the segment, then we need a new segment. */ new_segment = TRUE; } - else if ((last_hdr->flags & SEC_LOAD) == 0 - && (hdr->flags & SEC_LOAD) != 0) + else if ((last_hdr->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) == 0 + && (hdr->flags & (SEC_LOAD | SEC_THREAD_LOCAL)) != 0) { /* We don't want to put a loadable section after a - nonloadable section in the same segment. */ + nonloadable section in the same segment. + Consider .tbss sections as loadable for this purpose. */ new_segment = TRUE; } else if ((abfd->flags & D_PAGED) == 0) @@ -3336,7 +3339,7 @@ map_sections_to_segments (bfd *abfd) } else if (! writable && (hdr->flags & SEC_READONLY) == 0 - && (((last_hdr->lma + last_hdr->_raw_size - 1) + && (((last_hdr->lma + last_size - 1) & ~(maxpagesize - 1)) != (hdr->lma & ~(maxpagesize - 1)))) { @@ -3359,9 +3362,12 @@ map_sections_to_segments (bfd *abfd) { if ((hdr->flags & SEC_READONLY) == 0) writable = TRUE; - /* Ignore .tbss section for segment layout purposes. */ + last_hdr = hdr; + /* .tbss sections effectively have zero size. */ if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) != SEC_THREAD_LOCAL) - last_hdr = hdr; + last_size = hdr->_raw_size; + else + last_size = 0; continue; } @@ -3381,6 +3387,11 @@ map_sections_to_segments (bfd *abfd) writable = FALSE; last_hdr = hdr; + /* .tbss sections effectively have zero size. */ + if ((hdr->flags & (SEC_THREAD_LOCAL | SEC_LOAD)) != SEC_THREAD_LOCAL) + last_size = hdr->_raw_size; + else + last_size = 0; phdr_index = i; phdr_in_segment = FALSE; } diff --git a/bfd/elf32-arm.h b/bfd/elf32-arm.h index 89540f03d2..d3f8d1f0ea 100644 --- a/bfd/elf32-arm.h +++ b/bfd/elf32-arm.h @@ -106,7 +106,7 @@ bfd_boolean bfd_elf32_arm_allocate_interworking_sections bfd_boolean bfd_elf32_arm_get_bfd_for_interworking PARAMS ((bfd *, struct bfd_link_info *)); bfd_boolean bfd_elf32_arm_process_before_allocation - PARAMS ((bfd *, struct bfd_link_info *, int)); + PARAMS ((bfd *, struct bfd_link_info *, int, int)); #endif @@ -190,6 +190,26 @@ static const bfd_vma elf32_arm_plt_entry [PLT_ENTRY_SIZE / 4] = #endif +/* Used to build a map of a section. This is required for mixed-endian + code/data. */ + +typedef struct elf32_elf_section_map +{ + bfd_vma vma; + char type; +} +elf32_arm_section_map; + +struct _arm_elf_section_data +{ + struct bfd_elf_section_data elf; + int mapcount; + elf32_arm_section_map *map; +}; + +#define elf32_arm_section_data(sec) \ + ((struct _arm_elf_section_data *) elf_section_data (sec)) + /* The ARM linker needs to keep track of the number of relocs that it decides to copy in check_relocs for each symbol. This is so that it can discard PC relative relocs if it doesn't need them when @@ -247,6 +267,9 @@ struct elf32_arm_link_hash_table length should be applied by the linker. */ int no_pipeline_knowledge; + /* Nonzero to output a BE8 image. */ + int byteswap_code; + /* Short-cuts to get to dynamic linker sections. */ asection *sgot; asection *sgotplt; @@ -430,6 +453,7 @@ elf32_arm_link_hash_table_create (abfd) ret->arm_glue_size = 0; ret->bfd_of_glue_owner = NULL; ret->no_pipeline_knowledge = 0; + ret->byteswap_code = 0; ret->sym_sec.abfd = NULL; return &ret->root.root; @@ -808,10 +832,13 @@ bfd_elf32_arm_get_bfd_for_interworking (abfd, info) } bfd_boolean -bfd_elf32_arm_process_before_allocation (abfd, link_info, no_pipeline_knowledge) +bfd_elf32_arm_process_before_allocation (abfd, link_info, + no_pipeline_knowledge, + byteswap_code) bfd *abfd; struct bfd_link_info *link_info; int no_pipeline_knowledge; + int byteswap_code; { Elf_Internal_Shdr *symtab_hdr; Elf_Internal_Rela *internal_relocs = NULL; @@ -834,6 +861,14 @@ bfd_elf32_arm_process_before_allocation (abfd, link_info, no_pipeline_knowledge) BFD_ASSERT (globals->bfd_of_glue_owner != NULL); globals->no_pipeline_knowledge = no_pipeline_knowledge; + if (byteswap_code && !bfd_big_endian (abfd)) + { + _bfd_error_handler ( + _("%s: BE8 images only valid in big-endian mode."), + bfd_archive_filename (abfd)); + return FALSE; + } + globals->byteswap_code = byteswap_code; /* Rummage around all the relocs and map the glue vectors. */ sec = abfd->sections; @@ -1209,18 +1244,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 @@ -1744,6 +1767,31 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd, return bfd_reloc_ok; } + case R_ARM_ALU_PCREL7_0: + case R_ARM_ALU_PCREL15_8: + case R_ARM_ALU_PCREL23_15: + { + bfd_vma insn; + bfd_vma relocation; + + insn = bfd_get_32 (input_bfd, hit_data); +#if USE_REL + /* Extract the addend. */ + addend = (insn & 0xff) << ((insn & 0xf00) >> 7); + signed_addend = addend; +#endif + relocation = value + signed_addend; + + relocation -= (input_section->output_section->vma + + input_section->output_offset + + rel->r_offset); + insn = (insn & ~0xfff) + | ((howto->bitpos << 7) & 0xf00) + | ((relocation >> howto->bitpos) & 0xff); + bfd_put_32 (input_bfd, value, hit_data); + } + return bfd_reloc_ok; + case R_ARM_GNU_VTINHERIT: case R_ARM_GNU_VTENTRY: return bfd_reloc_ok; @@ -3080,14 +3128,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 +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; } @@ -3403,7 +3451,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 +3504,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; } @@ -4036,11 +4084,19 @@ elf32_arm_post_process_headers (abfd, link_info) struct bfd_link_info * link_info ATTRIBUTE_UNUSED; { Elf_Internal_Ehdr * i_ehdrp; /* ELF file header, internal form. */ + struct elf32_arm_link_hash_table *globals; i_ehdrp = elf_elfheader (abfd); i_ehdrp->e_ident[EI_OSABI] = ARM_ELF_OS_ABI_VERSION; i_ehdrp->e_ident[EI_ABIVERSION] = ARM_ELF_ABI_VERSION; + + if (link_info) + { + globals = elf32_arm_hash_table (link_info); + if (globals->byteswap_code) + i_ehdrp->e_flags |= EF_ARM_BE8; + } } static enum elf_reloc_type_class @@ -4076,7 +4132,7 @@ elf32_arm_section_flags (flags, hdr) return TRUE; } -void +static void elf32_arm_final_write_processing (abfd, linker) bfd *abfd; bfd_boolean linker ATTRIBUTE_UNUSED; @@ -4084,6 +4140,148 @@ elf32_arm_final_write_processing (abfd, linker) bfd_arm_update_notes (abfd, ARM_NOTE_SECTION); } + +/* Called for each symbol. Builds a section map based on mapping symbols. + Does not alter any of the symbols. */ + +static bfd_boolean +elf32_arm_output_symbol_hook (struct bfd_link_info *info, + const char *name, + Elf_Internal_Sym *elfsym, + asection *input_sec, + struct elf_link_hash_entry *h ATTRIBUTE_UNUSED) +{ + int mapcount; + elf32_arm_section_map *map; + struct elf32_arm_link_hash_table *globals; + + /* Only do this on final link. */ + if (info->relocatable) + return TRUE; + + /* Only build a map if we need to byteswap code. */ + globals = elf32_arm_hash_table (info); + if (!globals->byteswap_code) + return TRUE; + + /* We only want mapping symbols. */ + if (name == NULL + || name[0] != '$' + || (name[1] != 'a' + && name[1] != 't' + && name[1] != 'd')) + return TRUE; + + mapcount = ++(elf32_arm_section_data (input_sec)->mapcount); + map = elf32_arm_section_data (input_sec)->map; + /* TODO: This may be inefficient, but we probably don't usually have many + mapping symbols per section. */ + map = bfd_realloc (map, mapcount * sizeof (elf32_arm_section_map)); + elf32_arm_section_data (input_sec)->map = map; + + map[mapcount - 1].vma = elfsym->st_value; + map[mapcount - 1].type = name[1]; + return TRUE; +} + + +/* Allocate target specific section data. */ + +static bfd_boolean +elf32_arm_new_section_hook (bfd *abfd, asection *sec) +{ + struct _arm_elf_section_data *sdata; + bfd_size_type amt = sizeof (*sdata); + + sdata = bfd_zalloc (abfd, amt); + if (sdata == NULL) + return FALSE; + sec->used_by_bfd = sdata; + + return _bfd_elf_new_section_hook (abfd, sec); +} + + +/* Used to order a list of mapping symbols by address. */ + +static int +elf32_arm_compare_mapping (const void * a, const void * b) +{ + return ((const elf32_arm_section_map *) a)->vma + > ((const elf32_arm_section_map *) b)->vma; +} + + +/* Do code byteswapping. Return FALSE afterwards so that the section is + written out as normal. */ + +static bfd_boolean +elf32_arm_write_section (bfd *output_bfd ATTRIBUTE_UNUSED, asection *sec, + bfd_byte *contents) +{ + int mapcount; + elf32_arm_section_map *map; + bfd_vma ptr; + bfd_vma end; + bfd_vma offset; + bfd_byte tmp; + int i; + + mapcount = elf32_arm_section_data (sec)->mapcount; + map = elf32_arm_section_data (sec)->map; + + if (mapcount == 0) + return FALSE; + + qsort (map, mapcount, sizeof (elf32_arm_section_map), + elf32_arm_compare_mapping); + + offset = sec->output_section->vma + sec->output_offset; + ptr = map[0].vma - offset; + for (i = 0; i < mapcount; i++) + { + if (i == mapcount - 1) + end = bfd_section_size (output_bfd, sec); + else + end = map[i + 1].vma - offset; + + switch (map[i].type) + { + case 'a': + /* Byte swap code words. */ + while (ptr + 3 < end) + { + tmp = contents[ptr]; + contents[ptr] = contents[ptr + 3]; + contents[ptr + 3] = tmp; + tmp = contents[ptr + 1]; + contents[ptr + 1] = contents[ptr + 2]; + contents[ptr + 2] = tmp; + ptr += 4; + } + break; + + case 't': + /* Byte swap code halfwords. */ + while (ptr + 1 < end) + { + tmp = contents[ptr]; + contents[ptr] = contents[ptr + 1]; + contents[ptr + 1] = tmp; + ptr += 2; + } + break; + + case 'd': + /* Leave data alone. */ + break; + } + ptr = end; + } + free (map); + return FALSE; +} + #define ELF_ARCH bfd_arch_arm #define ELF_MACHINE_CODE EM_ARM #ifdef __QNXTARGET__ @@ -4099,16 +4297,19 @@ elf32_arm_final_write_processing (abfd, linker) #define bfd_elf32_bfd_link_hash_table_create elf32_arm_link_hash_table_create #define bfd_elf32_bfd_reloc_type_lookup elf32_arm_reloc_type_lookup #define bfd_elf32_find_nearest_line elf32_arm_find_nearest_line +#define bfd_elf32_new_section_hook elf32_arm_new_section_hook #define elf_backend_get_symbol_type elf32_arm_get_symbol_type #define elf_backend_gc_mark_hook elf32_arm_gc_mark_hook #define elf_backend_gc_sweep_hook elf32_arm_gc_sweep_hook #define elf_backend_check_relocs elf32_arm_check_relocs #define elf_backend_relocate_section elf32_arm_relocate_section +#define elf_backend_write_section elf32_arm_write_section #define elf_backend_adjust_dynamic_symbol elf32_arm_adjust_dynamic_symbol #define elf_backend_create_dynamic_sections elf32_arm_create_dynamic_sections #define elf_backend_finish_dynamic_symbol elf32_arm_finish_dynamic_symbol #define elf_backend_finish_dynamic_sections elf32_arm_finish_dynamic_sections +#define elf_backend_link_output_symbol_hook elf32_arm_output_symbol_hook #define elf_backend_size_dynamic_sections elf32_arm_size_dynamic_sections #define elf_backend_post_process_headers elf32_arm_post_process_headers #define elf_backend_reloc_type_class elf32_arm_reloc_type_class diff --git a/bfd/elf32-cr16c.c b/bfd/elf32-cr16c.c new file mode 100644 index 0000000000..3e2e275d60 --- /dev/null +++ b/bfd/elf32-cr16c.c @@ -0,0 +1,1015 @@ +/* BFD back-end for National Semiconductor's CR16C ELF + Copyright 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. */ + +#include "bfd.h" +#include "sysdep.h" +#include "libbfd.h" +#include "bfdlink.h" +#include "elf/cr16c.h" +#include "elf-bfd.h" + + +#define USE_REL 1 /* CR16C uses REL relocations instead of RELA. */ + +/* The following definition is based on EMPTY_HOWTO macro, + but also initiates the "name" field in HOWTO struct. */ +#define ONLY_NAME_HOWTO(C) \ + HOWTO ((C), 0, 0, 0, FALSE, 0, complain_overflow_dont, NULL, \ + STRINGX(C), FALSE, 0, 0, FALSE) + +/* reloc_map_index array maps CRASM relocation type into a BFD + relocation enum. The array's indices are synchronized with + RINDEX_16C_* indices, created in include/elf/cr16c.h. + The array is used in: + 1. elf32-cr16c.c : elf_cr16c_reloc_type_lookup(). + 2. asreloc.c : find_reloc_type(). */ + +RELOC_MAP reloc_map_index[RINDEX_16C_MAX] = +{ + {R_16C_NUM08, BFD_RELOC_16C_NUM08}, + {R_16C_NUM08_C, BFD_RELOC_16C_NUM08_C}, + {R_16C_NUM16, BFD_RELOC_16C_NUM16}, + {R_16C_NUM16_C, BFD_RELOC_16C_NUM16_C}, + {R_16C_NUM32, BFD_RELOC_16C_NUM32}, + {R_16C_NUM32_C, BFD_RELOC_16C_NUM32_C}, + {R_16C_DISP04, BFD_RELOC_16C_DISP04}, + {R_16C_DISP04_C, BFD_RELOC_16C_DISP04_C}, + {R_16C_DISP08, BFD_RELOC_16C_DISP08}, + {R_16C_DISP08_C, BFD_RELOC_16C_DISP08_C}, + {R_16C_DISP16, BFD_RELOC_16C_DISP16}, + {R_16C_DISP16_C, BFD_RELOC_16C_DISP16_C}, + {R_16C_DISP24, BFD_RELOC_16C_DISP24}, + {R_16C_DISP24_C, BFD_RELOC_16C_DISP24_C}, + {R_16C_DISP24a, BFD_RELOC_16C_DISP24a}, + {R_16C_DISP24a_C, BFD_RELOC_16C_DISP24a_C}, + {R_16C_REG04, BFD_RELOC_16C_REG04}, + {R_16C_REG04_C, BFD_RELOC_16C_REG04_C}, + {R_16C_REG04a, BFD_RELOC_16C_REG04a}, + {R_16C_REG04a_C, BFD_RELOC_16C_REG04a_C}, + {R_16C_REG14, BFD_RELOC_16C_REG14}, + {R_16C_REG14_C, BFD_RELOC_16C_REG14_C}, + {R_16C_REG16, BFD_RELOC_16C_REG16}, + {R_16C_REG16_C, BFD_RELOC_16C_REG16_C}, + {R_16C_REG20, BFD_RELOC_16C_REG20}, + {R_16C_REG20_C, BFD_RELOC_16C_REG20_C}, + {R_16C_ABS20, BFD_RELOC_16C_ABS20}, + {R_16C_ABS20_C, BFD_RELOC_16C_ABS20_C}, + {R_16C_ABS24, BFD_RELOC_16C_ABS24}, + {R_16C_ABS24_C, BFD_RELOC_16C_ABS24_C}, + {R_16C_IMM04, BFD_RELOC_16C_IMM04}, + {R_16C_IMM04_C, BFD_RELOC_16C_IMM04_C}, + {R_16C_IMM16, BFD_RELOC_16C_IMM16}, + {R_16C_IMM16_C, BFD_RELOC_16C_IMM16_C}, + {R_16C_IMM20, BFD_RELOC_16C_IMM20}, + {R_16C_IMM20_C, BFD_RELOC_16C_IMM20_C}, + {R_16C_IMM24, BFD_RELOC_16C_IMM24}, + {R_16C_IMM24_C, BFD_RELOC_16C_IMM24_C}, + {R_16C_IMM32, BFD_RELOC_16C_IMM32}, + {R_16C_IMM32_C, BFD_RELOC_16C_IMM32_C} +}; + +static reloc_howto_type elf_howto_table[] = +{ + /* 00 */ ONLY_NAME_HOWTO (RINDEX_16C_NUM08), + /* 01 */ ONLY_NAME_HOWTO (RINDEX_16C_NUM08_C), + /* 02 */ ONLY_NAME_HOWTO (RINDEX_16C_NUM16), + /* 03 */ ONLY_NAME_HOWTO (RINDEX_16C_NUM16_C), + /* 04 */ ONLY_NAME_HOWTO (RINDEX_16C_NUM32), + /* 05 */ ONLY_NAME_HOWTO (RINDEX_16C_NUM32_C), + /* 06 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP04), + /* 07 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP04_C), + /* 08 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP08), + /* 09 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP08_C), + /* 10 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP16), + /* 11 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP16_C), + /* 12 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP24), + /* 13 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP24_C), + /* 14 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP24a), + /* 15 */ ONLY_NAME_HOWTO (RINDEX_16C_DISP24a_C), + /* 16 */ ONLY_NAME_HOWTO (RINDEX_16C_REG04), + /* 17 */ ONLY_NAME_HOWTO (RINDEX_16C_REG04_C), + /* 18 */ ONLY_NAME_HOWTO (RINDEX_16C_REG04a), + /* 19 */ ONLY_NAME_HOWTO (RINDEX_16C_REG04a_C), + /* 20 */ ONLY_NAME_HOWTO (RINDEX_16C_REG14), + /* 21 */ ONLY_NAME_HOWTO (RINDEX_16C_REG14_C), + /* 22 */ ONLY_NAME_HOWTO (RINDEX_16C_REG16), + /* 23 */ ONLY_NAME_HOWTO (RINDEX_16C_REG16_C), + /* 24 */ ONLY_NAME_HOWTO (RINDEX_16C_REG20), + /* 25 */ ONLY_NAME_HOWTO (RINDEX_16C_REG20_C), + /* 26 */ ONLY_NAME_HOWTO (RINDEX_16C_ABS20), + /* 27 */ ONLY_NAME_HOWTO (RINDEX_16C_ABS20_C), + /* 28 */ ONLY_NAME_HOWTO (RINDEX_16C_ABS24), + /* 29 */ ONLY_NAME_HOWTO (RINDEX_16C_ABS24_C), + /* 30 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM04), + /* 31 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM04_C), + /* 32 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM16), + /* 33 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM16_C), + /* 34 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM20), + /* 35 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM20_C), + /* 36 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM24), + /* 37 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM24_C), + /* 38 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM32), + /* 39 */ ONLY_NAME_HOWTO (RINDEX_16C_IMM32_C) +}; + + +/* Code to turn a code_type into a howto ptr, uses the above howto table. */ + +static reloc_howto_type * +elf_cr16c_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED, + bfd_reloc_code_real_type code) +{ + unsigned int i; + + for (i = 0; i < RINDEX_16C_MAX; i++) + { + if (code == reloc_map_index[i].bfd_reloc_enum) + { + /* printf ("CR16C Relocation Type is - %x\n", code); */ + return & elf_howto_table[i]; + } + } + + /* printf ("This relocation Type is not supported - %x\n", code); */ + return 0; +} + +static void +elf_cr16c_info_to_howto (bfd *abfd ATTRIBUTE_UNUSED, + arelent *cache_ptr ATTRIBUTE_UNUSED, + Elf_Internal_Rela *dst ATTRIBUTE_UNUSED) +{ + abort (); +} + +static void +elf_cr16c_info_to_howto_rel (bfd *abfd ATTRIBUTE_UNUSED, + arelent *cache_ptr, + Elf_Internal_Rela *dst) +{ + unsigned int r_type = ELF32_R_TYPE (dst->r_info); + + BFD_ASSERT (r_type < (unsigned int) RINDEX_16C_MAX); + cache_ptr->howto = &elf_howto_table[r_type]; +} + +/* Perform a relocation as part of a final link. */ + +static bfd_reloc_status_type +cr16c_elf_final_link_relocate (reloc_howto_type *howto, + bfd *abfd, + bfd *output_bfd ATTRIBUTE_UNUSED, + asection *input_section, + bfd_byte *data, + bfd_vma octets, + bfd_vma Rvalue, + bfd_vma addend ATTRIBUTE_UNUSED, + struct bfd_link_info *info ATTRIBUTE_UNUSED, + asection *sym_sec ATTRIBUTE_UNUSED, + int is_local ATTRIBUTE_UNUSED) +{ + long value; + short sword; /* Extracted from the hole and put back. */ + unsigned long format, addr_type, code_factor; + unsigned short size; + unsigned short r_type; + asymbol *symbol = NULL; + + unsigned long disp20_opcod; + char neg = 0; + char neg2pos = 0; + + long left_val = 0; + long plus_factor = 0; /* To be added to the hole. */ + +#define MIN_BYTE ((int) 0xFFFFFF80) +#define MIN_WORD ((int) 0xFFFF8000) +#define MAX_UWORD ((unsigned) 0x0000FFFF) +#define MAX_UBYTE ((unsigned) 0x000000FF) + + r_type = reloc_map_index[howto->type].cr_reloc_type; + format = r_type & R_FORMAT; + size = r_type & R_SIZESP; + addr_type = r_type & R_ADDRTYPE; + code_factor = ((addr_type == R_CODE_ADDR) ? 1 : 0); + + if (sym_sec) + symbol = sym_sec->symbol; + + switch (format) + { + case R_NUMBER: + switch (size) + { + case R_S_16C_08: /* One byte. */ + value = bfd_get_8 (abfd, (char *) data + octets); + break; + case R_S_16C_16: /* Two bytes. */ + sword = bfd_get_16 (abfd, (bfd_byte *) data + octets); + value = sword; + break; + case R_S_16C_32: /* Four bytes. */ + value = bfd_get_32 (abfd, (bfd_byte *) data + octets); + break; + default: + return bfd_reloc_notsupported; + } + break; + + case R_16C_DISPL: + switch (size) + { + case R_S_16C_04: /* word1(4-7). */ + value = bfd_get_8 (abfd, (char *) data + octets); + left_val = value & 0xF; + value = (value & 0xF0) >> 4; + value++; + value <<= 1; + break; + case R_S_16C_08: /* word1(0-3,8-11). */ + sword = bfd_get_16 (abfd, (char *) data + octets); + value = sword & 0x000F; + value |= ((sword & 0x0F00) >> 4); + left_val = sword & 0xF0F0; + value <<= 1; + if (value & 0x100) + value |= 0xFFFFFF00; + break; + case R_S_16C_16: /* word2. */ + sword = bfd_get_16 (abfd, (bfd_byte *) data + octets); + value = sword; + value = ((value & 0xFFFE) >> 1) | ((value & 0x1) << 15); + value <<= 1; + if (value & 0x10000) + value |= 0xFFFF0000; + break; + case R_S_16C_24_a: /* word1(0-7),word2. */ + value = bfd_get_32 (abfd, (bfd_byte *) data + octets); + left_val = value & 0x0000FF00; + value = ((value & 0xFFFE0000) >> 17) | + ((value & 0x00010000) << 7) | ((value & 0x000000FF) << 15); + value <<= 1; + if (value & 0x1000000) + value |= 0xFE000000; + break; + case R_S_16C_24: /* word2(0-3,8-11),word3. */ + value = bfd_get_32 (abfd, (bfd_byte *) data + octets); + left_val = value & 0x0000F0F0; + value = ((value >> 16) & 0x0000FFFF) | + ((value & 0x00000F00) << 8) | ((value & 0x0000000F) << 20); + + value = ((value & 0x00FFFFFE) >> 1) | ((value & 0x00000001) << 23); + + value <<= 1; + if (value & 0x1000000) + value |= 0xFE000000; + break; + default: + return bfd_reloc_notsupported; + } + break; + + case R_16C_REGREL: + switch (size) + { + case R_S_16C_04: /* word1(12-15) not scaled. */ + value = bfd_get_8 (abfd, (char *) data + octets); + left_val = value & 0xF0; + value = value & 0xF; + break; + case R_S_16C_04_a: /* word1(12-15) scaled by 2. */ + value = bfd_get_8 (abfd, (char *) data + octets); + left_val = value & 0xF0; + value = value & 0xF; + value <<= 1; + break; + case R_S_16C_14: /* word1(4-5),word2(0-3,8-15). */ + value = bfd_get_32 (abfd, (bfd_byte *) data + octets); + left_val = value & 0x00F0FFCF; + value = ((value & 0xc0000000) >> 24) | + ((value & 0x3F000000) >> 16) | + ((value & 0x000F0000) >> 16) | (value & 0x00000030); + break; + case R_S_16C_16: /* word2. */ + sword = bfd_get_16 (abfd, (bfd_byte *) data + octets); + value = sword; + break; + case R_S_16C_20: /* word2(8-11),word3. */ + value = bfd_get_32 (abfd, (bfd_byte *) data + octets); + left_val = value & 0xF0; + value = (value & 0xF) << 16; + sword = bfd_get_16 (abfd, (bfd_byte *) data + octets + 1); + value = value | (unsigned short) sword; + disp20_opcod = bfd_get_32 (abfd, (bfd_byte *) data + octets - 3); + disp20_opcod |= 0x0FFF0000; + if ((disp20_opcod == 0x4FFF0018) || /* loadb -disp20(reg) */ + (disp20_opcod == 0x5FFF0018) || /* loadb -disp20(rp) */ + (disp20_opcod == 0x8FFF0018) || /* loadd -disp20(reg) */ + (disp20_opcod == 0x9FFF0018) || /* loadd -disp20(rp) */ + (disp20_opcod == 0xCFFF0018) || /* loadw -disp20(reg) */ + (disp20_opcod == 0xDFFF0018) || /* loadw -disp20(rp) */ + (disp20_opcod == 0x4FFF0019) || /* storb -disp20(reg) */ + (disp20_opcod == 0x5FFF0019) || /* storb -disp20(rp) */ + (disp20_opcod == 0x8FFF0019) || /* stord -disp20(reg) */ + (disp20_opcod == 0x9FFF0019) || /* stord -disp20(rp) */ + (disp20_opcod == 0xCFFF0019) || /* storw -disp20(reg) */ + (disp20_opcod == 0xDFFF0019)) + { /* storw -disp20(rp). */ + neg = 1; + value |= 0xFFF00000; + } + + break; + default: + return bfd_reloc_notsupported; + } + break; + + case R_16C_ABS: + switch (size) + { + case R_S_16C_20: /* word1(0-3),word2. */ + value = bfd_get_32 (abfd, (bfd_byte *) data + octets); + left_val = value & 0x0000FFF0; + value = ((value & 0xFFFF0000) >> 16) | + ((value & 0x0000000F) << 16); + break; + case R_S_16C_24: /* word2(0-3,8-11),word3. */ + value = bfd_get_32 (abfd, (bfd_byte *) data + octets); + left_val = value & 0x0000F0F0; + value = ((value & 0xFFFF0000) >> 16) | + ((value & 0x00000F00) << 8) | ((value & 0x0000000F) << 20); + break; + default: + return bfd_reloc_notsupported; + } + break; + + case R_16C_IMMED: + switch (size) + { + case R_S_16C_04: /* word1/2(4-7). */ + value = bfd_get_8 (abfd, (char *) data + octets); + left_val = value & 0xF; + value = (value & 0xF0) >> 4; + break; + case R_S_16C_16: /* word2. */ + sword = bfd_get_16 (abfd, (bfd_byte *) data + octets); + value = sword; + break; + case R_S_16C_20: /* word1(0-3),word2. */ + value = bfd_get_32 (abfd, (bfd_byte *) data + octets); + left_val = value & 0x0000FFF0; + value = ((value & 0xFFFF0000) >> 16) | + ((value & 0x0000000F) << 16); + break; + case R_S_16C_32: /* word2, word3. */ + value = bfd_get_32 (abfd, (bfd_byte *) data + octets); + value = ((value & 0x0000FFFF) << 16) | + ((value & 0xFFFF0000) >> 16); + break; + default: + return bfd_reloc_notsupported; + } + break; + default: + return bfd_reloc_notsupported; + } + + switch ((r_type & R_RELTO) >> 4) + { + + case 0: /* R_ABS. */ + plus_factor = Rvalue; + break; + case 1: /* R_PCREL. */ + plus_factor = Rvalue - + (input_section->output_section->vma + input_section->output_offset); + break; + default: + return bfd_reloc_notsupported; + } + + if (neg) + { + if (plus_factor >= -value) + neg2pos = 1; + /* We need to change load/stor with negative + displ opcode to positive disp opcode (CR16C). */ + } + + value = value + (plus_factor >> code_factor); + + switch (format) + { + case R_NUMBER: + switch (size) + { + case R_S_16C_08: /* One byte. */ + if (value > (int) MAX_UBYTE || value < MIN_BYTE) + return bfd_reloc_overflow; + value &= 0xFF; + bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets); + return bfd_reloc_ok; + break; + case R_S_16C_16: /* Two bytes. */ + if (value > (int) MAX_UWORD || value < MIN_WORD) + return bfd_reloc_overflow; + value &= 0xFFFF; + sword = value; + bfd_put_16 (abfd, (bfd_vma) sword, + (unsigned char *) data + octets); + return bfd_reloc_ok; + break; + case R_S_16C_32: /* Four bytes. */ + value &= 0xFFFFFFFF; + bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets); + return bfd_reloc_ok; + break; + default: + return bfd_reloc_notsupported; + } + break; + + case R_16C_DISPL: + switch (size) + { + case R_S_16C_04: /* word1(4-7). */ + if ((value - 32) > 32 || value < 2) + return bfd_reloc_overflow; + value >>= 1; + value--; + value &= 0xF; + value <<= 4; + value |= left_val; + bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets); + return bfd_reloc_ok; + break; + case R_S_16C_08: /* word1(0-3,8-11). */ + if (value > 255 || value < -256 || value == 0x80) + return bfd_reloc_overflow; + value &= 0x1FF; + value >>= 1; + sword = value & 0x000F; + sword |= (value & 0x00F0) << 4; + sword |= left_val; + bfd_put_16 (abfd, (bfd_vma) sword, + (unsigned char *) data + octets); + return bfd_reloc_ok; + break; + case R_S_16C_16: /* word2. */ + if (value > 65535 || value < -65536) + return bfd_reloc_overflow; + value >>= 1; + value &= 0xFFFF; + value = ((value & 0x8000) >> 15) | ((value & 0x7FFF) << 1); + sword = value; + bfd_put_16 (abfd, (bfd_vma) sword, + (unsigned char *) data + octets); + return bfd_reloc_ok; + break; + case R_S_16C_24_a: /* word1(0-7),word2. */ + if (value > 16777215 || value < -16777216) + return bfd_reloc_overflow; + value &= 0x1FFFFFF; + value >>= 1; + value = ((value & 0x00007FFF) << 17) | + ((value & 0x00800000) >> 7) | ((value & 0x007F8000) >> 15); + value |= left_val; + bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets); + return bfd_reloc_ok; + break; + case R_S_16C_24: /* word2(0-3,8-11),word3. */ + if (value > 16777215 || value < -16777216) + return bfd_reloc_overflow; + value &= 0x1FFFFFF; + value >>= 1; + + value = ((value & 0x007FFFFF) << 1) | ((value & 0x00800000) >> 23); + + value = ((value & 0x0000FFFF) << 16) | + ((value & 0x000F0000) >> 8) | ((value & 0x00F00000) >> 20); + value |= left_val; + bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets); + return bfd_reloc_ok; + break; + default: + return bfd_reloc_notsupported; + } + break; + + case R_16C_REGREL: + switch (size) + { + case R_S_16C_04: /* word1(12-15) not scaled. */ + if (value > 13 || value < 0) + return bfd_reloc_overflow; + value &= 0xF; + value |= left_val; + bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets); + return bfd_reloc_ok; + break; + case R_S_16C_04_a: /* word1(12-15) not scaled. */ + if (value > 26 || value < 0) + return bfd_reloc_overflow; + value &= 0x1F; + value >>= 1; + value |= left_val; + bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets); + return bfd_reloc_ok; + break; + case R_S_16C_14: /* word1(4-5),word2(0-3,8-15). */ + if (value < 0 || value > 16383) + return bfd_reloc_overflow; + value &= 0x3FFF; + value = ((value & 0x000000c0) << 24) | + ((value & 0x00003F00) << 16) | + ((value & 0x0000000F) << 16) | (value & 0x00000030); + value |= left_val; + bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets); + return bfd_reloc_ok; + break; + case R_S_16C_16: /* word2. */ + if (value > 65535 || value < 0) + return bfd_reloc_overflow; + value &= 0xFFFF; + sword = value; + bfd_put_16 (abfd, (bfd_vma) sword, + (unsigned char *) data + octets); + return bfd_reloc_ok; + break; + case R_S_16C_20: /* word2(8-11),word3. */ + /* if (value > 1048575 || value < 0) RELOC_ERROR(1); */ + value &= 0xFFFFF; + sword = value & 0x0000FFFF; + value = (value & 0x000F0000) >> 16; + value |= left_val; + bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets); + bfd_put_16 (abfd, (bfd_vma) sword, + (unsigned char *) data + octets + 1); + if (neg2pos) + { + /* Change load/stor negative displ opcode + to load/stor positive displ opcode. */ + value = bfd_get_8 (abfd, (char *) data + octets - 3); + value &= 0xF7; + value |= 0x2; + bfd_put_8 (abfd, (bfd_vma) value, + (unsigned char *) data + octets - 3); + } + return bfd_reloc_ok; + break; + default: + return bfd_reloc_notsupported; + } + break; + + case R_16C_ABS: + switch (size) + { + case R_S_16C_20: /* word1(0-3),word2. */ + if (value > 1048575 || value < 0) + return bfd_reloc_overflow; + value &= 0xFFFFF; + value = ((value & 0x0000FFFF) << 16) | + ((value & 0x000F0000) >> 16); + value |= left_val; + bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets); + return bfd_reloc_ok; + break; + case R_S_16C_24: /* word2(0-3,8-11),word3. */ + /* if (value > 16777215 || value < 0) RELOC_ERROR(1); */ + value &= 0xFFFFFF; + value = ((value & 0x0000FFFF) << 16) | + ((value & 0x000F0000) >> 8) | ((value & 0x00F00000) >> 20); + value |= left_val; + bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets); + return bfd_reloc_ok; + break; + default: + return bfd_reloc_notsupported; + } + break; + + case R_16C_IMMED: + switch (size) + { + case R_S_16C_04: /* word1/2(4-7). */ + if (value > 15 || value < -1) + return bfd_reloc_overflow; + value &= 0xF; + value <<= 4; + value |= left_val; + bfd_put_8 (abfd, (bfd_vma) value, (unsigned char *) data + octets); + return bfd_reloc_ok; + break; + case R_S_16C_16: /* word2. */ + if (value > 32767 || value < -32768) + return bfd_reloc_overflow; + value &= 0xFFFF; + sword = value; + bfd_put_16 (abfd, (bfd_vma) sword, + (unsigned char *) data + octets); + return bfd_reloc_ok; + break; + case R_S_16C_20: /* word1(0-3),word2. */ + if (value > 1048575 || value < 0) + return bfd_reloc_overflow; + value &= 0xFFFFF; + value = ((value & 0x0000FFFF) << 16) | + ((value & 0x000F0000) >> 16); + value |= left_val; + bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets); + return bfd_reloc_ok; + break; + case R_S_16C_32: /* word2, word3. */ + value &= 0xFFFFFFFF; + value = ((value & 0x0000FFFF) << 16) | + ((value & 0xFFFF0000) >> 16); + bfd_put_32 (abfd, (bfd_vma) value, (bfd_byte *) data + octets); + return bfd_reloc_ok; + break; + default: + return bfd_reloc_notsupported; + } + break; + default: + return bfd_reloc_notsupported; + } +} + +/* Relocate a CR16C ELF section. */ + +static bfd_boolean +elf32_cr16c_relocate_section (bfd *output_bfd, + struct bfd_link_info *info, + bfd *input_bfd, + asection *input_section, + bfd_byte *contents, + Elf_Internal_Rela *relocs, + Elf_Internal_Sym *local_syms, + asection **local_sections) +{ + Elf_Internal_Shdr *symtab_hdr; + struct elf_link_hash_entry **sym_hashes; + Elf_Internal_Rela *rel, *relend; + + symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; + sym_hashes = elf_sym_hashes (input_bfd); + + rel = relocs; + relend = relocs + input_section->reloc_count; + for (; rel < relend; rel++) + { + int r_type; + reloc_howto_type *howto; + unsigned long r_symndx; + Elf_Internal_Sym *sym; + asection *sec; + struct elf_link_hash_entry *h; + bfd_vma relocation; + bfd_reloc_status_type r; + + r_symndx = ELF32_R_SYM (rel->r_info); + r_type = ELF32_R_TYPE (rel->r_info); + howto = elf_howto_table + r_type; + + if (info->relocatable) + { + /* This is a relocatable link. We don't have to change + anything, unless the reloc is against a section symbol, + in which case we have to adjust according to where the + section symbol winds up in the output section. */ + if (r_symndx < symtab_hdr->sh_info) + { + sym = local_syms + r_symndx; + if (ELF_ST_TYPE (sym->st_info) == STT_SECTION) + { + sec = local_sections[r_symndx]; + rel->r_addend += sec->output_offset + sym->st_value; + } + } + + continue; + } + + /* This is a final link. */ + h = NULL; + sym = NULL; + sec = NULL; + if (r_symndx < symtab_hdr->sh_info) + { + sym = local_syms + r_symndx; + sec = local_sections[r_symndx]; + relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); + } + else + { + h = sym_hashes[r_symndx - symtab_hdr->sh_info]; + 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) + { + sec = h->root.u.def.section; + relocation = (h->root.u.def.value + + sec->output_section->vma + sec->output_offset); + } + else if (h->root.type == bfd_link_hash_undefweak) + relocation = 0; + else + { + if (!((*info->callbacks->undefined_symbol) + (info, h->root.root.string, input_bfd, + input_section, rel->r_offset, TRUE))) + return FALSE; + relocation = 0; + } + } + + r = cr16c_elf_final_link_relocate (howto, input_bfd, output_bfd, + input_section, + contents, rel->r_offset, + relocation, rel->r_addend, + info, sec, h == NULL); + + if (r != bfd_reloc_ok) + { + const char *name; + const char *msg = (const char *) 0; + + if (h != NULL) + name = h->root.root.string; + else + { + name = (bfd_elf_string_from_elf_section + (input_bfd, symtab_hdr->sh_link, sym->st_name)); + if (name == NULL || *name == '\0') + name = bfd_section_name (input_bfd, sec); + } + + switch (r) + { + case bfd_reloc_overflow: + if (!((*info->callbacks->reloc_overflow) + (info, name, howto->name, (bfd_vma) 0, + input_bfd, input_section, rel->r_offset))) + return FALSE; + break; + + case bfd_reloc_undefined: + if (!((*info->callbacks->undefined_symbol) + (info, name, input_bfd, input_section, + rel->r_offset, TRUE))) + return FALSE; + break; + + case bfd_reloc_outofrange: + msg = _("internal error: out of range error"); + goto common_error; + + case bfd_reloc_notsupported: + msg = _("internal error: unsupported relocation error"); + goto common_error; + + case bfd_reloc_dangerous: + msg = _("internal error: dangerous error"); + goto common_error; + + default: + msg = _("internal error: unknown error"); + /* fall through */ + + common_error: + if (!((*info->callbacks->warning) + (info, msg, name, input_bfd, input_section, + rel->r_offset))) + return FALSE; + break; + } + } + } + + return TRUE; +} + +static asection * +elf32_cr16c_gc_mark_hook (asection *sec, + struct bfd_link_info *info ATTRIBUTE_UNUSED, + Elf_Internal_Rela *rel, + struct elf_link_hash_entry *h, + Elf_Internal_Sym *sym) +{ + if (h != NULL) + { + switch (ELF32_R_TYPE (rel->r_info)) + { + + default: + switch (h->root.type) + { + case bfd_link_hash_defined: + case bfd_link_hash_defweak: + return h->root.u.def.section; + + case bfd_link_hash_common: + return h->root.u.c.p->section; + + default: + break; + } + } + } + else + { + return bfd_section_from_elf_index (sec->owner, sym->st_shndx); + } + + return NULL; +} + +/* Update the got entry reference counts for the section being removed. */ + +static bfd_boolean +elf32_cr16c_gc_sweep_hook (bfd *abfd ATTRIBUTE_UNUSED, + struct bfd_link_info *info ATTRIBUTE_UNUSED, + asection *sec ATTRIBUTE_UNUSED, + const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED) +{ + /* We don't support garbage collection of GOT and PLT relocs yet. */ + return TRUE; +} + +/* CR16C ELF uses three common sections: + One is for default common symbols (placed in usual common section). + Second is for near common symbols (placed in "ncommon" section). + Third is for far common symbols (placed in "fcommon" section). + The following implementation is based on elf32-mips architecture */ + +static asection cr16c_elf_fcom_section; +static asymbol cr16c_elf_fcom_symbol; +static asymbol * cr16c_elf_fcom_symbol_ptr; +static asection cr16c_elf_ncom_section; +static asymbol cr16c_elf_ncom_symbol; +static asymbol * cr16c_elf_ncom_symbol_ptr; + +/* Given a BFD section, try to locate the + corresponding ELF section index. */ + +static bfd_boolean +elf32_cr16c_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED, + asection *sec, + int *retval) +{ + if (strcmp (bfd_get_section_name (abfd, sec), ".fcommon") == 0) + *retval = SHN_CR16C_FCOMMON; + else if (strcmp (bfd_get_section_name (abfd, sec), ".ncommon") == 0) + *retval = SHN_CR16C_NCOMMON; + else + return FALSE; + + return TRUE; +} + +/* Handle the special CR16C section numbers that a symbol may use. */ + +static void +elf32_cr16c_symbol_processing (bfd *abfd ATTRIBUTE_UNUSED, + asymbol *asym) +{ + elf_symbol_type *elfsym = (elf_symbol_type *) asym; + unsigned int indx; + + indx = elfsym->internal_elf_sym.st_shndx; + + switch (indx) + { + case SHN_CR16C_FCOMMON: + if (cr16c_elf_fcom_section.name == NULL) + { + /* Initialize the far common section. */ + cr16c_elf_fcom_section.name = ".fcommon"; + cr16c_elf_fcom_section.flags = SEC_IS_COMMON | SEC_ALLOC; + cr16c_elf_fcom_section.output_section = &cr16c_elf_fcom_section; + cr16c_elf_fcom_section.symbol = &cr16c_elf_fcom_symbol; + cr16c_elf_fcom_section.symbol_ptr_ptr = &cr16c_elf_fcom_symbol_ptr; + cr16c_elf_fcom_symbol.name = ".fcommon"; + cr16c_elf_fcom_symbol.flags = BSF_SECTION_SYM; + cr16c_elf_fcom_symbol.section = &cr16c_elf_fcom_section; + cr16c_elf_fcom_symbol_ptr = &cr16c_elf_fcom_symbol; + } + asym->section = &cr16c_elf_fcom_section; + asym->value = elfsym->internal_elf_sym.st_size; + break; + case SHN_CR16C_NCOMMON: + if (cr16c_elf_ncom_section.name == NULL) + { + /* Initialize the far common section. */ + cr16c_elf_ncom_section.name = ".ncommon"; + cr16c_elf_ncom_section.flags = SEC_IS_COMMON | SEC_ALLOC; + cr16c_elf_ncom_section.output_section = &cr16c_elf_ncom_section; + cr16c_elf_ncom_section.symbol = &cr16c_elf_ncom_symbol; + cr16c_elf_ncom_section.symbol_ptr_ptr = &cr16c_elf_ncom_symbol_ptr; + cr16c_elf_ncom_symbol.name = ".ncommon"; + cr16c_elf_ncom_symbol.flags = BSF_SECTION_SYM; + cr16c_elf_ncom_symbol.section = &cr16c_elf_ncom_section; + cr16c_elf_ncom_symbol_ptr = &cr16c_elf_ncom_symbol; + } + asym->section = &cr16c_elf_ncom_section; + asym->value = elfsym->internal_elf_sym.st_size; + break; + } +} + +/* Hook called by the linker routine which adds symbols from an object + file. We must handle the special cr16c section numbers here. */ + +static bfd_boolean +elf32_cr16c_add_symbol_hook (bfd *abfd, + struct bfd_link_info *info ATTRIBUTE_UNUSED, + const Elf_Internal_Sym *sym, + const char **namep ATTRIBUTE_UNUSED, + flagword *flagsp ATTRIBUTE_UNUSED, + asection **secp, + bfd_vma *valp) +{ + unsigned int indx = sym->st_shndx; + + switch (indx) + { + case SHN_CR16C_FCOMMON: + *secp = bfd_make_section_old_way (abfd, ".fcommon"); + (*secp)->flags |= SEC_IS_COMMON; + *valp = sym->st_size; + break; + case SHN_CR16C_NCOMMON: + *secp = bfd_make_section_old_way (abfd, ".ncommon"); + (*secp)->flags |= SEC_IS_COMMON; + *valp = sym->st_size; + break; + } + + return TRUE; +} + +static bfd_boolean +elf32_cr16c_link_output_symbol_hook (struct bfd_link_info *info ATTRIBUTE_UNUSED, + const char *name ATTRIBUTE_UNUSED, + Elf_Internal_Sym *sym, + asection *input_sec, + struct elf_link_hash_entry *h ATTRIBUTE_UNUSED) +{ + /* If we see a common symbol, which implies a relocatable link, then + if a symbol was in a special common section in an input file, mark + it as a special common in the output file. */ + + if (sym->st_shndx == SHN_COMMON) + { + if (strcmp (input_sec->name, ".fcommon") == 0) + sym->st_shndx = SHN_CR16C_FCOMMON; + else if (strcmp (input_sec->name, ".ncommon") == 0) + sym->st_shndx = SHN_CR16C_NCOMMON; + } + + return TRUE; +} + +/* Definitions for setting CR16C target vector. */ +#define TARGET_LITTLE_SYM bfd_elf32_cr16c_vec +#define TARGET_LITTLE_NAME "elf32-cr16c" +#define ELF_ARCH bfd_arch_cr16c +#define ELF_MACHINE_CODE EM_CR +#define ELF_MAXPAGESIZE 0x1 +#define elf_symbol_leading_char '_' + +#define bfd_elf32_bfd_reloc_type_lookup elf_cr16c_reloc_type_lookup +#define elf_info_to_howto elf_cr16c_info_to_howto +#define elf_info_to_howto_rel elf_cr16c_info_to_howto_rel +#define elf_backend_relocate_section elf32_cr16c_relocate_section +#define elf_backend_gc_mark_hook elf32_cr16c_gc_mark_hook +#define elf_backend_gc_sweep_hook elf32_cr16c_gc_sweep_hook +#define elf_backend_symbol_processing elf32_cr16c_symbol_processing +#define elf_backend_section_from_bfd_section elf32_cr16c_section_from_bfd_section +#define elf_backend_add_symbol_hook elf32_cr16c_add_symbol_hook +#define elf_backend_link_output_symbol_hook elf32_cr16c_link_output_symbol_hook + +#define elf_backend_can_gc_sections 1 + +#include "elf32-target.h" diff --git a/bfd/elf32-cris.c b/bfd/elf32-cris.c index b405d9e63b..775fd0e7c3 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 4bdaffcd57..e845a254e4 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 6ccb9f536f..7fb6d0c19e 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 80408fa6ff..5f70e3f186 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 039b4a3b47..6412acdfb1 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 6943391331..877da8a6a3 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 cffd194c88..54dbb9a62b 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 f1c27d0011..7b173e4485 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 67be1755f1..60dab3483c 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 812b3ca045..21d37b176c 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 9de2f8b20e..2a139a405c 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 9864ef2efa..39832be83c 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 fd13ea897c..e6aa666c6d 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 5513ad66b0..af1c2221f8 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 515a9296b8..4eb08ad3e6 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 eabd070a77..074c108934 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 3ec6638d6c..1070957ea7 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 9f8f9ab815..3016652678 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 2aba9cd5a8..b9dcf3c5ae 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 e6dc4a01bb..8ce4678e29 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 985a43a522..bbf6ee0148 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 6cb987c2b8..e89777753a 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 1683683f77..2d4715b4e1 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 d64eca28c9..76dcc18b24 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 7f34a83b67..4b78681fae 100644 --- a/bfd/elf64-mmix.c +++ b/bfd/elf64-mmix.c @@ -1474,9 +1474,11 @@ mmix_elf_relocate_section (output_bfd, info, input_bfd, input_section, sec = local_sections [r_symndx]; relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel); - name = bfd_elf_string_from_elf_section - (input_bfd, symtab_hdr->sh_link, sym->st_name); - name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name; + name = bfd_elf_string_from_elf_section (input_bfd, + symtab_hdr->sh_link, + sym->st_name); + if (name == NULL) + name = bfd_section_name (input_bfd, sec); } else { @@ -1486,6 +1488,7 @@ mmix_elf_relocate_section (output_bfd, info, input_bfd, input_section, r_symndx, symtab_hdr, sym_hashes, h, sec, relocation, unresolved_reloc, undefined_signalled); + name = h->root.root.string; } r = mmix_final_link_relocate (howto, input_section, @@ -2024,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; } @@ -2269,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 a2aebfea21..a0d81d0550 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 c35c0a9d73..63a261a8e8 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 87b754e31b..ad6ca1c503 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 6c9d302564..dd3e4962e2 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 1aadfe579d..a1d62501f9 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/elfarm-nabi.c b/bfd/elfarm-nabi.c index 5ecbe8e3e6..961a52a0cc 100644 --- a/bfd/elfarm-nabi.c +++ b/bfd/elfarm-nabi.c @@ -516,6 +516,47 @@ static reloc_howto_type elf32_arm_howto_table[] = 0, /* dst_mask */ FALSE), /* pcrel_offset */ + HOWTO (R_ARM_ALU_PCREL7_0, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 12, /* bitsize */ + TRUE, /* pc_relative */ + 0, /* bitpos */ + complain_overflow_dont,/* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_ARM_ALU_PCREL_7_0", /* name */ + FALSE, /* partial_inplace */ + 0x00000fff, /* src_mask */ + 0x00000fff, /* dst_mask */ + TRUE), /* pcrel_offset */ + + HOWTO (R_ARM_ALU_PCREL15_8, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 12, /* bitsize */ + TRUE, /* pc_relative */ + 8, /* bitpos */ + complain_overflow_dont,/* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_ARM_ALU_PCREL_15_8",/* name */ + FALSE, /* partial_inplace */ + 0x00000fff, /* src_mask */ + 0x00000fff, /* dst_mask */ + TRUE), /* pcrel_offset */ + + HOWTO (R_ARM_ALU_PCREL23_15, /* type */ + 0, /* rightshift */ + 2, /* size (0 = byte, 1 = short, 2 = long) */ + 12, /* bitsize */ + TRUE, /* pc_relative */ + 16, /* bitpos */ + complain_overflow_dont,/* complain_on_overflow */ + bfd_elf_generic_reloc, /* special_function */ + "R_ARM_ALU_PCREL_23_15",/* name */ + FALSE, /* partial_inplace */ + 0x00000fff, /* src_mask */ + 0x00000fff, /* dst_mask */ + TRUE), /* pcrel_offset */ }; /* GNU extension to record C++ vtable hierarchy */ diff --git a/bfd/elfcode.h b/bfd/elfcode.h index d0dd9eddfb..bc69d48db4 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) @@ -149,10 +137,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #define LOG_FILE_ALIGN 2 #endif -#define elf_stringtab_init _bfd_elf_stringtab_init - -#define section_from_elf_index bfd_section_from_elf_index - #ifdef DEBUG static void elf_debug_section (int, Elf_Internal_Shdr *); static void elf_debug_file (Elf_Internal_Ehdr *); @@ -1109,8 +1093,8 @@ elf_slurp_symbol_table (bfd *abfd, asymbol **symptrs, bfd_boolean dynamic) else if (isym->st_shndx < SHN_LORESERVE || isym->st_shndx > SHN_HIRESERVE) { - sym->symbol.section = section_from_elf_index (abfd, - isym->st_shndx); + sym->symbol.section = bfd_section_from_elf_index (abfd, + isym->st_shndx); if (sym->symbol.section == NULL) { /* This symbol is in a section for which we did not @@ -1735,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 a11e7cdea8..5c8072ad25 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 de477dfbd2..0000000000 --- a/bfd/elflink.h +++ /dev/null @@ -1,3529 +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. */ - Elf_External_Sym *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. */ - Elf_External_Sym *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 *); -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 *); - - if (rel_hdr->sh_entsize == sizeof (Elf_External_Rel)) - { - swap_in = bed->s->swap_reloc_in; - swap_out = bed->s->swap_reloc_out; - } - else if (rel_hdr->sh_entsize == sizeof (Elf_External_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 (); - - 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 = ELF_R_INFO ((*rel_hash)->indx, - ELF_R_TYPE (irela[j].r_info)); - (*swap_out) (abfd, irela, erela); - } -} - -struct elf_link_sort_rela -{ - bfd_vma offset; - 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 (ELF_R_SYM (a->rela->r_info) < ELF_R_SYM (b->rela->r_info)) - return -1; - if (ELF_R_SYM (a->rela->r_info) > ELF_R_SYM (b->rela->r_info)) - 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->offset < b->offset) - return -1; - if (a->offset > b->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; - - 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 = sizeof (Elf_External_Rel); - swap_in = bed->s->swap_reloc_in; - swap_out = bed->s->swap_reloc_out; - } - else - { - ext_size = sizeof (Elf_External_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; - } - - 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); - 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 (ELF_R_SYM (sp->rela->r_info) != ELF_R_SYM (sq->rela->r_info)) - sq = sp; - sp->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 = 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 - / sizeof (Elf_External_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 == sizeof (Elf_External_Rel) - || entsize1 == sizeof (Elf_External_Rela)); - same_size = (!o->use_rela_p - == (entsize1 == sizeof (Elf_External_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 == sizeof (Elf_External_Rel) - || entsize2 == sizeof (Elf_External_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 = sizeof (Elf_External_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 *= sizeof (Elf_External_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 = 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 * sizeof (Elf_External_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; - Elf_External_Sym *dynsym = - (Elf_External_Sym *) 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; - Elf_External_Sym *dest; - - indx = elf_section_data (s)->this_idx; - BFD_ASSERT (indx > 0); - sym.st_shndx = indx; - sym.st_value = s->vma; - dest = dynsym + elf_section_data (s)->dynindx; - elf_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; - Elf_External_Sym *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; - elf_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)) - 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) - { - Elf_External_Dyn *dyncon, *dynconend; - - /* Fix up .dynamic entries. */ - o = bfd_get_section_by_name (dynobj, ".dynamic"); - BFD_ASSERT (o != NULL); - - dyncon = (Elf_External_Dyn *) o->contents; - dynconend = (Elf_External_Dyn *) (o->contents + o->_raw_size); - for (; dyncon < dynconend; dyncon++) - { - Elf_Internal_Dyn dyn; - const char *name; - unsigned int type; - - elf_swap_dyn_in (dynobj, dyncon, &dyn); - - switch (dyn.d_tag) - { - default: - break; - case DT_NULL: - if (relativecount > 0 && dyncon + 1 < 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: break; - } - if (dyn.d_tag != DT_NULL) - { - dyn.d_un.d_val = relativecount; - elf_swap_dyn_out (dynobj, &dyn, dyncon); - relativecount = 0; - } - } - break; - 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; - } - - elf_swap_dyn_out (dynobj, &dyn, dyncon); - } - } - break; - - 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; - elf_swap_dyn_out (dynobj, &dyn, dyncon); - 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; - elf_swap_dyn_out (dynobj, &dyn, dyncon); - 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; - } - } - } - elf_swap_dyn_out (dynobj, &dyn, dyncon); - break; - } - } - } - - /* 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) -{ - Elf_External_Sym *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 *); - - output_symbol_hook = get_elf_backend_data (finfo->output_bfd)-> - 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)) - return FALSE; - } - - dest = finfo->symbuf + finfo->symbuf_count; - 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); - } - - elf_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) -{ - 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 * sizeof (Elf_External_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, - 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 / sizeof (Elf_External_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; - - 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; - } - - /* 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, 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, 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) - { - const struct elf_backend_data *bed; - - bed = get_elf_backend_data (finfo->output_bfd); - 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; - Elf_External_Sym *esym; - - sym.st_name = h->dynstr_index; - esym = (Elf_External_Sym *) finfo->dynsym_sec->contents + h->dynindx; - elf_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 / sizeof (Elf_External_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 = 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; - - /* 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; - - /* 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 = ELF_R_SYM (rel->r_info); - 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 - = ELF_R_INFO (0, ELF_R_TYPE (rel->r_info)); - 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 - == sizeof (Elf_External_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 = ELF_R_SYM (irela->r_info); - 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 = ELF_R_INFO (r_symndx, - ELF_R_TYPE (irela->r_info)); - } - - /* 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; - } - irel[0].r_info = ELF_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 - * sizeof (Elf_External_Rel)); - (*bed->s->swap_reloc_out) (output_bfd, irel, erel); - } - else - { - irel[0].r_addend = addend; - erel += (elf_section_data (output_section)->rel_count - * sizeof (Elf_External_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; - - 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 / sizeof (Elf_External_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; - - for (rel = relstart; rel < relend; rel++) - { - unsigned long r_symndx; - asection *rsec; - struct elf_link_hash_entry *h; - - r_symndx = ELF_R_SYM (rel->r_info); - 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; - - /* 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/sizeof (Elf_External_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; -} - -/* 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; - - 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 / sizeof (Elf_External_Sym); - else - locsymcount = symtab_hdr->sh_info; - - for (j = 0; j < locsymcount; ++j) - { - if (local_got[j] > 0) - { - local_got[j] = gotoff; - gotoff += ARCH_SIZE / 8; - } - else - local_got[j] = (bfd_vma) -1; - } - } - - /* Then the global .got entries. .plt refcounts are handled by - adjust_dynamic_symbol */ - elf_link_hash_traverse (elf_hash_table (info), - elf_gc_allocate_got_offsets, - &gotoff); - 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 *offarg) -{ - bfd_vma *off = offarg; - - 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 = off[0]; - off[0] += ARCH_SIZE / 8; - } - 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 = ELF_R_SYM (rcookie->rel->r_info); - 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 = 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 / sizeof (Elf_External_Sym); - cookie.extsymoff = 0; - } - else - { - cookie.locsymcount = symtab_hdr->sh_info; - cookie.extsymoff = symtab_hdr->sh_info; - } - - 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 c1d6622006..b8527a91c7 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 12eb566941..faa2ecc221 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 8dfd56a68f..e250a97da7 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/libbfd.h b/bfd/libbfd.h index 62043f3860..e4e17f9803 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -1437,6 +1437,46 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@", "BFD_RELOC_M68HC11_PAGE", "BFD_RELOC_M68HC11_24", "BFD_RELOC_M68HC12_5B", + "BFD_RELOC_16C_NUM08", + "BFD_RELOC_16C_NUM08_C", + "BFD_RELOC_16C_NUM16", + "BFD_RELOC_16C_NUM16_C", + "BFD_RELOC_16C_NUM32", + "BFD_RELOC_16C_NUM32_C", + "BFD_RELOC_16C_DISP04", + "BFD_RELOC_16C_DISP04_C", + "BFD_RELOC_16C_DISP08", + "BFD_RELOC_16C_DISP08_C", + "BFD_RELOC_16C_DISP16", + "BFD_RELOC_16C_DISP16_C", + "BFD_RELOC_16C_DISP24", + "BFD_RELOC_16C_DISP24_C", + "BFD_RELOC_16C_DISP24a", + "BFD_RELOC_16C_DISP24a_C", + "BFD_RELOC_16C_REG04", + "BFD_RELOC_16C_REG04_C", + "BFD_RELOC_16C_REG04a", + "BFD_RELOC_16C_REG04a_C", + "BFD_RELOC_16C_REG14", + "BFD_RELOC_16C_REG14_C", + "BFD_RELOC_16C_REG16", + "BFD_RELOC_16C_REG16_C", + "BFD_RELOC_16C_REG20", + "BFD_RELOC_16C_REG20_C", + "BFD_RELOC_16C_ABS20", + "BFD_RELOC_16C_ABS20_C", + "BFD_RELOC_16C_ABS24", + "BFD_RELOC_16C_ABS24_C", + "BFD_RELOC_16C_IMM04", + "BFD_RELOC_16C_IMM04_C", + "BFD_RELOC_16C_IMM16", + "BFD_RELOC_16C_IMM16_C", + "BFD_RELOC_16C_IMM20", + "BFD_RELOC_16C_IMM20_C", + "BFD_RELOC_16C_IMM24", + "BFD_RELOC_16C_IMM24_C", + "BFD_RELOC_16C_IMM32", + "BFD_RELOC_16C_IMM32_C", "BFD_RELOC_CRIS_BDISP8", "BFD_RELOC_CRIS_UNSIGNED_5", "BFD_RELOC_CRIS_SIGNED_6", diff --git a/bfd/po/SRC-POTFILES.in b/bfd/po/SRC-POTFILES.in index 07742dd9f2..d29593d795 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 3396c4f713..dd37e15cbe 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 "" diff --git a/bfd/reloc.c b/bfd/reloc.c index 9bffaa3658..cc4f6a7c28 100644 --- a/bfd/reloc.c +++ b/bfd/reloc.c @@ -3771,6 +3771,89 @@ ENUMDOC This is the 5 bits of a value. ENUM + BFD_RELOC_16C_NUM08 +ENUMX + BFD_RELOC_16C_NUM08_C +ENUMX + BFD_RELOC_16C_NUM16 +ENUMX + BFD_RELOC_16C_NUM16_C +ENUMX + BFD_RELOC_16C_NUM32 +ENUMX + BFD_RELOC_16C_NUM32_C +ENUMX + BFD_RELOC_16C_DISP04 +ENUMX + BFD_RELOC_16C_DISP04_C +ENUMX + BFD_RELOC_16C_DISP08 +ENUMX + BFD_RELOC_16C_DISP08_C +ENUMX + BFD_RELOC_16C_DISP16 +ENUMX + BFD_RELOC_16C_DISP16_C +ENUMX + BFD_RELOC_16C_DISP24 +ENUMX + BFD_RELOC_16C_DISP24_C +ENUMX + BFD_RELOC_16C_DISP24a +ENUMX + BFD_RELOC_16C_DISP24a_C +ENUMX + BFD_RELOC_16C_REG04 +ENUMX + BFD_RELOC_16C_REG04_C +ENUMX + BFD_RELOC_16C_REG04a +ENUMX + BFD_RELOC_16C_REG04a_C +ENUMX + BFD_RELOC_16C_REG14 +ENUMX + BFD_RELOC_16C_REG14_C +ENUMX + BFD_RELOC_16C_REG16 +ENUMX + BFD_RELOC_16C_REG16_C +ENUMX + BFD_RELOC_16C_REG20 +ENUMX + BFD_RELOC_16C_REG20_C +ENUMX + BFD_RELOC_16C_ABS20 +ENUMX + BFD_RELOC_16C_ABS20_C +ENUMX + BFD_RELOC_16C_ABS24 +ENUMX + BFD_RELOC_16C_ABS24_C +ENUMX + BFD_RELOC_16C_IMM04 +ENUMX + BFD_RELOC_16C_IMM04_C +ENUMX + BFD_RELOC_16C_IMM16 +ENUMX + BFD_RELOC_16C_IMM16_C +ENUMX + BFD_RELOC_16C_IMM20 +ENUMX + BFD_RELOC_16C_IMM20_C +ENUMX + BFD_RELOC_16C_IMM24 +ENUMX + BFD_RELOC_16C_IMM24_C +ENUMX + BFD_RELOC_16C_IMM32 +ENUMX + BFD_RELOC_16C_IMM32_C +ENUMDOC + NS CR16C Relocations. + +ENUM BFD_RELOC_CRIS_BDISP8 ENUMX BFD_RELOC_CRIS_UNSIGNED_5 diff --git a/bfd/stabs.c b/bfd/stabs.c index 42944a41bf..04b91f6800 100644 --- a/bfd/stabs.c +++ b/bfd/stabs.c @@ -1,5 +1,5 @@ /* Stabs in sections linking support. - Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003 + Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc. Written by Ian Lance Taylor, Cygnus Support. @@ -56,12 +56,19 @@ struct stab_link_includes_table }; /* A linked list of totals that we have found for a particular header - file. */ + file. A total is a unique identifier for a particular BINCL...EINCL + sequence of STABs that can be used to identify duplicate sequences. + It consists of three fields, 'sum_chars' which is the sum of all the + STABS characters; 'num_chars' which is the number of these charactes + and 'symb' which is a buffer of all the symbols in the sequence. This + buffer is only checked as a last resort. */ struct stab_link_includes_totals { struct stab_link_includes_totals *next; - bfd_vma total; + bfd_vma sum_chars; /* Accumulated sum of STABS characters. */ + bfd_vma num_chars; /* Number of STABS characters. */ + const char* symb; /* The STABS characters themselves. */ }; /* An entry in the header file hash table. */ @@ -340,15 +347,21 @@ _bfd_link_section_stabs (abfd, psinfo, stabsec, stabstrsec, psecinfo, pstring_of first number after an open parenthesis). */ if (type == (int) N_BINCL) { - bfd_vma val; + bfd_vma sum_chars; + bfd_vma num_chars; + bfd_vma buf_len = 0; + char * symb; + char * symb_rover; int nest; - bfd_byte *incl_sym; - struct stab_link_includes_entry *incl_entry; - struct stab_link_includes_totals *t; - struct stab_excl_list *ne; + bfd_byte * incl_sym; + struct stab_link_includes_entry * incl_entry; + struct stab_link_includes_totals * t; + struct stab_excl_list * ne; - val = 0; + symb = symb_rover = NULL; + sum_chars = num_chars = 0; nest = 0; + for (incl_sym = sym + STABSIZE; incl_sym < symend; incl_sym += STABSIZE) @@ -377,7 +390,17 @@ _bfd_link_section_stabs (abfd, psinfo, stabsec, stabstrsec, psecinfo, pstring_of + bfd_get_32 (abfd, incl_sym + STRDXOFF)); for (; *str != '\0'; str++) { - val += *str; + if (num_chars >= buf_len) + { + buf_len += 32 * 1024; + symb = bfd_realloc (symb, buf_len); + if (symb == NULL) + goto error_return; + symb_rover = symb + num_chars; + } + * symb_rover ++ = * str; + sum_chars += *str; + num_chars ++; if (*str == '(') { /* Skip the file number. */ @@ -390,6 +413,8 @@ _bfd_link_section_stabs (abfd, psinfo, stabsec, stabstrsec, psecinfo, pstring_of } } + BFD_ASSERT (num_chars == (bfd_vma) (symb_rover - symb)); + /* If we have already included a header file with the same value, then replaced this one with an N_EXCL symbol. */ incl_entry = stab_link_includes_lookup (&sinfo->includes, string, @@ -398,7 +423,9 @@ _bfd_link_section_stabs (abfd, psinfo, stabsec, stabstrsec, psecinfo, pstring_of goto error_return; for (t = incl_entry->totals; t != NULL; t = t->next) - if (t->total == val) + if (t->sum_chars == sum_chars + && t->num_chars == num_chars + && memcmp (t->symb, symb, num_chars) == 0) break; /* Record this symbol, so that we can set the value @@ -408,7 +435,7 @@ _bfd_link_section_stabs (abfd, psinfo, stabsec, stabstrsec, psecinfo, pstring_of if (ne == NULL) goto error_return; ne->offset = sym - stabbuf; - ne->val = val; + ne->val = sum_chars; ne->type = (int) N_BINCL; ne->next = secinfo->excls; secinfo->excls = ne; @@ -421,7 +448,9 @@ _bfd_link_section_stabs (abfd, psinfo, stabsec, stabstrsec, psecinfo, pstring_of bfd_hash_allocate (&sinfo->includes.root, sizeof *t)); if (t == NULL) goto error_return; - t->total = val; + t->sum_chars = sum_chars; + t->num_chars = num_chars; + t->symb = bfd_realloc (symb, num_chars); /* Trim data down. */ t->next = incl_entry->totals; incl_entry->totals = t; } @@ -433,6 +462,9 @@ _bfd_link_section_stabs (abfd, psinfo, stabsec, stabstrsec, psecinfo, pstring_of pass to change the type to N_EXCL. */ ne->type = (int) N_EXCL; + /* Free off superfluous symbols. */ + free (symb); + /* Mark the skipped symbols. */ nest = 0; @@ -456,6 +488,9 @@ _bfd_link_section_stabs (abfd, psinfo, stabsec, stabstrsec, psecinfo, pstring_of } else if (incl_type == (int) N_BINCL) ++nest; + else if (incl_type == (int) N_EXCL) + /* Keep existing exclusion marks. */ + continue; else if (nest == 0) { *incl_pstridx = (bfd_size_type) -1; diff --git a/bfd/targets.c b/bfd/targets.c index 9d81c56431..256a2af642 100644 --- a/bfd/targets.c +++ b/bfd/targets.c @@ -517,6 +517,7 @@ extern const bfd_target bfd_elf32_bigarc_vec; extern const bfd_target bfd_elf32_bigarm_oabi_vec; extern const bfd_target bfd_elf32_bigarm_vec; extern const bfd_target bfd_elf32_bigmips_vec; +extern const bfd_target bfd_elf32_cr16c_vec; extern const bfd_target bfd_elf32_cris_vec; extern const bfd_target bfd_elf32_d10v_vec; extern const bfd_target bfd_elf32_d30v_vec; @@ -807,6 +808,7 @@ static const bfd_target * const _bfd_target_vector[] = { &bfd_elf32_bigarm_oabi_vec, &bfd_elf32_bigarm_vec, &bfd_elf32_bigmips_vec, + &bfd_elf32_cr16c_vec, &bfd_elf32_cris_vec, &bfd_elf32_d10v_vec, &bfd_elf32_d30v_vec, diff --git a/bfd/version.h b/bfd/version.h index 16afdadee7..edf210e21f 100644 --- a/bfd/version.h +++ b/bfd/version.h @@ -1,3 +1,3 @@ -#define BFD_VERSION_DATE 20040327 +#define BFD_VERSION_DATE 20040402 #define BFD_VERSION @bfd_version@ #define BFD_VERSION_STRING @bfd_version_string@ diff --git a/cpu/ChangeLog b/cpu/ChangeLog index ce4468bac7..d8eaa9ec36 100644 --- a/cpu/ChangeLog +++ b/cpu/ChangeLog @@ -1,3 +1,7 @@ +2004-03-30 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com> + + * m32r.opc (parse_hi16): Fixed shigh(0xffff8000) bug. + 2004-03-01 Richard Sandiford <rsandifo@redhat.com> * frv.cpu (define-arch frv): Add fr450 mach. diff --git a/cpu/m32r.opc b/cpu/m32r.opc index 6764223f2b..78bd0facef 100644 --- a/cpu/m32r.opc +++ b/cpu/m32r.opc @@ -1,6 +1,6 @@ /* M32R opcode support. -*- C -*- - Copyright 1998, 1999, 2000, 2001 Free Software Foundation, Inc. + Copyright 1998, 1999, 2000, 2001, 2004 Free Software Foundation, Inc. Contributed by Red Hat Inc; developed under contract from Mitsubishi Electric Corporation. @@ -23,9 +23,7 @@ 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. - -*/ + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ /* This file is an addendum to m32r.cpu. Heavy use of C code isn't appropriate in .cpu files, so it resides here. This especially applies @@ -40,8 +38,7 @@ <arch>-opc.c additions use: "-- opc.c" <arch>-asm.c additions use: "-- asm.c" <arch>-dis.c additions use: "-- dis.c" - <arch>-ibd.h additions use: "-- ibd.h" -*/ + <arch>-ibd.h additions use: "-- ibd.h" */ /* -- opc.h */ @@ -153,7 +150,10 @@ parse_hi16 (cd, strp, opindex, valuep) ++*strp; if (errmsg == NULL && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) - value = (value >> 16) + (value & 0x8000 ? 1 : 0); + { + value = value + (value & 0x8000 ? 0x10000 : 0); + value >>= 16; + } *valuep = value; return errmsg; } diff --git a/include/ChangeLog b/include/ChangeLog index 16886b65a6..883088ea6d 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,7 @@ +2004-03-30 Zack Weinberg <zack@codesourcery.com> + + * hashtab.h, splay-tree.h: Use new shorter form of GTY markers. + 2004-03-25 Stan Shebs <shebs@apple.com> * mpw/: Remove subdirectory and everything in it. diff --git a/include/elf/ChangeLog b/include/elf/ChangeLog index 385b857e38..28ec205b58 100644 --- a/include/elf/ChangeLog +++ b/include/elf/ChangeLog @@ -1,3 +1,9 @@ +2004-30-30 Galit Heller <Galit.Heller@nsc.com> + Tomer Levi <Tomer.Levi@nsc.com> + + * common.h (EM_CR): Define. + * cr16c.h: New file. + 2004-03-23 Paul Brook <paul@codesourcery.com> * arm.h (EF_ERM_BE8, EF_ARM_LE8, EF_ARM_EABI_VER3): Add. diff --git a/include/elf/common.h b/include/elf/common.h index bf233f61df..8ebc2cf472 100644 --- a/include/elf/common.h +++ b/include/elf/common.h @@ -180,6 +180,7 @@ #define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */ #define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ #define EM_IP2K 101 /* Ubicom IP2022 micro controller */ +#define EM_CR 103 /* National Semiconductor CompactRISC */ #define EM_MSP430 105 /* TI msp430 micro controller */ /* If it is necessary to assign new unofficial EM_* values, please pick large diff --git a/include/elf/cr16c.h b/include/elf/cr16c.h new file mode 100644 index 0000000000..1a91afe0fe --- /dev/null +++ b/include/elf/cr16c.h @@ -0,0 +1,258 @@ +/* CR16C ELF support for BFD. + Copyright 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. */ + +#ifndef _ELF_CR16C_H +#define _ELF_CR16C_H + +#include "bfd.h" +#include "elf/reloc-macros.h" + +/* Creating indices for reloc_map_index array. */ +START_RELOC_NUMBERS (elf_cr16c_reloc_type) + RELOC_NUMBER (RINDEX_16C_NUM08, 0) + RELOC_NUMBER (RINDEX_16C_NUM08_C, 1) + RELOC_NUMBER (RINDEX_16C_NUM16, 2) + RELOC_NUMBER (RINDEX_16C_NUM16_C, 3) + RELOC_NUMBER (RINDEX_16C_NUM32, 4) + RELOC_NUMBER (RINDEX_16C_NUM32_C, 5) + RELOC_NUMBER (RINDEX_16C_DISP04, 6) + RELOC_NUMBER (RINDEX_16C_DISP04_C, 7) + RELOC_NUMBER (RINDEX_16C_DISP08, 8) + RELOC_NUMBER (RINDEX_16C_DISP08_C, 9) + RELOC_NUMBER (RINDEX_16C_DISP16, 10) + RELOC_NUMBER (RINDEX_16C_DISP16_C, 11) + RELOC_NUMBER (RINDEX_16C_DISP24, 12) + RELOC_NUMBER (RINDEX_16C_DISP24_C, 13) + RELOC_NUMBER (RINDEX_16C_DISP24a, 14) + RELOC_NUMBER (RINDEX_16C_DISP24a_C, 15) + RELOC_NUMBER (RINDEX_16C_REG04, 16) + RELOC_NUMBER (RINDEX_16C_REG04_C, 17) + RELOC_NUMBER (RINDEX_16C_REG04a, 18) + RELOC_NUMBER (RINDEX_16C_REG04a_C, 19) + RELOC_NUMBER (RINDEX_16C_REG14, 20) + RELOC_NUMBER (RINDEX_16C_REG14_C, 21) + RELOC_NUMBER (RINDEX_16C_REG16, 22) + RELOC_NUMBER (RINDEX_16C_REG16_C, 23) + RELOC_NUMBER (RINDEX_16C_REG20, 24) + RELOC_NUMBER (RINDEX_16C_REG20_C, 25) + RELOC_NUMBER (RINDEX_16C_ABS20, 26) + RELOC_NUMBER (RINDEX_16C_ABS20_C, 27) + RELOC_NUMBER (RINDEX_16C_ABS24, 28) + RELOC_NUMBER (RINDEX_16C_ABS24_C, 29) + RELOC_NUMBER (RINDEX_16C_IMM04, 30) + RELOC_NUMBER (RINDEX_16C_IMM04_C, 31) + RELOC_NUMBER (RINDEX_16C_IMM16, 32) + RELOC_NUMBER (RINDEX_16C_IMM16_C, 33) + RELOC_NUMBER (RINDEX_16C_IMM20, 34) + RELOC_NUMBER (RINDEX_16C_IMM20_C, 35) + RELOC_NUMBER (RINDEX_16C_IMM24, 36) + RELOC_NUMBER (RINDEX_16C_IMM24_C, 37) + RELOC_NUMBER (RINDEX_16C_IMM32, 38) + RELOC_NUMBER (RINDEX_16C_IMM32_C, 39) +END_RELOC_NUMBERS (RINDEX_16C_MAX) + +/* CR16C Relocation Types ('cr_reloc_type' entry in the reloc_map structure). + The relocation constant name is determined as follows : + + R_16C_<format><size>[_C] + + Where : + + <format> is one of the following: + NUM - R_NUMBER mnemonic, + DISP - R_16C_DISPL mnemonic, + REG - R_16C_REGREL mnemonic, + ABS - R_16C_ABS mnemonic, + IMM - R_16C_IMMED mnemonic, + <size> stands for R_S_16C_<size> + _C means 'code label' and is only added when R_ADDRTYPE subfield + is of type R_CODE_ADDR. */ + +/* The table below shows what the hex digits in the definition of the + relocation type constants correspond to. + ------------------------------------------------------------------ + R_SIZESP R_FORMAT R_RELTO R_ADDRTYPE + ------------------------------------------------------------------ */ +/* R_S_16C_08 R_NUMBER R_ABS R_ADDRESS */ +#define R_16C_NUM08 0X0001 + +/* R_S_16C_08 R_NUMBER R_ABS R_CODE_ADDR */ +#define R_16C_NUM08_C 0X0006 + +/* R_S_16C_16 R_NUMBER R_ABS R_ADDRESS */ +#define R_16C_NUM16 0X1001 + +/* R_S_16C_16 R_NUMBER R_ABS R_CODE_ADDR */ +#define R_16C_NUM16_C 0X1006 + +/* R_S_16C_32 R_NUMBER R_ABS R_ADDRESS */ +#define R_16C_NUM32 0X2001 + +/* R_S_16C_32 R_NUMBER R_ABS R_CODE_ADDR */ +#define R_16C_NUM32_C 0X2006 + +/* R_S_16C_04 R_16C_DISPL R_PCREL R_ADDRESS */ +#define R_16C_DISP04 0X5411 + +/* R_S_16C_04 R_16C_DISPL R_PCREL R_CODE_ADDR */ +#define R_16C_DISP04_C 0X5416 + +/* R_S_16C_08 R_16C_DISPL R_PCREL R_ADDRESS */ +#define R_16C_DISP08 0X0411 + +/* R_S_16C_08 R_16C_DISPL R_PCREL R_CODE_ADDR */ +#define R_16C_DISP08_C 0X0416 + +/* R_S_16C_16 R_16C_DISPL R_PCREL R_ADDRESS */ +#define R_16C_DISP16 0X1411 + +/* R_S_16C_16 R_16C_DISPL R_PCREL R_CODE_ADDR */ +#define R_16C_DISP16_C 0X1416 + +/* R_S_16C_24 R_16C_DISPL R_PCREL R_ADDRESS */ +#define R_16C_DISP24 0X7411 + +/* R_S_16C_24 R_16C_DISPL R_PCREL R_CODE_ADDR */ +#define R_16C_DISP24_C 0X7416 + +/* R_S_16C_24a R_16C_DISPL R_PCREL R_ADDRESS */ +#define R_16C_DISP24a 0X6411 + +/* R_S_16C_24a R_16C_DISPL R_PCREL R_CODE_ADDR */ +#define R_16C_DISP24a_C 0X6416 + +/* R_S_16C_04 R_16C_REGREL R_ABS R_ADDRESS */ +#define R_16C_REG04 0X5201 + +/* R_S_16C_04 R_16C_REGREL R_ABS R_CODE_ADDR */ +#define R_16C_REG04_C 0X5206 + +/* R_S_16C_04_a R_16C_REGREL R_ABS R_ADDRESS */ +#define R_16C_REG04a 0X4201 + +/* R_S_16C_04_a R_16C_REGREL R_ABS R_CODE_ADDR */ +#define R_16C_REG04a_C 0X4206 + +/* R_S_16C_14 R_16C_REGREL R_ABS R_ADDRESS */ +#define R_16C_REG14 0X3201 + +/* R_S_16C_14 R_16C_REGREL R_ABS R_CODE_ADDR */ +#define R_16C_REG14_C 0X3206 + +/* R_S_16C_16 R_16C_REGREL R_ABS R_ADDRESS */ +#define R_16C_REG16 0X1201 + +/* R_S_16C_16 R_16C_REGREL R_ABS R_CODE_ADDR */ +#define R_16C_REG16_C 0X1206 + +/* R_S_16C_20 R_16C_REGREL R_ABS R_ADDRESS */ +#define R_16C_REG20 0X8201 + +/* R_S_16C_20 R_16C_REGREL R_ABS R_CODE_ADDR */ +#define R_16C_REG20_C 0X8206 + +/* R_S_16C_20 R_16C_ABS R_ABS R_ADDRESS */ +#define R_16C_ABS20 0X8101 + +/* R_S_16C_20 R_16C_ABS R_ABS R_CODE_ADDR */ +#define R_16C_ABS20_C 0X8106 + +/* R_S_16C_24 R_16C_ABS R_ABS R_ADDRESS */ +#define R_16C_ABS24 0X7101 + +/* R_S_16C_24 R_16C_ABS R_ABS R_CODE_ADDR */ +#define R_16C_ABS24_C 0X7106 + +/* R_S_16C_04 R_16C_IMMED R_ABS R_ADDRESS */ +#define R_16C_IMM04 0X5301 + +/* R_S_16C_04 R_16C_IMMED R_ABS R_CODE_ADDR */ +#define R_16C_IMM04_C 0X5306 + +/* R_S_16C_16 R_16C_IMMED R_ABS R_ADDRESS */ +#define R_16C_IMM16 0X1301 + +/* R_S_16C_16 R_16C_IMMED R_ABS R_CODE_ADDR */ +#define R_16C_IMM16_C 0X1306 + +/* R_S_16C_20 R_16C_IMMED R_ABS R_ADDRESS */ +#define R_16C_IMM20 0X8301 + +/* R_S_16C_20 R_16C_IMMED R_ABS R_CODE_ADDR */ +#define R_16C_IMM20_C 0X8306 + +/* R_S_16C_24 R_16C_IMMED R_ABS R_ADDRESS */ +#define R_16C_IMM24 0X7301 + +/* R_S_16C_24 R_16C_IMMED R_ABS R_CODE_ADDR */ +#define R_16C_IMM24_C 0X7306 + +/* R_S_16C_32 R_16C_IMMED R_ABS R_ADDRESS */ +#define R_16C_IMM32 0X2301 + +/* R_S_16C_32 R_16C_IMMED R_ABS R_CODE_ADDR */ +#define R_16C_IMM32_C 0X2306 + + +/* Relocation item type. */ +#define R_ADDRTYPE 0x000f +#define R_ADDRESS 0x0001 /* Take address of symbol. */ +#define R_CODE_ADDR 0x0006 /* Take address of symbol divided by 2. */ + +/* Relocation action. */ +#define R_RELTO 0x00f0 +#define R_ABS 0x0000 /* Keep symbol's address as such. */ +#define R_PCREL 0x0010 /* Subtract the pc address of hole. */ + +/* Relocation item data format. */ +#define R_FORMAT 0x0f00 +#define R_NUMBER 0x0000 /* Retain as two's complement value. */ +#define R_16C_DISPL 0x0400 /* CR16C displacement type. */ +#define R_16C_ABS 0x0100 /* CR16C absolute type. */ +#define R_16C_REGREL 0x0200 /* CR16C register-relative type. */ +#define R_16C_IMMED 0x0300 /* CR16C immediate type. */ + +/* Relocation item size. */ +#define R_SIZESP 0xf000 +#define R_S_16C_04 0x5000 +#define R_S_16C_04_a 0x4000 +#define R_S_16C_08 0x0000 +#define R_S_16C_14 0x3000 +#define R_S_16C_16 0x1000 +#define R_S_16C_20 0x8000 +#define R_S_16C_24_a 0x6000 +#define R_S_16C_24 0x7000 +#define R_S_16C_32 0x2000 + + +/* Processor specific section indices. These sections do not actually + exist. Symbols with a st_shndx field corresponding to one of these + values have a special meaning. */ + +/* Far common symbol. */ +#define SHN_CR16C_FCOMMON 0xff00 +#define SHN_CR16C_NCOMMON 0xff01 + +typedef struct reloc_map +{ + unsigned short cr_reloc_type; /* CR relocation type. */ + bfd_reloc_code_real_type bfd_reloc_enum; /* BFD relocation enum. */ +} RELOC_MAP; + +#endif /* _ELF_CR16C_H */ diff --git a/include/hashtab.h b/include/hashtab.h index f7bd4ae69d..1af7368d33 100644 --- a/include/hashtab.h +++ b/include/hashtab.h @@ -99,7 +99,7 @@ struct htab GTY(()) htab_del del_f; /* Table itself. */ - PTR * GTY ((use_param (""), length ("%h.size"))) entries; + PTR * GTY ((use_param, length ("%h.size"))) entries; /* Current size (in entries) of the hash table */ size_t size; @@ -123,7 +123,7 @@ struct htab GTY(()) htab_free free_f; /* Alternate allocate/free functions, which take an extra argument. */ - PTR GTY((skip (""))) alloc_arg; + PTR GTY((skip)) alloc_arg; htab_alloc_with_arg alloc_with_arg_f; htab_free_with_arg free_with_arg_f; }; diff --git a/include/splay-tree.h b/include/splay-tree.h index 86707fc1d2..e05aeb5afb 100644 --- a/include/splay-tree.h +++ b/include/splay-tree.h @@ -81,21 +81,21 @@ typedef void (*splay_tree_deallocate_fn) PARAMS((void *, void *)); struct splay_tree_node_s GTY(()) { /* The key. */ - splay_tree_key GTY ((use_param1 (""))) key; + splay_tree_key GTY ((use_param1)) key; /* The value. */ - splay_tree_value GTY ((use_param2 (""))) value; + splay_tree_value GTY ((use_param2)) value; /* The left and right children, respectively. */ - splay_tree_node GTY ((use_params (""))) left; - splay_tree_node GTY ((use_params (""))) right; + splay_tree_node GTY ((use_params)) left; + splay_tree_node GTY ((use_params)) right; }; /* The splay tree itself. */ struct splay_tree_s GTY(()) { /* The root of the tree. */ - splay_tree_node GTY ((use_params (""))) root; + splay_tree_node GTY ((use_params)) root; /* The comparision function. */ splay_tree_compare_fn comp; @@ -109,7 +109,7 @@ struct splay_tree_s GTY(()) /* Allocate/free functions, and a data pointer to pass to them. */ splay_tree_allocate_fn allocate; splay_tree_deallocate_fn deallocate; - PTR GTY((skip (""))) allocate_data; + PTR GTY((skip)) allocate_data; }; typedef struct splay_tree_s *splay_tree; diff --git a/libiberty/ChangeLog b/libiberty/ChangeLog index 2dce4d82d0..661ca4b45b 100644 --- a/libiberty/ChangeLog +++ b/libiberty/ChangeLog @@ -1,3 +1,15 @@ +2004-03-31 Richard Henderson <rth@redhat.com> + + * hashtab.c (htab_size): Move to top of file; mark inline. + (htab_elements): Likewise. + (htab_mod, htab_mod_m2): New. + (htab_delete): Refactor htab->size and htab->entries. + (htab_empty): Likewise. + (find_empty_slot_for_expand): Use htab_size, htab_mod, htab_mod_m2. + (htab_find_with_hash, htab_find_slot_with_hash): Likewise. + (htab_clear_slot): Use htab_size, htab_elements. + (htab_traverse_noresize, htab_traverse): Likewise. + 2004-03-17 Ian Lance Taylor <ian@wasabisystems.com> * pex-unix.c (pexecute): Use vfork instead of fork, with diff --git a/libiberty/hashtab.c b/libiberty/hashtab.c index 231fbc0dd7..f7751664f0 100644 --- a/libiberty/hashtab.c +++ b/libiberty/hashtab.c @@ -159,6 +159,44 @@ eq_pointer (p1, p2) return p1 == p2; } +/* Return the current size of given hash table. */ + +inline size_t +htab_size (htab) + htab_t htab; +{ + return htab->size; +} + +/* Return the current number of elements in given hash table. */ + +inline size_t +htab_elements (htab) + htab_t htab; +{ + return htab->n_elements - htab->n_deleted; +} + +/* Compute the primary hash for HASH given HTAB's current size. */ + +static inline hashval_t +htab_mod (hash, htab) + hashval_t hash; + htab_t htab; +{ + return hash % htab_size (htab); +} + +/* Compute the secondary hash for HASH given HTAB's current size. */ + +static inline hashval_t +htab_mod_m2 (hash, htab) + hashval_t hash; + htab_t htab; +{ + return 1 + hash % (htab_size (htab) - 2); +} + /* This function creates table with length slightly longer than given source length. Created hash table is initiated as empty (all the hash table entries are EMPTY_ENTRY). The function returns the @@ -282,22 +320,23 @@ void htab_delete (htab) htab_t htab; { + size_t size = htab_size (htab); + PTR *entries = htab->entries; int i; if (htab->del_f) - for (i = htab->size - 1; i >= 0; i--) - if (htab->entries[i] != EMPTY_ENTRY - && htab->entries[i] != DELETED_ENTRY) - (*htab->del_f) (htab->entries[i]); + for (i = size - 1; i >= 0; i--) + if (entries[i] != EMPTY_ENTRY && entries[i] != DELETED_ENTRY) + (*htab->del_f) (entries[i]); if (htab->free_f != NULL) { - (*htab->free_f) (htab->entries); + (*htab->free_f) (entries); (*htab->free_f) (htab); } else if (htab->free_with_arg_f != NULL) { - (*htab->free_with_arg_f) (htab->alloc_arg, htab->entries); + (*htab->free_with_arg_f) (htab->alloc_arg, entries); (*htab->free_with_arg_f) (htab->alloc_arg, htab); } } @@ -308,15 +347,16 @@ void htab_empty (htab) htab_t htab; { + size_t size = htab_size (htab); + PTR *entries = htab->entries; int i; if (htab->del_f) - for (i = htab->size - 1; i >= 0; i--) - if (htab->entries[i] != EMPTY_ENTRY - && htab->entries[i] != DELETED_ENTRY) - (*htab->del_f) (htab->entries[i]); + for (i = size - 1; i >= 0; i--) + if (entries[i] != EMPTY_ENTRY && entries[i] != DELETED_ENTRY) + (*htab->del_f) (entries[i]); - memset (htab->entries, 0, htab->size * sizeof (PTR)); + memset (entries, 0, size * sizeof (PTR)); } /* Similar to htab_find_slot, but without several unwanted side effects: @@ -331,8 +371,8 @@ find_empty_slot_for_expand (htab, hash) htab_t htab; hashval_t hash; { - size_t size = htab->size; - unsigned int index = hash % size; + hashval_t index = htab_mod (hash, htab); + size_t size = htab_size (htab); PTR *slot = htab->entries + index; hashval_t hash2; @@ -341,7 +381,7 @@ find_empty_slot_for_expand (htab, hash) else if (*slot == DELETED_ENTRY) abort (); - hash2 = 1 + hash % (size - 2); + hash2 = htab_mod_m2 (hash, htab); for (;;) { index += hash2; @@ -431,22 +471,20 @@ htab_find_with_hash (htab, element, hash) const PTR element; hashval_t hash; { - unsigned int index; - hashval_t hash2; + hashval_t index, hash2; size_t size; PTR entry; htab->searches++; - size = htab->size; - index = hash % size; + size = htab_size (htab); + index = htab_mod (hash, htab); entry = htab->entries[index]; if (entry == EMPTY_ENTRY || (entry != DELETED_ENTRY && (*htab->eq_f) (entry, element))) return entry; - hash2 = 1 + hash % (size - 2); - + hash2 = htab_mod_m2 (hash, htab); for (;;) { htab->collisions++; @@ -488,17 +526,19 @@ htab_find_slot_with_hash (htab, element, hash, insert) enum insert_option insert; { PTR *first_deleted_slot; - unsigned int index; - hashval_t hash2; + hashval_t index, hash2; size_t size; PTR entry; - if (insert == INSERT && htab->size * 3 <= htab->n_elements * 4 - && htab_expand (htab) == 0) - return NULL; + size = htab_size (htab); + if (insert == INSERT && size * 3 <= htab->n_elements * 4) + { + if (htab_expand (htab) == 0) + return NULL; + size = htab_size (htab); + } - size = htab->size; - index = hash % size; + index = htab_mod (hash, htab); htab->searches++; first_deleted_slot = NULL; @@ -511,7 +551,7 @@ htab_find_slot_with_hash (htab, element, hash, insert) else if ((*htab->eq_f) (entry, element)) return &htab->entries[index]; - hash2 = 1 + hash % (size - 2); + hash2 = htab_mod_m2 (hash, htab); for (;;) { htab->collisions++; @@ -590,7 +630,7 @@ htab_clear_slot (htab, slot) htab_t htab; PTR *slot; { - if (slot < htab->entries || slot >= htab->entries + htab->size + if (slot < htab->entries || slot >= htab->entries + htab_size (htab) || *slot == EMPTY_ENTRY || *slot == DELETED_ENTRY) abort (); @@ -616,7 +656,7 @@ htab_traverse_noresize (htab, callback, info) PTR *limit; slot = htab->entries; - limit = slot + htab->size; + limit = slot + htab_size (htab); do { @@ -638,30 +678,12 @@ htab_traverse (htab, callback, info) htab_trav callback; PTR info; { - if ((htab->n_elements - htab->n_deleted) * 8 < htab->size) + if (htab_elements (htab) * 8 < htab_size (htab)) htab_expand (htab); htab_traverse_noresize (htab, callback, info); } -/* Return the current size of given hash table. */ - -size_t -htab_size (htab) - htab_t htab; -{ - return htab->size; -} - -/* Return the current number of elements in given hash table. */ - -size_t -htab_elements (htab) - htab_t htab; -{ - return htab->n_elements - htab->n_deleted; -} - /* Return the fraction of fixed collisions during all work with given hash table. */ diff --git a/opcodes/ChangeLog b/opcodes/ChangeLog index 947ee4f6d6..65b0898b0d 100644 --- a/opcodes/ChangeLog +++ b/opcodes/ChangeLog @@ -1,3 +1,12 @@ +2004-03-30 Kazuhiro Inaoka <inaoka.kazuhiro@renesas.com> + + * m32r-asm.c: Regenerate. + +2004-03-29 Stan Shebs <shebs@apple.com> + + * mpw-config.in, mpw-make.sed: Remove MPW support files, no longer + used. + 2004-03-19 Alan Modra <amodra@bigpond.net.au> * aclocal.m4: Regenerate. diff --git a/opcodes/m32r-asm.c b/opcodes/m32r-asm.c index 8c2cc81ea8..87c33f04cd 100644 --- a/opcodes/m32r-asm.c +++ b/opcodes/m32r-asm.c @@ -4,7 +4,7 @@ THIS FILE IS MACHINE GENERATED WITH CGEN. - the resultant file is machine generated, cgen-asm.in isn't -Copyright 1996, 1997, 1998, 1999, 2000, 2001 Free Software Foundation, Inc. +Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2004 Free Software Foundation, Inc. This file is part of the GNU Binutils and GDB, the GNU debugger. @@ -111,7 +111,10 @@ parse_hi16 (cd, strp, opindex, valuep) ++*strp; if (errmsg == NULL && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER) - value = (value >> 16) + (value & 0x8000 ? 1 : 0); + { + value = value + (value & 0x8000 ? 0x10000 : 0); + value >>= 16; + } *valuep = value; return errmsg; } diff --git a/opcodes/mpw-config.in b/opcodes/mpw-config.in deleted file mode 100644 index ff9be9d72f..0000000000 --- a/opcodes/mpw-config.in +++ /dev/null @@ -1,27 +0,0 @@ -# Configuration fragment for opcodes. - -Set target_arch `echo {target_canonical} | sed -e 's/-.*-.*//'` - -Set archname ARCH_{target_arch} - -If "{target_arch}" =~ /m68k/ - Set BFD_MACHINES '"{o}"m68k-dis.c.o "{o}"m68k-opc.c.o' -Else If "{target_arch}" =~ /powerpc/ - Set BFD_MACHINES '"{o}"ppc-dis.c.o "{o}"ppc-opc.c.o' -Else If "{target_arch}" =~ /i386/ - Set BFD_MACHINES '"{o}"i386-dis.c.o' -Else If "{target_arch}" =~ /mips/ - Set BFD_MACHINES '"{o}"mips-dis.c.o "{o}"mips-opc.c.o' -Else If "{target_arch}" =~ /sh/ - Set BFD_MACHINES '"{o}"sh-dis.c.o' -End If - -Echo '# Start from mpw-config.in' > "{o}"mk.tmp -Echo "BFD_MACHINES = " {BFD_MACHINES} >> "{o}"mk.tmp -Echo "ARCHDEFS = -d" {archname} >> "{o}"mk.tmp -Echo '# End from mpw-config.in' >> "{o}"mk.tmp - -Echo '/* config.h. Generated by mpw-configure. */' > "{o}"config.new -Echo '#include "mpw.h"' >> "{o}"config.new - -MoveIfChange "{o}"config.new "{o}"config.h diff --git a/opcodes/mpw-make.sed b/opcodes/mpw-make.sed deleted file mode 100644 index ee604862de..0000000000 --- a/opcodes/mpw-make.sed +++ /dev/null @@ -1,25 +0,0 @@ -# Sed commands to finish translating the opcodes Makefile.in into MPW syntax. - -# Empty HDEFINES. -/HDEFINES/s/@HDEFINES@// - -# Fix pathnames to include directories. -/^INCDIR = /s/^INCDIR = .*$/INCDIR = "{topsrcdir}"include/ -/^CSEARCH = /s/$/ -i "{INCDIR}":mpw: -i ::extra-include:/ - -/BFD_MACHINES/s/@BFD_MACHINES@/{BFD_MACHINES}/ -/archdefs/s/@archdefs@/{ARCHDEFS}/ - -# No PIC foolery in this environment. -/@ALLLIBS@/s/@ALLLIBS@/{TARGETLIB}/ -/@PICLIST@/s/@PICLIST@// -/@PICFLAG@/s/@PICFLAG@// -/^{OFILES} \\Option-f stamp-picdir/,/^$/d - -# Remove the pic trickery from the default build rule. -/^\.c\.o \\Option-f /,/End If/c\ -.c.o \\Option-f .c - -# Remove pic trickery from other rules - aimed at the rule -# for disassemble.o in particular. -/-n "{PICFLAG}"/,/End If/d |