aboutsummaryrefslogtreecommitdiff
path: root/bfd
diff options
context:
space:
mode:
Diffstat (limited to 'bfd')
-rw-r--r--bfd/ChangeLog1086
-rw-r--r--bfd/Makefile.am19
-rw-r--r--bfd/Makefile.in29
-rw-r--r--bfd/aclocal.m410
-rw-r--r--bfd/aout-adobe.c3
-rw-r--r--bfd/aout-target.h9
-rw-r--r--bfd/aout-tic30.c10
-rw-r--r--bfd/archures.c9
-rw-r--r--bfd/bfd-in.h25
-rw-r--r--bfd/bfd-in2.h130
-rw-r--r--bfd/bfd.c27
-rw-r--r--bfd/bfdio.c102
-rw-r--r--bfd/binary.c5
-rw-r--r--bfd/bout.c3
-rw-r--r--bfd/cache.c111
-rw-r--r--bfd/coff-alpha.c5
-rw-r--r--bfd/coff-i386.c45
-rw-r--r--bfd/coff-mips.c1243
-rw-r--r--bfd/coff-rs6000.c6
-rw-r--r--bfd/coff64-rs6000.c6
-rw-r--r--bfd/coffcode.h26
-rw-r--r--bfd/config.bfd24
-rw-r--r--bfd/config.in6
-rwxr-xr-xbfd/configure393
-rw-r--r--bfd/configure.in17
-rw-r--r--bfd/cpu-cr16c.c38
-rw-r--r--bfd/cpu-frv.c5
-rw-r--r--bfd/cpu-m68k.c5
-rw-r--r--bfd/cpu-sh.c19
-rw-r--r--bfd/doc/ChangeLog7
-rw-r--r--bfd/doc/Makefile.in4
-rw-r--r--bfd/doc/bfdint.texi8
-rw-r--r--bfd/ecoff.c43
-rw-r--r--bfd/ecofflink.c49
-rw-r--r--bfd/ecoffswap.h74
-rw-r--r--bfd/elf-bfd.h271
-rw-r--r--bfd/elf-eh-frame.c42
-rw-r--r--bfd/elf-hppa.h50
-rw-r--r--bfd/elf-m10200.c30
-rw-r--r--bfd/elf-m10300.c47
-rw-r--r--bfd/elf.c151
-rw-r--r--bfd/elf32-arm.h292
-rw-r--r--bfd/elf32-avr.c35
-rw-r--r--bfd/elf32-cr16c.c1000
-rw-r--r--bfd/elf32-cris.c110
-rw-r--r--bfd/elf32-d10v.c34
-rw-r--r--bfd/elf32-dlx.c4
-rw-r--r--bfd/elf32-fr30.c51
-rw-r--r--bfd/elf32-frv.c567
-rw-r--r--bfd/elf32-gen.c4
-rw-r--r--bfd/elf32-h8300.c30
-rw-r--r--bfd/elf32-hppa.c60
-rw-r--r--bfd/elf32-i370.c26
-rw-r--r--bfd/elf32-i386.c44
-rw-r--r--bfd/elf32-i860.c34
-rw-r--r--bfd/elf32-ip2k.c7
-rw-r--r--bfd/elf32-iq2000.c13
-rw-r--r--bfd/elf32-m32r.c45
-rw-r--r--bfd/elf32-m68hc1x.c62
-rw-r--r--bfd/elf32-m68hc1x.h4
-rw-r--r--bfd/elf32-m68k.c34
-rw-r--r--bfd/elf32-mcore.c34
-rw-r--r--bfd/elf32-mips.c214
-rw-r--r--bfd/elf32-msp430.c33
-rw-r--r--bfd/elf32-openrisc.c37
-rw-r--r--bfd/elf32-ppc.c51
-rw-r--r--bfd/elf32-s390.c54
-rw-r--r--bfd/elf32-sh.c50
-rw-r--r--bfd/elf32-sh64.c29
-rw-r--r--bfd/elf32-sparc.c62
-rw-r--r--bfd/elf32-v850.c51
-rw-r--r--bfd/elf32-vax.c24
-rw-r--r--bfd/elf32-xstormy16.c38
-rw-r--r--bfd/elf32-xtensa.c152
-rw-r--r--bfd/elf64-alpha.c31
-rw-r--r--bfd/elf64-gen.c5
-rw-r--r--bfd/elf64-hppa.c15
-rw-r--r--bfd/elf64-mmix.c56
-rw-r--r--bfd/elf64-ppc.c51
-rw-r--r--bfd/elf64-s390.c54
-rw-r--r--bfd/elf64-sh64.c47
-rw-r--r--bfd/elf64-sparc.c70
-rw-r--r--bfd/elf64-x86-64.c57
-rw-r--r--bfd/elfarm-nabi.c41
-rw-r--r--bfd/elfcode.h25
-rw-r--r--bfd/elflink.c6744
-rw-r--r--bfd/elflink.h6333
-rw-r--r--bfd/elfxx-ia64.c59
-rw-r--r--bfd/elfxx-mips.c157
-rw-r--r--bfd/elfxx-mips.h4
-rw-r--r--bfd/elfxx-target.h41
-rw-r--r--bfd/hpux-core.c3
-rw-r--r--bfd/i386msdos.c3
-rw-r--r--bfd/i386os9k.c5
-rw-r--r--bfd/ieee.c3
-rw-r--r--bfd/ihex.c3
-rw-r--r--bfd/libaout.h175
-rw-r--r--bfd/libbfd-in.h5
-rw-r--r--bfd/libbfd.h69
-rw-r--r--bfd/libecoff.h36
-rw-r--r--bfd/linker.c18
-rw-r--r--bfd/mach-o.c3
-rw-r--r--bfd/mmo.c3
-rw-r--r--bfd/mpw-config.in86
-rw-r--r--bfd/mpw-make.sed81
-rw-r--r--bfd/netbsd-core.c147
-rw-r--r--bfd/nlm-target.h3
-rw-r--r--bfd/oasys.c3
-rw-r--r--bfd/opncls.c187
-rw-r--r--bfd/pe-i386.c17
-rw-r--r--bfd/pe-mips.c24
-rw-r--r--bfd/peXXigen.c24
-rw-r--r--bfd/pef.c3
-rw-r--r--bfd/pei-i386.c17
-rw-r--r--bfd/po/SRC-POTFILES.in1
-rw-r--r--bfd/po/bfd.pot1135
-rw-r--r--bfd/ppcboot.c3
-rw-r--r--bfd/reloc.c96
-rw-r--r--bfd/section.c124
-rw-r--r--bfd/simple.c40
-rw-r--r--bfd/som.c141
-rw-r--r--bfd/som.h38
-rw-r--r--bfd/srec.c3
-rw-r--r--bfd/stabs.c61
-rw-r--r--bfd/sunos.c1
-rw-r--r--bfd/targets.c10
-rw-r--r--bfd/tekhex.c5
-rw-r--r--bfd/versados.c3
-rw-r--r--bfd/version.h2
-rw-r--r--bfd/vms.c4
-rw-r--r--bfd/xsym.c3
131 files changed, 12916 insertions, 10939 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 8800d4f..e225888 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,7 +1,914 @@
+2004-05-03 Alan Modra <amodra@bigpond.net.au>
+
+ * elf.c (_bfd_elf_rela_local_sym): Set kept_section for excluded
+ SEC_MERGE sections.
+ * elflink.c (elf_link_input_bfd): Adjust output reloc index for
+ those against discarded link-once and SEC_MERGE section symbols.
+
+2004-05-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ * section.c (bfd_get_section_by_name_if): New.
+ * bfd-in2.h: Regenerated.
+
+2004-05-02 Alan Modra <amodra@bigpond.net.au>
+
+ * som.c (som_bfd_is_group_section): Define.
+
+2004-05-01 Alan Modra <amodra@bigpond.net.au>
+
+ * section.c (bfd_make_section_anyway): Copy the whole
+ bfd_hash_entry, not just "next" from existing entry.
+
+2004-04-30 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf.c (bfd_section_from_shdr): Maintain the section order in
+ a section group.
+ (special_sections): Add ".note.GNU-stack".
+ (elf_fake_sections): Handle section group for relocatable
+ link..
+
+2004-04-30 H.J. Lu <hongjiu.lu@intel.com>
+
+ * section.c (bfd_sections_find_if): New.
+ * bfd-in2.h: Regenerated.
+
+2004-04-30 Alan Modra <amodra@bigpond.net.au>
+
+ * section.c (bfd_make_section_anyway): Add all sections to hash tab.
+
+ * elf-bfd.h (bfd_elf_is_group_section): Declare.
+ * elf.c (bfd_elf_is_group_section): New function.
+ * elfxx-target.h (bfd_elfNN_bfd_is_group_section
+ * section.c (bfd_generic_is_group_section): New function.
+ * targets.c (struct bfd_target): Add _bfd_is_group_section field.
+ (BFD_JUMP_TABLE_LINK): Adjust.
+ * aout-adobe.c (aout_32_bfd_is_group_section): Define.
+ * aout-target.h (MY_bfd_is_group_section): Define.
+ * aout-tic30.c (MY_bfd_is_group_section): Define.
+ * bfd.c (bfd_is_group_section): Define.
+ * binary.c (binary_bfd_is_group_section): Define.
+ * bout.c (b_out_bfd_is_group_section): Define.
+ * coff-alpha.c (_bfd_ecoff_bfd_is_group_section): Define.
+ * coff-mips.c (_bfd_ecoff_bfd_is_group_section): Define.
+ * coff-rs6000.c (rs6000coff_vec, pmac_xcoff_vec): Adjust.
+ * coff64-rs6000.c (rs6000coff64_vec, aix5coff64_vec): Adjust.
+ * coffcode.h (coff_bfd_is_group_section): Define.
+ * i386msdos.c (msdos_bfd_is_group_section): Define.
+ * i386os9k.c (os9k_bfd_is_group_section): Define.
+ * ieee.c (ieee_bfd_is_group_section): Define.
+ * ihex.c (ihex_bfd_is_group_section): Define.
+ * libbfd-in.h (_bfd_nolink_bfd_is_group_section): Define.
+ * mach-o.c (bfd_mach_o_bfd_is_group_section): Define.
+ * mmo.c (mmo_bfd_is_group_section): Define.
+ * nlm-target.h (nlm_bfd_is_group_section): Define.
+ * oasys.c (oasys_bfd_is_group_section): Define.
+ * pef.c (bfd_pef_bfd_is_group_section): Define.
+ * ppcboot.c (ppcboot_bfd_is_group_section): Define.
+ * srec.c (srec_bfd_is_group_section): Define.
+ * tekhex.c (tekhex_bfd_is_group_section): Define.
+ * versados.c (versados_bfd_is_group_section): Define.
+ * vms.c (vms_bfd_is_group_section): Define.
+ * xsym.c (bfd_sym_bfd_is_group_section): Define.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Regenerate.
+
+2004-04-30 Alan Modra <amodra@bigpond.net.au>
+
+ * elflink.c (elf_gc_mark): Follow indirect and warning syms.
+
+2004-04-30 Hans-Peter Nilsson <hp@axis.com>
+
+ * configure.in: Update version to 2.15.91.
+ * configure: Regenerate.
+
+2004-04-29 Brian Ford <ford@vss.fsi.com>
+
+ * bfd.c (bfd_get_sign_extend_vma): Add pe[i]-i386 case to DJGPP hack.
+ * coffcode.h (DOT_DEBUG, GNU_LINKONCE_WI): Define.
+ [!COFF_WITH_PE] (sec_to_styp_flags, styp_to_sec_flags): Use them.
+ (coff_compute_section_file_positions) [RS6000COFF_C]: Likewise.
+ [COFF_WITH_PE] (sec_to_styp_flags): Handle DWARF 2/3 .debug* and
+ .gnu.linkonce.wi. sections.
+ * pe-i386.c (COFF_SUPPORT_GNU_LINKONCE): Define.
+ (COFF_SECTION_ALIGNMENT_ENTRIES): Add entries for .debug and
+ .gnu.linkonce.wi..
+ * pei-i386.c (COFF_SUPPORT_GNU_LINKONCE): Likewise.
+ (COFF_SECTION_ALIGNMENT_ENTRIES): Likewise.
+
+2004-04-28 Chris Demetriou <cgd@broadcom.com>
+
+ * reloc.c: Remove BFD_RELOC_PCREL_HI16_S and BFD_RELOC_PCREL_LO16.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Likewise.
+
+2004-04-28 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * som.c (struct som_misc_symbol_info): Add is_comdat, is_common and
+ dup_common fields.
+ (setup_sections): Use som_subspace_dictionary_record struct instead
+ subspace_dictionary_record. Set SEC_LINK_ONCE if subspace is
+ is_comdat, is_common or dup_common.
+ (som_prep_headers): Use som_subspace_dictionary_record struct. Set
+ is_comdat, is_common and dup_common in section subspace_dict from
+ copy_data.
+ (som_begin_writing): Use som_subspace_dictionary_record struct.
+ (som_finish_writing): Likewise.
+ (som_bfd_derive_misc_symbol_info): Add support to set is_comdat,
+ is_common and dup_common flags in info for symbol. Add comment
+ regarding linker support for these fields. Slightly reorganize
+ function.
+ (som_build_and_write_symbol_table): Set is_comdat, is_common and
+ dup_common fields in symbol table from symbol info.
+ (bfd_som_set_subsection_attributes): Add comdat, common and dup_common
+ arguments. Set corresponding fields in copy_data. Change all callers.
+ (som_bfd_ar_write_symbol_stuff): Set dup_common flag in library
+ symbol table.
+ (som_vec): Add SEC_LINK_ONCE to applicable section flags.
+ * som.h (som_subspace_dictionary_record): Define.
+ (som_copyable_section_data_struct): Add is_comdat, is_common and
+ dup_common fields.
+ (som_section_data_struct): Use som_subspace_dictionary_record struct
+ instead of subspace_dictionary_record.
+ (bfd_boolean bfd_som_set_subsection_attributes): Adjust prototype.
+
+2004-04-27 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (xtensa_read_table_entries): Use section _cooked_size
+ if set. Check reloc_done flag before applying relocations. Use
+ output addresses, both when applying relocations and when comparing
+ against the specified section.
+ (elf_xtensa_relocate_section): Use output address to check if dynamic
+ reloc is in a literal pool. Set section's reloc_done flag.
+
+2004-04-27 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-sh64.c (elf_backend_section_flags): New. Defined.
+ (sh64_elf_set_mach_from_flags): Remove the kludge for .cranges
+ section.
+ (sh64_elf_section_flags): New. Set SEC_DEBUGGING for .cranges
+ section.
+
+2004-04-27 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-alpha.c (elf64_alpha_read_ecoff_info): Don't assign
+ structure field removed in 2004-04-24 patch.
+ * elf64-sparc.c (sparc64_elf_plt_sym_val): Warning fix.
+
+ * elf-bfd.h (struct elf_backend_data <elf_backend_section_flags>):
+ Constify hdr arg.
+ * elf32-arm.h (elf32_arm_section_flags): Likewise.
+ * elf64-alpha.c (elf64_alpha_section_flags): Likewise.
+ * elfxx-ia64.c (elfNN_ia64_section_flags): Likewise.
+ * elf.c (_bfd_elf_make_section_from_shdr): Set the bfd_section
+ field before calling elf_backend_section_flags.
+
+2004-04-24 Chris Demetriou <cgd@broadcom.com>
+
+ * elf32-mips.c (elf_mips_gnu_rel_hi16, elf_mips_gnu_rel_lo16)
+ (elf_mips_gnu_pcrel64, elf_mips_gnu_pcrel32): Remove.
+ (bfd_elf32_bfd_reloc_type_lookup): Remove cases for
+ BFD_RELOC_PCREL_HI16_S, BFD_RELOC_PCREL_LO16, BFD_RELOC_64_PCREL,
+ and BFD_RELOC_32_PCREL.
+ (mips_elf32_rtype_to_howto): Remove cases for R_MIPS_GNU_REL_HI16,
+ R_MIPS_GNU_REL_LO16, R_MIPS_PC64, R_MIPS_PC32.
+ * elfxx-mips.c (mips_elf_calculate_relocation): Likewise.
+ (_bfd_mips_elf_lo16_reloc): Remove handling for R_MIPS_GNU_REL_HI16.
+ (mips_elf_next_relocation): Move comment about matching HI/LO
+ relocations to...
+ (_bfd_mips_elf_relocate_section): Here. Remove handling for
+ R_MIPS_GNU_REL_HI16.
+
+2004-04-23 Chris Demetriou <cgd@broadcom.com>
+
+ * coff-mips.c (mips_relhi_reloc, mips_rello_reloc)
+ (mips_switch_reloc, mips_read_relocs, mips_relax_section)
+ (mips_relax_pcrel16, PCREL16_EXPANSION_ADJUSTMENT): Remove.
+ (mips_relocate_hi): Remove now-unused 'adjust' and 'pcrel' arguments,
+ and update comments to reflect current usage.
+ (mips_howto_table): Remove entries for MIPS_R_RELHI, MIPS_R_RELLO,
+ and MIPS_R_SWITCH, as well as several empty entries. Update comment
+ for MIPS_R_PCREL16.
+ (mips_ecoff_swap_reloc_in, mips_ecoff_swap_reloc_out)
+ (mips_adjust_reloc_out, mips_bfd_reloc_type_lookup): Remove support
+ for MIPS_R_SWITCH, MIPS_R_RELLO, and MIPS_R_RELHI relocations.
+ (mips_adjust_reloc_in): Likewise, adjust maximum accepted relocation
+ type number to be MIPS_R_PCREL16.
+ (mips_relocate_section): Remove support for link-time relaxation
+ of branches used by embedded-PIC. Remove support for MIPS_R_SWITCH,
+ MIPS_R_RELLO, and MIPS_R_RELHI relocations.
+ (_bfd_ecoff_bfd_relax_section): Redefine to bfd_generic_relax_section.
+ * ecoff.c (ecoff_indirect_link_order): Remove support for link-time
+ relaxation of branches used by embedded-PIC.
+ * ecofflink.c (bfd_ecoff_debug_accumulate): Likewise.
+ * libecoff.h (struct ecoff_section_tdata): Remove embedded-PIC
+ related members, update comment.
+ * pe-mips.c: Remove disabled (commented-out and #if 0'd)
+ code related to embedded-PIC.
+ * elfxx-mips.c (_bfd_mips_elf_read_ecoff_info): Remove
+ initialization of now-removed 'adjust' member of
+ 'struct ecoff_debug_info'.
+
+2004-04-23 Chris Demetriou <cgd@broadcom.com>
+
+ * elfxx-mips.c (mips_elf_get_global_gotsym_index): Remove.
+
+2004-04-21 Philip Blundell <pb@nexus.co.uk>
+
+ * elf32-arm.h (elf32_arm_check_relocs): Don't output REL32
+ relocs for locally defined symbols during -shared final link.
+ (elf32_arm_final_link_relocate): Likewise.
+
+2004-04-22 Jakub Jelinek <jakub@redhat.com>
+
+ * elf64-x86-64.c (elf64_x86_64_copy_indirect_symbol): Copy also
+ ELF_LINK_POINTER_EQUALITY_NEEDED.
+ (elf64_x86_64_check_relocs): Set ELF_LINK_POINTER_EQUALITY_NEEDED
+ if r_type is not R_X86_64_PC32.
+ (elf64_x86_64_finish_dynamic_symbol): If
+ ELF_LINK_POINTER_EQUALITY_NEEDED is not set, clear st_value of
+ SHN_UNDEF symbols.
+
+2004-04-22 Kaz Kojima <kkojima@rr.iij4u.or.jp>
+
+ * elf32-sh.c (sh_elf_plt_sym_val): New function.
+ (elf_backend_plt_sym_val): Define.
+
+2004-04-22 Andrew Cagney <cagney@redhat.com>
+
+ * opncls.c (bfd_alloc): Fix type of "wanted" in doco.
+
+2004-04-22 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * hpux-core.c (hpux_core_core_file_p): Add cast in call to
+ make_bfd_asection.
+ * som.c (som_set_section_contents): Constantify second argument.
+ (hppa_som_gen_reloc_type): Abort for unsupported selectors.
+ (som_object_setup): Rework to avoid warning.
+ (setup_sections, som_write_fixups, bfd_section_from_som_symbol):
+ Likewise.
+
+2004-04-22 Andrew Cagney <cagney@redhat.com>
+
+ * cache.c (bfd_cache_close): Check for a previously closed file.
+
+2004-04-22 Jakub Jelinek <jakub@redhat.com>
+
+ * bfd.c (bfd_get_synthetic_symtab): Define.
+ * targets.c (BFD_JUMP_TABLE_DYNAMIC): Add
+ NAME##_get_synthetic_symtab.
+ (struct bfd_target): Add _bfd_get_synthetic_symtab.
+ * libbfd-in.h (_bfd_nodynamic_get_synthetic_symtab): Define.
+ * elf-bfd.h (struct elf_backend_data): Add plt_sym_val and
+ relplt_name fields.
+ (_bfd_elf_get_synthetic_symtab): New prototype.
+ * elfcode.h (elf_get_synthetic_symtab): Define.
+ * elf.c (_bfd_elf_get_synthetic_symtab): New function.
+ * elfxx-target.h (bfd_elfNN_get_synthetic_symtab): Define.
+ (elf_backend_plt_sym_val, elf_backend_relplt_name): Define.
+ (elfNN_bed): Add elf_backend_plt_sym_val and elf_backend_relplt_name.
+ * bfd-in2.h: Rebuilt.
+ * libbfd.h: Rebuilt.
+ * elf32-i386.c (elf_i386_plt_sym_val): New function.
+ (elf_backend_plt_sym_val): Define.
+ * elf64-x86-64.c (elf64_x86_64_plt_sym_val): New function.
+ (elf_backend_plt_sym_val): Define.
+ * elf32-s390.c (elf_s390_plt_sym_val): New function.
+ (elf_backend_plt_sym_val): Define.
+ * elf64-s390.c (elf_s390_plt_sym_val): New function.
+ (elf_backend_plt_sym_val): Define.
+ * elf32-sparc (elf32_sparc_plt_sym_val): New function.
+ (elf_backend_plt_sym_val): Define.
+ * elf64-sparc.c (sparc64_elf_plt_sym_val): New function.
+ (elf_backend_plt_sym_val): Define.
+ * elf32-ppc.c (ppc_elf_plt_sym_val): New function.
+ (elf_backend_plt_sym_val): Define.
+ * aout-target.h (MY_get_synthetic_symtab): Define.
+ * aout-tic30.c (MY_get_synthetic_symtab): Define.
+ * coff-rs6000.c (rs6000coff_vec): Add
+ _bfd_nodynamic_get_synthetic_symtab.
+ (pmac_xcoff_vec): Likewise.
+ * coff64-rs6000.c (rs6000coff64_vec): Add
+ _bfd_nodynamic_get_synthetic_symtab.
+ (aix5coff64_vec): Likewise.
+ * sunos.c (MY_get_synthetic_symtab): Define.
+ * vms.c (vms_get_synthetic_symtab): Define.
+
+2004-04-22 Nick Clifton <nickc@redhat.com>
+
+ * bfd.c (bfd_archive_filename): Return NULL on NULL input.
+
+2004-04-22 Peter Barada <peter@the-baradas.com>
+
+ * archures.c: Add bfd_mach_mcfv4e to bfd_architecture.
+ * bfd2-in.h: Regenerate.
+ * cpu-m68k.c: Add 'm68k:mcfv4e' to arch_info_struct[].
+
+2004-04-21 Chris Demetriou <cgd@broadcom.com>
+
+ * coff-mips.c (bfd_mips_ecoff_create_embedded_relocs): Remove.
+ * elf32-mips.c (bfd_mips_elf32_create_embedded_relocs): Remove.
+ * bfd-in.h (bfd_mips_ecoff_create_embedded_relocs)
+ (bfd_mips_elf32_create_embedded_relocs): Remove prototypes
+ * bfd-in2.h: Regenerate.
+
+2004-04-21 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (is_same_value): Add final_static_link argument and
+ require relocations against a weak symbol to reference the same
+ symbol hash entry if not a final, static link.
+ (get_cached_value, add_value_map): Add final_static_link argument.
+ (remove_literals): Pass final_static_link argument as needed.
+
+2004-04-21 Andrew Cagney <cagney@redhat.com>
+
+ * opncls.c (_bfd_new_bfd_contained_in): Copy "iovec".
+ (struct opncls, opncls_btell, opncls_bseek, opncls_bread)
+ (opncls_bwrite, opncls_bclose, opncls_bflush)
+ (opncls_bstat, opncls_iovec, bfd_openr_iovec): Implement a
+ bfd iovec that uses function callbacks.
+ (bfd_close): Use the iovec's bclose.
+ * cache.c (cache_btell, cache_bseek, cache_bread, cache_bwrite)
+ (cache_bclose, cache_bflush, cache_bstat)
+ (cache_iovec): New functions and global variable, implement a
+ cache "iovec", where applicable set bfd_error.
+ (bfd_cache_init, bfd_cache_close): Set/test the bfd's iovec.
+ * bfdio.c (struct bfd_iovec): Define.
+ (real_read): Delete function.
+ (bfd_bread, bfd_bread, bfd_bwrite, bfd_tell, bfd_flush, bfd_stat)
+ (bfd_seek, bfd_get_mtime, bfd_get_size): Use the bfd's "iovec",
+ assume that bread and bwrite set bfd_error.
+ * bfd.c (struct bfd): Add "iovec", update comments.
+ * bfd-in2.h, libbfd.h: Re-generate.
+
+2004-04-21 Andrew Cagney <cagney@redhat.com>
+
+ * libaout.h (enum machine_type): Add M_POWERPC_NETBSD.
+
+2004-04-21 Eric Botcazou <ebotcazou@act-europe.fr>
+
+ * elflink.c (elf_gc_mark_dynamic_ref_symbol): New function.
+ (bfd_elf_gc_sections): Fail if a shared object is being created.
+ Do not fail if dynamic sections have been created. Instead call
+ elf_gc_mark_dynamic_ref_symbol to mark sections that contain
+ dynamically referenced symbols. Do not mark the whole graph
+ rooted at .eh_frame, only the section proper.
+
+2004-04-20 DJ Delorie <dj@redhat.com>
+
+ * reloc.c: Add BFD_RELOC_32_SECREL.
+ * bfd-in2.h: Regenerate.
+ * libbfd.h: Likewise.
+ * coff-i386.c (howto_table) [COFF_WITH_PE]: Add R_SECREL32.
+ (coff_i386_rtype_to_howto) [COFF_WITH_PE]: Handle it.
+ (coff_i386_reloc_type_lookup) [COFF_WITH_PE]: Likewise.
+
+2004-04-19 Jakub Jelinek <jakub@redhat.com>
+
+ * elf32-sparc.c (elf32_sparc_relocate_section): Handle
+ relocs against hidden/protected undefweak symbols properly.
+ * elf64-sparc.c (sparc64_elf_relocate_section): Likewise.
+
+2004-04-18 Mark Kettenis <kettenis@gnu.org>
+
+ * libaout.h (enum machine_type): Add M_POWERPC_NETBSD.
+ * netbsd-core.c (netbsd_core_file_p): Set architecture for PowerPC
+ core files.
+
+2004-04-17 Brian Ford <ford@vss.fsi.com>
+
+ * peXXigen.c (_bfd_XXi_swap_aouthdr_out): Use the first non-zero
+ filepos for the SizeOfHeaders field.
+ (_bfd_XXi_swap_scnhdr_out): Correct section flags lossage on reloc
+ overflow.
+ (_bfd_XXi_swap_sym_in): Remove redundant section flags assignment.
+
+2004-04-16 Alan Modra <amodra@bigpond.net.au>
+
+ * simple.c (bfd_simple_get_relocated_section_contents): Don't
+ change reloc_done. Set and restore _cooked_size.
+ (RETURN): Delete.
+
+2004-04-15 Mark Kettenis <kettenis@gnu.org>
+
+ * netbsd-core.c (netbsd_core_file_p): Set architecture for VAX
+ core files.
+
+2004-04-15 Nick Clifton <nickc@redhat.com>
+
+ * bfd.c (bfd_archive_filename): Catch NULL bfd pointers.
+
+2004-04-15 Alan Modra <amodra@bigpond.net.au>
+
+ * elf64-sparc.c (sparc64_elf_check_relocs): Fix thinko last change.
+
+2004-04-15 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.c (_bfd_elf_merge_symbol): Treat weak as strong only
+ when it is a definition.
+
+2004-04-14 Alan Modra <amodra@bigpond.net.au>
+
+ * elf32-sparc.c (elf32_sparc_relocate_section): Don't abort
+ when statically linking PIC code.
+ * elf64-sparc.c (sparc64_elf_relocate_section): Likewise.
+
+2004-04-11 Thiemo Seufer <seufer@csv.ica.uni-stuttgart.de>
+
+ * config.bfd: Remove mips*-*-mach3* and mips*-dec-mach3* targets.
+ * configure.in: Remove mips-dec-bsd*, mips-dec-mach3*, mips-*-mach3*
+ targets amd aout_mips_big_vec, aout_mips_little_vec target vectors.
+ * configure: Regenerate.
+
+2004-04-08 Richard Sandiford <rsandifo@redhat.com>
+
+ * elflink.c: Include libiberty.h.
+ * Makefile.am (elflink.lo): Depend on libiberty.h.
+ * Makefile.in: Regenerate.
+
+2004-04-06 Daniel Jacobowitz <drow@mvista.com>
+
+ * elfxx-mips.c (MIPS_ELF_STUB_SECTION_NAME): Always use
+ ".MIPS.stubs".
+
+2004-04-05 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfxx-ia64.c (elfNN_ia64_size_dynamic_sections): Always
+ reserve the memory for dynamic linker
+
+2004-04-05 Mark Kettenis <kettenis@gnu.org>
+
+ * netbsd-core.c (CORE_WCOOKIE_OFFSET): New define.
+ (netbsd_core_file_p): Create a .wcookie section for OpenBSD/sparc.
+
+2004-04-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-cr16c.c (elf32_cr16c_relocate_section): Use
+ RELOC_FOR_GLOBAL_SYMBOL.
+ (elf32_cr16c_add_symbol_hook): Remove const from Elf_Internal_Sym.
+
+2004-04-02 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf32-arm.h (elf32_arm_final_link_relocate): Handle
+ R_ARM_ALU* only if OLD_ARM_ABI is not defined.
+
+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.
+ (ppc64_elf_add_symbol_hook): New function.
+ * elf-bfd.h (struct elf_backend_data <elf_add_symbol_hook>): Remove
+ const from Elf_Internal_Sym param.
+ * elflink.c (elf_link_add_object_symbols): Adjust.
+ * elf-hppa.h (elf_hppa_add_symbol_hook): Adjust.
+ * elf32-frv.c (elf32_frv_add_symbol_hook): Adjust.
+ * elf32-i370.c (elf_backend_add_symbol_hook): Adjust.
+ * elf32-m32r.c (m32r_elf_add_symbol_hook): Adjust.
+ * elf32-m68hc1x.c (elf32_m68hc11_add_symbol_hook): Adjust.
+ * elf32-m68hc1x.h (elf32_m68hc11_add_symbol_hook): Adjust.
+ * elf32-ppc.c (ppc_elf_add_symbol_hook): Adjust.
+ * elf32-sh64.c (sh64_elf_add_symbol_hook): Adjust.
+ * elf32-v850.c (v850_elf_add_symbol_hook): Adjust.
+ * elf64-alpha.c (elf64_alpha_add_symbol_hook): Adjust.
+ * elf64-mmix.c (mmix_elf_add_symbol_hook): Adjust.
+ * elf64-sh64.c (sh64_elf64_add_symbol_hook): Adjust.
+ * elf64-sparc.c (sparc64_elf_add_symbol_hook): Adjust.
+ * elfxx-ia64.c (elfNN_ia64_add_symbol_hook): Adjust.
+ * elfxx-mips.c (_bfd_mips_elf_add_symbol_hook): Adjust.
+ * elfxx-mips.h (_bfd_mips_elf_add_symbol_hook): Adjust.
+
+2004-03-26 Alan Modra <amodra@bigpond.net.au>
+
+ * elfxx-target.h (bfd_elfNN_bfd_link_add_symbols): Define.
+ * elf-bfd.h (_bfd_elf_link_add_archive_symbols): Delete.
+ (_bfd_elf_sort_symbol, _bfd_elf_add_dt_needed_tag): Delete.
+ (_bfd_elf_finalize_dynstr, bfd_elf32_bfd_link_add_symbols): Delete.
+ (bfd_elf64_bfd_link_add_symbols): Delete.
+ (bfd_elf_link_add_symbols): Declare.
+ * elfcode.h (elf_bfd_link_add_symbols): Delete.
+ * elflink.c: Include safe-ctype.h.
+ (elf_add_dt_needed_tag): Rename from _bfd_elf_add_dt_needed_tag,
+ make static.
+ (elf_sort_symbol): Rename from _bfd_elf_sort_symbol, make static.
+ (elf_finalize_dynstr): Rename from _bfd_elf_finalize_dynstr, make
+ static.
+ (elf_link_add_archive_symbols): Rename from
+ _bfd_elf_link_add_archive_symbols, make static.
+ (elf_link_add_object_symbols): New function. Corresponding
+ elflink.h function converted to use elf_size_info.
+ (bfd_elf_link_add_symbols): Likewise.
+ (bfd_elf_size_dynamic_sections): Adjust.
+ * elflink.h (elf_bfd_link_add_symbols): Delete.
+ (elf_link_add_object_symbols): Delete.
+ * elf32-gen.c (elf32_generic_link_add_symbols): Call
+ bfd_elf_link_add_symbols.
+ * elf64-gen.c (elf64_generic_link_add_symbols): Likewise.
+
+2004-03-25 Alan Modra <amodra@bigpond.net.au>
+
+ * 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.
+ (_bfd_elf_sort_symbol): Declare.
+ (_bfd_elf_finalize_dynstr): Declare.
+ (RELOC_FOR_GLOBAL_SYM): Formatting.
+ * elfcode.h (elf_add_dynamic_entry): Delete.
+ * elflink.c (_bfd_elf_add_dynamic_entry): New function. Corresponding
+ elflink.h function converted to use elf_size_info.
+ (_bfd_elf_add_dt_needed_tag): Likewise.
+ (_bfd_elf_sort_symbol): Likewise.
+ (_bfd_elf_finalize_dynstr): Likewise.
+ (compute_bucket_count): Likewise.
+ (bfd_elf_size_dynamic_sections): Likewise. Check result of
+ _bfd_elf_strtab_add before calling _bfd_elf_strtab_addref.
+ (elf_adjust_dynstr_offsets, elf_collect_hash_codes): Moved from..
+ * elflink.h: ..here.
+ (sort_symbol, add_dt_needed_tag): Delete.
+ (elf_add_dynamic_entry, elf_finalize_dynstr): Delete.
+ (compute_bucket_count, NAME(bfd_elf,size_dynamic_sections)): Delete.
+ Update all users.
+ * elf32-arm.h (add_dynamic_entry): Update. Remove casts.
+ * elf32-cris.c (add_dynamic_entry): Likewise.
+ * elf32-hppa.c (add_dynamic_entry): Likewise.
+ * elf32-i370.c (add_dynamic_entry): Likewise.
+ * elf32-i386.c (add_dynamic_entry): Likewise.
+ * elf32-m32r.c (add_dynamic_entry): Likewise.
+ * elf32-m68k.c (add_dynamic_entry): Likewise.
+ * elf32-ppc.c (add_dynamic_entry): Likewise.
+ * elf32-s390.c (add_dynamic_entry): Likewise.
+ * elf32-sh.c (add_dynamic_entry): Likewise.
+ * elf32-sparc.c (add_dynamic_entry): Likewise.
+ * elf32-vax.c (add_dynamic_entry): Likewise.
+ * elf32-xtensa.c (add_dynamic_entry): Likewise.
+ * elf64-alpha.c (add_dynamic_entry): Likewise.
+ * elf64-hppa.c (add_dynamic_entry): Likewise.
+ * elf64-ppc.c (add_dynamic_entry): Likewise.
+ * elf64-s390.c (add_dynamic_entry): Likewise.
+ * elf64-sparc.c (add_dynamic_entry): Likewise.
+ * elf64-x86-64.c (add_dynamic_entry): Likewise.
+ * elfxx-ia64.c (add_dynamic_entry): Likewise.
+ * elfxx-mips.c (MIPS_ELF_ADD_DYNAMIC_ENTRY): Likewise.
+ * elf-m10300.c (_bfd_mn10300_elf_size_dynamic_sections): Likewise.
+ * elf32-frv.c (elf32_frv_size_dynamic_sections): Likewise.
+ * elf64-sh64.c (sh64_elf64_size_dynamic_sections): Likewise.
+
+2004-03-23 Paul Brook <paul@codesourcery.com>
+
+ * elf32-arm.h (arm_print_private_bfd_data): Add EABI v3.
+
+2004-03-22 Bob Wilson <bob.wilson@acm.org>
+
+ * elf32-xtensa.c (elf_xtensa_check_relocs): Remove code to read
+ literal tables and check for relocs outside of literal pools.
+ (elf_xtensa_make_sym_local): Don't clear ELF_LINK_NON_GOT_REF flag.
+ (elf_xtensa_fix_refcounts): Don't check ELF_LINK_NON_GOT_REF or
+ set DF_TEXTREL.
+ (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.
+ * linker.c (bfd_wrapped_link_hash_lookup): Handle info->wrap_char.
+
+2004-03-22 Hans-Peter Nilsson <hp@axis.com>
+
+ * elf32-cris.c (cris_elf_relocate_section) <case R_CRIS_16_GOTPLT,
+ R_CRIS_16_GOTPLT>: Also error if there's no PLT for a symbol
+ not defined by the executable, or defined in a DSO.
+ <eliding run-time relocation of .got>: Initialize GOT entry for a
+ function symbol or ELF_LINK_HASH_NEEDS_PLT statically in an
+ executable.
+ (cris_elf_gc_sweep_hook): Improve fallthrough marking.
+ (elf_cris_try_fold_plt_to_got): Improve head comment. Do not fold
+ a PLT reloc to GOT for an executable.
+ (elf_cris_adjust_dynamic_symbol): Only fold a .got.plt entry with
+ .got for a DSO and explain why.
+ (elf_cris_discard_excess_program_dynamics): Also lose GOT-relocs
+ and unreferenced symbols for which a PLT is defined. Adjust
+ dynamic-symbol pruning correspondingly, to make sure we don't lose
+ a dynamic symbol also defined by a DSO.
+
+2004-03-22 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (RELOC_FOR_GLOBAL_SYMBOL): Add input_bfd, input_section
+ and rel args. Group input and output args. Wrap to 80 columns.
+ * elf-m10200.c, elf-m10300.c, elf32-arm.h, elf32-avr.c,
+ elf32-cris.c, elf32-d10v.c, elf32-fr30.c, elf32-h8300.c,
+ elf32-hppa.c, elf32-i386.c, elf32-i860.c, elf32-ip2k.c,
+ elf32-iq2000.c, elf32-m68hc1x.c, elf32-m68k.c, elf32-mcore.c,
+ elf32-msp430.c, elf32-openrisc.c, elf32-ppc.c, elf32-s390.c,
+ elf32-sparc.c, elf32-v850.c, elf32-vax.c, elf32-xstormy16.c,
+ elf32-xtensa.c, elf64-alpha.c, elf64-mmix.c, elf64-ppc.c,
+ elf64-s390.c, elf64-sparc.c, elf64-x86-64.c, elfxx-ia64.c: Update
+ RELOC_FOR_GLOBAL_SYMBOL invocation.
+
+2004-03-20 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf-bfd.h (RELOC_FOR_GLOBAL_SYMBOL): Report error if
+ unresolved symbols in objects aren't allowed.
+
+ * elf-hppa.h (elf_hppa_relocate_section): Properly handle
+ unresolved symbols.
+ (elf_hppa_remark_useless_dynamic_symbols): Likewise.
+ (elf_hppa_unmark_useless_dynamic_symbols):
+ * elf32-frv.c (elf32_frv_relocate_section): Likewise.
+ * elf32-hppa.c (elf32_hppa_size_stubs): Likewise.
+ (elf32_hppa_relocate_section): Likewise.
+ * elf32-i370.c (i370_elf_relocate_section): Likewise.
+ * elf32-m32r.c (m32r_elf_relocate_section): Likewise.
+ * elf32-sh.c (sh_elf_relocate_section): Likewise.
+ * elf64-sh64.c (sh_elf64_relocate_section): Likewise.
+ * elfxx-mips.c (mips_elf_calculate_relocation): Likewise.
+
+ * elf-m10200.c (mn10200_elf_relocate_section): Use
+ RELOC_FOR_GLOBAL_SYMBOL.
+ * elf32-avr.c (elf32_avr_relocate_section): Likewise.
+ * elf32-d10v.c (elf32_d10v_relocate_section): Likewise.
+ * elf32-fr30.c (fr30_elf_relocate_section): Likewise.
+ * elf32-h8300.c (elf32_h8_relocate_section): Likewise.
+ * elf32-i860.c (elf32_i860_relocate_section): Likewise.
+ * elf32-m68hc1x.c (m68hc11_get_relocation_value): Likewise.
+ * elf32-mcore.c (mcore_elf_relocate_section): Likewise.
+ * elf32-msp430.c (elf32_msp430_relocate_section): Likewise.
+ * elf32-openrisc.c (openrisc_elf_relocate_section): Likewise.
+ * elf32-v850.c (v850_elf_relocate_section): Likewise.
+ * elf32-xstormy16.c (xstormy16_elf_relocate_section): Likewise.
+ * elf64-mmix.c (mmix_elf_relocate_section): Likewise.
+
+2004-03-19 John David Anglin <dave.anglin@nrc-cnrc.gc.ca>
+
+ * elf32-hppa.c (elf32_hppa_check_relocs): Handle R_PARISC_PCREL32.
+ (final_link_relocate): Likewise.
+ * elf-hppa.h (elf_hppa_reloc_final_type): Handle selectors for
+ R_PARISC_PCREL32 and R_PARISC_PCREL64 relocations.
+
+2004-03-19 Alan Modra <amodra@bigpond.net.au>
+
+ * Makefile.am: Run "make dep-am".
+ * Makefile.in: Regenerate.
+ * aclocal.m4: Regenerate.
+ * config.in: Regenerate.
+ * po/bfd.pot: Regenerate.
+
+2004-03-19 Alan Modra <amodra@bigpond.net.au>
+ H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.c (_bfd_elf_merge_symbol): Revert last change. Move
+ type and size change code to where it was previously. Remove
+ dt_needed param. Treat old weak syms as strong if new sym is
+ from a shared lib, even when old sym is from another shared
+ lib. Remove unnecessary tests of oldweak and newweak. Correct
+ comments.
+ (_bfd_elf_add_default_symbol): Remove dt_needed param. Update
+ _bfd_elf_merge_symbol calls.
+ * elflink.h (elf_link_add_object_symbols): Update calls. Remove
+ dt_needed local var. Update comments.
+ * elf-bfd.h (_bfd_elf_merge_symbol): Update prototype.
+ (_bfd_elf_add_default_symbol): Likewise.
+
+ * elflink.c (_bfd_elf_merge_symbol): Reinstate code to handle
+ strong syms in one shared object overriding weak syms in another.
+
+2004-03-18 Alan Modra <amodra@bigpond.net.au>
+
+ * elf-bfd.h (struct elf_obj_tdata): Delete dt_soname field. Add
+ dyn_lib_class field. Rearrange for better packing.
+ (elf_dt_soname): Delete.
+ (elf_dyn_lib_class): Define.
+ * elf.c (bfd_elf_set_dt_needed_name): Update comment.
+ (bfd_elf_set_dt_needed_soname): Delete.
+ (bfd_elf_set_dyn_lib_class): New function.
+ * elflink.h (add_dt_needed_tag): New function. Split out from..
+ (elf_link_add_object_symbols): ..here. Rename "name" to "soname".
+ Use elf_dyn_lib_class to set dt_needed and add_needed. Move fallback
+ initialization of soname.
+ (elf_link_check_versioned_symbol): Test elf_dyn_lib_class instead of
+ elf_dt_soname.
+ * bfd-in.h (enum dynamic_lib_link_class): New.
+ (bfd_elf_set_dt_needed_soname): Delete.
+ (bfd_elf_set_dyn_lib_class): Declare.
+ * bfd-in2.h: Regenerate.
+
+ * elflink.c (_bfd_elf_merge_symbol): Rewrite weak symbol handling.
+ (_bfd_elf_add_default_symbol): Remove indirect BFD_ASSERTs.
+ * elflink.h (elf_link_add_object_symbols): Don't clear dt_needed in
+ symbol loop. Instead use add_needed to flag tag as written.
+
+2004-03-17 Nathan Sidwell <nathan@codesourcery.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_merge_private_bfd_data): Correct
+ logic for null_input_bfd detection.
+
2004-03-17 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* config.bfd: Switch sh-*-rtems* to ELF. Add sh-*-rtemscoff*.
+2004-03-16 Mark Kettenis <kettenis@gnu.org>
+
+ * netbsd-core.c (netbsd_core_file_p) [CORE_FPU_OFFSET]: Remove
+ code.
+
2004-03-16 Alan Modra <amodra@bigpond.net.au>
* elflink.c (elf_link_read_relocs_from_section): Don't use
@@ -9,11 +916,6 @@
(_bfd_elf_link_read_relocs): ..to here.
* elf32-ppc.c (ppc_elf_relax_section): Formatting.
- Merge from mainline.
- 2004-02-20 Jakub Jelinek <jakub@redhat.com>
- * elf32-ppc.c (allocate_dynrelocs): Create dynsym for undef weak
- symbols used in PIE relocs.
-
2004-03-16 Alan Modra <amodra@bigpond.net.au>
* configure.in (HOST_64BIT_TYPE, HOST_U_64BIT_TYPE): Don't override
@@ -127,15 +1029,189 @@
netbsd-core.lo.
* configure: Regenerate.
+2004-03-12 Nick Clifton <nickc@redhat.com>
+ Dave Murphy <wintermute2k4@ntlworld.com>
+
+ * elf32-arm.h (elf32_arm_merge_private_bfd_data): Skip most checks
+ if the input bfd does not contain any code.
+
2004-03-09 Steve Ellcey <sje@cup.hp.com>
* elfxx-ia64.c (plt_full_entry): Change ld8 to ld8.acq.
+2004-03-05 Fred Fish <fnf@redhat.com>
+
+ * elfxx-mips.c (_bfd_mips_elf_finish_dynamic_symbol): Just force
+ mips16 symbols to be even rather than testing first for even/odd.
+ (_bfd_mips_elf_link_output_symbol_hook): Ditto.
+
2004-03-05 Nathan Sidwell <nathan@codesourcery.com>
* elf.c (map_sections_to_segments): Ignore .tbss sections for
layout purposes.
+2004-03-03 Alexandre Oliva <aoliva@redhat.com>
+
+ * elflink.c (bfd_elf_record_link_assignment): Mark undefweak and
+ undefined symbols as hash_new.
+
+2003-03-03 Andrew Stubbs <andrew.stubbs@superh.com>
+
+ * archures.c: Add bfd_mach_sh4_nommu_nofpu.
+ * cpu-sh.c: Ditto.
+ * elf32-sh.c: Ditto.
+ * bfd-in2.h: Regenerate.
+
+2004-03-02 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf32-frv.c (struct frv_pic_relocs_info): Added fixups and
+ dynrelocs.
+ (_frv_count_got_plt_entries): Initialize them.
+ (frv_pic_relocs_info_find): Add insert argument. Adjust all
+ callers.
+ (frv_pic_relocs_info_for_global): Likewise.
+ (frv_pic_relocs_info_for_local): Likewise.
+ (frv_pic_merge_early_relocs_info): New.
+ (_frv_resolve_final_relocs_info): Use it in case one entry maps to
+ another.
+ (_frv_add_dyn_reloc): Add entry argument. Adjust all callers.
+ Check that we don't exceed the allocated count for entry.
+ (_frv_add_rofixup): Likewise.
+ (_frv_emit_got_relocs_plt_entries): Adjust for coding standards.
+ (elf32_frv_finish_dynamic_sections): Improve error message in case
+ we emit too few rofixup entries.
+
+2004-03-01 Richard Sandiford <rsandifo@redhat.com>
+
+ * archures.c (bfd_mach_fr450): New.
+ * bfd-in2.h: Regenerate.
+ * cpu-frv.c (arch_info_450): New bfd_arch_info_type.
+ (arch_info_500): Link to it.
+ * elf32-frv.c (elf32_frv_machine, frv_elf_merge_private_bfd_data)
+ (frv_elf_print_private_bfd_data): Handle fr405 and fr450 header flags.
+ (frv_elf_arch_extension_p): New function.
+ (frv_elf_merge_private_bfd_data): Use it.
+
+2004-02-28 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elf-bfd.h (_bfd_elf_link_add_archive_symbols): New prototype.
+
+ * elflink.h (is_global_data_symbol_definition): Moved to
+ elflink.c.
+ (elf_link_is_defined_archive_symbol): Likewise.
+ (elf_link_add_archive_symbols): Likewise. Renamed to
+ _bfd_elf_link_add_archive_symbols.
+
+ * elflink.c (elf_link_is_defined_archive_symbol): Get the size
+ of ELF symbol table entry from backend.
+ (_bfd_elf_link_add_archive_symbols): Call bfd_link_add_symbols
+ instead of elf_link_add_object_symbols.
+
+2004-02-27 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf-bfd.h (struct elf_backend_data): Added
+ elf_backend_can_make_relative_eh_frame,
+ elf_backend_can_make_lsda_relative_eh_frame and
+ elf_backend_encode_eh_address.
+ (_bfd_elf_encode_eh_address): Declare.
+ (_bfd_elf_can_make_relative): Declare.
+ * elf-eh-frame.c (_bfd_elf_discard_section_eh_frame): Use new
+ hooks to decide whether to attempt to make_relative and
+ make_lsda_relative.
+ (_bfd_elf_write_section_eh_frame_hdr): Call encode_eh_address.
+ (_bfd_elf_can_make_relative): New.
+ (_bfd_elf_encode_eh_address): New.
+ * elf32-frv.c (frv_elf_use_relative_eh_frame): New.
+ (frv_elf_encode_eh_address): New.
+ (elf_backend_can_make_relative_eh_frame): Define.
+ (elf_backend_can_make_lsda_relative_eh_frame): Define.
+ (elf_backend_encode_eh_address): Define.
+ * elfxx-target.h
+ (elf_backend_can_make_relative_eh_frame): Define.
+ (elf_backend_can_make_lsda_relative_eh_frame): Define.
+ (elf_backend_encode_eh_address): Define.
+ (elfNN_bed): Add them.
+
+2004-02-27 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf32-frv.c (elf32_frv_howto_table) <R_FRV_LABEL16>: Set
+ complain_on_overflow to signed.
+
+2004-02-27 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.h (sort_symbol): New.
+ (elf_link_add_object_symbols): Use a sorted symbol array for
+ weakdef.
+
+2004-02-27 Jakub Jelinek <jakub@redhat.com>
+
+ * elf32-s390.c (allocate_dynrelocs): Use SYMBOL_REFERENCES_LOCAL
+ for pc relative relocs.
+ (elf_s390_relocate_section): Likewise.
+ * elf64-s390.c (allocate_dynrelocs): Use SYMBOL_REFERENCES_LOCAL
+ for pc relative relocs.
+ (elf_s390_relocate_section): Likewise.
+
+2004-02-26 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfxx-ia64.c (elfNN_ia64_check_relocs): Fix call to
+ count_dyn_reloc.
+
+2004-02-25 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elfxx-ia64.c (elfNN_ia64_dyn_reloc_entry): Add the reltext.
+ field to track if a relocation is against readonly section.
+ (count_dyn_reloc): Take a new argument for rent->reltext.
+ (elfNN_ia64_check_relocs): Adjust call to count_dyn_reloc.
+ (get_reloc_section): Don't set ia64_info->reltext here.
+ (allocate_dynrel_entries): Set ia64_info->reltext here.
+
+2004-02-24 Alexandre Oliva <aoliva@redhat.com>
+
+ * elf32-frv.c (FRV_SYM_LOCAL): Weak undefined doesn't imply local.
+ (_frv_emit_got_relocs_plt_entries): Decay relocation to protected
+ function's descriptor to symbol+offset, and map local undefweak
+ symbol to NULL function descriptor.
+ (elf32_frv_relocate_section): Likewise.
+
+2004-02-23 Mark Kettenis <kettenis@gnu.org>
+
+ * libaout.h (enum machine_type): Add M_SPARC64_NETBSD and
+ M_X86_64_NETBSD.
+ * netbsd-core.c (M_SPARC64_OPENBSD): Define.
+ (netbsd_core_file_p): Set architecture from machine ID for
+ selected machines.
+
+2004-02-23 Jakub Jelinek <jakub@redhat.com>
+
+ * elflink.h (size_dynamic_sections): If not adding DT_FLAGS and
+ DF_BIND_NOW is set in info->flags, create DT_BIND_NOW dynamic entry.
+
+2004-02-21 H.J. Lu <hongjiu.lu@intel.com>
+
+ * elflink.c (_bfd_elf_merge_symbol): Properly handle undefined
+ symbols with non-default visibility.
+
+2004-02-21 Danny Smith <daanysmith@users.sourceforge.net>
+
+ * peXXigen.c (_bfd_XXi_swap_scnhdr_out): Clear
+ IMAGE_SCN_MEM_WRITE on known sections only.
+
+2004-02-20 Jakub Jelinek <jakub@redhat.com>
+
+ * elf32-ppc.c (allocate_dynrelocs): Create dynsym for undef weak
+ symbols used in PIE relocs.
+
+2004-02-19 Jakub Jelinek <jakub@redhat.com>
+
+ * elf32-sparc.c (elf32_sparc_finish_dynamic_sections): Clear
+ .plt sh_entsize.
+
+2004-02-18 Daniel Jacobowitz <drow@mvista.com>
+
+ * configure.in: Update version to 2.15.90.
+ * configure: Regenerate.
+
2004-02-17 Daniel Jacobowitz <drow@mvista.com>
Richard Sandiford <rsandifo@redhat.com>
diff --git a/bfd/Makefile.am b/bfd/Makefile.am
index 3a2d43e..c395d32 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 \
@@ -1160,7 +1169,7 @@ elf32-fr30.lo: elf32-fr30.c $(INCDIR)/filenames.h elf-bfd.h \
elf32-frv.lo: elf32-frv.c $(INCDIR)/filenames.h elf-bfd.h \
$(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
$(INCDIR)/bfdlink.h $(INCDIR)/elf/frv.h $(INCDIR)/elf/reloc-macros.h \
- elf32-target.h
+ $(INCDIR)/elf/dwarf2.h $(INCDIR)/hashtab.h elf32-target.h
elf32-gen.lo: elf32-gen.c $(INCDIR)/filenames.h elf-bfd.h \
$(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
$(INCDIR)/bfdlink.h elf32-target.h
@@ -1310,10 +1319,10 @@ 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
+ $(INCDIR)/elf/external.h $(INCDIR)/libiberty.h
elf-strtab.lo: elf-strtab.c $(INCDIR)/filenames.h elf-bfd.h \
$(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
$(INCDIR)/bfdlink.h $(INCDIR)/hashtab.h $(INCDIR)/libiberty.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 b3bf65b..4d4d784 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
@@ -116,8 +116,10 @@ WIN32LIBADD = @WIN32LIBADD@
all_backends = @all_backends@
bfd_backends = @bfd_backends@
bfd_default_target_size = @bfd_default_target_size@
+bfd_file_ptr = @bfd_file_ptr@
bfd_libs = @bfd_libs@
bfd_machines = @bfd_machines@
+bfd_ufile_ptr = @bfd_ufile_ptr@
bfd_version = @bfd_version@
bfd_version_string = @bfd_version_string@
l = @l@
@@ -181,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 \
@@ -238,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 \
@@ -341,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 \
@@ -507,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 \
@@ -723,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 \
@@ -812,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)
@@ -941,7 +947,7 @@ libbfd.la: $(libbfd_la_OBJECTS) $(libbfd_la_DEPENDENCIES)
all-recursive install-data-recursive install-exec-recursive \
installdirs-recursive install-recursive uninstall-recursive install-info-recursive \
check-recursive installcheck-recursive info-recursive dvi-recursive:
- @set fnord $$MAKEFLAGS; amf=$$2; \
+ @set fnord $(MAKEFLAGS); amf=$$2; \
dot_seen=no; \
target=`echo $@ | sed s/-recursive//`; \
list='$(SUBDIRS)'; for subdir in $$list; do \
@@ -961,7 +967,7 @@ check-recursive installcheck-recursive info-recursive dvi-recursive:
mostlyclean-recursive clean-recursive distclean-recursive \
maintainer-clean-recursive:
- @set fnord $$MAKEFLAGS; amf=$$2; \
+ @set fnord $(MAKEFLAGS); amf=$$2; \
dot_seen=no; \
rev=''; list='$(SUBDIRS)'; for subdir in $$list; do \
rev="$$subdir $$rev"; \
@@ -1450,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
@@ -1672,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 \
@@ -1695,7 +1706,7 @@ elf32-fr30.lo: elf32-fr30.c $(INCDIR)/filenames.h elf-bfd.h \
elf32-frv.lo: elf32-frv.c $(INCDIR)/filenames.h elf-bfd.h \
$(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
$(INCDIR)/bfdlink.h $(INCDIR)/elf/frv.h $(INCDIR)/elf/reloc-macros.h \
- elf32-target.h
+ $(INCDIR)/elf/dwarf2.h $(INCDIR)/hashtab.h elf32-target.h
elf32-gen.lo: elf32-gen.c $(INCDIR)/filenames.h elf-bfd.h \
$(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
$(INCDIR)/bfdlink.h elf32-target.h
@@ -1845,10 +1856,10 @@ 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
+ $(INCDIR)/elf/external.h $(INCDIR)/libiberty.h
elf-strtab.lo: elf-strtab.c $(INCDIR)/filenames.h elf-bfd.h \
$(INCDIR)/elf/common.h $(INCDIR)/elf/internal.h $(INCDIR)/elf/external.h \
$(INCDIR)/bfdlink.h $(INCDIR)/hashtab.h $(INCDIR)/libiberty.h
@@ -2127,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/aclocal.m4 b/bfd/aclocal.m4
index 9d27670..a97b35f 100644
--- a/bfd/aclocal.m4
+++ b/bfd/aclocal.m4
@@ -13,7 +13,7 @@ dnl PARTICULAR PURPOSE.
sinclude(../config/accross.m4)
dnl See whether we need to use fopen-bin.h rather than fopen-same.h.
-AC_DEFUN(BFD_BINARY_FOPEN,
+AC_DEFUN([BFD_BINARY_FOPEN],
[AC_REQUIRE([AC_CANONICAL_SYSTEM])
case "${host}" in
changequote(,)dnl
@@ -23,7 +23,7 @@ changequote([,])dnl
esac])dnl
dnl Get a default for CC_FOR_BUILD to put into Makefile.
-AC_DEFUN(BFD_CC_FOR_BUILD,
+AC_DEFUN([BFD_CC_FOR_BUILD],
[# Put a plausible default for CC_FOR_BUILD in Makefile.
if test -z "$CC_FOR_BUILD"; then
if test "x$cross_compiling" = "xno"; then
@@ -56,7 +56,7 @@ fi
AC_SUBST(EXEEXT_FOR_BUILD)])dnl
dnl See whether we need a declaration for a function.
-AC_DEFUN(BFD_NEED_DECLARATION,
+AC_DEFUN([BFD_NEED_DECLARATION],
[AC_MSG_CHECKING([whether $1 must be declared])
AC_CACHE_VAL(bfd_cv_decl_needed_$1,
[AC_TRY_COMPILE([
@@ -85,7 +85,7 @@ fi
dnl Check for existence of a type $1 in sys/procfs.h
-AC_DEFUN(BFD_HAVE_SYS_PROCFS_TYPE,
+AC_DEFUN([BFD_HAVE_SYS_PROCFS_TYPE],
[AC_MSG_CHECKING([for $1 in sys/procfs.h])
AC_CACHE_VAL(bfd_cv_have_sys_procfs_type_$1,
[AC_TRY_COMPILE([
@@ -105,7 +105,7 @@ AC_DEFUN(BFD_HAVE_SYS_PROCFS_TYPE,
dnl Check for existence of member $2 in type $1 in sys/procfs.h
-AC_DEFUN(BFD_HAVE_SYS_PROCFS_TYPE_MEMBER,
+AC_DEFUN([BFD_HAVE_SYS_PROCFS_TYPE_MEMBER],
[AC_MSG_CHECKING([for $1.$2 in sys/procfs.h])
AC_CACHE_VAL(bfd_cv_have_sys_procfs_type_member_$1_$2,
[AC_TRY_COMPILE([
diff --git a/bfd/aout-adobe.c b/bfd/aout-adobe.c
index 052e938..c13f80f 100644
--- a/bfd/aout-adobe.c
+++ b/bfd/aout-adobe.c
@@ -1,6 +1,6 @@
/* BFD back-end for a.out.adobe binaries.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
- 2002, 2003
+ 2002, 2003, 2004
Free Software Foundation, Inc.
Written by Cygnus Support. Based on bout.c.
@@ -517,6 +517,7 @@ aout_adobe_sizeof_headers (ignore_abfd, ignore)
#define aout_32_bfd_relax_section bfd_generic_relax_section
#define aout_32_bfd_gc_sections bfd_generic_gc_sections
#define aout_32_bfd_merge_sections bfd_generic_merge_sections
+#define aout_32_bfd_is_group_section bfd_generic_is_group_section
#define aout_32_bfd_discard_group bfd_generic_discard_group
#define aout_32_bfd_link_hash_table_create \
_bfd_generic_link_hash_table_create
diff --git a/bfd/aout-target.h b/bfd/aout-target.h
index d8cad54..80513c7 100644
--- a/bfd/aout-target.h
+++ b/bfd/aout-target.h
@@ -1,6 +1,6 @@
/* Define a target vector and some small routines for a variant of a.out.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003
+ 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@@ -513,6 +513,9 @@ MY_bfd_final_link (abfd, info)
#ifndef MY_bfd_merge_sections
#define MY_bfd_merge_sections bfd_generic_merge_sections
#endif
+#ifndef MY_bfd_is_group_section
+#define MY_bfd_is_group_section bfd_generic_is_group_section
+#endif
#ifndef MY_bfd_discard_group
#define MY_bfd_discard_group bfd_generic_discard_group
#endif
@@ -584,6 +587,10 @@ MY_bfd_final_link (abfd, info)
#define MY_canonicalize_dynamic_symtab \
_bfd_nodynamic_canonicalize_dynamic_symtab
#endif
+#ifndef MY_get_synthetic_symtab
+#define MY_get_synthetic_symtab \
+ _bfd_nodynamic_get_synthetic_symtab
+#endif
#ifndef MY_get_dynamic_reloc_upper_bound
#define MY_get_dynamic_reloc_upper_bound \
_bfd_nodynamic_get_dynamic_reloc_upper_bound
diff --git a/bfd/aout-tic30.c b/bfd/aout-tic30.c
index 1f37b99..1ae0ebf 100644
--- a/bfd/aout-tic30.c
+++ b/bfd/aout-tic30.c
@@ -1,5 +1,6 @@
/* BFD back-end for TMS320C30 a.out binaries.
- Copyright 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
Contributed by Steven Haworth (steve@pm.cse.rmit.edu.au)
This file is part of BFD, the Binary File Descriptor library.
@@ -969,6 +970,9 @@ tic30_aout_set_arch_mach (abfd, arch, machine)
#ifndef MY_bfd_merge_sections
#define MY_bfd_merge_sections bfd_generic_merge_sections
#endif
+#ifndef MY_bfd_is_group_section
+#define MY_bfd_is_group_section bfd_generic_is_group_section
+#endif
#ifndef MY_bfd_discard_group
#define MY_bfd_discard_group bfd_generic_discard_group
#endif
@@ -1040,6 +1044,10 @@ tic30_aout_set_arch_mach (abfd, arch, machine)
#define MY_canonicalize_dynamic_symtab \
_bfd_nodynamic_canonicalize_dynamic_symtab
#endif
+#ifndef MY_get_synthetic_symtab
+#define MY_get_synthetic_symtab \
+ _bfd_nodynamic_get_synthetic_symtab
+#endif
#ifndef MY_get_dynamic_reloc_upper_bound
#define MY_get_dynamic_reloc_upper_bound \
_bfd_nodynamic_get_dynamic_reloc_upper_bound
diff --git a/bfd/archures.c b/bfd/archures.c
index f8aeeef..027ac6a 100644
--- a/bfd/archures.c
+++ b/bfd/archures.c
@@ -1,6 +1,6 @@
/* BFD library support routines for architectures.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003
+ 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Hacked by John Gilmore and Steve Chamberlain of Cygnus Support.
@@ -85,6 +85,7 @@ DESCRIPTION
.#define bfd_mach_mcf5307 11
.#define bfd_mach_mcf5407 12
.#define bfd_mach_mcf528x 13
+.#define bfd_mach_mcfv4e 14
. bfd_arch_vax, {* DEC Vax *}
. bfd_arch_i960, {* Intel 960 *}
. {* The order of the following is important.
@@ -230,6 +231,7 @@ DESCRIPTION
.#define bfd_mach_sh3e 0x3e
.#define bfd_mach_sh4 0x40
.#define bfd_mach_sh4_nofpu 0x41
+.#define bfd_mach_sh4_nommu_nofpu 0x42
.#define bfd_mach_sh4a 0x4a
.#define bfd_mach_sh4a_nofpu 0x4b
.#define bfd_mach_sh4al_dsp 0x4d
@@ -285,6 +287,7 @@ DESCRIPTION
.#define bfd_mach_frvsimple 2
.#define bfd_mach_fr300 300
.#define bfd_mach_fr400 400
+.#define bfd_mach_fr450 450
.#define bfd_mach_frvtomcat 499 {* fr500 prototype *}
.#define bfd_mach_fr500 500
.#define bfd_mach_fr550 550
@@ -305,6 +308,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
@@ -373,6 +378,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;
@@ -433,6 +439,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 37df5f2..a3330e8 100644
--- a/bfd/bfd-in.h
+++ b/bfd/bfd-in.h
@@ -587,8 +587,6 @@ extern bfd_boolean bfd_ecoff_write_accumulated_debug
(void *handle, bfd *abfd, struct ecoff_debug_info *debug,
const struct ecoff_debug_swap *swap,
struct bfd_link_info *info, file_ptr where);
-extern bfd_boolean bfd_mips_ecoff_create_embedded_relocs
- (bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *, char **);
/* Externally visible ELF routines. */
@@ -599,29 +597,30 @@ struct bfd_link_needed_list
const char *name;
};
+enum dynamic_lib_link_class {
+ DYN_NORMAL = 0,
+ DYN_AS_NEEDED = 1,
+ DYN_DT_NEEDED = 2
+};
+
extern bfd_boolean bfd_elf_record_link_assignment
(bfd *, struct bfd_link_info *, const char *, bfd_boolean);
extern struct bfd_link_needed_list *bfd_elf_get_needed_list
(bfd *, struct bfd_link_info *);
extern bfd_boolean bfd_elf_get_bfd_needed_list
(bfd *, struct bfd_link_needed_list **);
-extern bfd_boolean bfd_elf32_size_dynamic_sections
- (bfd *, const char *, const char *, const char *, const char * const *,
- struct bfd_link_info *, struct bfd_section **, struct bfd_elf_version_tree *);
-extern bfd_boolean bfd_elf64_size_dynamic_sections
+extern bfd_boolean bfd_elf_size_dynamic_sections
(bfd *, const char *, const char *, const char *, const char * const *,
struct bfd_link_info *, struct bfd_section **, struct bfd_elf_version_tree *);
extern void bfd_elf_set_dt_needed_name
(bfd *, const char *);
-extern void bfd_elf_set_dt_needed_soname
- (bfd *, const char *);
extern const char *bfd_elf_get_dt_soname
(bfd *);
+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
@@ -669,8 +668,6 @@ extern struct bfd_section *_bfd_elf_tls_setup
extern bfd_boolean bfd_m68k_elf32_create_embedded_relocs
(bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *, char **);
-extern bfd_boolean bfd_mips_elf32_create_embedded_relocs
- (bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *, char **);
/* SunOS shared library support routines for the linker. */
@@ -785,7 +782,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 2d06fda..c246356 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -594,8 +594,6 @@ extern bfd_boolean bfd_ecoff_write_accumulated_debug
(void *handle, bfd *abfd, struct ecoff_debug_info *debug,
const struct ecoff_debug_swap *swap,
struct bfd_link_info *info, file_ptr where);
-extern bfd_boolean bfd_mips_ecoff_create_embedded_relocs
- (bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *, char **);
/* Externally visible ELF routines. */
@@ -606,29 +604,30 @@ struct bfd_link_needed_list
const char *name;
};
+enum dynamic_lib_link_class {
+ DYN_NORMAL = 0,
+ DYN_AS_NEEDED = 1,
+ DYN_DT_NEEDED = 2
+};
+
extern bfd_boolean bfd_elf_record_link_assignment
(bfd *, struct bfd_link_info *, const char *, bfd_boolean);
extern struct bfd_link_needed_list *bfd_elf_get_needed_list
(bfd *, struct bfd_link_info *);
extern bfd_boolean bfd_elf_get_bfd_needed_list
(bfd *, struct bfd_link_needed_list **);
-extern bfd_boolean bfd_elf32_size_dynamic_sections
- (bfd *, const char *, const char *, const char *, const char * const *,
- struct bfd_link_info *, struct bfd_section **, struct bfd_elf_version_tree *);
-extern bfd_boolean bfd_elf64_size_dynamic_sections
+extern bfd_boolean bfd_elf_size_dynamic_sections
(bfd *, const char *, const char *, const char *, const char * const *,
struct bfd_link_info *, struct bfd_section **, struct bfd_elf_version_tree *);
extern void bfd_elf_set_dt_needed_name
(bfd *, const char *);
-extern void bfd_elf_set_dt_needed_soname
- (bfd *, const char *);
extern const char *bfd_elf_get_dt_soname
(bfd *);
+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
@@ -676,8 +675,6 @@ extern struct bfd_section *_bfd_elf_tls_setup
extern bfd_boolean bfd_m68k_elf32_create_embedded_relocs
(bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *, char **);
-extern bfd_boolean bfd_mips_elf32_create_embedded_relocs
- (bfd *, struct bfd_link_info *, struct bfd_section *, struct bfd_section *, char **);
/* SunOS shared library support routines for the linker. */
@@ -792,7 +789,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 *);
@@ -838,6 +835,18 @@ bfd *bfd_fdopenr (const char *filename, const char *target, int fd);
bfd *bfd_openstreamr (const char *, const char *, void *);
+bfd *bfd_openr_iovec (const char *filename, const char *target,
+ void *(*open) (struct bfd *nbfd,
+ void *open_closure),
+ void *open_closure,
+ file_ptr (*pread) (struct bfd *nbfd,
+ void *stream,
+ void *buf,
+ file_ptr nbytes,
+ file_ptr offset),
+ int (*close) (struct bfd *nbfd,
+ void *stream));
+
bfd *bfd_openw (const char *filename, const char *target);
bfd_boolean bfd_close (bfd *abfd);
@@ -1424,6 +1433,12 @@ void bfd_section_list_clear (bfd *);
asection *bfd_get_section_by_name (bfd *abfd, const char *name);
+asection *bfd_get_section_by_name_if
+ (bfd *abfd,
+ const char *name,
+ bfd_boolean (*func) (bfd *abfd, asection *sect, void *obj),
+ void *obj);
+
char *bfd_get_unique_section_name
(bfd *abfd, const char *templat, int *count);
@@ -1441,6 +1456,11 @@ void bfd_map_over_sections
void (*func) (bfd *abfd, asection *sect, void *obj),
void *obj);
+asection *bfd_sections_find_if
+ (bfd *abfd,
+ bfd_boolean (*func) (bfd *abfd, asection *sect, void *obj),
+ void *obj);
+
bfd_boolean bfd_set_section_size
(bfd *abfd, asection *sec, bfd_size_type val);
@@ -1461,6 +1481,8 @@ bfd_boolean bfd_copy_private_section_data
void _bfd_strip_section_from_output
(struct bfd_link_info *info, asection *section);
+bfd_boolean bfd_generic_is_group_section (bfd *, const asection *sec);
+
bfd_boolean bfd_generic_discard_group (bfd *abfd, asection *group);
/* Extracted from archures.c. */
@@ -1482,6 +1504,7 @@ enum bfd_architecture
#define bfd_mach_mcf5307 11
#define bfd_mach_mcf5407 12
#define bfd_mach_mcf528x 13
+#define bfd_mach_mcfv4e 14
bfd_arch_vax, /* DEC Vax */
bfd_arch_i960, /* Intel 960 */
/* The order of the following is important.
@@ -1627,6 +1650,7 @@ enum bfd_architecture
#define bfd_mach_sh3e 0x3e
#define bfd_mach_sh4 0x40
#define bfd_mach_sh4_nofpu 0x41
+#define bfd_mach_sh4_nommu_nofpu 0x42
#define bfd_mach_sh4a 0x4a
#define bfd_mach_sh4a_nofpu 0x4b
#define bfd_mach_sh4al_dsp 0x4d
@@ -1682,6 +1706,7 @@ enum bfd_architecture
#define bfd_mach_frvsimple 2
#define bfd_mach_fr300 300
#define bfd_mach_fr400 400
+#define bfd_mach_fr450 450
#define bfd_mach_frvtomcat 499 /* fr500 prototype */
#define bfd_mach_fr500 500
#define bfd_mach_fr550 550
@@ -1702,6 +1727,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
@@ -2022,6 +2049,9 @@ The 24-bit relocation is used in some Intel 960 configurations. */
BFD_RELOC_12_PCREL,
BFD_RELOC_8_PCREL,
+/* Section relative relocations. Some targets need this for DWARF2. */
+ BFD_RELOC_32_SECREL,
+
/* For ELF. */
BFD_RELOC_32_GOT_PCREL,
BFD_RELOC_16_GOT_PCREL,
@@ -2272,12 +2302,6 @@ to compensate for the borrow when the low bits are added. */
/* Low 16 bits. */
BFD_RELOC_LO16,
-/* Like BFD_RELOC_HI16_S, but PC relative. */
- BFD_RELOC_PCREL_HI16_S,
-
-/* Like BFD_RELOC_LO16, but PC relative. */
- BFD_RELOC_PCREL_LO16,
-
/* Relocation against a MIPS literal section. */
BFD_RELOC_MIPS_LITERAL,
@@ -3340,6 +3364,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,
@@ -3658,14 +3724,10 @@ struct bfd
/* A pointer to the target jump table. */
const struct bfd_target *xvec;
- /* To avoid dragging too many header files into every file that
- includes `<<bfd.h>>', IOSTREAM has been declared as a "char *",
- and MTIME as a "long". Their correct types, to which they
- are cast when used, are "FILE *" and "time_t". The iostream
- is the result of an fopen on the filename. However, if the
- BFD_IN_MEMORY flag is set, then iostream is actually a pointer
- to a bfd_in_memory struct. */
+ /* The IOSTREAM, and corresponding IO vector that provide access
+ to the file backing the BFD. */
void *iostream;
+ const struct bfd_iovec *iovec;
/* Is the file descriptor being cached? That is, can it be closed as
needed, and re-opened when accessed later? */
@@ -3927,6 +3989,9 @@ bfd_boolean bfd_set_private_flags (bfd *abfd, flagword flags);
#define bfd_merge_sections(abfd, link_info) \
BFD_SEND (abfd, _bfd_merge_sections, (abfd, link_info))
+#define bfd_is_group_section(abfd, sec) \
+ BFD_SEND (abfd, _bfd_is_group_section, (abfd, sec))
+
#define bfd_discard_group(abfd, sec) \
BFD_SEND (abfd, _bfd_discard_group, (abfd, sec))
@@ -3957,6 +4022,9 @@ bfd_boolean bfd_set_private_flags (bfd *abfd, flagword flags);
#define bfd_canonicalize_dynamic_symtab(abfd, asymbols) \
BFD_SEND (abfd, _bfd_canonicalize_dynamic_symtab, (abfd, asymbols))
+#define bfd_get_synthetic_symtab(abfd, dynsyms, ret) \
+ BFD_SEND (abfd, _bfd_get_synthetic_symtab, (abfd, dynsyms, ret))
+
#define bfd_get_dynamic_reloc_upper_bound(abfd) \
BFD_SEND (abfd, _bfd_get_dynamic_reloc_upper_bound, (abfd))
@@ -4294,6 +4362,7 @@ typedef struct bfd_target
NAME##_bfd_link_split_section, \
NAME##_bfd_gc_sections, \
NAME##_bfd_merge_sections, \
+ NAME##_bfd_is_group_section, \
NAME##_bfd_discard_group
int (*_bfd_sizeof_headers) (bfd *, bfd_boolean);
@@ -4331,6 +4400,9 @@ typedef struct bfd_target
/* Attempt to merge SEC_MERGE sections. */
bfd_boolean (*_bfd_merge_sections) (bfd *, struct bfd_link_info *);
+ /* Is this section a member of a group? */
+ bfd_boolean (*_bfd_is_group_section) (bfd *, const struct bfd_section *);
+
/* Discard members of a group. */
bfd_boolean (*_bfd_discard_group) (bfd *, struct bfd_section *);
@@ -4338,6 +4410,7 @@ typedef struct bfd_target
#define BFD_JUMP_TABLE_DYNAMIC(NAME) \
NAME##_get_dynamic_symtab_upper_bound, \
NAME##_canonicalize_dynamic_symtab, \
+ NAME##_get_synthetic_symtab, \
NAME##_get_dynamic_reloc_upper_bound, \
NAME##_canonicalize_dynamic_reloc
@@ -4346,6 +4419,9 @@ typedef struct bfd_target
/* Read in the dynamic symbols. */
long (*_bfd_canonicalize_dynamic_symtab)
(bfd *, struct bfd_symbol **);
+ /* Create synthetized symbols. */
+ long (*_bfd_get_synthetic_symtab)
+ (bfd *, struct bfd_symbol **, struct bfd_symbol **);
/* Get the amount of memory required to hold the dynamic relocs. */
long (*_bfd_get_dynamic_reloc_upper_bound) (bfd *);
/* Read in the dynamic relocs. */
diff --git a/bfd/bfd.c b/bfd/bfd.c
index d37a48b..e184781 100644
--- a/bfd/bfd.c
+++ b/bfd/bfd.c
@@ -1,6 +1,6 @@
/* Generic BFD library interface and support routines.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003
+ 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Written by Cygnus Support.
@@ -45,14 +45,10 @@ CODE_FRAGMENT
. {* A pointer to the target jump table. *}
. const struct bfd_target *xvec;
.
-. {* To avoid dragging too many header files into every file that
-. includes `<<bfd.h>>', IOSTREAM has been declared as a "char *",
-. and MTIME as a "long". Their correct types, to which they
-. are cast when used, are "FILE *" and "time_t". The iostream
-. is the result of an fopen on the filename. However, if the
-. BFD_IN_MEMORY flag is set, then iostream is actually a pointer
-. to a bfd_in_memory struct. *}
+. {* The IOSTREAM, and corresponding IO vector that provide access
+. to the file backing the BFD. *}
. void *iostream;
+. const struct bfd_iovec *iovec;
.
. {* Is the file descriptor being cached? That is, can it be closed as
. needed, and re-opened when accessed later? *}
@@ -512,6 +508,9 @@ DESCRIPTION
const char *
bfd_archive_filename (bfd *abfd)
{
+ if (abfd == NULL)
+ return NULL;
+
if (abfd->my_archive)
{
static size_t curr = 0;
@@ -766,12 +765,14 @@ bfd_get_sign_extend_vma (bfd *abfd)
name = bfd_get_target (abfd);
- /* Return a proper value for DJGPP COFF (an x86 COFF variant).
+ /* Return a proper value for DJGPP & PE COFF (x86 COFF variants).
This function is required for DWARF2 support, but there is
no place to store this information in the COFF back end.
Should enough other COFF targets add support for DWARF2,
a place will have to be found. Until then, this hack will do. */
- if (strncmp (name, "coff-go32", sizeof ("coff-go32") - 1) == 0)
+ if (strncmp (name, "coff-go32", sizeof ("coff-go32") - 1) == 0
+ || strcmp (name, "pe-i386") == 0
+ || strcmp (name, "pei-i386") == 0)
return 1;
bfd_set_error (bfd_error_wrong_format);
@@ -1082,6 +1083,9 @@ DESCRIPTION
.#define bfd_merge_sections(abfd, link_info) \
. BFD_SEND (abfd, _bfd_merge_sections, (abfd, link_info))
.
+.#define bfd_is_group_section(abfd, sec) \
+. BFD_SEND (abfd, _bfd_is_group_section, (abfd, sec))
+.
.#define bfd_discard_group(abfd, sec) \
. BFD_SEND (abfd, _bfd_discard_group, (abfd, sec))
.
@@ -1112,6 +1116,9 @@ DESCRIPTION
.#define bfd_canonicalize_dynamic_symtab(abfd, asymbols) \
. BFD_SEND (abfd, _bfd_canonicalize_dynamic_symtab, (abfd, asymbols))
.
+.#define bfd_get_synthetic_symtab(abfd, dynsyms, ret) \
+. BFD_SEND (abfd, _bfd_get_synthetic_symtab, (abfd, dynsyms, ret))
+.
.#define bfd_get_dynamic_reloc_upper_bound(abfd) \
. BFD_SEND (abfd, _bfd_get_dynamic_reloc_upper_bound, (abfd))
.
diff --git a/bfd/bfdio.c b/bfd/bfdio.c
index a90cb33..53534f4 100644
--- a/bfd/bfdio.c
+++ b/bfd/bfdio.c
@@ -62,37 +62,41 @@ real_fseek (FILE *file, file_ptr offset, int whence)
#endif
}
-/* Note that archive entries don't have streams; they share their parent's.
- This allows someone to play with the iostream behind BFD's back.
+/*
+INTERNAL_DEFINITION
+ struct bfd_iovec
- Also, note that the origin pointer points to the beginning of a file's
- contents (0 for non-archive elements). For archive entries this is the
- first octet in the file, NOT the beginning of the archive header. */
+DESCRIPTION
-static size_t
-real_read (void *where, size_t a, size_t b, FILE *file)
-{
- /* FIXME - this looks like an optimization, but it's really to cover
- up for a feature of some OSs (not solaris - sigh) that
- ld/pe-dll.c takes advantage of (apparently) when it creates BFDs
- internally and tries to link against them. BFD seems to be smart
- enough to realize there are no symbol records in the "file" that
- doesn't exist but attempts to read them anyway. On Solaris,
- attempting to read zero bytes from a NULL file results in a core
- dump, but on other platforms it just returns zero bytes read.
- This makes it to something reasonable. - DJ */
- if (a == 0 || b == 0)
- return 0;
+ The <<struct bfd_iovec>> contains the internal file I/O class.
+ Each <<BFD>> has an instance of this class and all file I/O is
+ routed through it (it is assumed that the instance implements
+ all methods listed below).
+
+.struct bfd_iovec
+.{
+. {* To avoid problems with macros, a "b" rather than "f"
+. prefix is prepended to each method name. *}
+. {* Attempt to read/write NBYTES on ABFD's IOSTREAM storing/fetching
+. bytes starting at PTR. Return the number of bytes actually
+. transfered (a read past end-of-file returns less than NBYTES),
+. or -1 (setting <<bfd_error>>) if an error occurs. *}
+. file_ptr (*bread) (struct bfd *abfd, void *ptr, file_ptr nbytes);
+. file_ptr (*bwrite) (struct bfd *abfd, const void *ptr,
+. file_ptr nbytes);
+. {* Return the current IOSTREAM file offset, or -1 (setting <<bfd_error>>
+. if an error occurs. *}
+. file_ptr (*btell) (struct bfd *abfd);
+. {* For the following, on successful completion a value of 0 is returned.
+. Otherwise, a value of -1 is returned (and <<bfd_error>> is set). *}
+. int (*bseek) (struct bfd *abfd, file_ptr offset, int whence);
+. int (*bclose) (struct bfd *abfd);
+. int (*bflush) (struct bfd *abfd);
+. int (*bstat) (struct bfd *abfd, struct stat *sb);
+.};
+*/
-#if defined (__VAX) && defined (VMS)
- /* Apparently fread on Vax VMS does not keep the record length
- information. */
- return read (fileno (file), where, a * b);
-#else
- return fread (where, a, b, file);
-#endif
-}
/* Return value is amount read. */
@@ -121,25 +125,10 @@ bfd_bread (void *ptr, bfd_size_type size, bfd *abfd)
return get;
}
- nread = real_read (ptr, 1, (size_t) size, bfd_cache_lookup (abfd));
+ nread = abfd->iovec->bread (abfd, ptr, size);
if (nread != (size_t) -1)
abfd->where += nread;
- /* Set bfd_error if we did not read as much data as we expected.
-
- If the read failed due to an error set the bfd_error_system_call,
- else set bfd_error_file_truncated.
-
- A BFD backend may wish to override bfd_error_file_truncated to
- provide something more useful (eg. no_symbols or wrong_format). */
- if (nread != size)
- {
- if (ferror (bfd_cache_lookup (abfd)))
- bfd_set_error (bfd_error_system_call);
- else
- bfd_set_error (bfd_error_file_truncated);
- }
-
return nread;
}
@@ -175,7 +164,7 @@ bfd_bwrite (const void *ptr, bfd_size_type size, bfd *abfd)
return size;
}
- nwrote = fwrite (ptr, 1, (size_t) size, bfd_cache_lookup (abfd));
+ nwrote = abfd->iovec->bwrite (abfd, ptr, size);
if (nwrote != (size_t) -1)
abfd->where += nwrote;
if (nwrote != size)
@@ -196,7 +185,7 @@ bfd_tell (bfd *abfd)
if ((abfd->flags & BFD_IN_MEMORY) != 0)
return abfd->where;
- ptr = real_ftell (bfd_cache_lookup (abfd));
+ ptr = abfd->iovec->btell (abfd);
if (abfd->my_archive)
ptr -= abfd->origin;
@@ -209,7 +198,7 @@ bfd_flush (bfd *abfd)
{
if ((abfd->flags & BFD_IN_MEMORY) != 0)
return 0;
- return fflush (bfd_cache_lookup(abfd));
+ return abfd->iovec->bflush (abfd);
}
/* Returns 0 for success, negative value for failure (in which case
@@ -217,19 +206,12 @@ bfd_flush (bfd *abfd)
int
bfd_stat (bfd *abfd, struct stat *statbuf)
{
- FILE *f;
int result;
if ((abfd->flags & BFD_IN_MEMORY) != 0)
abort ();
- f = bfd_cache_lookup (abfd);
- if (f == NULL)
- {
- bfd_set_error (bfd_error_system_call);
- return -1;
- }
- result = fstat (fileno (f), statbuf);
+ result = abfd->iovec->bstat (abfd, statbuf);
if (result < 0)
bfd_set_error (bfd_error_system_call);
return result;
@@ -242,7 +224,6 @@ int
bfd_seek (bfd *abfd, file_ptr position, int direction)
{
int result;
- FILE *f;
file_ptr file_position;
/* For the time being, a BFD may not seek to it's end. The problem
is that we don't easily have a way to recognize the end of an
@@ -328,12 +309,11 @@ bfd_seek (bfd *abfd, file_ptr position, int direction)
In the meantime, no optimization for archives. */
}
- f = bfd_cache_lookup (abfd);
file_position = position;
if (direction == SEEK_SET && abfd->my_archive != NULL)
file_position += abfd->origin;
- result = real_fseek (f, file_position, direction);
+ result = abfd->iovec->bseek (abfd, file_position, direction);
if (result != 0)
{
int hold_errno = errno;
@@ -378,14 +358,12 @@ DESCRIPTION
long
bfd_get_mtime (bfd *abfd)
{
- FILE *fp;
struct stat buf;
if (abfd->mtime_set)
return abfd->mtime;
- fp = bfd_cache_lookup (abfd);
- if (0 != fstat (fileno (fp), &buf))
+ if (abfd->iovec->bstat (abfd, &buf) != 0)
return 0;
abfd->mtime = buf.st_mtime; /* Save value in case anyone wants it */
@@ -428,14 +406,12 @@ DESCRIPTION
long
bfd_get_size (bfd *abfd)
{
- FILE *fp;
struct stat buf;
if ((abfd->flags & BFD_IN_MEMORY) != 0)
return ((struct bfd_in_memory *) abfd->iostream)->size;
- fp = bfd_cache_lookup (abfd);
- if (0 != fstat (fileno (fp), & buf))
+ if (abfd->iovec->bstat (abfd, &buf) != 0)
return 0;
return buf.st_size;
diff --git a/bfd/binary.c b/bfd/binary.c
index 65f46af..c8d8941 100644
--- a/bfd/binary.c
+++ b/bfd/binary.c
@@ -1,6 +1,6 @@
/* BFD back-end for binary objects.
- Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
- Free Software Foundation, Inc.
+ Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+ 2004 Free Software Foundation, Inc.
Written by Ian Lance Taylor, Cygnus Support, <ian@cygnus.com>
This file is part of BFD, the Binary File Descriptor library.
@@ -339,6 +339,7 @@ binary_sizeof_headers (abfd, exec)
#define binary_bfd_relax_section bfd_generic_relax_section
#define binary_bfd_gc_sections bfd_generic_gc_sections
#define binary_bfd_merge_sections bfd_generic_merge_sections
+#define binary_bfd_is_group_section bfd_generic_is_group_section
#define binary_bfd_discard_group bfd_generic_discard_group
#define binary_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
#define binary_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
diff --git a/bfd/bout.c b/bfd/bout.c
index a39a9a3..0c6c808 100644
--- a/bfd/bout.c
+++ b/bfd/bout.c
@@ -1,6 +1,6 @@
/* BFD back-end for Intel 960 b.out binaries.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003
+ 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Written by Cygnus Support.
@@ -1487,6 +1487,7 @@ b_out_bfd_get_relocated_section_contents (output_bfd, link_info, link_order,
#define b_out_bfd_link_split_section _bfd_generic_link_split_section
#define b_out_bfd_gc_sections bfd_generic_gc_sections
#define b_out_bfd_merge_sections bfd_generic_merge_sections
+#define b_out_bfd_is_group_section bfd_generic_is_group_section
#define b_out_bfd_discard_group bfd_generic_discard_group
#define aout_32_get_section_contents_in_window \
diff --git a/bfd/cache.c b/bfd/cache.c
index 7d056ea..0586061 100644
--- a/bfd/cache.c
+++ b/bfd/cache.c
@@ -44,6 +44,109 @@ SECTION
static bfd_boolean bfd_cache_delete (bfd *);
+
+static file_ptr
+cache_btell (struct bfd *abfd)
+{
+ return real_ftell (bfd_cache_lookup (abfd));
+}
+
+static int
+cache_bseek (struct bfd *abfd, file_ptr offset, int whence)
+{
+ return real_fseek (bfd_cache_lookup (abfd), offset, whence);
+}
+
+/* Note that archive entries don't have streams; they share their parent's.
+ This allows someone to play with the iostream behind BFD's back.
+
+ Also, note that the origin pointer points to the beginning of a file's
+ contents (0 for non-archive elements). For archive entries this is the
+ first octet in the file, NOT the beginning of the archive header. */
+
+static file_ptr
+cache_bread (struct bfd *abfd, void *buf, file_ptr nbytes)
+{
+ file_ptr nread;
+ /* FIXME - this looks like an optimization, but it's really to cover
+ up for a feature of some OSs (not solaris - sigh) that
+ ld/pe-dll.c takes advantage of (apparently) when it creates BFDs
+ internally and tries to link against them. BFD seems to be smart
+ enough to realize there are no symbol records in the "file" that
+ doesn't exist but attempts to read them anyway. On Solaris,
+ attempting to read zero bytes from a NULL file results in a core
+ dump, but on other platforms it just returns zero bytes read.
+ This makes it to something reasonable. - DJ */
+ if (nbytes == 0)
+ return 0;
+
+#if defined (__VAX) && defined (VMS)
+ /* Apparently fread on Vax VMS does not keep the record length
+ information. */
+ nread = read (fileno (bfd_cache_lookup (abfd)), buf, nbytes);
+ /* Set bfd_error if we did not read as much data as we expected. If
+ the read failed due to an error set the bfd_error_system_call,
+ else set bfd_error_file_truncated. */
+ if (nread == (file_ptr)-1)
+ {
+ bfd_set_error (bfd_error_system_call);
+ return -1;
+ }
+#else
+ nread = fread (buf, 1, nbytes, bfd_cache_lookup (abfd));
+ /* Set bfd_error if we did not read as much data as we expected. If
+ the read failed due to an error set the bfd_error_system_call,
+ else set bfd_error_file_truncated. */
+ if (nread < nbytes && ferror (bfd_cache_lookup (abfd)))
+ {
+ bfd_set_error (bfd_error_system_call);
+ return -1;
+ }
+#endif
+ return nread;
+}
+
+static file_ptr
+cache_bwrite (struct bfd *abfd, const void *where, file_ptr nbytes)
+{
+ file_ptr nwrite = fwrite (where, 1, nbytes, bfd_cache_lookup (abfd));
+ if (nwrite < nbytes && ferror (bfd_cache_lookup (abfd)))
+ {
+ bfd_set_error (bfd_error_system_call);
+ return -1;
+ }
+ return nwrite;
+}
+
+static int
+cache_bclose (struct bfd *abfd)
+{
+ return bfd_cache_close (abfd);
+}
+
+static int
+cache_bflush (struct bfd *abfd)
+{
+ int sts = fflush (bfd_cache_lookup (abfd));
+ if (sts < 0)
+ bfd_set_error (bfd_error_system_call);
+ return sts;
+}
+
+static int
+cache_bstat (struct bfd *abfd, struct stat *sb)
+{
+ int sts = fstat (fileno (bfd_cache_lookup (abfd)), sb);
+ if (sts < 0)
+ bfd_set_error (bfd_error_system_call);
+ return sts;
+}
+
+static const struct bfd_iovec cache_iovec = {
+ &cache_bread, &cache_bwrite, &cache_btell, &cache_bseek,
+ &cache_bclose, &cache_bflush, &cache_bstat
+};
+
/*
INTERNAL_FUNCTION
BFD_CACHE_MAX_OPEN macro
@@ -205,6 +308,7 @@ bfd_cache_init (bfd *abfd)
if (! close_one ())
return FALSE;
}
+ abfd->iovec = &cache_iovec;
insert (abfd);
++open_files;
return TRUE;
@@ -229,8 +333,11 @@ RETURNS
bfd_boolean
bfd_cache_close (bfd *abfd)
{
- if (abfd->iostream == NULL
- || (abfd->flags & BFD_IN_MEMORY) != 0)
+ if (abfd->iovec != &cache_iovec)
+ return TRUE;
+
+ if (abfd->iostream == NULL)
+ /* Previously closed. */
return TRUE;
return bfd_cache_delete (abfd);
diff --git a/bfd/coff-alpha.c b/bfd/coff-alpha.c
index e9dd416..262af47 100644
--- a/bfd/coff-alpha.c
+++ b/bfd/coff-alpha.c
@@ -1,6 +1,6 @@
/* BFD back-end for ALPHA Extended-Coff files.
- Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
- Free Software Foundation, Inc.
+ Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+ 2003, 2004 Free Software Foundation, Inc.
Modified from coff-mips.c by Steve Chamberlain <sac@cygnus.com> and
Ian Lance Taylor <ian@cygnus.com>.
@@ -2359,6 +2359,7 @@ static const struct ecoff_backend_data alpha_ecoff_backend_data =
#define _bfd_ecoff_bfd_relax_section bfd_generic_relax_section
#define _bfd_ecoff_bfd_gc_sections bfd_generic_gc_sections
#define _bfd_ecoff_bfd_merge_sections bfd_generic_merge_sections
+#define _bfd_ecoff_bfd_is_group_section bfd_generic_is_group_section
#define _bfd_ecoff_bfd_discard_group bfd_generic_discard_group
const bfd_target ecoffalpha_little_vec =
diff --git a/bfd/coff-i386.c b/bfd/coff-i386.c
index a24344a..e2bf860 100644
--- a/bfd/coff-i386.c
+++ b/bfd/coff-i386.c
@@ -234,7 +234,24 @@ static reloc_howto_type howto_table[] =
EMPTY_HOWTO (010),
EMPTY_HOWTO (011),
EMPTY_HOWTO (012),
+#ifdef COFF_WITH_PE
+ /* 32-bit longword section relative relocation (013). */
+ HOWTO (R_SECREL32, /* type */
+ 0, /* rightshift */
+ 2, /* size (0 = byte, 1 = short, 2 = long) */
+ 32, /* bitsize */
+ FALSE, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_bitfield, /* complain_on_overflow */
+ coff_i386_reloc, /* special_function */
+ "secrel32", /* name */
+ TRUE, /* partial_inplace */
+ 0xffffffff, /* src_mask */
+ 0xffffffff, /* dst_mask */
+ TRUE), /* pcrel_offset */
+#else
EMPTY_HOWTO (013),
+#endif
EMPTY_HOWTO (014),
EMPTY_HOWTO (015),
EMPTY_HOWTO (016),
@@ -497,6 +514,30 @@ coff_i386_rtype_to_howto (abfd, sec, rel, h, sym, addendp)
{
*addendp -= pe_data(sec->output_section->owner)->pe_opthdr.ImageBase;
}
+
+ if (rel->r_type == R_SECREL32)
+ {
+ bfd_vma osect_vma;
+
+ if (h && (h->type == bfd_link_hash_defined
+ || h->type == bfd_link_hash_defweak))
+ osect_vma = h->root.u.def.section->output_section->vma;
+ else
+ {
+ asection *sec;
+ int i;
+
+ /* Sigh, the only way to get the section to offset against
+ is to find it the hard way. */
+
+ for (sec = abfd->sections, i = 1; i < sym->n_scnum; i++)
+ sec = sec->next;
+
+ osect_vma = sec->output_section->vma;
+ }
+
+ *addendp -= osect_vma;
+ }
#endif
return howto;
@@ -525,6 +566,10 @@ coff_i386_reloc_type_lookup (abfd, code)
return howto_table + R_RELBYTE;
case BFD_RELOC_8_PCREL:
return howto_table + R_PCRBYTE;
+#ifdef COFF_WITH_PE
+ case BFD_RELOC_32_SECREL:
+ return howto_table + R_SECREL32;
+#endif
default:
BFD_FAIL ();
return 0;
diff --git a/bfd/coff-mips.c b/bfd/coff-mips.c
index d6d8218..9ef1985 100644
--- a/bfd/coff-mips.c
+++ b/bfd/coff-mips.c
@@ -1,6 +1,6 @@
/* BFD back-end for MIPS Extended-Coff files.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003
+ 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Original version by Per Bothner.
Full support added by Ian Lance Taylor, ian@cygnus.com.
@@ -57,28 +57,12 @@ static bfd_reloc_status_type mips_reflo_reloc
static bfd_reloc_status_type mips_gprel_reloc
PARAMS ((bfd *abfd, arelent *reloc, asymbol *symbol, PTR data,
asection *section, bfd *output_bfd, char **error));
-static bfd_reloc_status_type mips_relhi_reloc
- PARAMS ((bfd *abfd, arelent *reloc, asymbol *symbol, PTR data,
- asection *section, bfd *output_bfd, char **error));
-static bfd_reloc_status_type mips_rello_reloc
- PARAMS ((bfd *abfd, arelent *reloc, asymbol *symbol, PTR data,
- asection *section, bfd *output_bfd, char **error));
-static bfd_reloc_status_type mips_switch_reloc
- PARAMS ((bfd *abfd, arelent *reloc, asymbol *symbol, PTR data,
- asection *section, bfd *output_bfd, char **error));
static void mips_relocate_hi
PARAMS ((struct internal_reloc *refhi, struct internal_reloc *reflo,
bfd *input_bfd, asection *input_section, bfd_byte *contents,
- size_t adjust, bfd_vma relocation, bfd_boolean pcrel));
+ bfd_vma relocation));
static bfd_boolean mips_relocate_section
PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, PTR));
-static bfd_boolean mips_read_relocs
- PARAMS ((bfd *, asection *));
-static bfd_boolean mips_relax_section
- PARAMS ((bfd *, asection *, struct bfd_link_info *, bfd_boolean *));
-static bfd_boolean mips_relax_pcrel16
- PARAMS ((struct bfd_link_info *, bfd *, asection *,
- struct ecoff_link_hash_entry *, bfd_byte *, bfd_vma));
static reloc_howto_type *mips_bfd_reloc_type_lookup
PARAMS ((bfd *, bfd_reloc_code_real_type));
@@ -243,10 +227,9 @@ static reloc_howto_type mips_howto_table[] =
EMPTY_HOWTO (10),
EMPTY_HOWTO (11),
- /* This reloc is a Cygnus extension used when generating position
- independent code for embedded systems. It represents a 16 bit PC
- relative reloc rightshifted twice as used in the MIPS branch
- instructions. */
+ /* FIXME: This relocation is used (internally only) to represent branches
+ when assembling. It should never appear in output files, and
+ be removed. (It used to be used for embedded-PIC support.) */
HOWTO (MIPS_R_PCREL16, /* type */
2, /* rightshift */
2, /* size (0 = byte, 1 = short, 2 = long) */
@@ -260,92 +243,10 @@ static reloc_howto_type mips_howto_table[] =
0xffff, /* src_mask */
0xffff, /* dst_mask */
TRUE), /* pcrel_offset */
-
- /* This reloc is a Cygnus extension used when generating position
- independent code for embedded systems. It represents the high 16
- bits of a PC relative reloc. The next reloc must be
- MIPS_R_RELLO, and the addend is formed from the addends of the
- two instructions, just as in MIPS_R_REFHI and MIPS_R_REFLO. The
- final value is actually PC relative to the location of the
- MIPS_R_RELLO reloc, not the MIPS_R_RELHI reloc. */
- HOWTO (MIPS_R_RELHI, /* type */
- 16, /* rightshift */
- 2, /* size (0 = byte, 1 = short, 2 = long) */
- 16, /* bitsize */
- TRUE, /* pc_relative */
- 0, /* bitpos */
- complain_overflow_bitfield, /* complain_on_overflow */
- mips_relhi_reloc, /* special_function */
- "RELHI", /* name */
- TRUE, /* partial_inplace */
- 0xffff, /* src_mask */
- 0xffff, /* dst_mask */
- TRUE), /* pcrel_offset */
-
- /* This reloc is a Cygnus extension used when generating position
- independent code for embedded systems. It represents the low 16
- bits of a PC relative reloc. */
- HOWTO (MIPS_R_RELLO, /* type */
- 0, /* rightshift */
- 2, /* size (0 = byte, 1 = short, 2 = long) */
- 16, /* bitsize */
- TRUE, /* pc_relative */
- 0, /* bitpos */
- complain_overflow_dont, /* complain_on_overflow */
- mips_rello_reloc, /* special_function */
- "RELLO", /* name */
- TRUE, /* partial_inplace */
- 0xffff, /* src_mask */
- 0xffff, /* dst_mask */
- TRUE), /* pcrel_offset */
-
- EMPTY_HOWTO (15),
- EMPTY_HOWTO (16),
- EMPTY_HOWTO (17),
- EMPTY_HOWTO (18),
- EMPTY_HOWTO (19),
- EMPTY_HOWTO (20),
- EMPTY_HOWTO (21),
-
- /* This reloc is a Cygnus extension used when generating position
- independent code for embedded systems. It represents an entry in
- a switch table, which is the difference between two symbols in
- the .text section. The symndx is actually the offset from the
- reloc address to the subtrahend. See include/coff/mips.h for
- more details. */
- HOWTO (MIPS_R_SWITCH, /* type */
- 0, /* rightshift */
- 2, /* size (0 = byte, 1 = short, 2 = long) */
- 32, /* bitsize */
- TRUE, /* pc_relative */
- 0, /* bitpos */
- complain_overflow_dont, /* complain_on_overflow */
- mips_switch_reloc, /* special_function */
- "SWITCH", /* name */
- TRUE, /* partial_inplace */
- 0xffffffff, /* src_mask */
- 0xffffffff, /* dst_mask */
- TRUE) /* pcrel_offset */
};
#define MIPS_HOWTO_COUNT \
(sizeof mips_howto_table / sizeof mips_howto_table[0])
-
-/* When the linker is doing relaxing, it may change an external PCREL16
- reloc. This typically represents an instruction like
- bal foo
- We change it to
- .set noreorder
- bal $L1
- lui $at,%hi(foo - $L1)
- $L1:
- addiu $at,%lo(foo - $L1)
- addu $at,$at,$31
- jalr $at
- PCREL16_EXPANSION_ADJUSTMENT is the number of bytes this changes the
- instruction by. */
-
-#define PCREL16_EXPANSION_ADJUSTMENT (4 * 4)
/* See whether the magic number matches. */
@@ -418,25 +319,6 @@ mips_ecoff_swap_reloc_in (abfd, ext_ptr, intern)
<< RELOC_BITS3_TYPEHI_SH_LITTLE));
intern->r_extern = (ext->r_bits[3] & RELOC_BITS3_EXTERN_LITTLE) != 0;
}
-
- /* If this is a MIPS_R_SWITCH reloc, or an internal MIPS_R_RELHI or
- MIPS_R_RELLO reloc, r_symndx is actually the offset from the
- reloc address to the base of the difference (see
- include/coff/mips.h for more details). We copy symndx into the
- r_offset field so as not to confuse ecoff_slurp_reloc_table in
- ecoff.c. In adjust_reloc_in we then copy r_offset into the reloc
- addend. */
- if (intern->r_type == MIPS_R_SWITCH
- || (! intern->r_extern
- && (intern->r_type == MIPS_R_RELLO
- || intern->r_type == MIPS_R_RELHI)))
- {
- BFD_ASSERT (! intern->r_extern);
- intern->r_offset = intern->r_symndx;
- if (intern->r_offset & 0x800000)
- intern->r_offset -= 0x1000000;
- intern->r_symndx = RELOC_SECTION_TEXT;
- }
}
/* Swap a reloc out. */
@@ -453,20 +335,7 @@ mips_ecoff_swap_reloc_out (abfd, intern, dst)
BFD_ASSERT (intern->r_extern
|| (intern->r_symndx >= 0 && intern->r_symndx <= 12));
- /* If this is a MIPS_R_SWITCH reloc, or an internal MIPS_R_RELLO or
- MIPS_R_RELHI reloc, we actually want to write the contents of
- r_offset out as the symbol index. This undoes the change made by
- mips_ecoff_swap_reloc_in. */
- if (intern->r_type != MIPS_R_SWITCH
- && (intern->r_extern
- || (intern->r_type != MIPS_R_RELHI
- && intern->r_type != MIPS_R_RELLO)))
- r_symndx = intern->r_symndx;
- else
- {
- BFD_ASSERT (intern->r_symndx == RELOC_SECTION_TEXT);
- r_symndx = intern->r_offset & 0xffffff;
- }
+ r_symndx = intern->r_symndx;
H_PUT_32 (abfd, intern->r_vaddr, ext->r_vaddr);
if (bfd_header_big_endian (abfd))
@@ -501,7 +370,7 @@ mips_adjust_reloc_in (abfd, intern, rptr)
const struct internal_reloc *intern;
arelent *rptr;
{
- if (intern->r_type > MIPS_R_SWITCH)
+ if (intern->r_type > MIPS_R_PCREL16)
abort ();
if (! intern->r_extern
@@ -514,18 +383,6 @@ mips_adjust_reloc_in (abfd, intern, rptr)
if (intern->r_type == MIPS_R_IGNORE)
rptr->sym_ptr_ptr = bfd_abs_section_ptr->symbol_ptr_ptr;
- /* If this is a MIPS_R_SWITCH reloc, or an internal MIPS_R_RELHI or
- MIPS_R_RELLO reloc, we want the addend field of the BFD relocto
- hold the value which was originally in the symndx field of the
- internal MIPS ECOFF reloc. This value was copied into
- intern->r_offset by mips_swap_reloc_in, and here we copy it into
- the addend field. */
- if (intern->r_type == MIPS_R_SWITCH
- || (! intern->r_extern
- && (intern->r_type == MIPS_R_RELHI
- || intern->r_type == MIPS_R_RELLO)))
- rptr->addend = intern->r_offset;
-
rptr->howto = &mips_howto_table[intern->r_type];
}
@@ -535,19 +392,9 @@ mips_adjust_reloc_in (abfd, intern, rptr)
static void
mips_adjust_reloc_out (abfd, rel, intern)
bfd *abfd ATTRIBUTE_UNUSED;
- const arelent *rel;
- struct internal_reloc *intern;
+ const arelent *rel ATTRIBUTE_UNUSED;
+ struct internal_reloc *intern ATTRIBUTE_UNUSED;
{
- /* For a MIPS_R_SWITCH reloc, or an internal MIPS_R_RELHI or
- MIPS_R_RELLO reloc, we must copy rel->addend into
- intern->r_offset. This will then be written out as the symbol
- index by mips_ecoff_swap_reloc_out. This operation parallels the
- action of mips_adjust_reloc_in. */
- if (intern->r_type == MIPS_R_SWITCH
- || (! intern->r_extern
- && (intern->r_type == MIPS_R_RELHI
- || intern->r_type == MIPS_R_RELLO)))
- intern->r_offset = rel->addend;
}
/* ECOFF relocs are either against external symbols, or against
@@ -880,209 +727,6 @@ mips_gprel_reloc (abfd,
return bfd_reloc_ok;
}
-/* Do a RELHI relocation. We do this in conjunction with a RELLO
- reloc, just as REFHI and REFLO are done together. RELHI and RELLO
- are Cygnus extensions used when generating position independent
- code for embedded systems. */
-
-/* FIXME: This should not be a static variable. */
-
-static struct mips_hi *mips_relhi_list;
-
-static bfd_reloc_status_type
-mips_relhi_reloc (abfd,
- reloc_entry,
- symbol,
- data,
- input_section,
- output_bfd,
- error_message)
- bfd *abfd ATTRIBUTE_UNUSED;
- arelent *reloc_entry;
- asymbol *symbol;
- PTR data;
- asection *input_section;
- bfd *output_bfd;
- char **error_message ATTRIBUTE_UNUSED;
-{
- bfd_reloc_status_type ret;
- bfd_vma relocation;
- struct mips_hi *n;
-
- /* If this is a reloc against a section symbol, then it is correct
- in the object file. The only time we want to change this case is
- when we are relaxing, and that is handled entirely by
- mips_relocate_section and never calls this function. */
- if ((symbol->flags & BSF_SECTION_SYM) != 0)
- {
- if (output_bfd != (bfd *) NULL)
- reloc_entry->address += input_section->output_offset;
- return bfd_reloc_ok;
- }
-
- /* This is an external symbol. If we're relocating, we don't want
- to change anything. */
- if (output_bfd != (bfd *) NULL)
- {
- reloc_entry->address += input_section->output_offset;
- return bfd_reloc_ok;
- }
-
- ret = bfd_reloc_ok;
- if (bfd_is_und_section (symbol->section)
- && output_bfd == (bfd *) NULL)
- ret = bfd_reloc_undefined;
-
- if (bfd_is_com_section (symbol->section))
- relocation = 0;
- else
- relocation = symbol->value;
-
- relocation += symbol->section->output_section->vma;
- relocation += symbol->section->output_offset;
- relocation += reloc_entry->addend;
-
- if (reloc_entry->address > input_section->_cooked_size)
- return bfd_reloc_outofrange;
-
- /* Save the information, and let RELLO do the actual relocation. */
- n = (struct mips_hi *) bfd_malloc ((bfd_size_type) sizeof *n);
- if (n == NULL)
- return bfd_reloc_outofrange;
- n->addr = (bfd_byte *) data + reloc_entry->address;
- n->addend = relocation;
- n->next = mips_relhi_list;
- mips_relhi_list = n;
-
- if (output_bfd != (bfd *) NULL)
- reloc_entry->address += input_section->output_offset;
-
- return ret;
-}
-
-/* Do a RELLO relocation. This is a straightforward 16 bit PC
- relative relocation; this function exists in order to do the RELHI
- relocation described above. */
-
-static bfd_reloc_status_type
-mips_rello_reloc (abfd,
- reloc_entry,
- symbol,
- data,
- input_section,
- output_bfd,
- error_message)
- bfd *abfd;
- arelent *reloc_entry;
- asymbol *symbol;
- PTR data;
- asection *input_section;
- bfd *output_bfd;
- char **error_message;
-{
- if (mips_relhi_list != NULL)
- {
- struct mips_hi *l;
-
- l = mips_relhi_list;
- while (l != NULL)
- {
- unsigned long insn;
- unsigned long val;
- unsigned long vallo;
- struct mips_hi *next;
-
- /* Do the RELHI relocation. Note that we actually don't
- need to know anything about the RELLO itself, except
- where to find the low 16 bits of the addend needed by the
- RELHI. */
- insn = bfd_get_32 (abfd, l->addr);
- vallo = (bfd_get_32 (abfd, (bfd_byte *) data + reloc_entry->address)
- & 0xffff);
- val = ((insn & 0xffff) << 16) + vallo;
- val += l->addend;
-
- /* If the symbol is defined, make val PC relative. If the
- symbol is not defined we don't want to do this, because
- we don't want the value in the object file to incorporate
- the address of the reloc. */
- if (! bfd_is_und_section (bfd_get_section (symbol))
- && ! bfd_is_com_section (bfd_get_section (symbol)))
- val -= (input_section->output_section->vma
- + input_section->output_offset
- + reloc_entry->address);
-
- /* The low order 16 bits are always treated as a signed
- value. Therefore, a negative value in the low order bits
- requires an adjustment in the high order bits. We need
- to make this adjustment in two ways: once for the bits we
- took from the data, and once for the bits we are putting
- back in to the data. */
- if ((vallo & 0x8000) != 0)
- val -= 0x10000;
- if ((val & 0x8000) != 0)
- val += 0x10000;
-
- insn = (insn &~ (unsigned) 0xffff) | ((val >> 16) & 0xffff);
- bfd_put_32 (abfd, (bfd_vma) insn, l->addr);
-
- next = l->next;
- free (l);
- l = next;
- }
-
- mips_relhi_list = NULL;
- }
-
- /* If this is a reloc against a section symbol, then it is correct
- in the object file. The only time we want to change this case is
- when we are relaxing, and that is handled entirely by
- mips_relocate_section and never calls this function. */
- if ((symbol->flags & BSF_SECTION_SYM) != 0)
- {
- if (output_bfd != (bfd *) NULL)
- reloc_entry->address += input_section->output_offset;
- return bfd_reloc_ok;
- }
-
- /* bfd_perform_relocation does not handle pcrel_offset relocations
- correctly when generating a relocatable file, so handle them
- directly here. */
- if (output_bfd != (bfd *) NULL)
- {
- reloc_entry->address += input_section->output_offset;
- return bfd_reloc_ok;
- }
-
- /* Now do the RELLO reloc in the usual way. */
- return mips_generic_reloc (abfd, reloc_entry, symbol, data,
- input_section, output_bfd, error_message);
-}
-
-/* This is the special function for the MIPS_R_SWITCH reloc. This
- special reloc is normally correct in the object file, and only
- requires special handling when relaxing. We don't want
- bfd_perform_relocation to tamper with it at all. */
-
-static bfd_reloc_status_type
-mips_switch_reloc (abfd,
- reloc_entry,
- symbol,
- data,
- input_section,
- output_bfd,
- error_message)
- bfd *abfd ATTRIBUTE_UNUSED;
- arelent *reloc_entry ATTRIBUTE_UNUSED;
- asymbol *symbol ATTRIBUTE_UNUSED;
- PTR data ATTRIBUTE_UNUSED;
- asection *input_section ATTRIBUTE_UNUSED;
- bfd *output_bfd ATTRIBUTE_UNUSED;
- char **error_message ATTRIBUTE_UNUSED;
-{
- return bfd_reloc_ok;
-}
-
/* Get the howto structure for a generic reloc type. */
static reloc_howto_type *
@@ -1119,15 +763,6 @@ mips_bfd_reloc_type_lookup (abfd, code)
case BFD_RELOC_16_PCREL_S2:
mips_type = MIPS_R_PCREL16;
break;
- case BFD_RELOC_PCREL_HI16_S:
- mips_type = MIPS_R_RELHI;
- break;
- case BFD_RELOC_PCREL_LO16:
- mips_type = MIPS_R_RELLO;
- break;
- case BFD_RELOC_GPREL32:
- mips_type = MIPS_R_SWITCH;
- break;
default:
return (reloc_howto_type *) NULL;
}
@@ -1136,21 +771,19 @@ mips_bfd_reloc_type_lookup (abfd, code)
}
/* A helper routine for mips_relocate_section which handles the REFHI
- and RELHI relocations. The REFHI relocation must be followed by a
- REFLO relocation (and RELHI by a RELLO), and the addend used is
- formed from the addends of both instructions. */
+ relocations. The REFHI relocation must be followed by a REFLO
+ relocation, and the addend used is formed from the addends of both
+ instructions. */
static void
-mips_relocate_hi (refhi, reflo, input_bfd, input_section, contents, adjust,
- relocation, pcrel)
+mips_relocate_hi (refhi, reflo, input_bfd, input_section, contents,
+ relocation)
struct internal_reloc *refhi;
struct internal_reloc *reflo;
bfd *input_bfd;
asection *input_section;
bfd_byte *contents;
- size_t adjust;
bfd_vma relocation;
- bfd_boolean pcrel;
{
unsigned long insn;
unsigned long val;
@@ -1160,12 +793,12 @@ mips_relocate_hi (refhi, reflo, input_bfd, input_section, contents, adjust,
return;
insn = bfd_get_32 (input_bfd,
- contents + adjust + refhi->r_vaddr - input_section->vma);
+ contents + refhi->r_vaddr - input_section->vma);
if (reflo == NULL)
vallo = 0;
else
vallo = (bfd_get_32 (input_bfd,
- contents + adjust + reflo->r_vaddr - input_section->vma)
+ contents + reflo->r_vaddr - input_section->vma)
& 0xffff);
val = ((insn & 0xffff) << 16) + vallo;
@@ -1179,17 +812,12 @@ mips_relocate_hi (refhi, reflo, input_bfd, input_section, contents, adjust,
if ((vallo & 0x8000) != 0)
val -= 0x10000;
- if (pcrel)
- val -= (input_section->output_section->vma
- + input_section->output_offset
- + (reflo->r_vaddr - input_section->vma + adjust));
-
if ((val & 0x8000) != 0)
val += 0x10000;
insn = (insn &~ (unsigned) 0xffff) | ((val >> 16) & 0xffff);
bfd_put_32 (input_bfd, (bfd_vma) insn,
- contents + adjust + refhi->r_vaddr - input_section->vma);
+ contents + refhi->r_vaddr - input_section->vma);
}
/* Relocate a section while linking a MIPS ECOFF file. */
@@ -1208,8 +836,6 @@ mips_relocate_section (output_bfd, info, input_bfd, input_section,
struct ecoff_link_hash_entry **sym_hashes;
bfd_vma gp;
bfd_boolean gp_undefined;
- size_t adjust;
- long *offsets;
struct external_reloc *ext_rel;
struct external_reloc *ext_rel_end;
unsigned int i;
@@ -1270,13 +896,6 @@ mips_relocate_section (output_bfd, info, input_bfd, input_section,
got_lo = FALSE;
- adjust = 0;
-
- if (ecoff_section_data (input_bfd, input_section) == NULL)
- offsets = NULL;
- else
- offsets = ecoff_section_data (input_bfd, input_section)->offsets;
-
ext_rel = (struct external_reloc *) external_relocs;
ext_rel_end = ext_rel + input_section->reloc_count;
for (i = 0; ext_rel < ext_rel_end; ext_rel++, i++)
@@ -1301,17 +920,15 @@ mips_relocate_section (output_bfd, info, input_bfd, input_section,
BFD_ASSERT (int_rel.r_type
< sizeof mips_howto_table / sizeof mips_howto_table[0]);
- /* The REFHI and RELHI relocs requires special handling. they
- must be followed by a REFLO or RELLO reloc, respectively, and
- the addend is formed from both relocs. */
- if (int_rel.r_type == MIPS_R_REFHI
- || int_rel.r_type == MIPS_R_RELHI)
+ /* The REFHI reloc requires special handling. It must be followed
+ by a REFLO reloc, and the addend is formed from both relocs. */
+ if (int_rel.r_type == MIPS_R_REFHI)
{
struct external_reloc *lo_ext_rel;
/* As a GNU extension, permit an arbitrary number of REFHI
- or RELHI relocs before the REFLO or RELLO reloc. This
- permits gcc to emit the HI and LO relocs itself. */
+ relocs before the REFLO reloc. This permits gcc to emit
+ the HI and LO relocs itself. */
for (lo_ext_rel = ext_rel + 1;
lo_ext_rel < ext_rel_end;
lo_ext_rel++)
@@ -1323,10 +940,7 @@ mips_relocate_section (output_bfd, info, input_bfd, input_section,
}
if (lo_ext_rel < ext_rel_end
- && (lo_int_rel.r_type
- == (int_rel.r_type == MIPS_R_REFHI
- ? MIPS_R_REFLO
- : MIPS_R_RELLO))
+ && lo_int_rel.r_type == MIPS_R_REFLO
&& int_rel.r_extern == lo_int_rel.r_extern
&& int_rel.r_symndx == lo_int_rel.r_symndx)
{
@@ -1338,32 +952,6 @@ mips_relocate_section (output_bfd, info, input_bfd, input_section,
howto = &mips_howto_table[int_rel.r_type];
- /* The SWITCH reloc must be handled specially. This reloc is
- marks the location of a difference between two portions of an
- object file. The symbol index does not reference a symbol,
- but is actually the offset from the reloc to the subtrahend
- of the difference. This reloc is correct in the object file,
- and needs no further adjustment, unless we are relaxing. If
- we are relaxing, we may have to add in an offset. Since no
- symbols are involved in this reloc, we handle it completely
- here. */
- if (int_rel.r_type == MIPS_R_SWITCH)
- {
- if (offsets != NULL
- && offsets[i] != 0)
- {
- r = _bfd_relocate_contents (howto, input_bfd,
- (bfd_vma) offsets[i],
- (contents
- + adjust
- + int_rel.r_vaddr
- - input_section->vma));
- BFD_ASSERT (r == bfd_reloc_ok);
- }
-
- continue;
- }
-
if (int_rel.r_extern)
{
h = sym_hashes[int_rel.r_symndx];
@@ -1439,91 +1027,6 @@ mips_relocate_section (output_bfd, info, input_bfd, input_section,
}
}
- /* If we are relaxing, mips_relax_section may have set
- offsets[i] to some value. A value of 1 means we must expand
- a PC relative branch into a multi-instruction of sequence,
- and any other value is an addend. */
- if (offsets != NULL
- && offsets[i] != 0)
- {
- BFD_ASSERT (! info->relocatable);
- BFD_ASSERT (int_rel.r_type == MIPS_R_PCREL16
- || int_rel.r_type == MIPS_R_RELHI
- || int_rel.r_type == MIPS_R_RELLO);
- if (offsets[i] != 1)
- addend += offsets[i];
- else
- {
- bfd_byte *here;
-
- BFD_ASSERT (int_rel.r_extern
- && int_rel.r_type == MIPS_R_PCREL16);
-
- /* Move the rest of the instructions up. */
- here = (contents
- + adjust
- + int_rel.r_vaddr
- - input_section->vma);
- memmove (here + PCREL16_EXPANSION_ADJUSTMENT, here,
- (size_t) (input_section->_raw_size
- - (int_rel.r_vaddr - input_section->vma)));
-
- /* Generate the new instructions. */
- if (! mips_relax_pcrel16 (info, input_bfd, input_section,
- h, here,
- (input_section->output_section->vma
- + input_section->output_offset
- + (int_rel.r_vaddr
- - input_section->vma)
- + adjust)))
- return FALSE;
-
- /* We must adjust everything else up a notch. */
- adjust += PCREL16_EXPANSION_ADJUSTMENT;
-
- /* mips_relax_pcrel16 handles all the details of this
- relocation. */
- continue;
- }
- }
-
- /* If we are relaxing, and this is a reloc against the .text
- segment, we may need to adjust it if some branches have been
- expanded. The reloc types which are likely to occur in the
- .text section are handled efficiently by mips_relax_section,
- and thus do not need to be handled here. */
- if (ecoff_data (input_bfd)->debug_info.adjust != NULL
- && ! int_rel.r_extern
- && int_rel.r_symndx == RELOC_SECTION_TEXT
- && (strcmp (bfd_get_section_name (input_bfd, input_section),
- ".text") != 0
- || (int_rel.r_type != MIPS_R_PCREL16
- && int_rel.r_type != MIPS_R_SWITCH
- && int_rel.r_type != MIPS_R_RELHI
- && int_rel.r_type != MIPS_R_RELLO)))
- {
- bfd_vma adr;
- struct ecoff_value_adjust *a;
-
- /* We need to get the addend so that we know whether we need
- to adjust the address. */
- BFD_ASSERT (int_rel.r_type == MIPS_R_REFWORD);
-
- adr = bfd_get_32 (input_bfd,
- (contents
- + adjust
- + int_rel.r_vaddr
- - input_section->vma));
-
- for (a = ecoff_data (input_bfd)->debug_info.adjust;
- a != (struct ecoff_value_adjust *) NULL;
- a = a->next)
- {
- if (adr >= a->start && adr < a->end)
- addend += a->adjust;
- }
- }
-
if (info->relocatable)
{
/* We are generating relocatable output, and must convert
@@ -1601,49 +1104,7 @@ mips_relocate_section (output_bfd, info, input_bfd, input_section,
currently holds just the addend. We must adjust
by the address to get the right value. */
if (howto->pc_relative)
- {
- relocation -= int_rel.r_vaddr - input_section->vma;
-
- /* If we are converting a RELHI or RELLO reloc
- from being against an external symbol to
- being against a section, we must put a
- special value into the r_offset field. This
- value is the old addend. The r_offset for
- both the RELHI and RELLO relocs are the same,
- and we set both when we see RELHI. */
- if (int_rel.r_type == MIPS_R_RELHI)
- {
- long addhi, addlo;
-
- addhi = bfd_get_32 (input_bfd,
- (contents
- + adjust
- + int_rel.r_vaddr
- - input_section->vma));
- addhi &= 0xffff;
- if (addhi & 0x8000)
- addhi -= 0x10000;
- addhi <<= 16;
-
- if (! use_lo)
- addlo = 0;
- else
- {
- addlo = bfd_get_32 (input_bfd,
- (contents
- + adjust
- + lo_int_rel.r_vaddr
- - input_section->vma));
- addlo &= 0xffff;
- if (addlo & 0x8000)
- addlo -= 0x10000;
-
- lo_int_rel.r_offset = addhi + addlo;
- }
-
- int_rel.r_offset = addhi + addlo;
- }
- }
+ relocation -= int_rel.r_vaddr - input_section->vma;
h = NULL;
}
@@ -1679,14 +1140,8 @@ mips_relocate_section (output_bfd, info, input_bfd, input_section,
/* Adjust a PC relative relocation by removing the reference
to the original address in the section and including the
- reference to the new address. However, external RELHI
- and RELLO relocs are PC relative, but don't include any
- reference to the address. The addend is merely an
- addend. */
- if (howto->pc_relative
- && (! int_rel.r_extern
- || (int_rel.r_type != MIPS_R_RELHI
- && int_rel.r_type != MIPS_R_RELLO)))
+ reference to the new address. */
+ if (howto->pc_relative)
relocation -= (input_section->output_section->vma
+ input_section->output_offset
- input_section->vma);
@@ -1696,11 +1151,9 @@ mips_relocate_section (output_bfd, info, input_bfd, input_section,
r = bfd_reloc_ok;
else
{
- if (int_rel.r_type != MIPS_R_REFHI
- && int_rel.r_type != MIPS_R_RELHI)
+ if (int_rel.r_type != MIPS_R_REFHI)
r = _bfd_relocate_contents (howto, input_bfd, relocation,
(contents
- + adjust
+ int_rel.r_vaddr
- input_section->vma));
else
@@ -1708,8 +1161,7 @@ mips_relocate_section (output_bfd, info, input_bfd, input_section,
mips_relocate_hi (&int_rel,
use_lo ? &lo_int_rel : NULL,
input_bfd, input_section, contents,
- adjust, relocation,
- int_rel.r_type == MIPS_R_RELHI);
+ relocation);
r = bfd_reloc_ok;
}
}
@@ -1759,32 +1211,24 @@ mips_relocate_section (output_bfd, info, input_bfd, input_section,
file. Make it look like a pcrel_offset relocation by
adding in the start address. */
if (howto->pc_relative)
- {
- if (int_rel.r_type != MIPS_R_RELHI || ! use_lo)
- relocation += int_rel.r_vaddr + adjust;
- else
- relocation += lo_int_rel.r_vaddr + adjust;
- }
+ relocation += int_rel.r_vaddr;
}
- if (int_rel.r_type != MIPS_R_REFHI
- && int_rel.r_type != MIPS_R_RELHI)
+ if (int_rel.r_type != MIPS_R_REFHI)
r = _bfd_final_link_relocate (howto,
input_bfd,
input_section,
contents,
(int_rel.r_vaddr
- - input_section->vma
- + adjust),
+ - input_section->vma),
relocation,
addend);
else
{
mips_relocate_hi (&int_rel,
use_lo ? &lo_int_rel : NULL,
- input_bfd, input_section, contents, adjust,
- relocation,
- int_rel.r_type == MIPS_R_RELHI);
+ input_bfd, input_section, contents,
+ relocation);
r = bfd_reloc_ok;
}
}
@@ -1801,8 +1245,7 @@ mips_relocate_section (output_bfd, info, input_bfd, input_section,
& 0xf0000000)
!= ((input_section->output_section->vma
+ input_section->output_offset
- + (int_rel.r_vaddr - input_section->vma)
- + adjust)
+ + (int_rel.r_vaddr - input_section->vma))
& 0xf0000000)))
r = bfd_reloc_overflow;
@@ -1835,621 +1278,6 @@ mips_relocate_section (output_bfd, info, input_bfd, input_section,
return TRUE;
}
-/* Read in the relocs for a section. */
-
-static bfd_boolean
-mips_read_relocs (abfd, sec)
- bfd *abfd;
- asection *sec;
-{
- struct ecoff_section_tdata *section_tdata;
- bfd_size_type amt;
-
- section_tdata = ecoff_section_data (abfd, sec);
- if (section_tdata == (struct ecoff_section_tdata *) NULL)
- {
- amt = sizeof (struct ecoff_section_tdata);
- sec->used_by_bfd = (PTR) bfd_alloc (abfd, amt);
- if (sec->used_by_bfd == NULL)
- return FALSE;
-
- section_tdata = ecoff_section_data (abfd, sec);
- section_tdata->external_relocs = NULL;
- section_tdata->contents = NULL;
- section_tdata->offsets = NULL;
- }
-
- if (section_tdata->external_relocs == NULL)
- {
- amt = ecoff_backend (abfd)->external_reloc_size;
- amt *= sec->reloc_count;
- section_tdata->external_relocs = (PTR) bfd_alloc (abfd, amt);
- if (section_tdata->external_relocs == NULL && amt != 0)
- return FALSE;
-
- if (bfd_seek (abfd, sec->rel_filepos, SEEK_SET) != 0
- || bfd_bread (section_tdata->external_relocs, amt, abfd) != amt)
- return FALSE;
- }
-
- return TRUE;
-}
-
-/* Relax a section when linking a MIPS ECOFF file. This is used for
- embedded PIC code, which always uses PC relative branches which
- only have an 18 bit range on MIPS. If a branch is not in range, we
- generate a long instruction sequence to compensate. Each time we
- find a branch to expand, we have to check all the others again to
- make sure they are still in range. This is slow, but it only has
- to be done when -relax is passed to the linker.
-
- This routine figures out which branches need to expand; the actual
- expansion is done in mips_relocate_section when the section
- contents are relocated. The information is stored in the offsets
- field of the ecoff_section_tdata structure. An offset of 1 means
- that the branch must be expanded into a multi-instruction PC
- relative branch (such an offset will only occur for a PC relative
- branch to an external symbol). Any other offset must be a multiple
- of four, and is the amount to change the branch by (such an offset
- will only occur for a PC relative branch within the same section).
-
- We do not modify the section relocs or contents themselves so that
- if memory usage becomes an issue we can discard them and read them
- again. The only information we must save in memory between this
- routine and the mips_relocate_section routine is the table of
- offsets. */
-
-static bfd_boolean
-mips_relax_section (abfd, sec, info, again)
- bfd *abfd;
- asection *sec;
- struct bfd_link_info *info;
- bfd_boolean *again;
-{
- struct ecoff_section_tdata *section_tdata;
- bfd_byte *contents = NULL;
- long *offsets;
- struct external_reloc *ext_rel;
- struct external_reloc *ext_rel_end;
- unsigned int i;
-
- /* Assume we are not going to need another pass. */
- *again = FALSE;
-
- /* If we are not generating an ECOFF file, this is much too
- confusing to deal with. */
- if (info->hash->creator->flavour != bfd_get_flavour (abfd))
- return TRUE;
-
- /* If there are no relocs, there is nothing to do. */
- if (sec->reloc_count == 0)
- return TRUE;
-
- /* We are only interested in PC relative relocs, and why would there
- ever be one from anything but the .text section? */
- if (strcmp (bfd_get_section_name (abfd, sec), ".text") != 0)
- return TRUE;
-
- /* Read in the relocs, if we haven't already got them. */
- section_tdata = ecoff_section_data (abfd, sec);
- if (section_tdata == (struct ecoff_section_tdata *) NULL
- || section_tdata->external_relocs == NULL)
- {
- if (! mips_read_relocs (abfd, sec))
- goto error_return;
- section_tdata = ecoff_section_data (abfd, sec);
- }
-
- if (sec->_cooked_size == 0)
- {
- /* We must initialize _cooked_size only the first time we are
- called. */
- sec->_cooked_size = sec->_raw_size;
- }
-
- contents = section_tdata->contents;
- offsets = section_tdata->offsets;
-
- /* Look for any external PC relative relocs. Internal PC relative
- relocs are already correct in the object file, so they certainly
- can not overflow. */
- ext_rel = (struct external_reloc *) section_tdata->external_relocs;
- ext_rel_end = ext_rel + sec->reloc_count;
- for (i = 0; ext_rel < ext_rel_end; ext_rel++, i++)
- {
- struct internal_reloc int_rel;
- struct ecoff_link_hash_entry *h;
- asection *hsec;
- bfd_signed_vma relocation;
- struct external_reloc *adj_ext_rel;
- unsigned int adj_i;
- unsigned long ext_count;
- struct ecoff_link_hash_entry **adj_h_ptr;
- struct ecoff_link_hash_entry **adj_h_ptr_end;
- struct ecoff_value_adjust *adjust;
- bfd_size_type amt;
-
- /* If we have already expanded this reloc, we certainly don't
- need to do it again. */
- if (offsets != (long *) NULL && offsets[i] == 1)
- continue;
-
- /* Quickly check that this reloc is external PCREL16. */
- if (bfd_header_big_endian (abfd))
- {
- if ((ext_rel->r_bits[3] & RELOC_BITS3_EXTERN_BIG) == 0
- || (((ext_rel->r_bits[3] & RELOC_BITS3_TYPE_BIG)
- >> RELOC_BITS3_TYPE_SH_BIG)
- != MIPS_R_PCREL16))
- continue;
- }
- else
- {
- if ((ext_rel->r_bits[3] & RELOC_BITS3_EXTERN_LITTLE) == 0
- || (((ext_rel->r_bits[3] & RELOC_BITS3_TYPE_LITTLE)
- >> RELOC_BITS3_TYPE_SH_LITTLE)
- != MIPS_R_PCREL16))
- continue;
- }
-
- mips_ecoff_swap_reloc_in (abfd, (PTR) ext_rel, &int_rel);
-
- h = ecoff_data (abfd)->sym_hashes[int_rel.r_symndx];
- if (h == (struct ecoff_link_hash_entry *) NULL)
- abort ();
-
- if (h->root.type != bfd_link_hash_defined
- && h->root.type != bfd_link_hash_defweak)
- {
- /* Just ignore undefined symbols. These will presumably
- generate an error later in the link. */
- continue;
- }
-
- /* Get the value of the symbol. */
- hsec = h->root.u.def.section;
- relocation = (h->root.u.def.value
- + hsec->output_section->vma
- + hsec->output_offset);
-
- /* Subtract out the current address. */
- relocation -= (sec->output_section->vma
- + sec->output_offset
- + (int_rel.r_vaddr - sec->vma));
-
- /* The addend is stored in the object file. In the normal case
- of ``bal symbol'', the addend will be -4. It will only be
- different in the case of ``bal symbol+constant''. To avoid
- always reading in the section contents, we don't check the
- addend in the object file (we could easily check the contents
- if we happen to have already read them in, but I fear that
- this could be confusing). This means we will screw up if
- there is a branch to a symbol that is in range, but added to
- a constant which puts it out of range; in such a case the
- link will fail with a reloc overflow error. Since the
- compiler will never generate such code, it should be easy
- enough to work around it by changing the assembly code in the
- source file. */
- relocation -= 4;
-
- /* Now RELOCATION is the number we want to put in the object
- file. See whether it fits. */
- if (relocation >= -0x20000 && relocation < 0x20000)
- continue;
-
- /* Now that we know this reloc needs work, which will rarely
- happen, go ahead and grab the section contents. */
- if (contents == (bfd_byte *) NULL)
- {
- if (info->keep_memory)
- contents = (bfd_byte *) bfd_alloc (abfd, sec->_raw_size);
- else
- contents = (bfd_byte *) bfd_malloc (sec->_raw_size);
- if (contents == (bfd_byte *) NULL)
- goto error_return;
- if (! bfd_get_section_contents (abfd, sec, (PTR) contents,
- (file_ptr) 0, sec->_raw_size))
- goto error_return;
- if (info->keep_memory)
- section_tdata->contents = contents;
- }
-
- /* We only support changing the bal instruction. It would be
- possible to handle other PC relative branches, but some of
- them (the conditional branches) would require a different
- length instruction sequence which would complicate both this
- routine and mips_relax_pcrel16. It could be written if
- somebody felt it were important. Ignoring this reloc will
- presumably cause a reloc overflow error later on. */
- if (bfd_get_32 (abfd, contents + int_rel.r_vaddr - sec->vma)
- != 0x0411ffff) /* bgezal $0,. == bal . */
- continue;
-
- /* Bother. We need to expand this reloc, and we will need to
- make another relaxation pass since this change may put other
- relocs out of range. We need to examine the local branches
- and we need to allocate memory to hold the offsets we must
- add to them. We also need to adjust the values of all
- symbols in the object file following this location. */
-
- sec->_cooked_size += PCREL16_EXPANSION_ADJUSTMENT;
- *again = TRUE;
-
- if (offsets == (long *) NULL)
- {
- bfd_size_type size;
-
- size = (bfd_size_type) sec->reloc_count * sizeof (long);
- offsets = (long *) bfd_zalloc (abfd, size);
- if (offsets == (long *) NULL)
- goto error_return;
- section_tdata->offsets = offsets;
- }
-
- offsets[i] = 1;
-
- /* Now look for all PC relative references that cross this reloc
- and adjust their offsets. */
- adj_ext_rel = (struct external_reloc *) section_tdata->external_relocs;
- for (adj_i = 0; adj_ext_rel < ext_rel_end; adj_ext_rel++, adj_i++)
- {
- struct internal_reloc adj_int_rel;
- bfd_vma start, stop;
- int change;
-
- mips_ecoff_swap_reloc_in (abfd, (PTR) adj_ext_rel, &adj_int_rel);
-
- if (adj_int_rel.r_type == MIPS_R_PCREL16)
- {
- unsigned long insn;
-
- /* We only care about local references. External ones
- will be relocated correctly anyhow. */
- if (adj_int_rel.r_extern)
- continue;
-
- /* We are only interested in a PC relative reloc within
- this section. FIXME: Cross section PC relative
- relocs may not be handled correctly; does anybody
- care? */
- if (adj_int_rel.r_symndx != RELOC_SECTION_TEXT)
- continue;
-
- start = adj_int_rel.r_vaddr;
-
- insn = bfd_get_32 (abfd,
- contents + adj_int_rel.r_vaddr - sec->vma);
-
- stop = (insn & 0xffff) << 2;
- if ((stop & 0x20000) != 0)
- stop -= 0x40000;
- stop += adj_int_rel.r_vaddr + 4;
- }
- else if (adj_int_rel.r_type == MIPS_R_RELHI)
- {
- struct internal_reloc rello;
- long addhi, addlo;
-
- /* The next reloc must be MIPS_R_RELLO, and we handle
- them together. */
- BFD_ASSERT (adj_ext_rel + 1 < ext_rel_end);
-
- mips_ecoff_swap_reloc_in (abfd, (PTR) (adj_ext_rel + 1), &rello);
-
- BFD_ASSERT (rello.r_type == MIPS_R_RELLO);
-
- addhi = bfd_get_32 (abfd,
- contents + adj_int_rel.r_vaddr - sec->vma);
- addhi &= 0xffff;
- if (addhi & 0x8000)
- addhi -= 0x10000;
- addhi <<= 16;
-
- addlo = bfd_get_32 (abfd, contents + rello.r_vaddr - sec->vma);
- addlo &= 0xffff;
- if (addlo & 0x8000)
- addlo -= 0x10000;
-
- if (adj_int_rel.r_extern)
- {
- /* The value we want here is
- sym - RELLOaddr + addend
- which we can express as
- sym - (RELLOaddr - addend)
- Therefore if we are expanding the area between
- RELLOaddr and RELLOaddr - addend we must adjust
- the addend. This is admittedly ambiguous, since
- we might mean (sym + addend) - RELLOaddr, but in
- practice we don't, and there is no way to handle
- that case correctly since at this point we have
- no idea whether any reloc is being expanded
- between sym and sym + addend. */
- start = rello.r_vaddr - (addhi + addlo);
- stop = rello.r_vaddr;
- }
- else
- {
- /* An internal RELHI/RELLO pair represents the
- difference between two addresses, $LC0 - foo.
- The symndx value is actually the difference
- between the reloc address and $LC0. This lets us
- compute $LC0, and, by considering the addend,
- foo. If the reloc we are expanding falls between
- those two relocs, we must adjust the addend. At
- this point, the symndx value is actually in the
- r_offset field, where it was put by
- mips_ecoff_swap_reloc_in. */
- start = rello.r_vaddr - adj_int_rel.r_offset;
- stop = start + addhi + addlo;
- }
- }
- else if (adj_int_rel.r_type == MIPS_R_SWITCH)
- {
- /* A MIPS_R_SWITCH reloc represents a word of the form
- .word $L3-$LS12
- The value in the object file is correct, assuming the
- original value of $L3. The symndx value is actually
- the difference between the reloc address and $LS12.
- This lets us compute the original value of $LS12 as
- vaddr - symndx
- and the original value of $L3 as
- vaddr - symndx + addend
- where addend is the value from the object file. At
- this point, the symndx value is actually found in the
- r_offset field, since it was moved by
- mips_ecoff_swap_reloc_in. */
- start = adj_int_rel.r_vaddr - adj_int_rel.r_offset;
- stop = start + bfd_get_32 (abfd,
- (contents
- + adj_int_rel.r_vaddr
- - sec->vma));
- }
- else
- continue;
-
- /* If the range expressed by this reloc, which is the
- distance between START and STOP crosses the reloc we are
- expanding, we must adjust the offset. The sign of the
- adjustment depends upon the direction in which the range
- crosses the reloc being expanded. */
- if (start <= int_rel.r_vaddr && stop > int_rel.r_vaddr)
- change = PCREL16_EXPANSION_ADJUSTMENT;
- else if (start > int_rel.r_vaddr && stop <= int_rel.r_vaddr)
- change = - PCREL16_EXPANSION_ADJUSTMENT;
- else
- change = 0;
-
- offsets[adj_i] += change;
-
- if (adj_int_rel.r_type == MIPS_R_RELHI)
- {
- adj_ext_rel++;
- adj_i++;
- offsets[adj_i] += change;
- }
- }
-
- /* Find all symbols in this section defined by this object file
- and adjust their values. Note that we decide whether to
- adjust the value based on the value stored in the ECOFF EXTR
- structure, because the value stored in the hash table may
- have been changed by an earlier expanded reloc and thus may
- no longer correctly indicate whether the symbol is before or
- after the expanded reloc. */
- ext_count = ecoff_data (abfd)->debug_info.symbolic_header.iextMax;
- adj_h_ptr = ecoff_data (abfd)->sym_hashes;
- adj_h_ptr_end = adj_h_ptr + ext_count;
- for (; adj_h_ptr < adj_h_ptr_end; adj_h_ptr++)
- {
- struct ecoff_link_hash_entry *adj_h;
-
- adj_h = *adj_h_ptr;
- if (adj_h != (struct ecoff_link_hash_entry *) NULL
- && (adj_h->root.type == bfd_link_hash_defined
- || adj_h->root.type == bfd_link_hash_defweak)
- && adj_h->root.u.def.section == sec
- && adj_h->esym.asym.value > int_rel.r_vaddr)
- adj_h->root.u.def.value += PCREL16_EXPANSION_ADJUSTMENT;
- }
-
- /* Add an entry to the symbol value adjust list. This is used
- by bfd_ecoff_debug_accumulate to adjust the values of
- internal symbols and FDR's. */
- amt = sizeof (struct ecoff_value_adjust);
- adjust = (struct ecoff_value_adjust *) bfd_alloc (abfd, amt);
- if (adjust == (struct ecoff_value_adjust *) NULL)
- goto error_return;
-
- adjust->start = int_rel.r_vaddr;
- adjust->end = sec->vma + sec->_raw_size;
- adjust->adjust = PCREL16_EXPANSION_ADJUSTMENT;
-
- adjust->next = ecoff_data (abfd)->debug_info.adjust;
- ecoff_data (abfd)->debug_info.adjust = adjust;
- }
-
- if (contents != (bfd_byte *) NULL && ! info->keep_memory)
- free (contents);
-
- return TRUE;
-
- error_return:
- if (contents != (bfd_byte *) NULL && ! info->keep_memory)
- free (contents);
- return FALSE;
-}
-
-/* This routine is called from mips_relocate_section when a PC
- relative reloc must be expanded into the five instruction sequence.
- It handles all the details of the expansion, including resolving
- the reloc. */
-
-static bfd_boolean
-mips_relax_pcrel16 (info, input_bfd, input_section, h, location, address)
- struct bfd_link_info *info ATTRIBUTE_UNUSED;
- bfd *input_bfd;
- asection *input_section ATTRIBUTE_UNUSED;
- struct ecoff_link_hash_entry *h;
- bfd_byte *location;
- bfd_vma address;
-{
- bfd_vma relocation;
-
- /* 0x0411ffff is bgezal $0,. == bal . */
- BFD_ASSERT (bfd_get_32 (input_bfd, location) == 0x0411ffff);
-
- /* We need to compute the distance between the symbol and the
- current address plus eight. */
- relocation = (h->root.u.def.value
- + h->root.u.def.section->output_section->vma
- + h->root.u.def.section->output_offset);
- relocation -= address + 8;
-
- /* If the lower half is negative, increment the upper 16 half. */
- if ((relocation & 0x8000) != 0)
- relocation += 0x10000;
-
- bfd_put_32 (input_bfd, (bfd_vma) 0x04110001, location); /* bal .+8 */
- bfd_put_32 (input_bfd,
- 0x3c010000 | ((relocation >> 16) & 0xffff), /* lui $at,XX */
- location + 4);
- bfd_put_32 (input_bfd,
- 0x24210000 | (relocation & 0xffff), /* addiu $at,$at,XX */
- location + 8);
- bfd_put_32 (input_bfd,
- (bfd_vma) 0x003f0821, location + 12); /* addu $at,$at,$ra */
- bfd_put_32 (input_bfd,
- (bfd_vma) 0x0020f809, location + 16); /* jalr $at */
-
- return TRUE;
-}
-
-/* Given a .sdata section and a .rel.sdata in-memory section, store
- relocation information into the .rel.sdata section which can be
- used at runtime to relocate the section. This is called by the
- linker when the --embedded-relocs switch is used. This is called
- after the add_symbols entry point has been called for all the
- objects, and before the final_link entry point is called. This
- function presumes that the object was compiled using
- -membedded-pic. */
-
-bfd_boolean
-bfd_mips_ecoff_create_embedded_relocs (abfd, info, datasec, relsec, errmsg)
- bfd *abfd;
- struct bfd_link_info *info;
- asection *datasec;
- asection *relsec;
- char **errmsg;
-{
- struct ecoff_link_hash_entry **sym_hashes;
- struct ecoff_section_tdata *section_tdata;
- struct external_reloc *ext_rel;
- struct external_reloc *ext_rel_end;
- bfd_byte *p;
- bfd_size_type amt;
-
- BFD_ASSERT (! info->relocatable);
-
- *errmsg = NULL;
-
- if (datasec->reloc_count == 0)
- return TRUE;
-
- sym_hashes = ecoff_data (abfd)->sym_hashes;
-
- if (! mips_read_relocs (abfd, datasec))
- return FALSE;
-
- amt = (bfd_size_type) datasec->reloc_count * 4;
- relsec->contents = (bfd_byte *) bfd_alloc (abfd, amt);
- if (relsec->contents == NULL)
- return FALSE;
-
- p = relsec->contents;
-
- section_tdata = ecoff_section_data (abfd, datasec);
- ext_rel = (struct external_reloc *) section_tdata->external_relocs;
- ext_rel_end = ext_rel + datasec->reloc_count;
- for (; ext_rel < ext_rel_end; ext_rel++, p += 4)
- {
- struct internal_reloc int_rel;
- bfd_boolean text_relative;
-
- mips_ecoff_swap_reloc_in (abfd, (PTR) ext_rel, &int_rel);
-
- /* We are going to write a four byte word into the runtime reloc
- section. The word will be the address in the data section
- which must be relocated. This must be on a word boundary,
- which means the lower two bits must be zero. We use the
- least significant bit to indicate how the value in the data
- section must be relocated. A 0 means that the value is
- relative to the text section, while a 1 indicates that the
- value is relative to the data section. Given that we are
- assuming the code was compiled using -membedded-pic, there
- should not be any other possibilities. */
-
- /* We can only relocate REFWORD relocs at run time. */
- if (int_rel.r_type != MIPS_R_REFWORD)
- {
- *errmsg = _("unsupported reloc type");
- bfd_set_error (bfd_error_bad_value);
- return FALSE;
- }
-
- if (int_rel.r_extern)
- {
- struct ecoff_link_hash_entry *h;
-
- h = sym_hashes[int_rel.r_symndx];
- /* If h is NULL, that means that there is a reloc against an
- external symbol which we thought was just a debugging
- symbol. This should not happen. */
- if (h == (struct ecoff_link_hash_entry *) NULL)
- abort ();
- if ((h->root.type == bfd_link_hash_defined
- || h->root.type == bfd_link_hash_defweak)
- && (h->root.u.def.section->flags & SEC_CODE) != 0)
- text_relative = TRUE;
- else
- text_relative = FALSE;
- }
- else
- {
- switch (int_rel.r_symndx)
- {
- case RELOC_SECTION_TEXT:
- text_relative = TRUE;
- break;
- case RELOC_SECTION_SDATA:
- case RELOC_SECTION_SBSS:
- case RELOC_SECTION_LIT8:
- text_relative = FALSE;
- break;
- default:
- /* No other sections should appear in -membedded-pic
- code. */
- *errmsg = _("reloc against unsupported section");
- bfd_set_error (bfd_error_bad_value);
- return FALSE;
- }
- }
-
- if ((int_rel.r_offset & 3) != 0)
- {
- *errmsg = _("reloc not properly aligned");
- bfd_set_error (bfd_error_bad_value);
- return FALSE;
- }
-
- bfd_put_32 (abfd,
- (int_rel.r_vaddr - datasec->vma + datasec->output_offset
- + (text_relative ? 0 : 1)),
- p);
- }
-
- return TRUE;
-}
-
/* This is the ECOFF backend structure. The backend field of the
target vector points to this. */
@@ -2557,7 +1385,7 @@ static const struct ecoff_backend_data mips_ecoff_backend_data =
_bfd_generic_get_section_contents_in_window
/* Relaxing sections is MIPS specific. */
-#define _bfd_ecoff_bfd_relax_section mips_relax_section
+#define _bfd_ecoff_bfd_relax_section bfd_generic_relax_section
/* GC of sections is not done. */
#define _bfd_ecoff_bfd_gc_sections bfd_generic_gc_sections
@@ -2565,6 +1393,7 @@ static const struct ecoff_backend_data mips_ecoff_backend_data =
/* Merging of sections is not done. */
#define _bfd_ecoff_bfd_merge_sections bfd_generic_merge_sections
+#define _bfd_ecoff_bfd_is_group_section bfd_generic_is_group_section
#define _bfd_ecoff_bfd_discard_group bfd_generic_discard_group
extern const bfd_target ecoff_big_vec;
diff --git a/bfd/coff-rs6000.c b/bfd/coff-rs6000.c
index 56e34e2..22d47c5 100644
--- a/bfd/coff-rs6000.c
+++ b/bfd/coff-rs6000.c
@@ -1,5 +1,5 @@
/* BFD back-end for IBM RS/6000 "XCOFF" files.
- Copyright 1990-1999, 2000, 2001, 2002, 2003
+ Copyright 1990-1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
FIXME: Can someone provide a transliteration of this name into ASCII?
Using the following chars caused a compiler warning on HIUX (so I replaced
@@ -4196,11 +4196,13 @@ const bfd_target rs6000coff_vec =
_bfd_generic_link_split_section,
bfd_generic_gc_sections,
bfd_generic_merge_sections,
+ bfd_generic_is_group_section,
bfd_generic_discard_group,
/* Dynamic */
_bfd_xcoff_get_dynamic_symtab_upper_bound,
_bfd_xcoff_canonicalize_dynamic_symtab,
+ _bfd_nodynamic_get_synthetic_symtab,
_bfd_xcoff_get_dynamic_reloc_upper_bound,
_bfd_xcoff_canonicalize_dynamic_reloc,
@@ -4438,11 +4440,13 @@ const bfd_target pmac_xcoff_vec =
_bfd_generic_link_split_section,
bfd_generic_gc_sections,
bfd_generic_merge_sections,
+ bfd_generic_is_group_section,
bfd_generic_discard_group,
/* Dynamic */
_bfd_xcoff_get_dynamic_symtab_upper_bound,
_bfd_xcoff_canonicalize_dynamic_symtab,
+ _bfd_nodynamic_get_synthetic_symtab,
_bfd_xcoff_get_dynamic_reloc_upper_bound,
_bfd_xcoff_canonicalize_dynamic_reloc,
diff --git a/bfd/coff64-rs6000.c b/bfd/coff64-rs6000.c
index ec9c695..857a4b4 100644
--- a/bfd/coff64-rs6000.c
+++ b/bfd/coff64-rs6000.c
@@ -1,5 +1,5 @@
/* BFD back-end for IBM RS/6000 "XCOFF64" files.
- Copyright 2000, 2001, 2002, 2003
+ Copyright 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Written Clinton Popetz.
Contributed by Cygnus Support.
@@ -2737,11 +2737,13 @@ const bfd_target rs6000coff64_vec =
_bfd_generic_link_split_section,
bfd_generic_gc_sections,
bfd_generic_merge_sections,
+ bfd_generic_is_group_section,
bfd_generic_discard_group,
/* Dynamic */
_bfd_xcoff_get_dynamic_symtab_upper_bound,
_bfd_xcoff_canonicalize_dynamic_symtab,
+ _bfd_nodynamic_get_synthetic_symtab,
_bfd_xcoff_get_dynamic_reloc_upper_bound,
_bfd_xcoff_canonicalize_dynamic_reloc,
@@ -2980,11 +2982,13 @@ const bfd_target aix5coff64_vec =
_bfd_generic_link_split_section,
bfd_generic_gc_sections,
bfd_generic_merge_sections,
+ bfd_generic_is_group_section,
bfd_generic_discard_group,
/* Dynamic */
_bfd_xcoff_get_dynamic_symtab_upper_bound,
_bfd_xcoff_canonicalize_dynamic_symtab,
+ _bfd_nodynamic_get_synthetic_symtab,
_bfd_xcoff_get_dynamic_reloc_upper_bound,
_bfd_xcoff_canonicalize_dynamic_reloc,
diff --git a/bfd/coffcode.h b/bfd/coffcode.h
index 15d9709..d495b53 100644
--- a/bfd/coffcode.h
+++ b/bfd/coffcode.h
@@ -1,6 +1,6 @@
/* Support for the generic parts of most COFF variants, for BFD.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003
+ 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Written by Cygnus Support.
@@ -309,6 +309,9 @@ CODE_FRAGMENT
#define STRING_SIZE_SIZE (4)
+#define DOT_DEBUG ".debug"
+#define GNU_LINKONCE_WI ".gnu.linkonce.wi."
+
static long sec_to_styp_flags
PARAMS ((const char *, flagword));
static bfd_boolean styp_to_sec_flags
@@ -428,7 +431,7 @@ sec_to_styp_flags (sec_name, sec_flags)
styp_flags = STYP_LIT;
#endif /* _LIT */
}
- else if (!strncmp (sec_name, ".debug", 6))
+ else if (!strncmp (sec_name, DOT_DEBUG, sizeof (DOT_DEBUG) - 1))
{
/* Handle the XCOFF debug section and DWARF2 debug sections. */
if (!sec_name[6])
@@ -441,7 +444,7 @@ sec_to_styp_flags (sec_name, sec_flags)
styp_flags = STYP_DEBUG_INFO;
}
#ifdef COFF_LONG_SECTION_NAMES
- else if (!strncmp (sec_name, ".gnu.linkonce.wi.", 17))
+ else if (!strncmp (sec_name, GNU_LINKONCE_WI, sizeof (GNU_LINKONCE_WI) - 1))
{
styp_flags = STYP_DEBUG_INFO;
}
@@ -518,7 +521,7 @@ sec_to_styp_flags (sec_name, sec_flags)
static long
sec_to_styp_flags (sec_name, sec_flags)
- const char *sec_name ATTRIBUTE_UNUSED;
+ const char *sec_name;
flagword sec_flags;
{
long styp_flags = 0;
@@ -531,6 +534,11 @@ sec_to_styp_flags (sec_name, sec_flags)
PE files. The STYP_* flags and the IMAGE_SCN_* flags overlap,
but there are more IMAGE_SCN_* flags. */
+ /* FIXME: There is no gas syntax to specify the debug section flag. */
+ if (strncmp (sec_name, DOT_DEBUG, sizeof (DOT_DEBUG) - 1) == 0
+ || strncmp (sec_name, GNU_LINKONCE_WI, sizeof (GNU_LINKONCE_WI) - 1) == 0)
+ sec_flags = SEC_READONLY | SEC_DEBUGGING;
+
/* skip LOAD */
/* READONLY later */
/* skip RELOC */
@@ -675,12 +683,12 @@ styp_to_sec_flags (abfd, hdr, name, section, flags_ptr)
#endif
sec_flags |= SEC_ALLOC;
}
- else if (strncmp (name, ".debug", 6) == 0
+ else if (strncmp (name, DOT_DEBUG, sizeof (DOT_DEBUG) - 1) == 0
#ifdef _COMMENT
|| strcmp (name, _COMMENT) == 0
#endif
#ifdef COFF_LONG_SECTION_NAMES
- || strncmp (name, ".gnu.linkonce.wi.", 17) == 0
+ || strncmp (name, GNU_LINKONCE_WI, sizeof (GNU_LINKONCE_WI) - 1) == 0
#endif
|| strncmp (name, ".stab", 5) == 0)
{
@@ -3004,7 +3012,7 @@ coff_compute_section_file_positions (abfd)
{
asection *dsec;
- dsec = bfd_make_section_old_way (abfd, ".debug");
+ dsec = bfd_make_section_old_way (abfd, DOT_DEBUG);
if (dsec == NULL)
abort ();
dsec->_raw_size = sz;
@@ -5556,6 +5564,10 @@ static const bfd_coff_backend_data ticoff1_swap_table =
#define coff_bfd_merge_sections bfd_generic_merge_sections
#endif
+#ifndef coff_bfd_is_group_section
+#define coff_bfd_is_group_section bfd_generic_is_group_section
+#endif
+
#ifndef coff_bfd_discard_group
#define coff_bfd_discard_group bfd_generic_discard_group
#endif
diff --git a/bfd/config.bfd b/bfd/config.bfd
index 2f9c197..a158ca6 100644
--- a/bfd/config.bfd
+++ b/bfd/config.bfd
@@ -89,12 +89,17 @@ esac
case "${targ}" in
mips*-dec-bsd*)
- echo "This target is obsolete and has been removed."
+ echo "This target is obsolete and has been removed."
+ exit 1
+ ;;
+
+ mips*-*-mach3*)
+ echo "This target is obsolete and has been removed."
exit 1
;;
mips*-*-pe*)
- echo "This target is obsolete and has been removed."
+ echo "This target is obsolete and has been removed."
exit 1
;;
@@ -306,6 +311,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"
@@ -762,10 +772,6 @@ case "${targ}" in
targ_defvec=bfd_elf32_bigmips_vec
targ_selvecs="bfd_elf32_littlemips_vec bfd_elf64_bigmips_vec bfd_elf64_littlemips_vec ecoff_big_vec ecoff_little_vec"
;;
- mips*-dec-mach3*)
- targ_defvec=aout_mips_little_vec
- targ_cflags=-DSTAT_FOR_EXEC
- ;;
mips*-dec-* | mips*el-*-ecoff*)
targ_defvec=ecoff_little_vec
targ_selvecs=ecoff_big_vec
@@ -792,10 +798,6 @@ case "${targ}" in
targ_defvec=ecoff_biglittle_vec
targ_selvecs="ecoff_little_vec ecoff_big_vec"
;;
- mips*-*-mach3*)
- targ_defvec=aout_mips_little_vec
- targ_cflags=-DSTAT_FOR_EXEC
- ;;
mips*-*-sysv4*)
targ_defvec=bfd_elf32_tradbigmips_vec
targ_selvecs="bfd_elf32_tradlittlemips_vec ecoff_big_vec ecoff_little_vec"
@@ -969,7 +971,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/config.in b/bfd/config.in
index ef9eca4..3224539 100644
--- a/bfd/config.in
+++ b/bfd/config.in
@@ -172,9 +172,15 @@
/* Define if you have the <sys/procfs.h> header file. */
#undef HAVE_SYS_PROCFS_H
+/* Define if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
/* Define if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
+/* Define if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
/* Define if you have the <time.h> header file. */
#undef HAVE_TIME_H
diff --git a/bfd/configure b/bfd/configure
index 424dba9..8bbd2b7 100755
--- a/bfd/configure
+++ b/bfd/configure
@@ -919,7 +919,7 @@ fi
PACKAGE=bfd
-VERSION=2.14.90
+VERSION=2.15.91
if test "`cd $srcdir && pwd`" != "`pwd`" && test -f $srcdir/config.status; then
{ echo "configure: error: source directory already configured; run "make distclean" there first" 1>&2; exit 1; }
@@ -3327,7 +3327,7 @@ EOF
fi
-for ac_hdr in stdlib.h unistd.h sys/stat.h sys/types.h
+for ac_hdr in unistd.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
@@ -3459,24 +3459,11 @@ else
#include <fcntl.h>
#include <sys/mman.h>
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-
-#if HAVE_STDLIB_H
-# include <stdlib.h>
-#endif
-
-#if HAVE_SYS_STAT_H
-# include <sys/stat.h>
-#endif
-
-#if HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
/* This mess was copied from the GNU getpagesize.h. */
#ifndef HAVE_GETPAGESIZE
+# ifdef HAVE_UNISTD_H
+# include <unistd.h>
+# endif
/* Assume that all systems that can run configure have sys/param.h. */
# ifndef HAVE_SYS_PARAM_H
@@ -3584,7 +3571,7 @@ main()
}
EOF
-if { (eval echo configure:3588: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3575: \"$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
@@ -3612,17 +3599,17 @@ unistd.h values.h sys/param.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:3616: checking for $ac_hdr" >&5
+echo "configure:3603: 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 3621 "configure"
+#line 3608 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3626: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3613: \"$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*
@@ -3652,12 +3639,12 @@ done
__argz_count __argz_stringify __argz_next
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:3656: checking for $ac_func" >&5
+echo "configure:3643: 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 3661 "configure"
+#line 3648 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -3680,7 +3667,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:3684: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3671: \"$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
@@ -3709,12 +3696,12 @@ done
for ac_func in stpcpy
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:3713: checking for $ac_func" >&5
+echo "configure:3700: 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 3718 "configure"
+#line 3705 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -3737,7 +3724,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:3741: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3728: \"$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
@@ -3771,19 +3758,19 @@ EOF
if test $ac_cv_header_locale_h = yes; then
echo $ac_n "checking for LC_MESSAGES""... $ac_c" 1>&6
-echo "configure:3775: checking for LC_MESSAGES" >&5
+echo "configure:3762: checking for LC_MESSAGES" >&5
if eval "test \"`echo '$''{'am_cv_val_LC_MESSAGES'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 3780 "configure"
+#line 3767 "configure"
#include "confdefs.h"
#include <locale.h>
int main() {
return LC_MESSAGES
; return 0; }
EOF
-if { (eval echo configure:3787: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3774: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
am_cv_val_LC_MESSAGES=yes
else
@@ -3804,7 +3791,7 @@ EOF
fi
fi
echo $ac_n "checking whether NLS is requested""... $ac_c" 1>&6
-echo "configure:3808: checking whether NLS is requested" >&5
+echo "configure:3795: checking whether NLS is requested" >&5
# Check whether --enable-nls or --disable-nls was given.
if test "${enable_nls+set}" = set; then
enableval="$enable_nls"
@@ -3824,7 +3811,7 @@ fi
EOF
echo $ac_n "checking whether included gettext is requested""... $ac_c" 1>&6
-echo "configure:3828: checking whether included gettext is requested" >&5
+echo "configure:3815: checking whether included gettext is requested" >&5
# Check whether --with-included-gettext or --without-included-gettext was given.
if test "${with_included_gettext+set}" = set; then
withval="$with_included_gettext"
@@ -3843,17 +3830,17 @@ fi
ac_safe=`echo "libintl.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for libintl.h""... $ac_c" 1>&6
-echo "configure:3847: checking for libintl.h" >&5
+echo "configure:3834: checking for libintl.h" >&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 3852 "configure"
+#line 3839 "configure"
#include "confdefs.h"
#include <libintl.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:3857: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:3844: \"$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*
@@ -3870,19 +3857,19 @@ fi
if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
echo "$ac_t""yes" 1>&6
echo $ac_n "checking for gettext in libc""... $ac_c" 1>&6
-echo "configure:3874: checking for gettext in libc" >&5
+echo "configure:3861: checking for gettext in libc" >&5
if eval "test \"`echo '$''{'gt_cv_func_gettext_libc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 3879 "configure"
+#line 3866 "configure"
#include "confdefs.h"
#include <libintl.h>
int main() {
return (int) gettext ("")
; return 0; }
EOF
-if { (eval echo configure:3886: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3873: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
gt_cv_func_gettext_libc=yes
else
@@ -3898,7 +3885,7 @@ echo "$ac_t""$gt_cv_func_gettext_libc" 1>&6
if test "$gt_cv_func_gettext_libc" != "yes"; then
echo $ac_n "checking for bindtextdomain in -lintl""... $ac_c" 1>&6
-echo "configure:3902: checking for bindtextdomain in -lintl" >&5
+echo "configure:3889: checking for bindtextdomain in -lintl" >&5
ac_lib_var=`echo intl'_'bindtextdomain | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -3906,7 +3893,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lintl $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 3910 "configure"
+#line 3897 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -3917,7 +3904,7 @@ int main() {
bindtextdomain()
; return 0; }
EOF
-if { (eval echo configure:3921: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3908: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -3933,19 +3920,19 @@ fi
if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then
echo "$ac_t""yes" 1>&6
echo $ac_n "checking for gettext in libintl""... $ac_c" 1>&6
-echo "configure:3937: checking for gettext in libintl" >&5
+echo "configure:3924: checking for gettext in libintl" >&5
if eval "test \"`echo '$''{'gt_cv_func_gettext_libintl'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 3942 "configure"
+#line 3929 "configure"
#include "confdefs.h"
int main() {
return (int) gettext ("")
; return 0; }
EOF
-if { (eval echo configure:3949: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3936: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
gt_cv_func_gettext_libintl=yes
else
@@ -3973,7 +3960,7 @@ EOF
# Extract the first word of "msgfmt", so it can be a program name with args.
set dummy msgfmt; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:3977: checking for $ac_word" >&5
+echo "configure:3964: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4007,12 +3994,12 @@ fi
for ac_func in dcgettext
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4011: checking for $ac_func" >&5
+echo "configure:3998: 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 4016 "configure"
+#line 4003 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -4035,7 +4022,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:4039: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4026: \"$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
@@ -4062,7 +4049,7 @@ done
# Extract the first word of "gmsgfmt", so it can be a program name with args.
set dummy gmsgfmt; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4066: checking for $ac_word" >&5
+echo "configure:4053: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4098,7 +4085,7 @@ fi
# Extract the first word of "xgettext", so it can be a program name with args.
set dummy xgettext; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4102: checking for $ac_word" >&5
+echo "configure:4089: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4130,7 +4117,7 @@ else
fi
cat > conftest.$ac_ext <<EOF
-#line 4134 "configure"
+#line 4121 "configure"
#include "confdefs.h"
int main() {
@@ -4138,7 +4125,7 @@ extern int _nl_msg_cat_cntr;
return _nl_msg_cat_cntr
; return 0; }
EOF
-if { (eval echo configure:4142: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4129: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
CATOBJEXT=.gmo
DATADIRNAME=share
@@ -4170,7 +4157,7 @@ fi
# Extract the first word of "msgfmt", so it can be a program name with args.
set dummy msgfmt; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4174: checking for $ac_word" >&5
+echo "configure:4161: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_MSGFMT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4204,7 +4191,7 @@ fi
# Extract the first word of "gmsgfmt", so it can be a program name with args.
set dummy gmsgfmt; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4208: checking for $ac_word" >&5
+echo "configure:4195: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_GMSGFMT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4240,7 +4227,7 @@ fi
# Extract the first word of "xgettext", so it can be a program name with args.
set dummy xgettext; ac_word=$2
echo $ac_n "checking for $ac_word""... $ac_c" 1>&6
-echo "configure:4244: checking for $ac_word" >&5
+echo "configure:4231: checking for $ac_word" >&5
if eval "test \"`echo '$''{'ac_cv_path_XGETTEXT'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4330,7 +4317,7 @@ fi
LINGUAS=
else
echo $ac_n "checking for catalogs to be installed""... $ac_c" 1>&6
-echo "configure:4334: checking for catalogs to be installed" >&5
+echo "configure:4321: checking for catalogs to be installed" >&5
NEW_LINGUAS=
for lang in ${LINGUAS=$ALL_LINGUAS}; do
case "$ALL_LINGUAS" in
@@ -4358,17 +4345,17 @@ echo "configure:4334: checking for catalogs to be installed" >&5
if test "$CATOBJEXT" = ".cat"; then
ac_safe=`echo "linux/version.h" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for linux/version.h""... $ac_c" 1>&6
-echo "configure:4362: checking for linux/version.h" >&5
+echo "configure:4349: checking for linux/version.h" >&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 4367 "configure"
+#line 4354 "configure"
#include "confdefs.h"
#include <linux/version.h>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:4372: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:4359: \"$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*
@@ -4446,7 +4433,7 @@ fi
# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff"
# ./install, which can be erroneously created by make from ./install.sh.
echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6
-echo "configure:4450: checking for a BSD compatible install" >&5
+echo "configure:4437: checking for a BSD compatible install" >&5
if test -z "$INSTALL"; then
if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -4506,19 +4493,19 @@ BFD_HOST_64_BIT=
BFD_HOST_U_64_BIT=
echo $ac_n "checking for long long""... $ac_c" 1>&6
-echo "configure:4510: checking for long long" >&5
+echo "configure:4497: checking for long long" >&5
if eval "test \"`echo '$''{'bfd_cv_has_long_long'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 4515 "configure"
+#line 4502 "configure"
#include "confdefs.h"
int main() {
unsigned long long ll = 18446744073709551615ULL;
; return 0; }
EOF
-if { (eval echo configure:4522: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4509: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
bfd_cv_has_long_long=yes
else
@@ -4534,13 +4521,13 @@ echo "$ac_t""$bfd_cv_has_long_long" 1>&6
if test $bfd_cv_has_long_long = yes; then
BFD_HOST_LONG_LONG=1
echo $ac_n "checking size of long long""... $ac_c" 1>&6
-echo "configure:4538: checking size of long long" >&5
+echo "configure:4525: checking size of long long" >&5
if eval "test \"`echo '$''{'ac_cv_sizeof_long_long'+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 4544 "configure"
+#line 4531 "configure"
#include "confdefs.h"
#include "confdefs.h"
#include <sys/types.h>
@@ -4550,7 +4537,7 @@ int main() {
switch (0) case 0: case (sizeof (long long) == $ac_size):;
; return 0; }
EOF
-if { (eval echo configure:4554: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4541: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_sizeof_long_long=$ac_size
else
@@ -4575,13 +4562,13 @@ EOF
fi
echo $ac_n "checking size of long""... $ac_c" 1>&6
-echo "configure:4579: checking size of long" >&5
+echo "configure:4566: checking size of long" >&5
if eval "test \"`echo '$''{'ac_cv_sizeof_long'+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 4585 "configure"
+#line 4572 "configure"
#include "confdefs.h"
#include "confdefs.h"
#include <sys/types.h>
@@ -4591,7 +4578,7 @@ int main() {
switch (0) case 0: case (sizeof (long) == $ac_size):;
; return 0; }
EOF
-if { (eval echo configure:4595: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4582: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_sizeof_long=$ac_size
else
@@ -4649,7 +4636,7 @@ if test "x$cross_compiling" = "xno"; then
EXEEXT_FOR_BUILD='$(EXEEXT)'
else
echo $ac_n "checking for build system executable suffix""... $ac_c" 1>&6
-echo "configure:4653: checking for build system executable suffix" >&5
+echo "configure:4640: checking for build system executable suffix" >&5
if eval "test \"`echo '$''{'bfd_cv_build_exeext'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4677,17 +4664,17 @@ for ac_hdr in stddef.h string.h strings.h stdlib.h time.h unistd.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:4681: checking for $ac_hdr" >&5
+echo "configure:4668: 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 4686 "configure"
+#line 4673 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:4691: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:4678: \"$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*
@@ -4717,17 +4704,17 @@ for ac_hdr in fcntl.h sys/file.h sys/time.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:4721: checking for $ac_hdr" >&5
+echo "configure:4708: 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 4726 "configure"
+#line 4713 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:4731: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:4718: \"$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*
@@ -4754,12 +4741,12 @@ fi
done
echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6
-echo "configure:4758: checking whether time.h and sys/time.h may both be included" >&5
+echo "configure:4745: checking whether time.h and sys/time.h may both be included" >&5
if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 4763 "configure"
+#line 4750 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/time.h>
@@ -4768,7 +4755,7 @@ int main() {
struct tm *tp;
; return 0; }
EOF
-if { (eval echo configure:4772: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4759: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_header_time=yes
else
@@ -4793,12 +4780,12 @@ for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6
-echo "configure:4797: checking for $ac_hdr that defines DIR" >&5
+echo "configure:4784: checking for $ac_hdr that defines DIR" >&5
if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 4802 "configure"
+#line 4789 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <$ac_hdr>
@@ -4806,7 +4793,7 @@ int main() {
DIR *dirp = 0;
; return 0; }
EOF
-if { (eval echo configure:4810: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:4797: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
eval "ac_cv_header_dirent_$ac_safe=yes"
else
@@ -4831,7 +4818,7 @@ done
# Two versions of opendir et al. are in -ldir and -lx on SCO Xenix.
if test $ac_header_dirent = dirent.h; then
echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6
-echo "configure:4835: checking for opendir in -ldir" >&5
+echo "configure:4822: checking for opendir in -ldir" >&5
ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -4839,7 +4826,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-ldir $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 4843 "configure"
+#line 4830 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -4850,7 +4837,7 @@ int main() {
opendir()
; return 0; }
EOF
-if { (eval echo configure:4854: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4841: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -4872,7 +4859,7 @@ fi
else
echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6
-echo "configure:4876: checking for opendir in -lx" >&5
+echo "configure:4863: checking for opendir in -lx" >&5
ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -4880,7 +4867,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lx $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 4884 "configure"
+#line 4871 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -4891,7 +4878,7 @@ int main() {
opendir()
; return 0; }
EOF
-if { (eval echo configure:4895: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4882: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -4916,12 +4903,12 @@ fi
for ac_func in fcntl getpagesize setitimer sysconf fdopen getuid getgid
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4920: checking for $ac_func" >&5
+echo "configure:4907: 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 4925 "configure"
+#line 4912 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -4944,7 +4931,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:4948: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4935: \"$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
@@ -4971,12 +4958,12 @@ done
for ac_func in strtoull
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4975: checking for $ac_func" >&5
+echo "configure:4962: 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 4980 "configure"
+#line 4967 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -4999,7 +4986,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:5003: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4990: \"$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
@@ -5034,12 +5021,12 @@ EOF
esac
echo $ac_n "checking whether strstr must be declared""... $ac_c" 1>&6
-echo "configure:5038: checking whether strstr must be declared" >&5
+echo "configure:5025: checking whether strstr must be declared" >&5
if eval "test \"`echo '$''{'bfd_cv_decl_needed_strstr'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 5043 "configure"
+#line 5030 "configure"
#include "confdefs.h"
#include <stdio.h>
@@ -5060,7 +5047,7 @@ int main() {
char *(*pfn) = (char *(*)) strstr
; return 0; }
EOF
-if { (eval echo configure:5064: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5051: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
bfd_cv_decl_needed_strstr=no
else
@@ -5081,12 +5068,12 @@ EOF
fi
echo $ac_n "checking whether malloc must be declared""... $ac_c" 1>&6
-echo "configure:5085: checking whether malloc must be declared" >&5
+echo "configure:5072: checking whether malloc must be declared" >&5
if eval "test \"`echo '$''{'bfd_cv_decl_needed_malloc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 5090 "configure"
+#line 5077 "configure"
#include "confdefs.h"
#include <stdio.h>
@@ -5107,7 +5094,7 @@ int main() {
char *(*pfn) = (char *(*)) malloc
; return 0; }
EOF
-if { (eval echo configure:5111: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5098: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
bfd_cv_decl_needed_malloc=no
else
@@ -5128,12 +5115,12 @@ EOF
fi
echo $ac_n "checking whether realloc must be declared""... $ac_c" 1>&6
-echo "configure:5132: checking whether realloc must be declared" >&5
+echo "configure:5119: checking whether realloc must be declared" >&5
if eval "test \"`echo '$''{'bfd_cv_decl_needed_realloc'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 5137 "configure"
+#line 5124 "configure"
#include "confdefs.h"
#include <stdio.h>
@@ -5154,7 +5141,7 @@ int main() {
char *(*pfn) = (char *(*)) realloc
; return 0; }
EOF
-if { (eval echo configure:5158: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5145: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
bfd_cv_decl_needed_realloc=no
else
@@ -5175,12 +5162,12 @@ EOF
fi
echo $ac_n "checking whether free must be declared""... $ac_c" 1>&6
-echo "configure:5179: checking whether free must be declared" >&5
+echo "configure:5166: checking whether free must be declared" >&5
if eval "test \"`echo '$''{'bfd_cv_decl_needed_free'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 5184 "configure"
+#line 5171 "configure"
#include "confdefs.h"
#include <stdio.h>
@@ -5201,7 +5188,7 @@ int main() {
char *(*pfn) = (char *(*)) free
; return 0; }
EOF
-if { (eval echo configure:5205: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5192: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
bfd_cv_decl_needed_free=no
else
@@ -5222,12 +5209,12 @@ EOF
fi
echo $ac_n "checking whether getenv must be declared""... $ac_c" 1>&6
-echo "configure:5226: checking whether getenv must be declared" >&5
+echo "configure:5213: checking whether getenv must be declared" >&5
if eval "test \"`echo '$''{'bfd_cv_decl_needed_getenv'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 5231 "configure"
+#line 5218 "configure"
#include "confdefs.h"
#include <stdio.h>
@@ -5248,7 +5235,7 @@ int main() {
char *(*pfn) = (char *(*)) getenv
; return 0; }
EOF
-if { (eval echo configure:5252: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5239: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
bfd_cv_decl_needed_getenv=no
else
@@ -5348,14 +5335,6 @@ if test "${target}" = "${host}"; then
COREFILE=trad-core.lo
TRAD_HEADER='"hosts/i860mach3.h"'
;;
- mips-dec-bsd*)
- COREFILE=trad-core.lo
- TRAD_HEADER='"hosts/mipsbsd.h"'
- ;;
- mips-dec-mach3*)
- COREFILE=trad-core.lo
- TRAD_HEADER='"hosts/mipsmach3.h"'
- ;;
mips-*-netbsd* | mips*-*-openbsd*)
COREFILE=netbsd-core.lo
;;
@@ -5366,10 +5345,6 @@ if test "${target}" = "${host}"; then
mips-sgi-irix4*) COREFILE=irix-core.lo ;;
mips-sgi-irix5*) COREFILE=irix-core.lo ;;
mips-sgi-irix6*) COREFILE=irix-core.lo ;;
- mips-*-mach3*)
- COREFILE=trad-core.lo
- TRAD_HEADER='"hosts/mipsmach3.h"'
- ;;
mips-*-sysv4*) ;;
mips-*-sysv* | mips-*-riscos*)
COREFILE=trad-core.lo
@@ -5436,16 +5411,16 @@ if test "${target}" = "${host}"; then
# Not all versions of AIX with -DAIX_CORE_DUMPX_CORE
# have c_impl as a member of struct core_dumpx
echo $ac_n "checking for c_impl in struct core_dumpx""... $ac_c" 1>&6
-echo "configure:5440: checking for c_impl in struct core_dumpx" >&5
+echo "configure:5415: checking for c_impl in struct core_dumpx" >&5
cat > conftest.$ac_ext <<EOF
-#line 5442 "configure"
+#line 5417 "configure"
#include "confdefs.h"
#include <core.h>
int main() {
struct core_dumpx c; c.c_impl = 0;
; return 0; }
EOF
-if { (eval echo configure:5449: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5424: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
cat >> confdefs.h <<\EOF
#define HAVE_ST_C_IMPL 1
@@ -5522,17 +5497,17 @@ rm -f conftest*
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
-echo "configure:5526: checking for $ac_hdr" >&5
+echo "configure:5501: 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 5531 "configure"
+#line 5506 "configure"
#include "confdefs.h"
#include <$ac_hdr>
EOF
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
-{ (eval echo configure:5536: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+{ (eval echo configure:5511: \"$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*
@@ -5560,12 +5535,12 @@ done
if test "$ac_cv_header_sys_procfs_h" = yes; then
echo $ac_n "checking for prstatus_t in sys/procfs.h""... $ac_c" 1>&6
-echo "configure:5564: checking for prstatus_t in sys/procfs.h" >&5
+echo "configure:5539: checking for prstatus_t in sys/procfs.h" >&5
if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_prstatus_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 5569 "configure"
+#line 5544 "configure"
#include "confdefs.h"
#define _SYSCALL32
@@ -5574,7 +5549,7 @@ int main() {
prstatus_t avar
; return 0; }
EOF
-if { (eval echo configure:5578: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5553: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
bfd_cv_have_sys_procfs_type_prstatus_t=yes
else
@@ -5596,12 +5571,12 @@ EOF
echo "$ac_t""$bfd_cv_have_sys_procfs_type_prstatus_t" 1>&6
echo $ac_n "checking for prstatus32_t in sys/procfs.h""... $ac_c" 1>&6
-echo "configure:5600: checking for prstatus32_t in sys/procfs.h" >&5
+echo "configure:5575: checking for prstatus32_t in sys/procfs.h" >&5
if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_prstatus32_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 5605 "configure"
+#line 5580 "configure"
#include "confdefs.h"
#define _SYSCALL32
@@ -5610,7 +5585,7 @@ int main() {
prstatus32_t avar
; return 0; }
EOF
-if { (eval echo configure:5614: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5589: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
bfd_cv_have_sys_procfs_type_prstatus32_t=yes
else
@@ -5632,12 +5607,12 @@ EOF
echo "$ac_t""$bfd_cv_have_sys_procfs_type_prstatus32_t" 1>&6
echo $ac_n "checking for prstatus_t.pr_who in sys/procfs.h""... $ac_c" 1>&6
-echo "configure:5636: checking for prstatus_t.pr_who in sys/procfs.h" >&5
+echo "configure:5611: checking for prstatus_t.pr_who in sys/procfs.h" >&5
if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_member_prstatus_t_pr_who'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 5641 "configure"
+#line 5616 "configure"
#include "confdefs.h"
#define _SYSCALL32
@@ -5646,7 +5621,7 @@ int main() {
prstatus_t avar; void* aref = (void*) &avar.pr_who
; return 0; }
EOF
-if { (eval echo configure:5650: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5625: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
bfd_cv_have_sys_procfs_type_member_prstatus_t_pr_who=yes
else
@@ -5668,12 +5643,12 @@ EOF
echo "$ac_t""$bfd_cv_have_sys_procfs_type_member_prstatus_t_pr_who" 1>&6
echo $ac_n "checking for prstatus32_t.pr_who in sys/procfs.h""... $ac_c" 1>&6
-echo "configure:5672: checking for prstatus32_t.pr_who in sys/procfs.h" >&5
+echo "configure:5647: checking for prstatus32_t.pr_who in sys/procfs.h" >&5
if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_member_prstatus32_t_pr_who'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 5677 "configure"
+#line 5652 "configure"
#include "confdefs.h"
#define _SYSCALL32
@@ -5682,7 +5657,7 @@ int main() {
prstatus32_t avar; void* aref = (void*) &avar.pr_who
; return 0; }
EOF
-if { (eval echo configure:5686: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5661: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
bfd_cv_have_sys_procfs_type_member_prstatus32_t_pr_who=yes
else
@@ -5704,12 +5679,12 @@ EOF
echo "$ac_t""$bfd_cv_have_sys_procfs_type_member_prstatus32_t_pr_who" 1>&6
echo $ac_n "checking for pstatus_t in sys/procfs.h""... $ac_c" 1>&6
-echo "configure:5708: checking for pstatus_t in sys/procfs.h" >&5
+echo "configure:5683: checking for pstatus_t in sys/procfs.h" >&5
if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_pstatus_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 5713 "configure"
+#line 5688 "configure"
#include "confdefs.h"
#define _SYSCALL32
@@ -5718,7 +5693,7 @@ int main() {
pstatus_t avar
; return 0; }
EOF
-if { (eval echo configure:5722: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5697: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
bfd_cv_have_sys_procfs_type_pstatus_t=yes
else
@@ -5740,12 +5715,12 @@ EOF
echo "$ac_t""$bfd_cv_have_sys_procfs_type_pstatus_t" 1>&6
echo $ac_n "checking for pxstatus_t in sys/procfs.h""... $ac_c" 1>&6
-echo "configure:5744: checking for pxstatus_t in sys/procfs.h" >&5
+echo "configure:5719: checking for pxstatus_t in sys/procfs.h" >&5
if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_pxstatus_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 5749 "configure"
+#line 5724 "configure"
#include "confdefs.h"
#define _SYSCALL32
@@ -5754,7 +5729,7 @@ int main() {
pxstatus_t avar
; return 0; }
EOF
-if { (eval echo configure:5758: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5733: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
bfd_cv_have_sys_procfs_type_pxstatus_t=yes
else
@@ -5776,12 +5751,12 @@ EOF
echo "$ac_t""$bfd_cv_have_sys_procfs_type_pxstatus_t" 1>&6
echo $ac_n "checking for pstatus32_t in sys/procfs.h""... $ac_c" 1>&6
-echo "configure:5780: checking for pstatus32_t in sys/procfs.h" >&5
+echo "configure:5755: checking for pstatus32_t in sys/procfs.h" >&5
if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_pstatus32_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 5785 "configure"
+#line 5760 "configure"
#include "confdefs.h"
#define _SYSCALL32
@@ -5790,7 +5765,7 @@ int main() {
pstatus32_t avar
; return 0; }
EOF
-if { (eval echo configure:5794: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5769: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
bfd_cv_have_sys_procfs_type_pstatus32_t=yes
else
@@ -5812,12 +5787,12 @@ EOF
echo "$ac_t""$bfd_cv_have_sys_procfs_type_pstatus32_t" 1>&6
echo $ac_n "checking for prpsinfo_t in sys/procfs.h""... $ac_c" 1>&6
-echo "configure:5816: checking for prpsinfo_t in sys/procfs.h" >&5
+echo "configure:5791: checking for prpsinfo_t in sys/procfs.h" >&5
if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_prpsinfo_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 5821 "configure"
+#line 5796 "configure"
#include "confdefs.h"
#define _SYSCALL32
@@ -5826,7 +5801,7 @@ int main() {
prpsinfo_t avar
; return 0; }
EOF
-if { (eval echo configure:5830: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5805: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
bfd_cv_have_sys_procfs_type_prpsinfo_t=yes
else
@@ -5848,12 +5823,12 @@ EOF
echo "$ac_t""$bfd_cv_have_sys_procfs_type_prpsinfo_t" 1>&6
echo $ac_n "checking for prpsinfo32_t in sys/procfs.h""... $ac_c" 1>&6
-echo "configure:5852: checking for prpsinfo32_t in sys/procfs.h" >&5
+echo "configure:5827: checking for prpsinfo32_t in sys/procfs.h" >&5
if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_prpsinfo32_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 5857 "configure"
+#line 5832 "configure"
#include "confdefs.h"
#define _SYSCALL32
@@ -5862,7 +5837,7 @@ int main() {
prpsinfo32_t avar
; return 0; }
EOF
-if { (eval echo configure:5866: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5841: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
bfd_cv_have_sys_procfs_type_prpsinfo32_t=yes
else
@@ -5884,12 +5859,12 @@ EOF
echo "$ac_t""$bfd_cv_have_sys_procfs_type_prpsinfo32_t" 1>&6
echo $ac_n "checking for psinfo_t in sys/procfs.h""... $ac_c" 1>&6
-echo "configure:5888: checking for psinfo_t in sys/procfs.h" >&5
+echo "configure:5863: checking for psinfo_t in sys/procfs.h" >&5
if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_psinfo_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 5893 "configure"
+#line 5868 "configure"
#include "confdefs.h"
#define _SYSCALL32
@@ -5898,7 +5873,7 @@ int main() {
psinfo_t avar
; return 0; }
EOF
-if { (eval echo configure:5902: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5877: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
bfd_cv_have_sys_procfs_type_psinfo_t=yes
else
@@ -5920,12 +5895,12 @@ EOF
echo "$ac_t""$bfd_cv_have_sys_procfs_type_psinfo_t" 1>&6
echo $ac_n "checking for psinfo32_t in sys/procfs.h""... $ac_c" 1>&6
-echo "configure:5924: checking for psinfo32_t in sys/procfs.h" >&5
+echo "configure:5899: checking for psinfo32_t in sys/procfs.h" >&5
if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_psinfo32_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 5929 "configure"
+#line 5904 "configure"
#include "confdefs.h"
#define _SYSCALL32
@@ -5934,7 +5909,7 @@ int main() {
psinfo32_t avar
; return 0; }
EOF
-if { (eval echo configure:5938: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5913: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
bfd_cv_have_sys_procfs_type_psinfo32_t=yes
else
@@ -5956,12 +5931,12 @@ EOF
echo "$ac_t""$bfd_cv_have_sys_procfs_type_psinfo32_t" 1>&6
echo $ac_n "checking for lwpstatus_t in sys/procfs.h""... $ac_c" 1>&6
-echo "configure:5960: checking for lwpstatus_t in sys/procfs.h" >&5
+echo "configure:5935: checking for lwpstatus_t in sys/procfs.h" >&5
if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_lwpstatus_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 5965 "configure"
+#line 5940 "configure"
#include "confdefs.h"
#define _SYSCALL32
@@ -5970,7 +5945,7 @@ int main() {
lwpstatus_t avar
; return 0; }
EOF
-if { (eval echo configure:5974: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5949: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
bfd_cv_have_sys_procfs_type_lwpstatus_t=yes
else
@@ -5992,12 +5967,12 @@ EOF
echo "$ac_t""$bfd_cv_have_sys_procfs_type_lwpstatus_t" 1>&6
echo $ac_n "checking for lwpxstatus_t in sys/procfs.h""... $ac_c" 1>&6
-echo "configure:5996: checking for lwpxstatus_t in sys/procfs.h" >&5
+echo "configure:5971: checking for lwpxstatus_t in sys/procfs.h" >&5
if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_lwpxstatus_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6001 "configure"
+#line 5976 "configure"
#include "confdefs.h"
#define _SYSCALL32
@@ -6006,7 +5981,7 @@ int main() {
lwpxstatus_t avar
; return 0; }
EOF
-if { (eval echo configure:6010: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:5985: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
bfd_cv_have_sys_procfs_type_lwpxstatus_t=yes
else
@@ -6028,12 +6003,12 @@ EOF
echo "$ac_t""$bfd_cv_have_sys_procfs_type_lwpxstatus_t" 1>&6
echo $ac_n "checking for lwpstatus_t.pr_context in sys/procfs.h""... $ac_c" 1>&6
-echo "configure:6032: checking for lwpstatus_t.pr_context in sys/procfs.h" >&5
+echo "configure:6007: checking for lwpstatus_t.pr_context in sys/procfs.h" >&5
if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_context'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6037 "configure"
+#line 6012 "configure"
#include "confdefs.h"
#define _SYSCALL32
@@ -6042,7 +6017,7 @@ int main() {
lwpstatus_t avar; void* aref = (void*) &avar.pr_context
; return 0; }
EOF
-if { (eval echo configure:6046: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6021: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_context=yes
else
@@ -6064,12 +6039,12 @@ EOF
echo "$ac_t""$bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_context" 1>&6
echo $ac_n "checking for lwpstatus_t.pr_reg in sys/procfs.h""... $ac_c" 1>&6
-echo "configure:6068: checking for lwpstatus_t.pr_reg in sys/procfs.h" >&5
+echo "configure:6043: checking for lwpstatus_t.pr_reg in sys/procfs.h" >&5
if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_reg'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6073 "configure"
+#line 6048 "configure"
#include "confdefs.h"
#define _SYSCALL32
@@ -6078,7 +6053,7 @@ int main() {
lwpstatus_t avar; void* aref = (void*) &avar.pr_reg
; return 0; }
EOF
-if { (eval echo configure:6082: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6057: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_reg=yes
else
@@ -6100,12 +6075,12 @@ EOF
echo "$ac_t""$bfd_cv_have_sys_procfs_type_member_lwpstatus_t_pr_reg" 1>&6
echo $ac_n "checking for win32_pstatus_t in sys/procfs.h""... $ac_c" 1>&6
-echo "configure:6104: checking for win32_pstatus_t in sys/procfs.h" >&5
+echo "configure:6079: checking for win32_pstatus_t in sys/procfs.h" >&5
if eval "test \"`echo '$''{'bfd_cv_have_sys_procfs_type_win32_pstatus_t'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 6109 "configure"
+#line 6084 "configure"
#include "confdefs.h"
#define _SYSCALL32
@@ -6114,7 +6089,7 @@ int main() {
win32_pstatus_t avar
; return 0; }
EOF
-if { (eval echo configure:6118: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:6093: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
bfd_cv_have_sys_procfs_type_win32_pstatus_t=yes
else
@@ -6274,8 +6249,6 @@ do
aout0_big_vec) tb="$tb aout0.lo aout32.lo" ;;
aout_arm_big_vec) tb="$tb aout-arm.lo aout32.lo" ;;
aout_arm_little_vec) tb="$tb aout-arm.lo aout32.lo" ;;
- aout_mips_big_vec) tb="$tb mipsbsd.lo aout32.lo" ;;
- aout_mips_little_vec) tb="$tb mipsbsd.lo aout32.lo" ;;
apollocoff_vec) tb="$tb coff-apollo.lo" ;;
arm_epoc_pe_big_vec) tb="$tb epoc-pe-arm.lo peigen.lo cofflink.lo " ;;
arm_epoc_pe_little_vec) tb="$tb epoc-pe-arm.lo peigen.lo cofflink.lo " ;;
@@ -6299,6 +6272,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 +6560,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:6564: 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 6567 "configure"
#include "confdefs.h"
:__GNUC__:__GNUC_MINOR__:__i386__:
EOF
@@ -6631,12 +6605,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:6609: 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 6614 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -6659,7 +6633,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:6637: \"$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 +6659,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:6663: 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 6669 "configure"
#include "confdefs.h"
#include "confdefs.h"
#include <sys/types.h>
@@ -6701,7 +6675,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:6679: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_sizeof_off_t=$ac_size
else
@@ -6725,7 +6699,7 @@ EOF
fi
echo $ac_n "checking file_ptr type""... $ac_c" 1>&6
-echo "configure:6729: checking file_ptr type" >&5
+echo "configure:6703: 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 \
@@ -6746,21 +6720,21 @@ test -n "${selarchs}" && tdefaults="${tdefaults} -DSELECT_ARCHITECTURES='${selar
test -n "${havevecs}" && tdefaults="${tdefaults} ${havevecs}"
-for ac_hdr in stdlib.h unistd.h sys/stat.h sys/types.h
+for ac_hdr in unistd.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:6728: 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 6733 "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:6738: \"$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 +6763,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:6767: 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 6772 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -6817,7 +6791,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:6795: \"$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 +6816,7 @@ fi
done
echo $ac_n "checking for working mmap""... $ac_c" 1>&6
-echo "configure:6846: checking for working mmap" >&5
+echo "configure:6820: 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 +6824,7 @@ else
ac_cv_func_mmap_fixed_mapped=no
else
cat > conftest.$ac_ext <<EOF
-#line 6854 "configure"
+#line 6828 "configure"
#include "confdefs.h"
/* Thanks to Mike Haertel and Jim Avera for this test.
@@ -6878,24 +6852,11 @@ else
#include <fcntl.h>
#include <sys/mman.h>
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-
-#if HAVE_STDLIB_H
-# include <stdlib.h>
-#endif
-
-#if HAVE_SYS_STAT_H
-# include <sys/stat.h>
-#endif
-
-#if HAVE_UNISTD_H
-# include <unistd.h>
-#endif
-
/* This mess was copied from the GNU getpagesize.h. */
#ifndef HAVE_GETPAGESIZE
+# ifdef HAVE_UNISTD_H
+# include <unistd.h>
+# endif
/* Assume that all systems that can run configure have sys/param.h. */
# ifndef HAVE_SYS_PARAM_H
@@ -7003,7 +6964,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:6968: \"$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 +6989,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:6993: 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 6998 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -7056,7 +7017,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:7021: \"$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 f970287..7d9594c 100644
--- a/bfd/configure.in
+++ b/bfd/configure.in
@@ -7,7 +7,7 @@ AC_INIT(libbfd.c)
AC_CANONICAL_SYSTEM
AC_ISC_POSIX
-AM_INIT_AUTOMAKE(bfd, 2.14.90)
+AM_INIT_AUTOMAKE(bfd, 2.15.91)
# Uncomment the next line to remove the date from the reported bfd version
#is_release=y
@@ -272,14 +272,6 @@ changequote([,])dnl
COREFILE=trad-core.lo
TRAD_HEADER='"hosts/i860mach3.h"'
;;
- mips-dec-bsd*)
- COREFILE=trad-core.lo
- TRAD_HEADER='"hosts/mipsbsd.h"'
- ;;
- mips-dec-mach3*)
- COREFILE=trad-core.lo
- TRAD_HEADER='"hosts/mipsmach3.h"'
- ;;
mips-*-netbsd* | mips*-*-openbsd*)
COREFILE=netbsd-core.lo
;;
@@ -290,10 +282,6 @@ changequote([,])dnl
mips-sgi-irix4*) COREFILE=irix-core.lo ;;
mips-sgi-irix5*) COREFILE=irix-core.lo ;;
mips-sgi-irix6*) COREFILE=irix-core.lo ;;
- mips-*-mach3*)
- COREFILE=trad-core.lo
- TRAD_HEADER='"hosts/mipsmach3.h"'
- ;;
mips-*-sysv4*) ;;
mips-*-sysv* | mips-*-riscos*)
COREFILE=trad-core.lo
@@ -583,8 +571,6 @@ do
aout0_big_vec) tb="$tb aout0.lo aout32.lo" ;;
aout_arm_big_vec) tb="$tb aout-arm.lo aout32.lo" ;;
aout_arm_little_vec) tb="$tb aout-arm.lo aout32.lo" ;;
- aout_mips_big_vec) tb="$tb mipsbsd.lo aout32.lo" ;;
- aout_mips_little_vec) tb="$tb mipsbsd.lo aout32.lo" ;;
apollocoff_vec) tb="$tb coff-apollo.lo" ;;
arm_epoc_pe_big_vec) tb="$tb epoc-pe-arm.lo peigen.lo cofflink.lo " ;;
arm_epoc_pe_little_vec) tb="$tb epoc-pe-arm.lo peigen.lo cofflink.lo " ;;
@@ -608,6 +594,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 0000000..0773e08
--- /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/cpu-frv.c b/bfd/cpu-frv.c
index f911881..499c66d 100644
--- a/bfd/cpu-frv.c
+++ b/bfd/cpu-frv.c
@@ -43,8 +43,11 @@ static const bfd_arch_info_type arch_info_300
static const bfd_arch_info_type arch_info_400
= FRV_ARCH (bfd_mach_fr400, "fr400", FALSE, &arch_info_300);
+static const bfd_arch_info_type arch_info_450
+ = FRV_ARCH (bfd_mach_fr450, "fr450", FALSE, &arch_info_400);
+
static const bfd_arch_info_type arch_info_500
- = FRV_ARCH (bfd_mach_fr500, "fr500", FALSE, &arch_info_400);
+ = FRV_ARCH (bfd_mach_fr500, "fr500", FALSE, &arch_info_450);
static const bfd_arch_info_type arch_info_550
= FRV_ARCH (bfd_mach_fr550, "fr550", FALSE, &arch_info_500);
diff --git a/bfd/cpu-m68k.c b/bfd/cpu-m68k.c
index 71c7029..426f583 100644
--- a/bfd/cpu-m68k.c
+++ b/bfd/cpu-m68k.c
@@ -1,6 +1,6 @@
/* BFD library support routines for architectures.
Copyright 1990, 1991, 1992, 1993, 1994, 1997, 1998, 2000, 2001, 2002,
- 2003 Free Software Foundation, Inc.
+ 2003, 2004 Free Software Foundation, Inc.
Hacked by Steve Chamberlain of Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
@@ -40,7 +40,8 @@ static const bfd_arch_info_type arch_info_struct[] =
N(bfd_mach_mcf5307, "m68k:5307", FALSE, &arch_info_struct[10]),
N(bfd_mach_mcf5407, "m68k:5407", FALSE, &arch_info_struct[11]),
N(bfd_mach_m68060, "m68k:68060", FALSE, &arch_info_struct[12]),
- N(bfd_mach_mcf528x, "m68k:528x", FALSE, 0),
+ N(bfd_mach_mcf528x, "m68k:528x", FALSE, &arch_info_struct[13]),
+ N(bfd_mach_mcfv4e, "m68k:cfv4e", FALSE, 0),
};
const bfd_arch_info_type bfd_m68k_arch =
diff --git a/bfd/cpu-sh.c b/bfd/cpu-sh.c
index 2f33240..be359df 100644
--- a/bfd/cpu-sh.c
+++ b/bfd/cpu-sh.c
@@ -1,5 +1,5 @@
/* BFD library support routines for the Renesas / SuperH SH architecture.
- Copyright 1993, 1994, 1997, 1998, 2000, 2001, 2002, 2003
+ Copyright 1993, 1994, 1997, 1998, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Hacked by Steve Chamberlain of Cygnus Support.
@@ -34,7 +34,8 @@
#define SH4A_NEXT &arch_info_struct[8]
#define SH4AL_DSP_NEXT &arch_info_struct[9]
#define SH4_NOFPU_NEXT &arch_info_struct[10]
-#define SH4A_NOFPU_NEXT &arch_info_struct[11]
+#define SH4_NOMMU_NOFPU_NEXT &arch_info_struct[11]
+#define SH4A_NOFPU_NEXT &arch_info_struct[12]
#define SH64_NEXT NULL
static const bfd_arch_info_type arch_info_struct[] =
@@ -184,6 +185,20 @@ static const bfd_arch_info_type arch_info_struct[] =
32, /* 32 bits in an address */
8, /* 8 bits in a byte */
bfd_arch_sh,
+ bfd_mach_sh4_nommu_nofpu,
+ "sh", /* arch_name */
+ "sh4-nommu-nofpu", /* printable name */
+ 1,
+ FALSE, /* not the default */
+ bfd_default_compatible,
+ bfd_default_scan,
+ SH4_NOMMU_NOFPU_NEXT
+ },
+ {
+ 32, /* 32 bits in a word */
+ 32, /* 32 bits in an address */
+ 8, /* 8 bits in a byte */
+ bfd_arch_sh,
bfd_mach_sh4a_nofpu,
"sh", /* arch_name */
"sh4a-nofpu", /* printable name */
diff --git a/bfd/doc/ChangeLog b/bfd/doc/ChangeLog
index 3316383..cc57b2b 100644
--- a/bfd/doc/ChangeLog
+++ b/bfd/doc/ChangeLog
@@ -1,3 +1,10 @@
+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.
For older changes see ChangeLog-9103
diff --git a/bfd/doc/Makefile.in b/bfd/doc/Makefile.in
index 1c1fce9..136b429 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
@@ -117,8 +117,10 @@ WIN32LIBADD = @WIN32LIBADD@
all_backends = @all_backends@
bfd_backends = @bfd_backends@
bfd_default_target_size = @bfd_default_target_size@
+bfd_file_ptr = @bfd_file_ptr@
bfd_libs = @bfd_libs@
bfd_machines = @bfd_machines@
+bfd_ufile_ptr = @bfd_ufile_ptr@
bfd_version = @bfd_version@
bfd_version_string = @bfd_version_string@
bfdincludedir = @bfdincludedir@
diff --git a/bfd/doc/bfdint.texi b/bfd/doc/bfdint.texi
index cd29ae8..95c0096 100644
--- a/bfd/doc/bfdint.texi
+++ b/bfd/doc/bfdint.texi
@@ -1073,11 +1073,6 @@ sizes.
Like @file{elfcode.h}, but for functions that are specific to ELF core
files. This is included only by @file{elfcode.h}.
-@item elflink.h
-@cindex @file{elflink.h}
-Like @file{elfcode.h}, but for functions used by the ELF linker. This
-is included only by @file{elfcode.h}.
-
@item elfxx-target.h
@cindex @file{elfxx-target.h}
This file is the source for the generated files @file{elf32-target.h}
@@ -1482,8 +1477,7 @@ external data. @file{elfcode.h} is compiled twice, once via
@file{elfcode.h} includes functions to swap the ELF structures in and
out of external form, as well as a few more complex functions.
-Linker support is found in @file{elflink.c} and @file{elflink.h}. The
-latter file is compiled twice, for both 32 and 64 bit support. The
+Linker support is found in @file{elflink.c}. The
linker support is only used if the processor specific file defines
@samp{elf_backend_relocate_section}, which is required to relocate the
section contents. If that macro is not defined, the generic linker code
diff --git a/bfd/ecoff.c b/bfd/ecoff.c
index cfc5ae1..5991fdd 100644
--- a/bfd/ecoff.c
+++ b/bfd/ecoff.c
@@ -4526,7 +4526,6 @@ ecoff_indirect_link_order (output_bfd, info, output_section, link_order)
{
asection *input_section;
bfd *input_bfd;
- struct ecoff_section_tdata *section_tdata;
bfd_size_type raw_size;
bfd_size_type cooked_size;
bfd_byte *contents = NULL;
@@ -4542,7 +4541,6 @@ ecoff_indirect_link_order (output_bfd, info, output_section, link_order)
input_section = link_order->u.indirect.section;
input_bfd = input_section->owner;
- section_tdata = ecoff_section_data (input_bfd, input_section);
raw_size = input_section->_raw_size;
cooked_size = input_section->_cooked_size;
@@ -4560,39 +4558,24 @@ ecoff_indirect_link_order (output_bfd, info, output_section, link_order)
if (contents == NULL && amt != 0)
goto error_return;
- /* If we are relaxing, the contents may have already been read into
- memory, in which case we copy them into our new buffer. We don't
- simply reuse the old buffer in case cooked_size > raw_size. */
- if (section_tdata != (struct ecoff_section_tdata *) NULL
- && section_tdata->contents != (bfd_byte *) NULL)
- memcpy (contents, section_tdata->contents, (size_t) raw_size);
- else
- {
- if (! bfd_get_section_contents (input_bfd, input_section,
- (PTR) contents,
- (file_ptr) 0, raw_size))
- goto error_return;
- }
+ if (! bfd_get_section_contents (input_bfd, input_section,
+ (PTR) contents,
+ (file_ptr) 0, raw_size))
+ goto error_return;
/* Get the relocs. If we are relaxing MIPS code, they will already
have been read in. Otherwise, we read them in now. */
external_reloc_size = ecoff_backend (input_bfd)->external_reloc_size;
external_relocs_size = external_reloc_size * input_section->reloc_count;
- if (section_tdata != (struct ecoff_section_tdata *) NULL
- && section_tdata->external_relocs != NULL)
- external_relocs = section_tdata->external_relocs;
- else
- {
- external_relocs = (PTR) bfd_malloc (external_relocs_size);
- if (external_relocs == NULL && external_relocs_size != 0)
- goto error_return;
+ external_relocs = (PTR) bfd_malloc (external_relocs_size);
+ if (external_relocs == NULL && external_relocs_size != 0)
+ goto error_return;
- if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
- || (bfd_bread (external_relocs, external_relocs_size, input_bfd)
- != external_relocs_size))
- goto error_return;
- }
+ if (bfd_seek (input_bfd, input_section->rel_filepos, SEEK_SET) != 0
+ || (bfd_bread (external_relocs, external_relocs_size, input_bfd)
+ != external_relocs_size))
+ goto error_return;
/* Relocate the section contents. */
if (! ((*ecoff_backend (input_bfd)->relocate_section)
@@ -4625,14 +4608,14 @@ ecoff_indirect_link_order (output_bfd, info, output_section, link_order)
if (contents != NULL)
free (contents);
- if (external_relocs != NULL && section_tdata == NULL)
+ if (external_relocs != NULL)
free (external_relocs);
return TRUE;
error_return:
if (contents != NULL)
free (contents);
- if (external_relocs != NULL && section_tdata == NULL)
+ if (external_relocs != NULL)
free (external_relocs);
return FALSE;
}
diff --git a/bfd/ecofflink.c b/bfd/ecofflink.c
index 9e23848..9abf9d1 100644
--- a/bfd/ecofflink.c
+++ b/bfd/ecofflink.c
@@ -800,20 +800,6 @@ bfd_ecoff_debug_accumulate (handle, output_bfd, output_debug, output_swap,
fdr_adr = fdr.adr;
- /* Adjust the FDR address for any changes that may have been
- made by relaxing. */
- if (input_debug->adjust != (struct ecoff_value_adjust *) NULL)
- {
- struct ecoff_value_adjust *adjust;
-
- for (adjust = input_debug->adjust;
- adjust != (struct ecoff_value_adjust *) NULL;
- adjust = adjust->next)
- if (fdr_adr >= adjust->start
- && fdr_adr < adjust->end)
- fdr.adr += adjust->adjust;
- }
-
/* FIXME: It is conceivable that this FDR points to the .init or
.fini section, in which case this will not do the right
thing. */
@@ -856,19 +842,6 @@ bfd_ecoff_debug_accumulate (handle, output_bfd, output_debug, output_swap,
case stLabel:
case stProc:
case stStaticProc:
- if (input_debug->adjust != (struct ecoff_value_adjust *) NULL)
- {
- bfd_vma value;
- struct ecoff_value_adjust *adjust;
-
- value = internal_sym.value;
- for (adjust = input_debug->adjust;
- adjust != (struct ecoff_value_adjust *) NULL;
- adjust = adjust->next)
- if (value >= adjust->start
- && value < adjust->end)
- internal_sym.value += adjust->adjust;
- }
internal_sym.value += section_adjust[internal_sym.sc];
break;
@@ -978,9 +951,8 @@ bfd_ecoff_debug_accumulate (handle, output_bfd, output_debug, output_swap,
output_symhdr->issMax += fdr.cbSs;
}
- if ((output_bfd->xvec->header_byteorder
- == input_bfd->xvec->header_byteorder)
- && input_debug->adjust == (struct ecoff_value_adjust *) NULL)
+ if (output_bfd->xvec->header_byteorder
+ == input_bfd->xvec->header_byteorder)
{
/* The two BFD's have the same endianness, and we don't have
to adjust the PDR addresses, so simply copying the
@@ -1036,23 +1008,6 @@ bfd_ecoff_debug_accumulate (handle, output_bfd, output_debug, output_swap,
PDR pdr;
(*input_swap->swap_pdr_in) (input_bfd, (PTR) in, &pdr);
-
- /* If we have been relaxing, we may have to adjust the
- address. */
- if (input_debug->adjust != (struct ecoff_value_adjust *) NULL)
- {
- bfd_vma adr;
- struct ecoff_value_adjust *adjust;
-
- adr = fdr_adr + pdr.adr;
- for (adjust = input_debug->adjust;
- adjust != (struct ecoff_value_adjust *) NULL;
- adjust = adjust->next)
- if (adr >= adjust->start
- && adr < adjust->end)
- pdr.adr += adjust->adjust;
- }
-
(*output_swap->swap_pdr_out) (output_bfd, &pdr, (PTR) out);
}
diff --git a/bfd/ecoffswap.h b/bfd/ecoffswap.h
index 7ea0394..0e77052 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 6bbacad..9d0ec36 100644
--- a/bfd/elf-bfd.h
+++ b/bfd/elf-bfd.h
@@ -1,6 +1,6 @@
/* BFD back-end data structures for ELF files.
Copyright 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
- 2002, 2003 Free Software Foundation, Inc.
+ 2002, 2003, 2004 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
@@ -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;
};
@@ -596,7 +597,7 @@ struct elf_backend_data
/* A function to convert machine dependent section header flags to
BFD internal section header flags. */
bfd_boolean (*elf_backend_section_flags)
- (flagword *, Elf_Internal_Shdr *);
+ (flagword *, const Elf_Internal_Shdr *);
/* A function to handle unusual program segment types when creating BFD
sections from ELF program segments. */
@@ -625,7 +626,7 @@ struct elf_backend_data
indices, and must set at least *FLAGS and *SEC for each processor
dependent case; failure to do so will cause a link error. */
bfd_boolean (*elf_add_symbol_hook)
- (bfd *abfd, struct bfd_link_info *info, const Elf_Internal_Sym *,
+ (bfd *abfd, struct bfd_link_info *info, Elf_Internal_Sym *,
const char **name, flagword *flags, asection **sec, bfd_vma *value);
/* If this field is not NULL, it is called by the elf_link_output_sym
@@ -860,6 +861,24 @@ struct elf_backend_data
bfd_boolean (*elf_backend_ignore_discarded_relocs)
(asection *);
+ /* These functions tell elf-eh-frame whether to attempt to turn
+ absolute or lsda encodings into pc-relative ones. The default
+ definition enables these transformations. */
+ bfd_boolean (*elf_backend_can_make_relative_eh_frame)
+ (bfd *, struct bfd_link_info *, asection *);
+ bfd_boolean (*elf_backend_can_make_lsda_relative_eh_frame)
+ (bfd *, struct bfd_link_info *, asection *);
+
+ /* This function returns an encoding after computing the encoded
+ value (and storing it in ENCODED) for the given OFFSET into OSEC,
+ to be stored in at LOC_OFFSET into the LOC_SEC input section.
+ The default definition chooses a 32-bit PC-relative encoding. */
+ bfd_byte (*elf_backend_encode_eh_address)
+ (bfd *abfd, struct bfd_link_info *info,
+ asection *osec, bfd_vma offset,
+ asection *loc_sec, bfd_vma loc_offset,
+ bfd_vma *encoded);
+
/* This function, if defined, may write out the given section.
Returns TRUE if it did so and FALSE if the caller should. */
bfd_boolean (*elf_backend_write_section)
@@ -883,6 +902,13 @@ struct elf_backend_data
(bfd *templ, bfd_vma ehdr_vma, bfd_vma *loadbasep,
int (*target_read_memory) (bfd_vma vma, char *myaddr, int len));
+ /* This function is used by `_bfd_elf_get_synthetic_symtab';
+ see elf.c. */
+ bfd_vma (*plt_sym_val) (bfd_vma, const asection *, const arelent *);
+
+ /* Name of the PLT relocation section. */
+ const char *relplt_name;
+
/* Alternate EM_xxxx machine codes for this backend. */
int elf_machine_alt1;
int elf_machine_alt2;
@@ -1114,9 +1140,6 @@ struct elf_obj_tdata
bfd_vma gp; /* The gp value */
unsigned int gp_size; /* The gp size */
- Elf_Internal_Shdr **group_sect_ptr;
- int num_group;
-
/* Information grabbed from an elf core file. */
int core_signal;
int core_pid;
@@ -1124,10 +1147,6 @@ struct elf_obj_tdata
char* core_program;
char* core_command;
- /* This is set to TRUE if the object was created by the backend
- linker. */
- bfd_boolean linker;
-
/* A mapping from external symbols to entries in the linker hash
table, used when linking. This is indexed by the symbol index
minus the sh_info field of the symbol table header. */
@@ -1153,21 +1172,6 @@ struct elf_obj_tdata
one. */
const char *dt_name;
- /* When a reference in a regular object is resolved by a shared
- object is loaded into via the DT_NEEDED entries by the linker
- ELF emulation code, we need to add the shared object to the
- DT_NEEDED list of the resulting binary to indicate the dependency
- as if the -l option is passed to the linker. This field holds the
- name of the loaded shared object. */
- const char *dt_soname;
-
- /* Irix 5 often screws up the symbol table, sorting local symbols
- after global symbols. This flag is set if the symbol table in
- this BFD appears to be screwed up. If it is, we ignore the
- sh_info field in the symbol table header, and always read all the
- symbols. */
- bfd_boolean bad_symtab;
-
/* Records the result of `get_program_header_size'. */
bfd_size_type program_header_size;
@@ -1195,8 +1199,8 @@ struct elf_obj_tdata
created. */
asection *eh_frame_hdr;
- /* Used to determine if the e_flags field has been initialized */
- bfd_boolean flags_init;
+ Elf_Internal_Shdr **group_sect_ptr;
+ int num_group;
/* Number of symbol version definitions we are about to emit. */
unsigned int cverdefs;
@@ -1219,6 +1223,25 @@ struct elf_obj_tdata
asymbol *elf_text_symbol;
asection *elf_data_section;
asection *elf_text_section;
+
+ /* Whether a dyanmic object was specified normally on the linker
+ command line, or was specified when --as-needed was in effect,
+ or was found via a DT_NEEDED entry. */
+ enum dynamic_lib_link_class dyn_lib_class;
+
+ /* This is set to TRUE if the object was created by the backend
+ linker. */
+ bfd_boolean linker;
+
+ /* Irix 5 often screws up the symbol table, sorting local symbols
+ after global symbols. This flag is set if the symbol table in
+ this BFD appears to be screwed up. If it is, we ignore the
+ sh_info field in the symbol table header, and always read all the
+ symbols. */
+ bfd_boolean bad_symtab;
+
+ /* Used to determine if the e_flags field has been initialized */
+ bfd_boolean flags_init;
};
#define elf_tdata(bfd) ((bfd) -> tdata.elf_obj_data)
@@ -1245,7 +1268,7 @@ struct elf_obj_tdata
#define elf_local_got_offsets(bfd) (elf_tdata(bfd) -> local_got.offsets)
#define elf_local_got_ents(bfd) (elf_tdata(bfd) -> local_got.ents)
#define elf_dt_name(bfd) (elf_tdata(bfd) -> dt_name)
-#define elf_dt_soname(bfd) (elf_tdata(bfd) -> dt_soname)
+#define elf_dyn_lib_class(bfd) (elf_tdata(bfd) -> dyn_lib_class)
#define elf_bad_symtab(bfd) (elf_tdata(bfd) -> bad_symtab)
#define elf_flags_init(bfd) (elf_tdata(bfd) -> flags_init)
@@ -1293,14 +1316,17 @@ 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
(bfd *, void *, bfd_vma);
+extern bfd_byte _bfd_elf_encode_eh_address
+ (bfd *abfd, struct bfd_link_info *info, asection *osec, bfd_vma offset,
+ asection *loc_sec, bfd_vma loc_offset, bfd_vma *encoded);
+extern bfd_boolean _bfd_elf_can_make_relative
+ (bfd *input_bfd, struct bfd_link_info *info, asection *eh_frame_section);
+
extern enum elf_reloc_type_class _bfd_elf_reloc_type_class
(const Elf_Internal_Rela *);
extern bfd_vma _bfd_elf_rela_local_sym
@@ -1342,6 +1368,8 @@ extern bfd_boolean _bfd_elf_slurp_version_tables
(bfd *);
extern bfd_boolean _bfd_elf_merge_sections
(bfd *, struct bfd_link_info *);
+extern bfd_boolean bfd_elf_is_group_section
+ (bfd *, const struct bfd_section *);
extern bfd_boolean bfd_elf_discard_group
(bfd *, struct bfd_section *);
extern void bfd_elf_set_group_contents
@@ -1366,6 +1394,8 @@ extern long _bfd_elf_get_dynamic_symtab_upper_bound
(bfd *);
extern long _bfd_elf_canonicalize_dynamic_symtab
(bfd *, asymbol **);
+extern long _bfd_elf_get_synthetic_symtab
+ (bfd *, asymbol **, asymbol **);
extern long _bfd_elf_get_reloc_upper_bound
(bfd *, sec_ptr);
extern long _bfd_elf_canonicalize_reloc
@@ -1455,12 +1485,12 @@ extern bfd_boolean _bfd_elf_maybe_strip_eh_frame_hdr
extern bfd_boolean _bfd_elf_merge_symbol
(bfd *, struct bfd_link_info *, const char *, Elf_Internal_Sym *,
asection **, bfd_vma *, struct elf_link_hash_entry **, bfd_boolean *,
- bfd_boolean *, bfd_boolean *, bfd_boolean *, bfd_boolean);
+ bfd_boolean *, bfd_boolean *, bfd_boolean *);
extern bfd_boolean _bfd_elf_add_default_symbol
(bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
const char *, Elf_Internal_Sym *, asection **, bfd_vma *,
- bfd_boolean *, bfd_boolean, bfd_boolean);
+ bfd_boolean *, bfd_boolean);
extern bfd_boolean _bfd_elf_export_symbol
(struct elf_link_hash_entry *, void *);
@@ -1471,8 +1501,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
@@ -1534,11 +1562,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_link_add_symbols
- (bfd *, struct bfd_link_info *);
-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
@@ -1569,8 +1592,6 @@ extern void bfd_elf32_write_relocs
(bfd *, asection *, void *);
extern bfd_boolean bfd_elf32_slurp_reloc_table
(bfd *, asection *, asymbol **, bfd_boolean);
-extern bfd_boolean bfd_elf32_add_dynamic_entry
- (struct bfd_link_info *, bfd_vma, bfd_vma);
extern const bfd_target *bfd_elf64_object_p
(bfd *);
@@ -1582,10 +1603,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_link_add_symbols
- (bfd *, struct bfd_link_info *);
-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 *);
@@ -1617,20 +1634,17 @@ extern void bfd_elf64_write_relocs
(bfd *, asection *, void *);
extern bfd_boolean bfd_elf64_slurp_reloc_table
(bfd *, asection *, asymbol **, bfd_boolean);
-extern bfd_boolean bfd_elf64_add_dynamic_entry
+
+extern bfd_boolean bfd_elf_link_add_symbols
+ (bfd *, struct bfd_link_info *);
+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 *);
@@ -1638,31 +1652,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
- (bfd *, struct bfd_link_info *);
-extern bfd_boolean _bfd_elf64_gc_common_finalize_got_offsets
+extern bfd_boolean bfd_elf_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. */
@@ -1693,60 +1701,73 @@ 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(h, sym_hashes, r_symndx, symtab_hdr, relocation, sec, unresolved_reloc, info, warned) \
- do \
- { \
- /* It seems this can happen with erroneous or unsupported \
- input (mixing a.out and elf in an archive, for example.) */ \
- if (sym_hashes == NULL) \
- return FALSE; \
- \
- 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; \
- \
- warned = FALSE; \
- unresolved_reloc = FALSE; \
- relocation = 0; \
- if (h->root.type == bfd_link_hash_defined \
- || h->root.type == bfd_link_hash_defweak) \
- { \
- sec = h->root.u.def.section; \
- if (sec == NULL \
- || sec->output_section == NULL) \
- /* Set a flag that will be cleared later if we find a \
- relocation value for this symbol. output_section \
- is typically NULL for symbols satisfied by a shared \
- library. */ \
- unresolved_reloc = TRUE; \
- else \
- relocation = (h->root.u.def.value \
- + sec->output_section->vma \
- + sec->output_offset); \
- } \
- else if (h->root.type == bfd_link_hash_undefweak) \
- ; \
- else if (!info->executable \
- && info->unresolved_syms_in_objects == RM_IGNORE \
- && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) \
- ; \
- else \
- { \
- if (! info->callbacks->undefined_symbol \
- (info, h->root.root.string, input_bfd, \
- input_section, rel->r_offset, \
- ((info->shared && info->unresolved_syms_in_shared_libs == RM_GENERATE_ERROR) \
- || (!info->shared && info->unresolved_syms_in_objects == RM_GENERATE_ERROR) \
- || ELF_ST_VISIBILITY (h->other)) \
- )) \
- return FALSE; \
- warned = TRUE; \
- } \
- } \
+#define RELOC_FOR_GLOBAL_SYMBOL(info, input_bfd, input_section, rel, \
+ r_symndx, symtab_hdr, sym_hashes, \
+ h, sec, relocation, \
+ unresolved_reloc, warned) \
+ do \
+ { \
+ /* It seems this can happen with erroneous or unsupported \
+ input (mixing a.out and elf in an archive, for example.) */ \
+ if (sym_hashes == NULL) \
+ return FALSE; \
+ \
+ 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; \
+ \
+ warned = FALSE; \
+ unresolved_reloc = FALSE; \
+ relocation = 0; \
+ if (h->root.type == bfd_link_hash_defined \
+ || h->root.type == bfd_link_hash_defweak) \
+ { \
+ sec = h->root.u.def.section; \
+ if (sec == NULL \
+ || sec->output_section == NULL) \
+ /* Set a flag that will be cleared later if we find a \
+ relocation value for this symbol. output_section \
+ is typically NULL for symbols satisfied by a shared \
+ library. */ \
+ unresolved_reloc = TRUE; \
+ else \
+ relocation = (h->root.u.def.value \
+ + sec->output_section->vma \
+ + sec->output_offset); \
+ } \
+ else if (h->root.type == bfd_link_hash_undefweak) \
+ ; \
+ else if (info->unresolved_syms_in_objects == RM_IGNORE \
+ && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT) \
+ ; \
+ else \
+ { \
+ bfd_boolean err; \
+ err = (info->unresolved_syms_in_objects == RM_GENERATE_ERROR \
+ || ELF_ST_VISIBILITY (h->other) != STV_DEFAULT); \
+ if (!info->callbacks->undefined_symbol (info, \
+ h->root.root.string, \
+ input_bfd, \
+ input_section, \
+ rel->r_offset, err)) \
+ return FALSE; \
+ warned = TRUE; \
+ } \
+ } \
while (0)
#endif /* _LIBELF_H_ */
diff --git a/bfd/elf-eh-frame.c b/bfd/elf-eh-frame.c
index 28e0b55..d3777b4 100644
--- a/bfd/elf-eh-frame.c
+++ b/bfd/elf-eh-frame.c
@@ -518,10 +518,16 @@ _bfd_elf_discard_section_eh_frame
/* For shared libraries, try to get rid of as many RELATIVE relocs
as possible. */
if (info->shared
+ && (get_elf_backend_data (abfd)
+ ->elf_backend_can_make_relative_eh_frame
+ (abfd, info, sec))
&& (cie.fde_encoding & 0xf0) == DW_EH_PE_absptr)
cie.make_relative = 1;
if (info->shared
+ && (get_elf_backend_data (abfd)
+ ->elf_backend_can_make_lsda_relative_eh_frame
+ (abfd, info, sec))
&& (cie.lsda_encoding & 0xf0) == DW_EH_PE_absptr)
cie.make_lsda_relative = 1;
@@ -1120,6 +1126,7 @@ _bfd_elf_write_section_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info)
asection *eh_frame_sec;
bfd_size_type size;
bfd_boolean retval;
+ bfd_vma encoded_eh_frame;
htab = elf_hash_table (info);
hdr_info = &htab->eh_info;
@@ -1143,7 +1150,10 @@ _bfd_elf_write_section_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info)
memset (contents, 0, EH_FRAME_HDR_SIZE);
contents[0] = 1; /* Version. */
- contents[1] = DW_EH_PE_pcrel | DW_EH_PE_sdata4; /* .eh_frame offset. */
+ contents[1] = get_elf_backend_data (abfd)->elf_backend_encode_eh_address
+ (abfd, info, eh_frame_sec, 0, sec, 4,
+ &encoded_eh_frame); /* .eh_frame offset. */
+
if (hdr_info->array && hdr_info->array_count == hdr_info->fde_count)
{
contents[2] = DW_EH_PE_udata4; /* FDE count encoding. */
@@ -1154,8 +1164,8 @@ _bfd_elf_write_section_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info)
contents[2] = DW_EH_PE_omit;
contents[3] = DW_EH_PE_omit;
}
- bfd_put_32 (abfd, eh_frame_sec->vma - sec->output_section->vma - 4,
- contents + 4);
+ bfd_put_32 (abfd, encoded_eh_frame, contents + 4);
+
if (contents[2] != DW_EH_PE_omit)
{
unsigned int i;
@@ -1181,3 +1191,29 @@ _bfd_elf_write_section_eh_frame_hdr (bfd *abfd, struct bfd_link_info *info)
free (contents);
return retval;
}
+
+/* Decide whether we can use a PC-relative encoding within the given
+ EH frame section. This is the default implementation. */
+
+bfd_boolean
+_bfd_elf_can_make_relative (bfd *input_bfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ asection *eh_frame_section ATTRIBUTE_UNUSED)
+{
+ return TRUE;
+}
+
+/* Select an encoding for the given address. Preference is given to
+ PC-relative addressing modes. */
+
+bfd_byte
+_bfd_elf_encode_eh_address (bfd *abfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ asection *osec, bfd_vma offset,
+ asection *loc_sec, bfd_vma loc_offset,
+ bfd_vma *encoded)
+{
+ *encoded = osec->vma + offset -
+ (loc_sec->output_section->vma + loc_sec->output_offset + loc_offset);
+ return DW_EH_PE_pcrel | DW_EH_PE_sdata4;
+}
diff --git a/bfd/elf-hppa.h b/bfd/elf-hppa.h
index a5c0b44..1f79147 100644
--- a/bfd/elf-hppa.h
+++ b/bfd/elf-hppa.h
@@ -1,5 +1,6 @@
/* Common code for PA ELF implementations.
- Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@@ -31,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
@@ -40,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
@@ -812,6 +811,28 @@ elf_hppa_reloc_final_type (bfd *abfd,
}
break;
+ case 32:
+ switch (field)
+ {
+ case e_fsel:
+ final_type = R_PARISC_PCREL32;
+ break;
+ default:
+ return R_PARISC_NONE;
+ }
+ break;
+
+ case 64:
+ switch (field)
+ {
+ case e_fsel:
+ final_type = R_PARISC_PCREL64;
+ break;
+ default:
+ return R_PARISC_NONE;
+ }
+ break;
+
default:
return R_PARISC_NONE;
}
@@ -1048,7 +1069,7 @@ static bfd_boolean elf_hppa_sort_unwind (bfd *abfd)
static bfd_boolean
elf_hppa_add_symbol_hook (bfd *abfd,
struct bfd_link_info *info ATTRIBUTE_UNUSED,
- const Elf_Internal_Sym *sym,
+ Elf_Internal_Sym *sym,
const char **namep ATTRIBUTE_UNUSED,
flagword *flagsp ATTRIBUTE_UNUSED,
asection **secp,
@@ -1096,8 +1117,7 @@ elf_hppa_unmark_useless_dynamic_symbols (struct elf_link_hash_entry *h,
Ultimately we should have better controls over the generic ELF BFD
linker code. */
if (! info->relocatable
- && ! (info->shared
- && info->unresolved_syms_in_shared_libs == RM_IGNORE)
+ && info->unresolved_syms_in_shared_libs != RM_IGNORE
&& 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)
@@ -1131,8 +1151,7 @@ elf_hppa_remark_useless_dynamic_symbols (struct elf_link_hash_entry *h,
Ultimately we should have better controls over the generic ELF BFD
linker code. */
if (! info->relocatable
- && ! (info->shared
- && info->unresolved_syms_in_shared_libs == RM_IGNORE)
+ && info->unresolved_syms_in_shared_libs != RM_IGNORE
&& 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
@@ -1274,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,
@@ -1398,16 +1417,9 @@ elf_hppa_relocate_section (bfd *output_bfd,
else
relocation = 0;
}
- /* Allow undefined symbols in shared libraries. */
- else if (info->shared
- && info->unresolved_syms_in_shared_libs == RM_IGNORE
+ else if (info->unresolved_syms_in_objects == RM_IGNORE
&& ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
{
- if (info->symbolic)
- (*info->callbacks->undefined_symbol)
- (info, h->root.root.string, input_bfd,
- input_section, rel->r_offset, FALSE);
-
/* If this symbol has an entry in the PA64 dynamic hash
table, then get it. */
dyn_name = get_dyn_name (input_bfd, h, rel,
@@ -1449,7 +1461,9 @@ elf_hppa_relocate_section (bfd *output_bfd,
{
if (!((*info->callbacks->undefined_symbol)
(info, h->root.root.string, input_bfd,
- input_section, rel->r_offset, TRUE)))
+ input_section, rel->r_offset,
+ (info->unresolved_syms_in_objects == RM_GENERATE_ERROR
+ || ELF_ST_VISIBILITY (h->other)))))
return FALSE;
break;
}
diff --git a/bfd/elf-m10200.c b/bfd/elf-m10200.c
index 133d2a9..5268525 100644
--- a/bfd/elf-m10200.c
+++ b/bfd/elf-m10200.c
@@ -1,5 +1,5 @@
/* Matsushita 10200 specific support for 32-bit ELF
- Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@@ -377,28 +377,12 @@ mn10200_elf_relocate_section (output_bfd, info, input_bfd, input_section,
}
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;
- }
+ bfd_boolean unresolved_reloc, warned;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned);
}
r = mn10200_elf_final_link_relocate (howto, input_bfd, output_bfd,
diff --git a/bfd/elf-m10300.c b/bfd/elf-m10300.c
index f628e76..c64d34f 100644
--- a/bfd/elf-m10300.c
+++ b/bfd/elf-m10300.c
@@ -1,5 +1,5 @@
/* Matsushita 10300 specific support for 32-bit ELF
- Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@@ -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;
}
@@ -1537,15 +1537,14 @@ mn10300_elf_relocate_section (output_bfd, info, input_bfd, input_section,
asection **local_sections;
{
Elf_Internal_Shdr *symtab_hdr;
- struct elf32_mn10300_link_hash_entry **sym_hashes;
+ struct elf_link_hash_entry **sym_hashes;
Elf_Internal_Rela *rel, *relend;
if (info->relocatable)
return TRUE;
symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
- sym_hashes = (struct elf32_mn10300_link_hash_entry **)
- (elf_sym_hashes (input_bfd));
+ sym_hashes = elf_sym_hashes (input_bfd);
rel = relocs;
relend = relocs + input_section->reloc_count;
@@ -1584,10 +1583,10 @@ mn10300_elf_relocate_section (output_bfd, info, input_bfd, input_section,
bfd_boolean warned;
struct elf_link_hash_entry *hh;
- RELOC_FOR_GLOBAL_SYMBOL (hh, (struct elf_link_hash_entry *) sym_hashes,
- r_symndx, symtab_hdr, relocation,
- sec, unresolved_reloc, info,
- warned);
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ hh, sec, relocation,
+ unresolved_reloc, warned);
h = (struct elf32_mn10300_link_hash_entry *) hh;
@@ -4187,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;
}
@@ -4492,31 +4491,31 @@ _bfd_mn10300_elf_size_dynamic_sections (output_bfd, info)
in by the dynamic linker and used by the debugger. */
if (! info->shared)
{
- if (! bfd_elf32_add_dynamic_entry (info, DT_DEBUG, 0))
+ if (!_bfd_elf_add_dynamic_entry (info, DT_DEBUG, 0))
return FALSE;
}
if (plt)
{
- if (! bfd_elf32_add_dynamic_entry (info, DT_PLTGOT, 0)
- || ! bfd_elf32_add_dynamic_entry (info, DT_PLTRELSZ, 0)
- || ! bfd_elf32_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
- || ! bfd_elf32_add_dynamic_entry (info, DT_JMPREL, 0))
+ if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
+ || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0))
return FALSE;
}
if (relocs)
{
- if (! bfd_elf32_add_dynamic_entry (info, DT_RELA, 0)
- || ! bfd_elf32_add_dynamic_entry (info, DT_RELASZ, 0)
- || ! bfd_elf32_add_dynamic_entry (info, DT_RELAENT,
- sizeof (Elf32_External_Rela)))
+ if (!_bfd_elf_add_dynamic_entry (info, DT_RELA, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_RELASZ, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_RELAENT,
+ sizeof (Elf32_External_Rela)))
return FALSE;
}
if (reltext)
{
- if (! bfd_elf32_add_dynamic_entry (info, DT_TEXTREL, 0))
+ if (!_bfd_elf_add_dynamic_entry (info, DT_TEXTREL, 0))
return FALSE;
}
}
diff --git a/bfd/elf.c b/bfd/elf.c
index 33b58f5..00443c2 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -613,6 +613,12 @@ setup_group (bfd *abfd, Elf_Internal_Shdr *hdr, asection *newsect)
}
bfd_boolean
+bfd_elf_is_group_section (bfd *abfd ATTRIBUTE_UNUSED, const asection *sec)
+{
+ return elf_next_in_group (sec) != NULL;
+}
+
+bfd_boolean
bfd_elf_discard_group (bfd *abfd ATTRIBUTE_UNUSED, asection *group)
{
asection *first = elf_next_in_group (group);
@@ -652,6 +658,9 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
if (newsect == NULL)
return FALSE;
+ hdr->bfd_section = newsect;
+ elf_section_data (newsect)->this_hdr = *hdr;
+
/* Always use the real type/flags. */
elf_section_type (newsect) = hdr->sh_type;
elf_section_flags (newsect) = hdr->sh_flags;
@@ -798,9 +807,6 @@ _bfd_elf_make_section_from_shdr (bfd *abfd,
}
}
- hdr->bfd_section = newsect;
- elf_section_data (newsect)->this_hdr = *hdr;
-
return TRUE;
}
@@ -1479,8 +1485,7 @@ _bfd_elf_link_hash_table_create (bfd *abfd)
/* This is a hook for the ELF emulation code in the generic linker to
tell the backend linker what file name to use for the DT_NEEDED
- entry for a dynamic object. The generic linker passes name as an
- empty string to indicate that no DT_NEEDED entry should be made. */
+ entry for a dynamic object. */
void
bfd_elf_set_dt_needed_name (bfd *abfd, const char *name)
@@ -1491,11 +1496,11 @@ bfd_elf_set_dt_needed_name (bfd *abfd, const char *name)
}
void
-bfd_elf_set_dt_needed_soname (bfd *abfd, const char *name)
+bfd_elf_set_dyn_lib_class (bfd *abfd, int lib_class)
{
if (bfd_get_flavour (abfd) == bfd_target_elf_flavour
&& bfd_get_format (abfd) == bfd_object)
- elf_dt_soname (abfd) = name;
+ elf_dyn_lib_class (abfd) = lib_class;
}
/* Get the list of DT_NEEDED entries for a link. This is a hook for
@@ -1946,8 +1951,10 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex)
hdr->bfd_section->flags
|= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_DISCARD;
+ /* We try to keep the same section order as it comes in. */
+ idx += n_elt;
while (--n_elt != 0)
- if ((s = (++idx)->shdr->bfd_section) != NULL
+ if ((s = (--idx)->shdr->bfd_section) != NULL
&& elf_next_in_group (s) != NULL)
{
elf_next_in_group (hdr->bfd_section) = s;
@@ -2055,6 +2062,7 @@ static struct bfd_elf_special_section const special_sections[] =
{ ".gnu.version", 12, 0, SHT_GNU_versym, 0 },
{ ".gnu.version_d", 14, 0, SHT_GNU_verdef, 0 },
{ ".gnu.version_r", 14, 0, SHT_GNU_verneed, 0 },
+ { ".note.GNU-stack",15, 0, SHT_PROGBITS, 0 },
{ ".note", 5, -1, SHT_NOTE, 0 },
{ ".rela", 5, -1, SHT_RELA, 0 },
{ ".rel", 4, -1, SHT_REL, 0 },
@@ -2387,7 +2395,31 @@ elf_fake_sections (bfd *abfd, asection *asect, void *failedptrarg)
asect->flags. */
if (this_hdr->sh_type == SHT_NULL)
{
- if ((asect->flags & SEC_ALLOC) != 0
+ if ((asect->flags & SEC_GROUP) != 0)
+ {
+ /* We also need to mark SHF_GROUP here for relocatable
+ link. */
+ struct bfd_link_order *l;
+ asection *elt;
+
+ for (l = asect->link_order_head; l != NULL; l = l->next)
+ if (l->type == bfd_indirect_link_order
+ && (elt = elf_next_in_group (l->u.indirect.section)) != NULL)
+ do
+ {
+ /* The name is not important. Anything will do. */
+ elf_group_name (elt->output_section) = "G";
+ elf_section_flags (elt->output_section) |= SHF_GROUP;
+
+ elt = elf_next_in_group (elt);
+ /* During a relocatable link, the lists are
+ circular. */
+ }
+ while (elt != elf_next_in_group (l->u.indirect.section));
+
+ this_hdr->sh_type = SHT_GROUP;
+ }
+ else if ((asect->flags & SEC_ALLOC) != 0
&& (((asect->flags & (SEC_LOAD | SEC_HAS_CONTENTS)) == 0)
|| (asect->flags & SEC_NEVER_LOAD) != 0))
this_hdr->sh_type = SHT_NOBITS;
@@ -3187,6 +3219,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;
@@ -3266,6 +3299,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;
@@ -3314,18 +3348,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)
@@ -3337,7 +3372,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))))
{
@@ -3360,9 +3395,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;
}
@@ -3382,6 +3420,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;
}
@@ -7503,3 +7546,79 @@ bfd_elf_bfd_from_remote_memory
return (*get_elf_backend_data (templ)->elf_backend_bfd_from_remote_memory)
(templ, ehdr_vma, loadbasep, target_read_memory);
}
+
+long
+_bfd_elf_get_synthetic_symtab (bfd *abfd, asymbol **dynsyms, asymbol **ret)
+{
+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
+ asection *relplt;
+ asymbol *s;
+ const char *relplt_name;
+ bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean);
+ arelent *p;
+ long count, i, n;
+ size_t size;
+ Elf_Internal_Shdr *hdr;
+ char *names;
+ asection *plt;
+
+ *ret = NULL;
+ if (!bed->plt_sym_val)
+ return 0;
+
+ relplt_name = bed->relplt_name;
+ if (relplt_name == NULL)
+ relplt_name = bed->default_use_rela_p ? ".rela.plt" : ".rel.plt";
+ relplt = bfd_get_section_by_name (abfd, relplt_name);
+ if (relplt == NULL)
+ return 0;
+
+ hdr = &elf_section_data (relplt)->this_hdr;
+ if (hdr->sh_link != elf_dynsymtab (abfd)
+ || (hdr->sh_type != SHT_REL && hdr->sh_type != SHT_RELA))
+ return 0;
+
+ plt = bfd_get_section_by_name (abfd, ".plt");
+ if (plt == NULL)
+ return 0;
+
+ slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table;
+ if (! (*slurp_relocs) (abfd, relplt, dynsyms, TRUE))
+ return -1;
+
+ count = relplt->_raw_size / hdr->sh_entsize;
+ size = count * sizeof (asymbol);
+ p = relplt->relocation;
+ for (i = 0; i < count; i++, s++, p++)
+ size += strlen ((*p->sym_ptr_ptr)->name) + sizeof ("@plt");
+
+ s = *ret = bfd_malloc (size);
+ if (s == NULL)
+ return -1;
+
+ names = (char *) (s + count);
+ p = relplt->relocation;
+ n = 0;
+ for (i = 0; i < count; i++, s++, p++)
+ {
+ size_t len;
+ bfd_vma addr;
+
+ addr = bed->plt_sym_val (i, plt, p);
+ if (addr == (bfd_vma) -1)
+ continue;
+
+ *s = **p->sym_ptr_ptr;
+ s->section = plt;
+ s->value = addr - plt->vma;
+ s->name = names;
+ len = strlen ((*p->sym_ptr_ptr)->name);
+ memcpy (names, (*p->sym_ptr_ptr)->name, len);
+ names += len;
+ memcpy (names, "@plt", sizeof ("@plt"));
+ names += sizeof ("@plt");
+ ++n;
+ }
+
+ return n;
+}
diff --git a/bfd/elf32-arm.h b/bfd/elf32-arm.h
index 7c284c1..64da333 100644
--- a/bfd/elf32-arm.h
+++ b/bfd/elf32-arm.h
@@ -1,5 +1,6 @@
/* 32-bit ELF support for ARM
- Copyright 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@@ -105,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
@@ -189,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
@@ -246,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;
@@ -429,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;
@@ -807,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;
@@ -833,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;
@@ -1208,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
@@ -1337,6 +1361,8 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
into the output file to be resolved at run time. */
if (info->shared
&& (input_section->flags & SEC_ALLOC)
+ && (r_type != R_ARM_REL32
+ || !SYMBOL_CALLS_LOCAL (info, h))
&& (h == NULL
|| ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
|| h->root.type != bfd_link_hash_undefweak)
@@ -1743,6 +1769,33 @@ elf32_arm_final_link_relocate (howto, input_bfd, output_bfd,
return bfd_reloc_ok;
}
+#ifndef OLD_ARM_ABI
+ 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;
+#endif
+
case R_ARM_GNU_VTINHERIT:
case R_ARM_GNU_VTENTRY:
return bfd_reloc_ok;
@@ -2124,10 +2177,10 @@ elf32_arm_relocate_section (output_bfd, info, input_bfd, input_section,
bfd_boolean warned;
bfd_boolean unresolved_reloc;
- RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx,
- symtab_hdr, relocation,
- sec, unresolved_reloc, info,
- warned);
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned);
if (unresolved_reloc || relocation != 0)
{
@@ -2430,11 +2483,16 @@ elf32_arm_merge_private_bfd_data (ibfd, obfd)
not, its flags may not have been initialised either, but it
cannot actually cause any incompatibility. Do not short-circuit
dynamic objects; their section list may be emptied by
- elf_link_add_object_symbols. */
+ elf_link_add_object_symbols.
+ Also check to see if there are no code sections in the input.
+ In this case there is no need to check for code specific flags.
+ XXX - do we need to worry about floating-point format compatability
+ in data sections ? */
if (!(ibfd->flags & DYNAMIC))
{
bfd_boolean null_input_bfd = TRUE;
+ bfd_boolean only_data_sections = TRUE;
for (sec = ibfd->sections; sec != NULL; sec = sec->next)
{
@@ -2442,11 +2500,17 @@ elf32_arm_merge_private_bfd_data (ibfd, obfd)
if (strcmp (sec->name, ".glue_7")
&& strcmp (sec->name, ".glue_7t"))
{
+ if ((bfd_get_section_flags (ibfd, sec)
+ & (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
+ == (SEC_LOAD | SEC_CODE | SEC_HAS_CONTENTS))
+ only_data_sections = FALSE;
+
null_input_bfd = FALSE;
break;
}
}
- if (null_input_bfd)
+
+ if (null_input_bfd || only_data_sections)
return TRUE;
}
@@ -2667,6 +2731,18 @@ elf32_arm_print_private_bfd_data (abfd, ptr)
| EF_ARM_MAPSYMSFIRST);
break;
+ case EF_ARM_EABI_VER3:
+ fprintf (file, _(" [Version3 EABI]"));
+
+ if (flags & EF_ARM_BE8)
+ fprintf (file, _(" [BE8]"));
+
+ if (flags & EF_ARM_LE8)
+ fprintf (file, _(" [LE8]"));
+
+ flags &= ~(EF_ARM_LE8 | EF_ARM_BE8);
+ break;
+
default:
fprintf (file, _(" <EABI version unrecognised>"));
break;
@@ -2967,7 +3043,8 @@ elf32_arm_check_relocs (abfd, info, sec, relocs)
if (info->shared
&& (sec->flags & SEC_ALLOC) != 0
&& ((ELF32_R_TYPE (rel->r_info) != R_ARM_PC24
- && ELF32_R_TYPE (rel->r_info) != R_ARM_PLT32)
+ && ELF32_R_TYPE (rel->r_info) != R_ARM_PLT32
+ && ELF32_R_TYPE (rel->r_info) != R_ARM_REL32)
|| (h != NULL
&& (! info->symbolic
|| (h->elf_link_hash_flags
@@ -3056,14 +3133,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;
}
@@ -3319,7 +3396,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;
}
@@ -3379,7 +3456,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;
}
@@ -3432,7 +3509,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;
}
@@ -3641,7 +3718,7 @@ elf32_arm_size_dynamic_sections (output_bfd, info)
the .dynamic section. The DT_DEBUG entry is filled in by the
dynamic linker and used by the debugger. */
#define add_dynamic_entry(TAG, VAL) \
- bfd_elf32_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
if (!info->shared)
{
@@ -4012,11 +4089,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
@@ -4036,7 +4121,7 @@ elf32_arm_reloc_type_class (rela)
}
}
-static bfd_boolean elf32_arm_section_flags PARAMS ((flagword *, Elf_Internal_Shdr *));
+static bfd_boolean elf32_arm_section_flags PARAMS ((flagword *, const Elf_Internal_Shdr *));
static void elf32_arm_final_write_processing PARAMS ((bfd *, bfd_boolean));
/* Set the right machine number for an Arm ELF file. */
@@ -4044,7 +4129,7 @@ static void elf32_arm_final_write_processing PARAMS ((bfd *, bfd_boolean
static bfd_boolean
elf32_arm_section_flags (flags, hdr)
flagword *flags;
- Elf_Internal_Shdr *hdr;
+ const Elf_Internal_Shdr *hdr;
{
if (hdr->sh_type == SHT_NOTE)
*flags |= SEC_LINK_ONCE | SEC_LINK_DUPLICATES_SAME_CONTENTS;
@@ -4052,7 +4137,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;
@@ -4060,6 +4145,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__
@@ -4075,16 +4302,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-avr.c b/bfd/elf32-avr.c
index 44f2b38..06e398b 100644
--- a/bfd/elf32-avr.c
+++ b/bfd/elf32-avr.c
@@ -1,5 +1,6 @@
/* AVR-specific support for 32-bit ELF
- Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
Contributed by Denis Chertykov <denisc@overta.ru>
This file is part of BFD, the Binary File Descriptor library.
@@ -758,34 +759,12 @@ elf32_avr_relocate_section (output_bfd, info, input_bfd, input_section,
}
else
{
- h = sym_hashes [r_symndx - symtab_hdr->sh_info];
+ bfd_boolean unresolved_reloc, warned;
- 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;
-
- name = h->root.root.string;
-
- 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;
- }
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned);
}
r = avr_final_link_relocate (howto, input_bfd, input_section,
diff --git a/bfd/elf32-cr16c.c b/bfd/elf32-cr16c.c
new file mode 100644
index 0000000..e722335
--- /dev/null
+++ b/bfd/elf32-cr16c.c
@@ -0,0 +1,1000 @@
+/* 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
+ {
+ bfd_boolean unresolved_reloc, warned;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned);
+ }
+
+ 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,
+ 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 e2a51f6..775fd0e 100644
--- a/bfd/elf32-cris.c
+++ b/bfd/elf32-cris.c
@@ -1,5 +1,5 @@
/* CRIS-specific support for 32-bit ELF.
- Copyright 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Axis Communications AB.
Written by Hans-Peter Nilsson, based on elf32-fr30.c
PIC and shlib bits based primarily on elf32-m68k.c and elf32-i386.c.
@@ -859,7 +859,10 @@ cris_elf_relocate_section (output_bfd, info, input_bfd, input_section,
bfd_boolean warned;
bfd_boolean unresolved_reloc;
- RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx, symtab_hdr, relocation, sec, unresolved_reloc, info, warned);
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned);
if (unresolved_reloc
/* Perhaps we should detect the cases that
@@ -957,11 +960,25 @@ cris_elf_relocate_section (output_bfd, info, input_bfd, input_section,
statically linking PIC code, or when using -Bsymbolic. Check
that we instead have a GOT entry as done for us by
elf_cris_adjust_dynamic_symbol, and drop through into the
- ordinary GOT cases. */
- if (h != NULL && h->got.offset == (bfd_vma) -1)
+ ordinary GOT cases. This must not happen for the
+ executable, because any reference it does to a function
+ that is satisfied by a DSO must generate a PLT. We assume
+ these call-specific relocs don't address non-functions. */
+ if (h != NULL
+ && (h->got.offset == (bfd_vma) -1
+ || (!info->shared
+ && !((h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_REGULAR) != 0
+ || ((h->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_DYNAMIC) == 0
+ && h->root.type == bfd_link_hash_undefweak)))))
{
(*_bfd_error_handler)
- (_("%s: No PLT nor GOT for relocation %s against symbol `%s' from %s section"),
+ ((h->got.offset == (bfd_vma) -1)
+ ? _("%s: No PLT nor GOT for relocation %s against\
+ symbol `%s' from %s section")
+ : _("%s: No PLT for relocation %s against\
+ symbol `%s' from %s section"),
bfd_archive_filename (input_bfd),
cris_elf_howto_table[r_type].name,
symname[0] != '\0' ? symname : _("[whose name is lost]"),
@@ -993,18 +1010,25 @@ cris_elf_relocate_section (output_bfd, info, input_bfd, input_section,
if (!elf_hash_table (info)->dynamic_sections_created
|| (! info->shared
- && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR))
+ && ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)
+ || h->type == STT_FUNC
+ || (h->elf_link_hash_flags
+ & ELF_LINK_HASH_NEEDS_PLT)))
|| (info->shared
&& (info->symbolic || h->dynindx == -1)
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR)))
{
/* This wasn't checked above for ! info->shared, but
- must hold there if we get here; the symbol must be
- defined in the regular program, or be undefweak. */
+ must hold there if we get here; the symbol must
+ be defined in the regular program or be undefweak
+ or be a function or otherwise need a PLT. */
BFD_ASSERT (!elf_hash_table (info)->dynamic_sections_created
|| info->shared
|| (h->elf_link_hash_flags
& ELF_LINK_HASH_DEF_REGULAR) != 0
+ || h->type == STT_FUNC
+ || (h->elf_link_hash_flags
+ & ELF_LINK_HASH_NEEDS_PLT)
|| h->root.type == bfd_link_hash_undefweak);
/* This is actually a static link, or it is a
@@ -1418,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
@@ -1508,12 +1532,15 @@ elf_cris_finish_dynamic_symbol (output_bfd, info, h, sym)
}
}
- /* We don't emit .got relocs for symbols that aren't in the
- dynamic-symbols table for an ordinary program and are either defined
- by the program or are undefined weak symbols. */
+ /* For an ordinary program, we emit .got relocs only for symbols that
+ are in the dynamic-symbols table and are either defined by the
+ program or are undefined weak symbols, or are function symbols
+ where we do not output a PLT: the PLT reloc was output above and all
+ references to the function symbol are redirected to the PLT. */
if (h->got.offset != (bfd_vma) -1
&& (info->shared
|| (h->dynindx != -1
+ && h->plt.offset == (bfd_vma) -1
&& (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0
&& h->root.type != bfd_link_hash_undefweak)))
{
@@ -1835,13 +1862,12 @@ cris_elf_gc_sweep_hook (abfd, info, sec, relocs)
r_symndx = ELF32_R_SYM (rel->r_info);
if (r_symndx < symtab_hdr->sh_info)
goto local_got_reloc;
-
+ /* Fall through. */
case R_CRIS_32_PLT_GOTREL:
/* FIXME: We don't garbage-collect away the .got section. */
if (local_got_refcounts != NULL)
local_got_refcounts[-1]--;
/* Fall through. */
-
case R_CRIS_8_PCREL:
case R_CRIS_16_PCREL:
case R_CRIS_32_PCREL:
@@ -1926,16 +1952,22 @@ elf_cris_adjust_gotplt_to_got (h, p)
want to do this:
- When all PLT references are GOTPLT references, and there are GOT
- references. We don't have to generate a PLT at all.
+ references, and this is not the executable. We don't have to
+ generate a PLT at all.
- - When there are both (ordinary) PLT references and GOT references.
+ - When there are both (ordinary) PLT references and GOT references,
+ and this isn't the executable.
We want to make the PLT reference use the ordinary GOT entry rather
- than a run-time dynamically resolved GOTPLT entry (since the GOT
- entry will have to be resolved at startup anyway).
+ than R_CRIS_JUMP_SLOT, a run-time dynamically resolved GOTPLT entry,
+ since the GOT entry will have to be resolved at startup anyway.
Though the latter case is handled when room for the PLT is allocated,
not here.
+ By folding into the GOT, we may need a round-trip to a PLT in the
+ executable for calls, a loss in performance. Still, losing a
+ reloc is a win in size and at least in start-up time.
+
Note that this function is called before symbols are forced local by
version scripts. The differing cases are handled by
elf_cris_hide_symbol. */
@@ -2042,10 +2074,14 @@ elf_cris_adjust_dynamic_symbol (info, h)
info);
}
- /* If there are only GOT references and GOTPLT references to this
- PLT entry, get rid of the PLT. */
- if (! elf_cris_try_fold_plt_to_got ((struct elf_cris_link_hash_entry *)
- h, info))
+ /* If we had a R_CRIS_GLOB_DAT that didn't have to point to a PLT;
+ where a pointer-equivalent symbol was unimportant (i.e. more
+ like R_CRIS_JUMP_SLOT after symbol evaluation) we could get rid
+ of the PLT. We can't for the executable, because the GOT
+ entries will point to the PLT there (and be constant). */
+ if (info->shared
+ && !elf_cris_try_fold_plt_to_got ((struct elf_cris_link_hash_entry*)
+ h, info))
return FALSE;
/* GC or folding may have rendered this entry unused. */
@@ -2059,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;
}
@@ -2083,8 +2119,11 @@ elf_cris_adjust_dynamic_symbol (info, h)
/* If there's already a GOT entry, use that, not a .got.plt. A
GOT field still has a reference count when we get here; it's
- not yet changed to an offset. */
- if (h->got.refcount > 0)
+ not yet changed to an offset. We can't do this for an
+ executable, because then the reloc associated with the PLT
+ would get a non-PLT reloc pointing to the PLT. FIXME: Move
+ this to elf_cris_try_fold_plt_to_got. */
+ if (info->shared && h->got.refcount > 0)
{
h->got.refcount += h->plt.refcount;
@@ -2383,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;
}
@@ -2600,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;
@@ -2770,7 +2809,7 @@ elf_cris_size_dynamic_sections (output_bfd, info)
the .dynamic section. The DT_DEBUG entry is filled in by the
dynamic linker and used by the debugger. */
#define add_dynamic_entry(TAG, VAL) \
- bfd_elf32_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
if (!info->shared)
{
@@ -2857,9 +2896,11 @@ elf_cris_discard_excess_program_dynamics (h, inf)
/* If we're not creating a shared library and have a symbol which is
referred to by .got references, but the symbol is defined locally,
- (or rather, not not defined by a DSO) then lose the reloc for the
- .got (don't allocate room for it). */
- if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0)
+ (or rather, not defined by a DSO) then lose the reloc for the .got
+ (don't allocate room for it). Likewise for relocs for something
+ for which we create a PLT. */
+ if ((h->root.elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) == 0
+ || h->root.plt.refcount > 0)
{
if (h->root.got.refcount > 0
/* The size of this section is only valid and in sync with the
@@ -2885,7 +2926,8 @@ elf_cris_discard_excess_program_dynamics (h, inf)
introduce new problems. Of course we don't do this if we're
exporting all dynamic symbols. */
if (! info->export_dynamic
- && (h->root.elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0)
+ && (h->root.elf_link_hash_flags
+ & (ELF_LINK_HASH_DEF_DYNAMIC|ELF_LINK_HASH_REF_DYNAMIC)) == 0)
{
h->root.dynindx = -1;
_bfd_elf_strtab_delref (elf_hash_table (info)->dynstr,
@@ -3048,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 f9454ff..e845a25 100644
--- a/bfd/elf32-d10v.c
+++ b/bfd/elf32-d10v.c
@@ -1,5 +1,5 @@
/* D10V-specific support for 32-bit ELF
- Copyright 1996, 1998, 1999, 2000, 2001, 2002, 2003
+ Copyright 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Contributed by Martin Hunt (hunt@cygnus.com).
@@ -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;
}
@@ -517,28 +517,12 @@ elf32_d10v_relocate_section (output_bfd, info, input_bfd, input_section,
}
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;
- }
+ bfd_boolean unresolved_reloc, warned;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned);
}
if (h != NULL)
diff --git a/bfd/elf32-dlx.c b/bfd/elf32-dlx.c
index 6ccb9f5..7fb6d0c 100644
--- a/bfd/elf32-dlx.c
+++ b/bfd/elf32-dlx.c
@@ -558,14 +558,14 @@ elf32_dlx_check_relocs (abfd, info, sec, relocs)
/* This relocation describes the C++ object vtable hierarchy.
Reconstruct it for later use during GC. */
case R_DLX_GNU_VTINHERIT:
- if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
+ if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
return FALSE;
break;
/* This relocation describes which C++ vtable entries are actually
used. Record for later use during GC. */
case R_DLX_GNU_VTENTRY:
- if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
+ if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
return FALSE;
break;
}
diff --git a/bfd/elf32-fr30.c b/bfd/elf32-fr30.c
index 472a07a..5f70e3f 100644
--- a/bfd/elf32-fr30.c
+++ b/bfd/elf32-fr30.c
@@ -1,5 +1,5 @@
/* FR30-specific support for 32-bit ELF.
- Copyright 1998, 1999, 2000, 2001, 2002, 2003
+ Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@@ -566,47 +566,12 @@ fr30_elf_relocate_section (output_bfd, info, input_bfd, input_section,
}
else
{
- h = sym_hashes [r_symndx - symtab_hdr->sh_info];
+ bfd_boolean unresolved_reloc, warned;
- 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;
-
- name = h->root.root.string;
-
- 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);
-#if 0
- fprintf (stderr,
- "defined: sec: %s, name: %s, value: %x + %x + %x gives: %x\n",
- sec->name, name, h->root.u.def.value,
- sec->output_section->vma, sec->output_offset, relocation);
-#endif
- }
- else if (h->root.type == bfd_link_hash_undefweak)
- {
-#if 0
- fprintf (stderr, "undefined: sec: %s, name: %s\n",
- sec->name, name);
-#endif
- relocation = 0;
- }
- else
- {
- if (! ((*info->callbacks->undefined_symbol)
- (info, h->root.root.string, input_bfd,
- input_section, rel->r_offset, TRUE)))
- return FALSE;
-#if 0
- fprintf (stderr, "unknown: name: %s\n", name);
-#endif
- relocation = 0;
- }
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned);
}
r = fr30_final_link_relocate (howto, input_bfd, input_section,
@@ -753,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 488438e..6412acd 100644
--- a/bfd/elf32-frv.c
+++ b/bfd/elf32-frv.c
@@ -1,5 +1,5 @@
/* FRV-specific support for 32-bit ELF.
- Copyright 2002, 2003 Free Software Foundation, Inc.
+ Copyright 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@@ -22,6 +22,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "libbfd.h"
#include "elf-bfd.h"
#include "elf/frv.h"
+#include "elf/dwarf2.h"
#include "hashtab.h"
/* Forward declarations. */
@@ -51,7 +52,7 @@ static bfd_boolean elf32_frv_relocate_section
PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
static bfd_boolean elf32_frv_add_symbol_hook
- PARAMS (( bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,
+ PARAMS (( bfd *, struct bfd_link_info *, Elf_Internal_Sym *,
const char **, flagword *, asection **, bfd_vma *));
static bfd_reloc_status_type frv_final_link_relocate
PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *,
@@ -117,7 +118,7 @@ static reloc_howto_type elf32_frv_howto_table [] =
16, /* bitsize */
TRUE, /* pc_relative */
0, /* bitpos */
- complain_overflow_bitfield, /* complain_on_overflow */
+ complain_overflow_signed, /* complain_on_overflow */
bfd_elf_generic_reloc, /* special_function */
"R_FRV_LABEL16", /* name */
FALSE, /* partial_inplace */
@@ -659,7 +660,6 @@ frv_elf_link_hash_table_create (bfd *abfd)
#define FRV_SYM_LOCAL(INFO, H) \
(_bfd_elf_symbol_refs_local_p ((H), (INFO), 1) \
|| ! elf_hash_table (INFO)->dynamic_sections_created \
- || (H)->root.type == bfd_link_hash_undefweak \
|| (/* The condition below is an ugly hack to get .scommon data to
be regarded as local. For some reason the
ELF_LINK_HASH_DEF_REGULAR bit is not set on such common
@@ -748,6 +748,10 @@ struct frv_pic_relocs_info
relocations referencing the symbol. */
unsigned relocs32, relocsfd, relocsfdv;
+ /* The number of .rofixups entries and dynamic relocations allocated
+ for this symbol, minus any that might have already been used. */
+ unsigned fixups, dynrelocs;
+
/* The offsets of the GOT entries assigned to symbol+addend, to the
function descriptor's address, and to a function descriptor,
respectively. Should be zero if unassigned. The offsets are
@@ -789,10 +793,14 @@ frv_pic_relocs_info_eq (const void *entry1, const void *entry2)
static struct frv_pic_relocs_info *
frv_pic_relocs_info_find (struct htab *ht,
bfd *abfd,
- const struct frv_pic_relocs_info *entry)
+ const struct frv_pic_relocs_info *entry,
+ enum insert_option insert)
{
struct frv_pic_relocs_info **loc =
- (struct frv_pic_relocs_info **) htab_find_slot (ht, entry, INSERT);
+ (struct frv_pic_relocs_info **) htab_find_slot (ht, entry, insert);
+
+ if (! loc)
+ return NULL;
if (*loc)
return *loc;
@@ -818,7 +826,8 @@ inline static struct frv_pic_relocs_info *
frv_pic_relocs_info_for_global (struct htab *ht,
bfd *abfd,
struct elf_link_hash_entry *h,
- bfd_vma addend)
+ bfd_vma addend,
+ enum insert_option insert)
{
struct frv_pic_relocs_info entry;
@@ -826,7 +835,7 @@ frv_pic_relocs_info_for_global (struct htab *ht,
entry.d.h = h;
entry.addend = addend;
- return frv_pic_relocs_info_find (ht, abfd, &entry);
+ return frv_pic_relocs_info_find (ht, abfd, &entry, insert);
}
/* Obtain the address of the entry in HT associated with the SYMNDXth
@@ -836,7 +845,8 @@ inline static struct frv_pic_relocs_info *
frv_pic_relocs_info_for_local (struct htab *ht,
bfd *abfd,
long symndx,
- bfd_vma addend)
+ bfd_vma addend,
+ enum insert_option insert)
{
struct frv_pic_relocs_info entry;
@@ -844,7 +854,59 @@ frv_pic_relocs_info_for_local (struct htab *ht,
entry.d.abfd = abfd;
entry.addend = addend;
- return frv_pic_relocs_info_find (ht, abfd, &entry);
+ return frv_pic_relocs_info_find (ht, abfd, &entry, insert);
+}
+
+/* Merge fields set by check_relocs() of two entries that end up being
+ mapped to the same (presumably global) symbol. */
+
+inline static void
+frv_pic_merge_early_relocs_info (struct frv_pic_relocs_info *e2,
+ struct frv_pic_relocs_info const *e1)
+{
+ e2->got12 |= e1->got12;
+ e2->gotlos |= e1->gotlos;
+ e2->gothilo |= e1->gothilo;
+ e2->fd |= e1->fd;
+ e2->fdgot12 |= e1->fdgot12;
+ e2->fdgotlos |= e1->fdgotlos;
+ e2->fdgothilo |= e1->fdgothilo;
+ e2->fdgoff12 |= e1->fdgoff12;
+ e2->fdgofflos |= e1->fdgofflos;
+ e2->fdgoffhilo |= e1->fdgoffhilo;
+ e2->gotoff |= e1->gotoff;
+ e2->call |= e1->call;
+ e2->sym |= e1->sym;
+
+#if 0
+ /* These are set in _frv_count_got_plt_entries() or later, and this
+ function is only called in _frv_resolve_final_relocs_info(), that
+ runs just before it, so we don't have to worry about the fields
+ below. */
+
+ e2->plt |= e1->plt;
+ e2->privfd |= e1->privfd;
+ e2->lazyplt |= e1->lazyplt;
+ e2->done |= e1->done;
+
+ e2->relocs32 += e1->relocs32;
+ e2->relocsfd += e1->relocsfd;
+ e2->relocsfdv += e1->relocsfdv;
+ e2->fixups += e1->fixups;
+ e2->dynrelocs += e1->dynrelocs;
+
+ if (abs (e1->got_entry) < abs (e2->got_entry))
+ e2->got_entry = e1->got_entry;
+ if (abs (e1->fdgot_entry) < abs (e2->fdgot_entry))
+ e2->fdgot_entry = e1->fdgot_entry;
+ if (abs (e1->fd_entry) < abs (e2->fd_entry))
+ e2->fd_entry = e1->fd_entry;
+
+ if (e1->plt_entry < e2->plt_entry)
+ e2->plt_entry = e1->plt_entry;
+ if (e1->lzplt_entry < e2->lzplt_entry)
+ e2->lzplt_entry = e1->lzplt_entry;
+#endif
}
/* Every block of 65535 lazy PLT entries shares a single call to the
@@ -859,7 +921,8 @@ frv_pic_relocs_info_for_local (struct htab *ht,
inline static bfd_vma
_frv_add_dyn_reloc (bfd *output_bfd, asection *sreloc, bfd_vma offset,
- int reloc_type, long dynindx, bfd_vma addend)
+ int reloc_type, long dynindx, bfd_vma addend,
+ struct frv_pic_relocs_info *entry)
{
Elf_Internal_Rela outrel;
bfd_vma reloc_offset;
@@ -874,13 +937,17 @@ _frv_add_dyn_reloc (bfd *output_bfd, asection *sreloc, bfd_vma offset,
sreloc->contents + reloc_offset);
sreloc->reloc_count++;
+ BFD_ASSERT (entry->dynrelocs > 0);
+ entry->dynrelocs--;
+
return reloc_offset;
}
/* Add a fixup to the ROFIXUP section. */
static bfd_vma
-_frv_add_rofixup (bfd *output_bfd, asection *rofixup, bfd_vma offset)
+_frv_add_rofixup (bfd *output_bfd, asection *rofixup, bfd_vma offset,
+ struct frv_pic_relocs_info *entry)
{
bfd_vma fixup_offset;
@@ -894,7 +961,13 @@ _frv_add_rofixup (bfd *output_bfd, asection *rofixup, bfd_vma offset)
bfd_put_32 (output_bfd, offset, rofixup->contents + fixup_offset);
}
rofixup->reloc_count++;
-
+
+ if (entry)
+ {
+ BFD_ASSERT (entry->fixups > 0);
+ entry->fixups--;
+ }
+
return fixup_offset;
}
@@ -999,13 +1072,13 @@ _frv_emit_got_relocs_plt_entries (struct frv_pic_relocs_info *entry,
{
if (sec)
ad += sec->output_section->vma;
- if (entry->symndx != -1 ||
- entry->d.h->root.type != bfd_link_hash_undefweak)
+ if (entry->symndx != -1
+ || entry->d.h->root.type != bfd_link_hash_undefweak)
_frv_add_rofixup (output_bfd, frv_gotfixup_section (info),
frv_got_section (info)->output_section->vma
+ frv_got_section (info)->output_offset
+ frv_got_initial_offset (info)
- + entry->got_entry);
+ + entry->got_entry, entry);
}
else
_frv_add_dyn_reloc (output_bfd, frv_gotrel_section (info),
@@ -1016,7 +1089,7 @@ _frv_emit_got_relocs_plt_entries (struct frv_pic_relocs_info *entry,
+ entry->got_entry)
+ frv_got_section (info)->output_section->vma
+ frv_got_section (info)->output_offset,
- R_FRV_32, idx, ad);
+ R_FRV_32, idx, ad, entry);
bfd_put_32 (output_bfd, ad,
frv_got_section (info)->contents
@@ -1029,65 +1102,79 @@ _frv_emit_got_relocs_plt_entries (struct frv_pic_relocs_info *entry,
if (entry->fdgot_entry)
{
int reloc, idx;
- bfd_vma ad;
+ bfd_vma ad = 0;
- /* If the symbol is dynamic and there may be dynamic symbol
- resolution because we are or are linked with a shared
- library, emit a FUNCDESC relocation such that the dynamic
- linker will allocate the function descriptor. */
- if (entry->symndx == -1 && ! FRV_FUNCDESC_LOCAL (info, entry->d.h))
+ if (! (entry->symndx == -1
+ && entry->d.h->root.type == bfd_link_hash_undefweak
+ && FRV_SYM_LOCAL (info, entry->d.h)))
{
- reloc = R_FRV_FUNCDESC;
- idx = dynindx;
- ad = addend;
- if (ad)
- return FALSE;
- }
- else
- {
- /* Otherwise, we know we have a private function descriptor,
- so reference it directly. */
- if (elf_hash_table (info)->dynamic_sections_created)
- BFD_ASSERT (entry->privfd);
- reloc = R_FRV_32;
- idx = elf_section_data (frv_got_section (info)->output_section)
- ->dynindx;
- ad = frv_got_section (info)->output_offset +
- frv_got_initial_offset (info) + entry->fd_entry;
- }
-
- /* If there is room for dynamic symbol resolution, emit the
- dynamic relocation. However, if we're linking an executable
- at a fixed location, we won't have emitted a dynamic symbol
- entry for the got section, so idx will be zero, which means
- we can and should compute the address of the private
- descriptor ourselves. */
- if (info->executable && !info->pie
- && (entry->symndx != -1 || FRV_FUNCDESC_LOCAL (info, entry->d.h)))
- {
- if (entry->symndx == -1
- && entry->d.h->root.type == bfd_link_hash_undefweak)
- ad = 0;
+ /* If the symbol is dynamic and there may be dynamic symbol
+ resolution because we are, or are linked with, a shared
+ library, emit a FUNCDESC relocation such that the dynamic
+ linker will allocate the function descriptor. If the
+ symbol needs a non-local function descriptor but binds
+ locally (e.g., its visibility is protected, emit a
+ dynamic relocation decayed to section+offset. */
+ if (entry->symndx == -1 && ! FRV_FUNCDESC_LOCAL (info, entry->d.h)
+ && FRV_SYM_LOCAL (info, entry->d.h)
+ && !(info->executable && !info->pie))
+ {
+ reloc = R_FRV_FUNCDESC;
+ idx = elf_section_data (entry->d.h->root.u.def.section
+ ->output_section)->dynindx;
+ ad = entry->d.h->root.u.def.section->output_offset
+ + entry->d.h->root.u.def.value;
+ }
+ else if (entry->symndx == -1
+ && ! FRV_FUNCDESC_LOCAL (info, entry->d.h))
+ {
+ reloc = R_FRV_FUNCDESC;
+ idx = dynindx;
+ ad = addend;
+ if (ad)
+ return FALSE;
+ }
else
{
+ /* Otherwise, we know we have a private function descriptor,
+ so reference it directly. */
+ if (elf_hash_table (info)->dynamic_sections_created)
+ BFD_ASSERT (entry->privfd);
+ reloc = R_FRV_32;
+ idx = elf_section_data (frv_got_section (info)
+ ->output_section)->dynindx;
+ ad = frv_got_section (info)->output_offset
+ + frv_got_initial_offset (info) + entry->fd_entry;
+ }
+
+ /* If there is room for dynamic symbol resolution, emit the
+ dynamic relocation. However, if we're linking an
+ executable at a fixed location, we won't have emitted a
+ dynamic symbol entry for the got section, so idx will be
+ zero, which means we can and should compute the address
+ of the private descriptor ourselves. */
+ if (info->executable && !info->pie
+ && (entry->symndx != -1
+ || FRV_FUNCDESC_LOCAL (info, entry->d.h)))
+ {
ad += frv_got_section (info)->output_section->vma;
_frv_add_rofixup (output_bfd, frv_gotfixup_section (info),
frv_got_section (info)->output_section->vma
+ frv_got_section (info)->output_offset
+ frv_got_initial_offset (info)
- + entry->fdgot_entry);
+ + entry->fdgot_entry, entry);
}
+ else
+ _frv_add_dyn_reloc (output_bfd, frv_gotrel_section (info),
+ _bfd_elf_section_offset
+ (output_bfd, info,
+ frv_got_section (info),
+ frv_got_initial_offset (info)
+ + entry->fdgot_entry)
+ + frv_got_section (info)->output_section->vma
+ + frv_got_section (info)->output_offset,
+ reloc, idx, ad, entry);
}
- else
- _frv_add_dyn_reloc (output_bfd, frv_gotrel_section (info),
- _bfd_elf_section_offset
- (output_bfd, info,
- frv_got_section (info),
- frv_got_initial_offset (info)
- + entry->fdgot_entry)
- + frv_got_section (info)->output_section->vma
- + frv_got_section (info)->output_offset,
- reloc, idx, ad);
bfd_put_32 (output_bfd, ad,
frv_got_section (info)->contents
@@ -1128,19 +1215,19 @@ _frv_emit_got_relocs_plt_entries (struct frv_pic_relocs_info *entry,
if (sec)
ad += sec->output_section->vma;
ofst = 0;
- if (entry->symndx != -1 ||
- entry->d.h->root.type != bfd_link_hash_undefweak)
+ if (entry->symndx != -1
+ || entry->d.h->root.type != bfd_link_hash_undefweak)
{
_frv_add_rofixup (output_bfd, frv_gotfixup_section (info),
frv_got_section (info)->output_section->vma
+ frv_got_section (info)->output_offset
+ frv_got_initial_offset (info)
- + entry->fd_entry);
+ + entry->fd_entry, entry);
_frv_add_rofixup (output_bfd, frv_gotfixup_section (info),
frv_got_section (info)->output_section->vma
+ frv_got_section (info)->output_offset
+ frv_got_initial_offset (info)
- + entry->fd_entry + 4);
+ + entry->fd_entry + 4, entry);
}
}
else
@@ -1156,7 +1243,7 @@ _frv_emit_got_relocs_plt_entries (struct frv_pic_relocs_info *entry,
+ entry->fd_entry)
+ frv_got_section (info)->output_section->vma
+ frv_got_section (info)->output_offset,
- R_FRV_FUNCDESC_VALUE, idx, ad);
+ R_FRV_FUNCDESC_VALUE, idx, ad, entry);
}
/* If we've omitted the dynamic relocation, just emit the fixed
@@ -1871,16 +1958,16 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
{
relocation = 0;
}
- else if ( ! info->executable
- && ! info->symbolic
- && info->unresolved_syms_in_objects == RM_IGNORE
+ else if (info->unresolved_syms_in_objects == RM_IGNORE
&& ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
relocation = 0;
else
{
if (! ((*info->callbacks->undefined_symbol)
(info, h->root.root.string, input_bfd,
- input_section, rel->r_offset, TRUE)))
+ input_section, rel->r_offset,
+ (info->unresolved_syms_in_objects == RM_GENERATE_ERROR
+ || ELF_ST_VISIBILITY (h->other)))))
return FALSE;
relocation = 0;
}
@@ -1908,14 +1995,14 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
if (h != NULL)
picrel = frv_pic_relocs_info_for_global (frv_relocs_info (info),
input_bfd, h,
- orig_addend);
+ orig_addend, INSERT);
else
/* In order to find the entry we created before, we must
use the original addend, not the one that may have been
modified by _bfd_elf_rela_local_sym(). */
picrel = frv_pic_relocs_info_for_local (frv_relocs_info (info),
input_bfd, r_symndx,
- orig_addend);
+ orig_addend, INSERT);
if (! picrel)
return FALSE;
@@ -2005,88 +2092,104 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
int dynindx;
bfd_vma addend = rel->r_addend;
- /* If the symbol is dynamic and there may be dynamic
- symbol resolution because we are or are linked with a
- shared library, emit a FUNCDESC relocation such that
- the dynamic linker will allocate the function
- descriptor. */
- if (h && ! FRV_FUNCDESC_LOCAL (info, h))
+ if (! (h && h->root.type == bfd_link_hash_undefweak
+ && FRV_SYM_LOCAL (info, h)))
{
- if (addend)
+ /* If the symbol is dynamic and there may be dynamic
+ symbol resolution because we are or are linked with a
+ shared library, emit a FUNCDESC relocation such that
+ the dynamic linker will allocate the function
+ descriptor. If the symbol needs a non-local function
+ descriptor but binds locally (e.g., its visibility is
+ protected, emit a dynamic relocation decayed to
+ section+offset. */
+ if (h && ! FRV_FUNCDESC_LOCAL (info, h)
+ && FRV_SYM_LOCAL (info, h)
+ && !(info->executable && !info->pie))
{
- info->callbacks->warning
- (info, _("R_FRV_FUNCDESC references dynamic symbol with nonzero addend"),
- name, input_bfd, input_section, rel->r_offset);
- return FALSE;
+ dynindx = elf_section_data (h->root.u.def.section
+ ->output_section)->dynindx;
+ addend += h->root.u.def.section->output_offset
+ + h->root.u.def.value;
+ }
+ else if (h && ! FRV_FUNCDESC_LOCAL (info, h))
+ {
+ if (addend)
+ {
+ info->callbacks->warning
+ (info, _("R_FRV_FUNCDESC references dynamic symbol with nonzero addend"),
+ name, input_bfd, input_section, rel->r_offset);
+ return FALSE;
+ }
+ dynindx = h->dynindx;
+ }
+ else
+ {
+ /* Otherwise, we know we have a private function
+ descriptor, so reference it directly. */
+ BFD_ASSERT (picrel->privfd);
+ r_type = R_FRV_32;
+ dynindx = elf_section_data (frv_got_section (info)
+ ->output_section)->dynindx;
+ addend = frv_got_section (info)->output_offset
+ + frv_got_initial_offset (info)
+ + picrel->fd_entry;
}
- dynindx = h->dynindx;
- }
- else
- {
- /* Otherwise, we know we have a private function
- descriptor, so reference it directly. */
- BFD_ASSERT (picrel->privfd);
- r_type = R_FRV_32;
- dynindx = elf_section_data (frv_got_section
- (info)->output_section)->dynindx;
- addend = frv_got_section (info)->output_offset
- + frv_got_initial_offset (info)
- + picrel->fd_entry;
- }
- /* If there is room for dynamic symbol resolution, emit
- the dynamic relocation. However, if we're linking an
- executable at a fixed location, we won't have emitted a
- dynamic symbol entry for the got section, so idx will
- be zero, which means we can and should compute the
- address of the private descriptor ourselves. */
- if (info->executable && !info->pie
- && (!h || FRV_FUNCDESC_LOCAL (info, h)))
- {
- addend += frv_got_section (info)->output_section->vma;
- if ((bfd_get_section_flags (output_bfd,
- input_section->output_section)
- & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
+ /* If there is room for dynamic symbol resolution, emit
+ the dynamic relocation. However, if we're linking an
+ executable at a fixed location, we won't have emitted a
+ dynamic symbol entry for the got section, so idx will
+ be zero, which means we can and should compute the
+ address of the private descriptor ourselves. */
+ if (info->executable && !info->pie
+ && (!h || FRV_FUNCDESC_LOCAL (info, h)))
+ {
+ addend += frv_got_section (info)->output_section->vma;
+ if ((bfd_get_section_flags (output_bfd,
+ input_section->output_section)
+ & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
+ {
+ if (_frv_osec_readonly_p (output_bfd,
+ input_section->output_section))
+ {
+ info->callbacks->warning
+ (info,
+ _("cannot emit fixups in read-only section"),
+ name, input_bfd, input_section, rel->r_offset);
+ return FALSE;
+ }
+ _frv_add_rofixup (output_bfd,
+ frv_gotfixup_section (info),
+ _bfd_elf_section_offset
+ (output_bfd, info,
+ input_section, rel->r_offset)
+ + input_section->output_section->vma
+ + input_section->output_offset,
+ picrel);
+ }
+ }
+ else if ((bfd_get_section_flags (output_bfd,
+ input_section->output_section)
+ & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
{
if (_frv_osec_readonly_p (output_bfd,
input_section->output_section))
{
info->callbacks->warning
(info,
- _("cannot emit fixups in read-only section"),
+ _("cannot emit dynamic relocations in read-only section"),
name, input_bfd, input_section, rel->r_offset);
return FALSE;
}
- if (! h || h->root.type != bfd_link_hash_undefweak)
- _frv_add_rofixup (output_bfd,
- frv_gotfixup_section (info),
+ _frv_add_dyn_reloc (output_bfd, frv_gotrel_section (info),
_bfd_elf_section_offset
(output_bfd, info,
input_section, rel->r_offset)
+ input_section->output_section->vma
- + input_section->output_offset);
- }
- }
- else if ((bfd_get_section_flags (output_bfd,
- input_section->output_section)
- & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
- {
- if (_frv_osec_readonly_p (output_bfd,
- input_section->output_section))
- {
- info->callbacks->warning
- (info,
- _("cannot emit dynamic relocations in read-only section"),
- name, input_bfd, input_section, rel->r_offset);
- return FALSE;
+ + input_section->output_offset,
+ r_type, dynindx, addend, picrel);
}
- _frv_add_dyn_reloc (output_bfd, frv_gotrel_section (info),
- _bfd_elf_section_offset
- (output_bfd, info,
- input_section, rel->r_offset)
- + input_section->output_section->vma
- + input_section->output_offset,
- r_type, dynindx, addend);
}
/* We want the addend in-place because dynamic
@@ -2163,7 +2266,8 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
(output_bfd, info,
input_section, rel->r_offset)
+ input_section->output_section->vma
- + input_section->output_offset);
+ + input_section->output_offset,
+ picrel);
if (r_type == R_FRV_FUNCDESC_VALUE)
_frv_add_rofixup
(output_bfd,
@@ -2172,7 +2276,7 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
(output_bfd, info,
input_section, rel->r_offset)
+ input_section->output_section->vma
- + input_section->output_offset + 4);
+ + input_section->output_offset + 4, picrel);
}
}
}
@@ -2197,7 +2301,7 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section,
input_section, rel->r_offset)
+ input_section->output_section->vma
+ input_section->output_offset,
- r_type, dynindx, addend);
+ r_type, dynindx, addend, picrel);
}
/* We want the addend in-place because dynamic
relocations are REL. Setting relocation to it
@@ -2480,7 +2584,7 @@ static bfd_boolean
elf32_frv_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
bfd *abfd;
struct bfd_link_info *info;
- const Elf_Internal_Sym *sym;
+ Elf_Internal_Sym *sym;
const char **namep ATTRIBUTE_UNUSED;
flagword *flagsp ATTRIBUTE_UNUSED;
asection **secp;
@@ -2572,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;
@@ -2620,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;
@@ -2675,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;
}
@@ -2777,6 +2881,7 @@ _frv_count_got_plt_entries (void **entryp, void *dinfo_)
{
struct frv_pic_relocs_info *entry = *entryp;
struct _frv_dynamic_got_info *dinfo = dinfo_;
+ unsigned relocs = 0, fixups = 0;
/* Allocate space for a GOT entry pointing to the symbol. */
if (entry->got12)
@@ -2833,27 +2938,33 @@ _frv_count_got_plt_entries (void **entryp, void *dinfo_)
dinfo->lzplt += 8;
if (!dinfo->info->executable || dinfo->info->pie)
- dinfo->relocs += entry->relocs32 + entry->relocsfd + entry->relocsfdv;
+ relocs = entry->relocs32 + entry->relocsfd + entry->relocsfdv;
else
{
if (entry->symndx != -1 || FRV_SYM_LOCAL (dinfo->info, entry->d.h))
{
if (entry->symndx != -1
- || entry->d.h->root.type != bfd_link_hash_undefweak)
- dinfo->fixups += entry->relocs32 + 2 * entry->relocsfdv;
+ || entry->d.h->root.type != bfd_link_hash_undefweak)
+ fixups += entry->relocs32 + 2 * entry->relocsfdv;
}
else
- dinfo->relocs += entry->relocs32 + entry->relocsfdv;
+ relocs += entry->relocs32 + entry->relocsfdv;
+
if (entry->symndx != -1 || FRV_FUNCDESC_LOCAL (dinfo->info, entry->d.h))
{
if (entry->symndx != -1
|| entry->d.h->root.type != bfd_link_hash_undefweak)
- dinfo->fixups += entry->relocsfd;
+ fixups += entry->relocsfd;
}
else
- dinfo->relocs += entry->relocsfd;
+ relocs += entry->relocsfd;
}
+ entry->dynrelocs += relocs;
+ entry->fixups += fixups;
+ dinfo->relocs += relocs;
+ dinfo->fixups += fixups;
+
return 1;
}
@@ -3181,6 +3292,7 @@ _frv_resolve_final_relocs_info (void **entryp, void *p)
if (entry->symndx == -1)
{
struct elf_link_hash_entry *h = entry->d.h;
+ struct frv_pic_relocs_info *oentry;
while (h->root.type == bfd_link_hash_indirect
|| h->root.type == bfd_link_hash_warning)
@@ -3189,6 +3301,17 @@ _frv_resolve_final_relocs_info (void **entryp, void *p)
if (entry->d.h == h)
return 1;
+ oentry = frv_pic_relocs_info_for_global (*htab, 0, h, entry->addend,
+ NO_INSERT);
+
+ if (oentry)
+ {
+ /* Merge the two entries. */
+ frv_pic_merge_early_relocs_info (oentry, entry);
+ htab_clear_slot (*htab, entryp);
+ return 1;
+ }
+
entry->d.h = h;
/* If we can't find this entry with the new bfd hash, re-insert
@@ -3413,20 +3536,20 @@ elf32_frv_size_dynamic_sections (bfd *output_bfd,
if (elf_hash_table (info)->dynamic_sections_created)
{
if (frv_got_section (info)->_raw_size)
- if (! bfd_elf32_add_dynamic_entry (info, DT_PLTGOT, 0))
+ if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0))
return FALSE;
if (frv_pltrel_section (info)->_raw_size)
- if (! bfd_elf32_add_dynamic_entry (info, DT_PLTRELSZ, 0)
- || ! bfd_elf32_add_dynamic_entry (info, DT_PLTREL, DT_REL)
- || ! bfd_elf32_add_dynamic_entry (info, DT_JMPREL, 0))
+ if (!_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_REL)
+ || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0))
return FALSE;
if (frv_gotrel_section (info)->_raw_size)
- if (! bfd_elf32_add_dynamic_entry (info, DT_REL, 0)
- || ! bfd_elf32_add_dynamic_entry (info, DT_RELSZ, 0)
- || ! bfd_elf32_add_dynamic_entry (info, DT_RELENT,
- sizeof (Elf32_External_Rel)))
+ if (!_bfd_elf_add_dynamic_entry (info, DT_REL, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_RELSZ, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_RELENT,
+ sizeof (Elf32_External_Rel)))
return FALSE;
}
@@ -3552,13 +3675,22 @@ elf32_frv_finish_dynamic_sections (bfd *output_bfd,
+ hgot->root.u.def.section->output_offset;
_frv_add_rofixup (output_bfd, frv_gotfixup_section (info),
- got_value);
+ got_value, 0);
}
if (frv_gotfixup_section (info)->_raw_size
!= (frv_gotfixup_section (info)->reloc_count * 4))
{
- if (!elf_hash_table (info)->dynamic_sections_created)
+ if (frv_gotfixup_section (info)->_raw_size
+ < frv_gotfixup_section (info)->reloc_count * 4)
+ {
+ info->callbacks->warning
+ (info, "LINKER BUG: .rofixup section size mismatch",
+ ".rofixup", NULL, NULL, 0);
+ abort ();
+ return FALSE;
+ }
+ else if (!elf_hash_table (info)->dynamic_sections_created)
{
info->callbacks->warning
(info, "no dynamic sections, missing -melf32frvfd?",
@@ -3672,6 +3804,57 @@ elf32_frv_finish_dynamic_symbol (bfd *output_bfd ATTRIBUTE_UNUSED,
return TRUE;
}
+/* Decide whether to attempt to turn absptr or lsda encodings in
+ shared libraries into pcrel within the given input section. */
+
+static bfd_boolean
+frv_elf_use_relative_eh_frame (bfd *input_bfd,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ asection *eh_frame_section ATTRIBUTE_UNUSED)
+{
+ /* We can't use PC-relative encodings in FDPIC binaries, in general. */
+ if (elf_elfheader (input_bfd)->e_flags & EF_FRV_FDPIC)
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Adjust the contents of an eh_frame_hdr section before they're output. */
+
+static bfd_byte
+frv_elf_encode_eh_address (bfd *abfd,
+ struct bfd_link_info *info,
+ asection *osec, bfd_vma offset,
+ asection *loc_sec, bfd_vma loc_offset,
+ bfd_vma *encoded)
+{
+ struct elf_link_hash_entry *h;
+
+ /* Non-FDPIC binaries can use PC-relative encodings. */
+ if (! (elf_elfheader (abfd)->e_flags & EF_FRV_FDPIC))
+ return _bfd_elf_encode_eh_address (abfd, info, osec, offset,
+ loc_sec, loc_offset, encoded);
+
+ h = elf_hash_table (info)->hgot;
+ BFD_ASSERT (h && h->root.type == bfd_link_hash_defined);
+
+ if (! h || (_frv_osec_to_segment (abfd, osec)
+ == _frv_osec_to_segment (abfd, loc_sec->output_section)))
+ return _bfd_elf_encode_eh_address (abfd, info, osec, offset,
+ loc_sec, loc_offset, encoded);
+
+ BFD_ASSERT (_frv_osec_to_segment (abfd, osec)
+ == _frv_osec_to_segment (abfd,
+ h->root.u.def.section->output_section));
+
+ *encoded = osec->vma + offset
+ - (h->root.u.def.value
+ + h->root.u.def.section->output_section->vma
+ + h->root.u.def.section->output_offset);
+
+ return DW_EH_PE_datarel | DW_EH_PE_sdata4;
+}
+
/* Look through the relocs for a section during the first phase.
Besides handling virtual table relocs for gc, we have to deal with
@@ -3845,18 +4028,18 @@ 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
= frv_pic_relocs_info_for_global (frv_relocs_info (info),
abfd, h,
- rel->r_addend);
+ rel->r_addend, INSERT);
}
else
picrel = frv_pic_relocs_info_for_local (frv_relocs_info (info),
abfd, r_symndx,
- rel->r_addend);
+ rel->r_addend, INSERT);
if (! picrel)
return FALSE;
break;
@@ -3924,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;
}
@@ -3952,6 +4135,8 @@ elf32_frv_machine (abfd)
default: break;
case EF_FRV_CPU_FR550: return bfd_mach_fr550;
case EF_FRV_CPU_FR500: return bfd_mach_fr500;
+ case EF_FRV_CPU_FR450: return bfd_mach_fr450;
+ case EF_FRV_CPU_FR405: return bfd_mach_fr400;
case EF_FRV_CPU_FR400: return bfd_mach_fr400;
case EF_FRV_CPU_FR300: return bfd_mach_fr300;
case EF_FRV_CPU_SIMPLE: return bfd_mach_frvsimple;
@@ -4002,6 +4187,33 @@ frv_elf_copy_private_bfd_data (ibfd, obfd)
return TRUE;
}
+/* Return true if the architecture described by elf header flag
+ EXTENSION is an extension of the architecture described by BASE. */
+
+static bfd_boolean
+frv_elf_arch_extension_p (flagword base, flagword extension)
+{
+ if (base == extension)
+ return TRUE;
+
+ /* CPU_GENERIC code can be merged with code for a specific
+ architecture, in which case the result is marked as being
+ for the specific architecture. Everything is therefore
+ an extension of CPU_GENERIC. */
+ if (base == EF_FRV_CPU_GENERIC)
+ return TRUE;
+
+ if (extension == EF_FRV_CPU_FR450)
+ if (base == EF_FRV_CPU_FR400 || base == EF_FRV_CPU_FR405)
+ return TRUE;
+
+ if (extension == EF_FRV_CPU_FR405)
+ if (base == EF_FRV_CPU_FR400)
+ return TRUE;
+
+ return FALSE;
+}
+
/* Merge backend specific data from an object file to the output
object file when linking. */
@@ -4186,13 +4398,10 @@ frv_elf_merge_private_bfd_data (ibfd, obfd)
the generic cpu). */
new_partial = (new_flags & EF_FRV_CPU_MASK);
old_partial = (old_flags & EF_FRV_CPU_MASK);
- if (new_partial == old_partial)
- ;
-
- else if (new_partial == EF_FRV_CPU_GENERIC)
+ if (frv_elf_arch_extension_p (new_partial, old_partial))
;
- else if (old_partial == EF_FRV_CPU_GENERIC)
+ else if (frv_elf_arch_extension_p (old_partial, new_partial))
old_flags = (old_flags & ~EF_FRV_CPU_MASK) | new_partial;
else
@@ -4204,6 +4413,8 @@ frv_elf_merge_private_bfd_data (ibfd, obfd)
case EF_FRV_CPU_SIMPLE: strcat (new_opt, " -mcpu=simple"); break;
case EF_FRV_CPU_FR550: strcat (new_opt, " -mcpu=fr550"); break;
case EF_FRV_CPU_FR500: strcat (new_opt, " -mcpu=fr500"); break;
+ case EF_FRV_CPU_FR450: strcat (new_opt, " -mcpu=fr450"); break;
+ case EF_FRV_CPU_FR405: strcat (new_opt, " -mcpu=fr405"); break;
case EF_FRV_CPU_FR400: strcat (new_opt, " -mcpu=fr400"); break;
case EF_FRV_CPU_FR300: strcat (new_opt, " -mcpu=fr300"); break;
case EF_FRV_CPU_TOMCAT: strcat (new_opt, " -mcpu=tomcat"); break;
@@ -4216,6 +4427,8 @@ frv_elf_merge_private_bfd_data (ibfd, obfd)
case EF_FRV_CPU_SIMPLE: strcat (old_opt, " -mcpu=simple"); break;
case EF_FRV_CPU_FR550: strcat (old_opt, " -mcpu=fr550"); break;
case EF_FRV_CPU_FR500: strcat (old_opt, " -mcpu=fr500"); break;
+ case EF_FRV_CPU_FR450: strcat (old_opt, " -mcpu=fr450"); break;
+ case EF_FRV_CPU_FR405: strcat (old_opt, " -mcpu=fr405"); break;
case EF_FRV_CPU_FR400: strcat (old_opt, " -mcpu=fr400"); break;
case EF_FRV_CPU_FR300: strcat (old_opt, " -mcpu=fr300"); break;
case EF_FRV_CPU_TOMCAT: strcat (old_opt, " -mcpu=tomcat"); break;
@@ -4283,6 +4496,8 @@ frv_elf_print_private_bfd_data (abfd, ptr)
case EF_FRV_CPU_SIMPLE: fprintf (file, " -mcpu=simple"); break;
case EF_FRV_CPU_FR550: fprintf (file, " -mcpu=fr550"); break;
case EF_FRV_CPU_FR500: fprintf (file, " -mcpu=fr500"); break;
+ case EF_FRV_CPU_FR450: fprintf (file, " -mcpu=fr450"); break;
+ case EF_FRV_CPU_FR405: fprintf (file, " -mcpu=fr405"); break;
case EF_FRV_CPU_FR400: fprintf (file, " -mcpu=fr400"); break;
case EF_FRV_CPU_FR300: fprintf (file, " -mcpu=fr300"); break;
case EF_FRV_CPU_TOMCAT: fprintf (file, " -mcpu=tomcat"); break;
@@ -4391,6 +4606,12 @@ frv_elf_print_private_bfd_data (abfd, ptr)
#define elf_backend_want_plt_sym 0
#define elf_backend_plt_header_size 0
+#define elf_backend_can_make_relative_eh_frame \
+ frv_elf_use_relative_eh_frame
+#define elf_backend_can_make_lsda_relative_eh_frame \
+ frv_elf_use_relative_eh_frame
+#define elf_backend_encode_eh_address frv_elf_encode_eh_address
+
#define elf_backend_may_use_rel_p 1
#define elf_backend_may_use_rela_p 1
/* We use REL for dynamic relocations only. */
diff --git a/bfd/elf32-gen.c b/bfd/elf32-gen.c
index b1ad744..f2edf69 100644
--- a/bfd/elf32-gen.c
+++ b/bfd/elf32-gen.c
@@ -1,5 +1,5 @@
/* Generic support for 32-bit ELF
- Copyright 1993, 1995, 1998, 1999, 2001, 2002
+ Copyright 1993, 1995, 1998, 1999, 2001, 2002, 2004
Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@@ -88,7 +88,7 @@ elf32_generic_link_add_symbols (abfd, info)
return FALSE;
}
- return bfd_elf32_bfd_link_add_symbols (abfd, info);
+ return bfd_elf_link_add_symbols (abfd, info);
}
#define TARGET_LITTLE_SYM bfd_elf32_little_generic_vec
diff --git a/bfd/elf32-h8300.c b/bfd/elf32-h8300.c
index 547adfa..877da8a 100644
--- a/bfd/elf32-h8300.c
+++ b/bfd/elf32-h8300.c
@@ -439,28 +439,12 @@ elf32_h8_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
}
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;
- }
+ bfd_boolean unresolved_reloc, warned;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned);
}
r = elf32_h8_final_link_relocate (r_type, input_bfd, output_bfd,
@@ -1574,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 cf6c630..54dbb9a 100644
--- a/bfd/elf32-hppa.c
+++ b/bfd/elf32-hppa.c
@@ -1,6 +1,6 @@
/* BFD back-end for HP PA-RISC ELF files.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1999, 2000, 2001,
- 2002, 2003 Free Software Foundation, Inc.
+ 2002, 2003, 2004 Free Software Foundation, Inc.
Original code by
Center for Software Science
@@ -1147,12 +1147,13 @@ elf32_hppa_check_relocs (bfd *abfd,
}
break;
- case R_PARISC_SEGBASE: /* Used to set segment base. */
+ case R_PARISC_SEGBASE: /* Used to set segment base. */
case R_PARISC_SEGREL32: /* Relative reloc, used for unwind. */
case R_PARISC_PCREL14F: /* PC relative load/store. */
case R_PARISC_PCREL14R:
case R_PARISC_PCREL17R: /* External branches. */
case R_PARISC_PCREL21L: /* As above, and for load/store too. */
+ case R_PARISC_PCREL32:
/* We don't need to propagate the relocation if linking a
shared object since these are section relative. */
continue;
@@ -1198,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;
@@ -1620,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
@@ -1802,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.
@@ -1880,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;
}
@@ -1951,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;
}
@@ -2240,7 +2228,7 @@ elf32_hppa_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
communicate the LTP value of a load module to the dynamic
linker. */
#define add_dynamic_entry(TAG, VAL) \
- bfd_elf32_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
if (!add_dynamic_entry (DT_PLTGOT, 0))
return FALSE;
@@ -2792,8 +2780,7 @@ elf32_hppa_size_stubs
}
else if (hash->elf.root.type == bfd_link_hash_undefined)
{
- if (! (info->shared
- && info->unresolved_syms_in_objects == RM_IGNORE
+ if (! (info->unresolved_syms_in_objects == RM_IGNORE
&& (ELF_ST_VISIBILITY (hash->elf.other)
== STV_DEFAULT)
&& hash->elf.type != STT_PARISC_MILLI))
@@ -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
@@ -3145,6 +3132,7 @@ final_link_relocate (asection *input_section,
case R_PARISC_PCREL17R:
case R_PARISC_PCREL14R:
case R_PARISC_PCREL14F:
+ case R_PARISC_PCREL32:
/* Make it a pc relative offset. */
value -= location;
addend -= 8;
@@ -3238,6 +3226,7 @@ final_link_relocate (asection *input_section,
case R_PARISC_DIR17F:
case R_PARISC_PCREL17C:
case R_PARISC_PCREL14F:
+ case R_PARISC_PCREL32:
case R_PARISC_DPREL14F:
case R_PARISC_PLABEL32:
case R_PARISC_DLTIND14F:
@@ -3430,26 +3419,25 @@ elf32_hppa_relocate_section (bfd *output_bfd,
{
struct elf_link_hash_entry *hh;
bfd_boolean unresolved_reloc;
+ struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
- RELOC_FOR_GLOBAL_SYMBOL (hh, elf_sym_hashes (input_bfd), r_symndx, symtab_hdr,
- relocation, sym_sec, unresolved_reloc, info,
- warned_undef);
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ hh, sym_sec, relocation,
+ unresolved_reloc, warned_undef);
if (relocation == 0
&& hh->root.type != bfd_link_hash_defined
&& hh->root.type != bfd_link_hash_defweak
&& hh->root.type != bfd_link_hash_undefweak)
{
- if (!info->executable
- && info->unresolved_syms_in_objects == RM_IGNORE
+ if (info->unresolved_syms_in_objects == RM_IGNORE
&& ELF_ST_VISIBILITY (hh->other) == STV_DEFAULT
&& hh->type == STT_PARISC_MILLI)
{
if (! info->callbacks->undefined_symbol
(info, hh->root.root.string, input_bfd,
- input_section, rel->r_offset,
- ((info->shared && info->unresolved_syms_in_shared_libs == RM_GENERATE_ERROR)
- || (!info->shared && info->unresolved_syms_in_objects == RM_GENERATE_ERROR))))
+ input_section, rel->r_offset, FALSE))
return FALSE;
warned_undef = TRUE;
}
@@ -3478,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
@@ -3570,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-i370.c b/bfd/elf32-i370.c
index 80c45f6..f782925 100644
--- a/bfd/elf32-i370.c
+++ b/bfd/elf32-i370.c
@@ -1,5 +1,5 @@
/* i370-specific support for 32-bit ELF
- Copyright 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003
+ Copyright 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Written by Ian Lance Taylor, Cygnus Support.
Hacked by Linas Vepstas for i370 linas@linas.org
@@ -791,7 +791,7 @@ i370_elf_size_dynamic_sections (output_bfd, info)
the .dynamic section. The DT_DEBUG entry is filled in by the
dynamic linker and used by the debugger. */
#define add_dynamic_entry(TAG, VAL) \
- bfd_elf32_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
if (!info->shared)
{
@@ -1246,19 +1246,21 @@ i370_elf_relocate_section (output_bfd, info, input_bfd, input_section,
}
else if (h->root.type == bfd_link_hash_undefweak)
relocation = 0;
- else if (info->shared
+ else if (info->unresolved_syms_in_objects == RM_IGNORE
&& ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
relocation = 0;
else
{
- (*info->callbacks->undefined_symbol) (info,
- h->root.root.string,
- input_bfd,
- input_section,
- rel->r_offset,
- TRUE);
- ret = FALSE;
- continue;
+ if ((*info->callbacks->undefined_symbol)
+ (info, h->root.root.string, input_bfd,
+ input_section, rel->r_offset,
+ (info->unresolved_syms_in_objects == RM_GENERATE_ERROR
+ || ELF_ST_VISIBILITY (h->other))))
+ {
+ ret = FALSE;
+ continue;
+ }
+ relocation = 0;
}
}
@@ -1546,7 +1548,7 @@ static int i370_noop ()
#define elf_backend_add_symbol_hook \
(bfd_boolean (*) \
- PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *, \
+ PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Sym *, \
const char **, flagword *, asection **, bfd_vma *))) i370_noop
#define elf_backend_finish_dynamic_symbol \
(bfd_boolean (*) \
diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c
index 0a3d83f..a53d93e 100644
--- a/bfd/elf32-i386.c
+++ b/bfd/elf32-i386.c
@@ -1,6 +1,6 @@
/* Intel 80386/80486-specific support for 32-bit ELF
- Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
- Free Software Foundation, Inc.
+ Copyright 1993, 1994, 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.
@@ -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;
}
@@ -1895,7 +1884,7 @@ elf_i386_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
the .dynamic section. The DT_DEBUG entry is filled in by the
dynamic linker and used by the debugger. */
#define add_dynamic_entry(TAG, VAL) \
- bfd_elf32_add_dynamic_entry (info, (TAG), (VAL))
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
if (info->executable)
{
@@ -2179,7 +2168,10 @@ elf_i386_relocate_section (bfd *output_bfd,
{
bfd_boolean warned;
- RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx, symtab_hdr, relocation, sec, unresolved_reloc, info, warned);
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned);
}
switch (r_type)
@@ -3256,6 +3248,17 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd,
return TRUE;
}
+/* Return address for Ith PLT stub in section PLT, for relocation REL
+ or (bfd_vma) -1 if it should not be included. */
+
+static bfd_vma
+elf_i386_plt_sym_val (bfd_vma i, const asection *plt,
+ const arelent *rel ATTRIBUTE_UNUSED)
+{
+ return plt->vma + (i + 1) * PLT_ENTRY_SIZE;
+}
+
+
#define TARGET_LITTLE_SYM bfd_elf32_i386_vec
#define TARGET_LITTLE_NAME "elf32-i386"
#define ELF_ARCH bfd_arch_i386
@@ -3293,6 +3296,7 @@ elf_i386_finish_dynamic_sections (bfd *output_bfd,
#define elf_backend_reloc_type_class elf_i386_reloc_type_class
#define elf_backend_relocate_section elf_i386_relocate_section
#define elf_backend_size_dynamic_sections elf_i386_size_dynamic_sections
+#define elf_backend_plt_sym_val elf_i386_plt_sym_val
#include "elf32-target.h"
diff --git a/bfd/elf32-i860.c b/bfd/elf32-i860.c
index 8ab3c92..f156bc5 100644
--- a/bfd/elf32-i860.c
+++ b/bfd/elf32-i860.c
@@ -1,5 +1,5 @@
/* Intel i860 specific support for 32-bit ELF.
- Copyright 1993, 1995, 1999, 2000, 2001, 2002, 2003
+ Copyright 1993, 1995, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Full i860 support contributed by Jason Eckhardt <jle@cygnus.com>.
@@ -1112,34 +1112,12 @@ elf32_i860_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
}
else
{
- h = sym_hashes [r_symndx - symtab_hdr->sh_info];
+ bfd_boolean unresolved_reloc, warned;
- 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;
-
- name = h->root.root.string;
-
- 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;
- }
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned);
}
switch (r_type)
diff --git a/bfd/elf32-ip2k.c b/bfd/elf32-ip2k.c
index 7606e0d..6493be6 100644
--- a/bfd/elf32-ip2k.c
+++ b/bfd/elf32-ip2k.c
@@ -1,5 +1,5 @@
/* Ubicom IP2xxx specific support for 32-bit ELF
- Copyright 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@@ -1535,7 +1535,10 @@ ip2k_elf_relocate_section (output_bfd, info, input_bfd, input_section,
bfd_boolean warned;
bfd_boolean unresolved_reloc;
- RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx, symtab_hdr, relocation, sec, unresolved_reloc, info, warned);
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned);
name = h->root.root.string;
}
diff --git a/bfd/elf32-iq2000.c b/bfd/elf32-iq2000.c
index f85ffac..60dab34 100644
--- a/bfd/elf32-iq2000.c
+++ b/bfd/elf32-iq2000.c
@@ -1,5 +1,5 @@
/* IQ2000-specific support for 32-bit ELF.
- Copyright (C) 2003 Free Software Foundation, Inc.
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@@ -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;
@@ -621,9 +621,10 @@ iq2000_elf_relocate_section (output_bfd, info, input_bfd, input_section,
bfd_boolean unresolved_reloc;
bfd_boolean warned;
- RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx,
- symtab_hdr, relocation,
- sec, unresolved_reloc, info, warned);
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned);
name = h->root.root.string;
}
diff --git a/bfd/elf32-m32r.c b/bfd/elf32-m32r.c
index 3f5fbca..21d37b1 100644
--- a/bfd/elf32-m32r.c
+++ b/bfd/elf32-m32r.c
@@ -51,7 +51,7 @@ bfd_boolean _bfd_m32r_elf_section_from_bfd_section
void _bfd_m32r_elf_symbol_processing
PARAMS ((bfd *, asymbol *));
static bfd_boolean m32r_elf_add_symbol_hook
- PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,
+ PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Sym *,
const char **, flagword *, asection **, bfd_vma *));
static bfd_boolean m32r_elf_relocate_section
PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
@@ -1391,7 +1391,7 @@ static bfd_boolean
m32r_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
bfd *abfd;
struct bfd_link_info *info;
- const Elf_Internal_Sym *sym;
+ Elf_Internal_Sym *sym;
const char **namep;
flagword *flagsp ATTRIBUTE_UNUSED;
asection **secp;
@@ -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;
}
@@ -2442,7 +2431,7 @@ printf("m32r_elf_size_dynamic_sections()\n");
the .dynamic section. The DT_DEBUG entry is filled in by the
dynamic linker and used by the debugger. */
#define add_dynamic_entry(TAG, VAL) \
- bfd_elf32_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
if (! info->shared)
{
@@ -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
@@ -2773,8 +2763,7 @@ m32r_elf_relocate_section (output_bfd, info, input_bfd, input_section,
}
else if (h->root.type == bfd_link_hash_undefweak)
relocation = 0;
- else if (info->shared
- && (!info->symbolic)
+ else if (info->unresolved_syms_in_objects == RM_IGNORE
&& ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
relocation = 0;
else
@@ -2782,7 +2771,7 @@ m32r_elf_relocate_section (output_bfd, info, input_bfd, input_section,
if (! ((*info->callbacks->undefined_symbol)
(info, h->root.root.string, input_bfd,
input_section, offset,
- (!info->shared
+ (info->unresolved_syms_in_objects == RM_GENERATE_ERROR
|| ELF_ST_VISIBILITY (h->other)))))
return FALSE;
relocation = 0;
@@ -2846,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
@@ -4657,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 709b8f4..2a139a4 100644
--- a/bfd/elf32-m68hc1x.c
+++ b/bfd/elf32-m68hc1x.c
@@ -1,5 +1,6 @@
/* Motorola 68HC11/HC12-specific support for 32-bit ELF
- Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
Contributed by Stephane Carrez (stcarrez@nerim.fr)
This file is part of BFD, the Binary File Descriptor library.
@@ -47,16 +48,6 @@ static void m68hc11_elf_set_symbol (bfd* abfd, struct bfd_link_info *info,
static bfd_boolean m68hc11_elf_export_one_stub
(struct bfd_hash_entry *gen_entry, void *in_arg);
-static bfd_boolean m68hc11_get_relocation_value
- (bfd* abfd,
- struct bfd_link_info* info,
- asection **local_sections,
- Elf_Internal_Sym* local_syms,
- Elf_Internal_Rela* rel,
- const char** name,
- bfd_vma* relocation,
- bfd_boolean* is_far);
-
static void scan_sections_for_abi (bfd*, asection*, PTR);
struct m68hc11_scan_param
@@ -190,7 +181,7 @@ m68hc12_add_stub (const char *stub_name, asection *section,
bfd_boolean
elf32_m68hc11_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
- const Elf_Internal_Sym *sym,
+ Elf_Internal_Sym *sym,
const char **namep ATTRIBUTE_UNUSED,
flagword *flagsp ATTRIBUTE_UNUSED,
asection **secp ATTRIBUTE_UNUSED,
@@ -902,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;
}
@@ -919,7 +910,8 @@ elf32_m68hc11_check_relocs (bfd *abfd, struct bfd_link_info *info,
}
static bfd_boolean
-m68hc11_get_relocation_value (bfd *abfd, struct bfd_link_info *info,
+m68hc11_get_relocation_value (bfd *input_bfd, struct bfd_link_info *info,
+ asection *input_section,
asection **local_sections,
Elf_Internal_Sym *local_syms,
Elf_Internal_Rela *rel,
@@ -934,8 +926,8 @@ m68hc11_get_relocation_value (bfd *abfd, struct bfd_link_info *info,
Elf_Internal_Sym *sym;
const char* stub_name = 0;
- symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
- sym_hashes = elf_sym_hashes (abfd);
+ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
+ sym_hashes = elf_sym_hashes (input_bfd);
r_symndx = ELF32_R_SYM (rel->r_info);
@@ -953,33 +945,17 @@ m68hc11_get_relocation_value (bfd *abfd, struct bfd_link_info *info,
*is_far = (sym && (sym->st_other & STO_M68HC12_FAR));
if (*is_far)
stub_name = (bfd_elf_string_from_elf_section
- (abfd, symtab_hdr->sh_link,
+ (input_bfd, symtab_hdr->sh_link,
sym->st_name));
}
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, abfd,
- sec, rel->r_offset, TRUE)))
- return FALSE;
- *relocation = 0;
- }
+ bfd_boolean unresolved_reloc, warned;
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, *relocation, unresolved_reloc, warned);
+
*is_far = (h && (h->other & STO_M68HC12_FAR));
stub_name = h->root.root.string;
}
@@ -989,7 +965,7 @@ m68hc11_get_relocation_value (bfd *abfd, struct bfd_link_info *info,
else
{
*name = (bfd_elf_string_from_elf_section
- (abfd, symtab_hdr->sh_link, sym->st_name));
+ (input_bfd, symtab_hdr->sh_link, sym->st_name));
if (*name == NULL || **name == '\0')
*name = bfd_section_name (input_bfd, sec);
}
@@ -1082,8 +1058,8 @@ elf32_m68hc11_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
(*ebd->elf_info_to_howto_rel) (input_bfd, &arel, rel);
howto = arel.howto;
- m68hc11_get_relocation_value (input_bfd, info,
- local_sections, local_syms,
+ m68hc11_get_relocation_value (input_bfd, info, input_section,
+ local_sections, local_syms,
rel, &name, &relocation, &is_far);
/* Do the memory bank mapping. */
diff --git a/bfd/elf32-m68hc1x.h b/bfd/elf32-m68hc1x.h
index 5964023..f6b2001 100644
--- a/bfd/elf32-m68hc1x.h
+++ b/bfd/elf32-m68hc1x.h
@@ -1,5 +1,5 @@
/* Motorola 68HC11/68HC12-specific support for 32-bit ELF
- Copyright 2003 Free Software Foundation, Inc.
+ Copyright 2003, 2004 Free Software Foundation, Inc.
Contributed by Stephane Carrez (stcarrez@nerim.fr)
This file is part of BFD, the Binary File Descriptor library.
@@ -178,7 +178,7 @@ bfd_boolean elf32_m68hc11_relocate_section
bfd_boolean elf32_m68hc11_add_symbol_hook
(bfd *abfd, struct bfd_link_info *info,
- const Elf_Internal_Sym *sym, const char **namep,
+ Elf_Internal_Sym *sym, const char **namep,
flagword *flagsp, asection **secp,
bfd_vma *valp);
diff --git a/bfd/elf32-m68k.c b/bfd/elf32-m68k.c
index 1c7fed9..39832be 100644
--- a/bfd/elf32-m68k.c
+++ b/bfd/elf32-m68k.c
@@ -1,6 +1,6 @@
/* Motorola 68k series support for 32-bit ELF
- Copyright 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
- Free Software Foundation, Inc.
+ Copyright 1993, 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.
@@ -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
@@ -1247,7 +1236,7 @@ elf_m68k_size_dynamic_sections (output_bfd, info)
the .dynamic section. The DT_DEBUG entry is filled in by the
dynamic linker and used by the debugger. */
#define add_dynamic_entry(TAG, VAL) \
- bfd_elf32_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
if (!info->shared)
{
@@ -1410,7 +1399,10 @@ elf_m68k_relocate_section (output_bfd, info, input_bfd, input_section,
{
bfd_boolean warned;
- RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx, symtab_hdr, relocation, sec, unresolved_reloc, info, warned);
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned);
}
switch (r_type)
@@ -2239,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 0fc9768..e6aa666 100644
--- a/bfd/elf32-mcore.c
+++ b/bfd/elf32-mcore.c
@@ -1,5 +1,5 @@
/* Motorola MCore specific support for 32-bit ELF
- Copyright 1994, 1995, 1999, 2000, 2001, 2002, 2003
+ Copyright 1994, 1995, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@@ -472,30 +472,12 @@ mcore_elf_relocate_section (output_bfd, info, input_bfd, input_section,
}
else
{
- h = sym_hashes [r_symndx - symtab_hdr->sh_info];
- 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->shared
- && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
- relocation = 0;
- else
- {
- if (! ((*info->callbacks->undefined_symbol)
- (info, h->root.root.string, input_bfd,
- input_section, rel->r_offset, TRUE)))
- return FALSE;
+ bfd_boolean unresolved_reloc, warned;
- ret = FALSE;
- continue;
- }
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned);
}
switch (r_type)
@@ -665,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-mips.c b/bfd/elf32-mips.c
index a0480f0..63f1062 100644
--- a/bfd/elf32-mips.c
+++ b/bfd/elf32-mips.c
@@ -599,39 +599,6 @@ static reloc_howto_type elf_mips16_gprel_howto =
0x07ff001f, /* dst_mask */
FALSE); /* pcrel_offset */
-/* GNU extensions for embedded-pic. */
-/* High 16 bits of symbol value, pc-relative. */
-static reloc_howto_type elf_mips_gnu_rel_hi16 =
- HOWTO (R_MIPS_GNU_REL_HI16, /* type */
- 16, /* rightshift */
- 2, /* size (0 = byte, 1 = short, 2 = long) */
- 16, /* bitsize */
- TRUE, /* pc_relative */
- 0, /* bitpos */
- complain_overflow_dont, /* complain_on_overflow */
- _bfd_mips_elf_hi16_reloc, /* special_function */
- "R_MIPS_GNU_REL_HI16", /* name */
- TRUE, /* partial_inplace */
- 0xffff, /* src_mask */
- 0xffff, /* dst_mask */
- TRUE); /* pcrel_offset */
-
-/* Low 16 bits of symbol value, pc-relative. */
-static reloc_howto_type elf_mips_gnu_rel_lo16 =
- HOWTO (R_MIPS_GNU_REL_LO16, /* type */
- 0, /* rightshift */
- 2, /* size (0 = byte, 1 = short, 2 = long) */
- 16, /* bitsize */
- TRUE, /* pc_relative */
- 0, /* bitpos */
- complain_overflow_dont, /* complain_on_overflow */
- _bfd_mips_elf_lo16_reloc, /* special_function */
- "R_MIPS_GNU_REL_LO16", /* name */
- TRUE, /* partial_inplace */
- 0xffff, /* src_mask */
- 0xffff, /* dst_mask */
- TRUE); /* pcrel_offset */
-
/* 16 bit offset for pc-relative branches. */
static reloc_howto_type elf_mips_gnu_rel16_s2 =
HOWTO (R_MIPS_GNU_REL16_S2, /* type */
@@ -648,38 +615,6 @@ static reloc_howto_type elf_mips_gnu_rel16_s2 =
0xffff, /* dst_mask */
TRUE); /* pcrel_offset */
-/* 64 bit pc-relative. */
-static reloc_howto_type elf_mips_gnu_pcrel64 =
- HOWTO (R_MIPS_PC64, /* type */
- 0, /* rightshift */
- 4, /* size (0 = byte, 1 = short, 2 = long) */
- 64, /* bitsize */
- TRUE, /* pc_relative */
- 0, /* bitpos */
- complain_overflow_signed, /* complain_on_overflow */
- _bfd_mips_elf_generic_reloc, /* special_function */
- "R_MIPS_PC64", /* name */
- TRUE, /* partial_inplace */
- MINUS_ONE, /* src_mask */
- MINUS_ONE, /* dst_mask */
- TRUE); /* pcrel_offset */
-
-/* 32 bit pc-relative. */
-static reloc_howto_type elf_mips_gnu_pcrel32 =
- HOWTO (R_MIPS_PC32, /* type */
- 0, /* rightshift */
- 2, /* size (0 = byte, 1 = short, 2 = long) */
- 32, /* bitsize */
- TRUE, /* pc_relative */
- 0, /* bitpos */
- complain_overflow_signed, /* complain_on_overflow */
- _bfd_mips_elf_generic_reloc, /* special_function */
- "R_MIPS_PC32", /* name */
- TRUE, /* partial_inplace */
- 0xffffffff, /* src_mask */
- 0xffffffff, /* dst_mask */
- TRUE); /* pcrel_offset */
-
/* GNU extension to record C++ vtable hierarchy */
static reloc_howto_type elf_mips_gnu_vtinherit_howto =
HOWTO (R_MIPS_GNU_VTINHERIT, /* type */
@@ -1134,16 +1069,8 @@ bfd_elf32_bfd_reloc_type_lookup (bfd *abfd, bfd_reloc_code_real_type code)
return &elf_mips_gnu_vtinherit_howto;
case BFD_RELOC_VTABLE_ENTRY:
return &elf_mips_gnu_vtentry_howto;
- case BFD_RELOC_PCREL_HI16_S:
- return &elf_mips_gnu_rel_hi16;
- case BFD_RELOC_PCREL_LO16:
- return &elf_mips_gnu_rel_lo16;
case BFD_RELOC_16_PCREL_S2:
return &elf_mips_gnu_rel16_s2;
- case BFD_RELOC_64_PCREL:
- return &elf_mips_gnu_pcrel64;
- case BFD_RELOC_32_PCREL:
- return &elf_mips_gnu_pcrel32;
}
}
@@ -1163,16 +1090,8 @@ mips_elf32_rtype_to_howto (unsigned int r_type,
return &elf_mips_gnu_vtinherit_howto;
case R_MIPS_GNU_VTENTRY:
return &elf_mips_gnu_vtentry_howto;
- case R_MIPS_GNU_REL_HI16:
- return &elf_mips_gnu_rel_hi16;
- case R_MIPS_GNU_REL_LO16:
- return &elf_mips_gnu_rel_lo16;
case R_MIPS_GNU_REL16_S2:
return &elf_mips_gnu_rel16_s2;
- case R_MIPS_PC64:
- return &elf_mips_gnu_pcrel64;
- case R_MIPS_PC32:
- return &elf_mips_gnu_pcrel32;
default:
BFD_ASSERT (r_type < (unsigned int) R_MIPS_max);
return &elf_mips_howto_table_rel[r_type];
@@ -1335,139 +1254,6 @@ elf32_mips_irix_compat (bfd *abfd)
return ict_none;
}
-/* Given a data section and an in-memory embedded reloc section, store
- relocation information into the embedded reloc section which can be
- used at runtime to relocate the data section. This is called by the
- linker when the --embedded-relocs switch is used. This is called
- after the add_symbols entry point has been called for all the
- objects, and before the final_link entry point is called. */
-
-bfd_boolean
-bfd_mips_elf32_create_embedded_relocs (bfd *abfd, struct bfd_link_info *info,
- asection *datasec, asection *relsec,
- char **errmsg)
-{
- Elf_Internal_Shdr *symtab_hdr;
- Elf_Internal_Sym *isymbuf = NULL;
- Elf_Internal_Rela *internal_relocs = NULL;
- Elf_Internal_Rela *irel, *irelend;
- bfd_byte *p;
-
- BFD_ASSERT (! info->relocatable);
-
- *errmsg = NULL;
-
- if (datasec->reloc_count == 0)
- return TRUE;
-
- /* Read this BFD's symbols if we haven't done so already, or get the cached
- copy if it exists. */
- symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
- if (symtab_hdr->sh_info != 0)
- {
- isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
- if (isymbuf == NULL)
- isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr,
- symtab_hdr->sh_info, 0,
- NULL, NULL, NULL);
- if (isymbuf == NULL)
- goto error_return;
- }
-
- /* Get a copy of the native relocations. */
- internal_relocs = _bfd_elf_link_read_relocs (abfd, datasec, NULL, NULL,
- info->keep_memory);
- if (internal_relocs == NULL)
- goto error_return;
-
- relsec->contents = bfd_alloc (abfd, datasec->reloc_count * 12);
- if (relsec->contents == NULL)
- goto error_return;
-
- p = relsec->contents;
-
- irelend = internal_relocs + datasec->reloc_count;
-
- for (irel = internal_relocs; irel < irelend; irel++, p += 12)
- {
- asection *targetsec;
-
- /* We are going to write a four byte longword into the runtime
- reloc section. The longword will be the address in the data
- section which must be relocated. It is followed by the name
- of the target section NUL-padded or truncated to 8
- characters. */
-
- /* We can only relocate absolute longword relocs at run time. */
- if ((ELF32_R_TYPE (irel->r_info) != (int) R_MIPS_32) &&
- (ELF32_R_TYPE (irel->r_info) != (int) R_MIPS_64))
- {
- *errmsg = _("unsupported reloc type");
- bfd_set_error (bfd_error_bad_value);
- goto error_return;
- }
- /* Get the target section referred to by the reloc. */
- if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
- {
- Elf_Internal_Sym *isym;
-
- /* A local symbol. */
- isym = isymbuf + ELF32_R_SYM (irel->r_info);
- targetsec = bfd_section_from_elf_index (abfd, isym->st_shndx);
- }
- else
- {
- unsigned long indx;
- struct elf_link_hash_entry *h;
-
- /* An external symbol. */
- indx = ELF32_R_SYM (irel->r_info);
- h = elf_sym_hashes (abfd)[indx];
- targetsec = NULL;
- /*
- For some reason, in certain programs, the symbol will
- not be in the hash table. It seems to happen when you
- declare a static table of pointers to const external structures.
- In this case, the relocs are relative to data, not
- text, so just treating it like an undefined link
- should be sufficient. */
- BFD_ASSERT(h != NULL);
- if (h->root.type == bfd_link_hash_defined
- || h->root.type == bfd_link_hash_defweak)
- targetsec = h->root.u.def.section;
- }
-
-
- /*
- Set the low bit of the relocation offset if it's a MIPS64 reloc.
- Relocations will always be on (at least) 32-bit boundaries. */
-
- bfd_put_32 (abfd, ((irel->r_offset + datasec->output_offset) +
- ((ELF32_R_TYPE (irel->r_info) == (int) R_MIPS_64) ? 1 : 0)),
- p);
- memset (p + 4, 0, 8);
- if (targetsec != NULL)
- strncpy (p + 4, targetsec->output_section->name, 8);
- }
-
- if (internal_relocs != NULL
- && elf_section_data (datasec)->relocs != internal_relocs)
- free (internal_relocs);
- if (isymbuf != NULL
- && symtab_hdr->contents != (unsigned char *) isymbuf)
- free (isymbuf);
- return TRUE;
-
- error_return:
- if (internal_relocs != NULL
- && elf_section_data (datasec)->relocs != internal_relocs)
- free (internal_relocs);
- if (isymbuf != NULL
- && symtab_hdr->contents != (unsigned char *) isymbuf)
- free (isymbuf);
- return FALSE;
-}
-
/* ECOFF swapping routines. These are used when dealing with the
.mdebug section, which is in the ECOFF debugging format. */
static const struct ecoff_debug_swap mips_elf32_ecoff_debug_swap = {
diff --git a/bfd/elf32-msp430.c b/bfd/elf32-msp430.c
index 306a798..dfe33bd 100644
--- a/bfd/elf32-msp430.c
+++ b/bfd/elf32-msp430.c
@@ -1,5 +1,5 @@
/* MSP430-specific support for 32-bit ELF
- Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+ Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Dmitry Diky <diwil@mail.ru>
This file is part of BFD, the Binary File Descriptor library.
@@ -457,33 +457,12 @@ elf32_msp430_relocate_section (output_bfd, info, input_bfd, input_section,
}
else
{
- h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ bfd_boolean unresolved_reloc, warned;
- 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;
-
- name = h->root.root.string;
-
- 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;
- }
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned);
}
r = msp430_final_link_relocate (howto, input_bfd, input_section,
diff --git a/bfd/elf32-openrisc.c b/bfd/elf32-openrisc.c
index 62f86d4..af1c222 100644
--- a/bfd/elf32-openrisc.c
+++ b/bfd/elf32-openrisc.c
@@ -1,5 +1,5 @@
/* OpenRISC-specific support for 32-bit ELF.
- Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Johan Rydberg, jrydberg@opencores.org
This file is part of BFD, the Binary File Descriptor library.
@@ -383,33 +383,12 @@ openrisc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
}
else
{
- h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ bfd_boolean unresolved_reloc, warned;
- 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;
-
- name = h->root.root.string;
-
- 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;
- }
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned);
}
r = openrisc_final_link_relocate (howto, input_bfd, input_section,
@@ -556,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 6849da8..bdd3450 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;
}
@@ -3470,7 +3459,7 @@ ppc_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
the .dynamic section. The DT_DEBUG entry is filled in by the
dynamic linker and used by the debugger. */
#define add_dynamic_entry(TAG, VAL) \
- bfd_elf32_add_dynamic_entry (info, (TAG), (VAL))
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
if (info->executable)
{
@@ -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;
@@ -4376,7 +4365,7 @@ ppc_elf_tls_optimize (bfd *obfd ATTRIBUTE_UNUSED,
static bfd_boolean
ppc_elf_add_symbol_hook (bfd *abfd,
struct bfd_link_info *info,
- const Elf_Internal_Sym *sym,
+ Elf_Internal_Sym *sym,
const char **namep ATTRIBUTE_UNUSED,
flagword *flagsp ATTRIBUTE_UNUSED,
asection **secp,
@@ -4701,10 +4690,10 @@ ppc_elf_relocate_section (bfd *output_bfd,
}
else
{
- RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx,
- symtab_hdr, relocation, sec,
- unresolved_reloc, info,
- warned);
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned);
sym_name = h->root.root.string;
}
@@ -6139,6 +6128,17 @@ ppc_elf_final_write_processing (bfd *abfd, bfd_boolean linker ATTRIBUTE_UNUSED)
apuinfo_list_finish ();
}
+/* Return address for Ith PLT stub in section PLT, for relocation REL
+ or (bfd_vma) -1 if it should not be included. */
+
+static bfd_vma
+ppc_elf_plt_sym_val (bfd_vma i ATTRIBUTE_UNUSED,
+ const asection *plt ATTRIBUTE_UNUSED,
+ const arelent *rel)
+{
+ return rel->address;
+}
+
/* Add extra PPC sections -- Note, for now, make .sbss2 and
.PPC.EMB.sbss0 a normal section, and not a bss section so
that the linker doesn't crater when trying to make more than
@@ -6216,5 +6216,6 @@ static struct bfd_elf_special_section const ppc_elf_special_sections[]=
#define elf_backend_final_write_processing ppc_elf_final_write_processing
#define elf_backend_write_section ppc_elf_write_section
#define elf_backend_special_sections ppc_elf_special_sections
+#define elf_backend_plt_sym_val ppc_elf_plt_sym_val
#include "elf32-target.h"
diff --git a/bfd/elf32-s390.c b/bfd/elf32-s390.c
index 07ba23c..fb8758b 100644
--- a/bfd/elf32-s390.c
+++ b/bfd/elf32-s390.c
@@ -1,5 +1,5 @@
/* IBM S/390-specific support for 32-bit ELF
- Copyright 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Carl B. Pedersen and Martin Schwidefsky.
This file is part of BFD, the Binary File Descriptor library.
@@ -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;
}
@@ -1884,9 +1873,7 @@ allocate_dynrelocs (h, inf)
if (info->shared)
{
- if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0
- && ((h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0
- || info->symbolic))
+ if (SYMBOL_REFERENCES_LOCAL (info, h))
{
struct elf_s390_dyn_relocs **pp;
@@ -1925,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;
}
@@ -2159,7 +2146,7 @@ elf_s390_size_dynamic_sections (output_bfd, info)
the .dynamic section. The DT_DEBUG entry is filled in by the
dynamic linker and used by the debugger. */
#define add_dynamic_entry(TAG, VAL) \
- bfd_elf32_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
if (info->executable)
{
@@ -2324,10 +2311,10 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
{
bfd_boolean warned ATTRIBUTE_UNUSED;
- RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx,
- symtab_hdr, relocation, sec,
- unresolved_reloc, info,
- warned);
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned);
}
switch (r_type)
@@ -2562,10 +2549,7 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
&& r_type != R_390_PC32DBL
&& r_type != R_390_PC32)
|| (h != NULL
- && h->dynindx != -1
- && (! info->symbolic
- || (h->elf_link_hash_flags
- & ELF_LINK_HASH_DEF_REGULAR) == 0))))
+ && !SYMBOL_REFERENCES_LOCAL (info, h))))
|| (ELIMINATE_COPY_RELOCS
&& !info->shared
&& h != NULL
@@ -3473,6 +3457,17 @@ elf_s390_grok_prstatus (abfd, note)
raw_size, note->descpos + offset);
}
+/* Return address for Ith PLT stub in section PLT, for relocation REL
+ or (bfd_vma) -1 if it should not be included. */
+
+static bfd_vma
+elf_s390_plt_sym_val (bfd_vma i, const asection *plt,
+ const arelent *rel ATTRIBUTE_UNUSED)
+{
+ return plt->vma + PLT_FIRST_ENTRY_SIZE + i * PLT_ENTRY_SIZE;
+}
+
+
#define TARGET_BIG_SYM bfd_elf32_s390_vec
#define TARGET_BIG_NAME "elf32-s390"
#define ELF_ARCH bfd_arch_s390
@@ -3507,6 +3502,7 @@ elf_s390_grok_prstatus (abfd, note)
#define elf_backend_size_dynamic_sections elf_s390_size_dynamic_sections
#define elf_backend_reloc_type_class elf_s390_reloc_type_class
#define elf_backend_grok_prstatus elf_s390_grok_prstatus
+#define elf_backend_plt_sym_val elf_s390_plt_sym_val
#define bfd_elf32_mkobject elf_s390_mkobject
#define elf_backend_object_p elf_s390_object_p
diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c
index c8a091d..d69457f 100644
--- a/bfd/elf32-sh.c
+++ b/bfd/elf32-sh.c
@@ -1,5 +1,5 @@
/* Renesas / SuperH SH specific support for 32-bit ELF
- Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Contributed by Ian Lance Taylor, Cygnus Support.
@@ -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;
}
@@ -4620,7 +4609,7 @@ sh_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
the .dynamic section. The DT_DEBUG entry is filled in by the
dynamic linker and used by the debugger. */
#define add_dynamic_entry(TAG, VAL) \
- bfd_elf32_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
if (info->executable)
{
@@ -4938,8 +4927,7 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
}
else if (h->root.type == bfd_link_hash_undefweak)
relocation = 0;
- else if (! info->executable
- && info->unresolved_syms_in_objects == RM_IGNORE
+ else if (info->unresolved_syms_in_objects == RM_IGNORE
&& ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
relocation = 0;
else
@@ -4947,8 +4935,7 @@ sh_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
if (! info->callbacks->undefined_symbol
(info, h->root.root.string, input_bfd,
input_section, rel->r_offset,
- ((info->shared && info->unresolved_syms_in_shared_libs == RM_GENERATE_ERROR)
- || (!info->shared && info->unresolved_syms_in_objects == RM_GENERATE_ERROR)
+ (info->unresolved_syms_in_objects == RM_GENERATE_ERROR
|| ELF_ST_VISIBILITY (h->other))))
return FALSE;
relocation = 0;
@@ -6492,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;
@@ -6876,6 +6863,9 @@ sh_elf_set_mach_from_flags (bfd *abfd)
case EF_SH4AL_DSP:
bfd_default_set_arch_mach (abfd, bfd_arch_sh, bfd_mach_sh4al_dsp);
break;
+ case EF_SH4_NOMMU_NOFPU:
+ bfd_default_set_arch_mach (abfd, bfd_arch_sh, bfd_mach_sh4_nommu_nofpu);
+ break;
default:
return FALSE;
}
@@ -7490,6 +7480,17 @@ elf32_shlin_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
return TRUE;
}
+
+/* Return address for Ith PLT stub in section PLT, for relocation REL
+ or (bfd_vma) -1 if it should not be included. */
+
+static bfd_vma
+sh_elf_plt_sym_val (bfd_vma i, const asection *plt,
+ const arelent *rel ATTRIBUTE_UNUSED)
+{
+ return plt->vma + (i + 1) * PLT_ENTRY_SIZE;
+}
+
#define TARGET_BIG_SYM bfd_elf32_sh_vec
#define TARGET_BIG_NAME "elf32-sh"
#define TARGET_LITTLE_SYM bfd_elf32_shl_vec
@@ -7537,6 +7538,7 @@ elf32_shlin_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
#define elf_backend_finish_dynamic_sections \
sh_elf_finish_dynamic_sections
#define elf_backend_reloc_type_class sh_elf_reloc_type_class
+#define elf_backend_plt_sym_val sh_elf_plt_sym_val
#define elf_backend_can_gc_sections 1
#define elf_backend_can_refcount 1
diff --git a/bfd/elf32-sh64.c b/bfd/elf32-sh64.c
index eac444a..62cf2e6 100644
--- a/bfd/elf32-sh64.c
+++ b/bfd/elf32-sh64.c
@@ -1,5 +1,5 @@
/* SuperH SH64-specific support for 32-bit ELF
- Copyright 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@@ -56,7 +56,7 @@ static bfd_boolean shmedia_prepare_reloc
static int sh64_elf_get_symbol_type
(Elf_Internal_Sym *, int);
static bfd_boolean sh64_elf_add_symbol_hook
- (bfd *, struct bfd_link_info *, const Elf_Internal_Sym *, const char **,
+ (bfd *, struct bfd_link_info *, Elf_Internal_Sym *, const char **,
flagword *, asection **, bfd_vma *);
static bfd_boolean sh64_elf_link_output_symbol_hook
(struct bfd_link_info *, const char *, Elf_Internal_Sym *, asection *,
@@ -89,6 +89,7 @@ static void sh64_find_section_for_address
#define elf_backend_final_write_processing sh64_elf_final_write_processing
#define elf_backend_section_from_shdr sh64_backend_section_from_shdr
#define elf_backend_special_sections sh64_elf_special_sections
+#define elf_backend_section_flags sh64_elf_section_flags
#define bfd_elf32_new_section_hook sh64_elf_new_section_hook
@@ -149,7 +150,6 @@ static bfd_boolean
sh64_elf_set_mach_from_flags (bfd *abfd)
{
flagword flags = elf_elfheader (abfd)->e_flags;
- asection *cranges;
switch (flags & EF_SH_MACH_MASK)
{
@@ -164,18 +164,19 @@ sh64_elf_set_mach_from_flags (bfd *abfd)
return FALSE;
}
- /* We also need to set SEC_DEBUGGING on an incoming .cranges section.
- We could have used elf_backend_section_flags if it had given us the
- section name; the bfd_section member in the header argument is not
- set at the point of the call. FIXME: Find out whether that is by
- undocumented design or a bug. */
- cranges = bfd_get_section_by_name (abfd, SH64_CRANGES_SECTION_NAME);
- if (cranges != NULL
- && ! bfd_set_section_flags (abfd, cranges,
- bfd_get_section_flags (abfd, cranges)
- | SEC_DEBUGGING))
+ return TRUE;
+}
+
+static bfd_boolean
+sh64_elf_section_flags (flagword *flags,
+ const Elf_Internal_Shdr *hdr)
+{
+ if (hdr->bfd_section == NULL)
return FALSE;
+ if (strcmp (hdr->bfd_section->name, SH64_CRANGES_SECTION_NAME) == 0)
+ *flags |= SEC_DEBUGGING;
+
return TRUE;
}
@@ -374,7 +375,7 @@ sh64_elf_get_symbol_type (Elf_Internal_Sym *elf_sym, int type)
static bfd_boolean
sh64_elf_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
- const Elf_Internal_Sym *sym, const char **namep,
+ Elf_Internal_Sym *sym, const char **namep,
flagword *flagsp ATTRIBUTE_UNUSED,
asection **secp, bfd_vma *valp)
{
diff --git a/bfd/elf32-sparc.c b/bfd/elf32-sparc.c
index c20e403..3809567 100644
--- a/bfd/elf32-sparc.c
+++ b/bfd/elf32-sparc.c
@@ -1,6 +1,6 @@
/* SPARC-specific support for 32-bit ELF
Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
- 2003 Free Software Foundation, Inc.
+ 2003, 2004 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@@ -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;
}
@@ -2027,7 +2016,7 @@ elf32_sparc_size_dynamic_sections (output_bfd, info)
the .dynamic section. The DT_DEBUG entry is filled in by the
dynamic linker and used by the debugger. */
#define add_dynamic_entry(TAG, VAL) \
- bfd_elf32_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
if (info->executable)
{
@@ -2215,10 +2204,10 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
{
bfd_boolean warned ATTRIBUTE_UNUSED;
- RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx,
- symtab_hdr, relocation, sec,
- unresolved_reloc, info,
- warned);
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned);
}
switch (r_type)
@@ -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
@@ -2334,7 +2323,7 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
if (h == NULL)
break;
- if (h->plt.offset == (bfd_vma) -1)
+ if (h->plt.offset == (bfd_vma) -1 || htab->splt == NULL)
{
/* We didn't make a PLT entry for this symbol. This
happens when statically linking PIC code, or when
@@ -2342,9 +2331,6 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
break;
}
- if (htab->splt == NULL)
- abort ();
-
relocation = (htab->splt->output_section->vma
+ htab->splt->output_offset
+ h->plt.offset);
@@ -2388,6 +2374,9 @@ elf32_sparc_relocate_section (output_bfd, info, input_bfd, input_section,
break;
if ((info->shared
+ && (h == NULL
+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
+ || h->root.type != bfd_link_hash_undefweak)
&& (! howto->pc_relative
|| (h != NULL
&& h->dynindx != -1
@@ -3283,8 +3272,7 @@ elf32_sparc_finish_dynamic_sections (output_bfd, info)
splt->contents + splt->_raw_size - 4);
}
- elf_section_data (splt->output_section)->this_hdr.sh_entsize =
- PLT_ENTRY_SIZE;
+ elf_section_data (splt->output_section)->this_hdr.sh_entsize = 0;
}
/* Set the first entry in the global offset table to the address of
@@ -3444,6 +3432,17 @@ elf32_sparc_reloc_type_class (rela)
return reloc_class_normal;
}
}
+
+/* Return address for Ith PLT stub in section PLT, for relocation REL
+ or (bfd_vma) -1 if it should not be included. */
+
+static bfd_vma
+elf32_sparc_plt_sym_val (bfd_vma i ATTRIBUTE_UNUSED,
+ const asection *plt ATTRIBUTE_UNUSED,
+ const arelent *rel)
+{
+ return rel->address;
+}
#define TARGET_BIG_SYM bfd_elf32_sparc_vec
#define TARGET_BIG_NAME "elf32-sparc"
@@ -3482,6 +3481,7 @@ elf32_sparc_reloc_type_class (rela)
#define elf_backend_gc_sweep_hook elf32_sparc_gc_sweep_hook
#define elf_backend_grok_psinfo elf32_sparc_grok_psinfo
#define elf_backend_reloc_type_class elf32_sparc_reloc_type_class
+#define elf_backend_plt_sym_val elf32_sparc_plt_sym_val
#define elf_backend_can_gc_sections 1
#define elf_backend_can_refcount 1
diff --git a/bfd/elf32-v850.c b/bfd/elf32-v850.c
index 45bb4f6..b9dcf3c 100644
--- a/bfd/elf32-v850.c
+++ b/bfd/elf32-v850.c
@@ -1,5 +1,5 @@
/* V850-specific support for 32-bit ELF
- Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@@ -73,7 +73,7 @@ static bfd_boolean v850_elf_section_from_bfd_section
static void v850_elf_symbol_processing
PARAMS ((bfd *, asymbol *));
static bfd_boolean v850_elf_add_symbol_hook
- PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,
+ PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Sym *,
const char **, flagword *, asection **, bfd_vma *));
static bfd_boolean v850_elf_link_output_symbol_hook
PARAMS ((struct bfd_link_info *, const char *, Elf_Internal_Sym *,
@@ -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;
@@ -1696,43 +1696,12 @@ v850_elf_relocate_section (output_bfd, info, input_bfd, input_section,
}
else
{
- h = sym_hashes[r_symndx - symtab_hdr->sh_info];
+ bfd_boolean unresolved_reloc, warned;
- 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);
-#if 0
- fprintf (stderr, "defined: sec: %s, name: %s, value: %x + %x + %x gives: %x\n",
- sec->name, h->root.root.string, h->root.u.def.value, sec->output_section->vma, sec->output_offset, relocation);
-#endif
- }
- else if (h->root.type == bfd_link_hash_undefweak)
- {
-#if 0
- fprintf (stderr, "undefined: sec: %s, name: %s\n",
- sec->name, h->root.root.string);
-#endif
- relocation = 0;
- }
- else
- {
- if (! ((*info->callbacks->undefined_symbol)
- (info, h->root.root.string, input_bfd,
- input_section, rel->r_offset, TRUE)))
- return FALSE;
-#if 0
- fprintf (stderr, "unknown: name: %s\n", h->root.root.string);
-#endif
- relocation = 0;
- }
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned);
}
/* FIXME: We should use the addend, but the COFF relocations don't. */
@@ -2155,7 +2124,7 @@ static bfd_boolean
v850_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
bfd *abfd;
struct bfd_link_info *info ATTRIBUTE_UNUSED;
- const Elf_Internal_Sym *sym;
+ Elf_Internal_Sym *sym;
const char **namep ATTRIBUTE_UNUSED;
flagword *flagsp ATTRIBUTE_UNUSED;
asection **secp;
diff --git a/bfd/elf32-vax.c b/bfd/elf32-vax.c
index e085e35..8ce4678 100644
--- a/bfd/elf32-vax.c
+++ b/bfd/elf32-vax.c
@@ -1,6 +1,6 @@
/* VAX series support for 32-bit ELF
- Copyright 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
- Free Software Foundation, Inc.
+ Copyright 1993, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003,
+ 2004 Free Software Foundation, Inc.
Contributed by Matt Thomas <matt@3am-software.com>.
This file is part of BFD, the Binary File Descriptor library.
@@ -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;
}
@@ -1297,7 +1297,7 @@ elf_vax_size_dynamic_sections (output_bfd, info)
the .dynamic section. The DT_DEBUG entry is filled in by the
dynamic linker and used by the debugger. */
#define add_dynamic_entry(TAG, VAL) \
- bfd_elf32_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
if (!info->shared)
{
@@ -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;
}
@@ -1489,10 +1489,10 @@ elf_vax_relocate_section (output_bfd, info, input_bfd, input_section,
bfd_boolean unresolved_reloc;
bfd_boolean warned;
- RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx,
- symtab_hdr, relocation, sec,
- unresolved_reloc, info,
- warned);
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned);
if ((h->root.type == bfd_link_hash_defined
|| h->root.type == bfd_link_hash_defweak)
@@ -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 1377ff2..bbf6ee0 100644
--- a/bfd/elf32-xstormy16.c
+++ b/bfd/elf32-xstormy16.c
@@ -1,5 +1,5 @@
/* XSTORMY16-specific support for 32-bit ELF.
- Copyright 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@@ -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;
}
@@ -853,34 +853,12 @@ xstormy16_elf_relocate_section (output_bfd, info, input_bfd, input_section,
}
else
{
- h = sym_hashes [r_symndx - symtab_hdr->sh_info];
+ bfd_boolean unresolved_reloc, warned;
- 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;
-
- name = h->root.root.string;
-
- 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;
- }
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned);
}
switch (ELF32_R_TYPE (rel->r_info))
diff --git a/bfd/elf32-xtensa.c b/bfd/elf32-xtensa.c
index 44450c5..710a1a6 100644
--- a/bfd/elf32-xtensa.c
+++ b/bfd/elf32-xtensa.c
@@ -1,5 +1,5 @@
/* Xtensa-specific support for 32-bit ELF.
- Copyright 2003 Free Software Foundation, Inc.
+ Copyright 2003, 2004 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@@ -497,13 +497,15 @@ xtensa_read_table_entries (abfd, section, table_p, sec_name)
int block_count;
bfd_size_type num_records;
Elf_Internal_Rela *internal_relocs;
+ bfd_vma section_addr;
table_section_name =
xtensa_get_property_section_name (section, sec_name);
table_section = bfd_get_section_by_name (abfd, table_section_name);
free (table_section_name);
if (table_section != NULL)
- table_size = bfd_get_section_size_before_reloc (table_section);
+ table_size = (table_section->_cooked_size
+ ? table_section->_cooked_size : table_section->_raw_size);
if (table_size == 0)
{
@@ -517,10 +519,12 @@ xtensa_read_table_entries (abfd, section, table_p, sec_name)
bfd_malloc (num_records * sizeof (property_table_entry));
block_count = 0;
+ section_addr = section->output_section->vma + section->output_offset;
+
/* If the file has not yet been relocated, process the relocations
and sort out the table entries that apply to the specified section. */
internal_relocs = retrieve_internal_relocs (abfd, table_section, TRUE);
- if (internal_relocs)
+ if (internal_relocs && !table_section->reloc_done)
{
unsigned i;
@@ -539,7 +543,7 @@ xtensa_read_table_entries (abfd, section, table_p, sec_name)
{
bfd_vma sym_off = get_elf_r_symndx_offset (abfd, r_symndx);
blocks[block_count].address =
- (section->vma + sym_off + rel->r_addend
+ (section_addr + sym_off + rel->r_addend
+ bfd_get_32 (abfd, table_data + rel->r_offset));
blocks[block_count].size =
bfd_get_32 (abfd, table_data + rel->r_offset + 4);
@@ -549,16 +553,16 @@ xtensa_read_table_entries (abfd, section, table_p, sec_name)
}
else
{
- /* No relocations. Presumably the file has been relocated
- and the addresses are already in the table. */
+ /* The file has already been relocated and the addresses are
+ already in the table. */
bfd_vma off;
for (off = 0; off < table_size; off += 8)
{
bfd_vma address = bfd_get_32 (abfd, table_data + off);
- if (address >= section->vma
- && address < ( section->vma + section->_raw_size))
+ if (address >= section_addr
+ && address < ( section_addr + section->_raw_size))
{
blocks[block_count].address = address;
blocks[block_count].size =
@@ -619,8 +623,6 @@ elf_xtensa_check_relocs (abfd, info, sec, relocs)
struct elf_link_hash_entry **sym_hashes;
const Elf_Internal_Rela *rel;
const Elf_Internal_Rela *rel_end;
- property_table_entry *lit_table;
- int ltblsize;
if (info->relocatable)
return TRUE;
@@ -628,11 +630,6 @@ elf_xtensa_check_relocs (abfd, info, sec, relocs)
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
sym_hashes = elf_sym_hashes (abfd);
- ltblsize = xtensa_read_table_entries (abfd, sec, &lit_table,
- XTENSA_LIT_SEC_NAME);
- if (ltblsize < 0)
- return FALSE;
-
rel_end = relocs + sec->reloc_count;
for (rel = relocs; rel < rel_end; rel++)
{
@@ -669,11 +666,6 @@ elf_xtensa_check_relocs (abfd, info, sec, relocs)
if ((sec->flags & SEC_ALLOC) != 0)
{
- if ((sec->flags & SEC_READONLY) != 0
- && !elf_xtensa_in_literal_pool (lit_table, ltblsize,
- sec->vma + rel->r_offset))
- h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF;
-
if (h->got.refcount <= 0)
h->got.refcount = 1;
else
@@ -689,11 +681,6 @@ elf_xtensa_check_relocs (abfd, info, sec, relocs)
if ((sec->flags & SEC_ALLOC) != 0)
{
- if ((sec->flags & SEC_READONLY) != 0
- && !elf_xtensa_in_literal_pool (lit_table, ltblsize,
- sec->vma + rel->r_offset))
- h->elf_link_hash_flags |= ELF_LINK_NON_GOT_REF;
-
if (h->plt.refcount <= 0)
{
h->elf_link_hash_flags |= ELF_LINK_HASH_NEEDS_PLT;
@@ -736,14 +723,6 @@ elf_xtensa_check_relocs (abfd, info, sec, relocs)
elf_local_got_refcounts (abfd) = local_got_refcounts;
}
local_got_refcounts[r_symndx] += 1;
-
- /* If the relocation is not inside the GOT, the DF_TEXTREL
- flag needs to be set. */
- if (info->shared
- && (sec->flags & SEC_READONLY) != 0
- && !elf_xtensa_in_literal_pool (lit_table, ltblsize,
- sec->vma + rel->r_offset))
- info->flags |= DF_TEXTREL;
}
break;
@@ -758,14 +737,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;
@@ -774,7 +753,6 @@ elf_xtensa_check_relocs (abfd, info, sec, relocs)
}
}
- free (lit_table);
return TRUE;
}
@@ -1044,7 +1022,6 @@ elf_xtensa_make_sym_local (info, h)
else
{
/* Don't need any dynamic relocations at all. */
- h->elf_link_hash_flags &= ~ELF_LINK_NON_GOT_REF;
h->plt.refcount = 0;
h->got.refcount = 0;
}
@@ -1064,11 +1041,6 @@ elf_xtensa_fix_refcounts (h, arg)
if (! xtensa_elf_dynamic_symbol_p (h, info))
elf_xtensa_make_sym_local (info, h);
- /* If the symbol has a relocation outside the GOT, set the
- DF_TEXTREL flag. */
- if ((h->elf_link_hash_flags & ELF_LINK_NON_GOT_REF) != 0)
- info->flags |= DF_TEXTREL;
-
return TRUE;
}
@@ -1366,7 +1338,7 @@ elf_xtensa_size_dynamic_sections (output_bfd, info)
the .dynamic section. The DT_DEBUG entry is filled in by the
dynamic linker and used by the debugger. */
#define add_dynamic_entry(TAG, VAL) \
- bfd_elf32_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
if (! info->shared)
{
@@ -1391,12 +1363,6 @@ elf_xtensa_size_dynamic_sections (output_bfd, info)
return FALSE;
}
- if ((info->flags & DF_TEXTREL) != 0)
- {
- if (!add_dynamic_entry (DT_TEXTREL, 0))
- return FALSE;
- }
-
if (!add_dynamic_entry (DT_XTENSA_GOT_LOC_OFF, 0)
|| !add_dynamic_entry (DT_XTENSA_GOT_LOC_SZ, 0))
return FALSE;
@@ -1851,6 +1817,8 @@ elf_xtensa_relocate_section (output_bfd, info, input_bfd,
struct elf_link_hash_entry **sym_hashes;
asection *srelgot, *srelplt;
bfd *dynobj;
+ property_table_entry *lit_table = 0;
+ int ltblsize = 0;
char *error_message = NULL;
if (xtensa_default_isa == NULL)
@@ -1868,6 +1836,14 @@ elf_xtensa_relocate_section (output_bfd, info, input_bfd,
srelplt = bfd_get_section_by_name (dynobj, ".rela.plt");
}
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ ltblsize = xtensa_read_table_entries (input_bfd, input_section,
+ &lit_table, XTENSA_LIT_SEC_NAME);
+ if (ltblsize < 0)
+ return FALSE;
+ }
+
rel = relocs;
relend = relocs + input_section->reloc_count;
for (; rel < relend; rel++)
@@ -1993,10 +1969,10 @@ elf_xtensa_relocate_section (output_bfd, info, input_bfd,
}
else
{
- RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx,
- symtab_hdr, relocation, sec,
- unresolved_reloc, info,
- warned);
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned);
if (relocation == 0
&& !unresolved_reloc
@@ -2068,6 +2044,20 @@ elf_xtensa_relocate_section (output_bfd, info, input_bfd,
outrel.r_offset += (input_section->output_section->vma
+ input_section->output_offset);
+ /* Complain if the relocation is in a read-only section
+ and not in a literal pool. */
+ if ((input_section->flags & SEC_READONLY) != 0
+ && !elf_xtensa_in_literal_pool (lit_table, ltblsize,
+ outrel.r_offset))
+ {
+ error_message =
+ _("dynamic relocation in read-only section");
+ if (!((*info->callbacks->reloc_dangerous)
+ (info, error_message, input_bfd, input_section,
+ rel->r_offset)))
+ return FALSE;
+ }
+
if (dynamic_symbol)
{
outrel.r_addend = rel->r_addend;
@@ -2155,6 +2145,11 @@ elf_xtensa_relocate_section (output_bfd, info, input_bfd,
}
}
+ if (lit_table)
+ free (lit_table);
+
+ input_section->reloc_done = TRUE;
+
return TRUE;
}
@@ -2730,7 +2725,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
@@ -3441,7 +3436,7 @@ struct value_map_hash_table_struct
static bfd_boolean is_same_value
- PARAMS ((const literal_value *, const literal_value *));
+ PARAMS ((const literal_value *, const literal_value *, bfd_boolean));
static value_map_hash_table *value_map_hash_table_init
PARAMS ((void));
static unsigned hash_literal_value
@@ -3449,16 +3444,20 @@ static unsigned hash_literal_value
static unsigned hash_bfd_vma
PARAMS ((bfd_vma));
static value_map *get_cached_value
- PARAMS ((value_map_hash_table *, const literal_value *));
+ PARAMS ((value_map_hash_table *, const literal_value *, bfd_boolean));
static value_map *add_value_map
- PARAMS ((value_map_hash_table *, const literal_value *, const r_reloc *));
+ PARAMS ((value_map_hash_table *, const literal_value *, const r_reloc *,
+ bfd_boolean));
static bfd_boolean
-is_same_value (src1, src2)
+is_same_value (src1, src2, final_static_link)
const literal_value *src1;
const literal_value *src2;
+ bfd_boolean final_static_link;
{
+ struct elf_link_hash_entry *h1, *h2;
+
if (r_reloc_is_const (&src1->r_rel) != r_reloc_is_const (&src2->r_rel))
return FALSE;
@@ -3476,8 +3475,14 @@ is_same_value (src1, src2)
if (src1->value != src2->value)
return FALSE;
- /* Now check for the same section and the same elf_hash. */
- if (r_reloc_is_defined (&src1->r_rel))
+ /* Now check for the same section (if defined) or the same elf_hash
+ (if undefined or weak). */
+ h1 = r_reloc_get_hash_entry (&src1->r_rel);
+ h2 = r_reloc_get_hash_entry (&src2->r_rel);
+ if (r_reloc_is_defined (&src1->r_rel)
+ && (final_static_link
+ || ((!h1 || h1->root.type != bfd_link_hash_defweak)
+ && (!h2 || h2->root.type != bfd_link_hash_defweak))))
{
if (r_reloc_get_section (&src1->r_rel)
!= r_reloc_get_section (&src2->r_rel))
@@ -3485,11 +3490,8 @@ is_same_value (src1, src2)
}
else
{
- if (r_reloc_get_hash_entry (&src1->r_rel)
- != r_reloc_get_hash_entry (&src2->r_rel))
- return FALSE;
-
- if (r_reloc_get_hash_entry (&src1->r_rel) == 0)
+ /* Require that the hash entries (i.e., symbols) be identical. */
+ if (h1 != h2 || h1 == 0)
return FALSE;
}
@@ -3550,9 +3552,10 @@ hash_literal_value (src)
/* Check if the specified literal_value has been seen before. */
static value_map *
-get_cached_value (map, val)
+get_cached_value (map, val, final_static_link)
value_map_hash_table *map;
const literal_value *val;
+ bfd_boolean final_static_link;
{
value_map *map_e;
value_map *bucket;
@@ -3563,7 +3566,7 @@ get_cached_value (map, val)
bucket = map->buckets[idx];
for (map_e = bucket; map_e; map_e = map_e->next)
{
- if (is_same_value (&map_e->val, val))
+ if (is_same_value (&map_e->val, val, final_static_link))
return map_e;
}
return NULL;
@@ -3574,17 +3577,18 @@ get_cached_value (map, val)
already has an entry here. */
static value_map *
-add_value_map (map, val, loc)
+add_value_map (map, val, loc, final_static_link)
value_map_hash_table *map;
const literal_value *val;
const r_reloc *loc;
+ bfd_boolean final_static_link;
{
value_map **bucket_p;
unsigned idx;
value_map *val_e = (value_map *) bfd_zmalloc (sizeof (value_map));
- BFD_ASSERT (get_cached_value (map, val) == NULL);
+ BFD_ASSERT (get_cached_value (map, val, final_static_link) == NULL);
val_e->val = *val;
val_e->loc = *loc;
@@ -4490,6 +4494,7 @@ remove_literals (abfd, sec, link_info, values)
bfd_byte *contents;
Elf_Internal_Rela *internal_relocs;
source_reloc *src_relocs;
+ bfd_boolean final_static_link;
bfd_boolean ok = TRUE;
int i;
@@ -4510,6 +4515,10 @@ remove_literals (abfd, sec, link_info, values)
goto error_return;
}
+ final_static_link =
+ (!link_info->relocatable
+ && !elf_hash_table (link_info)->dynamic_sections_created);
+
/* Sort the source_relocs by target offset. */
src_relocs = relax_info->src_relocs;
qsort (src_relocs, relax_info->src_count,
@@ -4562,7 +4571,7 @@ remove_literals (abfd, sec, link_info, values)
val.value = bfd_get_32 (abfd, contents + rel->r_rel.target_offset);
/* Check if we've seen another literal with the same value. */
- val_map = get_cached_value (values, &val);
+ val_map = get_cached_value (values, &val, final_static_link);
if (val_map != NULL)
{
/* First check that THIS and all the other relocs to this
@@ -4585,7 +4594,7 @@ remove_literals (abfd, sec, link_info, values)
{
/* This is the first time we've seen this literal value. */
BFD_ASSERT (sec == r_reloc_get_section (&rel->r_rel));
- add_value_map (values, &val, &rel->r_rel);
+ add_value_map (values, &val, &rel->r_rel, final_static_link);
}
}
@@ -5825,7 +5834,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 8bd03c2..01c66b5 100644
--- a/bfd/elf64-alpha.c
+++ b/bfd/elf64-alpha.c
@@ -1,5 +1,5 @@
/* Alpha specific support for 64-bit ELF
- Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
+ Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Contributed by Richard Henderson <rth@tamu.edu>.
@@ -75,7 +75,7 @@ static bfd_boolean elf64_alpha_object_p
static bfd_boolean elf64_alpha_section_from_shdr
PARAMS ((bfd *, Elf_Internal_Shdr *, const char *));
static bfd_boolean elf64_alpha_section_flags
- PARAMS ((flagword *, Elf_Internal_Shdr *));
+ PARAMS ((flagword *, const Elf_Internal_Shdr *));
static bfd_boolean elf64_alpha_fake_sections
PARAMS ((bfd *, Elf_Internal_Shdr *, asection *));
static bfd_boolean elf64_alpha_create_got_section
@@ -123,7 +123,7 @@ static bfd_boolean elf64_alpha_size_rela_got_section
static bfd_boolean elf64_alpha_size_rela_got_1
PARAMS ((struct alpha_elf_link_hash_entry *, struct bfd_link_info *));
static bfd_boolean elf64_alpha_add_symbol_hook
- PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,
+ PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Sym *,
const char **, flagword *, asection **, bfd_vma *));
static struct alpha_elf_got_entry *get_got_entry
PARAMS ((bfd *, struct alpha_elf_link_hash_entry *, unsigned long,
@@ -2315,7 +2315,7 @@ elf64_alpha_section_from_shdr (abfd, hdr, name)
static bfd_boolean
elf64_alpha_section_flags (flags, hdr)
flagword *flags;
- Elf_Internal_Shdr *hdr;
+ const Elf_Internal_Shdr *hdr;
{
if (hdr->sh_flags & SHF_ALPHA_GPREL)
*flags |= SEC_SMALL_DATA;
@@ -2363,7 +2363,7 @@ static bfd_boolean
elf64_alpha_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
bfd *abfd;
struct bfd_link_info *info;
- const Elf_Internal_Sym *sym;
+ Elf_Internal_Sym *sym;
const char **namep ATTRIBUTE_UNUSED;
flagword *flagsp ATTRIBUTE_UNUSED;
asection **secp;
@@ -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;
@@ -2572,7 +2572,6 @@ elf64_alpha_read_ecoff_info (abfd, section, debug)
#undef READ
debug->fdr = NULL;
- debug->adjust = NULL;
return TRUE;
@@ -4094,7 +4093,7 @@ elf64_alpha_size_dynamic_sections (output_bfd, info)
the .dynamic section. The DT_DEBUG entry is filled in by the
dynamic linker and used by the debugger. */
#define add_dynamic_entry(TAG, VAL) \
- bfd_elf64_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
if (info->executable)
{
@@ -4399,12 +4398,12 @@ elf64_alpha_relocate_section (output_bfd, info, input_bfd, input_section,
bfd_boolean warned;
bfd_boolean unresolved_reloc;
struct elf_link_hash_entry *hh;
-
- RELOC_FOR_GLOBAL_SYMBOL (hh,
- (struct elf_link_hash_entry *) alpha_elf_sym_hashes (input_bfd),
- r_symndx, symtab_hdr, value,
- sec, unresolved_reloc, info,
- warned);
+ struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
+
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ hh, sec, value,
+ unresolved_reloc, warned);
if (warned)
continue;
@@ -5335,7 +5334,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-gen.c b/bfd/elf64-gen.c
index 590456c..be1dc3e 100644
--- a/bfd/elf64-gen.c
+++ b/bfd/elf64-gen.c
@@ -1,5 +1,6 @@
/* Generic support for 64-bit ELF
- Copyright 1993, 1995, 1998, 1999, 2001, 2002 Free Software Foundation, Inc.
+ Copyright 1993, 1995, 1998, 1999, 2001, 2002, 2004
+ Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@@ -87,7 +88,7 @@ elf64_generic_link_add_symbols (abfd, info)
return FALSE;
}
- return bfd_elf64_bfd_link_add_symbols (abfd, info);
+ return bfd_elf_link_add_symbols (abfd, info);
}
#define TARGET_LITTLE_SYM bfd_elf64_little_generic_vec
diff --git a/bfd/elf64-hppa.c b/bfd/elf64-hppa.c
index 5bc9309..76dcc18 100644
--- a/bfd/elf64-hppa.c
+++ b/bfd/elf64-hppa.c
@@ -1,5 +1,6 @@
/* Support for HPPA 64-bit ELF
- Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@@ -932,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;
}
@@ -1043,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;
}
@@ -1147,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;
}
@@ -1173,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;
}
@@ -1509,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;
}
@@ -1832,7 +1833,7 @@ elf64_hppa_size_dynamic_sections (output_bfd, info)
the PLT, it is how we communicate the __gp value of a load
module to the dynamic linker. */
#define add_dynamic_entry(TAG, VAL) \
- bfd_elf64_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
if (!add_dynamic_entry (DT_HP_DLD_FLAGS, 0)
|| !add_dynamic_entry (DT_PLTGOT, 0))
diff --git a/bfd/elf64-mmix.c b/bfd/elf64-mmix.c
index ca627ef..4b78681 100644
--- a/bfd/elf64-mmix.c
+++ b/bfd/elf64-mmix.c
@@ -1,5 +1,5 @@
/* MMIX-specific support for 64-bit ELF.
- Copyright 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Hans-Peter Nilsson <hp@bitrange.com>
This file is part of BFD, the Binary File Descriptor library.
@@ -205,7 +205,7 @@ static bfd_boolean mmix_elf_section_from_bfd_section
PARAMS ((bfd *, asection *, int *));
static bfd_boolean mmix_elf_add_symbol_hook
- PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,
+ PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Sym *,
const char **, flagword *, asection **, bfd_vma *));
static bfd_boolean mmix_elf_is_local_label_name
@@ -1474,45 +1474,21 @@ 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
{
- 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;
+ bfd_boolean unresolved_reloc;
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, undefined_signalled);
name = h->root.root.string;
-
- 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->shared
- && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
- relocation = 0;
- else
- {
- /* The test on undefined_signalled is redundant at the
- moment, but kept for symmetry. */
- if (! undefined_signalled
- && ! ((*info->callbacks->undefined_symbol)
- (info, h->root.root.string, input_bfd,
- input_section, rel->r_offset, TRUE)))
- return FALSE;
- undefined_signalled = TRUE;
- relocation = 0;
- }
}
r = mmix_final_link_relocate (howto, input_section,
@@ -2051,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;
}
@@ -2202,7 +2178,7 @@ bfd_boolean
mmix_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
bfd *abfd;
struct bfd_link_info *info ATTRIBUTE_UNUSED;
- const Elf_Internal_Sym *sym;
+ Elf_Internal_Sym *sym;
const char **namep ATTRIBUTE_UNUSED;
flagword *flagsp ATTRIBUTE_UNUSED;
asection **secp;
@@ -2296,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 304a635..a0d81d0 100644
--- a/bfd/elf64-ppc.c
+++ b/bfd/elf64-ppc.c
@@ -1,5 +1,6 @@
/* PowerPC64-specific support for 64-bit ELF.
- Copyright 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
Written by Linus Nordberg, Swox AB <info@swox.com>,
based on elf32-ppc.c by Ian Lance Taylor.
Largely rewritten by Alan Modra <amodra@bigpond.net.au>
@@ -81,6 +82,7 @@ static bfd_reloc_status_type ppc64_elf_unhandled_reloc
#define elf_backend_grok_psinfo ppc64_elf_grok_psinfo
#define elf_backend_create_dynamic_sections ppc64_elf_create_dynamic_sections
#define elf_backend_copy_indirect_symbol ppc64_elf_copy_indirect_symbol
+#define elf_backend_add_symbol_hook ppc64_elf_add_symbol_hook
#define elf_backend_check_relocs ppc64_elf_check_relocs
#define elf_backend_gc_mark_hook ppc64_elf_gc_mark_hook
#define elf_backend_gc_sweep_hook ppc64_elf_gc_sweep_hook
@@ -3473,6 +3475,22 @@ ppc64_elf_mark_entry_syms (struct bfd_link_info *info)
return TRUE;
}
+/* Hack symbols defined in .opd sections to be function type. */
+
+static bfd_boolean
+ppc64_elf_add_symbol_hook (bfd *ibfd ATTRIBUTE_UNUSED,
+ struct bfd_link_info *info ATTRIBUTE_UNUSED,
+ Elf_Internal_Sym *isym,
+ const char **name ATTRIBUTE_UNUSED,
+ flagword *flags ATTRIBUTE_UNUSED,
+ asection **sec,
+ bfd_vma *value ATTRIBUTE_UNUSED)
+{
+ if (strcmp (bfd_get_section_name (ibfd, *sec), ".opd") == 0)
+ isym->st_info = ELF_ST_INFO (ELF_ST_BIND (isym->st_info), STT_FUNC);
+ return TRUE;
+}
+
static bfd_boolean
update_local_sym_info (bfd *abfd, Elf_Internal_Shdr *symtab_hdr,
unsigned long r_symndx, bfd_vma r_addend, int tls_type)
@@ -3790,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;
@@ -4386,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
@@ -5556,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. */
@@ -5676,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;
}
@@ -5757,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;
}
@@ -6064,7 +6071,7 @@ ppc64_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
the .dynamic section. The DT_DEBUG entry is filled in by the
dynamic linker and used by the debugger. */
#define add_dynamic_entry(TAG, VAL) \
- bfd_elf64_add_dynamic_entry (info, (TAG), (VAL))
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
if (info->executable)
{
@@ -7480,10 +7487,10 @@ ppc64_elf_relocate_section (bfd *output_bfd,
}
else
{
- RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx,
- symtab_hdr, relocation, sec,
- unresolved_reloc, info,
- warned);
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned);
sym_name = h->root.root.string;
sym_type = h->type;
}
diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c
index 2260248..63e9950 100644
--- a/bfd/elf64-s390.c
+++ b/bfd/elf64-s390.c
@@ -1,5 +1,5 @@
/* IBM S/390-specific support for 64-bit ELF
- Copyright 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed Martin Schwidefsky (schwidefsky@de.ibm.com).
This file is part of BFD, the Binary File Descriptor library.
@@ -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;
}
@@ -1855,9 +1844,7 @@ allocate_dynrelocs (h, inf)
if (info->shared)
{
- if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0
- && ((h->elf_link_hash_flags & ELF_LINK_FORCED_LOCAL) != 0
- || info->symbolic))
+ if (SYMBOL_REFERENCES_LOCAL (info, h))
{
struct elf_s390_dyn_relocs **pp;
@@ -1896,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;
}
@@ -2129,7 +2116,7 @@ elf_s390_size_dynamic_sections (output_bfd, info)
the .dynamic section. The DT_DEBUG entry is filled in by the
dynamic linker and used by the debugger. */
#define add_dynamic_entry(TAG, VAL) \
- bfd_elf64_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
if (info->executable)
{
@@ -2294,10 +2281,10 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
{
bfd_boolean warned ATTRIBUTE_UNUSED;
- RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx,
- symtab_hdr, relocation, sec,
- unresolved_reloc, info,
- warned);
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned);
}
switch (r_type)
@@ -2540,10 +2527,7 @@ elf_s390_relocate_section (output_bfd, info, input_bfd, input_section,
&& r_type != R_390_PC32DBL
&& r_type != R_390_PC64)
|| (h != NULL
- && h->dynindx != -1
- && (! info->symbolic
- || (h->elf_link_hash_flags
- & ELF_LINK_HASH_DEF_REGULAR) == 0))))
+ && !SYMBOL_REFERENCES_LOCAL (info, h))))
|| (ELIMINATE_COPY_RELOCS
&& !info->shared
&& h != NULL
@@ -3385,6 +3369,17 @@ elf_s390_finish_dynamic_sections (output_bfd, info)
return TRUE;
}
+/* Return address for Ith PLT stub in section PLT, for relocation REL
+ or (bfd_vma) -1 if it should not be included. */
+
+static bfd_vma
+elf_s390_plt_sym_val (bfd_vma i, const asection *plt,
+ const arelent *rel ATTRIBUTE_UNUSED)
+{
+ return plt->vma + PLT_FIRST_ENTRY_SIZE + i * PLT_ENTRY_SIZE;
+}
+
+
/* Why was the hash table entry size definition changed from
ARCH_SIZE/8 to 4? This breaks the 64 bit dynamic linker and
this is the only reason for the s390_elf64_size_info structure. */
@@ -3454,6 +3449,7 @@ const struct elf_size_info s390_elf64_size_info =
#define elf_backend_relocate_section elf_s390_relocate_section
#define elf_backend_size_dynamic_sections elf_s390_size_dynamic_sections
#define elf_backend_reloc_type_class elf_s390_reloc_type_class
+#define elf_backend_plt_sym_val elf_s390_plt_sym_val
#define bfd_elf64_mkobject elf_s390_mkobject
#define elf_backend_object_p elf_s390_object_p
diff --git a/bfd/elf64-sh64.c b/bfd/elf64-sh64.c
index 15c2992..ad6ca1c 100644
--- a/bfd/elf64-sh64.c
+++ b/bfd/elf64-sh64.c
@@ -1,5 +1,5 @@
/* SuperH SH64-specific support for 64-bit ELF
- Copyright 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@@ -141,7 +141,7 @@ static bfd_boolean sh_elf64_check_relocs
static int sh64_elf64_get_symbol_type
(Elf_Internal_Sym *, int);
static bfd_boolean sh64_elf64_add_symbol_hook
- (bfd *, struct bfd_link_info *, const Elf_Internal_Sym *, const char **,
+ (bfd *, struct bfd_link_info *, Elf_Internal_Sym *, const char **,
flagword *, asection **, bfd_vma *);
static bfd_boolean sh64_elf64_link_output_symbol_hook
(struct bfd_link_info *, const char *, Elf_Internal_Sym *, asection *,
@@ -1703,15 +1703,16 @@ sh_elf64_relocate_section (bfd *output_bfd ATTRIBUTE_UNUSED,
}
else if (h->root.type == bfd_link_hash_undefweak)
relocation = 0;
- else if (info->shared
- && !info->symbolic
- && info->unresolved_syms_in_objects == RM_IGNORE)
+ else if (info->unresolved_syms_in_objects == RM_IGNORE
+ && ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
relocation = 0;
else
{
if (! ((*info->callbacks->undefined_symbol)
(info, h->root.root.string, input_bfd,
- input_section, rel->r_offset, TRUE)))
+ input_section, rel->r_offset,
+ (info->unresolved_syms_in_objects == RM_GENERATE_ERROR
+ || ELF_ST_VISIBILITY (h->other)))))
return FALSE;
relocation = 0;
}
@@ -2561,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;
@@ -2633,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;
}
@@ -2716,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;
}
@@ -2886,7 +2887,7 @@ sh64_elf64_get_symbol_type (Elf_Internal_Sym * elf_sym, int type)
static bfd_boolean
sh64_elf64_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
- const Elf_Internal_Sym *sym, const char **namep,
+ Elf_Internal_Sym *sym, const char **namep,
flagword *flagsp ATTRIBUTE_UNUSED,
asection **secp, bfd_vma *valp)
{
@@ -3298,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;
}
@@ -3424,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;
}
@@ -3727,31 +3728,31 @@ sh64_elf64_size_dynamic_sections (bfd *output_bfd,
dynamic linker and used by the debugger. */
if (info->executable)
{
- if (! bfd_elf64_add_dynamic_entry (info, DT_DEBUG, 0))
+ if (!_bfd_elf_add_dynamic_entry (info, DT_DEBUG, 0))
return FALSE;
}
if (plt)
{
- if (! bfd_elf64_add_dynamic_entry (info, DT_PLTGOT, 0)
- || ! bfd_elf64_add_dynamic_entry (info, DT_PLTRELSZ, 0)
- || ! bfd_elf64_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
- || ! bfd_elf64_add_dynamic_entry (info, DT_JMPREL, 0))
+ if (!_bfd_elf_add_dynamic_entry (info, DT_PLTGOT, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_PLTRELSZ, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_PLTREL, DT_RELA)
+ || !_bfd_elf_add_dynamic_entry (info, DT_JMPREL, 0))
return FALSE;
}
if (relocs)
{
- if (! bfd_elf64_add_dynamic_entry (info, DT_RELA, 0)
- || ! bfd_elf64_add_dynamic_entry (info, DT_RELASZ, 0)
- || ! bfd_elf64_add_dynamic_entry (info, DT_RELAENT,
- sizeof (Elf64_External_Rela)))
+ if (!_bfd_elf_add_dynamic_entry (info, DT_RELA, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_RELASZ, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_RELAENT,
+ sizeof (Elf64_External_Rela)))
return FALSE;
}
if (reltext)
{
- if (! bfd_elf64_add_dynamic_entry (info, DT_TEXTREL, 0))
+ if (!_bfd_elf_add_dynamic_entry (info, DT_TEXTREL, 0))
return FALSE;
}
}
diff --git a/bfd/elf64-sparc.c b/bfd/elf64-sparc.c
index 4224310..905890e 100644
--- a/bfd/elf64-sparc.c
+++ b/bfd/elf64-sparc.c
@@ -1,6 +1,6 @@
/* SPARC-specific support for 64-bit ELF
Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
- 2003 Free Software Foundation, Inc.
+ 2003, 2004 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@@ -61,7 +61,7 @@ static bfd_boolean sparc64_elf_size_dynamic_sections
static int sparc64_elf_get_symbol_type
PARAMS (( Elf_Internal_Sym *, int));
static bfd_boolean sparc64_elf_add_symbol_hook
- PARAMS ((bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,
+ PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Sym *,
const char **, flagword *, asection **, bfd_vma *));
static bfd_boolean sparc64_elf_output_arch_syms
PARAMS ((bfd *, struct bfd_link_info *, PTR,
@@ -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;
}
@@ -1385,7 +1385,7 @@ static bfd_boolean
sparc64_elf_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
bfd *abfd;
struct bfd_link_info *info;
- const Elf_Internal_Sym *sym;
+ Elf_Internal_Sym *sym;
const char **namep;
flagword *flagsp ATTRIBUTE_UNUSED;
asection **secp ATTRIBUTE_UNUSED;
@@ -1876,7 +1876,7 @@ sparc64_elf_size_dynamic_sections (output_bfd, info)
the .dynamic section. The DT_DEBUG entry is filled in by the
dynamic linker and used by the debugger. */
#define add_dynamic_entry(TAG, VAL) \
- bfd_elf64_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
int reg;
struct sparc64_elf_app_reg * app_regs;
@@ -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
@@ -2039,6 +2028,8 @@ sparc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
got_base = elf_hash_table (info)->hgot->root.u.def.value;
sgot = splt = sreloc = NULL;
+ if (dynobj != NULL)
+ splt = bfd_get_section_by_name (dynobj, ".plt");
rel = relocs;
relend = relocs + NUM_SHDR_ENTRIES (& elf_section_data (input_section)->rel_hdr);
@@ -2079,10 +2070,10 @@ sparc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
{
bfd_boolean warned;
- RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx,
- symtab_hdr, relocation, sec,
- unresolved_reloc, info,
- warned);
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned);
if (warned)
{
/* To avoid generating warning messages about truncated
@@ -2222,6 +2213,13 @@ sparc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
break;
}
+ /* FIXME: Dynamic reloc handling really needs to be rewritten. */
+ if (!skip
+ && h != NULL
+ && ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
+ && h->root.type == bfd_link_hash_undefweak)
+ skip = TRUE, relocate = TRUE;
+
if (skip)
memset (&outrel, 0, sizeof outrel);
/* h->dynindx may be -1 if the symbol was marked to
@@ -2327,7 +2325,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
@@ -2420,7 +2418,7 @@ sparc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
procedure linkage table. */
BFD_ASSERT (h != NULL);
- if (h->plt.offset == (bfd_vma) -1)
+ if (h->plt.offset == (bfd_vma) -1 || splt == NULL)
{
/* We didn't make a PLT entry for this symbol. This
happens when statically linking PIC code, or when
@@ -2428,12 +2426,6 @@ sparc64_elf_relocate_section (output_bfd, info, input_bfd, input_section,
goto do_default;
}
- if (splt == NULL)
- {
- splt = bfd_get_section_by_name (dynobj, ".plt");
- BFD_ASSERT (splt != NULL);
- }
-
relocation = (splt->output_section->vma
+ splt->output_offset
+ sparc64_elf_plt_entry_offset (h->plt.offset));
@@ -3115,6 +3107,24 @@ sparc64_elf_object_p (abfd)
return bfd_default_set_arch_mach (abfd, bfd_arch_sparc, mach);
}
+/* Return address for Ith PLT stub in section PLT, for relocation REL
+ or (bfd_vma) -1 if it should not be included. */
+
+static bfd_vma
+sparc64_elf_plt_sym_val (bfd_vma i, const asection *plt,
+ const arelent *rel ATTRIBUTE_UNUSED)
+{
+ bfd_vma j;
+
+ i += PLT_HEADER_SIZE / PLT_ENTRY_SIZE;
+ if (i < LARGE_PLT_THRESHOLD)
+ return plt->vma + i * PLT_ENTRY_SIZE;
+
+ j = (i - LARGE_PLT_THRESHOLD) % 160;
+ i -= j;
+ return plt->vma + i * PLT_ENTRY_SIZE + j * 4 * 6;
+}
+
/* Relocations in the 64 bit SPARC ELF ABI are more complex than in
standard ELF, because R_SPARC_OLO10 has secondary addend in
ELF64_R_TYPE_DATA field. This structure is used to redirect the
@@ -3214,6 +3224,8 @@ const struct elf_size_info sparc64_elf_size_info =
sparc64_elf_merge_private_bfd_data
#define elf_backend_fake_sections \
sparc64_elf_fake_sections
+#define elf_backend_plt_sym_val \
+ sparc64_elf_plt_sym_val
#define elf_backend_size_info \
sparc64_elf_size_info
diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c
index a688620..ee1b14e 100644
--- a/bfd/elf64-x86-64.c
+++ b/bfd/elf64-x86-64.c
@@ -1,5 +1,5 @@
/* X86-64 specific support for 64-bit ELF
- Copyright 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright 2000, 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
Contributed by Jan Hubicka <jh@suse.cz>.
This file is part of BFD, the Binary File Descriptor library.
@@ -561,7 +561,8 @@ elf64_x86_64_copy_indirect_symbol (const struct elf_backend_data *bed,
(ind->elf_link_hash_flags & (ELF_LINK_HASH_REF_DYNAMIC
| ELF_LINK_HASH_REF_REGULAR
| ELF_LINK_HASH_REF_REGULAR_NONWEAK
- | ELF_LINK_HASH_NEEDS_PLT));
+ | ELF_LINK_HASH_NEEDS_PLT
+ | ELF_LINK_POINTER_EQUALITY_NEEDED));
else
_bfd_elf_link_hash_copy_indirect (bed, dir, ind);
}
@@ -812,6 +813,8 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec,
/* We may need a .plt entry if the function this reloc
refers to is in a shared lib. */
h->plt.refcount += 1;
+ if (r_type != R_X86_64_PC32)
+ h->elf_link_hash_flags |= ELF_LINK_POINTER_EQUALITY_NEEDED;
}
/* If we are creating a shared library, and this is a reloc
@@ -951,14 +954,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 +1261,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 +1289,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 +1357,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 +1442,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;
}
@@ -1683,7 +1675,7 @@ elf64_x86_64_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
the .dynamic section. The DT_DEBUG entry is filled in by the
dynamic linker and used by the debugger. */
#define add_dynamic_entry(TAG, VAL) \
- bfd_elf64_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
if (info->executable)
{
@@ -1820,10 +1812,10 @@ elf64_x86_64_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
{
bfd_boolean warned;
- RELOC_FOR_GLOBAL_SYMBOL (h, sym_hashes, r_symndx,
- symtab_hdr, relocation, sec,
- unresolved_reloc, info,
- warned);
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sec, relocation,
+ unresolved_reloc, warned);
}
/* When generating a shared object, the relocations handled here are
copied into the output file to be resolved at run time. */
@@ -2530,11 +2522,16 @@ elf64_x86_64_finish_dynamic_symbol (bfd *output_bfd,
if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) == 0)
{
/* Mark the symbol as undefined, rather than as defined in
- the .plt section. Leave the value alone. This is a clue
+ the .plt section. Leave the value if there were any
+ relocations where pointer equality matters (this is a clue
for the dynamic linker, to make function pointer
comparisons work between an application and shared
- library. */
+ library), otherwise set it to zero. If a function is only
+ called from a binary, there is no need to slow down
+ shared libraries because of that. */
sym->st_shndx = SHN_UNDEF;
+ if ((h->elf_link_hash_flags & ELF_LINK_POINTER_EQUALITY_NEEDED) == 0)
+ sym->st_value = 0;
}
}
@@ -2761,6 +2758,15 @@ elf64_x86_64_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *inf
return TRUE;
}
+/* Return address for Ith PLT stub in section PLT, for relocation REL
+ or (bfd_vma) -1 if it should not be included. */
+
+static bfd_vma
+elf64_x86_64_plt_sym_val (bfd_vma i, const asection *plt,
+ const arelent *rel ATTRIBUTE_UNUSED)
+{
+ return plt->vma + (i + 1) * PLT_ENTRY_SIZE;
+}
#define TARGET_LITTLE_SYM bfd_elf64_x86_64_vec
#define TARGET_LITTLE_NAME "elf64-x86-64"
@@ -2795,6 +2801,7 @@ elf64_x86_64_finish_dynamic_sections (bfd *output_bfd, struct bfd_link_info *inf
#define elf_backend_reloc_type_class elf64_x86_64_reloc_type_class
#define elf_backend_relocate_section elf64_x86_64_relocate_section
#define elf_backend_size_dynamic_sections elf64_x86_64_size_dynamic_sections
+#define elf_backend_plt_sym_val elf64_x86_64_plt_sym_val
#define elf_backend_object_p elf64_x86_64_elf_object_p
#define bfd_elf64_mkobject elf64_x86_64_mkobject
diff --git a/bfd/elfarm-nabi.c b/bfd/elfarm-nabi.c
index 5ecbe8e..961a52a 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 87d96fa..0c7be88 100644
--- a/bfd/elfcode.h
+++ b/bfd/elfcode.h
@@ -105,6 +105,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define elf_canonicalize_symtab NAME(bfd_elf,canonicalize_symtab)
#define elf_canonicalize_dynamic_symtab \
NAME(bfd_elf,canonicalize_dynamic_symtab)
+#define elf_get_synthetic_symtab \
+ NAME(bfd_elf,get_synthetic_symtab)
#define elf_make_empty_symbol NAME(bfd_elf,make_empty_symbol)
#define elf_get_symbol_info NAME(bfd_elf,get_symbol_info)
#define elf_get_lineno NAME(bfd_elf,get_lineno)
@@ -115,24 +117,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define elf_no_info_to_howto NAME(bfd_elf,no_info_to_howto)
#define elf_no_info_to_howto_rel NAME(bfd_elf,no_info_to_howto_rel)
#define elf_find_section NAME(bfd_elf,find_section)
-#define elf_bfd_link_add_symbols NAME(bfd_elf,bfd_link_add_symbols)
-#define elf_add_dynamic_entry NAME(bfd_elf,add_dynamic_entry)
#define elf_write_shdrs_and_ehdr NAME(bfd_elf,write_shdrs_and_ehdr)
#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)
@@ -151,10 +139,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 *);
@@ -1111,8 +1095,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
@@ -1737,7 +1721,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 5770b25..32f4264 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -24,6 +24,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#include "libbfd.h"
#define ARCH_SIZE 0
#include "elf-bfd.h"
+#include "safe-ctype.h"
+#include "libiberty.h"
bfd_boolean
_bfd_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
@@ -89,7 +91,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;
@@ -219,7 +221,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");
@@ -284,7 +286,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;
}
@@ -346,8 +348,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)
{
@@ -430,6 +432,13 @@ bfd_elf_record_link_assignment (bfd *output_bfd ATTRIBUTE_UNUSED,
if (h == NULL)
return FALSE;
+ /* Since we're defining the symbol, don't let it seem to have not
+ been defined. record_dynamic_symbol and size_dynamic_sections
+ may depend on this. */
+ if (h->root.type == bfd_link_hash_undefweak
+ || h->root.type == bfd_link_hash_undefined)
+ h->root.type = bfd_link_hash_new;
+
if (h->root.type == bfd_link_hash_new)
h->elf_link_hash_flags &= ~ELF_LINK_NON_ELF;
@@ -458,7 +467,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
@@ -467,7 +476,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;
}
}
@@ -480,9 +489,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;
@@ -646,8 +655,7 @@ _bfd_elf_link_renumber_dynsyms (bfd *output_bfd, struct bfd_link_info *info)
TYPE_CHANGE_OK if it is OK for the type to change. We set
SIZE_CHANGE_OK if it is OK for the size to change. By OK to
change, we mean that we shouldn't warn if the type or size does
- change. DT_NEEDED indicates if it comes from a DT_NEEDED entry of
- a shared object. */
+ change. */
bfd_boolean
_bfd_elf_merge_symbol (bfd *abfd,
@@ -660,8 +668,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
bfd_boolean *skip,
bfd_boolean *override,
bfd_boolean *type_change_ok,
- bfd_boolean *size_change_ok,
- bfd_boolean dt_needed)
+ bfd_boolean *size_change_ok)
{
asection *sec;
struct elf_link_hash_entry *h;
@@ -669,7 +676,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
int bind;
bfd *oldbfd;
bfd_boolean newdyn, olddyn, olddef, newdef, newdyncommon, olddyncommon;
- bfd_boolean newweakdef, oldweakdef, newweakundef, oldweakundef;
+ bfd_boolean newweak, oldweak;
*skip = FALSE;
*override = FALSE;
@@ -807,7 +814,7 @@ _bfd_elf_merge_symbol (bfd *abfd,
is the first time we see it in a dynamic object, we mark
if it is weak. Otherwise, we clear it. */
if ((h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC) == 0)
- {
+ {
if (bind == STB_WEAK)
h->elf_link_hash_flags |= ELF_LINK_DYNAMIC_WEAK;
}
@@ -830,7 +837,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;
}
@@ -843,8 +850,26 @@ _bfd_elf_merge_symbol (bfd *abfd,
object, we remove the old definition. */
if ((*sym_hash)->root.type == bfd_link_hash_indirect)
h = *sym_hash;
- h->root.type = bfd_link_hash_new;
- h->root.u.undef.abfd = NULL;
+
+ if ((h->root.und_next || info->hash->undefs_tail == &h->root)
+ && bfd_is_und_section (sec))
+ {
+ /* If the new symbol is undefined and the old symbol was
+ also undefined before, we need to make sure
+ _bfd_generic_link_add_one_symbol doesn't mess
+ up the linker hash table undefs list. Since the old
+ definition came from a dynamic object, it is still on the
+ undefs list. */
+ h->root.type = bfd_link_hash_undefined;
+ /* FIXME: What if the new symbol is weak undefined? */
+ h->root.u.undef.abfd = abfd;
+ }
+ else
+ {
+ h->root.type = bfd_link_hash_new;
+ h->root.u.undef.abfd = NULL;
+ }
+
if (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC)
{
h->elf_link_hash_flags &= ~ELF_LINK_HASH_DEF_DYNAMIC;
@@ -857,48 +882,43 @@ _bfd_elf_merge_symbol (bfd *abfd,
return TRUE;
}
- /* We need to treat weak definition right, depending on if there is a
- definition from a dynamic object. */
- if (bind == STB_WEAK)
- {
- if (olddef)
- {
- newweakdef = TRUE;
- newweakundef = FALSE;
- }
- else
- {
- newweakdef = FALSE;
- newweakundef = TRUE;
- }
- }
- else
- newweakdef = newweakundef = FALSE;
+ /* Differentiate strong and weak symbols. */
+ newweak = bind == STB_WEAK;
+ oldweak = (h->root.type == bfd_link_hash_defweak
+ || h->root.type == bfd_link_hash_undefweak);
- /* If the new weak definition comes from a relocatable file and the
- old symbol comes from a dynamic object, we treat the new one as
- strong. */
- if (newweakdef && !newdyn && olddyn)
- newweakdef = FALSE;
+ /* If a new weak symbol definition comes from a regular file and the
+ old symbol comes from a dynamic library, we treat the new one as
+ strong. Similarly, an old weak symbol definition from a regular
+ file is treated as strong when the new symbol comes from a dynamic
+ library. Further, an old weak symbol from a dynamic library is
+ treated as strong if the new symbol is from a dynamic library.
+ This reflects the way glibc's ld.so works.
- if (h->root.type == bfd_link_hash_defweak)
- {
- oldweakdef = TRUE;
- oldweakundef = FALSE;
- }
- else if (h->root.type == bfd_link_hash_undefweak)
- {
- oldweakdef = FALSE;
- oldweakundef = TRUE;
- }
- else
- oldweakdef = oldweakundef = FALSE;
+ Do this before setting *type_change_ok or *size_change_ok so that
+ we warn properly when dynamic library symbols are overridden. */
+
+ if (newdef && !newdyn && olddyn)
+ newweak = FALSE;
+ if (olddef && newdyn)
+ oldweak = FALSE;
+
+ /* It's OK to change the type if either the existing symbol or the
+ new symbol is weak. A type change is also OK if the old symbol
+ is undefined and the new symbol is defined. */
+
+ if (oldweak
+ || newweak
+ || (newdef
+ && h->root.type == bfd_link_hash_undefined))
+ *type_change_ok = TRUE;
- /* If the old weak definition comes from a relocatable file and the
- new symbol comes from a dynamic object, we treat the old one as
- strong. */
- if (oldweakdef && !olddyn && newdyn)
- oldweakdef = FALSE;
+ /* It's OK to change the size if either the existing symbol or the
+ new symbol is weak, or if the old symbol is undefined. */
+
+ if (*type_change_ok
+ || h->root.type == bfd_link_hash_undefined)
+ *size_change_ok = TRUE;
/* NEWDYNCOMMON and OLDDYNCOMMON indicate whether the new or old
symbol, respectively, appears to be a common symbol in a dynamic
@@ -925,11 +945,10 @@ _bfd_elf_merge_symbol (bfd *abfd,
if (newdyn
&& newdef
+ && !newweak
&& (sec->flags & SEC_ALLOC) != 0
&& (sec->flags & SEC_LOAD) == 0
&& sym->st_size > 0
- && !newweakdef
- && !newweakundef
&& ELF_ST_TYPE (sym->st_info) != STT_FUNC)
newdyncommon = TRUE;
else
@@ -947,28 +966,6 @@ _bfd_elf_merge_symbol (bfd *abfd,
else
olddyncommon = FALSE;
- /* It's OK to change the type if either the existing symbol or the
- new symbol is weak unless it comes from a DT_NEEDED entry of
- a shared object, in which case, the DT_NEEDED entry may not be
- required at the run time. The type change is also OK if the
- old symbol is undefined and the new symbol is defined. */
-
- if ((! dt_needed && oldweakdef)
- || oldweakundef
- || newweakdef
- || newweakundef
- || (newdef
- && (h->root.type == bfd_link_hash_undefined
- || h->root.type == bfd_link_hash_undefweak)))
- *type_change_ok = TRUE;
-
- /* It's OK to change the size if either the existing symbol or the
- new symbol is weak, or if the old symbol is undefined. */
-
- if (*type_change_ok
- || h->root.type == bfd_link_hash_undefined)
- *size_change_ok = TRUE;
-
/* If both the old and the new symbols look like common symbols in a
dynamic object, set the size of the symbol to the larger of the
two. */
@@ -1006,24 +1003,14 @@ _bfd_elf_merge_symbol (bfd *abfd,
represent variables; this can cause confusion in principle, but
any such confusion would seem to indicate an erroneous program or
shared library. We also permit a common symbol in a regular
- object to override a weak symbol in a shared object.
-
- We prefer a non-weak definition in a shared library to a weak
- definition in the executable unless it comes from a DT_NEEDED
- entry of a shared object, in which case, the DT_NEEDED entry
- may not be required at the run time. */
+ object to override a weak symbol in a shared object. */
if (newdyn
&& newdef
&& (olddef
|| (h->root.type == bfd_link_hash_common
- && (newweakdef
- || newweakundef
- || ELF_ST_TYPE (sym->st_info) == STT_FUNC)))
- && (!oldweakdef
- || dt_needed
- || newweakdef
- || newweakundef))
+ && (newweak
+ || ELF_ST_TYPE (sym->st_info) == STT_FUNC))))
{
*override = TRUE;
newdef = FALSE;
@@ -1067,20 +1054,17 @@ _bfd_elf_merge_symbol (bfd *abfd,
As above, we again permit a common symbol in a regular object to
override a definition in a shared object if the shared object
- symbol is a function or is weak.
-
- As above, we permit a non-weak definition in a shared object to
- override a weak definition in a regular object. */
+ symbol is a function or is weak. */
flip = NULL;
if (! newdyn
&& (newdef
|| (bfd_is_com_section (sec)
- && (oldweakdef || h->type == STT_FUNC)))
+ && (oldweak
+ || h->type == STT_FUNC)))
&& olddyn
&& olddef
- && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0
- && ((!newweakdef && !newweakundef) || oldweakdef))
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0)
{
/* Change the hash table entry to undefined, and let
_bfd_generic_link_add_one_symbol do the right thing with the
@@ -1169,57 +1153,13 @@ _bfd_elf_merge_symbol (bfd *abfd,
}
}
- /* Handle the special case of a weak definition in a regular object
- followed by a non-weak definition in a shared object. In this
- case, we prefer the definition in the shared object unless it
- comes from a DT_NEEDED entry of a shared object, in which case,
- the DT_NEEDED entry may not be required at the run time. */
- if (olddef
- && ! dt_needed
- && oldweakdef
- && newdef
- && newdyn
- && !newweakdef
- && !newweakundef)
- {
- /* To make this work we have to frob the flags so that the rest
- of the code does not think we are using the regular
- definition. */
- if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_REGULAR) != 0)
- h->elf_link_hash_flags |= ELF_LINK_HASH_REF_REGULAR;
- else if ((h->elf_link_hash_flags & ELF_LINK_HASH_DEF_DYNAMIC) != 0)
- h->elf_link_hash_flags |= ELF_LINK_HASH_REF_DYNAMIC;
- h->elf_link_hash_flags &= ~ (ELF_LINK_HASH_DEF_REGULAR
- | ELF_LINK_HASH_DEF_DYNAMIC);
-
- /* If H is the target of an indirection, we want the caller to
- use H rather than the indirect symbol. Otherwise if we are
- defining a new indirect symbol we will wind up attaching it
- to the entry we are overriding. */
- *sym_hash = h;
- }
-
- /* Handle the special case of a non-weak definition in a shared
- object followed by a weak definition in a regular object. In
- this case we prefer the definition in the shared object. To make
- this work we have to tell the caller to not treat the new symbol
- as a definition. */
- if (olddef
- && olddyn
- && !oldweakdef
- && newdef
- && ! newdyn
- && (newweakdef || newweakundef))
- *override = TRUE;
-
return TRUE;
}
/* This function is called to create an indirect symbol from the
default for the symbol with the default version if needed. The
symbol is described by H, NAME, SYM, PSEC, VALUE, and OVERRIDE. We
- set DYNSYM if the new indirect symbol is dynamic. DT_NEEDED
- indicates if it comes from a DT_NEEDED entry of a shared object. */
+ set DYNSYM if the new indirect symbol is dynamic. */
bfd_boolean
_bfd_elf_add_default_symbol (bfd *abfd,
@@ -1230,8 +1170,7 @@ _bfd_elf_add_default_symbol (bfd *abfd,
asection **psec,
bfd_vma *value,
bfd_boolean *dynsym,
- bfd_boolean override,
- bfd_boolean dt_needed)
+ bfd_boolean override)
{
bfd_boolean type_change_ok;
bfd_boolean size_change_ok;
@@ -1292,7 +1231,7 @@ _bfd_elf_add_default_symbol (bfd *abfd,
sec = *psec;
if (!_bfd_elf_merge_symbol (abfd, info, shortname, sym, &sec, value,
&hi, &skip, &override, &type_change_ok,
- &size_change_ok, dt_needed))
+ &size_change_ok))
return FALSE;
if (skip)
@@ -1341,7 +1280,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;
}
}
@@ -1359,12 +1298,6 @@ _bfd_elf_add_default_symbol (bfd *abfd,
{
struct elf_link_hash_entry *ht;
- /* If the symbol became indirect, then we assume that we have
- not seen a definition before. */
- BFD_ASSERT ((hi->elf_link_hash_flags
- & (ELF_LINK_HASH_DEF_DYNAMIC
- | ELF_LINK_HASH_DEF_REGULAR)) == 0);
-
ht = (struct elf_link_hash_entry *) hi->root.u.i.link;
(*bed->elf_backend_copy_indirect_symbol) (bed, ht, hi);
@@ -1405,7 +1338,7 @@ nondefault:
sec = *psec;
if (!_bfd_elf_merge_symbol (abfd, info, shortname, sym, &sec, value,
&hi, &skip, &override, &type_change_ok,
- &size_change_ok, dt_needed))
+ &size_change_ok))
return FALSE;
if (skip)
@@ -1437,12 +1370,6 @@ nondefault:
if (hi->root.type == bfd_link_hash_indirect)
{
- /* If the symbol became indirect, then we assume that we have
- not seen a definition before. */
- BFD_ASSERT ((hi->elf_link_hash_flags
- & (ELF_LINK_HASH_DEF_DYNAMIC
- | ELF_LINK_HASH_DEF_REGULAR)) == 0);
-
(*bed->elf_backend_copy_indirect_symbol) (bed, h, hi);
/* See if the new flags lead us to realize that the symbol
@@ -1511,7 +1438,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;
@@ -2155,7 +2082,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;
@@ -2543,3 +2470,6488 @@ _bfd_elf_tls_setup (bfd *obfd, struct bfd_link_info *info)
return tls;
}
+
+/* Return TRUE iff this is a non-common, definition of a non-function symbol. */
+static bfd_boolean
+is_global_data_symbol_definition (bfd *abfd ATTRIBUTE_UNUSED,
+ Elf_Internal_Sym *sym)
+{
+ /* Local symbols do not count, but target specific ones might. */
+ if (ELF_ST_BIND (sym->st_info) != STB_GLOBAL
+ && ELF_ST_BIND (sym->st_info) < STB_LOOS)
+ return FALSE;
+
+ /* Function symbols do not count. */
+ if (ELF_ST_TYPE (sym->st_info) == STT_FUNC)
+ return FALSE;
+
+ /* If the section is undefined, then so is the symbol. */
+ if (sym->st_shndx == SHN_UNDEF)
+ return FALSE;
+
+ /* If the symbol is defined in the common section, then
+ it is a common definition and so does not count. */
+ if (sym->st_shndx == SHN_COMMON)
+ return FALSE;
+
+ /* If the symbol is in a target specific section then we
+ must rely upon the backend to tell us what it is. */
+ if (sym->st_shndx >= SHN_LORESERVE && sym->st_shndx < SHN_ABS)
+ /* FIXME - this function is not coded yet:
+
+ return _bfd_is_global_symbol_definition (abfd, sym);
+
+ Instead for now assume that the definition is not global,
+ Even if this is wrong, at least the linker will behave
+ in the same way that it used to do. */
+ return FALSE;
+
+ return TRUE;
+}
+
+/* Search the symbol table of the archive element of the archive ABFD
+ whose archive map contains a mention of SYMDEF, and determine if
+ the symbol is defined in this element. */
+static bfd_boolean
+elf_link_is_defined_archive_symbol (bfd * abfd, carsym * symdef)
+{
+ Elf_Internal_Shdr * hdr;
+ bfd_size_type symcount;
+ bfd_size_type extsymcount;
+ bfd_size_type extsymoff;
+ Elf_Internal_Sym *isymbuf;
+ Elf_Internal_Sym *isym;
+ Elf_Internal_Sym *isymend;
+ bfd_boolean result;
+
+ abfd = _bfd_get_elt_at_filepos (abfd, symdef->file_offset);
+ if (abfd == NULL)
+ return FALSE;
+
+ if (! bfd_check_format (abfd, bfd_object))
+ return FALSE;
+
+ /* If we have already included the element containing this symbol in the
+ link then we do not need to include it again. Just claim that any symbol
+ it contains is not a definition, so that our caller will not decide to
+ (re)include this element. */
+ if (abfd->archive_pass)
+ return FALSE;
+
+ /* Select the appropriate symbol table. */
+ if ((abfd->flags & DYNAMIC) == 0 || elf_dynsymtab (abfd) == 0)
+ hdr = &elf_tdata (abfd)->symtab_hdr;
+ else
+ hdr = &elf_tdata (abfd)->dynsymtab_hdr;
+
+ symcount = hdr->sh_size / get_elf_backend_data (abfd)->s->sizeof_sym;
+
+ /* The sh_info field of the symtab header tells us where the
+ external symbols start. We don't care about the local symbols. */
+ if (elf_bad_symtab (abfd))
+ {
+ extsymcount = symcount;
+ extsymoff = 0;
+ }
+ else
+ {
+ extsymcount = symcount - hdr->sh_info;
+ extsymoff = hdr->sh_info;
+ }
+
+ if (extsymcount == 0)
+ return FALSE;
+
+ /* Read in the symbol table. */
+ isymbuf = bfd_elf_get_elf_syms (abfd, hdr, extsymcount, extsymoff,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ return FALSE;
+
+ /* Scan the symbol table looking for SYMDEF. */
+ result = FALSE;
+ for (isym = isymbuf, isymend = isymbuf + extsymcount; isym < isymend; isym++)
+ {
+ const char *name;
+
+ name = bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
+ isym->st_name);
+ if (name == NULL)
+ break;
+
+ if (strcmp (name, symdef->name) == 0)
+ {
+ result = is_global_data_symbol_definition (abfd, isym);
+ break;
+ }
+ }
+
+ free (isymbuf);
+
+ return result;
+}
+
+/* Add an entry to the .dynamic table. */
+
+bfd_boolean
+_bfd_elf_add_dynamic_entry (struct bfd_link_info *info,
+ bfd_vma tag,
+ bfd_vma val)
+{
+ struct elf_link_hash_table *hash_table;
+ const struct elf_backend_data *bed;
+ asection *s;
+ bfd_size_type newsize;
+ bfd_byte *newcontents;
+ Elf_Internal_Dyn dyn;
+
+ hash_table = elf_hash_table (info);
+ if (! is_elf_hash_table (hash_table))
+ return FALSE;
+
+ bed = get_elf_backend_data (hash_table->dynobj);
+ s = bfd_get_section_by_name (hash_table->dynobj, ".dynamic");
+ BFD_ASSERT (s != NULL);
+
+ newsize = s->_raw_size + bed->s->sizeof_dyn;
+ newcontents = bfd_realloc (s->contents, newsize);
+ if (newcontents == NULL)
+ return FALSE;
+
+ dyn.d_tag = tag;
+ dyn.d_un.d_val = val;
+ bed->s->swap_dyn_out (hash_table->dynobj, &dyn, newcontents + s->_raw_size);
+
+ s->_raw_size = newsize;
+ s->contents = newcontents;
+
+ return TRUE;
+}
+
+/* Add a DT_NEEDED entry for this dynamic object if DO_IT is true,
+ otherwise just check whether one already exists. Returns -1 on error,
+ 1 if a DT_NEEDED tag already exists, and 0 on success. */
+
+static int
+elf_add_dt_needed_tag (struct bfd_link_info *info,
+ const char *soname,
+ bfd_boolean do_it)
+{
+ struct elf_link_hash_table *hash_table;
+ bfd_size_type oldsize;
+ bfd_size_type strindex;
+
+ hash_table = elf_hash_table (info);
+ oldsize = _bfd_elf_strtab_size (hash_table->dynstr);
+ strindex = _bfd_elf_strtab_add (hash_table->dynstr, soname, FALSE);
+ if (strindex == (bfd_size_type) -1)
+ return -1;
+
+ if (oldsize == _bfd_elf_strtab_size (hash_table->dynstr))
+ {
+ asection *sdyn;
+ const struct elf_backend_data *bed;
+ bfd_byte *extdyn;
+
+ bed = get_elf_backend_data (hash_table->dynobj);
+ sdyn = bfd_get_section_by_name (hash_table->dynobj, ".dynamic");
+ BFD_ASSERT (sdyn != NULL);
+
+ for (extdyn = sdyn->contents;
+ extdyn < sdyn->contents + sdyn->_raw_size;
+ extdyn += bed->s->sizeof_dyn)
+ {
+ Elf_Internal_Dyn dyn;
+
+ bed->s->swap_dyn_in (hash_table->dynobj, extdyn, &dyn);
+ if (dyn.d_tag == DT_NEEDED
+ && dyn.d_un.d_val == strindex)
+ {
+ _bfd_elf_strtab_delref (hash_table->dynstr, strindex);
+ return 1;
+ }
+ }
+ }
+
+ if (do_it)
+ {
+ if (!_bfd_elf_add_dynamic_entry (info, DT_NEEDED, strindex))
+ return -1;
+ }
+ else
+ /* We were just checking for existence of the tag. */
+ _bfd_elf_strtab_delref (hash_table->dynstr, strindex);
+
+ return 0;
+}
+
+/* Sort symbol by value and section. */
+static int
+elf_sort_symbol (const void *arg1, const void *arg2)
+{
+ const struct elf_link_hash_entry *h1;
+ const struct elf_link_hash_entry *h2;
+ bfd_signed_vma vdiff;
+
+ h1 = *(const struct elf_link_hash_entry **) arg1;
+ h2 = *(const struct elf_link_hash_entry **) arg2;
+ vdiff = h1->root.u.def.value - h2->root.u.def.value;
+ if (vdiff != 0)
+ return vdiff > 0 ? 1 : -1;
+ else
+ {
+ long sdiff = h1->root.u.def.section - h2->root.u.def.section;
+ if (sdiff != 0)
+ return sdiff > 0 ? 1 : -1;
+ }
+ return 0;
+}
+
+/* This function is used to adjust offsets into .dynstr for
+ dynamic symbols. This is called via elf_link_hash_traverse. */
+
+static bfd_boolean
+elf_adjust_dynstr_offsets (struct elf_link_hash_entry *h, void *data)
+{
+ struct elf_strtab_hash *dynstr = data;
+
+ if (h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+ if (h->dynindx != -1)
+ h->dynstr_index = _bfd_elf_strtab_offset (dynstr, h->dynstr_index);
+ return TRUE;
+}
+
+/* Assign string offsets in .dynstr, update all structures referencing
+ them. */
+
+static bfd_boolean
+elf_finalize_dynstr (bfd *output_bfd, struct bfd_link_info *info)
+{
+ struct elf_link_hash_table *hash_table = elf_hash_table (info);
+ struct elf_link_local_dynamic_entry *entry;
+ struct elf_strtab_hash *dynstr = hash_table->dynstr;
+ bfd *dynobj = hash_table->dynobj;
+ asection *sdyn;
+ bfd_size_type size;
+ const struct elf_backend_data *bed;
+ bfd_byte *extdyn;
+
+ _bfd_elf_strtab_finalize (dynstr);
+ size = _bfd_elf_strtab_size (dynstr);
+
+ bed = get_elf_backend_data (dynobj);
+ sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
+ BFD_ASSERT (sdyn != NULL);
+
+ /* Update all .dynamic entries referencing .dynstr strings. */
+ for (extdyn = sdyn->contents;
+ extdyn < sdyn->contents + sdyn->_raw_size;
+ extdyn += bed->s->sizeof_dyn)
+ {
+ Elf_Internal_Dyn dyn;
+
+ bed->s->swap_dyn_in (dynobj, extdyn, &dyn);
+ switch (dyn.d_tag)
+ {
+ case DT_STRSZ:
+ dyn.d_un.d_val = size;
+ break;
+ case DT_NEEDED:
+ case DT_SONAME:
+ case DT_RPATH:
+ case DT_RUNPATH:
+ case DT_FILTER:
+ case DT_AUXILIARY:
+ dyn.d_un.d_val = _bfd_elf_strtab_offset (dynstr, dyn.d_un.d_val);
+ break;
+ default:
+ continue;
+ }
+ bed->s->swap_dyn_out (dynobj, &dyn, extdyn);
+ }
+
+ /* Now update local dynamic symbols. */
+ for (entry = hash_table->dynlocal; entry ; entry = entry->next)
+ entry->isym.st_name = _bfd_elf_strtab_offset (dynstr,
+ entry->isym.st_name);
+
+ /* And the rest of dynamic symbols. */
+ elf_link_hash_traverse (hash_table, elf_adjust_dynstr_offsets, dynstr);
+
+ /* Adjust version definitions. */
+ if (elf_tdata (output_bfd)->cverdefs)
+ {
+ asection *s;
+ bfd_byte *p;
+ bfd_size_type i;
+ Elf_Internal_Verdef def;
+ Elf_Internal_Verdaux defaux;
+
+ s = bfd_get_section_by_name (dynobj, ".gnu.version_d");
+ p = s->contents;
+ do
+ {
+ _bfd_elf_swap_verdef_in (output_bfd, (Elf_External_Verdef *) p,
+ &def);
+ p += sizeof (Elf_External_Verdef);
+ for (i = 0; i < def.vd_cnt; ++i)
+ {
+ _bfd_elf_swap_verdaux_in (output_bfd,
+ (Elf_External_Verdaux *) p, &defaux);
+ defaux.vda_name = _bfd_elf_strtab_offset (dynstr,
+ defaux.vda_name);
+ _bfd_elf_swap_verdaux_out (output_bfd,
+ &defaux, (Elf_External_Verdaux *) p);
+ p += sizeof (Elf_External_Verdaux);
+ }
+ }
+ while (def.vd_next);
+ }
+
+ /* Adjust version references. */
+ if (elf_tdata (output_bfd)->verref)
+ {
+ asection *s;
+ bfd_byte *p;
+ bfd_size_type i;
+ Elf_Internal_Verneed need;
+ Elf_Internal_Vernaux needaux;
+
+ s = bfd_get_section_by_name (dynobj, ".gnu.version_r");
+ p = s->contents;
+ do
+ {
+ _bfd_elf_swap_verneed_in (output_bfd, (Elf_External_Verneed *) p,
+ &need);
+ need.vn_file = _bfd_elf_strtab_offset (dynstr, need.vn_file);
+ _bfd_elf_swap_verneed_out (output_bfd, &need,
+ (Elf_External_Verneed *) p);
+ p += sizeof (Elf_External_Verneed);
+ for (i = 0; i < need.vn_cnt; ++i)
+ {
+ _bfd_elf_swap_vernaux_in (output_bfd,
+ (Elf_External_Vernaux *) p, &needaux);
+ needaux.vna_name = _bfd_elf_strtab_offset (dynstr,
+ needaux.vna_name);
+ _bfd_elf_swap_vernaux_out (output_bfd,
+ &needaux,
+ (Elf_External_Vernaux *) p);
+ p += sizeof (Elf_External_Vernaux);
+ }
+ }
+ while (need.vn_next);
+ }
+
+ return TRUE;
+}
+
+/* Add symbols from an ELF object file to the linker hash table. */
+
+static bfd_boolean
+elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
+{
+ bfd_boolean (*add_symbol_hook)
+ (bfd *, struct bfd_link_info *, Elf_Internal_Sym *,
+ const char **, flagword *, asection **, bfd_vma *);
+ bfd_boolean (*check_relocs)
+ (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
+ bfd_boolean collect;
+ Elf_Internal_Shdr *hdr;
+ bfd_size_type symcount;
+ bfd_size_type extsymcount;
+ bfd_size_type extsymoff;
+ struct elf_link_hash_entry **sym_hash;
+ bfd_boolean dynamic;
+ Elf_External_Versym *extversym = NULL;
+ Elf_External_Versym *ever;
+ struct elf_link_hash_entry *weaks;
+ struct elf_link_hash_entry **nondeflt_vers = NULL;
+ bfd_size_type nondeflt_vers_cnt = 0;
+ Elf_Internal_Sym *isymbuf = NULL;
+ Elf_Internal_Sym *isym;
+ Elf_Internal_Sym *isymend;
+ const struct elf_backend_data *bed;
+ bfd_boolean add_needed;
+ struct elf_link_hash_table * hash_table;
+ bfd_size_type amt;
+
+ hash_table = elf_hash_table (info);
+
+ bed = get_elf_backend_data (abfd);
+ add_symbol_hook = bed->elf_add_symbol_hook;
+ collect = bed->collect;
+
+ if ((abfd->flags & DYNAMIC) == 0)
+ dynamic = FALSE;
+ else
+ {
+ dynamic = TRUE;
+
+ /* You can't use -r against a dynamic object. Also, there's no
+ hope of using a dynamic object which does not exactly match
+ the format of the output file. */
+ if (info->relocatable
+ || !is_elf_hash_table (hash_table)
+ || hash_table->root.creator != abfd->xvec)
+ {
+ bfd_set_error (bfd_error_invalid_operation);
+ goto error_return;
+ }
+ }
+
+ /* As a GNU extension, any input sections which are named
+ .gnu.warning.SYMBOL are treated as warning symbols for the given
+ symbol. This differs from .gnu.warning sections, which generate
+ warnings when they are included in an output file. */
+ if (info->executable)
+ {
+ asection *s;
+
+ for (s = abfd->sections; s != NULL; s = s->next)
+ {
+ const char *name;
+
+ name = bfd_get_section_name (abfd, s);
+ if (strncmp (name, ".gnu.warning.", sizeof ".gnu.warning." - 1) == 0)
+ {
+ char *msg;
+ bfd_size_type sz;
+ bfd_size_type prefix_len;
+ const char * gnu_warning_prefix = _("warning: ");
+
+ name += sizeof ".gnu.warning." - 1;
+
+ /* If this is a shared object, then look up the symbol
+ in the hash table. If it is there, and it is already
+ been defined, then we will not be using the entry
+ from this shared object, so we don't need to warn.
+ FIXME: If we see the definition in a regular object
+ later on, we will warn, but we shouldn't. The only
+ fix is to keep track of what warnings we are supposed
+ to emit, and then handle them all at the end of the
+ link. */
+ if (dynamic)
+ {
+ struct elf_link_hash_entry *h;
+
+ h = elf_link_hash_lookup (hash_table, name,
+ FALSE, FALSE, TRUE);
+
+ /* FIXME: What about bfd_link_hash_common? */
+ if (h != NULL
+ && (h->root.type == bfd_link_hash_defined
+ || h->root.type == bfd_link_hash_defweak))
+ {
+ /* We don't want to issue this warning. Clobber
+ the section size so that the warning does not
+ get copied into the output file. */
+ s->_raw_size = 0;
+ continue;
+ }
+ }
+
+ sz = bfd_section_size (abfd, s);
+ prefix_len = strlen (gnu_warning_prefix);
+ msg = bfd_alloc (abfd, prefix_len + sz + 1);
+ if (msg == NULL)
+ goto error_return;
+
+ strcpy (msg, gnu_warning_prefix);
+ if (! bfd_get_section_contents (abfd, s, msg + prefix_len, 0, sz))
+ goto error_return;
+
+ msg[prefix_len + sz] = '\0';
+
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, abfd, name, BSF_WARNING, s, 0, msg,
+ FALSE, collect, NULL)))
+ goto error_return;
+
+ if (! info->relocatable)
+ {
+ /* Clobber the section size so that the warning does
+ not get copied into the output file. */
+ s->_raw_size = 0;
+ }
+ }
+ }
+ }
+
+ add_needed = TRUE;
+ if (! dynamic)
+ {
+ /* If we are creating a shared library, create all the dynamic
+ sections immediately. We need to attach them to something,
+ so we attach them to this BFD, provided it is the right
+ format. FIXME: If there are no input BFD's of the same
+ format as the output, we can't make a shared library. */
+ if (info->shared
+ && is_elf_hash_table (hash_table)
+ && hash_table->root.creator == abfd->xvec
+ && ! hash_table->dynamic_sections_created)
+ {
+ if (! _bfd_elf_link_create_dynamic_sections (abfd, info))
+ goto error_return;
+ }
+ }
+ else if (!is_elf_hash_table (hash_table))
+ goto error_return;
+ else
+ {
+ asection *s;
+ const char *soname = NULL;
+ struct bfd_link_needed_list *rpath = NULL, *runpath = NULL;
+ int ret;
+
+ /* ld --just-symbols and dynamic objects don't mix very well.
+ Test for --just-symbols by looking at info set up by
+ _bfd_elf_link_just_syms. */
+ if ((s = abfd->sections) != NULL
+ && s->sec_info_type == ELF_INFO_TYPE_JUST_SYMS)
+ goto error_return;
+
+ /* If this dynamic lib was specified on the command line with
+ --as-needed in effect, then we don't want to add a DT_NEEDED
+ tag unless the lib is actually used. Similary for libs brought
+ in by another lib's DT_NEEDED. */
+ add_needed = elf_dyn_lib_class (abfd) == DYN_NORMAL;
+
+ s = bfd_get_section_by_name (abfd, ".dynamic");
+ if (s != NULL)
+ {
+ bfd_byte *dynbuf;
+ bfd_byte *extdyn;
+ int elfsec;
+ unsigned long shlink;
+
+ dynbuf = bfd_malloc (s->_raw_size);
+ if (dynbuf == NULL)
+ goto error_return;
+
+ if (! bfd_get_section_contents (abfd, s, dynbuf, 0, s->_raw_size))
+ goto error_free_dyn;
+
+ elfsec = _bfd_elf_section_from_bfd_section (abfd, s);
+ if (elfsec == -1)
+ goto error_free_dyn;
+ shlink = elf_elfsections (abfd)[elfsec]->sh_link;
+
+ for (extdyn = dynbuf;
+ extdyn < dynbuf + s->_raw_size;
+ extdyn += bed->s->sizeof_dyn)
+ {
+ Elf_Internal_Dyn dyn;
+
+ bed->s->swap_dyn_in (abfd, extdyn, &dyn);
+ if (dyn.d_tag == DT_SONAME)
+ {
+ unsigned int tagv = dyn.d_un.d_val;
+ soname = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
+ if (soname == NULL)
+ goto error_free_dyn;
+ }
+ if (dyn.d_tag == DT_NEEDED)
+ {
+ struct bfd_link_needed_list *n, **pn;
+ char *fnm, *anm;
+ unsigned int tagv = dyn.d_un.d_val;
+
+ amt = sizeof (struct bfd_link_needed_list);
+ n = bfd_alloc (abfd, amt);
+ fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
+ if (n == NULL || fnm == NULL)
+ goto error_free_dyn;
+ amt = strlen (fnm) + 1;
+ anm = bfd_alloc (abfd, amt);
+ if (anm == NULL)
+ goto error_free_dyn;
+ memcpy (anm, fnm, amt);
+ n->name = anm;
+ n->by = abfd;
+ n->next = NULL;
+ for (pn = & hash_table->needed;
+ *pn != NULL;
+ pn = &(*pn)->next)
+ ;
+ *pn = n;
+ }
+ if (dyn.d_tag == DT_RUNPATH)
+ {
+ struct bfd_link_needed_list *n, **pn;
+ char *fnm, *anm;
+ unsigned int tagv = dyn.d_un.d_val;
+
+ amt = sizeof (struct bfd_link_needed_list);
+ n = bfd_alloc (abfd, amt);
+ fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
+ if (n == NULL || fnm == NULL)
+ goto error_free_dyn;
+ amt = strlen (fnm) + 1;
+ anm = bfd_alloc (abfd, amt);
+ if (anm == NULL)
+ goto error_free_dyn;
+ memcpy (anm, fnm, amt);
+ n->name = anm;
+ n->by = abfd;
+ n->next = NULL;
+ for (pn = & runpath;
+ *pn != NULL;
+ pn = &(*pn)->next)
+ ;
+ *pn = n;
+ }
+ /* Ignore DT_RPATH if we have seen DT_RUNPATH. */
+ if (!runpath && dyn.d_tag == DT_RPATH)
+ {
+ struct bfd_link_needed_list *n, **pn;
+ char *fnm, *anm;
+ unsigned int tagv = dyn.d_un.d_val;
+
+ amt = sizeof (struct bfd_link_needed_list);
+ n = bfd_alloc (abfd, amt);
+ fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
+ if (n == NULL || fnm == NULL)
+ goto error_free_dyn;
+ amt = strlen (fnm) + 1;
+ anm = bfd_alloc (abfd, amt);
+ if (anm == NULL)
+ {
+ error_free_dyn:
+ free (dynbuf);
+ goto error_return;
+ }
+ memcpy (anm, fnm, amt);
+ n->name = anm;
+ n->by = abfd;
+ n->next = NULL;
+ for (pn = & rpath;
+ *pn != NULL;
+ pn = &(*pn)->next)
+ ;
+ *pn = n;
+ }
+ }
+
+ free (dynbuf);
+ }
+
+ /* DT_RUNPATH overrides DT_RPATH. Do _NOT_ bfd_release, as that
+ frees all more recently bfd_alloc'd blocks as well. */
+ if (runpath)
+ rpath = runpath;
+
+ if (rpath)
+ {
+ struct bfd_link_needed_list **pn;
+ for (pn = & hash_table->runpath;
+ *pn != NULL;
+ pn = &(*pn)->next)
+ ;
+ *pn = rpath;
+ }
+
+ /* We do not want to include any of the sections in a dynamic
+ object in the output file. We hack by simply clobbering the
+ list of sections in the BFD. This could be handled more
+ cleanly by, say, a new section flag; the existing
+ SEC_NEVER_LOAD flag is not the one we want, because that one
+ still implies that the section takes up space in the output
+ file. */
+ bfd_section_list_clear (abfd);
+
+ /* If this is the first dynamic object found in the link, create
+ the special sections required for dynamic linking. */
+ if (! _bfd_elf_link_create_dynamic_sections (abfd, info))
+ goto error_return;
+
+ /* Find the name to use in a DT_NEEDED entry that refers to this
+ object. If the object has a DT_SONAME entry, we use it.
+ Otherwise, if the generic linker stuck something in
+ elf_dt_name, we use that. Otherwise, we just use the file
+ name. */
+ if (soname == NULL || *soname == '\0')
+ {
+ soname = elf_dt_name (abfd);
+ if (soname == NULL || *soname == '\0')
+ soname = bfd_get_filename (abfd);
+ }
+
+ /* Save the SONAME because sometimes the linker emulation code
+ will need to know it. */
+ elf_dt_name (abfd) = soname;
+
+ ret = elf_add_dt_needed_tag (info, soname, add_needed);
+ if (ret < 0)
+ goto error_return;
+
+ /* If we have already included this dynamic object in the
+ link, just ignore it. There is no reason to include a
+ particular dynamic object more than once. */
+ if (ret > 0)
+ return TRUE;
+ }
+
+ /* If this is a dynamic object, we always link against the .dynsym
+ symbol table, not the .symtab symbol table. The dynamic linker
+ will only see the .dynsym symbol table, so there is no reason to
+ look at .symtab for a dynamic object. */
+
+ if (! dynamic || elf_dynsymtab (abfd) == 0)
+ hdr = &elf_tdata (abfd)->symtab_hdr;
+ else
+ hdr = &elf_tdata (abfd)->dynsymtab_hdr;
+
+ symcount = hdr->sh_size / bed->s->sizeof_sym;
+
+ /* 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. */
+ if (elf_bad_symtab (abfd))
+ {
+ extsymcount = symcount;
+ extsymoff = 0;
+ }
+ else
+ {
+ extsymcount = symcount - hdr->sh_info;
+ extsymoff = hdr->sh_info;
+ }
+
+ sym_hash = NULL;
+ if (extsymcount != 0)
+ {
+ isymbuf = bfd_elf_get_elf_syms (abfd, hdr, extsymcount, extsymoff,
+ NULL, NULL, NULL);
+ if (isymbuf == NULL)
+ goto error_return;
+
+ /* We store a pointer to the hash table entry for each external
+ symbol. */
+ amt = extsymcount * sizeof (struct elf_link_hash_entry *);
+ sym_hash = bfd_alloc (abfd, amt);
+ if (sym_hash == NULL)
+ goto error_free_sym;
+ elf_sym_hashes (abfd) = sym_hash;
+ }
+
+ if (dynamic)
+ {
+ /* Read in any version definitions. */
+ if (! _bfd_elf_slurp_version_tables (abfd))
+ goto error_free_sym;
+
+ /* Read in the symbol versions, but don't bother to convert them
+ to internal format. */
+ if (elf_dynversym (abfd) != 0)
+ {
+ Elf_Internal_Shdr *versymhdr;
+
+ versymhdr = &elf_tdata (abfd)->dynversym_hdr;
+ extversym = bfd_malloc (versymhdr->sh_size);
+ if (extversym == NULL)
+ goto error_free_sym;
+ amt = versymhdr->sh_size;
+ if (bfd_seek (abfd, versymhdr->sh_offset, SEEK_SET) != 0
+ || bfd_bread (extversym, amt, abfd) != amt)
+ goto error_free_vers;
+ }
+ }
+
+ weaks = NULL;
+
+ ever = extversym != NULL ? extversym + extsymoff : NULL;
+ for (isym = isymbuf, isymend = isymbuf + extsymcount;
+ isym < isymend;
+ isym++, sym_hash++, ever = (ever != NULL ? ever + 1 : NULL))
+ {
+ int bind;
+ bfd_vma value;
+ asection *sec;
+ flagword flags;
+ const char *name;
+ struct elf_link_hash_entry *h;
+ bfd_boolean definition;
+ bfd_boolean size_change_ok;
+ bfd_boolean type_change_ok;
+ bfd_boolean new_weakdef;
+ bfd_boolean override;
+ unsigned int old_alignment;
+ bfd *old_bfd;
+
+ override = FALSE;
+
+ flags = BSF_NO_FLAGS;
+ sec = NULL;
+ value = isym->st_value;
+ *sym_hash = NULL;
+
+ bind = ELF_ST_BIND (isym->st_info);
+ if (bind == STB_LOCAL)
+ {
+ /* This should be impossible, since ELF requires that all
+ global symbols follow all local symbols, and that sh_info
+ point to the first global symbol. Unfortunately, Irix 5
+ screws this up. */
+ continue;
+ }
+ else if (bind == STB_GLOBAL)
+ {
+ if (isym->st_shndx != SHN_UNDEF
+ && isym->st_shndx != SHN_COMMON)
+ flags = BSF_GLOBAL;
+ }
+ else if (bind == STB_WEAK)
+ flags = BSF_WEAK;
+ else
+ {
+ /* Leave it up to the processor backend. */
+ }
+
+ if (isym->st_shndx == SHN_UNDEF)
+ sec = bfd_und_section_ptr;
+ else if (isym->st_shndx < SHN_LORESERVE || isym->st_shndx > SHN_HIRESERVE)
+ {
+ sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
+ if (sec == NULL)
+ sec = bfd_abs_section_ptr;
+ else if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
+ value -= sec->vma;
+ }
+ else if (isym->st_shndx == SHN_ABS)
+ sec = bfd_abs_section_ptr;
+ else if (isym->st_shndx == SHN_COMMON)
+ {
+ sec = bfd_com_section_ptr;
+ /* What ELF calls the size we call the value. What ELF
+ calls the value we call the alignment. */
+ value = isym->st_size;
+ }
+ else
+ {
+ /* Leave it up to the processor backend. */
+ }
+
+ name = bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
+ isym->st_name);
+ if (name == NULL)
+ goto error_free_vers;
+
+ if (isym->st_shndx == SHN_COMMON
+ && ELF_ST_TYPE (isym->st_info) == STT_TLS)
+ {
+ asection *tcomm = bfd_get_section_by_name (abfd, ".tcommon");
+
+ if (tcomm == NULL)
+ {
+ tcomm = bfd_make_section (abfd, ".tcommon");
+ if (tcomm == NULL
+ || !bfd_set_section_flags (abfd, tcomm, (SEC_ALLOC
+ | SEC_IS_COMMON
+ | SEC_LINKER_CREATED
+ | SEC_THREAD_LOCAL)))
+ goto error_free_vers;
+ }
+ sec = tcomm;
+ }
+ else if (add_symbol_hook)
+ {
+ if (! (*add_symbol_hook) (abfd, info, isym, &name, &flags, &sec,
+ &value))
+ goto error_free_vers;
+
+ /* The hook function sets the name to NULL if this symbol
+ should be skipped for some reason. */
+ if (name == NULL)
+ continue;
+ }
+
+ /* Sanity check that all possibilities were handled. */
+ if (sec == NULL)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ goto error_free_vers;
+ }
+
+ if (bfd_is_und_section (sec)
+ || bfd_is_com_section (sec))
+ definition = FALSE;
+ else
+ definition = TRUE;
+
+ size_change_ok = FALSE;
+ type_change_ok = get_elf_backend_data (abfd)->type_change_ok;
+ old_alignment = 0;
+ old_bfd = NULL;
+
+ if (is_elf_hash_table (hash_table))
+ {
+ Elf_Internal_Versym iver;
+ unsigned int vernum = 0;
+ bfd_boolean skip;
+
+ if (ever != NULL)
+ {
+ _bfd_elf_swap_versym_in (abfd, ever, &iver);
+ vernum = iver.vs_vers & VERSYM_VERSION;
+
+ /* If this is a hidden symbol, or if it is not version
+ 1, we append the version name to the symbol name.
+ However, we do not modify a non-hidden absolute
+ symbol, because it might be the version symbol
+ itself. FIXME: What if it isn't? */
+ if ((iver.vs_vers & VERSYM_HIDDEN) != 0
+ || (vernum > 1 && ! bfd_is_abs_section (sec)))
+ {
+ const char *verstr;
+ size_t namelen, verlen, newlen;
+ char *newname, *p;
+
+ if (isym->st_shndx != SHN_UNDEF)
+ {
+ if (vernum > elf_tdata (abfd)->dynverdef_hdr.sh_info)
+ {
+ (*_bfd_error_handler)
+ (_("%s: %s: invalid version %u (max %d)"),
+ bfd_archive_filename (abfd), name, vernum,
+ elf_tdata (abfd)->dynverdef_hdr.sh_info);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_free_vers;
+ }
+ else if (vernum > 1)
+ verstr =
+ elf_tdata (abfd)->verdef[vernum - 1].vd_nodename;
+ else
+ verstr = "";
+ }
+ else
+ {
+ /* We cannot simply test for the number of
+ entries in the VERNEED section since the
+ numbers for the needed versions do not start
+ at 0. */
+ Elf_Internal_Verneed *t;
+
+ verstr = NULL;
+ for (t = elf_tdata (abfd)->verref;
+ t != NULL;
+ t = t->vn_nextref)
+ {
+ Elf_Internal_Vernaux *a;
+
+ for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
+ {
+ if (a->vna_other == vernum)
+ {
+ verstr = a->vna_nodename;
+ break;
+ }
+ }
+ if (a != NULL)
+ break;
+ }
+ if (verstr == NULL)
+ {
+ (*_bfd_error_handler)
+ (_("%s: %s: invalid needed version %d"),
+ bfd_archive_filename (abfd), name, vernum);
+ bfd_set_error (bfd_error_bad_value);
+ goto error_free_vers;
+ }
+ }
+
+ namelen = strlen (name);
+ verlen = strlen (verstr);
+ newlen = namelen + verlen + 2;
+ if ((iver.vs_vers & VERSYM_HIDDEN) == 0
+ && isym->st_shndx != SHN_UNDEF)
+ ++newlen;
+
+ newname = bfd_alloc (abfd, newlen);
+ if (newname == NULL)
+ goto error_free_vers;
+ memcpy (newname, name, namelen);
+ p = newname + namelen;
+ *p++ = ELF_VER_CHR;
+ /* If this is a defined non-hidden version symbol,
+ we add another @ to the name. This indicates the
+ default version of the symbol. */
+ if ((iver.vs_vers & VERSYM_HIDDEN) == 0
+ && isym->st_shndx != SHN_UNDEF)
+ *p++ = ELF_VER_CHR;
+ memcpy (p, verstr, verlen + 1);
+
+ name = newname;
+ }
+ }
+
+ if (!_bfd_elf_merge_symbol (abfd, info, name, isym, &sec, &value,
+ sym_hash, &skip, &override,
+ &type_change_ok, &size_change_ok))
+ goto error_free_vers;
+
+ if (skip)
+ continue;
+
+ if (override)
+ definition = FALSE;
+
+ h = *sym_hash;
+ 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;
+
+ /* Remember the old alignment if this is a common symbol, so
+ that we don't reduce the alignment later on. We can't
+ check later, because _bfd_generic_link_add_one_symbol
+ will set a default for the alignment which we want to
+ override. We also remember the old bfd where the existing
+ definition comes from. */
+ switch (h->root.type)
+ {
+ default:
+ break;
+
+ case bfd_link_hash_defined:
+ case bfd_link_hash_defweak:
+ old_bfd = h->root.u.def.section->owner;
+ break;
+
+ case bfd_link_hash_common:
+ old_bfd = h->root.u.c.p->section->owner;
+ old_alignment = h->root.u.c.p->alignment_power;
+ break;
+ }
+
+ if (elf_tdata (abfd)->verdef != NULL
+ && ! override
+ && vernum > 1
+ && definition)
+ h->verinfo.verdef = &elf_tdata (abfd)->verdef[vernum - 1];
+ }
+
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, abfd, name, flags, sec, value, NULL, FALSE, collect,
+ (struct bfd_link_hash_entry **) sym_hash)))
+ goto error_free_vers;
+
+ h = *sym_hash;
+ 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;
+ *sym_hash = h;
+
+ new_weakdef = FALSE;
+ if (dynamic
+ && definition
+ && (flags & BSF_WEAK) != 0
+ && ELF_ST_TYPE (isym->st_info) != STT_FUNC
+ && is_elf_hash_table (hash_table)
+ && h->weakdef == NULL)
+ {
+ /* Keep a list of all weak defined non function symbols from
+ a dynamic object, using the weakdef field. Later in this
+ function we will set the weakdef field to the correct
+ value. We only put non-function symbols from dynamic
+ objects on this list, because that happens to be the only
+ time we need to know the normal symbol corresponding to a
+ weak symbol, and the information is time consuming to
+ figure out. If the weakdef field is not already NULL,
+ then this symbol was already defined by some previous
+ dynamic object, and we will be using that previous
+ definition anyhow. */
+
+ h->weakdef = weaks;
+ weaks = h;
+ new_weakdef = TRUE;
+ }
+
+ /* Set the alignment of a common symbol. */
+ if (isym->st_shndx == SHN_COMMON
+ && h->root.type == bfd_link_hash_common)
+ {
+ unsigned int align;
+
+ align = bfd_log2 (isym->st_value);
+ if (align > old_alignment
+ /* Permit an alignment power of zero if an alignment of one
+ is specified and no other alignments have been specified. */
+ || (isym->st_value == 1 && old_alignment == 0))
+ h->root.u.c.p->alignment_power = align;
+ else
+ h->root.u.c.p->alignment_power = old_alignment;
+ }
+
+ if (is_elf_hash_table (hash_table))
+ {
+ int old_flags;
+ bfd_boolean dynsym;
+ int new_flag;
+
+ /* Check the alignment when a common symbol is involved. This
+ can change when a common symbol is overridden by a normal
+ definition or a common symbol is ignored due to the old
+ normal definition. We need to make sure the maximum
+ alignment is maintained. */
+ if ((old_alignment || isym->st_shndx == SHN_COMMON)
+ && h->root.type != bfd_link_hash_common)
+ {
+ unsigned int common_align;
+ unsigned int normal_align;
+ unsigned int symbol_align;
+ bfd *normal_bfd;
+ bfd *common_bfd;
+
+ symbol_align = ffs (h->root.u.def.value) - 1;
+ if (h->root.u.def.section->owner != NULL
+ && (h->root.u.def.section->owner->flags & DYNAMIC) == 0)
+ {
+ normal_align = h->root.u.def.section->alignment_power;
+ if (normal_align > symbol_align)
+ normal_align = symbol_align;
+ }
+ else
+ normal_align = symbol_align;
+
+ if (old_alignment)
+ {
+ common_align = old_alignment;
+ common_bfd = old_bfd;
+ normal_bfd = abfd;
+ }
+ else
+ {
+ common_align = bfd_log2 (isym->st_value);
+ common_bfd = abfd;
+ normal_bfd = old_bfd;
+ }
+
+ if (normal_align < common_align)
+ (*_bfd_error_handler)
+ (_("Warning: alignment %u of symbol `%s' in %s is smaller than %u in %s"),
+ 1 << normal_align,
+ name,
+ bfd_archive_filename (normal_bfd),
+ 1 << common_align,
+ bfd_archive_filename (common_bfd));
+ }
+
+ /* Remember the symbol size and type. */
+ if (isym->st_size != 0
+ && (definition || h->size == 0))
+ {
+ if (h->size != 0 && h->size != isym->st_size && ! size_change_ok)
+ (*_bfd_error_handler)
+ (_("Warning: size of symbol `%s' changed from %lu in %s to %lu in %s"),
+ name, (unsigned long) h->size,
+ bfd_archive_filename (old_bfd),
+ (unsigned long) isym->st_size,
+ bfd_archive_filename (abfd));
+
+ h->size = isym->st_size;
+ }
+
+ /* If this is a common symbol, then we always want H->SIZE
+ to be the size of the common symbol. The code just above
+ won't fix the size if a common symbol becomes larger. We
+ don't warn about a size change here, because that is
+ covered by --warn-common. */
+ if (h->root.type == bfd_link_hash_common)
+ h->size = h->root.u.c.size;
+
+ if (ELF_ST_TYPE (isym->st_info) != STT_NOTYPE
+ && (definition || h->type == STT_NOTYPE))
+ {
+ if (h->type != STT_NOTYPE
+ && h->type != ELF_ST_TYPE (isym->st_info)
+ && ! type_change_ok)
+ (*_bfd_error_handler)
+ (_("Warning: type of symbol `%s' changed from %d to %d in %s"),
+ name, h->type, ELF_ST_TYPE (isym->st_info),
+ bfd_archive_filename (abfd));
+
+ h->type = ELF_ST_TYPE (isym->st_info);
+ }
+
+ /* If st_other has a processor-specific meaning, specific
+ code might be needed here. We never merge the visibility
+ attribute with the one from a dynamic object. */
+ if (bed->elf_backend_merge_symbol_attribute)
+ (*bed->elf_backend_merge_symbol_attribute) (h, isym, definition,
+ dynamic);
+
+ if (isym->st_other != 0 && !dynamic)
+ {
+ unsigned char hvis, symvis, other, nvis;
+
+ /* Take the balance of OTHER from the definition. */
+ other = (definition ? isym->st_other : h->other);
+ other &= ~ ELF_ST_VISIBILITY (-1);
+
+ /* Combine visibilities, using the most constraining one. */
+ hvis = ELF_ST_VISIBILITY (h->other);
+ symvis = ELF_ST_VISIBILITY (isym->st_other);
+ if (! hvis)
+ nvis = symvis;
+ else if (! symvis)
+ nvis = hvis;
+ else
+ nvis = hvis < symvis ? hvis : symvis;
+
+ h->other = other | nvis;
+ }
+
+ /* Set a flag in the hash table entry indicating the type of
+ reference or definition we just found. Keep a count of
+ the number of dynamic symbols we find. A dynamic symbol
+ is one which is referenced or defined by both a regular
+ object and a shared object. */
+ old_flags = h->elf_link_hash_flags;
+ dynsym = FALSE;
+ if (! dynamic)
+ {
+ if (! definition)
+ {
+ new_flag = ELF_LINK_HASH_REF_REGULAR;
+ if (bind != STB_WEAK)
+ new_flag |= ELF_LINK_HASH_REF_REGULAR_NONWEAK;
+ }
+ else
+ new_flag = ELF_LINK_HASH_DEF_REGULAR;
+ if (! info->executable
+ || (old_flags & (ELF_LINK_HASH_DEF_DYNAMIC
+ | ELF_LINK_HASH_REF_DYNAMIC)) != 0)
+ dynsym = TRUE;
+ }
+ else
+ {
+ if (! definition)
+ new_flag = ELF_LINK_HASH_REF_DYNAMIC;
+ else
+ new_flag = ELF_LINK_HASH_DEF_DYNAMIC;
+ if ((old_flags & (ELF_LINK_HASH_DEF_REGULAR
+ | ELF_LINK_HASH_REF_REGULAR)) != 0
+ || (h->weakdef != NULL
+ && ! new_weakdef
+ && h->weakdef->dynindx != -1))
+ dynsym = TRUE;
+ }
+
+ h->elf_link_hash_flags |= new_flag;
+
+ /* Check to see if we need to add an indirect symbol for
+ the default name. */
+ if (definition || h->root.type == bfd_link_hash_common)
+ if (!_bfd_elf_add_default_symbol (abfd, info, h, name, isym,
+ &sec, &value, &dynsym,
+ override))
+ goto error_free_vers;
+
+ if (definition && !dynamic)
+ {
+ char *p = strchr (name, ELF_VER_CHR);
+ if (p != NULL && p[1] != ELF_VER_CHR)
+ {
+ /* Queue non-default versions so that .symver x, x@FOO
+ aliases can be checked. */
+ if (! nondeflt_vers)
+ {
+ amt = (isymend - isym + 1)
+ * sizeof (struct elf_link_hash_entry *);
+ nondeflt_vers = bfd_malloc (amt);
+ }
+ nondeflt_vers [nondeflt_vers_cnt++] = h;
+ }
+ }
+
+ if (dynsym && h->dynindx == -1)
+ {
+ 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))
+ goto error_free_vers;
+ }
+ }
+ else if (dynsym && h->dynindx != -1)
+ /* If the symbol already has a dynamic index, but
+ visibility says it should not be visible, turn it into
+ a local symbol. */
+ switch (ELF_ST_VISIBILITY (h->other))
+ {
+ case STV_INTERNAL:
+ case STV_HIDDEN:
+ (*bed->elf_backend_hide_symbol) (info, h, TRUE);
+ dynsym = FALSE;
+ break;
+ }
+
+ if (!add_needed
+ && definition
+ && dynsym
+ && (h->elf_link_hash_flags
+ & ELF_LINK_HASH_REF_REGULAR) != 0)
+ {
+ int ret;
+ const char *soname = elf_dt_name (abfd);
+
+ /* A symbol from a library loaded via DT_NEEDED of some
+ other library is referenced by a regular object.
+ Add a DT_NEEDED entry for it. */
+ add_needed = TRUE;
+ ret = elf_add_dt_needed_tag (info, soname, add_needed);
+ if (ret < 0)
+ goto error_free_vers;
+
+ BFD_ASSERT (ret == 0);
+ }
+ }
+ }
+
+ /* Now that all the symbols from this input file are created, handle
+ .symver foo, foo@BAR such that any relocs against foo become foo@BAR. */
+ if (nondeflt_vers != NULL)
+ {
+ bfd_size_type cnt, symidx;
+
+ for (cnt = 0; cnt < nondeflt_vers_cnt; ++cnt)
+ {
+ struct elf_link_hash_entry *h = nondeflt_vers[cnt], *hi;
+ char *shortname, *p;
+
+ p = strchr (h->root.root.string, ELF_VER_CHR);
+ if (p == NULL
+ || (h->root.type != bfd_link_hash_defined
+ && h->root.type != bfd_link_hash_defweak))
+ continue;
+
+ amt = p - h->root.root.string;
+ shortname = bfd_malloc (amt + 1);
+ memcpy (shortname, h->root.root.string, amt);
+ shortname[amt] = '\0';
+
+ hi = (struct elf_link_hash_entry *)
+ bfd_link_hash_lookup (&hash_table->root, shortname,
+ FALSE, FALSE, FALSE);
+ if (hi != NULL
+ && hi->root.type == h->root.type
+ && hi->root.u.def.value == h->root.u.def.value
+ && hi->root.u.def.section == h->root.u.def.section)
+ {
+ (*bed->elf_backend_hide_symbol) (info, hi, TRUE);
+ hi->root.type = bfd_link_hash_indirect;
+ hi->root.u.i.link = (struct bfd_link_hash_entry *) h;
+ (*bed->elf_backend_copy_indirect_symbol) (bed, h, hi);
+ sym_hash = elf_sym_hashes (abfd);
+ if (sym_hash)
+ for (symidx = 0; symidx < extsymcount; ++symidx)
+ if (sym_hash[symidx] == hi)
+ {
+ sym_hash[symidx] = h;
+ break;
+ }
+ }
+ free (shortname);
+ }
+ free (nondeflt_vers);
+ nondeflt_vers = NULL;
+ }
+
+ if (extversym != NULL)
+ {
+ free (extversym);
+ extversym = NULL;
+ }
+
+ if (isymbuf != NULL)
+ free (isymbuf);
+ isymbuf = NULL;
+
+ /* Now set the weakdefs field correctly for all the weak defined
+ symbols we found. The only way to do this is to search all the
+ symbols. Since we only need the information for non functions in
+ dynamic objects, that's the only time we actually put anything on
+ the list WEAKS. We need this information so that if a regular
+ object refers to a symbol defined weakly in a dynamic object, the
+ real symbol in the dynamic object is also put in the dynamic
+ symbols; we also must arrange for both symbols to point to the
+ same memory location. We could handle the general case of symbol
+ aliasing, but a general symbol alias can only be generated in
+ assembler code, handling it correctly would be very time
+ consuming, and other ELF linkers don't handle general aliasing
+ either. */
+ if (weaks != NULL)
+ {
+ struct elf_link_hash_entry **hpp;
+ struct elf_link_hash_entry **hppend;
+ struct elf_link_hash_entry **sorted_sym_hash;
+ struct elf_link_hash_entry *h;
+ size_t sym_count;
+
+ /* Since we have to search the whole symbol list for each weak
+ defined symbol, search time for N weak defined symbols will be
+ O(N^2). Binary search will cut it down to O(NlogN). */
+ amt = extsymcount * sizeof (struct elf_link_hash_entry *);
+ sorted_sym_hash = bfd_malloc (amt);
+ if (sorted_sym_hash == NULL)
+ goto error_return;
+ sym_hash = sorted_sym_hash;
+ hpp = elf_sym_hashes (abfd);
+ hppend = hpp + extsymcount;
+ sym_count = 0;
+ for (; hpp < hppend; hpp++)
+ {
+ h = *hpp;
+ if (h != NULL
+ && h->root.type == bfd_link_hash_defined
+ && h->type != STT_FUNC)
+ {
+ *sym_hash = h;
+ sym_hash++;
+ sym_count++;
+ }
+ }
+
+ qsort (sorted_sym_hash, sym_count,
+ sizeof (struct elf_link_hash_entry *),
+ elf_sort_symbol);
+
+ while (weaks != NULL)
+ {
+ struct elf_link_hash_entry *hlook;
+ asection *slook;
+ bfd_vma vlook;
+ long ilook;
+ size_t i, j, idx;
+
+ hlook = weaks;
+ weaks = hlook->weakdef;
+ hlook->weakdef = NULL;
+
+ BFD_ASSERT (hlook->root.type == bfd_link_hash_defined
+ || hlook->root.type == bfd_link_hash_defweak
+ || hlook->root.type == bfd_link_hash_common
+ || hlook->root.type == bfd_link_hash_indirect);
+ slook = hlook->root.u.def.section;
+ vlook = hlook->root.u.def.value;
+
+ ilook = -1;
+ i = 0;
+ j = sym_count;
+ while (i < j)
+ {
+ bfd_signed_vma vdiff;
+ idx = (i + j) / 2;
+ h = sorted_sym_hash [idx];
+ vdiff = vlook - h->root.u.def.value;
+ if (vdiff < 0)
+ j = idx;
+ else if (vdiff > 0)
+ i = idx + 1;
+ else
+ {
+ long sdiff = slook - h->root.u.def.section;
+ if (sdiff < 0)
+ j = idx;
+ else if (sdiff > 0)
+ i = idx + 1;
+ else
+ {
+ ilook = idx;
+ break;
+ }
+ }
+ }
+
+ /* We didn't find a value/section match. */
+ if (ilook == -1)
+ continue;
+
+ for (i = ilook; i < sym_count; i++)
+ {
+ h = sorted_sym_hash [i];
+
+ /* Stop if value or section doesn't match. */
+ if (h->root.u.def.value != vlook
+ || h->root.u.def.section != slook)
+ break;
+ else if (h != hlook)
+ {
+ hlook->weakdef = h;
+
+ /* If the weak definition is in the list of dynamic
+ symbols, make sure the real definition is put
+ there as well. */
+ if (hlook->dynindx != -1 && h->dynindx == -1)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ goto error_return;
+ }
+
+ /* If the real definition is in the list of dynamic
+ symbols, make sure the weak definition is put
+ there as well. If we don't do this, then the
+ dynamic loader might not merge the entries for the
+ real definition and the weak definition. */
+ if (h->dynindx != -1 && hlook->dynindx == -1)
+ {
+ if (! bfd_elf_link_record_dynamic_symbol (info, hlook))
+ goto error_return;
+ }
+ break;
+ }
+ }
+ }
+
+ free (sorted_sym_hash);
+ }
+
+ /* If this object is the same format as the output object, and it is
+ not a shared library, then let the backend look through the
+ relocs.
+
+ This is required to build global offset table entries and to
+ arrange for dynamic relocs. It is not required for the
+ particular common case of linking non PIC code, even when linking
+ against shared libraries, but unfortunately there is no way of
+ knowing whether an object file has been compiled PIC or not.
+ Looking through the relocs is not particularly time consuming.
+ The problem is that we must either (1) keep the relocs in memory,
+ which causes the linker to require additional runtime memory or
+ (2) read the relocs twice from the input file, which wastes time.
+ This would be a good case for using mmap.
+
+ I have no idea how to handle linking PIC code into a file of a
+ different format. It probably can't be done. */
+ check_relocs = get_elf_backend_data (abfd)->check_relocs;
+ if (! dynamic
+ && is_elf_hash_table (hash_table)
+ && hash_table->root.creator == abfd->xvec
+ && check_relocs != NULL)
+ {
+ asection *o;
+
+ for (o = abfd->sections; o != NULL; o = o->next)
+ {
+ Elf_Internal_Rela *internal_relocs;
+ bfd_boolean ok;
+
+ if ((o->flags & SEC_RELOC) == 0
+ || o->reloc_count == 0
+ || ((info->strip == strip_all || info->strip == strip_debugger)
+ && (o->flags & SEC_DEBUGGING) != 0)
+ || bfd_is_abs_section (o->output_section))
+ continue;
+
+ internal_relocs = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL,
+ info->keep_memory);
+ if (internal_relocs == NULL)
+ goto error_return;
+
+ ok = (*check_relocs) (abfd, info, o, internal_relocs);
+
+ if (elf_section_data (o)->relocs != internal_relocs)
+ free (internal_relocs);
+
+ if (! ok)
+ goto error_return;
+ }
+ }
+
+ /* If this is a non-traditional link, try to optimize the handling
+ of the .stab/.stabstr sections. */
+ if (! dynamic
+ && ! info->traditional_format
+ && is_elf_hash_table (hash_table)
+ && (info->strip != strip_all && info->strip != strip_debugger))
+ {
+ asection *stabstr;
+
+ stabstr = bfd_get_section_by_name (abfd, ".stabstr");
+ if (stabstr != NULL)
+ {
+ bfd_size_type string_offset = 0;
+ asection *stab;
+
+ for (stab = abfd->sections; stab; stab = stab->next)
+ if (strncmp (".stab", stab->name, 5) == 0
+ && (!stab->name[5] ||
+ (stab->name[5] == '.' && ISDIGIT (stab->name[6])))
+ && (stab->flags & SEC_MERGE) == 0
+ && !bfd_is_abs_section (stab->output_section))
+ {
+ struct bfd_elf_section_data *secdata;
+
+ secdata = elf_section_data (stab);
+ if (! _bfd_link_section_stabs (abfd,
+ & hash_table->stab_info,
+ stab, stabstr,
+ &secdata->sec_info,
+ &string_offset))
+ goto error_return;
+ if (secdata->sec_info)
+ stab->sec_info_type = ELF_INFO_TYPE_STABS;
+ }
+ }
+ }
+
+ if (! info->relocatable
+ && ! dynamic
+ && is_elf_hash_table (hash_table))
+ {
+ asection *s;
+
+ for (s = abfd->sections; s != NULL; s = s->next)
+ if ((s->flags & SEC_MERGE) != 0
+ && !bfd_is_abs_section (s->output_section))
+ {
+ struct bfd_elf_section_data *secdata;
+
+ secdata = elf_section_data (s);
+ if (! _bfd_merge_section (abfd,
+ & hash_table->merge_info,
+ s, &secdata->sec_info))
+ goto error_return;
+ else if (secdata->sec_info)
+ s->sec_info_type = ELF_INFO_TYPE_MERGE;
+ }
+ }
+
+ if (is_elf_hash_table (hash_table))
+ {
+ /* Add this bfd to the loaded list. */
+ struct elf_link_loaded_list *n;
+
+ n = bfd_alloc (abfd, sizeof (struct elf_link_loaded_list));
+ if (n == NULL)
+ goto error_return;
+ n->abfd = abfd;
+ n->next = hash_table->loaded;
+ hash_table->loaded = n;
+ }
+
+ return TRUE;
+
+ error_free_vers:
+ if (nondeflt_vers != NULL)
+ free (nondeflt_vers);
+ if (extversym != NULL)
+ free (extversym);
+ error_free_sym:
+ if (isymbuf != NULL)
+ free (isymbuf);
+ error_return:
+ return FALSE;
+}
+
+/* Add symbols from an ELF archive file to the linker hash table. We
+ don't use _bfd_generic_link_add_archive_symbols because of a
+ problem which arises on UnixWare. The UnixWare libc.so is an
+ archive which includes an entry libc.so.1 which defines a bunch of
+ symbols. The libc.so archive also includes a number of other
+ object files, which also define symbols, some of which are the same
+ as those defined in libc.so.1. Correct linking requires that we
+ consider each object file in turn, and include it if it defines any
+ symbols we need. _bfd_generic_link_add_archive_symbols does not do
+ this; it looks through the list of undefined symbols, and includes
+ any object file which defines them. When this algorithm is used on
+ UnixWare, it winds up pulling in libc.so.1 early and defining a
+ bunch of symbols. This means that some of the other objects in the
+ archive are not included in the link, which is incorrect since they
+ precede libc.so.1 in the archive.
+
+ Fortunately, ELF archive handling is simpler than that done by
+ _bfd_generic_link_add_archive_symbols, which has to allow for a.out
+ oddities. In ELF, if we find a symbol in the archive map, and the
+ symbol is currently undefined, we know that we must pull in that
+ object file.
+
+ Unfortunately, we do have to make multiple passes over the symbol
+ table until nothing further is resolved. */
+
+static bfd_boolean
+elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
+{
+ symindex c;
+ bfd_boolean *defined = NULL;
+ bfd_boolean *included = NULL;
+ carsym *symdefs;
+ bfd_boolean loop;
+ bfd_size_type amt;
+
+ if (! bfd_has_map (abfd))
+ {
+ /* An empty archive is a special case. */
+ if (bfd_openr_next_archived_file (abfd, NULL) == NULL)
+ return TRUE;
+ bfd_set_error (bfd_error_no_armap);
+ return FALSE;
+ }
+
+ /* Keep track of all symbols we know to be already defined, and all
+ files we know to be already included. This is to speed up the
+ second and subsequent passes. */
+ c = bfd_ardata (abfd)->symdef_count;
+ if (c == 0)
+ return TRUE;
+ amt = c;
+ amt *= sizeof (bfd_boolean);
+ defined = bfd_zmalloc (amt);
+ included = bfd_zmalloc (amt);
+ if (defined == NULL || included == NULL)
+ goto error_return;
+
+ symdefs = bfd_ardata (abfd)->symdefs;
+
+ do
+ {
+ file_ptr last;
+ symindex i;
+ carsym *symdef;
+ carsym *symdefend;
+
+ loop = FALSE;
+ last = -1;
+
+ symdef = symdefs;
+ symdefend = symdef + c;
+ for (i = 0; symdef < symdefend; symdef++, i++)
+ {
+ struct elf_link_hash_entry *h;
+ bfd *element;
+ struct bfd_link_hash_entry *undefs_tail;
+ symindex mark;
+
+ if (defined[i] || included[i])
+ continue;
+ if (symdef->file_offset == last)
+ {
+ included[i] = TRUE;
+ continue;
+ }
+
+ h = elf_link_hash_lookup (elf_hash_table (info), symdef->name,
+ FALSE, FALSE, FALSE);
+
+ if (h == NULL)
+ {
+ char *p, *copy;
+ size_t len, first;
+
+ /* If this is a default version (the name contains @@),
+ look up the symbol again with only one `@' as well
+ as without the version. The effect is that references
+ to the symbol with and without the version will be
+ matched by the default symbol in the archive. */
+
+ p = strchr (symdef->name, ELF_VER_CHR);
+ if (p == NULL || p[1] != ELF_VER_CHR)
+ continue;
+
+ /* First check with only one `@'. */
+ len = strlen (symdef->name);
+ copy = bfd_alloc (abfd, len);
+ if (copy == NULL)
+ goto error_return;
+ first = p - symdef->name + 1;
+ memcpy (copy, symdef->name, first);
+ memcpy (copy + first, symdef->name + first + 1, len - first);
+
+ h = elf_link_hash_lookup (elf_hash_table (info), copy,
+ FALSE, FALSE, FALSE);
+
+ if (h == NULL)
+ {
+ /* We also need to check references to the symbol
+ without the version. */
+
+ copy[first - 1] = '\0';
+ h = elf_link_hash_lookup (elf_hash_table (info),
+ copy, FALSE, FALSE, FALSE);
+ }
+
+ bfd_release (abfd, copy);
+ }
+
+ if (h == NULL)
+ continue;
+
+ if (h->root.type == bfd_link_hash_common)
+ {
+ /* We currently have a common symbol. The archive map contains
+ a reference to this symbol, so we may want to include it. We
+ only want to include it however, if this archive element
+ contains a definition of the symbol, not just another common
+ declaration of it.
+
+ Unfortunately some archivers (including GNU ar) will put
+ declarations of common symbols into their archive maps, as
+ well as real definitions, so we cannot just go by the archive
+ map alone. Instead we must read in the element's symbol
+ table and check that to see what kind of symbol definition
+ this is. */
+ if (! elf_link_is_defined_archive_symbol (abfd, symdef))
+ continue;
+ }
+ else if (h->root.type != bfd_link_hash_undefined)
+ {
+ if (h->root.type != bfd_link_hash_undefweak)
+ defined[i] = TRUE;
+ continue;
+ }
+
+ /* We need to include this archive member. */
+ element = _bfd_get_elt_at_filepos (abfd, symdef->file_offset);
+ if (element == NULL)
+ goto error_return;
+
+ if (! bfd_check_format (element, bfd_object))
+ goto error_return;
+
+ /* Doublecheck that we have not included this object
+ already--it should be impossible, but there may be
+ something wrong with the archive. */
+ if (element->archive_pass != 0)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ goto error_return;
+ }
+ element->archive_pass = 1;
+
+ undefs_tail = info->hash->undefs_tail;
+
+ if (! (*info->callbacks->add_archive_element) (info, element,
+ symdef->name))
+ goto error_return;
+ if (! bfd_link_add_symbols (element, info))
+ goto error_return;
+
+ /* If there are any new undefined symbols, we need to make
+ another pass through the archive in order to see whether
+ they can be defined. FIXME: This isn't perfect, because
+ common symbols wind up on undefs_tail and because an
+ undefined symbol which is defined later on in this pass
+ does not require another pass. This isn't a bug, but it
+ does make the code less efficient than it could be. */
+ if (undefs_tail != info->hash->undefs_tail)
+ loop = TRUE;
+
+ /* Look backward to mark all symbols from this object file
+ which we have already seen in this pass. */
+ mark = i;
+ do
+ {
+ included[mark] = TRUE;
+ if (mark == 0)
+ break;
+ --mark;
+ }
+ while (symdefs[mark].file_offset == symdef->file_offset);
+
+ /* We mark subsequent symbols from this object file as we go
+ on through the loop. */
+ last = symdef->file_offset;
+ }
+ }
+ while (loop);
+
+ free (defined);
+ free (included);
+
+ return TRUE;
+
+ error_return:
+ if (defined != NULL)
+ free (defined);
+ if (included != NULL)
+ free (included);
+ return FALSE;
+}
+
+/* Given an ELF BFD, add symbols to the global hash table as
+ appropriate. */
+
+bfd_boolean
+bfd_elf_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
+{
+ switch (bfd_get_format (abfd))
+ {
+ case bfd_object:
+ return elf_link_add_object_symbols (abfd, info);
+ case bfd_archive:
+ return elf_link_add_archive_symbols (abfd, info);
+ default:
+ bfd_set_error (bfd_error_wrong_format);
+ return FALSE;
+ }
+}
+
+/* This function will be called though elf_link_hash_traverse to store
+ all hash value of the exported symbols in an array. */
+
+static bfd_boolean
+elf_collect_hash_codes (struct elf_link_hash_entry *h, void *data)
+{
+ unsigned long **valuep = data;
+ const char *name;
+ char *p;
+ unsigned long ha;
+ char *alc = NULL;
+
+ if (h->root.type == bfd_link_hash_warning)
+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
+
+ /* Ignore indirect symbols. These are added by the versioning code. */
+ if (h->dynindx == -1)
+ return TRUE;
+
+ name = h->root.root.string;
+ p = strchr (name, ELF_VER_CHR);
+ if (p != NULL)
+ {
+ alc = bfd_malloc (p - name + 1);
+ memcpy (alc, name, p - name);
+ alc[p - name] = '\0';
+ name = alc;
+ }
+
+ /* Compute the hash value. */
+ ha = bfd_elf_hash (name);
+
+ /* Store the found hash value in the array given as the argument. */
+ *(*valuep)++ = ha;
+
+ /* And store it in the struct so that we can put it in the hash table
+ later. */
+ h->elf_hash_value = ha;
+
+ if (alc != NULL)
+ free (alc);
+
+ return TRUE;
+}
+
+/* Array used to determine the number of hash table buckets to use
+ based on the number of symbols there are. If there are fewer than
+ 3 symbols we use 1 bucket, fewer than 17 symbols we use 3 buckets,
+ fewer than 37 we use 17 buckets, and so forth. We never use more
+ than 32771 buckets. */
+
+static const size_t elf_buckets[] =
+{
+ 1, 3, 17, 37, 67, 97, 131, 197, 263, 521, 1031, 2053, 4099, 8209,
+ 16411, 32771, 0
+};
+
+/* Compute bucket count for hashing table. We do not use a static set
+ of possible tables sizes anymore. Instead we determine for all
+ possible reasonable sizes of the table the outcome (i.e., the
+ number of collisions etc) and choose the best solution. The
+ weighting functions are not too simple to allow the table to grow
+ without bounds. Instead one of the weighting factors is the size.
+ Therefore the result is always a good payoff between few collisions
+ (= short chain lengths) and table size. */
+static size_t
+compute_bucket_count (struct bfd_link_info *info)
+{
+ size_t dynsymcount = elf_hash_table (info)->dynsymcount;
+ size_t best_size = 0;
+ unsigned long int *hashcodes;
+ unsigned long int *hashcodesp;
+ unsigned long int i;
+ bfd_size_type amt;
+
+ /* Compute the hash values for all exported symbols. At the same
+ time store the values in an array so that we could use them for
+ optimizations. */
+ amt = dynsymcount;
+ amt *= sizeof (unsigned long int);
+ hashcodes = bfd_malloc (amt);
+ if (hashcodes == NULL)
+ return 0;
+ hashcodesp = hashcodes;
+
+ /* Put all hash values in HASHCODES. */
+ elf_link_hash_traverse (elf_hash_table (info),
+ elf_collect_hash_codes, &hashcodesp);
+
+ /* We have a problem here. The following code to optimize the table
+ size requires an integer type with more the 32 bits. If
+ BFD_HOST_U_64_BIT is set we know about such a type. */
+#ifdef BFD_HOST_U_64_BIT
+ if (info->optimize)
+ {
+ unsigned long int nsyms = hashcodesp - hashcodes;
+ size_t minsize;
+ size_t maxsize;
+ BFD_HOST_U_64_BIT best_chlen = ~((BFD_HOST_U_64_BIT) 0);
+ unsigned long int *counts ;
+ bfd *dynobj = elf_hash_table (info)->dynobj;
+ const struct elf_backend_data *bed = get_elf_backend_data (dynobj);
+
+ /* Possible optimization parameters: if we have NSYMS symbols we say
+ that the hashing table must at least have NSYMS/4 and at most
+ 2*NSYMS buckets. */
+ minsize = nsyms / 4;
+ if (minsize == 0)
+ minsize = 1;
+ best_size = maxsize = nsyms * 2;
+
+ /* Create array where we count the collisions in. We must use bfd_malloc
+ since the size could be large. */
+ amt = maxsize;
+ amt *= sizeof (unsigned long int);
+ counts = bfd_malloc (amt);
+ if (counts == NULL)
+ {
+ free (hashcodes);
+ return 0;
+ }
+
+ /* Compute the "optimal" size for the hash table. The criteria is a
+ minimal chain length. The minor criteria is (of course) the size
+ of the table. */
+ for (i = minsize; i < maxsize; ++i)
+ {
+ /* Walk through the array of hashcodes and count the collisions. */
+ BFD_HOST_U_64_BIT max;
+ unsigned long int j;
+ unsigned long int fact;
+
+ memset (counts, '\0', i * sizeof (unsigned long int));
+
+ /* Determine how often each hash bucket is used. */
+ for (j = 0; j < nsyms; ++j)
+ ++counts[hashcodes[j] % i];
+
+ /* For the weight function we need some information about the
+ pagesize on the target. This is information need not be 100%
+ accurate. Since this information is not available (so far) we
+ define it here to a reasonable default value. If it is crucial
+ to have a better value some day simply define this value. */
+# ifndef BFD_TARGET_PAGESIZE
+# define BFD_TARGET_PAGESIZE (4096)
+# endif
+
+ /* We in any case need 2 + NSYMS entries for the size values and
+ the chains. */
+ max = (2 + nsyms) * (bed->s->arch_size / 8);
+
+# if 1
+ /* Variant 1: optimize for short chains. We add the squares
+ of all the chain lengths (which favors many small chain
+ over a few long chains). */
+ for (j = 0; j < i; ++j)
+ max += counts[j] * counts[j];
+
+ /* This adds penalties for the overall size of the table. */
+ fact = i / (BFD_TARGET_PAGESIZE / (bed->s->arch_size / 8)) + 1;
+ max *= fact * fact;
+# else
+ /* Variant 2: Optimize a lot more for small table. Here we
+ also add squares of the size but we also add penalties for
+ empty slots (the +1 term). */
+ for (j = 0; j < i; ++j)
+ max += (1 + counts[j]) * (1 + counts[j]);
+
+ /* The overall size of the table is considered, but not as
+ strong as in variant 1, where it is squared. */
+ fact = i / (BFD_TARGET_PAGESIZE / (bed->s->arch_size / 8)) + 1;
+ max *= fact;
+# endif
+
+ /* Compare with current best results. */
+ if (max < best_chlen)
+ {
+ best_chlen = max;
+ best_size = i;
+ }
+ }
+
+ free (counts);
+ }
+ else
+#endif /* defined (BFD_HOST_U_64_BIT) */
+ {
+ /* This is the fallback solution if no 64bit type is available or if we
+ are not supposed to spend much time on optimizations. We select the
+ bucket count using a fixed set of numbers. */
+ for (i = 0; elf_buckets[i] != 0; i++)
+ {
+ best_size = elf_buckets[i];
+ if (dynsymcount < elf_buckets[i + 1])
+ break;
+ }
+ }
+
+ /* Free the arrays we needed. */
+ free (hashcodes);
+
+ return best_size;
+}
+
+/* Set up the sizes and contents of the ELF dynamic sections. This is
+ called by the ELF linker emulation before_allocation routine. We
+ must set the sizes of the sections before the linker sets the
+ addresses of the various sections. */
+
+bfd_boolean
+bfd_elf_size_dynamic_sections (bfd *output_bfd,
+ const char *soname,
+ const char *rpath,
+ const char *filter_shlib,
+ const char * const *auxiliary_filters,
+ struct bfd_link_info *info,
+ asection **sinterpptr,
+ struct bfd_elf_version_tree *verdefs)
+{
+ bfd_size_type soname_indx;
+ bfd *dynobj;
+ const struct elf_backend_data *bed;
+ struct elf_assign_sym_version_info asvinfo;
+
+ *sinterpptr = NULL;
+
+ soname_indx = (bfd_size_type) -1;
+
+ if (!is_elf_hash_table (info->hash))
+ return TRUE;
+
+ if (info->execstack)
+ elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | PF_X;
+ else if (info->noexecstack)
+ elf_tdata (output_bfd)->stack_flags = PF_R | PF_W;
+ else
+ {
+ bfd *inputobj;
+ asection *notesec = NULL;
+ int exec = 0;
+
+ for (inputobj = info->input_bfds;
+ inputobj;
+ inputobj = inputobj->link_next)
+ {
+ asection *s;
+
+ if (inputobj->flags & DYNAMIC)
+ continue;
+ s = bfd_get_section_by_name (inputobj, ".note.GNU-stack");
+ if (s)
+ {
+ if (s->flags & SEC_CODE)
+ exec = PF_X;
+ notesec = s;
+ }
+ else
+ exec = PF_X;
+ }
+ if (notesec)
+ {
+ elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | exec;
+ if (exec && info->relocatable
+ && notesec->output_section != bfd_abs_section_ptr)
+ notesec->output_section->flags |= SEC_CODE;
+ }
+ }
+
+ /* Any syms created from now on start with -1 in
+ got.refcount/offset and plt.refcount/offset. */
+ elf_hash_table (info)->init_refcount = elf_hash_table (info)->init_offset;
+
+ /* The backend may have to create some sections regardless of whether
+ we're dynamic or not. */
+ bed = get_elf_backend_data (output_bfd);
+ if (bed->elf_backend_always_size_sections
+ && ! (*bed->elf_backend_always_size_sections) (output_bfd, info))
+ return FALSE;
+
+ dynobj = elf_hash_table (info)->dynobj;
+
+ /* If there were no dynamic objects in the link, there is nothing to
+ do here. */
+ if (dynobj == NULL)
+ return TRUE;
+
+ if (! _bfd_elf_maybe_strip_eh_frame_hdr (info))
+ return FALSE;
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ struct elf_info_failed eif;
+ struct elf_link_hash_entry *h;
+ asection *dynstr;
+ struct bfd_elf_version_tree *t;
+ struct bfd_elf_version_expr *d;
+ bfd_boolean all_defined;
+
+ *sinterpptr = bfd_get_section_by_name (dynobj, ".interp");
+ BFD_ASSERT (*sinterpptr != NULL || !info->executable);
+
+ if (soname != NULL)
+ {
+ soname_indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
+ soname, TRUE);
+ if (soname_indx == (bfd_size_type) -1
+ || !_bfd_elf_add_dynamic_entry (info, DT_SONAME, soname_indx))
+ return FALSE;
+ }
+
+ if (info->symbolic)
+ {
+ if (!_bfd_elf_add_dynamic_entry (info, DT_SYMBOLIC, 0))
+ return FALSE;
+ info->flags |= DF_SYMBOLIC;
+ }
+
+ if (rpath != NULL)
+ {
+ bfd_size_type indx;
+
+ indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, rpath,
+ TRUE);
+ if (indx == (bfd_size_type) -1
+ || !_bfd_elf_add_dynamic_entry (info, DT_RPATH, indx))
+ return FALSE;
+
+ if (info->new_dtags)
+ {
+ _bfd_elf_strtab_addref (elf_hash_table (info)->dynstr, indx);
+ if (!_bfd_elf_add_dynamic_entry (info, DT_RUNPATH, indx))
+ return FALSE;
+ }
+ }
+
+ if (filter_shlib != NULL)
+ {
+ bfd_size_type indx;
+
+ indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
+ filter_shlib, TRUE);
+ if (indx == (bfd_size_type) -1
+ || !_bfd_elf_add_dynamic_entry (info, DT_FILTER, indx))
+ return FALSE;
+ }
+
+ if (auxiliary_filters != NULL)
+ {
+ const char * const *p;
+
+ for (p = auxiliary_filters; *p != NULL; p++)
+ {
+ bfd_size_type indx;
+
+ indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
+ *p, TRUE);
+ if (indx == (bfd_size_type) -1
+ || !_bfd_elf_add_dynamic_entry (info, DT_AUXILIARY, indx))
+ return FALSE;
+ }
+ }
+
+ eif.info = info;
+ eif.verdefs = verdefs;
+ eif.failed = FALSE;
+
+ /* If we are supposed to export all symbols into the dynamic symbol
+ table (this is not the normal case), then do so. */
+ if (info->export_dynamic)
+ {
+ elf_link_hash_traverse (elf_hash_table (info),
+ _bfd_elf_export_symbol,
+ &eif);
+ if (eif.failed)
+ return FALSE;
+ }
+
+ /* Make all global versions with definition. */
+ for (t = verdefs; t != NULL; t = t->next)
+ for (d = t->globals.list; d != NULL; d = d->next)
+ if (!d->symver && d->symbol)
+ {
+ const char *verstr, *name;
+ size_t namelen, verlen, newlen;
+ char *newname, *p;
+ struct elf_link_hash_entry *newh;
+
+ name = d->symbol;
+ namelen = strlen (name);
+ verstr = t->name;
+ verlen = strlen (verstr);
+ newlen = namelen + verlen + 3;
+
+ newname = bfd_malloc (newlen);
+ if (newname == NULL)
+ return FALSE;
+ memcpy (newname, name, namelen);
+
+ /* Check the hidden versioned definition. */
+ p = newname + namelen;
+ *p++ = ELF_VER_CHR;
+ memcpy (p, verstr, verlen + 1);
+ newh = elf_link_hash_lookup (elf_hash_table (info),
+ newname, FALSE, FALSE,
+ FALSE);
+ if (newh == NULL
+ || (newh->root.type != bfd_link_hash_defined
+ && newh->root.type != bfd_link_hash_defweak))
+ {
+ /* Check the default versioned definition. */
+ *p++ = ELF_VER_CHR;
+ memcpy (p, verstr, verlen + 1);
+ newh = elf_link_hash_lookup (elf_hash_table (info),
+ newname, FALSE, FALSE,
+ FALSE);
+ }
+ free (newname);
+
+ /* Mark this version if there is a definition and it is
+ not defined in a shared object. */
+ if (newh != NULL
+ && ((newh->elf_link_hash_flags
+ & ELF_LINK_HASH_DEF_DYNAMIC) == 0)
+ && (newh->root.type == bfd_link_hash_defined
+ || newh->root.type == bfd_link_hash_defweak))
+ d->symver = 1;
+ }
+
+ /* Attach all the symbols to their version information. */
+ asvinfo.output_bfd = output_bfd;
+ asvinfo.info = info;
+ asvinfo.verdefs = verdefs;
+ asvinfo.failed = FALSE;
+
+ elf_link_hash_traverse (elf_hash_table (info),
+ _bfd_elf_link_assign_sym_version,
+ &asvinfo);
+ if (asvinfo.failed)
+ return FALSE;
+
+ if (!info->allow_undefined_version)
+ {
+ /* Check if all global versions have a definition. */
+ all_defined = TRUE;
+ for (t = verdefs; t != NULL; t = t->next)
+ for (d = t->globals.list; d != NULL; d = d->next)
+ if (!d->symver && !d->script)
+ {
+ (*_bfd_error_handler)
+ (_("%s: undefined version: %s"),
+ d->pattern, t->name);
+ all_defined = FALSE;
+ }
+
+ if (!all_defined)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ }
+
+ /* Find all symbols which were defined in a dynamic object and make
+ the backend pick a reasonable value for them. */
+ elf_link_hash_traverse (elf_hash_table (info),
+ _bfd_elf_adjust_dynamic_symbol,
+ &eif);
+ if (eif.failed)
+ return FALSE;
+
+ /* Add some entries to the .dynamic section. We fill in some of the
+ values later, in elf_bfd_final_link, but we must add the entries
+ now so that we know the final size of the .dynamic section. */
+
+ /* If there are initialization and/or finalization functions to
+ call then add the corresponding DT_INIT/DT_FINI entries. */
+ h = (info->init_function
+ ? elf_link_hash_lookup (elf_hash_table (info),
+ info->init_function, FALSE,
+ FALSE, FALSE)
+ : NULL);
+ if (h != NULL
+ && (h->elf_link_hash_flags & (ELF_LINK_HASH_REF_REGULAR
+ | ELF_LINK_HASH_DEF_REGULAR)) != 0)
+ {
+ if (!_bfd_elf_add_dynamic_entry (info, DT_INIT, 0))
+ return FALSE;
+ }
+ h = (info->fini_function
+ ? elf_link_hash_lookup (elf_hash_table (info),
+ info->fini_function, FALSE,
+ FALSE, FALSE)
+ : NULL);
+ if (h != NULL
+ && (h->elf_link_hash_flags & (ELF_LINK_HASH_REF_REGULAR
+ | ELF_LINK_HASH_DEF_REGULAR)) != 0)
+ {
+ if (!_bfd_elf_add_dynamic_entry (info, DT_FINI, 0))
+ return FALSE;
+ }
+
+ if (bfd_get_section_by_name (output_bfd, ".preinit_array") != NULL)
+ {
+ /* DT_PREINIT_ARRAY is not allowed in shared library. */
+ if (! info->executable)
+ {
+ bfd *sub;
+ asection *o;
+
+ for (sub = info->input_bfds; sub != NULL;
+ sub = sub->link_next)
+ for (o = sub->sections; o != NULL; o = o->next)
+ if (elf_section_data (o)->this_hdr.sh_type
+ == SHT_PREINIT_ARRAY)
+ {
+ (*_bfd_error_handler)
+ (_("%s: .preinit_array section is not allowed in DSO"),
+ bfd_archive_filename (sub));
+ break;
+ }
+
+ bfd_set_error (bfd_error_nonrepresentable_section);
+ return FALSE;
+ }
+
+ if (!_bfd_elf_add_dynamic_entry (info, DT_PREINIT_ARRAY, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_PREINIT_ARRAYSZ, 0))
+ return FALSE;
+ }
+ if (bfd_get_section_by_name (output_bfd, ".init_array") != NULL)
+ {
+ if (!_bfd_elf_add_dynamic_entry (info, DT_INIT_ARRAY, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_INIT_ARRAYSZ, 0))
+ return FALSE;
+ }
+ if (bfd_get_section_by_name (output_bfd, ".fini_array") != NULL)
+ {
+ if (!_bfd_elf_add_dynamic_entry (info, DT_FINI_ARRAY, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_FINI_ARRAYSZ, 0))
+ return FALSE;
+ }
+
+ dynstr = bfd_get_section_by_name (dynobj, ".dynstr");
+ /* If .dynstr is excluded from the link, we don't want any of
+ these tags. Strictly, we should be checking each section
+ individually; This quick check covers for the case where
+ someone does a /DISCARD/ : { *(*) }. */
+ if (dynstr != NULL && dynstr->output_section != bfd_abs_section_ptr)
+ {
+ bfd_size_type strsize;
+
+ strsize = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
+ if (!_bfd_elf_add_dynamic_entry (info, DT_HASH, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_STRTAB, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_SYMTAB, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_STRSZ, strsize)
+ || !_bfd_elf_add_dynamic_entry (info, DT_SYMENT,
+ bed->s->sizeof_sym))
+ return FALSE;
+ }
+ }
+
+ /* The backend must work out the sizes of all the other dynamic
+ sections. */
+ if (bed->elf_backend_size_dynamic_sections
+ && ! (*bed->elf_backend_size_dynamic_sections) (output_bfd, info))
+ return FALSE;
+
+ if (elf_hash_table (info)->dynamic_sections_created)
+ {
+ bfd_size_type dynsymcount;
+ asection *s;
+ size_t bucketcount = 0;
+ size_t hash_entry_size;
+ unsigned int dtagcount;
+
+ /* Set up the version definition section. */
+ s = bfd_get_section_by_name (dynobj, ".gnu.version_d");
+ BFD_ASSERT (s != NULL);
+
+ /* We may have created additional version definitions if we are
+ just linking a regular application. */
+ verdefs = asvinfo.verdefs;
+
+ /* Skip anonymous version tag. */
+ if (verdefs != NULL && verdefs->vernum == 0)
+ verdefs = verdefs->next;
+
+ if (verdefs == NULL)
+ _bfd_strip_section_from_output (info, s);
+ else
+ {
+ unsigned int cdefs;
+ bfd_size_type size;
+ struct bfd_elf_version_tree *t;
+ bfd_byte *p;
+ Elf_Internal_Verdef def;
+ Elf_Internal_Verdaux defaux;
+
+ cdefs = 0;
+ size = 0;
+
+ /* Make space for the base version. */
+ size += sizeof (Elf_External_Verdef);
+ size += sizeof (Elf_External_Verdaux);
+ ++cdefs;
+
+ for (t = verdefs; t != NULL; t = t->next)
+ {
+ struct bfd_elf_version_deps *n;
+
+ size += sizeof (Elf_External_Verdef);
+ size += sizeof (Elf_External_Verdaux);
+ ++cdefs;
+
+ for (n = t->deps; n != NULL; n = n->next)
+ size += sizeof (Elf_External_Verdaux);
+ }
+
+ s->_raw_size = size;
+ s->contents = bfd_alloc (output_bfd, s->_raw_size);
+ if (s->contents == NULL && s->_raw_size != 0)
+ return FALSE;
+
+ /* Fill in the version definition section. */
+
+ p = s->contents;
+
+ def.vd_version = VER_DEF_CURRENT;
+ def.vd_flags = VER_FLG_BASE;
+ def.vd_ndx = 1;
+ def.vd_cnt = 1;
+ def.vd_aux = sizeof (Elf_External_Verdef);
+ def.vd_next = (sizeof (Elf_External_Verdef)
+ + sizeof (Elf_External_Verdaux));
+
+ if (soname_indx != (bfd_size_type) -1)
+ {
+ _bfd_elf_strtab_addref (elf_hash_table (info)->dynstr,
+ soname_indx);
+ def.vd_hash = bfd_elf_hash (soname);
+ defaux.vda_name = soname_indx;
+ }
+ else
+ {
+ const char *name;
+ bfd_size_type indx;
+
+ name = basename (output_bfd->filename);
+ def.vd_hash = bfd_elf_hash (name);
+ indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
+ name, FALSE);
+ if (indx == (bfd_size_type) -1)
+ return FALSE;
+ defaux.vda_name = indx;
+ }
+ defaux.vda_next = 0;
+
+ _bfd_elf_swap_verdef_out (output_bfd, &def,
+ (Elf_External_Verdef *) p);
+ p += sizeof (Elf_External_Verdef);
+ _bfd_elf_swap_verdaux_out (output_bfd, &defaux,
+ (Elf_External_Verdaux *) p);
+ p += sizeof (Elf_External_Verdaux);
+
+ for (t = verdefs; t != NULL; t = t->next)
+ {
+ unsigned int cdeps;
+ struct bfd_elf_version_deps *n;
+ struct elf_link_hash_entry *h;
+ struct bfd_link_hash_entry *bh;
+
+ cdeps = 0;
+ for (n = t->deps; n != NULL; n = n->next)
+ ++cdeps;
+
+ /* Add a symbol representing this version. */
+ bh = NULL;
+ if (! (_bfd_generic_link_add_one_symbol
+ (info, dynobj, t->name, BSF_GLOBAL, bfd_abs_section_ptr,
+ 0, NULL, FALSE,
+ get_elf_backend_data (dynobj)->collect, &bh)))
+ return FALSE;
+ h = (struct elf_link_hash_entry *) bh;
+ h->elf_link_hash_flags &= ~ ELF_LINK_NON_ELF;
+ h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
+ h->type = STT_OBJECT;
+ h->verinfo.vertree = t;
+
+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
+ return FALSE;
+
+ def.vd_version = VER_DEF_CURRENT;
+ def.vd_flags = 0;
+ if (t->globals.list == NULL
+ && t->locals.list == NULL
+ && ! t->used)
+ def.vd_flags |= VER_FLG_WEAK;
+ def.vd_ndx = t->vernum + 1;
+ def.vd_cnt = cdeps + 1;
+ def.vd_hash = bfd_elf_hash (t->name);
+ def.vd_aux = sizeof (Elf_External_Verdef);
+ def.vd_next = 0;
+ if (t->next != NULL)
+ def.vd_next = (sizeof (Elf_External_Verdef)
+ + (cdeps + 1) * sizeof (Elf_External_Verdaux));
+
+ _bfd_elf_swap_verdef_out (output_bfd, &def,
+ (Elf_External_Verdef *) p);
+ p += sizeof (Elf_External_Verdef);
+
+ defaux.vda_name = h->dynstr_index;
+ _bfd_elf_strtab_addref (elf_hash_table (info)->dynstr,
+ h->dynstr_index);
+ defaux.vda_next = 0;
+ if (t->deps != NULL)
+ defaux.vda_next = sizeof (Elf_External_Verdaux);
+ t->name_indx = defaux.vda_name;
+
+ _bfd_elf_swap_verdaux_out (output_bfd, &defaux,
+ (Elf_External_Verdaux *) p);
+ p += sizeof (Elf_External_Verdaux);
+
+ for (n = t->deps; n != NULL; n = n->next)
+ {
+ if (n->version_needed == NULL)
+ {
+ /* This can happen if there was an error in the
+ version script. */
+ defaux.vda_name = 0;
+ }
+ else
+ {
+ defaux.vda_name = n->version_needed->name_indx;
+ _bfd_elf_strtab_addref (elf_hash_table (info)->dynstr,
+ defaux.vda_name);
+ }
+ if (n->next == NULL)
+ defaux.vda_next = 0;
+ else
+ defaux.vda_next = sizeof (Elf_External_Verdaux);
+
+ _bfd_elf_swap_verdaux_out (output_bfd, &defaux,
+ (Elf_External_Verdaux *) p);
+ p += sizeof (Elf_External_Verdaux);
+ }
+ }
+
+ if (!_bfd_elf_add_dynamic_entry (info, DT_VERDEF, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_VERDEFNUM, cdefs))
+ return FALSE;
+
+ elf_tdata (output_bfd)->cverdefs = cdefs;
+ }
+
+ if ((info->new_dtags && info->flags) || (info->flags & DF_STATIC_TLS))
+ {
+ if (!_bfd_elf_add_dynamic_entry (info, DT_FLAGS, info->flags))
+ return FALSE;
+ }
+ else if (info->flags & DF_BIND_NOW)
+ {
+ if (!_bfd_elf_add_dynamic_entry (info, DT_BIND_NOW, 0))
+ return FALSE;
+ }
+
+ if (info->flags_1)
+ {
+ if (info->executable)
+ info->flags_1 &= ~ (DF_1_INITFIRST
+ | DF_1_NODELETE
+ | DF_1_NOOPEN);
+ if (!_bfd_elf_add_dynamic_entry (info, DT_FLAGS_1, info->flags_1))
+ return FALSE;
+ }
+
+ /* Work out the size of the version reference section. */
+
+ s = bfd_get_section_by_name (dynobj, ".gnu.version_r");
+ BFD_ASSERT (s != NULL);
+ {
+ struct elf_find_verdep_info sinfo;
+
+ sinfo.output_bfd = output_bfd;
+ sinfo.info = info;
+ sinfo.vers = elf_tdata (output_bfd)->cverdefs;
+ if (sinfo.vers == 0)
+ sinfo.vers = 1;
+ sinfo.failed = FALSE;
+
+ elf_link_hash_traverse (elf_hash_table (info),
+ _bfd_elf_link_find_version_dependencies,
+ &sinfo);
+
+ if (elf_tdata (output_bfd)->verref == NULL)
+ _bfd_strip_section_from_output (info, s);
+ else
+ {
+ Elf_Internal_Verneed *t;
+ unsigned int size;
+ unsigned int crefs;
+ bfd_byte *p;
+
+ /* Build the version definition section. */
+ size = 0;
+ crefs = 0;
+ for (t = elf_tdata (output_bfd)->verref;
+ t != NULL;
+ t = t->vn_nextref)
+ {
+ Elf_Internal_Vernaux *a;
+
+ size += sizeof (Elf_External_Verneed);
+ ++crefs;
+ for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
+ size += sizeof (Elf_External_Vernaux);
+ }
+
+ s->_raw_size = size;
+ s->contents = bfd_alloc (output_bfd, s->_raw_size);
+ if (s->contents == NULL)
+ return FALSE;
+
+ p = s->contents;
+ for (t = elf_tdata (output_bfd)->verref;
+ t != NULL;
+ t = t->vn_nextref)
+ {
+ unsigned int caux;
+ Elf_Internal_Vernaux *a;
+ bfd_size_type indx;
+
+ caux = 0;
+ for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
+ ++caux;
+
+ t->vn_version = VER_NEED_CURRENT;
+ t->vn_cnt = caux;
+ indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
+ elf_dt_name (t->vn_bfd) != NULL
+ ? elf_dt_name (t->vn_bfd)
+ : basename (t->vn_bfd->filename),
+ FALSE);
+ if (indx == (bfd_size_type) -1)
+ return FALSE;
+ t->vn_file = indx;
+ t->vn_aux = sizeof (Elf_External_Verneed);
+ if (t->vn_nextref == NULL)
+ t->vn_next = 0;
+ else
+ t->vn_next = (sizeof (Elf_External_Verneed)
+ + caux * sizeof (Elf_External_Vernaux));
+
+ _bfd_elf_swap_verneed_out (output_bfd, t,
+ (Elf_External_Verneed *) p);
+ p += sizeof (Elf_External_Verneed);
+
+ for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
+ {
+ a->vna_hash = bfd_elf_hash (a->vna_nodename);
+ indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
+ a->vna_nodename, FALSE);
+ if (indx == (bfd_size_type) -1)
+ return FALSE;
+ a->vna_name = indx;
+ if (a->vna_nextptr == NULL)
+ a->vna_next = 0;
+ else
+ a->vna_next = sizeof (Elf_External_Vernaux);
+
+ _bfd_elf_swap_vernaux_out (output_bfd, a,
+ (Elf_External_Vernaux *) p);
+ p += sizeof (Elf_External_Vernaux);
+ }
+ }
+
+ if (!_bfd_elf_add_dynamic_entry (info, DT_VERNEED, 0)
+ || !_bfd_elf_add_dynamic_entry (info, DT_VERNEEDNUM, crefs))
+ return FALSE;
+
+ elf_tdata (output_bfd)->cverrefs = crefs;
+ }
+ }
+
+ /* Assign dynsym indicies. In a shared library we generate a
+ section symbol for each output section, which come first.
+ Next come all of the back-end allocated local dynamic syms,
+ followed by the rest of the global symbols. */
+
+ dynsymcount = _bfd_elf_link_renumber_dynsyms (output_bfd, info);
+
+ /* Work out the size of the symbol version section. */
+ s = bfd_get_section_by_name (dynobj, ".gnu.version");
+ BFD_ASSERT (s != NULL);
+ if (dynsymcount == 0
+ || (verdefs == NULL && elf_tdata (output_bfd)->verref == NULL))
+ {
+ _bfd_strip_section_from_output (info, s);
+ /* The DYNSYMCOUNT might have changed if we were going to
+ output a dynamic symbol table entry for S. */
+ dynsymcount = _bfd_elf_link_renumber_dynsyms (output_bfd, info);
+ }
+ else
+ {
+ s->_raw_size = dynsymcount * sizeof (Elf_External_Versym);
+ s->contents = bfd_zalloc (output_bfd, s->_raw_size);
+ if (s->contents == NULL)
+ return FALSE;
+
+ if (!_bfd_elf_add_dynamic_entry (info, DT_VERSYM, 0))
+ return FALSE;
+ }
+
+ /* Set the size of the .dynsym and .hash sections. We counted
+ the number of dynamic symbols in elf_link_add_object_symbols.
+ We will build the contents of .dynsym and .hash when we build
+ the final symbol table, because until then we do not know the
+ correct value to give the symbols. We built the .dynstr
+ section as we went along in elf_link_add_object_symbols. */
+ s = bfd_get_section_by_name (dynobj, ".dynsym");
+ BFD_ASSERT (s != NULL);
+ s->_raw_size = dynsymcount * bed->s->sizeof_sym;
+ s->contents = bfd_alloc (output_bfd, s->_raw_size);
+ if (s->contents == NULL && s->_raw_size != 0)
+ return FALSE;
+
+ if (dynsymcount != 0)
+ {
+ Elf_Internal_Sym isym;
+
+ /* The first entry in .dynsym is a dummy symbol. */
+ isym.st_value = 0;
+ isym.st_size = 0;
+ isym.st_name = 0;
+ isym.st_info = 0;
+ isym.st_other = 0;
+ isym.st_shndx = 0;
+ bed->s->swap_symbol_out (output_bfd, &isym, s->contents, 0);
+ }
+
+ /* Compute the size of the hashing table. As a side effect this
+ computes the hash values for all the names we export. */
+ bucketcount = compute_bucket_count (info);
+
+ s = bfd_get_section_by_name (dynobj, ".hash");
+ BFD_ASSERT (s != NULL);
+ hash_entry_size = elf_section_data (s)->this_hdr.sh_entsize;
+ s->_raw_size = ((2 + bucketcount + dynsymcount) * hash_entry_size);
+ s->contents = bfd_zalloc (output_bfd, s->_raw_size);
+ if (s->contents == NULL)
+ return FALSE;
+
+ bfd_put (8 * hash_entry_size, output_bfd, bucketcount, s->contents);
+ bfd_put (8 * hash_entry_size, output_bfd, dynsymcount,
+ s->contents + hash_entry_size);
+
+ elf_hash_table (info)->bucketcount = bucketcount;
+
+ s = bfd_get_section_by_name (dynobj, ".dynstr");
+ BFD_ASSERT (s != NULL);
+
+ elf_finalize_dynstr (output_bfd, info);
+
+ s->_raw_size = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
+
+ for (dtagcount = 0; dtagcount <= info->spare_dynamic_tags; ++dtagcount)
+ if (!_bfd_elf_add_dynamic_entry (info, DT_NULL, 0))
+ return FALSE;
+ }
+
+ 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. */
+ r_symndx = 0;
+ if (bfd_is_abs_section (sec))
+ ;
+ else if (sec == NULL || sec->owner == NULL)
+ {
+ bfd_set_error (bfd_error_bad_value);
+ return FALSE;
+ }
+ else
+ {
+ asection *osec = sec->output_section;
+
+ /* If we have discarded a section, the output
+ section will be the absolute section. In
+ case of discarded link-once and discarded
+ SEC_MERGE sections, use the kept section. */
+ if (bfd_is_abs_section (osec)
+ && sec->kept_section != NULL
+ && sec->kept_section->output_section != NULL)
+ {
+ osec = sec->kept_section->output_section;
+ irela->r_addend -= osec->vma;
+ }
+
+ if (!bfd_is_abs_section (osec))
+ {
+ r_symndx = osec->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];
+ 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;
+ 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;
+}
+
+/* Mark sections containing dynamically referenced symbols. This is called
+ through elf_link_hash_traverse. */
+
+static bfd_boolean
+elf_gc_mark_dynamic_ref_symbol (struct elf_link_hash_entry *h,
+ void *okp ATTRIBUTE_UNUSED)
+{
+ 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_defined
+ || h->root.type == bfd_link_hash_defweak)
+ && (h->elf_link_hash_flags & ELF_LINK_HASH_REF_DYNAMIC))
+ h->root.u.def.section->flags |= SEC_KEEP;
+
+ 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
+ || info->shared
+ || !is_elf_hash_table (info->hash))
+ {
+ (*_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;
+
+ /* Mark dynamically referenced symbols. */
+ if (elf_hash_table (info)->dynamic_sections_created)
+ elf_link_hash_traverse (elf_hash_table (info),
+ elf_gc_mark_dynamic_ref_symbol,
+ &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)
+ {
+ /* _bfd_elf_discard_section_eh_frame knows how to discard
+ orphaned FDEs so don't mark sections referenced by the
+ EH frame section. */
+ if (strcmp (o->name, ".eh_frame") == 0)
+ o->gc_mark = 1;
+ else 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 c37d739..0000000
--- a/bfd/elflink.h
+++ /dev/null
@@ -1,6333 +0,0 @@
-/* ELF linker support.
- Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
- 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. */
-
-#include "safe-ctype.h"
-
-static bfd_boolean elf_link_add_object_symbols (bfd *, struct bfd_link_info *);
-static bfd_boolean elf_link_add_archive_symbols (bfd *,
- struct bfd_link_info *);
-static bfd_boolean elf_finalize_dynstr (bfd *, struct bfd_link_info *);
-static bfd_boolean elf_collect_hash_codes (struct elf_link_hash_entry *,
- void *);
-static bfd_boolean elf_section_ignore_discarded_relocs (asection *);
-
-/* Given an ELF BFD, add symbols to the global hash table as
- appropriate. */
-
-bfd_boolean
-elf_bfd_link_add_symbols (bfd *abfd, struct bfd_link_info *info)
-{
- switch (bfd_get_format (abfd))
- {
- case bfd_object:
- return elf_link_add_object_symbols (abfd, info);
- case bfd_archive:
- return elf_link_add_archive_symbols (abfd, info);
- default:
- bfd_set_error (bfd_error_wrong_format);
- return FALSE;
- }
-}
-
-/* Return TRUE iff this is a non-common, definition of a non-function symbol. */
-static bfd_boolean
-is_global_data_symbol_definition (bfd *abfd ATTRIBUTE_UNUSED,
- Elf_Internal_Sym *sym)
-{
- /* Local symbols do not count, but target specific ones might. */
- if (ELF_ST_BIND (sym->st_info) != STB_GLOBAL
- && ELF_ST_BIND (sym->st_info) < STB_LOOS)
- return FALSE;
-
- /* Function symbols do not count. */
- if (ELF_ST_TYPE (sym->st_info) == STT_FUNC)
- return FALSE;
-
- /* If the section is undefined, then so is the symbol. */
- if (sym->st_shndx == SHN_UNDEF)
- return FALSE;
-
- /* If the symbol is defined in the common section, then
- it is a common definition and so does not count. */
- if (sym->st_shndx == SHN_COMMON)
- return FALSE;
-
- /* If the symbol is in a target specific section then we
- must rely upon the backend to tell us what it is. */
- if (sym->st_shndx >= SHN_LORESERVE && sym->st_shndx < SHN_ABS)
- /* FIXME - this function is not coded yet:
-
- return _bfd_is_global_symbol_definition (abfd, sym);
-
- Instead for now assume that the definition is not global,
- Even if this is wrong, at least the linker will behave
- in the same way that it used to do. */
- return FALSE;
-
- return TRUE;
-}
-
-/* Search the symbol table of the archive element of the archive ABFD
- whose archive map contains a mention of SYMDEF, and determine if
- the symbol is defined in this element. */
-static bfd_boolean
-elf_link_is_defined_archive_symbol (bfd * abfd, carsym * symdef)
-{
- Elf_Internal_Shdr * hdr;
- bfd_size_type symcount;
- bfd_size_type extsymcount;
- bfd_size_type extsymoff;
- Elf_Internal_Sym *isymbuf;
- Elf_Internal_Sym *isym;
- Elf_Internal_Sym *isymend;
- bfd_boolean result;
-
- abfd = _bfd_get_elt_at_filepos (abfd, symdef->file_offset);
- if (abfd == NULL)
- return FALSE;
-
- if (! bfd_check_format (abfd, bfd_object))
- return FALSE;
-
- /* If we have already included the element containing this symbol in the
- link then we do not need to include it again. Just claim that any symbol
- it contains is not a definition, so that our caller will not decide to
- (re)include this element. */
- if (abfd->archive_pass)
- return FALSE;
-
- /* Select the appropriate symbol table. */
- if ((abfd->flags & DYNAMIC) == 0 || elf_dynsymtab (abfd) == 0)
- hdr = &elf_tdata (abfd)->symtab_hdr;
- else
- hdr = &elf_tdata (abfd)->dynsymtab_hdr;
-
- symcount = hdr->sh_size / sizeof (Elf_External_Sym);
-
- /* The sh_info field of the symtab header tells us where the
- external symbols start. We don't care about the local symbols. */
- if (elf_bad_symtab (abfd))
- {
- extsymcount = symcount;
- extsymoff = 0;
- }
- else
- {
- extsymcount = symcount - hdr->sh_info;
- extsymoff = hdr->sh_info;
- }
-
- if (extsymcount == 0)
- return FALSE;
-
- /* Read in the symbol table. */
- isymbuf = bfd_elf_get_elf_syms (abfd, hdr, extsymcount, extsymoff,
- NULL, NULL, NULL);
- if (isymbuf == NULL)
- return FALSE;
-
- /* Scan the symbol table looking for SYMDEF. */
- result = FALSE;
- for (isym = isymbuf, isymend = isymbuf + extsymcount; isym < isymend; isym++)
- {
- const char *name;
-
- name = bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
- isym->st_name);
- if (name == NULL)
- break;
-
- if (strcmp (name, symdef->name) == 0)
- {
- result = is_global_data_symbol_definition (abfd, isym);
- break;
- }
- }
-
- free (isymbuf);
-
- return result;
-}
-
-/* Add symbols from an ELF archive file to the linker hash table. We
- don't use _bfd_generic_link_add_archive_symbols because of a
- problem which arises on UnixWare. The UnixWare libc.so is an
- archive which includes an entry libc.so.1 which defines a bunch of
- symbols. The libc.so archive also includes a number of other
- object files, which also define symbols, some of which are the same
- as those defined in libc.so.1. Correct linking requires that we
- consider each object file in turn, and include it if it defines any
- symbols we need. _bfd_generic_link_add_archive_symbols does not do
- this; it looks through the list of undefined symbols, and includes
- any object file which defines them. When this algorithm is used on
- UnixWare, it winds up pulling in libc.so.1 early and defining a
- bunch of symbols. This means that some of the other objects in the
- archive are not included in the link, which is incorrect since they
- precede libc.so.1 in the archive.
-
- Fortunately, ELF archive handling is simpler than that done by
- _bfd_generic_link_add_archive_symbols, which has to allow for a.out
- oddities. In ELF, if we find a symbol in the archive map, and the
- symbol is currently undefined, we know that we must pull in that
- object file.
-
- Unfortunately, we do have to make multiple passes over the symbol
- table until nothing further is resolved. */
-
-static bfd_boolean
-elf_link_add_archive_symbols (bfd *abfd, struct bfd_link_info *info)
-{
- symindex c;
- bfd_boolean *defined = NULL;
- bfd_boolean *included = NULL;
- carsym *symdefs;
- bfd_boolean loop;
- bfd_size_type amt;
-
- if (! bfd_has_map (abfd))
- {
- /* An empty archive is a special case. */
- if (bfd_openr_next_archived_file (abfd, NULL) == NULL)
- return TRUE;
- bfd_set_error (bfd_error_no_armap);
- return FALSE;
- }
-
- /* Keep track of all symbols we know to be already defined, and all
- files we know to be already included. This is to speed up the
- second and subsequent passes. */
- c = bfd_ardata (abfd)->symdef_count;
- if (c == 0)
- return TRUE;
- amt = c;
- amt *= sizeof (bfd_boolean);
- defined = bfd_zmalloc (amt);
- included = bfd_zmalloc (amt);
- if (defined == NULL || included == NULL)
- goto error_return;
-
- symdefs = bfd_ardata (abfd)->symdefs;
-
- do
- {
- file_ptr last;
- symindex i;
- carsym *symdef;
- carsym *symdefend;
-
- loop = FALSE;
- last = -1;
-
- symdef = symdefs;
- symdefend = symdef + c;
- for (i = 0; symdef < symdefend; symdef++, i++)
- {
- struct elf_link_hash_entry *h;
- bfd *element;
- struct bfd_link_hash_entry *undefs_tail;
- symindex mark;
-
- if (defined[i] || included[i])
- continue;
- if (symdef->file_offset == last)
- {
- included[i] = TRUE;
- continue;
- }
-
- h = elf_link_hash_lookup (elf_hash_table (info), symdef->name,
- FALSE, FALSE, FALSE);
-
- if (h == NULL)
- {
- char *p, *copy;
- size_t len, first;
-
- /* If this is a default version (the name contains @@),
- look up the symbol again with only one `@' as well
- as without the version. The effect is that references
- to the symbol with and without the version will be
- matched by the default symbol in the archive. */
-
- p = strchr (symdef->name, ELF_VER_CHR);
- if (p == NULL || p[1] != ELF_VER_CHR)
- continue;
-
- /* First check with only one `@'. */
- len = strlen (symdef->name);
- copy = bfd_alloc (abfd, len);
- if (copy == NULL)
- goto error_return;
- first = p - symdef->name + 1;
- memcpy (copy, symdef->name, first);
- memcpy (copy + first, symdef->name + first + 1, len - first);
-
- h = elf_link_hash_lookup (elf_hash_table (info), copy,
- FALSE, FALSE, FALSE);
-
- if (h == NULL)
- {
- /* We also need to check references to the symbol
- without the version. */
-
- copy[first - 1] = '\0';
- h = elf_link_hash_lookup (elf_hash_table (info),
- copy, FALSE, FALSE, FALSE);
- }
-
- bfd_release (abfd, copy);
- }
-
- if (h == NULL)
- continue;
-
- if (h->root.type == bfd_link_hash_common)
- {
- /* We currently have a common symbol. The archive map contains
- a reference to this symbol, so we may want to include it. We
- only want to include it however, if this archive element
- contains a definition of the symbol, not just another common
- declaration of it.
-
- Unfortunately some archivers (including GNU ar) will put
- declarations of common symbols into their archive maps, as
- well as real definitions, so we cannot just go by the archive
- map alone. Instead we must read in the element's symbol
- table and check that to see what kind of symbol definition
- this is. */
- if (! elf_link_is_defined_archive_symbol (abfd, symdef))
- continue;
- }
- else if (h->root.type != bfd_link_hash_undefined)
- {
- if (h->root.type != bfd_link_hash_undefweak)
- defined[i] = TRUE;
- continue;
- }
-
- /* We need to include this archive member. */
- element = _bfd_get_elt_at_filepos (abfd, symdef->file_offset);
- if (element == NULL)
- goto error_return;
-
- if (! bfd_check_format (element, bfd_object))
- goto error_return;
-
- /* Doublecheck that we have not included this object
- already--it should be impossible, but there may be
- something wrong with the archive. */
- if (element->archive_pass != 0)
- {
- bfd_set_error (bfd_error_bad_value);
- goto error_return;
- }
- element->archive_pass = 1;
-
- undefs_tail = info->hash->undefs_tail;
-
- if (! (*info->callbacks->add_archive_element) (info, element,
- symdef->name))
- goto error_return;
- if (! elf_link_add_object_symbols (element, info))
- goto error_return;
-
- /* If there are any new undefined symbols, we need to make
- another pass through the archive in order to see whether
- they can be defined. FIXME: This isn't perfect, because
- common symbols wind up on undefs_tail and because an
- undefined symbol which is defined later on in this pass
- does not require another pass. This isn't a bug, but it
- does make the code less efficient than it could be. */
- if (undefs_tail != info->hash->undefs_tail)
- loop = TRUE;
-
- /* Look backward to mark all symbols from this object file
- which we have already seen in this pass. */
- mark = i;
- do
- {
- included[mark] = TRUE;
- if (mark == 0)
- break;
- --mark;
- }
- while (symdefs[mark].file_offset == symdef->file_offset);
-
- /* We mark subsequent symbols from this object file as we go
- on through the loop. */
- last = symdef->file_offset;
- }
- }
- while (loop);
-
- free (defined);
- free (included);
-
- return TRUE;
-
- error_return:
- if (defined != NULL)
- free (defined);
- if (included != NULL)
- free (included);
- return FALSE;
-}
-
-/* Add symbols from an ELF object file to the linker hash table. */
-
-static bfd_boolean
-elf_link_add_object_symbols (bfd *abfd, struct bfd_link_info *info)
-{
- bfd_boolean (*add_symbol_hook)
- (bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,
- const char **, flagword *, asection **, bfd_vma *);
- bfd_boolean (*check_relocs)
- (bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
- bfd_boolean collect;
- Elf_Internal_Shdr *hdr;
- bfd_size_type symcount;
- bfd_size_type extsymcount;
- bfd_size_type extsymoff;
- struct elf_link_hash_entry **sym_hash;
- bfd_boolean dynamic;
- Elf_External_Versym *extversym = NULL;
- Elf_External_Versym *ever;
- struct elf_link_hash_entry *weaks;
- struct elf_link_hash_entry **nondeflt_vers = NULL;
- bfd_size_type nondeflt_vers_cnt = 0;
- Elf_Internal_Sym *isymbuf = NULL;
- Elf_Internal_Sym *isym;
- Elf_Internal_Sym *isymend;
- const struct elf_backend_data *bed;
- bfd_boolean dt_needed;
- struct elf_link_hash_table * hash_table;
- bfd_size_type amt;
-
- hash_table = elf_hash_table (info);
-
- bed = get_elf_backend_data (abfd);
- add_symbol_hook = bed->elf_add_symbol_hook;
- collect = bed->collect;
-
- if ((abfd->flags & DYNAMIC) == 0)
- dynamic = FALSE;
- else
- {
- dynamic = TRUE;
-
- /* You can't use -r against a dynamic object. Also, there's no
- hope of using a dynamic object which does not exactly match
- the format of the output file. */
- if (info->relocatable
- || !is_elf_hash_table (hash_table)
- || hash_table->root.creator != abfd->xvec)
- {
- bfd_set_error (bfd_error_invalid_operation);
- goto error_return;
- }
- }
-
- /* As a GNU extension, any input sections which are named
- .gnu.warning.SYMBOL are treated as warning symbols for the given
- symbol. This differs from .gnu.warning sections, which generate
- warnings when they are included in an output file. */
- if (info->executable)
- {
- asection *s;
-
- for (s = abfd->sections; s != NULL; s = s->next)
- {
- const char *name;
-
- name = bfd_get_section_name (abfd, s);
- if (strncmp (name, ".gnu.warning.", sizeof ".gnu.warning." - 1) == 0)
- {
- char *msg;
- bfd_size_type sz;
- bfd_size_type prefix_len;
- const char * gnu_warning_prefix = _("warning: ");
-
- name += sizeof ".gnu.warning." - 1;
-
- /* If this is a shared object, then look up the symbol
- in the hash table. If it is there, and it is already
- been defined, then we will not be using the entry
- from this shared object, so we don't need to warn.
- FIXME: If we see the definition in a regular object
- later on, we will warn, but we shouldn't. The only
- fix is to keep track of what warnings we are supposed
- to emit, and then handle them all at the end of the
- link. */
- if (dynamic)
- {
- struct elf_link_hash_entry *h;
-
- h = elf_link_hash_lookup (hash_table, name,
- FALSE, FALSE, TRUE);
-
- /* FIXME: What about bfd_link_hash_common? */
- if (h != NULL
- && (h->root.type == bfd_link_hash_defined
- || h->root.type == bfd_link_hash_defweak))
- {
- /* We don't want to issue this warning. Clobber
- the section size so that the warning does not
- get copied into the output file. */
- s->_raw_size = 0;
- continue;
- }
- }
-
- sz = bfd_section_size (abfd, s);
- prefix_len = strlen (gnu_warning_prefix);
- msg = bfd_alloc (abfd, prefix_len + sz + 1);
- if (msg == NULL)
- goto error_return;
-
- strcpy (msg, gnu_warning_prefix);
- if (! bfd_get_section_contents (abfd, s, msg + prefix_len, 0, sz))
- goto error_return;
-
- msg[prefix_len + sz] = '\0';
-
- if (! (_bfd_generic_link_add_one_symbol
- (info, abfd, name, BSF_WARNING, s, 0, msg,
- FALSE, collect, NULL)))
- goto error_return;
-
- if (! info->relocatable)
- {
- /* Clobber the section size so that the warning does
- not get copied into the output file. */
- s->_raw_size = 0;
- }
- }
- }
- }
-
- dt_needed = FALSE;
- if (! dynamic)
- {
- /* If we are creating a shared library, create all the dynamic
- sections immediately. We need to attach them to something,
- so we attach them to this BFD, provided it is the right
- format. FIXME: If there are no input BFD's of the same
- format as the output, we can't make a shared library. */
- if (info->shared
- && is_elf_hash_table (hash_table)
- && hash_table->root.creator == abfd->xvec
- && ! hash_table->dynamic_sections_created)
- {
- if (! _bfd_elf_link_create_dynamic_sections (abfd, info))
- goto error_return;
- }
- }
- else if (!is_elf_hash_table (hash_table))
- goto error_return;
- else
- {
- asection *s;
- bfd_boolean add_needed;
- const char *name;
- bfd_size_type oldsize;
- bfd_size_type strindex;
- struct bfd_link_needed_list *rpath = NULL, *runpath = NULL;
-
- /* ld --just-symbols and dynamic objects don't mix very well.
- Test for --just-symbols by looking at info set up by
- _bfd_elf_link_just_syms. */
- if ((s = abfd->sections) != NULL
- && s->sec_info_type == ELF_INFO_TYPE_JUST_SYMS)
- goto error_return;
-
- /* Find the name to use in a DT_NEEDED entry that refers to this
- object. If the object has a DT_SONAME entry, we use it.
- Otherwise, if the generic linker stuck something in
- elf_dt_name, we use that. Otherwise, we just use the file
- name. If the generic linker put a null string into
- elf_dt_name, we don't make a DT_NEEDED entry at all, even if
- there is a DT_SONAME entry. */
- add_needed = TRUE;
- name = bfd_get_filename (abfd);
- if (elf_dt_name (abfd) != NULL)
- {
- name = elf_dt_name (abfd);
- if (*name == '\0')
- {
- if (elf_dt_soname (abfd) != NULL)
- dt_needed = TRUE;
-
- add_needed = FALSE;
- }
- }
- s = bfd_get_section_by_name (abfd, ".dynamic");
- if (s != NULL)
- {
- Elf_External_Dyn *dynbuf = NULL;
- Elf_External_Dyn *extdyn;
- Elf_External_Dyn *extdynend;
- int elfsec;
- unsigned long shlink;
-
- dynbuf = bfd_malloc (s->_raw_size);
- if (dynbuf == NULL)
- goto error_return;
-
- if (! bfd_get_section_contents (abfd, s, dynbuf, 0, s->_raw_size))
- goto error_free_dyn;
-
- elfsec = _bfd_elf_section_from_bfd_section (abfd, s);
- if (elfsec == -1)
- goto error_free_dyn;
- shlink = elf_elfsections (abfd)[elfsec]->sh_link;
-
- extdyn = dynbuf;
- extdynend = extdyn + s->_raw_size / sizeof (Elf_External_Dyn);
- for (; extdyn < extdynend; extdyn++)
- {
- Elf_Internal_Dyn dyn;
-
- elf_swap_dyn_in (abfd, extdyn, &dyn);
- if (dyn.d_tag == DT_SONAME)
- {
- unsigned int tagv = dyn.d_un.d_val;
- name = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
- if (name == NULL)
- goto error_free_dyn;
- }
- if (dyn.d_tag == DT_NEEDED)
- {
- struct bfd_link_needed_list *n, **pn;
- char *fnm, *anm;
- unsigned int tagv = dyn.d_un.d_val;
-
- amt = sizeof (struct bfd_link_needed_list);
- n = bfd_alloc (abfd, amt);
- fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
- if (n == NULL || fnm == NULL)
- goto error_free_dyn;
- amt = strlen (fnm) + 1;
- anm = bfd_alloc (abfd, amt);
- if (anm == NULL)
- goto error_free_dyn;
- memcpy (anm, fnm, amt);
- n->name = anm;
- n->by = abfd;
- n->next = NULL;
- for (pn = & hash_table->needed;
- *pn != NULL;
- pn = &(*pn)->next)
- ;
- *pn = n;
- }
- if (dyn.d_tag == DT_RUNPATH)
- {
- struct bfd_link_needed_list *n, **pn;
- char *fnm, *anm;
- unsigned int tagv = dyn.d_un.d_val;
-
- amt = sizeof (struct bfd_link_needed_list);
- n = bfd_alloc (abfd, amt);
- fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
- if (n == NULL || fnm == NULL)
- goto error_free_dyn;
- amt = strlen (fnm) + 1;
- anm = bfd_alloc (abfd, amt);
- if (anm == NULL)
- goto error_free_dyn;
- memcpy (anm, fnm, amt);
- n->name = anm;
- n->by = abfd;
- n->next = NULL;
- for (pn = & runpath;
- *pn != NULL;
- pn = &(*pn)->next)
- ;
- *pn = n;
- }
- /* Ignore DT_RPATH if we have seen DT_RUNPATH. */
- if (!runpath && dyn.d_tag == DT_RPATH)
- {
- struct bfd_link_needed_list *n, **pn;
- char *fnm, *anm;
- unsigned int tagv = dyn.d_un.d_val;
-
- amt = sizeof (struct bfd_link_needed_list);
- n = bfd_alloc (abfd, amt);
- fnm = bfd_elf_string_from_elf_section (abfd, shlink, tagv);
- if (n == NULL || fnm == NULL)
- goto error_free_dyn;
- amt = strlen (fnm) + 1;
- anm = bfd_alloc (abfd, amt);
- if (anm == NULL)
- {
- error_free_dyn:
- free (dynbuf);
- goto error_return;
- }
- memcpy (anm, fnm, amt);
- n->name = anm;
- n->by = abfd;
- n->next = NULL;
- for (pn = & rpath;
- *pn != NULL;
- pn = &(*pn)->next)
- ;
- *pn = n;
- }
- }
-
- free (dynbuf);
- }
-
- /* DT_RUNPATH overrides DT_RPATH. Do _NOT_ bfd_release, as that
- frees all more recently bfd_alloc'd blocks as well. */
- if (runpath)
- rpath = runpath;
-
- if (rpath)
- {
- struct bfd_link_needed_list **pn;
- for (pn = & hash_table->runpath;
- *pn != NULL;
- pn = &(*pn)->next)
- ;
- *pn = rpath;
- }
-
- /* We do not want to include any of the sections in a dynamic
- object in the output file. We hack by simply clobbering the
- list of sections in the BFD. This could be handled more
- cleanly by, say, a new section flag; the existing
- SEC_NEVER_LOAD flag is not the one we want, because that one
- still implies that the section takes up space in the output
- file. */
- bfd_section_list_clear (abfd);
-
- /* If this is the first dynamic object found in the link, create
- the special sections required for dynamic linking. */
- if (! _bfd_elf_link_create_dynamic_sections (abfd, info))
- goto error_return;
-
- if (add_needed)
- {
- /* Add a DT_NEEDED entry for this dynamic object. */
- oldsize = _bfd_elf_strtab_size (hash_table->dynstr);
- strindex = _bfd_elf_strtab_add (hash_table->dynstr, name, FALSE);
- if (strindex == (bfd_size_type) -1)
- goto error_return;
-
- if (oldsize == _bfd_elf_strtab_size (hash_table->dynstr))
- {
- asection *sdyn;
- Elf_External_Dyn *dyncon, *dynconend;
-
- /* The hash table size did not change, which means that
- the dynamic object name was already entered. If we
- have already included this dynamic object in the
- link, just ignore it. There is no reason to include
- a particular dynamic object more than once. */
- sdyn = bfd_get_section_by_name (hash_table->dynobj, ".dynamic");
- BFD_ASSERT (sdyn != NULL);
-
- dyncon = (Elf_External_Dyn *) sdyn->contents;
- dynconend = (Elf_External_Dyn *) (sdyn->contents +
- sdyn->_raw_size);
- for (; dyncon < dynconend; dyncon++)
- {
- Elf_Internal_Dyn dyn;
-
- elf_swap_dyn_in (hash_table->dynobj, dyncon, & dyn);
- if (dyn.d_tag == DT_NEEDED
- && dyn.d_un.d_val == strindex)
- {
- _bfd_elf_strtab_delref (hash_table->dynstr, strindex);
- return TRUE;
- }
- }
- }
-
- if (! elf_add_dynamic_entry (info, DT_NEEDED, strindex))
- goto error_return;
- }
-
- /* Save the SONAME, if there is one, because sometimes the
- linker emulation code will need to know it. */
- if (*name == '\0')
- name = basename (bfd_get_filename (abfd));
- elf_dt_name (abfd) = name;
- }
-
- /* If this is a dynamic object, we always link against the .dynsym
- symbol table, not the .symtab symbol table. The dynamic linker
- will only see the .dynsym symbol table, so there is no reason to
- look at .symtab for a dynamic object. */
-
- if (! dynamic || elf_dynsymtab (abfd) == 0)
- hdr = &elf_tdata (abfd)->symtab_hdr;
- else
- hdr = &elf_tdata (abfd)->dynsymtab_hdr;
-
- symcount = hdr->sh_size / sizeof (Elf_External_Sym);
-
- /* 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. */
- if (elf_bad_symtab (abfd))
- {
- extsymcount = symcount;
- extsymoff = 0;
- }
- else
- {
- extsymcount = symcount - hdr->sh_info;
- extsymoff = hdr->sh_info;
- }
-
- sym_hash = NULL;
- if (extsymcount != 0)
- {
- isymbuf = bfd_elf_get_elf_syms (abfd, hdr, extsymcount, extsymoff,
- NULL, NULL, NULL);
- if (isymbuf == NULL)
- goto error_return;
-
- /* We store a pointer to the hash table entry for each external
- symbol. */
- amt = extsymcount * sizeof (struct elf_link_hash_entry *);
- sym_hash = bfd_alloc (abfd, amt);
- if (sym_hash == NULL)
- goto error_free_sym;
- elf_sym_hashes (abfd) = sym_hash;
- }
-
- if (dynamic)
- {
- /* Read in any version definitions. */
- if (! _bfd_elf_slurp_version_tables (abfd))
- goto error_free_sym;
-
- /* Read in the symbol versions, but don't bother to convert them
- to internal format. */
- if (elf_dynversym (abfd) != 0)
- {
- Elf_Internal_Shdr *versymhdr;
-
- versymhdr = &elf_tdata (abfd)->dynversym_hdr;
- extversym = bfd_malloc (versymhdr->sh_size);
- if (extversym == NULL)
- goto error_free_sym;
- amt = versymhdr->sh_size;
- if (bfd_seek (abfd, versymhdr->sh_offset, SEEK_SET) != 0
- || bfd_bread (extversym, amt, abfd) != amt)
- goto error_free_vers;
- }
- }
-
- weaks = NULL;
-
- ever = extversym != NULL ? extversym + extsymoff : NULL;
- for (isym = isymbuf, isymend = isymbuf + extsymcount;
- isym < isymend;
- isym++, sym_hash++, ever = (ever != NULL ? ever + 1 : NULL))
- {
- int bind;
- bfd_vma value;
- asection *sec;
- flagword flags;
- const char *name;
- struct elf_link_hash_entry *h;
- bfd_boolean definition;
- bfd_boolean size_change_ok;
- bfd_boolean type_change_ok;
- bfd_boolean new_weakdef;
- bfd_boolean override;
- unsigned int old_alignment;
- bfd *old_bfd;
-
- override = FALSE;
-
- flags = BSF_NO_FLAGS;
- sec = NULL;
- value = isym->st_value;
- *sym_hash = NULL;
-
- bind = ELF_ST_BIND (isym->st_info);
- if (bind == STB_LOCAL)
- {
- /* This should be impossible, since ELF requires that all
- global symbols follow all local symbols, and that sh_info
- point to the first global symbol. Unfortunately, Irix 5
- screws this up. */
- continue;
- }
- else if (bind == STB_GLOBAL)
- {
- if (isym->st_shndx != SHN_UNDEF
- && isym->st_shndx != SHN_COMMON)
- flags = BSF_GLOBAL;
- }
- else if (bind == STB_WEAK)
- flags = BSF_WEAK;
- else
- {
- /* Leave it up to the processor backend. */
- }
-
- if (isym->st_shndx == SHN_UNDEF)
- sec = bfd_und_section_ptr;
- else if (isym->st_shndx < SHN_LORESERVE || isym->st_shndx > SHN_HIRESERVE)
- {
- sec = section_from_elf_index (abfd, isym->st_shndx);
- if (sec == NULL)
- sec = bfd_abs_section_ptr;
- else if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
- value -= sec->vma;
- }
- else if (isym->st_shndx == SHN_ABS)
- sec = bfd_abs_section_ptr;
- else if (isym->st_shndx == SHN_COMMON)
- {
- sec = bfd_com_section_ptr;
- /* What ELF calls the size we call the value. What ELF
- calls the value we call the alignment. */
- value = isym->st_size;
- }
- else
- {
- /* Leave it up to the processor backend. */
- }
-
- name = bfd_elf_string_from_elf_section (abfd, hdr->sh_link,
- isym->st_name);
- if (name == NULL)
- goto error_free_vers;
-
- if (isym->st_shndx == SHN_COMMON
- && ELF_ST_TYPE (isym->st_info) == STT_TLS)
- {
- asection *tcomm = bfd_get_section_by_name (abfd, ".tcommon");
-
- if (tcomm == NULL)
- {
- tcomm = bfd_make_section (abfd, ".tcommon");
- if (tcomm == NULL
- || !bfd_set_section_flags (abfd, tcomm, (SEC_ALLOC
- | SEC_IS_COMMON
- | SEC_LINKER_CREATED
- | SEC_THREAD_LOCAL)))
- goto error_free_vers;
- }
- sec = tcomm;
- }
- else if (add_symbol_hook)
- {
- if (! (*add_symbol_hook) (abfd, info, isym, &name, &flags, &sec,
- &value))
- goto error_free_vers;
-
- /* The hook function sets the name to NULL if this symbol
- should be skipped for some reason. */
- if (name == NULL)
- continue;
- }
-
- /* Sanity check that all possibilities were handled. */
- if (sec == NULL)
- {
- bfd_set_error (bfd_error_bad_value);
- goto error_free_vers;
- }
-
- if (bfd_is_und_section (sec)
- || bfd_is_com_section (sec))
- definition = FALSE;
- else
- definition = TRUE;
-
- size_change_ok = FALSE;
- type_change_ok = get_elf_backend_data (abfd)->type_change_ok;
- old_alignment = 0;
- old_bfd = NULL;
-
- if (is_elf_hash_table (hash_table))
- {
- Elf_Internal_Versym iver;
- unsigned int vernum = 0;
- bfd_boolean skip;
-
- if (ever != NULL)
- {
- _bfd_elf_swap_versym_in (abfd, ever, &iver);
- vernum = iver.vs_vers & VERSYM_VERSION;
-
- /* If this is a hidden symbol, or if it is not version
- 1, we append the version name to the symbol name.
- However, we do not modify a non-hidden absolute
- symbol, because it might be the version symbol
- itself. FIXME: What if it isn't? */
- if ((iver.vs_vers & VERSYM_HIDDEN) != 0
- || (vernum > 1 && ! bfd_is_abs_section (sec)))
- {
- const char *verstr;
- size_t namelen, verlen, newlen;
- char *newname, *p;
-
- if (isym->st_shndx != SHN_UNDEF)
- {
- if (vernum > elf_tdata (abfd)->dynverdef_hdr.sh_info)
- {
- (*_bfd_error_handler)
- (_("%s: %s: invalid version %u (max %d)"),
- bfd_archive_filename (abfd), name, vernum,
- elf_tdata (abfd)->dynverdef_hdr.sh_info);
- bfd_set_error (bfd_error_bad_value);
- goto error_free_vers;
- }
- else if (vernum > 1)
- verstr =
- elf_tdata (abfd)->verdef[vernum - 1].vd_nodename;
- else
- verstr = "";
- }
- else
- {
- /* We cannot simply test for the number of
- entries in the VERNEED section since the
- numbers for the needed versions do not start
- at 0. */
- Elf_Internal_Verneed *t;
-
- verstr = NULL;
- for (t = elf_tdata (abfd)->verref;
- t != NULL;
- t = t->vn_nextref)
- {
- Elf_Internal_Vernaux *a;
-
- for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
- {
- if (a->vna_other == vernum)
- {
- verstr = a->vna_nodename;
- break;
- }
- }
- if (a != NULL)
- break;
- }
- if (verstr == NULL)
- {
- (*_bfd_error_handler)
- (_("%s: %s: invalid needed version %d"),
- bfd_archive_filename (abfd), name, vernum);
- bfd_set_error (bfd_error_bad_value);
- goto error_free_vers;
- }
- }
-
- namelen = strlen (name);
- verlen = strlen (verstr);
- newlen = namelen + verlen + 2;
- if ((iver.vs_vers & VERSYM_HIDDEN) == 0
- && isym->st_shndx != SHN_UNDEF)
- ++newlen;
-
- newname = bfd_alloc (abfd, newlen);
- if (newname == NULL)
- goto error_free_vers;
- memcpy (newname, name, namelen);
- p = newname + namelen;
- *p++ = ELF_VER_CHR;
- /* If this is a defined non-hidden version symbol,
- we add another @ to the name. This indicates the
- default version of the symbol. */
- if ((iver.vs_vers & VERSYM_HIDDEN) == 0
- && isym->st_shndx != SHN_UNDEF)
- *p++ = ELF_VER_CHR;
- memcpy (p, verstr, verlen + 1);
-
- name = newname;
- }
- }
-
- if (!_bfd_elf_merge_symbol (abfd, info, name, isym, &sec, &value,
- sym_hash, &skip, &override,
- &type_change_ok, &size_change_ok,
- dt_needed))
- goto error_free_vers;
-
- if (skip)
- continue;
-
- if (override)
- definition = FALSE;
-
- h = *sym_hash;
- 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;
-
- /* Remember the old alignment if this is a common symbol, so
- that we don't reduce the alignment later on. We can't
- check later, because _bfd_generic_link_add_one_symbol
- will set a default for the alignment which we want to
- override. We also remember the old bfd where the existing
- definition comes from. */
- switch (h->root.type)
- {
- default:
- break;
-
- case bfd_link_hash_defined:
- case bfd_link_hash_defweak:
- old_bfd = h->root.u.def.section->owner;
- break;
-
- case bfd_link_hash_common:
- old_bfd = h->root.u.c.p->section->owner;
- old_alignment = h->root.u.c.p->alignment_power;
- break;
- }
-
- if (elf_tdata (abfd)->verdef != NULL
- && ! override
- && vernum > 1
- && definition)
- h->verinfo.verdef = &elf_tdata (abfd)->verdef[vernum - 1];
- }
-
- if (! (_bfd_generic_link_add_one_symbol
- (info, abfd, name, flags, sec, value, NULL, FALSE, collect,
- (struct bfd_link_hash_entry **) sym_hash)))
- goto error_free_vers;
-
- h = *sym_hash;
- 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;
- *sym_hash = h;
-
- new_weakdef = FALSE;
- if (dynamic
- && definition
- && (flags & BSF_WEAK) != 0
- && ELF_ST_TYPE (isym->st_info) != STT_FUNC
- && is_elf_hash_table (hash_table)
- && h->weakdef == NULL)
- {
- /* Keep a list of all weak defined non function symbols from
- a dynamic object, using the weakdef field. Later in this
- function we will set the weakdef field to the correct
- value. We only put non-function symbols from dynamic
- objects on this list, because that happens to be the only
- time we need to know the normal symbol corresponding to a
- weak symbol, and the information is time consuming to
- figure out. If the weakdef field is not already NULL,
- then this symbol was already defined by some previous
- dynamic object, and we will be using that previous
- definition anyhow. */
-
- h->weakdef = weaks;
- weaks = h;
- new_weakdef = TRUE;
- }
-
- /* Set the alignment of a common symbol. */
- if (isym->st_shndx == SHN_COMMON
- && h->root.type == bfd_link_hash_common)
- {
- unsigned int align;
-
- align = bfd_log2 (isym->st_value);
- if (align > old_alignment
- /* Permit an alignment power of zero if an alignment of one
- is specified and no other alignments have been specified. */
- || (isym->st_value == 1 && old_alignment == 0))
- h->root.u.c.p->alignment_power = align;
- else
- h->root.u.c.p->alignment_power = old_alignment;
- }
-
- if (is_elf_hash_table (hash_table))
- {
- int old_flags;
- bfd_boolean dynsym;
- int new_flag;
-
- /* Check the alignment when a common symbol is involved. This
- can change when a common symbol is overridden by a normal
- definition or a common symbol is ignored due to the old
- normal definition. We need to make sure the maximum
- alignment is maintained. */
- if ((old_alignment || isym->st_shndx == SHN_COMMON)
- && h->root.type != bfd_link_hash_common)
- {
- unsigned int common_align;
- unsigned int normal_align;
- unsigned int symbol_align;
- bfd *normal_bfd;
- bfd *common_bfd;
-
- symbol_align = ffs (h->root.u.def.value) - 1;
- if (h->root.u.def.section->owner != NULL
- && (h->root.u.def.section->owner->flags & DYNAMIC) == 0)
- {
- normal_align = h->root.u.def.section->alignment_power;
- if (normal_align > symbol_align)
- normal_align = symbol_align;
- }
- else
- normal_align = symbol_align;
-
- if (old_alignment)
- {
- common_align = old_alignment;
- common_bfd = old_bfd;
- normal_bfd = abfd;
- }
- else
- {
- common_align = bfd_log2 (isym->st_value);
- common_bfd = abfd;
- normal_bfd = old_bfd;
- }
-
- if (normal_align < common_align)
- (*_bfd_error_handler)
- (_("Warning: alignment %u of symbol `%s' in %s is smaller than %u in %s"),
- 1 << normal_align,
- name,
- bfd_archive_filename (normal_bfd),
- 1 << common_align,
- bfd_archive_filename (common_bfd));
- }
-
- /* Remember the symbol size and type. */
- if (isym->st_size != 0
- && (definition || h->size == 0))
- {
- if (h->size != 0 && h->size != isym->st_size && ! size_change_ok)
- (*_bfd_error_handler)
- (_("Warning: size of symbol `%s' changed from %lu in %s to %lu in %s"),
- name, (unsigned long) h->size,
- bfd_archive_filename (old_bfd),
- (unsigned long) isym->st_size,
- bfd_archive_filename (abfd));
-
- h->size = isym->st_size;
- }
-
- /* If this is a common symbol, then we always want H->SIZE
- to be the size of the common symbol. The code just above
- won't fix the size if a common symbol becomes larger. We
- don't warn about a size change here, because that is
- covered by --warn-common. */
- if (h->root.type == bfd_link_hash_common)
- h->size = h->root.u.c.size;
-
- if (ELF_ST_TYPE (isym->st_info) != STT_NOTYPE
- && (definition || h->type == STT_NOTYPE))
- {
- if (h->type != STT_NOTYPE
- && h->type != ELF_ST_TYPE (isym->st_info)
- && ! type_change_ok)
- (*_bfd_error_handler)
- (_("Warning: type of symbol `%s' changed from %d to %d in %s"),
- name, h->type, ELF_ST_TYPE (isym->st_info),
- bfd_archive_filename (abfd));
-
- h->type = ELF_ST_TYPE (isym->st_info);
- }
-
- /* If st_other has a processor-specific meaning, specific
- code might be needed here. We never merge the visibility
- attribute with the one from a dynamic object. */
- if (bed->elf_backend_merge_symbol_attribute)
- (*bed->elf_backend_merge_symbol_attribute) (h, isym, definition,
- dynamic);
-
- if (isym->st_other != 0 && !dynamic)
- {
- unsigned char hvis, symvis, other, nvis;
-
- /* Take the balance of OTHER from the definition. */
- other = (definition ? isym->st_other : h->other);
- other &= ~ ELF_ST_VISIBILITY (-1);
-
- /* Combine visibilities, using the most constraining one. */
- hvis = ELF_ST_VISIBILITY (h->other);
- symvis = ELF_ST_VISIBILITY (isym->st_other);
- if (! hvis)
- nvis = symvis;
- else if (! symvis)
- nvis = hvis;
- else
- nvis = hvis < symvis ? hvis : symvis;
-
- h->other = other | nvis;
- }
-
- /* Set a flag in the hash table entry indicating the type of
- reference or definition we just found. Keep a count of
- the number of dynamic symbols we find. A dynamic symbol
- is one which is referenced or defined by both a regular
- object and a shared object. */
- old_flags = h->elf_link_hash_flags;
- dynsym = FALSE;
- if (! dynamic)
- {
- if (! definition)
- {
- new_flag = ELF_LINK_HASH_REF_REGULAR;
- if (bind != STB_WEAK)
- new_flag |= ELF_LINK_HASH_REF_REGULAR_NONWEAK;
- }
- else
- new_flag = ELF_LINK_HASH_DEF_REGULAR;
- if (! info->executable
- || (old_flags & (ELF_LINK_HASH_DEF_DYNAMIC
- | ELF_LINK_HASH_REF_DYNAMIC)) != 0)
- dynsym = TRUE;
- }
- else
- {
- if (! definition)
- new_flag = ELF_LINK_HASH_REF_DYNAMIC;
- else
- new_flag = ELF_LINK_HASH_DEF_DYNAMIC;
- if ((old_flags & (ELF_LINK_HASH_DEF_REGULAR
- | ELF_LINK_HASH_REF_REGULAR)) != 0
- || (h->weakdef != NULL
- && ! new_weakdef
- && h->weakdef->dynindx != -1))
- dynsym = TRUE;
- }
-
- h->elf_link_hash_flags |= new_flag;
-
- /* Check to see if we need to add an indirect symbol for
- the default name. */
- if (definition || h->root.type == bfd_link_hash_common)
- if (!_bfd_elf_add_default_symbol (abfd, info, h, name, isym,
- &sec, &value, &dynsym,
- override, dt_needed))
- goto error_free_vers;
-
- if (definition && !dynamic)
- {
- char *p = strchr (name, ELF_VER_CHR);
- if (p != NULL && p[1] != ELF_VER_CHR)
- {
- /* Queue non-default versions so that .symver x, x@FOO
- aliases can be checked. */
- if (! nondeflt_vers)
- {
- amt = (isymend - isym + 1)
- * sizeof (struct elf_link_hash_entry *);
- nondeflt_vers = bfd_malloc (amt);
- }
- nondeflt_vers [nondeflt_vers_cnt++] = h;
- }
- }
-
- if (dynsym && h->dynindx == -1)
- {
- 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))
- goto error_free_vers;
- }
- }
- else if (dynsym && h->dynindx != -1)
- /* If the symbol already has a dynamic index, but
- visibility says it should not be visible, turn it into
- a local symbol. */
- switch (ELF_ST_VISIBILITY (h->other))
- {
- case STV_INTERNAL:
- case STV_HIDDEN:
- (*bed->elf_backend_hide_symbol) (info, h, TRUE);
- break;
- }
-
- if (dt_needed && definition
- && (h->elf_link_hash_flags
- & ELF_LINK_HASH_REF_REGULAR) != 0)
- {
- bfd_size_type oldsize;
- bfd_size_type strindex;
-
- /* The symbol from a DT_NEEDED object is referenced from
- the regular object to create a dynamic executable. We
- have to make sure there is a DT_NEEDED entry for it. */
-
- dt_needed = FALSE;
- oldsize = _bfd_elf_strtab_size (hash_table->dynstr);
- strindex = _bfd_elf_strtab_add (hash_table->dynstr,
- elf_dt_soname (abfd), FALSE);
- if (strindex == (bfd_size_type) -1)
- goto error_free_vers;
-
- if (oldsize == _bfd_elf_strtab_size (hash_table->dynstr))
- {
- asection *sdyn;
- Elf_External_Dyn *dyncon, *dynconend;
-
- sdyn = bfd_get_section_by_name (hash_table->dynobj,
- ".dynamic");
- BFD_ASSERT (sdyn != NULL);
-
- dyncon = (Elf_External_Dyn *) sdyn->contents;
- dynconend = (Elf_External_Dyn *) (sdyn->contents +
- sdyn->_raw_size);
- for (; dyncon < dynconend; dyncon++)
- {
- Elf_Internal_Dyn dyn;
-
- elf_swap_dyn_in (hash_table->dynobj,
- dyncon, &dyn);
- BFD_ASSERT (dyn.d_tag != DT_NEEDED ||
- dyn.d_un.d_val != strindex);
- }
- }
-
- if (! elf_add_dynamic_entry (info, DT_NEEDED, strindex))
- goto error_free_vers;
- }
- }
- }
-
- /* Now that all the symbols from this input file are created, handle
- .symver foo, foo@BAR such that any relocs against foo become foo@BAR. */
- if (nondeflt_vers != NULL)
- {
- bfd_size_type cnt, symidx;
-
- for (cnt = 0; cnt < nondeflt_vers_cnt; ++cnt)
- {
- struct elf_link_hash_entry *h = nondeflt_vers[cnt], *hi;
- char *shortname, *p;
-
- p = strchr (h->root.root.string, ELF_VER_CHR);
- if (p == NULL
- || (h->root.type != bfd_link_hash_defined
- && h->root.type != bfd_link_hash_defweak))
- continue;
-
- amt = p - h->root.root.string;
- shortname = bfd_malloc (amt + 1);
- memcpy (shortname, h->root.root.string, amt);
- shortname[amt] = '\0';
-
- hi = (struct elf_link_hash_entry *)
- bfd_link_hash_lookup (&hash_table->root, shortname,
- FALSE, FALSE, FALSE);
- if (hi != NULL
- && hi->root.type == h->root.type
- && hi->root.u.def.value == h->root.u.def.value
- && hi->root.u.def.section == h->root.u.def.section)
- {
- (*bed->elf_backend_hide_symbol) (info, hi, TRUE);
- hi->root.type = bfd_link_hash_indirect;
- hi->root.u.i.link = (struct bfd_link_hash_entry *) h;
- (*bed->elf_backend_copy_indirect_symbol) (bed, h, hi);
- sym_hash = elf_sym_hashes (abfd);
- if (sym_hash)
- for (symidx = 0; symidx < extsymcount; ++symidx)
- if (sym_hash[symidx] == hi)
- {
- sym_hash[symidx] = h;
- break;
- }
- }
- free (shortname);
- }
- free (nondeflt_vers);
- nondeflt_vers = NULL;
- }
-
- if (extversym != NULL)
- {
- free (extversym);
- extversym = NULL;
- }
-
- if (isymbuf != NULL)
- free (isymbuf);
- isymbuf = NULL;
-
- /* Now set the weakdefs field correctly for all the weak defined
- symbols we found. The only way to do this is to search all the
- symbols. Since we only need the information for non functions in
- dynamic objects, that's the only time we actually put anything on
- the list WEAKS. We need this information so that if a regular
- object refers to a symbol defined weakly in a dynamic object, the
- real symbol in the dynamic object is also put in the dynamic
- symbols; we also must arrange for both symbols to point to the
- same memory location. We could handle the general case of symbol
- aliasing, but a general symbol alias can only be generated in
- assembler code, handling it correctly would be very time
- consuming, and other ELF linkers don't handle general aliasing
- either. */
- while (weaks != NULL)
- {
- struct elf_link_hash_entry *hlook;
- asection *slook;
- bfd_vma vlook;
- struct elf_link_hash_entry **hpp;
- struct elf_link_hash_entry **hppend;
-
- hlook = weaks;
- weaks = hlook->weakdef;
- hlook->weakdef = NULL;
-
- BFD_ASSERT (hlook->root.type == bfd_link_hash_defined
- || hlook->root.type == bfd_link_hash_defweak
- || hlook->root.type == bfd_link_hash_common
- || hlook->root.type == bfd_link_hash_indirect);
- slook = hlook->root.u.def.section;
- vlook = hlook->root.u.def.value;
-
- hpp = elf_sym_hashes (abfd);
- hppend = hpp + extsymcount;
- for (; hpp < hppend; hpp++)
- {
- struct elf_link_hash_entry *h;
-
- h = *hpp;
- if (h != NULL && h != hlook
- && h->root.type == bfd_link_hash_defined
- && h->root.u.def.section == slook
- && h->root.u.def.value == vlook)
- {
- hlook->weakdef = h;
-
- /* If the weak definition is in the list of dynamic
- symbols, make sure the real definition is put there
- as well. */
- if (hlook->dynindx != -1
- && h->dynindx == -1)
- {
- if (! _bfd_elf_link_record_dynamic_symbol (info, h))
- goto error_return;
- }
-
- /* If the real definition is in the list of dynamic
- symbols, make sure the weak definition is put there
- as well. If we don't do this, then the dynamic
- loader might not merge the entries for the real
- definition and the weak definition. */
- if (h->dynindx != -1
- && hlook->dynindx == -1)
- {
- if (! _bfd_elf_link_record_dynamic_symbol (info, hlook))
- goto error_return;
- }
- break;
- }
- }
- }
-
- /* If this object is the same format as the output object, and it is
- not a shared library, then let the backend look through the
- relocs.
-
- This is required to build global offset table entries and to
- arrange for dynamic relocs. It is not required for the
- particular common case of linking non PIC code, even when linking
- against shared libraries, but unfortunately there is no way of
- knowing whether an object file has been compiled PIC or not.
- Looking through the relocs is not particularly time consuming.
- The problem is that we must either (1) keep the relocs in memory,
- which causes the linker to require additional runtime memory or
- (2) read the relocs twice from the input file, which wastes time.
- This would be a good case for using mmap.
-
- I have no idea how to handle linking PIC code into a file of a
- different format. It probably can't be done. */
- check_relocs = get_elf_backend_data (abfd)->check_relocs;
- if (! dynamic
- && is_elf_hash_table (hash_table)
- && hash_table->root.creator == abfd->xvec
- && check_relocs != NULL)
- {
- asection *o;
-
- for (o = abfd->sections; o != NULL; o = o->next)
- {
- Elf_Internal_Rela *internal_relocs;
- bfd_boolean ok;
-
- if ((o->flags & SEC_RELOC) == 0
- || o->reloc_count == 0
- || ((info->strip == strip_all || info->strip == strip_debugger)
- && (o->flags & SEC_DEBUGGING) != 0)
- || bfd_is_abs_section (o->output_section))
- continue;
-
- internal_relocs = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL,
- info->keep_memory);
- if (internal_relocs == NULL)
- goto error_return;
-
- ok = (*check_relocs) (abfd, info, o, internal_relocs);
-
- if (elf_section_data (o)->relocs != internal_relocs)
- free (internal_relocs);
-
- if (! ok)
- goto error_return;
- }
- }
-
- /* If this is a non-traditional link, try to optimize the handling
- of the .stab/.stabstr sections. */
- if (! dynamic
- && ! info->traditional_format
- && is_elf_hash_table (hash_table)
- && (info->strip != strip_all && info->strip != strip_debugger))
- {
- asection *stabstr;
-
- stabstr = bfd_get_section_by_name (abfd, ".stabstr");
- if (stabstr != NULL)
- {
- bfd_size_type string_offset = 0;
- asection *stab;
-
- for (stab = abfd->sections; stab; stab = stab->next)
- if (strncmp (".stab", stab->name, 5) == 0
- && (!stab->name[5] ||
- (stab->name[5] == '.' && ISDIGIT (stab->name[6])))
- && (stab->flags & SEC_MERGE) == 0
- && !bfd_is_abs_section (stab->output_section))
- {
- struct bfd_elf_section_data *secdata;
-
- secdata = elf_section_data (stab);
- if (! _bfd_link_section_stabs (abfd,
- & hash_table->stab_info,
- stab, stabstr,
- &secdata->sec_info,
- &string_offset))
- goto error_return;
- if (secdata->sec_info)
- stab->sec_info_type = ELF_INFO_TYPE_STABS;
- }
- }
- }
-
- if (! info->relocatable
- && ! dynamic
- && is_elf_hash_table (hash_table))
- {
- asection *s;
-
- for (s = abfd->sections; s != NULL; s = s->next)
- if ((s->flags & SEC_MERGE) != 0
- && !bfd_is_abs_section (s->output_section))
- {
- struct bfd_elf_section_data *secdata;
-
- secdata = elf_section_data (s);
- if (! _bfd_merge_section (abfd,
- & hash_table->merge_info,
- s, &secdata->sec_info))
- goto error_return;
- else if (secdata->sec_info)
- s->sec_info_type = ELF_INFO_TYPE_MERGE;
- }
- }
-
- if (is_elf_hash_table (hash_table))
- {
- /* Add this bfd to the loaded list. */
- struct elf_link_loaded_list *n;
-
- n = bfd_alloc (abfd, sizeof (struct elf_link_loaded_list));
- if (n == NULL)
- goto error_return;
- n->abfd = abfd;
- n->next = hash_table->loaded;
- hash_table->loaded = n;
- }
-
- return TRUE;
-
- error_free_vers:
- if (nondeflt_vers != NULL)
- free (nondeflt_vers);
- if (extversym != NULL)
- free (extversym);
- error_free_sym:
- if (isymbuf != NULL)
- free (isymbuf);
- error_return:
- return FALSE;
-}
-
-/* Add an entry to the .dynamic table. */
-
-bfd_boolean
-elf_add_dynamic_entry (struct bfd_link_info *info, bfd_vma tag, bfd_vma val)
-{
- Elf_Internal_Dyn dyn;
- bfd *dynobj;
- asection *s;
- bfd_size_type newsize;
- bfd_byte *newcontents;
-
- if (! is_elf_hash_table (info->hash))
- return FALSE;
-
- dynobj = elf_hash_table (info)->dynobj;
-
- s = bfd_get_section_by_name (dynobj, ".dynamic");
- BFD_ASSERT (s != NULL);
-
- newsize = s->_raw_size + sizeof (Elf_External_Dyn);
- newcontents = bfd_realloc (s->contents, newsize);
- if (newcontents == NULL)
- return FALSE;
-
- dyn.d_tag = tag;
- dyn.d_un.d_val = val;
- elf_swap_dyn_out (dynobj, &dyn,
- (Elf_External_Dyn *) (newcontents + s->_raw_size));
-
- s->_raw_size = newsize;
- s->contents = newcontents;
-
- return TRUE;
-}
-
-/* Array used to determine the number of hash table buckets to use
- based on the number of symbols there are. If there are fewer than
- 3 symbols we use 1 bucket, fewer than 17 symbols we use 3 buckets,
- fewer than 37 we use 17 buckets, and so forth. We never use more
- than 32771 buckets. */
-
-static const size_t elf_buckets[] =
-{
- 1, 3, 17, 37, 67, 97, 131, 197, 263, 521, 1031, 2053, 4099, 8209,
- 16411, 32771, 0
-};
-
-/* Compute bucket count for hashing table. We do not use a static set
- of possible tables sizes anymore. Instead we determine for all
- possible reasonable sizes of the table the outcome (i.e., the
- number of collisions etc) and choose the best solution. The
- weighting functions are not too simple to allow the table to grow
- without bounds. Instead one of the weighting factors is the size.
- Therefore the result is always a good payoff between few collisions
- (= short chain lengths) and table size. */
-static size_t
-compute_bucket_count (struct bfd_link_info *info)
-{
- size_t dynsymcount = elf_hash_table (info)->dynsymcount;
- size_t best_size = 0;
- unsigned long int *hashcodes;
- unsigned long int *hashcodesp;
- unsigned long int i;
- bfd_size_type amt;
-
- /* Compute the hash values for all exported symbols. At the same
- time store the values in an array so that we could use them for
- optimizations. */
- amt = dynsymcount;
- amt *= sizeof (unsigned long int);
- hashcodes = bfd_malloc (amt);
- if (hashcodes == NULL)
- return 0;
- hashcodesp = hashcodes;
-
- /* Put all hash values in HASHCODES. */
- elf_link_hash_traverse (elf_hash_table (info),
- elf_collect_hash_codes, &hashcodesp);
-
- /* We have a problem here. The following code to optimize the table
- size requires an integer type with more the 32 bits. If
- BFD_HOST_U_64_BIT is set we know about such a type. */
-#ifdef BFD_HOST_U_64_BIT
- if (info->optimize)
- {
- unsigned long int nsyms = hashcodesp - hashcodes;
- size_t minsize;
- size_t maxsize;
- BFD_HOST_U_64_BIT best_chlen = ~((BFD_HOST_U_64_BIT) 0);
- unsigned long int *counts ;
-
- /* Possible optimization parameters: if we have NSYMS symbols we say
- that the hashing table must at least have NSYMS/4 and at most
- 2*NSYMS buckets. */
- minsize = nsyms / 4;
- if (minsize == 0)
- minsize = 1;
- best_size = maxsize = nsyms * 2;
-
- /* Create array where we count the collisions in. We must use bfd_malloc
- since the size could be large. */
- amt = maxsize;
- amt *= sizeof (unsigned long int);
- counts = bfd_malloc (amt);
- if (counts == NULL)
- {
- free (hashcodes);
- return 0;
- }
-
- /* Compute the "optimal" size for the hash table. The criteria is a
- minimal chain length. The minor criteria is (of course) the size
- of the table. */
- for (i = minsize; i < maxsize; ++i)
- {
- /* Walk through the array of hashcodes and count the collisions. */
- BFD_HOST_U_64_BIT max;
- unsigned long int j;
- unsigned long int fact;
-
- memset (counts, '\0', i * sizeof (unsigned long int));
-
- /* Determine how often each hash bucket is used. */
- for (j = 0; j < nsyms; ++j)
- ++counts[hashcodes[j] % i];
-
- /* For the weight function we need some information about the
- pagesize on the target. This is information need not be 100%
- accurate. Since this information is not available (so far) we
- define it here to a reasonable default value. If it is crucial
- to have a better value some day simply define this value. */
-# ifndef BFD_TARGET_PAGESIZE
-# define BFD_TARGET_PAGESIZE (4096)
-# endif
-
- /* We in any case need 2 + NSYMS entries for the size values and
- the chains. */
- max = (2 + nsyms) * (ARCH_SIZE / 8);
-
-# if 1
- /* Variant 1: optimize for short chains. We add the squares
- of all the chain lengths (which favors many small chain
- over a few long chains). */
- for (j = 0; j < i; ++j)
- max += counts[j] * counts[j];
-
- /* This adds penalties for the overall size of the table. */
- fact = i / (BFD_TARGET_PAGESIZE / (ARCH_SIZE / 8)) + 1;
- max *= fact * fact;
-# else
- /* Variant 2: Optimize a lot more for small table. Here we
- also add squares of the size but we also add penalties for
- empty slots (the +1 term). */
- for (j = 0; j < i; ++j)
- max += (1 + counts[j]) * (1 + counts[j]);
-
- /* The overall size of the table is considered, but not as
- strong as in variant 1, where it is squared. */
- fact = i / (BFD_TARGET_PAGESIZE / (ARCH_SIZE / 8)) + 1;
- max *= fact;
-# endif
-
- /* Compare with current best results. */
- if (max < best_chlen)
- {
- best_chlen = max;
- best_size = i;
- }
- }
-
- free (counts);
- }
- else
-#endif /* defined (BFD_HOST_U_64_BIT) */
- {
- /* This is the fallback solution if no 64bit type is available or if we
- are not supposed to spend much time on optimizations. We select the
- bucket count using a fixed set of numbers. */
- for (i = 0; elf_buckets[i] != 0; i++)
- {
- best_size = elf_buckets[i];
- if (dynsymcount < elf_buckets[i + 1])
- break;
- }
- }
-
- /* Free the arrays we needed. */
- free (hashcodes);
-
- return best_size;
-}
-
-/* Set up the sizes and contents of the ELF dynamic sections. This is
- called by the ELF linker emulation before_allocation routine. We
- must set the sizes of the sections before the linker sets the
- addresses of the various sections. */
-
-bfd_boolean
-NAME(bfd_elf,size_dynamic_sections) (bfd *output_bfd,
- const char *soname,
- const char *rpath,
- const char *filter_shlib,
- const char * const *auxiliary_filters,
- struct bfd_link_info *info,
- asection **sinterpptr,
- struct bfd_elf_version_tree *verdefs)
-{
- bfd_size_type soname_indx;
- bfd *dynobj;
- const struct elf_backend_data *bed;
- struct elf_assign_sym_version_info asvinfo;
-
- *sinterpptr = NULL;
-
- soname_indx = (bfd_size_type) -1;
-
- if (!is_elf_hash_table (info->hash))
- return TRUE;
-
- if (info->execstack)
- elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | PF_X;
- else if (info->noexecstack)
- elf_tdata (output_bfd)->stack_flags = PF_R | PF_W;
- else
- {
- bfd *inputobj;
- asection *notesec = NULL;
- int exec = 0;
-
- for (inputobj = info->input_bfds;
- inputobj;
- inputobj = inputobj->link_next)
- {
- asection *s;
-
- if (inputobj->flags & DYNAMIC)
- continue;
- s = bfd_get_section_by_name (inputobj, ".note.GNU-stack");
- if (s)
- {
- if (s->flags & SEC_CODE)
- exec = PF_X;
- notesec = s;
- }
- else
- exec = PF_X;
- }
- if (notesec)
- {
- elf_tdata (output_bfd)->stack_flags = PF_R | PF_W | exec;
- if (exec && info->relocatable
- && notesec->output_section != bfd_abs_section_ptr)
- notesec->output_section->flags |= SEC_CODE;
- }
- }
-
- /* Any syms created from now on start with -1 in
- got.refcount/offset and plt.refcount/offset. */
- elf_hash_table (info)->init_refcount = elf_hash_table (info)->init_offset;
-
- /* The backend may have to create some sections regardless of whether
- we're dynamic or not. */
- bed = get_elf_backend_data (output_bfd);
- if (bed->elf_backend_always_size_sections
- && ! (*bed->elf_backend_always_size_sections) (output_bfd, info))
- return FALSE;
-
- dynobj = elf_hash_table (info)->dynobj;
-
- /* If there were no dynamic objects in the link, there is nothing to
- do here. */
- if (dynobj == NULL)
- return TRUE;
-
- if (! _bfd_elf_maybe_strip_eh_frame_hdr (info))
- return FALSE;
-
- if (elf_hash_table (info)->dynamic_sections_created)
- {
- struct elf_info_failed eif;
- struct elf_link_hash_entry *h;
- asection *dynstr;
- struct bfd_elf_version_tree *t;
- struct bfd_elf_version_expr *d;
- bfd_boolean all_defined;
-
- *sinterpptr = bfd_get_section_by_name (dynobj, ".interp");
- BFD_ASSERT (*sinterpptr != NULL || !info->executable);
-
- if (soname != NULL)
- {
- soname_indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
- soname, TRUE);
- if (soname_indx == (bfd_size_type) -1
- || ! elf_add_dynamic_entry (info, DT_SONAME, soname_indx))
- return FALSE;
- }
-
- if (info->symbolic)
- {
- if (! elf_add_dynamic_entry (info, DT_SYMBOLIC, 0))
- return FALSE;
- info->flags |= DF_SYMBOLIC;
- }
-
- if (rpath != NULL)
- {
- bfd_size_type indx;
-
- indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr, rpath,
- TRUE);
- if (info->new_dtags)
- _bfd_elf_strtab_addref (elf_hash_table (info)->dynstr, indx);
- if (indx == (bfd_size_type) -1
- || ! elf_add_dynamic_entry (info, DT_RPATH, indx)
- || (info->new_dtags
- && ! elf_add_dynamic_entry (info, DT_RUNPATH, indx)))
- return FALSE;
- }
-
- if (filter_shlib != NULL)
- {
- bfd_size_type indx;
-
- indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
- filter_shlib, TRUE);
- if (indx == (bfd_size_type) -1
- || ! elf_add_dynamic_entry (info, DT_FILTER, indx))
- return FALSE;
- }
-
- if (auxiliary_filters != NULL)
- {
- const char * const *p;
-
- for (p = auxiliary_filters; *p != NULL; p++)
- {
- bfd_size_type indx;
-
- indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
- *p, TRUE);
- if (indx == (bfd_size_type) -1
- || ! elf_add_dynamic_entry (info, DT_AUXILIARY, indx))
- return FALSE;
- }
- }
-
- eif.info = info;
- eif.verdefs = verdefs;
- eif.failed = FALSE;
-
- /* If we are supposed to export all symbols into the dynamic symbol
- table (this is not the normal case), then do so. */
- if (info->export_dynamic)
- {
- elf_link_hash_traverse (elf_hash_table (info),
- _bfd_elf_export_symbol,
- &eif);
- if (eif.failed)
- return FALSE;
- }
-
- /* Make all global versions with definition. */
- for (t = verdefs; t != NULL; t = t->next)
- for (d = t->globals.list; d != NULL; d = d->next)
- if (!d->symver && d->symbol)
- {
- const char *verstr, *name;
- size_t namelen, verlen, newlen;
- char *newname, *p;
- struct elf_link_hash_entry *newh;
-
- name = d->symbol;
- namelen = strlen (name);
- verstr = t->name;
- verlen = strlen (verstr);
- newlen = namelen + verlen + 3;
-
- newname = bfd_malloc (newlen);
- if (newname == NULL)
- return FALSE;
- memcpy (newname, name, namelen);
-
- /* Check the hidden versioned definition. */
- p = newname + namelen;
- *p++ = ELF_VER_CHR;
- memcpy (p, verstr, verlen + 1);
- newh = elf_link_hash_lookup (elf_hash_table (info),
- newname, FALSE, FALSE,
- FALSE);
- if (newh == NULL
- || (newh->root.type != bfd_link_hash_defined
- && newh->root.type != bfd_link_hash_defweak))
- {
- /* Check the default versioned definition. */
- *p++ = ELF_VER_CHR;
- memcpy (p, verstr, verlen + 1);
- newh = elf_link_hash_lookup (elf_hash_table (info),
- newname, FALSE, FALSE,
- FALSE);
- }
- free (newname);
-
- /* Mark this version if there is a definition and it is
- not defined in a shared object. */
- if (newh != NULL
- && ((newh->elf_link_hash_flags
- & ELF_LINK_HASH_DEF_DYNAMIC) == 0)
- && (newh->root.type == bfd_link_hash_defined
- || newh->root.type == bfd_link_hash_defweak))
- d->symver = 1;
- }
-
- /* Attach all the symbols to their version information. */
- asvinfo.output_bfd = output_bfd;
- asvinfo.info = info;
- asvinfo.verdefs = verdefs;
- asvinfo.failed = FALSE;
-
- elf_link_hash_traverse (elf_hash_table (info),
- _bfd_elf_link_assign_sym_version,
- &asvinfo);
- if (asvinfo.failed)
- return FALSE;
-
- if (!info->allow_undefined_version)
- {
- /* Check if all global versions have a definition. */
- all_defined = TRUE;
- for (t = verdefs; t != NULL; t = t->next)
- for (d = t->globals.list; d != NULL; d = d->next)
- if (!d->symver && !d->script)
- {
- (*_bfd_error_handler)
- (_("%s: undefined version: %s"),
- d->pattern, t->name);
- all_defined = FALSE;
- }
-
- if (!all_defined)
- {
- bfd_set_error (bfd_error_bad_value);
- return FALSE;
- }
- }
-
- /* Find all symbols which were defined in a dynamic object and make
- the backend pick a reasonable value for them. */
- elf_link_hash_traverse (elf_hash_table (info),
- _bfd_elf_adjust_dynamic_symbol,
- &eif);
- if (eif.failed)
- return FALSE;
-
- /* Add some entries to the .dynamic section. We fill in some of the
- values later, in elf_bfd_final_link, but we must add the entries
- now so that we know the final size of the .dynamic section. */
-
- /* If there are initialization and/or finalization functions to
- call then add the corresponding DT_INIT/DT_FINI entries. */
- h = (info->init_function
- ? elf_link_hash_lookup (elf_hash_table (info),
- info->init_function, FALSE,
- FALSE, FALSE)
- : NULL);
- if (h != NULL
- && (h->elf_link_hash_flags & (ELF_LINK_HASH_REF_REGULAR
- | ELF_LINK_HASH_DEF_REGULAR)) != 0)
- {
- if (! elf_add_dynamic_entry (info, DT_INIT, 0))
- return FALSE;
- }
- h = (info->fini_function
- ? elf_link_hash_lookup (elf_hash_table (info),
- info->fini_function, FALSE,
- FALSE, FALSE)
- : NULL);
- if (h != NULL
- && (h->elf_link_hash_flags & (ELF_LINK_HASH_REF_REGULAR
- | ELF_LINK_HASH_DEF_REGULAR)) != 0)
- {
- if (! elf_add_dynamic_entry (info, DT_FINI, 0))
- return FALSE;
- }
-
- if (bfd_get_section_by_name (output_bfd, ".preinit_array") != NULL)
- {
- /* DT_PREINIT_ARRAY is not allowed in shared library. */
- if (! info->executable)
- {
- bfd *sub;
- asection *o;
-
- for (sub = info->input_bfds; sub != NULL;
- sub = sub->link_next)
- for (o = sub->sections; o != NULL; o = o->next)
- if (elf_section_data (o)->this_hdr.sh_type
- == SHT_PREINIT_ARRAY)
- {
- (*_bfd_error_handler)
- (_("%s: .preinit_array section is not allowed in DSO"),
- bfd_archive_filename (sub));
- break;
- }
-
- bfd_set_error (bfd_error_nonrepresentable_section);
- return FALSE;
- }
-
- if (!elf_add_dynamic_entry (info, DT_PREINIT_ARRAY, 0)
- || !elf_add_dynamic_entry (info, DT_PREINIT_ARRAYSZ, 0))
- return FALSE;
- }
- if (bfd_get_section_by_name (output_bfd, ".init_array") != NULL)
- {
- if (!elf_add_dynamic_entry (info, DT_INIT_ARRAY, 0)
- || !elf_add_dynamic_entry (info, DT_INIT_ARRAYSZ, 0))
- return FALSE;
- }
- if (bfd_get_section_by_name (output_bfd, ".fini_array") != NULL)
- {
- if (!elf_add_dynamic_entry (info, DT_FINI_ARRAY, 0)
- || !elf_add_dynamic_entry (info, DT_FINI_ARRAYSZ, 0))
- return FALSE;
- }
-
- dynstr = bfd_get_section_by_name (dynobj, ".dynstr");
- /* If .dynstr is excluded from the link, we don't want any of
- these tags. Strictly, we should be checking each section
- individually; This quick check covers for the case where
- someone does a /DISCARD/ : { *(*) }. */
- if (dynstr != NULL && dynstr->output_section != bfd_abs_section_ptr)
- {
- bfd_size_type strsize;
-
- strsize = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
- if (! elf_add_dynamic_entry (info, DT_HASH, 0)
- || ! elf_add_dynamic_entry (info, DT_STRTAB, 0)
- || ! elf_add_dynamic_entry (info, DT_SYMTAB, 0)
- || ! elf_add_dynamic_entry (info, DT_STRSZ, strsize)
- || ! elf_add_dynamic_entry (info, DT_SYMENT,
- sizeof (Elf_External_Sym)))
- return FALSE;
- }
- }
-
- /* The backend must work out the sizes of all the other dynamic
- sections. */
- if (bed->elf_backend_size_dynamic_sections
- && ! (*bed->elf_backend_size_dynamic_sections) (output_bfd, info))
- return FALSE;
-
- if (elf_hash_table (info)->dynamic_sections_created)
- {
- bfd_size_type dynsymcount;
- asection *s;
- size_t bucketcount = 0;
- size_t hash_entry_size;
- unsigned int dtagcount;
-
- /* Set up the version definition section. */
- s = bfd_get_section_by_name (dynobj, ".gnu.version_d");
- BFD_ASSERT (s != NULL);
-
- /* We may have created additional version definitions if we are
- just linking a regular application. */
- verdefs = asvinfo.verdefs;
-
- /* Skip anonymous version tag. */
- if (verdefs != NULL && verdefs->vernum == 0)
- verdefs = verdefs->next;
-
- if (verdefs == NULL)
- _bfd_strip_section_from_output (info, s);
- else
- {
- unsigned int cdefs;
- bfd_size_type size;
- struct bfd_elf_version_tree *t;
- bfd_byte *p;
- Elf_Internal_Verdef def;
- Elf_Internal_Verdaux defaux;
-
- cdefs = 0;
- size = 0;
-
- /* Make space for the base version. */
- size += sizeof (Elf_External_Verdef);
- size += sizeof (Elf_External_Verdaux);
- ++cdefs;
-
- for (t = verdefs; t != NULL; t = t->next)
- {
- struct bfd_elf_version_deps *n;
-
- size += sizeof (Elf_External_Verdef);
- size += sizeof (Elf_External_Verdaux);
- ++cdefs;
-
- for (n = t->deps; n != NULL; n = n->next)
- size += sizeof (Elf_External_Verdaux);
- }
-
- s->_raw_size = size;
- s->contents = bfd_alloc (output_bfd, s->_raw_size);
- if (s->contents == NULL && s->_raw_size != 0)
- return FALSE;
-
- /* Fill in the version definition section. */
-
- p = s->contents;
-
- def.vd_version = VER_DEF_CURRENT;
- def.vd_flags = VER_FLG_BASE;
- def.vd_ndx = 1;
- def.vd_cnt = 1;
- def.vd_aux = sizeof (Elf_External_Verdef);
- def.vd_next = (sizeof (Elf_External_Verdef)
- + sizeof (Elf_External_Verdaux));
-
- if (soname_indx != (bfd_size_type) -1)
- {
- _bfd_elf_strtab_addref (elf_hash_table (info)->dynstr,
- soname_indx);
- def.vd_hash = bfd_elf_hash (soname);
- defaux.vda_name = soname_indx;
- }
- else
- {
- const char *name;
- bfd_size_type indx;
-
- name = basename (output_bfd->filename);
- def.vd_hash = bfd_elf_hash (name);
- indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
- name, FALSE);
- if (indx == (bfd_size_type) -1)
- return FALSE;
- defaux.vda_name = indx;
- }
- defaux.vda_next = 0;
-
- _bfd_elf_swap_verdef_out (output_bfd, &def,
- (Elf_External_Verdef *) p);
- p += sizeof (Elf_External_Verdef);
- _bfd_elf_swap_verdaux_out (output_bfd, &defaux,
- (Elf_External_Verdaux *) p);
- p += sizeof (Elf_External_Verdaux);
-
- for (t = verdefs; t != NULL; t = t->next)
- {
- unsigned int cdeps;
- struct bfd_elf_version_deps *n;
- struct elf_link_hash_entry *h;
- struct bfd_link_hash_entry *bh;
-
- cdeps = 0;
- for (n = t->deps; n != NULL; n = n->next)
- ++cdeps;
-
- /* Add a symbol representing this version. */
- bh = NULL;
- if (! (_bfd_generic_link_add_one_symbol
- (info, dynobj, t->name, BSF_GLOBAL, bfd_abs_section_ptr,
- 0, NULL, FALSE,
- get_elf_backend_data (dynobj)->collect, &bh)))
- return FALSE;
- h = (struct elf_link_hash_entry *) bh;
- h->elf_link_hash_flags &= ~ ELF_LINK_NON_ELF;
- h->elf_link_hash_flags |= ELF_LINK_HASH_DEF_REGULAR;
- h->type = STT_OBJECT;
- h->verinfo.vertree = t;
-
- if (! _bfd_elf_link_record_dynamic_symbol (info, h))
- return FALSE;
-
- def.vd_version = VER_DEF_CURRENT;
- def.vd_flags = 0;
- if (t->globals.list == NULL && t->locals.list == NULL && ! t->used)
- def.vd_flags |= VER_FLG_WEAK;
- def.vd_ndx = t->vernum + 1;
- def.vd_cnt = cdeps + 1;
- def.vd_hash = bfd_elf_hash (t->name);
- def.vd_aux = sizeof (Elf_External_Verdef);
- if (t->next != NULL)
- def.vd_next = (sizeof (Elf_External_Verdef)
- + (cdeps + 1) * sizeof (Elf_External_Verdaux));
- else
- def.vd_next = 0;
-
- _bfd_elf_swap_verdef_out (output_bfd, &def,
- (Elf_External_Verdef *) p);
- p += sizeof (Elf_External_Verdef);
-
- defaux.vda_name = h->dynstr_index;
- _bfd_elf_strtab_addref (elf_hash_table (info)->dynstr,
- h->dynstr_index);
- if (t->deps == NULL)
- defaux.vda_next = 0;
- else
- defaux.vda_next = sizeof (Elf_External_Verdaux);
- t->name_indx = defaux.vda_name;
-
- _bfd_elf_swap_verdaux_out (output_bfd, &defaux,
- (Elf_External_Verdaux *) p);
- p += sizeof (Elf_External_Verdaux);
-
- for (n = t->deps; n != NULL; n = n->next)
- {
- if (n->version_needed == NULL)
- {
- /* This can happen if there was an error in the
- version script. */
- defaux.vda_name = 0;
- }
- else
- {
- defaux.vda_name = n->version_needed->name_indx;
- _bfd_elf_strtab_addref (elf_hash_table (info)->dynstr,
- defaux.vda_name);
- }
- if (n->next == NULL)
- defaux.vda_next = 0;
- else
- defaux.vda_next = sizeof (Elf_External_Verdaux);
-
- _bfd_elf_swap_verdaux_out (output_bfd, &defaux,
- (Elf_External_Verdaux *) p);
- p += sizeof (Elf_External_Verdaux);
- }
- }
-
- if (! elf_add_dynamic_entry (info, DT_VERDEF, 0)
- || ! elf_add_dynamic_entry (info, DT_VERDEFNUM, cdefs))
- return FALSE;
-
- elf_tdata (output_bfd)->cverdefs = cdefs;
- }
-
- if ((info->new_dtags && info->flags) || (info->flags & DF_STATIC_TLS))
- {
- if (! elf_add_dynamic_entry (info, DT_FLAGS, info->flags))
- return FALSE;
- }
-
- if (info->flags_1)
- {
- if (info->executable)
- info->flags_1 &= ~ (DF_1_INITFIRST
- | DF_1_NODELETE
- | DF_1_NOOPEN);
- if (! elf_add_dynamic_entry (info, DT_FLAGS_1, info->flags_1))
- return FALSE;
- }
-
- /* Work out the size of the version reference section. */
-
- s = bfd_get_section_by_name (dynobj, ".gnu.version_r");
- BFD_ASSERT (s != NULL);
- {
- struct elf_find_verdep_info sinfo;
-
- sinfo.output_bfd = output_bfd;
- sinfo.info = info;
- sinfo.vers = elf_tdata (output_bfd)->cverdefs;
- if (sinfo.vers == 0)
- sinfo.vers = 1;
- sinfo.failed = FALSE;
-
- elf_link_hash_traverse (elf_hash_table (info),
- _bfd_elf_link_find_version_dependencies,
- &sinfo);
-
- if (elf_tdata (output_bfd)->verref == NULL)
- _bfd_strip_section_from_output (info, s);
- else
- {
- Elf_Internal_Verneed *t;
- unsigned int size;
- unsigned int crefs;
- bfd_byte *p;
-
- /* Build the version definition section. */
- size = 0;
- crefs = 0;
- for (t = elf_tdata (output_bfd)->verref;
- t != NULL;
- t = t->vn_nextref)
- {
- Elf_Internal_Vernaux *a;
-
- size += sizeof (Elf_External_Verneed);
- ++crefs;
- for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
- size += sizeof (Elf_External_Vernaux);
- }
-
- s->_raw_size = size;
- s->contents = bfd_alloc (output_bfd, s->_raw_size);
- if (s->contents == NULL)
- return FALSE;
-
- p = s->contents;
- for (t = elf_tdata (output_bfd)->verref;
- t != NULL;
- t = t->vn_nextref)
- {
- unsigned int caux;
- Elf_Internal_Vernaux *a;
- bfd_size_type indx;
-
- caux = 0;
- for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
- ++caux;
-
- t->vn_version = VER_NEED_CURRENT;
- t->vn_cnt = caux;
- indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
- elf_dt_name (t->vn_bfd) != NULL
- ? elf_dt_name (t->vn_bfd)
- : basename (t->vn_bfd->filename),
- FALSE);
- if (indx == (bfd_size_type) -1)
- return FALSE;
- t->vn_file = indx;
- t->vn_aux = sizeof (Elf_External_Verneed);
- if (t->vn_nextref == NULL)
- t->vn_next = 0;
- else
- t->vn_next = (sizeof (Elf_External_Verneed)
- + caux * sizeof (Elf_External_Vernaux));
-
- _bfd_elf_swap_verneed_out (output_bfd, t,
- (Elf_External_Verneed *) p);
- p += sizeof (Elf_External_Verneed);
-
- for (a = t->vn_auxptr; a != NULL; a = a->vna_nextptr)
- {
- a->vna_hash = bfd_elf_hash (a->vna_nodename);
- indx = _bfd_elf_strtab_add (elf_hash_table (info)->dynstr,
- a->vna_nodename, FALSE);
- if (indx == (bfd_size_type) -1)
- return FALSE;
- a->vna_name = indx;
- if (a->vna_nextptr == NULL)
- a->vna_next = 0;
- else
- a->vna_next = sizeof (Elf_External_Vernaux);
-
- _bfd_elf_swap_vernaux_out (output_bfd, a,
- (Elf_External_Vernaux *) p);
- p += sizeof (Elf_External_Vernaux);
- }
- }
-
- if (! elf_add_dynamic_entry (info, DT_VERNEED, 0)
- || ! elf_add_dynamic_entry (info, DT_VERNEEDNUM, crefs))
- return FALSE;
-
- elf_tdata (output_bfd)->cverrefs = crefs;
- }
- }
-
- /* Assign dynsym indicies. In a shared library we generate a
- section symbol for each output section, which come first.
- Next come all of the back-end allocated local dynamic syms,
- followed by the rest of the global symbols. */
-
- dynsymcount = _bfd_elf_link_renumber_dynsyms (output_bfd, info);
-
- /* Work out the size of the symbol version section. */
- s = bfd_get_section_by_name (dynobj, ".gnu.version");
- BFD_ASSERT (s != NULL);
- if (dynsymcount == 0
- || (verdefs == NULL && elf_tdata (output_bfd)->verref == NULL))
- {
- _bfd_strip_section_from_output (info, s);
- /* The DYNSYMCOUNT might have changed if we were going to
- output a dynamic symbol table entry for S. */
- dynsymcount = _bfd_elf_link_renumber_dynsyms (output_bfd, info);
- }
- else
- {
- s->_raw_size = dynsymcount * sizeof (Elf_External_Versym);
- s->contents = bfd_zalloc (output_bfd, s->_raw_size);
- if (s->contents == NULL)
- return FALSE;
-
- if (! elf_add_dynamic_entry (info, DT_VERSYM, 0))
- return FALSE;
- }
-
- /* Set the size of the .dynsym and .hash sections. We counted
- the number of dynamic symbols in elf_link_add_object_symbols.
- We will build the contents of .dynsym and .hash when we build
- the final symbol table, because until then we do not know the
- correct value to give the symbols. We built the .dynstr
- section as we went along in elf_link_add_object_symbols. */
- s = bfd_get_section_by_name (dynobj, ".dynsym");
- BFD_ASSERT (s != NULL);
- s->_raw_size = dynsymcount * sizeof (Elf_External_Sym);
- s->contents = bfd_alloc (output_bfd, s->_raw_size);
- if (s->contents == NULL && s->_raw_size != 0)
- return FALSE;
-
- if (dynsymcount != 0)
- {
- Elf_Internal_Sym isym;
-
- /* The first entry in .dynsym is a dummy symbol. */
- isym.st_value = 0;
- isym.st_size = 0;
- isym.st_name = 0;
- isym.st_info = 0;
- isym.st_other = 0;
- isym.st_shndx = 0;
- elf_swap_symbol_out (output_bfd, &isym, s->contents, 0);
- }
-
- /* Compute the size of the hashing table. As a side effect this
- computes the hash values for all the names we export. */
- bucketcount = compute_bucket_count (info);
-
- s = bfd_get_section_by_name (dynobj, ".hash");
- BFD_ASSERT (s != NULL);
- hash_entry_size = elf_section_data (s)->this_hdr.sh_entsize;
- s->_raw_size = ((2 + bucketcount + dynsymcount) * hash_entry_size);
- s->contents = bfd_zalloc (output_bfd, s->_raw_size);
- if (s->contents == NULL)
- return FALSE;
-
- bfd_put (8 * hash_entry_size, output_bfd, bucketcount, s->contents);
- bfd_put (8 * hash_entry_size, output_bfd, dynsymcount,
- s->contents + hash_entry_size);
-
- elf_hash_table (info)->bucketcount = bucketcount;
-
- s = bfd_get_section_by_name (dynobj, ".dynstr");
- BFD_ASSERT (s != NULL);
-
- elf_finalize_dynstr (output_bfd, info);
-
- s->_raw_size = _bfd_elf_strtab_size (elf_hash_table (info)->dynstr);
-
- for (dtagcount = 0; dtagcount <= info->spare_dynamic_tags; ++dtagcount)
- if (! elf_add_dynamic_entry (info, DT_NULL, 0))
- return FALSE;
- }
-
- return TRUE;
-}
-
-/* This function is used to adjust offsets into .dynstr for
- dynamic symbols. This is called via elf_link_hash_traverse. */
-
-static bfd_boolean
-elf_adjust_dynstr_offsets (struct elf_link_hash_entry *h, void *data)
-{
- struct elf_strtab_hash *dynstr = data;
-
- if (h->root.type == bfd_link_hash_warning)
- h = (struct elf_link_hash_entry *) h->root.u.i.link;
-
- if (h->dynindx != -1)
- h->dynstr_index = _bfd_elf_strtab_offset (dynstr, h->dynstr_index);
- return TRUE;
-}
-
-/* Assign string offsets in .dynstr, update all structures referencing
- them. */
-
-static bfd_boolean
-elf_finalize_dynstr (bfd *output_bfd, struct bfd_link_info *info)
-{
- struct elf_link_local_dynamic_entry *entry;
- struct elf_strtab_hash *dynstr = elf_hash_table (info)->dynstr;
- bfd *dynobj = elf_hash_table (info)->dynobj;
- asection *sdyn;
- bfd_size_type size;
- Elf_External_Dyn *dyncon, *dynconend;
-
- _bfd_elf_strtab_finalize (dynstr);
- size = _bfd_elf_strtab_size (dynstr);
-
- /* Update all .dynamic entries referencing .dynstr strings. */
- sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
- BFD_ASSERT (sdyn != NULL);
-
- dyncon = (Elf_External_Dyn *) sdyn->contents;
- dynconend = (Elf_External_Dyn *) (sdyn->contents +
- sdyn->_raw_size);
- for (; dyncon < dynconend; dyncon++)
- {
- Elf_Internal_Dyn dyn;
-
- elf_swap_dyn_in (dynobj, dyncon, & dyn);
- switch (dyn.d_tag)
- {
- case DT_STRSZ:
- dyn.d_un.d_val = size;
- elf_swap_dyn_out (dynobj, & dyn, dyncon);
- break;
- case DT_NEEDED:
- case DT_SONAME:
- case DT_RPATH:
- case DT_RUNPATH:
- case DT_FILTER:
- case DT_AUXILIARY:
- dyn.d_un.d_val = _bfd_elf_strtab_offset (dynstr, dyn.d_un.d_val);
- elf_swap_dyn_out (dynobj, & dyn, dyncon);
- break;
- default:
- break;
- }
- }
-
- /* Now update local dynamic symbols. */
- for (entry = elf_hash_table (info)->dynlocal; entry ; entry = entry->next)
- entry->isym.st_name = _bfd_elf_strtab_offset (dynstr,
- entry->isym.st_name);
-
- /* And the rest of dynamic symbols. */
- elf_link_hash_traverse (elf_hash_table (info),
- elf_adjust_dynstr_offsets, dynstr);
-
- /* Adjust version definitions. */
- if (elf_tdata (output_bfd)->cverdefs)
- {
- asection *s;
- bfd_byte *p;
- bfd_size_type i;
- Elf_Internal_Verdef def;
- Elf_Internal_Verdaux defaux;
-
- s = bfd_get_section_by_name (dynobj, ".gnu.version_d");
- p = (bfd_byte *) s->contents;
- do
- {
- _bfd_elf_swap_verdef_in (output_bfd, (Elf_External_Verdef *) p,
- &def);
- p += sizeof (Elf_External_Verdef);
- for (i = 0; i < def.vd_cnt; ++i)
- {
- _bfd_elf_swap_verdaux_in (output_bfd,
- (Elf_External_Verdaux *) p, &defaux);
- defaux.vda_name = _bfd_elf_strtab_offset (dynstr,
- defaux.vda_name);
- _bfd_elf_swap_verdaux_out (output_bfd,
- &defaux, (Elf_External_Verdaux *) p);
- p += sizeof (Elf_External_Verdaux);
- }
- }
- while (def.vd_next);
- }
-
- /* Adjust version references. */
- if (elf_tdata (output_bfd)->verref)
- {
- asection *s;
- bfd_byte *p;
- bfd_size_type i;
- Elf_Internal_Verneed need;
- Elf_Internal_Vernaux needaux;
-
- s = bfd_get_section_by_name (dynobj, ".gnu.version_r");
- p = (bfd_byte *) s->contents;
- do
- {
- _bfd_elf_swap_verneed_in (output_bfd, (Elf_External_Verneed *) p,
- &need);
- need.vn_file = _bfd_elf_strtab_offset (dynstr, need.vn_file);
- _bfd_elf_swap_verneed_out (output_bfd, &need,
- (Elf_External_Verneed *) p);
- p += sizeof (Elf_External_Verneed);
- for (i = 0; i < need.vn_cnt; ++i)
- {
- _bfd_elf_swap_vernaux_in (output_bfd,
- (Elf_External_Vernaux *) p, &needaux);
- needaux.vna_name = _bfd_elf_strtab_offset (dynstr,
- needaux.vna_name);
- _bfd_elf_swap_vernaux_out (output_bfd,
- &needaux,
- (Elf_External_Vernaux *) p);
- p += sizeof (Elf_External_Vernaux);
- }
- }
- while (need.vn_next);
- }
-
- 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. */
- 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_dt_soname (abfd) == NULL)
- 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);
-}
-
-/* This function will be called though elf_link_hash_traverse to store
- all hash value of the exported symbols in an array. */
-
-static bfd_boolean
-elf_collect_hash_codes (struct elf_link_hash_entry *h, void *data)
-{
- unsigned long **valuep = data;
- const char *name;
- char *p;
- unsigned long ha;
- char *alc = NULL;
-
- if (h->root.type == bfd_link_hash_warning)
- h = (struct elf_link_hash_entry *) h->root.u.i.link;
-
- /* Ignore indirect symbols. These are added by the versioning code. */
- if (h->dynindx == -1)
- return TRUE;
-
- name = h->root.root.string;
- p = strchr (name, ELF_VER_CHR);
- if (p != NULL)
- {
- alc = bfd_malloc (p - name + 1);
- memcpy (alc, name, p - name);
- alc[p - name] = '\0';
- name = alc;
- }
-
- /* Compute the hash value. */
- ha = bfd_elf_hash (name);
-
- /* Store the found hash value in the array given as the argument. */
- *(*valuep)++ = ha;
-
- /* And store it in the struct so that we can put it in the hash table
- later. */
- h->elf_hash_value = ha;
-
- if (alc != NULL)
- free (alc);
-
- return TRUE;
-}
-
-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 2996485..20d9083 100644
--- a/bfd/elfxx-ia64.c
+++ b/bfd/elfxx-ia64.c
@@ -1,5 +1,6 @@
/* IA-64 support for 64-bit ELF
- Copyright 1998, 1999, 2000, 2001, 2002, 2003 Free Software Foundation, Inc.
+ Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004
+ Free Software Foundation, Inc.
Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
This file is part of BFD, the Binary File Descriptor library.
@@ -92,6 +93,9 @@ struct elfNN_ia64_dyn_sym_info
asection *srel;
int type;
int count;
+
+ /* Is this reloc against readonly section? */
+ bfd_boolean reltext;
} *reloc_entries;
/* TRUE when the section contents have been updated. */
@@ -182,13 +186,13 @@ static bfd_boolean is_unwind_section_name
static bfd_boolean elfNN_ia64_section_from_shdr
PARAMS ((bfd *, Elf_Internal_Shdr *, const char *));
static bfd_boolean elfNN_ia64_section_flags
- PARAMS ((flagword *, Elf_Internal_Shdr *));
+ PARAMS ((flagword *, const Elf_Internal_Shdr *));
static bfd_boolean elfNN_ia64_fake_sections
PARAMS ((bfd *abfd, Elf_Internal_Shdr *hdr, asection *sec));
static void elfNN_ia64_final_write_processing
PARAMS ((bfd *abfd, bfd_boolean linker));
static bfd_boolean elfNN_ia64_add_symbol_hook
- PARAMS ((bfd *abfd, struct bfd_link_info *info, const Elf_Internal_Sym *sym,
+ PARAMS ((bfd *abfd, struct bfd_link_info *info, Elf_Internal_Sym *sym,
const char **namep, flagword *flagsp, asection **secp,
bfd_vma *valp));
static int elfNN_ia64_additional_program_headers
@@ -243,9 +247,6 @@ static asection *get_pltoff
static asection *get_reloc_section
PARAMS ((bfd *abfd, struct elfNN_ia64_link_hash_table *ia64_info,
asection *sec, bfd_boolean create));
-static bfd_boolean count_dyn_reloc
- PARAMS ((bfd *abfd, struct elfNN_ia64_dyn_sym_info *dyn_i,
- asection *srel, int type));
static bfd_boolean elfNN_ia64_check_relocs
PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *sec,
const Elf_Internal_Rela *relocs));
@@ -1270,7 +1271,7 @@ elfNN_ia64_section_from_shdr (abfd, hdr, name)
static bfd_boolean
elfNN_ia64_section_flags (flags, hdr)
flagword *flags;
- Elf_Internal_Shdr *hdr;
+ const Elf_Internal_Shdr *hdr;
{
if (hdr->sh_flags & SHF_IA_64_SHORT)
*flags |= SEC_SMALL_DATA;
@@ -1429,7 +1430,7 @@ static bfd_boolean
elfNN_ia64_add_symbol_hook (abfd, info, sym, namep, flagsp, secp, valp)
bfd *abfd;
struct bfd_link_info *info;
- const Elf_Internal_Sym *sym;
+ Elf_Internal_Sym *sym;
const char **namep ATTRIBUTE_UNUSED;
flagword *flagsp ATTRIBUTE_UNUSED;
asection **secp;
@@ -2175,18 +2176,12 @@ get_reloc_section (abfd, ia64_info, sec, create)
return NULL;
}
- if (sec->flags & SEC_READONLY)
- ia64_info->reltext = 1;
-
return srel;
}
static bfd_boolean
-count_dyn_reloc (abfd, dyn_i, srel, type)
- bfd *abfd;
- struct elfNN_ia64_dyn_sym_info *dyn_i;
- asection *srel;
- int type;
+count_dyn_reloc (bfd *abfd, struct elfNN_ia64_dyn_sym_info *dyn_i,
+ asection *srel, int type, bfd_boolean reltext)
{
struct elfNN_ia64_dyn_reloc_entry *rent;
@@ -2207,6 +2202,7 @@ count_dyn_reloc (abfd, dyn_i, srel, type)
rent->count = 0;
dyn_i->reloc_entries = rent;
}
+ rent->reltext = reltext;
rent->count++;
return TRUE;
@@ -2463,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;
}
@@ -2491,7 +2487,8 @@ elfNN_ia64_check_relocs (abfd, info, sec, relocs)
if (!srel)
return FALSE;
}
- if (!count_dyn_reloc (abfd, dyn_i, srel, dynrel_type))
+ if (!count_dyn_reloc (abfd, dyn_i, srel, dynrel_type,
+ (sec->flags & SEC_READONLY) != 0))
return FALSE;
}
}
@@ -2634,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;
@@ -2798,6 +2795,8 @@ allocate_dynrel_entries (dyn_i, data)
default:
abort ();
}
+ if (rent->reltext)
+ ia64_info->reltext = 1;
rent->srel->_raw_size += sizeof (ElfNN_External_Rela) * count;
}
@@ -2942,8 +2941,12 @@ elfNN_ia64_size_dynamic_sections (output_bfd, info)
data.ofs = (data.ofs + 31) & (bfd_vma) -32;
elfNN_ia64_dyn_sym_traverse (ia64_info, allocate_plt2_entries, &data);
- if (data.ofs != 0)
+ if (data.ofs != 0 || ia64_info->root.dynamic_sections_created)
{
+ /* FIXME: we always reserve the memory for dynamic linker even if
+ there are no PLT entries since dynamic linker may assume the
+ reserved memory always exists. */
+
BFD_ASSERT (ia64_info->root.dynamic_sections_created);
ia64_info->plt_sec->_raw_size = data.ofs;
@@ -3084,7 +3087,7 @@ elfNN_ia64_size_dynamic_sections (output_bfd, info)
/* The DT_DEBUG entry is filled in by the dynamic linker and used
by the debugger. */
#define add_dynamic_entry(TAG, VAL) \
- bfd_elfNN_add_dynamic_entry (info, (bfd_vma) (TAG), (bfd_vma) (VAL))
+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
if (!add_dynamic_entry (DT_DEBUG, 0))
return FALSE;
@@ -3839,7 +3842,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)
@@ -3976,12 +3979,12 @@ elfNN_ia64_relocate_section (output_bfd, info, input_bfd, input_section,
{
bfd_boolean unresolved_reloc;
bfd_boolean warned;
+ struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
- RELOC_FOR_GLOBAL_SYMBOL (h, elf_sym_hashes (input_bfd),
- r_symndx,
- symtab_hdr, value, sym_sec,
- unresolved_reloc, info,
- warned);
+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
+ r_symndx, symtab_hdr, sym_hashes,
+ h, sym_sec, value,
+ unresolved_reloc, warned);
if (h->root.type == bfd_link_hash_undefweak)
undef_weak_ref = TRUE;
@@ -4597,7 +4600,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 f072f26..e5226d9 100644
--- a/bfd/elfxx-mips.c
+++ b/bfd/elfxx-mips.c
@@ -1,6 +1,6 @@
/* MIPS-specific support for ELF
Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
- 2003 Free Software Foundation, Inc.
+ 2003, 2004 Free Software Foundation, Inc.
Most of the information added by Ian Lance Taylor, Cygnus Support,
<ian@cygnus.com>.
@@ -400,8 +400,6 @@ static asection *mips_elf_got_section
(bfd *, bfd_boolean);
static struct mips_got_info *mips_elf_got_info
(bfd *, asection **);
-static long mips_elf_get_global_gotsym_index
- (bfd *abfd);
static bfd_vma mips_elf_local_got_index
(bfd *, bfd *, struct bfd_link_info *, bfd_vma);
static bfd_vma mips_elf_global_got_index
@@ -530,8 +528,7 @@ static bfd *reldyn_sorting_bfd;
(NEWABI_P (abfd) ? ".MIPS.options" : ".options")
/* The name of the stub section. */
-#define MIPS_ELF_STUB_SECTION_NAME(abfd) \
- (NEWABI_P (abfd) ? ".MIPS.stubs" : ".stub")
+#define MIPS_ELF_STUB_SECTION_NAME(abfd) ".MIPS.stubs"
/* The size of an external REL relocation. */
#define MIPS_ELF_REL_SIZE(abfd) \
@@ -564,17 +561,8 @@ static bfd *reldyn_sorting_bfd;
: bfd_put_32 (abfd, val, ptr))
/* Add a dynamic symbol table-entry. */
-#ifdef BFD64
-#define MIPS_ELF_ADD_DYNAMIC_ENTRY(info, tag, val) \
- (ABI_64_P (elf_hash_table (info)->dynobj) \
- ? bfd_elf64_add_dynamic_entry (info, tag, val) \
- : bfd_elf32_add_dynamic_entry (info, tag, val))
-#else
#define MIPS_ELF_ADD_DYNAMIC_ENTRY(info, tag, val) \
- (ABI_64_P (elf_hash_table (info)->dynobj) \
- ? (abort (), FALSE) \
- : bfd_elf32_add_dynamic_entry (info, tag, val))
-#endif
+ _bfd_elf_add_dynamic_entry (info, tag, val)
#define MIPS_ELF_RTYPE_TO_HOWTO(abfd, rtype, rela) \
(get_elf_backend_data (abfd)->elf_backend_mips_rtype_to_howto (rtype, rela))
@@ -821,7 +809,6 @@ _bfd_mips_elf_read_ecoff_info (bfd *abfd, asection *section,
#undef READ
debug->fdr = NULL;
- debug->adjust = NULL;
return TRUE;
@@ -1233,13 +1220,6 @@ _bfd_mips_elf_lo16_reloc (bfd *abfd, arelent *reloc_entry, asymbol *symbol,
carry or borrow will induce a change of +1 or -1 in the high part. */
hi->rel.addend += (vallo + 0x8000) & 0xffff;
- /* R_MIPS_GNU_REL_HI16 relocations are relative to the address of the
- lo16 relocation, not their own address. If we're calculating the
- final value, and hence subtracting the "PC", subtract the offset
- of the lo16 relocation from here. */
- if (output_bfd == NULL && hi->rel.howto->type == R_MIPS_GNU_REL_HI16)
- hi->rel.addend -= reloc_entry->address - hi->rel.address;
-
ret = _bfd_mips_elf_generic_reloc (abfd, &hi->rel, symbol, hi->data,
hi->input_section, output_bfd,
error_message);
@@ -1825,28 +1805,6 @@ mips_elf_got_info (bfd *abfd, asection **sgotp)
return g;
}
-/* Obtain the lowest dynamic index of a symbol that was assigned a
- global GOT entry. */
-static long
-mips_elf_get_global_gotsym_index (bfd *abfd)
-{
- asection *sgot;
- struct mips_got_info *g;
-
- if (abfd == NULL)
- return 0;
-
- sgot = mips_elf_got_section (abfd, TRUE);
- if (sgot == NULL || mips_elf_section_data (sgot) == NULL)
- return 0;
-
- g = mips_elf_section_data (sgot)->u.got_info;
- if (g == NULL || g->global_gotsym == NULL)
- return 0;
-
- return g->global_gotsym->dynindx;
-}
-
/* Returns the GOT offset at which the indicated address can be found.
If there is not yet a GOT entry for this value, create one. Returns
-1 if no satisfactory GOT offset can be found. */
@@ -2153,7 +2111,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;
}
@@ -2763,12 +2721,6 @@ mips_elf_next_relocation (bfd *abfd ATTRIBUTE_UNUSED, unsigned int r_type,
const Elf_Internal_Rela *relocation,
const Elf_Internal_Rela *relend)
{
- /* According to the MIPS ELF ABI, the R_MIPS_LO16 relocation must be
- immediately following. However, for the IRIX6 ABI, the next
- relocation may be a composed relocation consisting of several
- relocations for the same address. In that case, the R_MIPS_LO16
- relocation may occur as one of these. We permit a similar
- extension in general, as that is useful for GCC. */
while (relocation < relend)
{
if (ELF_R_TYPE (abfd, relocation->r_info) == r_type)
@@ -2965,7 +2917,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);
@@ -3156,8 +3108,7 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
and check to see if they exist by looking at their
addresses. */
symbol = 0;
- else if (info->shared
- && info->unresolved_syms_in_objects == RM_IGNORE
+ else if (info->unresolved_syms_in_objects == RM_IGNORE
&& ELF_ST_VISIBILITY (h->root.other) == STV_DEFAULT)
symbol = 0;
else if (strcmp (*namep, "_DYNAMIC_LINK") == 0 ||
@@ -3178,9 +3129,8 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
if (! ((*info->callbacks->undefined_symbol)
(info, h->root.root.root.string, input_bfd,
input_section, relocation->r_offset,
- ((info->shared && info->unresolved_syms_in_shared_libs == RM_GENERATE_ERROR)
- || (!info->shared && info->unresolved_syms_in_objects == RM_GENERATE_ERROR)
- || ELF_ST_VISIBILITY (h->root.other)))))
+ (info->unresolved_syms_in_objects == RM_GENERATE_ERROR)
+ || ELF_ST_VISIBILITY (h->root.other))))
return bfd_reloc_undefined;
symbol = 0;
}
@@ -3385,29 +3335,12 @@ mips_elf_calculate_relocation (bfd *abfd, bfd *input_bfd,
value &= howto->dst_mask;
break;
- case R_MIPS_PC32:
- case R_MIPS_PC64:
- case R_MIPS_GNU_REL_LO16:
- value = symbol + addend - p;
- value &= howto->dst_mask;
- break;
-
case R_MIPS_GNU_REL16_S2:
value = symbol + _bfd_mips_elf_sign_extend (addend, 18) - p;
overflowed_p = mips_elf_overflow_p (value, 18);
value = (value >> 2) & howto->dst_mask;
break;
- case R_MIPS_GNU_REL_HI16:
- /* Instead of subtracting 'p' here, we should be subtracting the
- equivalent value for the LO part of the reloc, since the value
- here is relative to that address. Because that's not easy to do,
- we adjust 'addend' in _bfd_mips_elf_relocate_section(). See also
- the comment there for more information. */
- value = mips_elf_high (addend + symbol - p);
- value &= howto->dst_mask;
- break;
-
case R_MIPS16_26:
/* The calculation for R_MIPS16_26 is just the same as for an
R_MIPS_26. It's only the storage of the relocated field into
@@ -4726,7 +4659,7 @@ _bfd_mips_elf_section_from_bfd_section (bfd *abfd ATTRIBUTE_UNUSED,
bfd_boolean
_bfd_mips_elf_add_symbol_hook (bfd *abfd, struct bfd_link_info *info,
- const Elf_Internal_Sym *sym, const char **namep,
+ Elf_Internal_Sym *sym, const char **namep,
flagword *flagsp ATTRIBUTE_UNUSED,
asection **secp, bfd_vma *valp)
{
@@ -4859,7 +4792,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;
@@ -4891,9 +4824,8 @@ _bfd_mips_elf_link_output_symbol_hook
&& strcmp (input_sec->name, ".scommon") == 0)
sym->st_shndx = SHN_MIPS_SCOMMON;
- if (sym->st_other == STO_MIPS16
- && (sym->st_value & 1) != 0)
- --sym->st_value;
+ if (sym->st_other == STO_MIPS16)
+ sym->st_value &= ~1;
return TRUE;
}
@@ -4972,7 +4904,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;
}
@@ -5017,7 +4949,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)
@@ -5041,7 +4973,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;
}
}
@@ -5360,7 +5292,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;
}
@@ -5472,14 +5404,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;
@@ -6267,7 +6199,6 @@ _bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
combination of the addend stored in two different
relocations. */
if (r_type == R_MIPS_HI16
- || r_type == R_MIPS_GNU_REL_HI16
|| (r_type == R_MIPS_GOT16
&& mips_elf_local_relocation_p (input_bfd, rel,
local_sections, FALSE)))
@@ -6275,7 +6206,6 @@ _bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
bfd_vma l;
const Elf_Internal_Rela *lo16_relocation;
reloc_howto_type *lo16_howto;
- unsigned int lo;
/* The combined value is the sum of the HI16 addend,
left-shifted by sixteen bits, and the LO16
@@ -6283,18 +6213,25 @@ _bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
a `lui' of the HI16 value, and then an `addiu' of
the LO16 value.)
- Scan ahead to find a matching LO16 relocation. */
- if (r_type == R_MIPS_GNU_REL_HI16)
- lo = R_MIPS_GNU_REL_LO16;
- else
- lo = R_MIPS_LO16;
- lo16_relocation = mips_elf_next_relocation (input_bfd, lo,
+ Scan ahead to find a matching LO16 relocation.
+
+ According to the MIPS ELF ABI, the R_MIPS_LO16
+ relocation must be immediately following.
+ However, for the IRIX6 ABI, the next relocation
+ may be a composed relocation consisting of
+ several relocations for the same address. In
+ that case, the R_MIPS_LO16 relocation may occur
+ as one of these. We permit a similar extension
+ in general, as that is useful for GCC. */
+ lo16_relocation = mips_elf_next_relocation (input_bfd,
+ R_MIPS_LO16,
rel, relend);
if (lo16_relocation == NULL)
return FALSE;
/* Obtain the addend kept there. */
- lo16_howto = MIPS_ELF_RTYPE_TO_HOWTO (input_bfd, lo, FALSE);
+ lo16_howto = MIPS_ELF_RTYPE_TO_HOWTO (input_bfd,
+ R_MIPS_LO16, FALSE);
l = mips_elf_obtain_contents (lo16_howto, lo16_relocation,
input_bfd, contents);
l &= lo16_howto->src_mask;
@@ -6305,16 +6242,6 @@ _bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
/* Compute the combined addend. */
addend += l;
-
- /* If PC-relative, subtract the difference between the
- address of the LO part of the reloc and the address of
- the HI part. The relocation is relative to the LO
- part, but mips_elf_calculate_relocation() doesn't
- know its address or the difference from the HI part, so
- we subtract that difference here. See also the
- comment in mips_elf_calculate_relocation(). */
- if (r_type == R_MIPS_GNU_REL_HI16)
- addend -= (lo16_relocation->r_offset - rel->r_offset);
}
else if (r_type == R_MIPS16_GPREL)
{
@@ -6372,8 +6299,7 @@ _bfd_mips_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
else
{
if (r_type == R_MIPS_HI16
- || r_type == R_MIPS_GOT16
- || r_type == R_MIPS_GNU_REL_HI16)
+ || r_type == R_MIPS_GOT16)
addend = mips_elf_high (addend);
else if (r_type == R_MIPS_HIGHER)
addend = mips_elf_higher (addend);
@@ -6814,9 +6740,8 @@ _bfd_mips_elf_finish_dynamic_symbol (bfd *output_bfd,
}
/* If this is a mips16 symbol, force the value to be even. */
- if (sym->st_other == STO_MIPS16
- && (sym->st_value & 1) != 0)
- --sym->st_value;
+ if (sym->st_other == STO_MIPS16)
+ sym->st_value &= ~1;
return TRUE;
}
@@ -7744,7 +7669,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 ++;
@@ -8801,7 +8726,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. */
@@ -9030,10 +8955,10 @@ _bfd_mips_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
which are automatically generated by gas. */
if (strcmp (sec->name, ".reginfo")
&& strcmp (sec->name, ".mdebug")
- && ((!strcmp (sec->name, ".text")
- || !strcmp (sec->name, ".data")
- || !strcmp (sec->name, ".bss"))
- && sec->_raw_size != 0))
+ && (sec->_raw_size != 0
+ || (strcmp (sec->name, ".text")
+ && strcmp (sec->name, ".data")
+ && strcmp (sec->name, ".bss"))))
{
null_input_bfd = FALSE;
break;
diff --git a/bfd/elfxx-mips.h b/bfd/elfxx-mips.h
index 9e5d7af..0a684d9 100644
--- a/bfd/elfxx-mips.h
+++ b/bfd/elfxx-mips.h
@@ -1,5 +1,5 @@
/* MIPS ELF specific backend routines.
- Copyright 2002, 2003 Free Software Foundation, Inc.
+ Copyright 2002, 2003, 2004 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@@ -35,7 +35,7 @@ extern bfd_boolean _bfd_mips_elf_fake_sections
extern bfd_boolean _bfd_mips_elf_section_from_bfd_section
(bfd *, asection *, int *);
extern bfd_boolean _bfd_mips_elf_add_symbol_hook
- (bfd *, struct bfd_link_info *, const Elf_Internal_Sym *,
+ (bfd *, struct bfd_link_info *, Elf_Internal_Sym *,
const char **, flagword *, asection **, bfd_vma *);
extern bfd_boolean _bfd_mips_elf_link_output_symbol_hook
(struct bfd_link_info *, const char *, Elf_Internal_Sym *,
diff --git a/bfd/elfxx-target.h b/bfd/elfxx-target.h
index ca0e47b..61ed197 100644
--- a/bfd/elfxx-target.h
+++ b/bfd/elfxx-target.h
@@ -1,6 +1,6 @@
/* Target definitions for NN-bit ELF
Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
- 2003 Free Software Foundation, Inc.
+ 2003, 2004 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@@ -34,6 +34,8 @@
#define bfd_elfNN_canonicalize_dynamic_symtab \
_bfd_elf_canonicalize_dynamic_symtab
+#define bfd_elfNN_get_synthetic_symtab \
+ _bfd_elf_get_synthetic_symtab
#ifndef bfd_elfNN_canonicalize_reloc
#define bfd_elfNN_canonicalize_reloc _bfd_elf_canonicalize_reloc
#endif
@@ -126,7 +128,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
@@ -134,6 +136,10 @@
_bfd_elf_merge_sections
#endif
+#ifndef bfd_elfNN_bfd_is_group_section
+#define bfd_elfNN_bfd_is_group_section bfd_elf_is_group_section
+#endif
+
#ifndef bfd_elfNN_bfd_discard_group
#define bfd_elfNN_bfd_discard_group bfd_elf_discard_group
#endif
@@ -189,6 +195,12 @@
#ifndef bfd_elfNN_bfd_link_hash_table_create
#define bfd_elfNN_bfd_link_hash_table_create _bfd_elf_link_hash_table_create
#endif
+#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
@@ -235,6 +247,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
@@ -391,6 +407,15 @@
#ifndef elf_backend_ignore_discarded_relocs
#define elf_backend_ignore_discarded_relocs NULL
#endif
+#ifndef elf_backend_can_make_relative_eh_frame
+#define elf_backend_can_make_relative_eh_frame _bfd_elf_can_make_relative
+#endif
+#ifndef elf_backend_can_make_lsda_relative_eh_frame
+#define elf_backend_can_make_lsda_relative_eh_frame _bfd_elf_can_make_relative
+#endif
+#ifndef elf_backend_encode_eh_address
+#define elf_backend_encode_eh_address _bfd_elf_encode_eh_address
+#endif
#ifndef elf_backend_write_section
#define elf_backend_write_section NULL
#endif
@@ -424,6 +449,13 @@
#define elf_backend_rela_normal 0
#endif
+#ifndef elf_backend_plt_sym_val
+#define elf_backend_plt_sym_val NULL
+#endif
+#ifndef elf_backend_relplt_name
+#define elf_backend_relplt_name NULL
+#endif
+
#ifndef ELF_MACHINE_ALT1
#define ELF_MACHINE_ALT1 0
#endif
@@ -497,11 +529,16 @@ static const struct elf_backend_data elfNN_bed =
elf_backend_reloc_type_class,
elf_backend_discard_info,
elf_backend_ignore_discarded_relocs,
+ elf_backend_can_make_relative_eh_frame,
+ elf_backend_can_make_lsda_relative_eh_frame,
+ elf_backend_encode_eh_address,
elf_backend_write_section,
elf_backend_mips_irix_compat,
elf_backend_mips_rtype_to_howto,
elf_backend_ecoff_debug_swap,
elf_backend_bfd_from_remote_memory,
+ elf_backend_plt_sym_val,
+ elf_backend_relplt_name,
ELF_MACHINE_ALT1,
ELF_MACHINE_ALT2,
&elf_backend_size_info,
diff --git a/bfd/hpux-core.c b/bfd/hpux-core.c
index 30967c9..d624ad5 100644
--- a/bfd/hpux-core.c
+++ b/bfd/hpux-core.c
@@ -276,7 +276,8 @@ hpux_core_core_file_p (abfd)
case CORE_ANON_SHMEM:
if (!make_bfd_asection (abfd, ".data",
SEC_ALLOC + SEC_LOAD + SEC_HAS_CONTENTS,
- core_header.len, core_header.addr, 2))
+ core_header.len,
+ (bfd_vma) core_header.addr, 2))
goto fail;
bfd_seek (abfd, (file_ptr) core_header.len, SEEK_CUR);
diff --git a/bfd/i386msdos.c b/bfd/i386msdos.c
index 059466b..2dbd8df 100644
--- a/bfd/i386msdos.c
+++ b/bfd/i386msdos.c
@@ -1,6 +1,6 @@
/* BFD back-end for MS-DOS executables.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2001, 2002,
- 2003 Free Software Foundation, Inc.
+ 2003, 2004 Free Software Foundation, Inc.
Written by Bryan Ford of the University of Utah.
Contributed by the Center for Software Science at the
@@ -176,6 +176,7 @@ msdos_set_section_contents (abfd, section, location, offset, count)
#define msdos_bfd_relax_section bfd_generic_relax_section
#define msdos_bfd_gc_sections bfd_generic_gc_sections
#define msdos_bfd_merge_sections bfd_generic_merge_sections
+#define msdos_bfd_is_group_section bfd_generic_is_group_section
#define msdos_bfd_discard_group bfd_generic_discard_group
#define msdos_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
#define msdos_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
diff --git a/bfd/i386os9k.c b/bfd/i386os9k.c
index d9a34e3..3be6bdd 100644
--- a/bfd/i386os9k.c
+++ b/bfd/i386os9k.c
@@ -1,6 +1,6 @@
/* BFD back-end for os9000 i386 binaries.
- Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2001, 2002
- Free Software Foundation, Inc.
+ Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1998, 1999, 2001, 2002,
+ 2004 Free Software Foundation, Inc.
Written by Cygnus Support.
This file is part of BFD, the Binary File Descriptor library.
@@ -333,6 +333,7 @@ os9k_sizeof_headers (ignore_abfd, ignore)
#define os9k_bfd_relax_section bfd_generic_relax_section
#define os9k_bfd_gc_sections bfd_generic_gc_sections
#define os9k_bfd_merge_sections bfd_generic_merge_sections
+#define os9k_bfd_is_group_section bfd_generic_is_group_section
#define os9k_bfd_discard_group bfd_generic_discard_group
#define os9k_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
#define os9k_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
diff --git a/bfd/ieee.c b/bfd/ieee.c
index 8a08028..fcabf75 100644
--- a/bfd/ieee.c
+++ b/bfd/ieee.c
@@ -1,6 +1,6 @@
/* BFD back-end for ieee-695 objects.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003
+ 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Written by Steve Chamberlain of Cygnus Support.
@@ -4037,6 +4037,7 @@ ieee_bfd_debug_info_accumulate (abfd, section)
#define ieee_bfd_relax_section bfd_generic_relax_section
#define ieee_bfd_gc_sections bfd_generic_gc_sections
#define ieee_bfd_merge_sections bfd_generic_merge_sections
+#define ieee_bfd_is_group_section bfd_generic_is_group_section
#define ieee_bfd_discard_group bfd_generic_discard_group
#define ieee_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
#define ieee_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
diff --git a/bfd/ihex.c b/bfd/ihex.c
index 5d2d47f..5c4c438 100644
--- a/bfd/ihex.c
+++ b/bfd/ihex.c
@@ -1,5 +1,5 @@
/* BFD back-end for Intel Hex objects.
- Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003
+ Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Written by Ian Lance Taylor of Cygnus Support <ian@cygnus.com>.
@@ -988,6 +988,7 @@ ihex_sizeof_headers (abfd, exec)
#define ihex_bfd_relax_section bfd_generic_relax_section
#define ihex_bfd_gc_sections bfd_generic_gc_sections
#define ihex_bfd_merge_sections bfd_generic_merge_sections
+#define ihex_bfd_is_group_section bfd_generic_is_group_section
#define ihex_bfd_discard_group bfd_generic_discard_group
#define ihex_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
#define ihex_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
diff --git a/bfd/libaout.h b/bfd/libaout.h
index 67054e3..ddd0a9f 100644
--- a/bfd/libaout.h
+++ b/bfd/libaout.h
@@ -1,6 +1,6 @@
/* BFD back-end data structures for a.out (and similar) files.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003
+ 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Written by Cygnus Support.
@@ -221,73 +221,75 @@ struct aout_backend_data
struct internal_exec
{
- long a_info; /* Magic number and flags, packed */
- bfd_vma a_text; /* length of text, in bytes */
- bfd_vma a_data; /* length of data, in bytes */
- bfd_vma a_bss; /* length of uninitialized data area in mem */
- bfd_vma a_syms; /* length of symbol table data in file */
- bfd_vma a_entry; /* start address */
- bfd_vma a_trsize; /* length of text's relocation info, in bytes */
- bfd_vma a_drsize; /* length of data's relocation info, in bytes */
- /* Added for i960 */
- bfd_vma a_tload; /* Text runtime load address */
- bfd_vma a_dload; /* Data runtime load address */
- unsigned char a_talign; /* Alignment of text segment */
- unsigned char a_dalign; /* Alignment of data segment */
- unsigned char a_balign; /* Alignment of bss segment */
- char a_relaxable; /* Enough info for linker relax */
+ long a_info; /* Magic number and flags, packed. */
+ bfd_vma a_text; /* Length of text, in bytes. */
+ bfd_vma a_data; /* Length of data, in bytes. */
+ bfd_vma a_bss; /* Length of uninitialized data area in mem. */
+ bfd_vma a_syms; /* Length of symbol table data in file. */
+ bfd_vma a_entry; /* Start address. */
+ bfd_vma a_trsize; /* Length of text's relocation info, in bytes. */
+ bfd_vma a_drsize; /* Length of data's relocation info, in bytes. */
+ /* Added for i960 */
+ bfd_vma a_tload; /* Text runtime load address. */
+ bfd_vma a_dload; /* Data runtime load address. */
+ unsigned char a_talign; /* Alignment of text segment. */
+ unsigned char a_dalign; /* Alignment of data segment. */
+ unsigned char a_balign; /* Alignment of bss segment. */
+ char a_relaxable; /* Enough info for linker relax. */
};
/* Magic number is written
-< MSB >
-3130292827262524232221201918171615141312111009080706050403020100
-< FLAGS >< MACHINE TYPE >< MAGIC NUMBER >
-*/
+ < MSB >
+ 3130292827262524232221201918171615141312111009080706050403020100
+ < FLAGS >< MACHINE TYPE >< MAGIC NUMBER > */
+
/* Magic number for NetBSD is
-<MSB >
-3130292827262524232221201918171615141312111009080706050403020100
-< FLAGS >< MACHINE TYPE >< MAGIC NUMBER >
-*/
+ <MSB >
+ 3130292827262524232221201918171615141312111009080706050403020100
+ < FLAGS >< MACHINE TYPE >< MAGIC NUMBER > */
-enum machine_type {
+enum machine_type
+{
M_UNKNOWN = 0,
M_68010 = 1,
M_68020 = 2,
M_SPARC = 3,
/* Skip a bunch so we don't run into any of SUN's numbers. */
/* Make these up for the ns32k. */
- M_NS32032 = (64), /* ns32032 running ? */
- M_NS32532 = (64 + 5), /* ns32532 running mach */
-
+ M_NS32032 = (64), /* NS32032 running ? */
+ M_NS32532 = (64 + 5), /* NS32532 running mach. */
M_386 = 100,
- M_29K = 101, /* AMD 29000 */
- M_386_DYNIX = 102, /* Sequent running dynix */
- M_ARM = 103, /* Advanced Risc Machines ARM */
- M_SPARCLET = 131, /* SPARClet = M_SPARC + 128 */
- M_386_NETBSD = 134, /* NetBSD/i386 binary */
- M_68K_NETBSD = 135, /* NetBSD/m68k binary */
- M_68K4K_NETBSD = 136, /* NetBSD/m68k4k binary */
- M_532_NETBSD = 137, /* NetBSD/ns32k binary */
- M_SPARC_NETBSD = 138, /* NetBSD/sparc binary */
- M_PMAX_NETBSD = 139, /* NetBSD/pmax (MIPS little-endian) binary */
- M_VAX_NETBSD = 140, /* NetBSD/vax binary */
- M_ALPHA_NETBSD = 141, /* NetBSD/alpha binary */
- M_ARM6_NETBSD = 143, /* NetBSD/arm32 binary */
- M_SPARCLET_1 = 147, /* 0x93, reserved */
- M_VAX4K_NETBSD = 150, /* NetBSD/vax 4K pages binary */
- M_MIPS1 = 151, /* MIPS R2000/R3000 binary */
- M_MIPS2 = 152, /* MIPS R4000/R6000 binary */
- M_SPARCLET_2 = 163, /* 0xa3, reserved */
- M_SPARCLET_3 = 179, /* 0xb3, reserved */
- M_SPARCLET_4 = 195, /* 0xc3, reserved */
- M_HP200 = 200, /* HP 200 (68010) BSD binary */
- M_HP300 = (300 % 256), /* HP 300 (68020+68881) BSD binary */
- M_HPUX = (0x20c % 256), /* HP 200/300 HPUX binary */
- M_SPARCLET_5 = 211, /* 0xd3, reserved */
- M_SPARCLET_6 = 227, /* 0xe3, reserved */
- /* M_SPARCLET_7 = 243 / * 0xf3, reserved */
+ M_29K = 101, /* AMD 29000. */
+ M_386_DYNIX = 102, /* Sequent running dynix. */
+ M_ARM = 103, /* Advanced Risc Machines ARM. */
+ M_SPARCLET = 131, /* SPARClet = M_SPARC + 128. */
+ M_386_NETBSD = 134, /* NetBSD/i386 binary. */
+ M_68K_NETBSD = 135, /* NetBSD/m68k binary. */
+ M_68K4K_NETBSD = 136, /* NetBSD/m68k4k binary. */
+ M_532_NETBSD = 137, /* NetBSD/ns32k binary. */
+ M_SPARC_NETBSD = 138, /* NetBSD/sparc binary. */
+ M_PMAX_NETBSD = 139, /* NetBSD/pmax (MIPS little-endian) binary. */
+ M_VAX_NETBSD = 140, /* NetBSD/vax binary. */
+ M_ALPHA_NETBSD = 141, /* NetBSD/alpha binary. */
+ M_ARM6_NETBSD = 143, /* NetBSD/arm32 binary. */
+ M_SPARCLET_1 = 147, /* 0x93, reserved. */
+ M_POWERPC_NETBSD = 149, /* NetBSD/powerpc (big-endian) binary. */
+ M_VAX4K_NETBSD = 150, /* NetBSD/vax 4K pages binary. */
+ M_MIPS1 = 151, /* MIPS R2000/R3000 binary. */
+ M_MIPS2 = 152, /* MIPS R4000/R6000 binary. */
+ M_SPARC64_NETBSD = 156, /* NetBSD/sparc64 binary. */
+ M_X86_64_NETBSD = 157, /* NetBSD/amd64 binary. */
+ M_SPARCLET_2 = 163, /* 0xa3, reserved. */
+ M_SPARCLET_3 = 179, /* 0xb3, reserved. */
+ M_SPARCLET_4 = 195, /* 0xc3, reserved. */
+ M_HP200 = 200, /* HP 200 (68010) BSD binary. */
+ M_HP300 = (300 % 256), /* HP 300 (68020+68881) BSD binary. */
+ M_HPUX = (0x20c % 256), /* HP 200/300 HPUX binary. */
+ M_SPARCLET_5 = 211, /* 0xd3, reserved. */
+ M_SPARCLET_6 = 227, /* 0xe3, reserved. */
+/*M_SPARCLET_7 = 243 / * 0xf3, reserved. */
M_SPARCLITE_LE = 243,
- M_CRIS = 255 /* Axis CRIS binary. */
+ M_CRIS = 255 /* Axis CRIS binary. */
};
#define N_DYNAMIC(exec) ((exec).a_info & 0x80000000)
@@ -334,7 +336,8 @@ enum machine_type {
((exec).a_info&0x00ffffff) | (((flags) & 0xff) << 24))
#endif
-typedef struct aout_symbol {
+typedef struct aout_symbol
+{
asymbol symbol;
short desc;
char other;
@@ -345,9 +348,10 @@ typedef struct aout_symbol {
Various things depend on this struct being around any time an a.out
file is being handled. An example is dbxread.c in GDB. */
-struct aoutdata {
- struct internal_exec *hdr; /* exec file header */
- aout_symbol_type *symbols; /* symtab for input bfd */
+struct aoutdata
+{
+ struct internal_exec *hdr; /* Exec file header. */
+ aout_symbol_type *symbols; /* Symtab for input bfd. */
/* For ease, we do this. */
asection *textsec;
@@ -417,30 +421,31 @@ struct aoutdata {
bfd_vma *local_got_offsets;
};
-struct aout_data_struct {
- struct aoutdata a;
- struct internal_exec e;
+struct aout_data_struct
+{
+ struct aoutdata a;
+ struct internal_exec e;
};
-#define adata(bfd) ((bfd)->tdata.aout_data->a)
-#define exec_hdr(bfd) (adata(bfd).hdr)
-#define obj_aout_symbols(bfd) (adata(bfd).symbols)
-#define obj_textsec(bfd) (adata(bfd).textsec)
-#define obj_datasec(bfd) (adata(bfd).datasec)
-#define obj_bsssec(bfd) (adata(bfd).bsssec)
-#define obj_sym_filepos(bfd) (adata(bfd).sym_filepos)
-#define obj_str_filepos(bfd) (adata(bfd).str_filepos)
-#define obj_reloc_entry_size(bfd) (adata(bfd).reloc_entry_size)
-#define obj_symbol_entry_size(bfd) (adata(bfd).symbol_entry_size)
-#define obj_aout_subformat(bfd) (adata(bfd).subformat)
-#define obj_aout_external_syms(bfd) (adata(bfd).external_syms)
-#define obj_aout_external_sym_count(bfd) (adata(bfd).external_sym_count)
-#define obj_aout_sym_window(bfd) (adata(bfd).sym_window)
-#define obj_aout_external_strings(bfd) (adata(bfd).external_strings)
-#define obj_aout_external_string_size(bfd) (adata(bfd).external_string_size)
-#define obj_aout_string_window(bfd) (adata(bfd).string_window)
-#define obj_aout_sym_hashes(bfd) (adata(bfd).sym_hashes)
-#define obj_aout_dynamic_info(bfd) (adata(bfd).dynamic_info)
+#define adata(bfd) ((bfd)->tdata.aout_data->a)
+#define exec_hdr(bfd) (adata (bfd).hdr)
+#define obj_aout_symbols(bfd) (adata (bfd).symbols)
+#define obj_textsec(bfd) (adata (bfd).textsec)
+#define obj_datasec(bfd) (adata (bfd).datasec)
+#define obj_bsssec(bfd) (adata (bfd).bsssec)
+#define obj_sym_filepos(bfd) (adata (bfd).sym_filepos)
+#define obj_str_filepos(bfd) (adata (bfd).str_filepos)
+#define obj_reloc_entry_size(bfd) (adata (bfd).reloc_entry_size)
+#define obj_symbol_entry_size(bfd) (adata (bfd).symbol_entry_size)
+#define obj_aout_subformat(bfd) (adata (bfd).subformat)
+#define obj_aout_external_syms(bfd) (adata (bfd).external_syms)
+#define obj_aout_external_sym_count(bfd) (adata (bfd).external_sym_count)
+#define obj_aout_sym_window(bfd) (adata (bfd).sym_window)
+#define obj_aout_external_strings(bfd) (adata (bfd).external_strings)
+#define obj_aout_external_string_size(bfd) (adata (bfd).external_string_size)
+#define obj_aout_string_window(bfd) (adata (bfd).string_window)
+#define obj_aout_sym_hashes(bfd) (adata (bfd).sym_hashes)
+#define obj_aout_dynamic_info(bfd) (adata (bfd).dynamic_info)
/* We take the address of the first element of an asymbol to ensure that the
macro is only ever applied to an asymbol. */
@@ -602,7 +607,7 @@ extern bfd_boolean NAME(aout,bfd_free_cached_info)
#ifndef WRITE_HEADERS
#define WRITE_HEADERS(abfd, execp) \
{ \
- bfd_size_type text_size; /* dummy vars */ \
+ bfd_size_type text_size; /* Dummy vars. */ \
file_ptr text_end; \
if (adata(abfd).magic == undecided_magic) \
NAME(aout,adjust_sizes_and_vmas) (abfd, &text_size, &text_end); \
@@ -617,7 +622,7 @@ extern bfd_boolean NAME(aout,bfd_free_cached_info)
NAME(aout,swap_exec_header_out) (abfd, execp, &exec_bytes); \
\
if (bfd_seek (abfd, (file_ptr) 0, SEEK_SET) != 0 \
- || bfd_bwrite ((PTR) &exec_bytes, (bfd_size_type) EXEC_BYTES_SIZE, \
+ || bfd_bwrite ((PTR) &exec_bytes, (bfd_size_type) EXEC_BYTES_SIZE,\
abfd) != EXEC_BYTES_SIZE) \
return FALSE; \
/* Now write out reloc info, followed by syms and strings. */ \
@@ -632,12 +637,12 @@ extern bfd_boolean NAME(aout,bfd_free_cached_info)
return FALSE; \
} \
\
- if (bfd_seek (abfd, (file_ptr) (N_TRELOFF(*execp)), SEEK_SET) != 0) \
+ if (bfd_seek (abfd, (file_ptr) (N_TRELOFF (*execp)), SEEK_SET) != 0) \
return FALSE; \
if (!NAME(aout,squirt_out_relocs) (abfd, obj_textsec (abfd))) \
return FALSE; \
\
- if (bfd_seek (abfd, (file_ptr) (N_DRELOFF(*execp)), SEEK_SET) != 0) \
+ if (bfd_seek (abfd, (file_ptr) (N_DRELOFF (*execp)), SEEK_SET) != 0) \
return FALSE; \
if (!NAME(aout,squirt_out_relocs) (abfd, obj_datasec (abfd))) \
return FALSE; \
diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h
index 10cafef..fb021d3 100644
--- a/bfd/libbfd-in.h
+++ b/bfd/libbfd-in.h
@@ -355,6 +355,9 @@ extern bfd_boolean _bfd_generic_set_section_contents
#define _bfd_nolink_bfd_merge_sections \
((bfd_boolean (*) (bfd *, struct bfd_link_info *)) \
bfd_false)
+#define _bfd_nolink_bfd_is_group_section \
+ ((bfd_boolean (*) (bfd *, const struct bfd_section *)) \
+ bfd_false)
#define _bfd_nolink_bfd_discard_group \
((bfd_boolean (*) (bfd *, struct bfd_section *)) \
bfd_false)
@@ -378,6 +381,8 @@ extern bfd_boolean _bfd_generic_set_section_contents
#define _bfd_nodynamic_get_dynamic_symtab_upper_bound _bfd_n1
#define _bfd_nodynamic_canonicalize_dynamic_symtab \
((long (*) (bfd *, asymbol **)) _bfd_n1)
+#define _bfd_nodynamic_get_synthetic_symtab \
+ ((long (*) (bfd *, asymbol **, asymbol **)) _bfd_n1)
#define _bfd_nodynamic_get_dynamic_reloc_upper_bound _bfd_n1
#define _bfd_nodynamic_canonicalize_dynamic_reloc \
((long (*) (bfd *, arelent **, asymbol **)) _bfd_n1)
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index 62043f3..6841e29 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -360,6 +360,9 @@ extern bfd_boolean _bfd_generic_set_section_contents
#define _bfd_nolink_bfd_merge_sections \
((bfd_boolean (*) (bfd *, struct bfd_link_info *)) \
bfd_false)
+#define _bfd_nolink_bfd_is_group_section \
+ ((bfd_boolean (*) (bfd *, const struct bfd_section *)) \
+ bfd_false)
#define _bfd_nolink_bfd_discard_group \
((bfd_boolean (*) (bfd *, struct bfd_section *)) \
bfd_false)
@@ -383,6 +386,8 @@ extern bfd_boolean _bfd_generic_set_section_contents
#define _bfd_nodynamic_get_dynamic_symtab_upper_bound _bfd_n1
#define _bfd_nodynamic_canonicalize_dynamic_symtab \
((long (*) (bfd *, asymbol **)) _bfd_n1)
+#define _bfd_nodynamic_get_synthetic_symtab \
+ ((long (*) (bfd *, asymbol **, asymbol **)) _bfd_n1)
#define _bfd_nodynamic_get_dynamic_reloc_upper_bound _bfd_n1
#define _bfd_nodynamic_canonicalize_dynamic_reloc \
((long (*) (bfd *, arelent **, asymbol **)) _bfd_n1)
@@ -657,6 +662,27 @@ bfd_boolean bfd_write_bigendian_4byte_int (bfd *, unsigned int);
unsigned int bfd_log2 (bfd_vma x);
/* Extracted from bfdio.c. */
+struct bfd_iovec
+{
+ /* To avoid problems with macros, a "b" rather than "f"
+ prefix is prepended to each method name. */
+ /* Attempt to read/write NBYTES on ABFD's IOSTREAM storing/fetching
+ bytes starting at PTR. Return the number of bytes actually
+ transfered (a read past end-of-file returns less than NBYTES),
+ or -1 (setting <<bfd_error>>) if an error occurs. */
+ file_ptr (*bread) (struct bfd *abfd, void *ptr, file_ptr nbytes);
+ file_ptr (*bwrite) (struct bfd *abfd, const void *ptr,
+ file_ptr nbytes);
+ /* Return the current IOSTREAM file offset, or -1 (setting <<bfd_error>>
+ if an error occurs. */
+ file_ptr (*btell) (struct bfd *abfd);
+ /* For the following, on successful completion a value of 0 is returned.
+ Otherwise, a value of -1 is returned (and <<bfd_error>> is set). */
+ int (*bseek) (struct bfd *abfd, file_ptr offset, int whence);
+ int (*bclose) (struct bfd *abfd);
+ int (*bflush) (struct bfd *abfd);
+ int (*bstat) (struct bfd *abfd, struct stat *sb);
+};
/* Extracted from bfdwin.c. */
struct _bfd_window_internal {
struct _bfd_window_internal *next;
@@ -699,6 +725,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_16_PCREL",
"BFD_RELOC_12_PCREL",
"BFD_RELOC_8_PCREL",
+ "BFD_RELOC_32_SECREL",
"BFD_RELOC_32_GOT_PCREL",
"BFD_RELOC_16_GOT_PCREL",
"BFD_RELOC_8_GOT_PCREL",
@@ -836,8 +863,6 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_HI16",
"BFD_RELOC_HI16_S",
"BFD_RELOC_LO16",
- "BFD_RELOC_PCREL_HI16_S",
- "BFD_RELOC_PCREL_LO16",
"BFD_RELOC_MIPS_LITERAL",
"BFD_RELOC_MIPS_GOT16",
"BFD_RELOC_MIPS_CALL16",
@@ -1437,6 +1462,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/libecoff.h b/bfd/libecoff.h
index 161f06c..7d4006a 100644
--- a/bfd/libecoff.h
+++ b/bfd/libecoff.h
@@ -176,41 +176,13 @@ typedef struct ecoff_symbol_struct
#define ecoff_get_sym_index(symbol) ((symbol)->udata.i)
#define ecoff_set_sym_index(symbol, idx) ((symbol)->udata.i = (idx))
-/* When generating MIPS embedded PIC code, the linker relaxes the code
- to turn PC relative branches into longer code sequences when the PC
- relative branch is out of range. This involves reading the relocs
- in bfd_relax_section as well as in bfd_final_link, and requires the
- code to keep track of which relocs have been expanded. A pointer
- to this structure is put in the used_by_bfd pointer of a section to
- keep track of this information. The user_by_bfd pointer will be
- NULL if the information was not needed. */
+/* A pointer to this structure is put in the used_by_bfd pointer of
+ a section to keep track of any per-section data.
+ The user_by_bfd pointer will be NULL if the information was not
+ needed. */
struct ecoff_section_tdata
{
- /* The unswapped relocs for this section. These are stored in
- memory so the input file does not have to be read twice. */
- PTR external_relocs;
-
- /* The contents of the section. These bytes may or may not be saved
- in memory, but if it is this is a pointer to them. */
- bfd_byte *contents;
-
- /* Offset adjustments for PC relative branches. A number other than
- 1 is an addend for a PC relative branch, or a switch table entry
- which is the difference of two .text locations; this addend
- arises because the branch or difference crosses one or more
- branches which were expanded into a larger code sequence. A 1
- means that this branch was itself expanded into a larger code
- sequence. 1 is not a possible offset, since all offsets must be
- multiples of the instruction size, which is 4; also, the only
- relocs with non-zero offsets will be PC relative branches or
- switch table entries within the same object file. If this field
- is NULL, no branches were expanded and no offsets are required.
- Otherwise there are as many entries as there are relocs in the
- section, and the entry for any reloc that is not PC relative is
- zero. */
- long *offsets;
-
/* When producing an executable (i.e., final, non-relocatable link)
on the Alpha, we may need to use multiple global pointer values
to span the entire .lita section. In essence, we allow each
diff --git a/bfd/linker.c b/bfd/linker.c
index c55fb93..58befc3 100644
--- a/bfd/linker.c
+++ b/bfd/linker.c
@@ -1,6 +1,6 @@
/* linker.c -- BFD linker routines
- Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003
- Free Software Foundation, Inc.
+ Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
+ 2003, 2004 Free Software Foundation, Inc.
Written by Steve Chamberlain and Ian Lance Taylor, Cygnus Support
This file is part of BFD, the Binary File Descriptor library.
@@ -523,10 +523,14 @@ bfd_wrapped_link_hash_lookup (bfd *abfd,
if (info->wrap_hash != NULL)
{
const char *l;
+ char prefix = '\0';
l = string;
- if (*l == bfd_get_symbol_leading_char (abfd))
- ++l;
+ if (*l == bfd_get_symbol_leading_char (abfd) || *l == info->wrap_char)
+ {
+ prefix = *l;
+ ++l;
+ }
#undef WRAP
#define WRAP "__wrap_"
@@ -544,8 +548,7 @@ bfd_wrapped_link_hash_lookup (bfd *abfd,
if (n == NULL)
return NULL;
- /* Note that symbol_leading_char may be '\0'. */
- n[0] = bfd_get_symbol_leading_char (abfd);
+ n[0] = prefix;
n[1] = '\0';
strcat (n, WRAP);
strcat (n, l);
@@ -576,8 +579,7 @@ bfd_wrapped_link_hash_lookup (bfd *abfd,
if (n == NULL)
return NULL;
- /* Note that symbol_leading_char may be '\0'. */
- n[0] = bfd_get_symbol_leading_char (abfd);
+ n[0] = prefix;
n[1] = '\0';
strcat (n, l + sizeof REAL - 1);
h = bfd_link_hash_lookup (info->hash, n, create, TRUE, follow);
diff --git a/bfd/mach-o.c b/bfd/mach-o.c
index b5d6a72..eaa7aba 100644
--- a/bfd/mach-o.c
+++ b/bfd/mach-o.c
@@ -1,5 +1,5 @@
/* Mach-O support for BFD.
- Copyright 1999, 2000, 2001, 2002, 2003
+ Copyright 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@@ -68,6 +68,7 @@
#define bfd_mach_o_set_section_contents _bfd_generic_set_section_contents
#define bfd_mach_o_bfd_gc_sections bfd_generic_gc_sections
#define bfd_mach_o_bfd_merge_sections bfd_generic_merge_sections
+#define bfd_mach_o_bfd_is_group_section bfd_generic_is_group_section
#define bfd_mach_o_bfd_discard_group bfd_generic_discard_group
static bfd_boolean bfd_mach_o_bfd_copy_private_symbol_data
diff --git a/bfd/mmo.c b/bfd/mmo.c
index 74b4c9d..d791062 100644
--- a/bfd/mmo.c
+++ b/bfd/mmo.c
@@ -1,5 +1,5 @@
/* BFD back-end for mmo objects (MMIX-specific object-format).
- Copyright 2001, 2002, 2003
+ Copyright 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Written by Hans-Peter Nilsson (hp@bitrange.com).
Infrastructure and other bits originally copied from srec.c and
@@ -3286,6 +3286,7 @@ mmo_canonicalize_reloc (abfd, section, relptr, symbols)
#define mmo_set_arch_mach bfd_default_set_arch_mach
#define mmo_bfd_relax_section bfd_generic_relax_section
#define mmo_bfd_merge_sections bfd_generic_merge_sections
+#define mmo_bfd_is_group_section bfd_generic_is_group_section
#define mmo_bfd_discard_group bfd_generic_discard_group
/* objcopy will be upset if we return -1 from bfd_get_reloc_upper_bound by
diff --git a/bfd/mpw-config.in b/bfd/mpw-config.in
deleted file mode 100644
index 31addee..0000000
--- a/bfd/mpw-config.in
+++ /dev/null
@@ -1,86 +0,0 @@
-# Configuration fragment for BFD.
-
-# This is almost always correct.
-
-Set selarchs "&bfd_{target_cpu}_arch"
-Set defvec ""
-Set selvecs ""
-Set havevecs ""
-
-If "{target_canonical}" =~ /m68k-apple-macos/
- Set BFD_BACKENDS '"{o}"coff-m68k.c.o "{o}"cofflink.c.o'
- Set defvec m68kcoff_vec
- Set selvecs '&m68kcoff_vec'
- Set havevecs '-d HAVE_m68kcoff_vec'
-
-Else If "{target_canonical}" =~ /powerpc-apple-macos/
- Set BFD_BACKENDS '"{o}"coff-pmac.c.o "{o}"xcofflink.c.o'
- Set defvec pmac_xcoff_vec
- Set selvecs '&pmac_xcoff_vec'
- Set havevecs '-d HAVE_pmac_xcoff_vec'
- Set selarchs "&bfd_powerpc_arch"
-
-Else If "{target_canonical}" =~ /i386-\Option-x-go32/
- Set BFD_BACKENDS '"{o}"coff-i386.c.o'
- Set defvec i386coff_vec
- Set selvecs '&i386coff_vec'
- Set havevecs '-d HAVE_i386coff_vec'
-
-Else If "{target_canonical}" =~ /mips-\Option-x-\Option-x/
- Set BFD_BACKENDS '"{o}"coff-mips.c.o "{o}"ecoff.c.o "{o}"ecofflink.c.o "{o}"elf32.c.o "{o}"elf32-mips.c.o "{o}"elflink.c.o'
- Set defvec ecoff_big_vec
- Set selvecs '&ecoff_big_vec,&ecoff_little_vec,&bfd_elf32_bigmips_vec'
- Set havevecs '-d HAVE_ecoff_big_vec -d HAVE_ecoff_little_vec -d HAVE_bfd_elf32_bigmips_vec'
-
-Else If "{target_canonical}" =~ /sh-\Option-x-hms/
- Set BFD_BACKENDS '"{o}"coff-sh.c.o "{o}"cofflink.c.o'
- Set defvec shcoff_vec
- Set selvecs '&shcoff_vec,&shlcoff_vec'
- Set havevecs '-d HAVE_shcoff_vec -d HAVE_shlcoff_vec'
-End If
-
-Set ta `echo {selarchs} | sed -e 's/&bfd_/{o}cpu-/g' -e 's/_arch/.c.o/g'`
-
-Set tdefaults "-d DEFAULT_VECTOR={defvec} -d SELECT_VECS={selvecs} -d SELECT_ARCHITECTURES={selarchs} {havevecs}"
-
-Echo '# From mpw-config.in' > "{o}"mk.tmp
-Echo 'WORDSIZE = 32' >> "{o}"mk.tmp
-Echo 'BFD_MACHINES = ' {ta} >> "{o}"mk.tmp
-Echo 'BFD_BACKENDS = ' {BFD_BACKENDS} >> "{o}"mk.tmp
-Echo 'TDEFAULTS = ' {tdefaults} >> "{o}"mk.tmp
-Echo 'HDEPFILES = ' >> "{o}"mk.tmp
-Echo 'TDEPFILES = ' >> "{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
-
-# We can only handle 32-bit targets right now.
-
-sed -e 's/@WORDSIZE@/32/' \Option-d
- -e 's/@wordsize@/32/' \Option-d
- -e "s/@VERSION@/`Catenate {srcdir}VERSION`/" \Option-d
- -e 's/@BFD_HOST_64_BIT_DEFINED@/0/' \Option-d
- -e 's/@BFD_HOST_64_BIT@//' \Option-d
- -e 's/@BFD_HOST_U_64_BIT@//' \Option-d
- -e 's/@BFD_HOST_64BIT_LONG@/0/' \Option-d
- "{srcdir}"bfd-in2.h >"{o}"bfd.h-new
-
-MoveIfChange "{o}"bfd.h-new "{o}"bfd.h
-
-sed -e 's/NN/32/g' "{srcdir}"elfxx-target.h >"{o}"elf32-target.h-new
-MoveIfChange "{o}"elf32-target.h-new "{o}"elf32-target.h
-
-# Pre-expand some macros in coffswap.h, so MPW C doesn't choke.
-
-sed -e 's/^ PUT_AOUTHDR_TSIZE (/ bfd_h_put_32 (/' \Option-d
- -e 's/^ PUT_AOUTHDR_DSIZE (/ bfd_h_put_32 (/' \Option-d
- -e 's/^ PUT_AOUTHDR_BSIZE (/ bfd_h_put_32 (/' \Option-d
- -e 's/^ PUT_AOUTHDR_ENTRY (/ bfd_h_put_32 (/' \Option-d
- -e 's/^ PUT_AOUTHDR_TEXT_START (/ bfd_h_put_32 (/' \Option-d
- -e 's/^ PUT_AOUTHDR_DATA_START (/ bfd_h_put_32 (/' \Option-d
- "{srcdir}"coffswap.h >"{o}"coffswap.h-new
-
-MoveIfChange "{o}"coffswap.h-new "{o}"coffswap.h
diff --git a/bfd/mpw-make.sed b/bfd/mpw-make.sed
deleted file mode 100644
index b2463c7..0000000
--- a/bfd/mpw-make.sed
+++ /dev/null
@@ -1,81 +0,0 @@
-# Sed commands to finish translating the Unix BFD Makefile into MPW syntax.
-
-# Whack out unused host and target define bits.
-/HDEFINES/s/@HDEFINES@//
-/TDEFINES/s/@TDEFINES@//
-
-# Fix pathnames to include directories.
-/^INCDIR = /s/^INCDIR = .*$/INCDIR = "{topsrcdir}"include/
-/^CSEARCH = /s/$/ -i "{INCDIR}":mpw: -i ::extra-include:/
-
-# Comment out setting of vars, configure script will add these itself.
-/^WORDSIZE =/s/^/#/
-# /^ALL_BACKENDS/s/^/#/
-/^BFD_BACKENDS/s/^/#/
-/^BFD_MACHINES/s/^/#/
-/^TDEFAULTS/s/^/#/
-
-# Remove extra, useless, "all".
-/^all \\Option-f _oldest/,/^$/d
-
-# Remove the Makefile rebuild rule.
-/^Makefile /,/--recheck/d
-
-# Don't do any recursive subdir stuff.
-/ subdir_do/s/{MAKE}/null-command/
-
-/BFD_H/s/^{BFD_H}/#{BFD_H}/
-
-# Add explicit srcdir paths to special files.
-/config.bfd/s/ config.bfd/ "{s}"config.bfd/g
-/targmatch.sed/s/ targmatch.sed/ "{s}"targmatch.sed/g
-
-# Point at include files that are always in the objdir.
-/bfd/s/"{s}"bfd\.h/"{o}"bfd.h/g
-/config/s/"{s}"config\.h/"{o}"config.h/g
-/targmatch/s/"{s}"targmatch\.h/"{o}"targmatch.h/g
-/targmatch/s/^targmatch\.h/"{o}"targmatch.h/
-/elf32-target/s/"{s}"elf32-target\.h/"{o}"elf32-target.h/g
-/elf32-target/s/^elf32-target\.h/"{o}"elf32-target.h/
-/elf64-target/s/"{s}"elf64-target\.h/"{o}"elf64-target.h/g
-/elf64-target/s/^elf64-target\.h/"{o}"elf64-target.h/
-
-/"{s}"{INCDIR}/s/"{s}"{INCDIR}/"{INCDIR}"/g
-
-/dep/s/\.dep/__dep/g
-
-# Removing duplicates is cool but presently unnecessary,
-# so whack this out.
-/^ofiles \\Option-f/,/^$/d
-/ofiles/s/{OFILES} ofiles/{OFILES}/
-/echo ofiles = /d
-/cat ofiles/s/`cat ofiles`/{OFILES}/
-
-# No corefile support.
-/COREFILE/s/@COREFILE@//
-/COREFLAG/s/@COREFLAG@//
-
-# 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
-
-# MPW Make doesn't know about $<.
-/"{o}"targets.c.o \\Option-f "{s}"targets.c Makefile/,/^$/c\
-"{o}"targets.c.o \\Option-f "{s}"targets.c Makefile\
- {CC} @DASH_C_FLAG@ {ALL_CFLAGS} {TDEFAULTS} "{s}"targets.c -o "{o}"targets.c.o
-
-/"{o}"archures.c.o \\Option-f "{s}"archures.c Makefile/,/^$/c\
-"{o}"archures.c.o \\Option-f "{s}"archures.c Makefile\
- {CC} @DASH_C_FLAG@ {ALL_CFLAGS} {TDEFAULTS} "{s}"archures.c -o "{o}"archures.c.o
-
-# Remove the .h rebuilding rules, we don't currently have a doc subdir,
-# or a way to build the prototype-hacking tool that's in it.
-/^"{srcdir}"bfd-in2.h \\Option-f /,/^$/d
-/^"{srcdir}"libbfd.h \\Option-f /,/^$/d
-/^"{srcdir}"libcoff.h \\Option-f /,/^$/d
diff --git a/bfd/netbsd-core.c b/bfd/netbsd-core.c
index 96488ac..570c0f7 100644
--- a/bfd/netbsd-core.c
+++ b/bfd/netbsd-core.c
@@ -4,41 +4,46 @@
Free Software Foundation, Inc.
Written by Paul Kranenburg, EUR
-This file is part of BFD, the Binary File Descriptor library.
+ 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 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.
+ 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. */
+ 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 "libaout.h" /* BFD a.out internal data structures */
+#include "libaout.h" /* BFD a.out internal data structures. */
#include <sys/param.h>
#include <sys/dir.h>
#include <signal.h>
#include <sys/core.h>
-/*
- * FIXME: On NetBSD/sparc CORE_FPU_OFFSET should be (sizeof (struct trapframe))
- */
+/* The machine ID for OpenBSD/sparc64 and older versions of
+ NetBSD/sparc64 overlaps with M_MIPS1. */
+#define M_SPARC64_OPENBSD M_MIPS1
-struct netbsd_core_struct {
- struct core core;
+/* Offset of StackGhost cookie within `struct md_coredump' on
+ OpenBSD/sparc. */
+#define CORE_WCOOKIE_OFFSET 344
+
+struct netbsd_core_struct
+{
+ struct core core;
} *rawptr;
-/* forward declarations */
+/* Forward declarations. */
static const bfd_target *netbsd_core_file_p
PARAMS ((bfd *abfd));
@@ -60,7 +65,7 @@ netbsd_core_file_p (abfd)
{
int i, val;
file_ptr offset;
- asection *asect, *asect2;
+ asection *asect;
struct core core;
struct coreseg coreseg;
bfd_size_type amt = sizeof core;
@@ -68,7 +73,7 @@ netbsd_core_file_p (abfd)
val = bfd_bread ((void *) &core, amt, abfd);
if (val != sizeof core)
{
- /* Too small to be a core file */
+ /* Too small to be a core file. */
bfd_set_error (bfd_error_wrong_format);
return 0;
}
@@ -139,27 +144,58 @@ netbsd_core_file_p (abfd)
asect->filepos = offset;
asect->alignment_power = 2;
- offset += coreseg.c_size;
-
-#ifdef CORE_FPU_OFFSET
- switch (CORE_GETFLAG (coreseg))
+ if (CORE_GETMID (core) == M_SPARC_NETBSD
+ && CORE_GETFLAG (coreseg) == CORE_CPU
+ && coreseg.c_size > CORE_WCOOKIE_OFFSET)
{
- case CORE_CPU:
- /* Hackish... */
- asect->_raw_size = CORE_FPU_OFFSET;
- asect2 = bfd_make_section_anyway (abfd, ".reg2");
- if (asect2 == NULL)
+ /* Truncate the .reg section. */
+ asect->_raw_size = CORE_WCOOKIE_OFFSET;
+
+ /* And create the .wcookie section. */
+ asect = bfd_make_section_anyway (abfd, ".wcookie");
+ if (asect == NULL)
goto punt;
- asect2->_raw_size = coreseg.c_size - CORE_FPU_OFFSET;
- asect2->vma = 0;
- asect2->filepos = asect->filepos + CORE_FPU_OFFSET;
- asect2->alignment_power = 2;
- asect2->flags = SEC_ALLOC + SEC_HAS_CONTENTS;
- break;
+
+ asect->flags = SEC_ALLOC + SEC_HAS_CONTENTS;
+ asect->_raw_size = 4;
+ asect->vma = 0;
+ asect->filepos = offset + CORE_WCOOKIE_OFFSET;
+ asect->alignment_power = 2;
}
-#endif
+
+ offset += coreseg.c_size;
}
+ /* Set architecture from machine ID. */
+ switch (CORE_GETMID (core))
+ {
+ case M_X86_64_NETBSD:
+ bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_x86_64);
+ break;
+
+ case M_386_NETBSD:
+ bfd_default_set_arch_mach (abfd, bfd_arch_i386, bfd_mach_i386_i386);
+ break;
+
+ case M_POWERPC_NETBSD:
+ bfd_default_set_arch_mach (abfd, bfd_arch_powerpc, bfd_mach_ppc);
+ break;
+
+ case M_SPARC_NETBSD:
+ bfd_default_set_arch_mach (abfd, bfd_arch_sparc, bfd_mach_sparc);
+ break;
+
+ case M_SPARC64_NETBSD:
+ case M_SPARC64_OPENBSD:
+ bfd_default_set_arch_mach (abfd, bfd_arch_sparc, bfd_mach_sparc_v9);
+ break;
+
+ case M_VAX_NETBSD:
+ case M_VAX4K_NETBSD:
+ bfd_default_set_arch_mach (abfd, bfd_arch_vax, 0);
+ break;
+ }
+
/* OK, we believe you. You're a core file (sure, sure). */
return abfd->xvec;
@@ -191,14 +227,17 @@ netbsd_core_file_matches_executable_p (core_bfd, exec_bfd)
bfd *core_bfd ATTRIBUTE_UNUSED;
bfd *exec_bfd ATTRIBUTE_UNUSED;
{
- return TRUE; /* FIXME, We have no way of telling at this point */
+ /* FIXME, We have no way of telling at this point. */
+ return TRUE;
}
/* If somebody calls any byte-swapping routines, shoot them. */
+
static void
swap_abort ()
{
- abort (); /* This way doesn't require any declaration for ANSI to fuck up */
+ /* This way doesn't require any declaration for ANSI to fuck up. */
+ abort ();
}
#define NO_GET ((bfd_vma (*) (const void *)) swap_abort)
@@ -212,15 +251,15 @@ const bfd_target netbsd_core_vec =
{
"netbsd-core",
bfd_target_unknown_flavour,
- BFD_ENDIAN_UNKNOWN, /* target byte order */
- BFD_ENDIAN_UNKNOWN, /* target headers byte order */
- (HAS_RELOC | EXEC_P | /* object flags */
+ BFD_ENDIAN_UNKNOWN, /* Target byte order. */
+ BFD_ENDIAN_UNKNOWN, /* Target headers byte order. */
+ (HAS_RELOC | EXEC_P | /* Object flags. */
HAS_LINENO | HAS_DEBUG |
HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED),
- (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
- 0, /* symbol prefix */
- ' ', /* ar_pad_char */
- 16, /* ar_max_namelen */
+ (SEC_HAS_CONTENTS | SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* Section flags. */
+ 0, /* Symbol prefix. */
+ ' ', /* ar_pad_char. */
+ 16, /* ar_max_namelen. */
NO_GET64, NO_GETS64, NO_PUT64, /* 64 bit data. */
NO_GET, NO_GETS, NO_PUT, /* 32 bit data. */
NO_GET, NO_GETS, NO_PUT, /* 16 bit data. */
@@ -228,17 +267,17 @@ const bfd_target netbsd_core_vec =
NO_GET, NO_GETS, NO_PUT, /* 32 bit hdrs. */
NO_GET, NO_GETS, NO_PUT, /* 16 bit hdrs. */
- { /* bfd_check_format */
- _bfd_dummy_target, /* unknown format */
- _bfd_dummy_target, /* object file */
- _bfd_dummy_target, /* archive */
- netbsd_core_file_p /* a core file */
+ { /* bfd_check_format. */
+ _bfd_dummy_target, /* Unknown format. */
+ _bfd_dummy_target, /* Object file. */
+ _bfd_dummy_target, /* Archive. */
+ netbsd_core_file_p /* A core file. */
},
- { /* bfd_set_format */
+ { /* bfd_set_format. */
bfd_false, bfd_false,
bfd_false, bfd_false
},
- { /* bfd_write_contents */
+ { /* bfd_write_contents. */
bfd_false, bfd_false,
bfd_false, bfd_false
},
@@ -255,5 +294,5 @@ const bfd_target netbsd_core_vec =
NULL,
- (PTR) 0 /* backend_data */
+ (PTR) 0 /* Backend_data. */
};
diff --git a/bfd/nlm-target.h b/bfd/nlm-target.h
index 70ae4f4..cf84000 100644
--- a/bfd/nlm-target.h
+++ b/bfd/nlm-target.h
@@ -1,5 +1,5 @@
/* Target definitions for 32/64-bit NLM (NetWare Loadable Module)
- Copyright 1993, 1994, 1998, 1999, 2000, 2001, 2002, 2003
+ Copyright 1993, 1994, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@@ -44,6 +44,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
#define nlm_bfd_relax_section bfd_generic_relax_section
#define nlm_bfd_gc_sections bfd_generic_gc_sections
#define nlm_bfd_merge_sections bfd_generic_merge_sections
+#define nlm_bfd_is_group_section bfd_generic_is_group_section
#define nlm_bfd_discard_group bfd_generic_discard_group
#define nlm_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
#define nlm_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
diff --git a/bfd/oasys.c b/bfd/oasys.c
index be6a8d9..2108bda 100644
--- a/bfd/oasys.c
+++ b/bfd/oasys.c
@@ -1,6 +1,6 @@
/* BFD back-end for oasys objects.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2001,
- 2002, 2003 Free Software Foundation, Inc.
+ 2002, 2003, 2004 Free Software Foundation, Inc.
Written by Steve Chamberlain of Cygnus Support, <sac@cygnus.com>.
This file is part of BFD, the Binary File Descriptor library.
@@ -1506,6 +1506,7 @@ oasys_sizeof_headers (abfd, exec)
#define oasys_bfd_relax_section bfd_generic_relax_section
#define oasys_bfd_gc_sections bfd_generic_gc_sections
#define oasys_bfd_merge_sections bfd_generic_merge_sections
+#define oasys_bfd_is_group_section bfd_generic_is_group_section
#define oasys_bfd_discard_group bfd_generic_discard_group
#define oasys_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
#define oasys_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
diff --git a/bfd/opncls.c b/bfd/opncls.c
index 6abd405..7603030 100644
--- a/bfd/opncls.c
+++ b/bfd/opncls.c
@@ -103,6 +103,7 @@ _bfd_new_bfd_contained_in (bfd *obfd)
if (nbfd == NULL)
return NULL;
nbfd->xvec = obfd->xvec;
+ nbfd->iovec = obfd->iovec;
nbfd->my_archive = obfd;
nbfd->direction = read_direction;
nbfd->target_defaulted = obfd->target_defaulted;
@@ -322,6 +323,183 @@ bfd_openstreamr (const char *filename, const char *target, void *streamarg)
return nbfd;
}
+
+/*
+FUNCTION
+ bfd_openr_iovec
+
+SYNOPSIS
+ bfd *bfd_openr_iovec (const char *filename, const char *target,
+ void *(*open) (struct bfd *nbfd,
+ void *open_closure),
+ void *open_closure,
+ file_ptr (*pread) (struct bfd *nbfd,
+ void *stream,
+ void *buf,
+ file_ptr nbytes,
+ file_ptr offset),
+ int (*close) (struct bfd *nbfd,
+ void *stream));
+
+DESCRIPTION
+
+ Create and return a BFD backed by a read-only @var{stream}.
+ The @var{stream} is created using @var{open}, accessed using
+ @var{pread} and destroyed using @var{close}.
+
+ Calls <<bfd_find_target>>, so @var{target} is interpreted as by
+ that function.
+
+ Calls @var{open} (which can call <<bfd_zalloc>> and
+ <<bfd_get_filename>>) to obtain the read-only stream backing
+ the BFD. @var{open} either succeeds returning the
+ non-<<NULL>> @var{stream}, or fails returning <<NULL>>
+ (setting <<bfd_error>>).
+
+ Calls @var{pread} to request @var{nbytes} of data from
+ @var{stream} starting at @var{offset} (e.g., via a call to
+ <<bfd_read>>). @var{pread} either succeeds returning the
+ number of bytes read (which can be less than @var{nbytes} when
+ end-of-file), or fails returning -1 (setting <<bfd_error>>).
+
+ Calls @var{close} when the BFD is later closed using
+ <<bfd_close>>. @var{close} either succeeds returning 0, or
+ fails returning -1 (setting <<bfd_error>>).
+
+ If <<bfd_openr_iovec>> returns <<NULL>> then an error has
+ occurred. Possible errors are <<bfd_error_no_memory>>,
+ <<bfd_error_invalid_target>> and <<bfd_error_system_call>>.
+
+*/
+
+struct opncls
+{
+ void *stream;
+ file_ptr (*pread) (struct bfd *abfd, void *stream, void *buf,
+ file_ptr nbytes, file_ptr offset);
+ int (*close) (struct bfd *abfd, void *stream);
+ file_ptr where;
+};
+
+static file_ptr
+opncls_btell (struct bfd *abfd)
+{
+ struct opncls *vec = abfd->iostream;
+ return vec->where;
+}
+
+static int
+opncls_bseek (struct bfd *abfd, file_ptr offset, int whence)
+{
+ struct opncls *vec = abfd->iostream;
+ switch (whence)
+ {
+ case SEEK_SET: vec->where = offset; break;
+ case SEEK_CUR: vec->where += offset; break;
+ case SEEK_END: return -1;
+ }
+ return 0;
+}
+
+static file_ptr
+opncls_bread (struct bfd *abfd, void *buf, file_ptr nbytes)
+{
+ struct opncls *vec = abfd->iostream;
+ file_ptr nread = vec->pread (abfd, vec->stream, buf, nbytes, vec->where);
+ if (nread < 0)
+ return nread;
+ vec->where += nread;
+ return nread;
+}
+
+static file_ptr
+opncls_bwrite (struct bfd *abfd ATTRIBUTE_UNUSED,
+ const void *where ATTRIBUTE_UNUSED,
+ file_ptr nbytes ATTRIBUTE_UNUSED)
+{
+ return -1;
+}
+
+static int
+opncls_bclose (struct bfd *abfd)
+{
+ struct opncls *vec = abfd->iostream;
+ /* Since the VEC's memory is bound to the bfd deleting the bfd will
+ free it. */
+ int status = 0;
+ if (vec->close != NULL)
+ status = vec->close (abfd, vec->stream);
+ abfd->iostream = NULL;
+ return status;
+}
+
+static int
+opncls_bflush (struct bfd *abfd ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+static int
+opncls_bstat (struct bfd *abfd ATTRIBUTE_UNUSED, struct stat *sb)
+{
+ memset (sb, 0, sizeof (*sb));
+ return 0;
+}
+
+static const struct bfd_iovec opncls_iovec = {
+ &opncls_bread, &opncls_bwrite, &opncls_btell, &opncls_bseek,
+ &opncls_bclose, &opncls_bflush, &opncls_bstat
+};
+
+bfd *
+bfd_openr_iovec (const char *filename, const char *target,
+ void *(*open) (struct bfd *nbfd,
+ void *open_closure),
+ void *open_closure,
+ file_ptr (*pread) (struct bfd *abfd,
+ void *stream,
+ void *buf,
+ file_ptr nbytes,
+ file_ptr offset),
+ int (*close) (struct bfd *nbfd,
+ void *stream))
+{
+ bfd *nbfd;
+ const bfd_target *target_vec;
+ struct opncls *vec;
+ void *stream;
+
+ nbfd = _bfd_new_bfd ();
+ if (nbfd == NULL)
+ return NULL;
+
+ target_vec = bfd_find_target (target, nbfd);
+ if (target_vec == NULL)
+ {
+ _bfd_delete_bfd (nbfd);
+ return NULL;
+ }
+
+ nbfd->filename = filename;
+ nbfd->direction = read_direction;
+
+ stream = open (nbfd, open_closure);
+ if (stream == NULL)
+ {
+ _bfd_delete_bfd (nbfd);
+ return NULL;
+ }
+
+ vec = bfd_zalloc (nbfd, sizeof (struct opncls));
+ vec->stream = stream;
+ vec->pread = pread;
+ vec->close = close;
+
+ nbfd->iovec = &opncls_iovec;
+ nbfd->iostream = vec;
+
+ return nbfd;
+}
/* bfd_openw -- open for writing.
Returns a pointer to a freshly-allocated BFD on success, or NULL.
@@ -415,7 +593,12 @@ bfd_close (bfd *abfd)
if (! BFD_SEND (abfd, _close_and_cleanup, (abfd)))
return FALSE;
- ret = bfd_cache_close (abfd);
+ /* FIXME: cagney/2004-02-15: Need to implement a BFD_IN_MEMORY io
+ vector. */
+ if (!(abfd->flags & BFD_IN_MEMORY))
+ ret = abfd->iovec->bclose (abfd);
+ else
+ ret = 0;
/* If the file was open for writing and is now executable,
make it so. */
@@ -630,7 +813,7 @@ INTERNAL_FUNCTION
bfd_alloc
SYNOPSIS
- void *bfd_alloc (bfd *abfd, size_t wanted);
+ void *bfd_alloc (bfd *abfd, bfd_size_type wanted);
DESCRIPTION
Allocate a block of @var{wanted} bytes of memory attached to
diff --git a/bfd/pe-i386.c b/bfd/pe-i386.c
index a912cff..be691fd 100644
--- a/bfd/pe-i386.c
+++ b/bfd/pe-i386.c
@@ -1,5 +1,5 @@
/* BFD back-end for Intel 386 PECOFF files.
- Copyright 1995, 1996, 1999, 2001, 2002 Free Software Foundation, Inc.
+ Copyright 1995, 1996, 1999, 2001, 2002, 2004 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@@ -20,12 +20,13 @@
#include "bfd.h"
#include "sysdep.h"
-#define TARGET_SYM i386pe_vec
-#define TARGET_NAME "pe-i386"
+#define TARGET_SYM i386pe_vec
+#define TARGET_NAME "pe-i386"
#define COFF_WITH_PE
-#define PCRELOFFSET TRUE
-#define TARGET_UNDERSCORE '_'
+#define PCRELOFFSET TRUE
+#define TARGET_UNDERSCORE '_'
#define COFF_LONG_SECTION_NAMES
+#define COFF_SUPPORT_GNU_LINKONCE
#define COFF_LONG_FILENAMES
#define COFF_SECTION_ALIGNMENT_ENTRIES \
@@ -38,6 +39,10 @@
{ COFF_SECTION_NAME_PARTIAL_MATCH (".idata"), \
COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
{ COFF_SECTION_NAME_EXACT_MATCH (".pdata"), \
- COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.wi."), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }
#include "coff-i386.c"
diff --git a/bfd/pe-mips.c b/bfd/pe-mips.c
index 3066aaa..6e74c7e 100644
--- a/bfd/pe-mips.c
+++ b/bfd/pe-mips.c
@@ -41,16 +41,6 @@ static reloc_howto_type *coff_mips_rtype_to_howto
PARAMS ((bfd *, asection *, struct internal_reloc *,
struct coff_link_hash_entry *, struct internal_syment *,
bfd_vma *));
-#if 0
-static void mips_ecoff_swap_reloc_in
- PARAMS ((bfd *, PTR, struct internal_reloc *));
-static void mips_ecoff_swap_reloc_out
- PARAMS ((bfd *, const struct internal_reloc *, PTR));
-static void mips_adjust_reloc_in
- PARAMS ((bfd *, const struct internal_reloc *, arelent *));
-static void mips_adjust_reloc_out
- PARAMS ((bfd *, const arelent *, struct internal_reloc *));
-#endif
static bfd_boolean in_reloc_p
PARAMS ((bfd *, reloc_howto_type *));
@@ -534,20 +524,6 @@ coff_mips_reloc_type_lookup (abfd, code)
case BFD_RELOC_MIPS_LITERAL:
mips_type = MIPS_R_LITERAL;
break;
-/* FIXME?
- case BFD_RELOC_16_PCREL_S2:
- mips_type = MIPS_R_PCREL16;
- break;
- case BFD_RELOC_PCREL_HI16_S:
- mips_type = MIPS_R_RELHI;
- break;
- case BFD_RELOC_PCREL_LO16:
- mips_type = MIPS_R_RELLO;
- break;
- case BFD_RELOC_GPREL32:
- mips_type = MIPS_R_SWITCH;
- break;
-*/
case BFD_RELOC_RVA:
mips_type = MIPS_R_RVA;
break;
diff --git a/bfd/peXXigen.c b/bfd/peXXigen.c
index 559f2a2..d7f3750 100644
--- a/bfd/peXXigen.c
+++ b/bfd/peXXigen.c
@@ -198,7 +198,6 @@ _bfd_XXi_swap_sym_in (abfd, ext1, in1)
sec->lineno_count = 0;
sec->userdata = NULL;
sec->next = (asection *) NULL;
- sec->flags = 0;
sec->alignment_power = 2;
sec->flags = SEC_HAS_CONTENTS | SEC_ALLOC | SEC_DATA | SEC_LOAD;
@@ -658,14 +657,19 @@ _bfd_XXi_swap_aouthdr_out (abfd, in, out)
{
asection *sec;
+ bfd_vma hsize = 0;
bfd_vma dsize = 0;
- bfd_vma isize = SA(abfd->sections->filepos);
+ bfd_vma isize = 0;
bfd_vma tsize = 0;
for (sec = abfd->sections; sec; sec = sec->next)
{
int rounded = FA(sec->_raw_size);
+ /* The first non-zero section filepos is the header size.
+ Sections without contents will have a filepos of 0. */
+ if (hsize == 0)
+ hsize = sec->filepos;
if (sec->flags & SEC_DATA)
dsize += rounded;
if (sec->flags & SEC_CODE)
@@ -682,10 +686,10 @@ _bfd_XXi_swap_aouthdr_out (abfd, in, out)
aouthdr_in->dsize = dsize;
aouthdr_in->tsize = tsize;
- extra->SizeOfImage = isize;
+ extra->SizeOfHeaders = hsize;
+ extra->SizeOfImage = SA(hsize) + isize;
}
- extra->SizeOfHeaders = abfd->sections->filepos;
H_PUT_16 (abfd, aouthdr_in->magic, aouthdr_out->standard.magic);
#define LINKER_VERSION 256 /* That is, 2.56 */
@@ -983,7 +987,6 @@ _bfd_XXi_swap_scnhdr_out (abfd, in, out)
};
pe_required_section_flags * p;
- int flags = scnhdr_int->s_flags;
/* We have defaulted to adding the IMAGE_SCN_MEM_WRITE flag, but now
we know exactly what this specific section wants so we remove it
@@ -992,19 +995,18 @@ _bfd_XXi_swap_scnhdr_out (abfd, in, out)
default WP_TEXT file flag has been cleared. WP_TEXT may be cleared
by ld --enable-auto-import (if auto-import is actually needed),
by ld --omagic, or by obcopy --writable-text. */
-
- if (strcmp (scnhdr_int->s_name, ".text")
- || (bfd_get_file_flags (abfd) & WP_TEXT))
- flags &= ~IMAGE_SCN_MEM_WRITE;
for (p = known_sections; p->section_name; p++)
if (strcmp (scnhdr_int->s_name, p->section_name) == 0)
{
- flags |= p->must_have;
+ if (strcmp (scnhdr_int->s_name, ".text")
+ || (bfd_get_file_flags (abfd) & WP_TEXT))
+ scnhdr_int->s_flags &= ~IMAGE_SCN_MEM_WRITE;
+ scnhdr_int->s_flags |= p->must_have;
break;
}
- H_PUT_32 (abfd, flags, scnhdr_ext->s_flags);
+ H_PUT_32 (abfd, scnhdr_int->s_flags, scnhdr_ext->s_flags);
}
if (coff_data (abfd)->link_info
diff --git a/bfd/pef.c b/bfd/pef.c
index 7d758cf..e1bb5a7 100644
--- a/bfd/pef.c
+++ b/bfd/pef.c
@@ -1,5 +1,5 @@
/* PEF support for BFD.
- Copyright 1999, 2000, 2001, 2002, 2003
+ Copyright 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@@ -52,6 +52,7 @@
#define bfd_pef_bfd_relax_section bfd_generic_relax_section
#define bfd_pef_bfd_gc_sections bfd_generic_gc_sections
#define bfd_pef_bfd_merge_sections bfd_generic_merge_sections
+#define bfd_pef_bfd_is_group_section bfd_generic_is_group_section
#define bfd_pef_bfd_discard_group bfd_generic_discard_group
#define bfd_pef_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
#define bfd_pef_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
diff --git a/bfd/pei-i386.c b/bfd/pei-i386.c
index 63a63a8..4a59f14 100644
--- a/bfd/pei-i386.c
+++ b/bfd/pei-i386.c
@@ -1,5 +1,5 @@
/* BFD back-end for Intel 386 PE IMAGE COFF files.
- Copyright 1995, 1996, 1999, 2002 Free Software Foundation, Inc.
+ Copyright 1995, 1996, 1999, 2002, 2004 Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@@ -20,13 +20,14 @@
#include "bfd.h"
#include "sysdep.h"
-#define TARGET_SYM i386pei_vec
-#define TARGET_NAME "pei-i386"
+#define TARGET_SYM i386pei_vec
+#define TARGET_NAME "pei-i386"
#define COFF_IMAGE_WITH_PE
#define COFF_WITH_PE
-#define PCRELOFFSET TRUE
-#define TARGET_UNDERSCORE '_'
+#define PCRELOFFSET TRUE
+#define TARGET_UNDERSCORE '_'
#define COFF_LONG_SECTION_NAMES
+#define COFF_SUPPORT_GNU_LINKONCE
#define COFF_LONG_FILENAMES
#define COFF_SECTION_ALIGNMENT_ENTRIES \
@@ -39,6 +40,10 @@
{ COFF_SECTION_NAME_PARTIAL_MATCH (".idata"), \
COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
{ COFF_SECTION_NAME_EXACT_MATCH (".pdata"), \
- COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 2 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".debug"), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }, \
+{ COFF_SECTION_NAME_PARTIAL_MATCH (".gnu.linkonce.wi."), \
+ COFF_ALIGNMENT_FIELD_EMPTY, COFF_ALIGNMENT_FIELD_EMPTY, 0 }
#include "coff-i386.c"
diff --git a/bfd/po/SRC-POTFILES.in b/bfd/po/SRC-POTFILES.in
index 07742dd..d29593d 100644
--- a/bfd/po/SRC-POTFILES.in
+++ b/bfd/po/SRC-POTFILES.in
@@ -185,7 +185,6 @@ elfcore.h
elf-eh-frame.c
elf-hppa.h
elflink.c
-elflink.h
elf-m10200.c
elf-m10300.c
elfn32-mips.c
diff --git a/bfd/po/bfd.pot b/bfd/po/bfd.pot
index 5d4f234..dd37e15 100644
--- a/bfd/po/bfd.pot
+++ b/bfd/po/bfd.pot
@@ -1,12 +1,14 @@
# SOME DESCRIPTIVE TITLE.
-# Copyright (C) YEAR Free Software Foundation, Inc.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
#
#, fuzzy
msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
-"POT-Creation-Date: 2003-07-17 14:52+0100\n"
+"Report-Msgid-Bugs-To: \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"
@@ -34,22 +36,22 @@ msgstr ""
msgid "%s: Bad relocation record imported: %d"
msgstr ""
-#: aoutx.h:1295 aoutx.h:1716
+#: aoutx.h:1296 aoutx.h:1717
#, c-format
msgid "%s: can not represent section `%s' in a.out object file format"
msgstr ""
-#: aoutx.h:1682
+#: aoutx.h:1683
#, c-format
msgid ""
"%s: can not represent section for symbol `%s' in a.out object file format"
msgstr ""
-#: aoutx.h:1684
+#: aoutx.h:1685
msgid "*unknown*"
msgstr ""
-#: aoutx.h:3776
+#: aoutx.h:3777
#, c-format
msgid "%s: relocatable link from %s to %s not supported"
msgstr ""
@@ -171,15 +173,16 @@ msgid "not mapping: data=%lx mapped=%d\n"
msgstr ""
#: bfdwin.c:205
+#, c-format
msgid "not mapping: env var not set\n"
msgstr ""
-#: binary.c:306
+#: binary.c:308
#, c-format
msgid "Warning: Writing section `%s' to huge (ie negative) file offset 0x%lx."
msgstr ""
-#: coff-rs6000.c:3616 coff64-rs6000.c:2109
+#: coff64-rs6000.c:2108 coff-rs6000.c:3615
#, c-format
msgid "%s: symbol `%s' has unrecognized smclas %d"
msgstr ""
@@ -212,169 +215,181 @@ msgstr ""
msgid "using multiple gp values"
msgstr ""
-#: coff-arm.c:1066 elf32-arm.h:294
+#: coff-arm.c:1066 elf32-arm.h:465
#, c-format
msgid "%s: unable to find THUMB glue '%s' for `%s'"
msgstr ""
-#: coff-arm.c:1096 elf32-arm.h:329
+#: coff-arm.c:1096 elf32-arm.h:500
#, c-format
msgid "%s: unable to find ARM glue '%s' for `%s'"
msgstr ""
-#: coff-arm.c:1394 coff-arm.c:1489 elf32-arm.h:892 elf32-arm.h:999
+#: coff-arm.c:1400 coff-arm.c:1495 elf32-arm.h:1063 elf32-arm.h:1170
#, c-format
msgid "%s(%s): warning: interworking not enabled."
msgstr ""
-#: coff-arm.c:1398 elf32-arm.h:1002
+#: coff-arm.c:1404 elf32-arm.h:1173
#, c-format
msgid " first occurrence: %s: arm call to thumb"
msgstr ""
-#: coff-arm.c:1493 elf32-arm.h:895
+#: coff-arm.c:1499 elf32-arm.h:1066
#, c-format
msgid " first occurrence: %s: thumb call to arm"
msgstr ""
-#: coff-arm.c:1496
+#: coff-arm.c:1502
msgid " consider relinking with --support-old-code enabled"
msgstr ""
-#: coff-arm.c:1788 coff-tic80.c:687 cofflink.c:3038
+#: coff-arm.c:1797 cofflink.c:2987 coff-tic80.c:687
#, c-format
msgid "%s: bad reloc address 0x%lx in section `%s'"
msgstr ""
-#: coff-arm.c:2132
+#: coff-arm.c:2141
#, c-format
msgid "%s: illegal symbol index in reloc: %d"
msgstr ""
-#: coff-arm.c:2265
+#: coff-arm.c:2274
#, c-format
msgid "ERROR: %s is compiled for APCS-%d, whereas %s is compiled for APCS-%d"
msgstr ""
-#: coff-arm.c:2280 elf32-arm.h:2328
+#: 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:2283 elf32-arm.h:2333
+#: coff-arm.c:2292 elf32-arm.h:2487
#, c-format
msgid ""
"ERROR: %s passes floats in integer registers, whereas %s passes them in "
"float registers"
msgstr ""
-#: coff-arm.c:2298
+#: coff-arm.c:2307
#, c-format
msgid ""
"ERROR: %s is compiled as position independent code, whereas target %s is "
"absolute position"
msgstr ""
-#: coff-arm.c:2301
+#: coff-arm.c:2310
#, c-format
msgid ""
"ERROR: %s is compiled as absolute position code, whereas target %s is "
"position independent"
msgstr ""
-#: coff-arm.c:2330 elf32-arm.h:2405
+#: coff-arm.c:2339 elf32-arm.h:2559
#, c-format
msgid "Warning: %s supports interworking, whereas %s does not"
msgstr ""
-#: coff-arm.c:2333 elf32-arm.h:2412
+#: coff-arm.c:2342 elf32-arm.h:2566
#, c-format
msgid "Warning: %s does not support interworking, whereas %s does"
msgstr ""
-#: coff-arm.c:2360
+#: coff-arm.c:2369
#, c-format
msgid "private flags = %x:"
msgstr ""
-#: coff-arm.c:2368 elf32-arm.h:2467
+#: coff-arm.c:2377 elf32-arm.h:2621
+#, c-format
msgid " [floats passed in float registers]"
msgstr ""
-#: coff-arm.c:2370
+#: coff-arm.c:2379
+#, c-format
msgid " [floats passed in integer registers]"
msgstr ""
-#: coff-arm.c:2373 elf32-arm.h:2470
+#: coff-arm.c:2382 elf32-arm.h:2624
+#, c-format
msgid " [position independent]"
msgstr ""
-#: coff-arm.c:2375
+#: coff-arm.c:2384
+#, c-format
msgid " [absolute position]"
msgstr ""
-#: coff-arm.c:2379
+#: coff-arm.c:2388
+#, c-format
msgid " [interworking flag not initialised]"
msgstr ""
-#: coff-arm.c:2381
+#: coff-arm.c:2390
+#, c-format
msgid " [interworking supported]"
msgstr ""
-#: coff-arm.c:2383
+#: coff-arm.c:2392
+#, c-format
msgid " [interworking not supported]"
msgstr ""
-#: coff-arm.c:2431 elf32-arm.h:2150
+#: 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:2435 elf32-arm.h:2154
+#: coff-arm.c:2444 elf32-arm.h:2290
#, c-format
msgid "Warning: Clearing the interworking flag of %s due to outside request"
msgstr ""
-#: coffcode.h:1108
+#: coffcode.h:1112
#, c-format
msgid "%s (%s): Section flag %s (0x%x) ignored"
msgstr ""
-#: coffcode.h:2214
+#: coffcode.h:2224
#, c-format
msgid "Unrecognized TI COFF target id '0x%x'"
msgstr ""
-#: coffcode.h:4439
+#: coffcode.h:4428
+#, c-format
+msgid "%s: warning: line number table read failed"
+msgstr ""
+
+#: coffcode.h:4461
#, c-format
msgid "%s: warning: illegal symbol index %ld in line numbers"
msgstr ""
-#: coffcode.h:4453
+#: coffcode.h:4475
#, c-format
msgid "%s: warning: duplicate line number information for `%s'"
msgstr ""
-#: coffcode.h:4807
+#: coffcode.h:4831
#, c-format
msgid "%s: Unrecognized storage class %d for %s symbol `%s'"
msgstr ""
-#: coffcode.h:4940
+#: coffcode.h:4964
#, c-format
msgid "warning: %s: local symbol `%s' has no section"
msgstr ""
-#: coff-tic4x.c:218 coff-tic54x.c:373 coffcode.h:5047
+#: coffcode.h:5071 coff-i860.c:610 coff-tic4x.c:218 coff-tic54x.c:366
#, c-format
msgid "%s: warning: illegal symbol index %ld in relocs"
msgstr ""
-#: coffcode.h:5085
+#: coffcode.h:5109
#, c-format
msgid "%s: illegal relocation type %d at address 0x%lx"
msgstr ""
@@ -384,40 +399,45 @@ msgstr ""
msgid "%s: bad string table size %lu"
msgstr ""
-#: coff-h8300.c:1047
+#: coff-h8300.c:1124
#, c-format
msgid "cannot handle R_MEM_INDIRECT reloc when using %s output"
msgstr ""
+#: coff-i860.c:142
+#, c-format
+msgid "Relocation `%s' not yet implemented\n"
+msgstr ""
+
#: coff-i960.c:137 coff-i960.c:486
msgid "uncertain calling convention for non-COFF symbol"
msgstr ""
-#: cofflink.c:538 elflink.h:1276
+#: cofflink.c:506 elflink.c:3665
#, c-format
msgid "Warning: type of symbol `%s' changed from %d to %d in %s"
msgstr ""
-#: cofflink.c:2328
+#: cofflink.c:2293
#, c-format
msgid "%s: relocs in section `%s', but it has no contents"
msgstr ""
-#: cofflink.c:2671 coffswap.h:890
+#: cofflink.c:2629 coffswap.h:890
#, c-format
msgid "%s: %s: reloc overflow: 0x%lx > 0xffff"
msgstr ""
-#: cofflink.c:2680 coffswap.h:876
+#: cofflink.c:2638 coffswap.h:876
#, c-format
msgid "%s: warning: %s: line number overflow: 0x%lx > 0xffff"
msgstr ""
-#: coff-m68k.c:482 coff-mips.c:2394 elf32-m68k.c:2193 elf32-mips.c:1783
+#: coff-m68k.c:482 coff-mips.c:2394 elf32-m68k.c:2145 elf32-mips.c:1405
msgid "unsupported reloc type"
msgstr ""
-#: coff-mips.c:839 elf32-mips.c:1088 elf64-mips.c:1590 elfn32-mips.c:1554
+#: coff-mips.c:839 elf32-mips.c:795 elf64-mips.c:1490 elfn32-mips.c:1301
msgid "GP relative relocation when _gp not defined"
msgstr ""
@@ -431,17 +451,17 @@ msgstr ""
msgid "reloc not properly aligned"
msgstr ""
-#: coff-rs6000.c:2790
+#: coff-rs6000.c:2789
#, c-format
msgid "%s: unsupported relocation type 0x%02x"
msgstr ""
-#: coff-rs6000.c:2883
+#: coff-rs6000.c:2882
#, c-format
msgid "%s: TOC reloc at 0x%x to symbol `%s' with no TOC entry"
msgstr ""
-#: coff-tic4x.c:170 coff-tic54x.c:288 coff-tic80.c:450
+#: coff-tic4x.c:170 coff-tic54x.c:281 coff-tic80.c:450
#, c-format
msgid "Unrecognized reloc type 0x%x"
msgstr ""
@@ -461,72 +481,72 @@ msgstr ""
msgid "warning: unable to update contents of %s section in %s"
msgstr ""
-#: dwarf2.c:380
+#: dwarf2.c:289
msgid "Dwarf Error: Can't find .debug_str section."
msgstr ""
-#: dwarf2.c:397
+#: dwarf2.c:306
#, c-format
msgid ""
"Dwarf Error: DW_FORM_strp offset (%lu) greater than or equal to .debug_str "
"size (%lu)."
msgstr ""
-#: dwarf2.c:541
+#: dwarf2.c:441
msgid "Dwarf Error: Can't find .debug_abbrev section."
msgstr ""
-#: dwarf2.c:556
+#: dwarf2.c:456
#, c-format
msgid ""
"Dwarf Error: Abbrev offset (%lu) greater than or equal to .debug_abbrev size "
"(%lu)."
msgstr ""
-#: dwarf2.c:756
+#: dwarf2.c:654
#, c-format
msgid "Dwarf Error: Invalid or unhandled FORM value: %u."
msgstr ""
-#: dwarf2.c:933
+#: dwarf2.c:827
msgid "Dwarf Error: mangled line number section (bad file number)."
msgstr ""
-#: dwarf2.c:1032
+#: dwarf2.c:920
msgid "Dwarf Error: Can't find .debug_line section."
msgstr ""
-#: dwarf2.c:1049
+#: dwarf2.c:937
#, c-format
msgid ""
"Dwarf Error: Line offset (%lu) greater than or equal to .debug_line size (%"
"lu)."
msgstr ""
-#: dwarf2.c:1255
+#: dwarf2.c:1142
msgid "Dwarf Error: mangled line number section."
msgstr ""
-#: dwarf2.c:1470 dwarf2.c:1620
+#: dwarf2.c:1352 dwarf2.c:1501
#, c-format
msgid "Dwarf Error: Could not find abbrev number %u."
msgstr ""
-#: dwarf2.c:1581
+#: dwarf2.c:1462
#, c-format
msgid ""
"Dwarf Error: found dwarf version '%u', this reader only handles version 2 "
"information."
msgstr ""
-#: dwarf2.c:1588
+#: dwarf2.c:1469
#, c-format
msgid ""
"Dwarf Error: found address size '%u', this reader can not handle sizes "
"greater than '%u'."
msgstr ""
-#: dwarf2.c:1611
+#: dwarf2.c:1492
#, c-format
msgid "Dwarf Error: Bad abbrev number: %u."
msgstr ""
@@ -592,323 +612,404 @@ msgid ""
" Type: %s"
msgstr ""
-#: elf32-arm.h:1228
+#: elf32-arm.h:1416
#, c-format
msgid "%s: Warning: Arm BLX instruction targets Arm function '%s'."
msgstr ""
-#: elf32-arm.h:1424
+#: elf32-arm.h:1612
#, c-format
msgid "%s: Warning: Thumb BLX instruction targets thumb function '%s'."
msgstr ""
-#: elf32-arm.h:1918 elf32-sh.c:4706 elf64-sh64.c:1613
+#: 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:2012
+#: elf32-arm.h:2172
#, c-format
msgid ""
"%s: warning: unresolvable relocation %d against symbol `%s' from %s section"
msgstr ""
-#: elf-m10200.c:442 elf-m10300.c:1695 elf32-arm.h:2088 elf32-avr.c:812
-#: elf32-cris.c:1390 elf32-d10v.c:482 elf32-fr30.c:634 elf32-frv.c:815
-#: elf32-h8300.c:509 elf32-i860.c:1028 elf32-ip2k.c:1586 elf32-iq2000.c:699
-#: elf32-m32r.c:1283 elf32-m68hc1x.c:1305 elf32-msp430.c:510
-#: elf32-openrisc.c:436 elf32-v850.c:1777 elf32-xstormy16.c:976
-#: elf64-mmix.c:1332
+#: 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 ""
-#: elf-m10200.c:446 elf-m10300.c:1699 elf32-arm.h:2092 elf32-avr.c:816
-#: elf32-cris.c:1394 elf32-d10v.c:486 elf32-fr30.c:638 elf32-frv.c:819
-#: elf32-h8300.c:513 elf32-i860.c:1032 elf32-iq2000.c:703 elf32-m32r.c:1287
-#: elf32-m68hc1x.c:1309 elf32-msp430.c:514 elf32-openrisc.c:440
-#: elf32-v850.c:1781 elf32-xstormy16.c:980 elf64-mmix.c:1336 elfxx-mips.c:6452
+#: 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 ""
-#: elf-m10200.c:450 elf-m10300.c:1703 elf32-arm.h:2096 elf32-d10v.c:490
-#: elf32-h8300.c:517 elf32-m32r.c:1291 elf32-m68hc1x.c:1313
+#: 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 ""
-#: elf-m10200.c:454 elf-m10300.c:1707 elf32-arm.h:2100 elf32-avr.c:824
-#: elf32-cris.c:1402 elf32-d10v.c:494 elf32-fr30.c:646 elf32-frv.c:827
-#: elf32-h8300.c:521 elf32-i860.c:1040 elf32-ip2k.c:1601 elf32-iq2000.c:711
-#: elf32-m32r.c:1295 elf32-m68hc1x.c:1317 elf32-msp430.c:522
-#: elf32-openrisc.c:448 elf32-v850.c:1801 elf32-xstormy16.c:988
-#: elf64-mmix.c:1344
+#: 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:2202
+#: 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:2302
+#: 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:2316
+#: elf32-arm.h:2470
#, c-format
msgid "ERROR: %s is compiled for APCS-%d, whereas target %s uses APCS-%d"
msgstr ""
-#: elf32-arm.h:2344
+#: elf32-arm.h:2498
#, c-format
msgid "ERROR: %s uses VFP instructions, whereas %s does not"
msgstr ""
-#: elf32-arm.h:2349
+#: elf32-arm.h:2503
#, c-format
msgid "ERROR: %s uses FPA instructions, whereas %s does not"
msgstr ""
-#: elf32-arm.h:2360 elf32-arm.h:2365
+#: elf32-arm.h:2514
#, c-format
msgid "ERROR: %s uses Maverick instructions, whereas %s does not"
msgstr ""
-#: elf32-arm.h:2385
+#: elf32-arm.h:2519
+#, c-format
+msgid "ERROR: %s does not use Maverick instructions, whereas %s does"
+msgstr ""
+
+#: elf32-arm.h:2539
#, c-format
msgid "ERROR: %s uses software FP, whereas %s uses hardware FP"
msgstr ""
-#: elf32-arm.h:2390
+#: elf32-arm.h:2544
#, c-format
msgid "ERROR: %s uses hardware FP, whereas %s uses software FP"
msgstr ""
#. Ignore init flag - it may not be set, despite the flags field
#. containing valid data.
-#: elf32-arm.h:2443 elf32-cris.c:2975 elf32-m68hc1x.c:1459 elf32-m68k.c:397
-#: elf32-vax.c:546 elfxx-mips.c:9240
+#. Ignore init flag - it may not be set, despite the flags field containing valid data.
+#: 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:2452
+#: elf32-arm.h:2606
+#, c-format
msgid " [interworking enabled]"
msgstr ""
-#: elf32-arm.h:2460
+#: elf32-arm.h:2614
+#, c-format
msgid " [VFP float format]"
msgstr ""
-#: elf32-arm.h:2462
+#: elf32-arm.h:2616
+#, c-format
msgid " [Maverick float format]"
msgstr ""
-#: elf32-arm.h:2464
+#: elf32-arm.h:2618
+#, c-format
msgid " [FPA float format]"
msgstr ""
-#: elf32-arm.h:2473
+#: elf32-arm.h:2627
+#, c-format
msgid " [new ABI]"
msgstr ""
-#: elf32-arm.h:2476
+#: elf32-arm.h:2630
+#, c-format
msgid " [old ABI]"
msgstr ""
-#: elf32-arm.h:2479
+#: elf32-arm.h:2633
+#, c-format
msgid " [software FP]"
msgstr ""
-#: elf32-arm.h:2488
+#: elf32-arm.h:2642
+#, c-format
msgid " [Version1 EABI]"
msgstr ""
-#: elf32-arm.h:2491 elf32-arm.h:2502
+#: elf32-arm.h:2645 elf32-arm.h:2656
+#, c-format
msgid " [sorted symbol table]"
msgstr ""
-#: elf32-arm.h:2493 elf32-arm.h:2504
+#: elf32-arm.h:2647 elf32-arm.h:2658
+#, c-format
msgid " [unsorted symbol table]"
msgstr ""
-#: elf32-arm.h:2499
+#: elf32-arm.h:2653
+#, c-format
msgid " [Version2 EABI]"
msgstr ""
-#: elf32-arm.h:2507
+#: elf32-arm.h:2661
+#, c-format
msgid " [dynamic symbols use segment index]"
msgstr ""
-#: elf32-arm.h:2510
+#: elf32-arm.h:2664
+#, c-format
msgid " [mapping symbols precede others]"
msgstr ""
-#: elf32-arm.h:2517
+#: 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>"
msgstr ""
-#: elf32-arm.h:2524
+#: elf32-arm.h:2690
+#, c-format
msgid " [relocatable executable]"
msgstr ""
-#: elf32-arm.h:2527
+#: elf32-arm.h:2693
+#, c-format
msgid " [has entry point]"
msgstr ""
-#: elf32-arm.h:2532
+#: elf32-arm.h:2698
+#, c-format
msgid "<Unrecognised flag bits set>"
msgstr ""
-#: elf32-avr.c:820 elf32-cris.c:1398 elf32-fr30.c:642 elf32-frv.c:823
-#: elf32-i860.c:1036 elf32-ip2k.c:1597 elf32-iq2000.c:707 elf32-msp430.c:518
-#: elf32-openrisc.c:444 elf32-v850.c:1785 elf32-xstormy16.c:984
-#: elf64-mmix.c:1340
+#: 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:931
+#: elf32-cris.c:921
#, c-format
msgid "%s: unresolvable relocation %s against symbol `%s' from %s section"
msgstr ""
-#: elf32-cris.c:993
+#: 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:996 elf32-cris.c:1122
+#: 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:1111
+#: 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:1118
+#: 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:1143
+#: elf32-cris.c:1138
#, c-format
msgid ""
"%s: relocation %s is not allowed for global symbol: `%s' from %s section"
msgstr ""
-#: elf32-cris.c:1158
+#: elf32-cris.c:1153
#, c-format
msgid "%s: relocation %s in section %s with no GOT created"
msgstr ""
-#: elf32-cris.c:1277
+#: elf32-cris.c:1272
#, c-format
msgid "%s: Internal inconsistency; no relocation section %s"
msgstr ""
-#: elf32-cris.c:2500
+#: 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:2978
+#: elf32-cris.c:2983
+#, c-format
msgid " [symbols have a _ prefix]"
msgstr ""
-#: elf32-cris.c:3017
+#: elf32-cris.c:3022
#, c-format
msgid "%s: uses _-prefixed symbols, but writing file with non-prefixed symbols"
msgstr ""
-#: elf32-cris.c:3018
+#: elf32-cris.c:3023
#, c-format
msgid "%s: uses non-prefixed symbols, but writing file with _-prefixed symbols"
msgstr ""
-#: elf32-frv.c:1223
+#: elf32-frv.c:2013
+msgid "Dynamic relocation references symbol with nonzero addend"
+msgstr ""
+
+#: elf32-frv.c:2026
+msgid "relocation references symbol not defined in the module"
+msgstr ""
+
+#: elf32-frv.c:2120
+msgid "R_FRV_FUNCDESC references dynamic symbol with nonzero addend"
+msgstr ""
+
+#: elf32-frv.c:2158 elf32-frv.c:2257
+msgid "cannot emit fixups in read-only section"
+msgstr ""
+
+#: elf32-frv.c:2181 elf32-frv.c:2294
+msgid "cannot emit dynamic relocations in read-only section"
+msgstr ""
+
+#: elf32-frv.c:2216
+msgid "R_FRV_FUNCDESC_VALUE references dynamic symbol with nonzero addend"
+msgstr ""
+
+#: elf32-frv.c:2386
+msgid "relocations between different segments are not supported"
+msgstr ""
+
+#: elf32-frv.c:2387
+msgid "warning: relocation references a different segment"
+msgstr ""
+
+#: elf32-frv.c:4390
#, c-format
msgid ""
"%s: compiled with %s and linked with modules that use non-pic relocations"
msgstr ""
-#: elf32-frv.c:1273 elf32-iq2000.c:895
+#: elf32-frv.c:4443 elf32-iq2000.c:862
#, c-format
msgid "%s: compiled with %s and linked with modules compiled with %s"
msgstr ""
-#: elf32-frv.c:1285
+#: elf32-frv.c:4455
#, c-format
msgid ""
"%s: uses different unknown e_flags (0x%lx) fields than previous modules (0x%"
"lx)"
msgstr ""
-#: elf32-frv.c:1321 elf32-iq2000.c:933
+#: 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:672 elf32-m68hc1x.c:176 elf64-ppc.c:3118
+#: 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:957 elf32-hppa.c:3538
+#: 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:1340 elf64-x86-64.c:672 elf64-x86-64.c:797
+#: 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:1360
+#: 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:1553
+#: elf32-hppa.c:1377
#, c-format
msgid "Could not find relocation section for %s"
msgstr ""
-#: elf32-hppa.c:2828
+#: elf32-hppa.c:2572
#, c-format
msgid "%s: duplicate export stub %s"
msgstr ""
-#: elf32-hppa.c:3416
+#: 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:3192
#, c-format
msgid "%s(%s+0x%lx): fixing %s"
msgstr ""
-#: elf32-hppa.c:4039
+#: elf32-hppa.c:3810
#, c-format
msgid "%s(%s+0x%lx): cannot handle %s for %s"
msgstr ""
-#: elf32-hppa.c:4357
+#: elf32-hppa.c:4103
msgid ".got section not immediately after .plt section"
msgstr ""
@@ -917,33 +1018,33 @@ msgstr ""
msgid "%s: invalid relocation type %d"
msgstr ""
-#: elf32-i386.c:841 elf32-s390.c:990 elf32-sparc.c:887 elf32-xtensa.c:637
-#: elf64-s390.c:943 elf64-x86-64.c:650
+#: 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:949 elf32-s390.c:1168 elf32-sh.c:6426 elf32-sparc.c:1011
-#: elf64-s390.c:1129
+#: 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:1064 elf32-s390.c:1279 elf64-ppc.c:3929 elf64-s390.c:1243
-#: elf64-x86-64.c:886
+#: 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:2908 elf32-m68k.c:1757 elf32-s390.c:3022 elf32-sparc.c:2879
-#: elf32-xtensa.c:2193 elf64-s390.c:3018 elf64-sparc.c:2664
-#: elf64-x86-64.c:2452
+#: 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:2947 elf32-m68k.c:1796 elf32-s390.c:3072 elf64-s390.c:3068
-#: elf64-x86-64.c:2490
+#: 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 ""
@@ -968,130 +1069,155 @@ msgid "ip2k linker: redundant page instruction at 0x%08lx (dest = 0x%08lx)."
msgstr ""
#. Only if it's not an unresolved symbol.
-#: elf32-ip2k.c:1593
+#: elf32-ip2k.c:1575
msgid "unsupported relocation between data/insn address spaces"
msgstr ""
-#: elf32-iq2000.c:907 elf32-m68hc1x.c:1431 elf32-ppc.c:2175 elf64-sparc.c:3072
-#: elfxx-mips.c:9197
+#: 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 ""
-#: elf32-m32r.c:930
+#: elf32-m32r.c:1487
msgid "SDA relocation when _SDA_BASE_ not defined"
msgstr ""
-#: elf32-ia64.c:3817 elf32-m32r.c:1018 elf64-alpha.c:4279 elf64-alpha.c:4407
-#: elf64-ia64.c:3817
+#: 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:1226
+#: 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:3128
#, c-format
msgid "%s: The target (%s) of an %s relocation is in the wrong section (%s)"
msgstr ""
-#: elf32-m32r.c:1952
+#: elf32-m32r.c:4211
#, c-format
msgid "%s: Instruction set mismatch with previous modules"
msgstr ""
-#: elf32-m32r.c:1975
+#: elf32-m32r.c:4234
#, c-format
msgid "private flags = %lx"
msgstr ""
-#: elf32-m32r.c:1980
+#: elf32-m32r.c:4239
+#, c-format
msgid ": m32r instructions"
msgstr ""
-#: elf32-m32r.c:1981
+#: elf32-m32r.c:4240
+#, c-format
msgid ": m32rx instructions"
msgstr ""
-#: elf32-m68hc1x.c:1217
+#: elf32-m32r.c:4241
+#, c-format
+msgid ": m32r2 instructions"
+msgstr ""
+
+#: 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:1240
+#: 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:1259
+#: 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:1396
+#: 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:1404
+#: 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:1414
+#: elf32-m68hc1x.c:1295
#, c-format
msgid "%s: linking files compiled for HCS12 with others compiled for HC12"
msgstr ""
-#: elf32-m68hc1x.c:1462
+#: elf32-m68hc1x.c:1341
+#, c-format
msgid "[abi=32-bit int, "
msgstr ""
-#: elf32-m68hc1x.c:1464
+#: elf32-m68hc1x.c:1343
+#, c-format
msgid "[abi=16-bit int, "
msgstr ""
-#: elf32-m68hc1x.c:1467
+#: elf32-m68hc1x.c:1346
+#, c-format
msgid "64-bit double, "
msgstr ""
-#: elf32-m68hc1x.c:1469
+#: elf32-m68hc1x.c:1348
+#, c-format
msgid "32-bit double, "
msgstr ""
-#: elf32-m68hc1x.c:1472
+#: elf32-m68hc1x.c:1351
+#, c-format
msgid "cpu=HC11]"
msgstr ""
-#: elf32-m68hc1x.c:1474
+#: elf32-m68hc1x.c:1353
+#, c-format
msgid "cpu=HCS12]"
msgstr ""
-#: elf32-m68hc1x.c:1476
+#: elf32-m68hc1x.c:1355
+#, c-format
msgid "cpu=HC12]"
msgstr ""
-#: elf32-m68hc1x.c:1479
+#: elf32-m68hc1x.c:1358
+#, c-format
msgid " [memory=bank-model]"
msgstr ""
-#: elf32-m68hc1x.c:1481
+#: elf32-m68hc1x.c:1360
+#, c-format
msgid " [memory=flat]"
msgstr ""
#: elf32-m68k.c:400
+#, c-format
msgid " [cpu32]"
msgstr ""
#: elf32-m68k.c:403
+#, c-format
msgid " [m68000]"
msgstr ""
@@ -1105,230 +1231,239 @@ msgstr ""
msgid "%s: Unknown relocation type %d\n"
msgstr ""
-#: elf32-mips.c:1170 elf64-mips.c:1717 elfn32-mips.c:1664
-msgid "32bits gp relative relocation occurs for an external symbol"
-msgstr ""
-
-#: elf32-mips.c:1314 elf64-mips.c:1830 elfn32-mips.c:1783
+#: elf32-mips.c:968 elf64-mips.c:1693 elfn32-mips.c:1488
#, c-format
msgid "Linking mips16 objects into %s format is not supported"
msgstr ""
-#: elf32-ppc.c:2056
+#: elf32-ppc.c:2174
#, c-format
msgid "generic linker can't handle %s"
msgstr ""
-#: elf32-ppc.c:2138
+#: elf32-ppc.c:2256
#, c-format
msgid ""
"%s: compiled with -mrelocatable and linked with modules compiled normally"
msgstr ""
-#: elf32-ppc.c:2147
+#: elf32-ppc.c:2265
#, c-format
msgid ""
"%s: compiled normally and linked with modules compiled with -mrelocatable"
msgstr ""
-#: elf32-ppc.c:3413
+#: elf32-ppc.c:3534
#, c-format
msgid "%s: relocation %s cannot be used when making a shared object"
msgstr ""
-#. It does not make sense to have a procedure linkage
-#. table entry for a local symbol.
-#: elf32-ppc.c:3619
+#: elf32-ppc.c:3740
#, c-format
msgid "%s(%s+0x%lx): %s reloc against local symbol"
msgstr ""
-#: elf32-ppc.c:4862 elf64-ppc.c:7789
+#: elf32-ppc.c:4945 elf64-ppc.c:8022
#, c-format
msgid "%s: unknown relocation type %d for symbol %s"
msgstr ""
-#: elf32-ppc.c:5113
+#: elf32-ppc.c:5196
#, c-format
msgid "%s(%s+0x%lx): non-zero addend on %s reloc against `%s'"
msgstr ""
-#: elf32-ppc.c:5399 elf32-ppc.c:5425 elf32-ppc.c:5484
+#: 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:5539
+#: elf32-ppc.c:5647
#, c-format
msgid "%s: relocation %s is not yet supported for symbol %s."
msgstr ""
-#: elf32-ppc.c:5594 elf64-ppc.c:8461
+#: 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:5644 elf64-ppc.c:8507
+#: 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:5888
+#: elf32-ppc.c:5996
#, c-format
msgid "corrupt or empty %s section in %s"
msgstr ""
-#: elf32-ppc.c:5895
+#: elf32-ppc.c:6003
#, c-format
msgid "unable to read in %s section from %s"
msgstr ""
-#: elf32-ppc.c:5901
+#: elf32-ppc.c:6009
#, c-format
msgid "corrupt %s section in %s"
msgstr ""
-#: elf32-ppc.c:5944
+#: elf32-ppc.c:6052
#, c-format
msgid "warning: unable to set size of %s section in %s"
msgstr ""
-#: elf32-ppc.c:5994
+#: elf32-ppc.c:6102
msgid "failed to allocate space for new APUinfo section."
msgstr ""
-#: elf32-ppc.c:6013
+#: elf32-ppc.c:6121
msgid "failed to compute new APUinfo section."
msgstr ""
-#: elf32-ppc.c:6016
+#: elf32-ppc.c:6124
msgid "failed to install new APUinfo section."
msgstr ""
-#: elf32-s390.c:2256 elf64-s390.c:2226
+#: 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:221 elf64-sh64.c:2407
+#: 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:224 elf64-sh64.c:2410
+#: 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:226 elf64-sh64.c:2412
+#: 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:461 elf64-sh64.c:2990
+#: elf32-sh64.c:442 elf64-sh64.c:2955
#, c-format
msgid "%s: encountered datalabel symbol in input"
msgstr ""
-#: elf32-sh64.c:544
+#: elf32-sh64.c:519
msgid "PTB mismatch: a SHmedia address (bit 0 == 1)"
msgstr ""
-#: elf32-sh64.c:547
+#: elf32-sh64.c:522
msgid "PTA mismatch: a SHcompact address (bit 0 == 0)"
msgstr ""
-#: elf32-sh64.c:565
+#: elf32-sh64.c:540
#, c-format
msgid "%s: GAS error: unexpected PTB insn with R_SH_PT_16"
msgstr ""
-#: elf32-sh64.c:614 elf64-sh64.c:1748
+#: elf32-sh64.c:589 elf64-sh64.c:1736
#, c-format
msgid "%s: error: unaligned relocation type %d at %08x reloc %08x\n"
msgstr ""
-#: elf32-sh64.c:698
+#: elf32-sh64.c:670
#, c-format
msgid "%s: could not write out added .cranges entries"
msgstr ""
-#: elf32-sh64.c:760
+#: elf32-sh64.c:732
#, c-format
msgid "%s: could not write out sorted .cranges entries"
msgstr ""
-#: elf32-sh.c:2103
+#: elf32-sh.c:2252
#, c-format
msgid "%s: 0x%lx: warning: bad R_SH_USES offset"
msgstr ""
-#: elf32-sh.c:2115
+#: elf32-sh.c:2264
#, c-format
msgid "%s: 0x%lx: warning: R_SH_USES points to unrecognized insn 0x%x"
msgstr ""
-#: elf32-sh.c:2132
+#: elf32-sh.c:2281
#, c-format
msgid "%s: 0x%lx: warning: bad R_SH_USES load offset"
msgstr ""
-#: elf32-sh.c:2147
+#: elf32-sh.c:2296
#, c-format
msgid "%s: 0x%lx: warning: could not find expected reloc"
msgstr ""
-#: elf32-sh.c:2175
+#: elf32-sh.c:2324
#, c-format
msgid "%s: 0x%lx: warning: symbol in unexpected section"
msgstr ""
-#: elf32-sh.c:2300
+#: elf32-sh.c:2449
#, c-format
msgid "%s: 0x%lx: warning: could not find expected COUNT reloc"
msgstr ""
-#: elf32-sh.c:2309
+#: elf32-sh.c:2458
#, c-format
msgid "%s: 0x%lx: warning: bad count"
msgstr ""
-#: elf32-sh.c:2712 elf32-sh.c:3088
+#: elf32-sh.c:2858 elf32-sh.c:3227
#, c-format
msgid "%s: 0x%lx: fatal: reloc overflow while relaxing"
msgstr ""
-#: elf32-sh.c:4654 elf64-sh64.c:1585
+#: elf32-sh.c:4756 elf64-sh64.c:1568
msgid "Unexpected STO_SH5_ISA32 on local symbol is not handled"
msgstr ""
-#: elf32-sh.c:4809
+#: elf32-sh.c:4913
#, c-format
msgid "%s: unresolvable relocation against symbol `%s' from %s section"
msgstr ""
-#: elf32-sh.c:4881
+#: elf32-sh.c:4984
#, c-format
msgid "%s: 0x%lx: fatal: unaligned branch target for relax-support relocation"
msgstr ""
-#: elf32-sh.c:6627 elf64-alpha.c:4848
+#: elf32-sh.c:5017 elf32-sh.c:5032
+#, c-format
+msgid "%s: 0x%lx: fatal: unaligned %s relocation 0x%lx"
+msgstr ""
+
+#: 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:5060
+#, c-format
+msgid "%s: 0x%lx: fatal: R_SH_PSHL relocation %d not in range -32..32"
+msgstr ""
+
+#: 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:2521 elf64-sparc.c:2314
+#: elf32-sparc.c:2499 elf64-sparc.c:2270
#, c-format
msgid "%s: probably compiled without -fPIC?"
msgstr ""
-#: elf32-sparc.c:3348
+#: elf32-sparc.c:3325
#, c-format
msgid "%s: compiled for a 64 bit system and target is 32 bit"
msgstr ""
-#: elf32-sparc.c:3362
+#: elf32-sparc.c:3339
#, c-format
msgid "%s: linking little endian files with big endian files"
msgstr ""
@@ -1363,48 +1498,59 @@ msgid ""
msgstr ""
#: elf32-v850.c:1144
+#, c-format
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:1963
+#: elf32-v850.c:1951
#, c-format
msgid "%s: Architecture mismatch with previous modules"
msgstr ""
-#: elf32-v850.c:1983
+#: elf32-v850.c:1972
#, c-format
msgid "private flags = %lx: "
msgstr ""
-#: elf32-v850.c:1988
+#: elf32-v850.c:1977
+#, c-format
msgid "v850 architecture"
msgstr ""
-#: elf32-v850.c:1989
+#: elf32-v850.c:1978
+#, c-format
msgid "v850e architecture"
msgstr ""
+#: elf32-v850.c:1979
+#, c-format
+msgid "v850e1 architecture"
+msgstr ""
+
#: elf32-vax.c:549
+#, c-format
msgid " [nonpic]"
msgstr ""
#: elf32-vax.c:552
+#, c-format
msgid " [d-float]"
msgstr ""
#: elf32-vax.c:555
+#, c-format
msgid " [g-float]"
msgstr ""
@@ -1415,79 +1561,92 @@ msgid ""
"%ld"
msgstr ""
-#: elf32-vax.c:1667
+#: elf32-vax.c:1645
#, c-format
msgid "%s: warning: PLT addend of %d to `%s' from %s section ignored"
msgstr ""
-#: elf32-vax.c:1802
+#: elf32-vax.c:1771
#, c-format
msgid "%s: warning: %s relocation against symbol `%s' from %s section"
msgstr ""
-#: elf32-vax.c:1808
+#: elf32-vax.c:1777
#, c-format
msgid "%s: warning: %s relocation to 0x%x from %s section"
msgstr ""
-#: elf32-ia64.c:2326 elf32-xstormy16.c:462 elf64-ia64.c:2326
+#: elf32-xstormy16.c:462 elf32-ia64.c:2418 elf64-ia64.c:2418
msgid "non-zero addend in @fptr reloc"
msgstr ""
-#: elf64-alpha.c:1108
+#: 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 ""
-#: elf64-alpha.c:3731
+#: elf64-alpha.c:3565
+#, c-format
+msgid "Symbol %s has no GOT subsection for offset 0x%x"
+msgstr ""
+
+#: elf64-alpha.c:3651
#, c-format
msgid "%s: .got subsegment exceeds 64K (size %d)"
msgstr ""
-#: elf64-alpha.c:4602 elf64-alpha.c:4614
+#: elf64-alpha.c:4498 elf64-alpha.c:4510
#, c-format
msgid "%s: gp-relative relocation against dynamic symbol %s"
msgstr ""
-#: elf64-alpha.c:4640 elf64-alpha.c:4773
+#: elf64-alpha.c:4536 elf64-alpha.c:4669
#, c-format
msgid "%s: pc-relative relocation against dynamic symbol %s"
msgstr ""
-#: elf64-alpha.c:4668
+#: elf64-alpha.c:4564
#, c-format
msgid "%s: change in gp: BRSGP %s"
msgstr ""
-#: elf64-alpha.c:4693
+#: elf64-alpha.c:4589
msgid "<unknown>"
msgstr ""
-#: elf64-alpha.c:4698
+#: elf64-alpha.c:4594
#, c-format
msgid "%s: !samegp reloc against symbol without .prologue: %s"
msgstr ""
-#: elf64-alpha.c:4749
+#: elf64-alpha.c:4645
#, c-format
msgid "%s: unhandled dynamic relocation against %s"
msgstr ""
-#: elf64-alpha.c:4832
+#: elf64-alpha.c:4728
#, c-format
msgid "%s: dtp-relative relocation against dynamic symbol %s"
msgstr ""
-#: elf64-alpha.c:4855
+#: elf64-alpha.c:4751
#, c-format
msgid "%s: tp-relative relocation against dynamic symbol %s"
msgstr ""
-#: elf64-hppa.c:2086
+#: elf64-hppa.c:2083
#, c-format
msgid "stub entry for %s cannot load .plt, dp offset = %ld"
msgstr ""
-#: elf64-mmix.c:1032
+#: elf64-mips.c:1599 elfn32-mips.c:1388
+msgid "32bits gp relative relocation occurs for an external symbol"
+msgstr ""
+
+#: elf64-mmix.c:1171
#, c-format
msgid ""
"%s: Internal inconsistency error for value for\n"
@@ -1495,106 +1654,113 @@ msgid ""
"08lx\n"
msgstr ""
-#: elf64-mmix.c:1416
+#: elf64-mmix.c:1603
#, c-format
msgid ""
"%s: base-plus-offset relocation against register symbol: (unknown) in %s"
msgstr ""
-#: elf64-mmix.c:1421
+#: elf64-mmix.c:1608
#, c-format
msgid "%s: base-plus-offset relocation against register symbol: %s in %s"
msgstr ""
-#: elf64-mmix.c:1465
+#: elf64-mmix.c:1652
#, c-format
msgid "%s: register relocation against non-register symbol: (unknown) in %s"
msgstr ""
-#: elf64-mmix.c:1470
+#: elf64-mmix.c:1657
#, c-format
msgid "%s: register relocation against non-register symbol: %s in %s"
msgstr ""
-#: elf64-mmix.c:1507
+#: elf64-mmix.c:1694
#, c-format
msgid "%s: directive LOCAL valid only with a register or absolute value"
msgstr ""
-#: elf64-mmix.c:1535
+#: 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:1994
+#: 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:2053
+#: elf64-mmix.c:2261
msgid "Register section has contents\n"
msgstr ""
-#: elf64-mmix.c:2216
+#: elf64-mmix.c:2467
#, c-format
msgid ""
"Internal inconsistency: remaining %u != max %u.\n"
" Please report this bug."
msgstr ""
-#: elf64-ppc.c:2388 libbfd.c:831
+#: 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:2391 libbfd.c:833
+#: 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:4857
+#: elf64-ppc.c:4656
#, c-format
-msgid "%s: unexpected reloc type %u in .opd section"
+msgid ""
+"copy reloc against `%s' requires lazy plt linking; avoid setting "
+"LD_BIND_NOW=1 or upgrade gcc"
msgstr ""
-#: elf64-ppc.c:4877
+#: elf64-ppc.c:5027
#, c-format
msgid "%s: .opd is not a regular array of opd entries"
msgstr ""
-#: elf64-ppc.c:4897
+#: elf64-ppc.c:5037
+#, c-format
+msgid "%s: unexpected reloc type %u in .opd section"
+msgstr ""
+
+#: elf64-ppc.c:5057
#, c-format
msgid "%s: undefined sym `%s' in .opd section"
msgstr ""
-#: elf64-ppc.c:6136
+#: elf64-ppc.c:6272
#, c-format
msgid "can't find branch stub `%s'"
msgstr ""
-#: elf64-ppc.c:6175 elf64-ppc.c:6250
+#: elf64-ppc.c:6311 elf64-ppc.c:6386
#, c-format
msgid "linkage table error against `%s'"
msgstr ""
-#: elf64-ppc.c:6340
+#: elf64-ppc.c:6503
#, c-format
msgid "can't build branch stub `%s'"
msgstr ""
-#: elf64-ppc.c:7047
+#: elf64-ppc.c:7222
msgid ".glink and .plt too far apart"
msgstr ""
-#: elf64-ppc.c:7135
+#: elf64-ppc.c:7334
msgid "stubs don't match calculated size"
msgstr ""
-#: elf64-ppc.c:7147
+#: elf64-ppc.c:7346
#, c-format
msgid ""
"linker stubs in %u groups\n"
@@ -1605,14 +1771,24 @@ msgid ""
" plt call %lu"
msgstr ""
-#: elf64-ppc.c:7723
+#: elf64-ppc.c:7544
+#, c-format
+msgid "%s(%s+0x%lx): %s used with TLS symbol %s"
+msgstr ""
+
+#: elf64-ppc.c:7545
+#, c-format
+msgid "%s(%s+0x%lx): %s used with non-TLS symbol %s"
+msgstr ""
+
+#: 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:7731
+#: elf64-ppc.c:7964
#, c-format
msgid ""
"%s(%s+0x%lx): sibling call optimization to `%s' does not allow automatic "
@@ -1620,107 +1796,105 @@ msgid ""
"or make `%s' extern"
msgstr ""
-#: elf64-ppc.c:8329
+#: elf64-ppc.c:8562
#, c-format
msgid "%s: relocation %s is not supported for symbol %s."
msgstr ""
-#: elf64-ppc.c:8408
+#: elf64-ppc.c:8641
#, c-format
msgid "%s: error: relocation %s not a multiple of %d"
msgstr ""
-#: elf-hppa.h:1458 elf-hppa.h:1491 elf-m10300.c:1628 elf64-sh64.c:1704
-#, c-format
-msgid ""
-"%s: warning: unresolvable relocation against symbol `%s' from %s section"
-msgstr ""
-
-#: elf64-sparc.c:1370
+#: elf64-sparc.c:1371
#, c-format
msgid "%s: check_relocs: unhandled reloc type %d"
msgstr ""
-#: elf64-sparc.c:1407
+#: elf64-sparc.c:1408
#, c-format
msgid "%s: Only registers %%g[2367] can be declared using STT_REGISTER"
msgstr ""
-#: elf64-sparc.c:1427
+#: elf64-sparc.c:1428
#, c-format
msgid "Register %%g%d used incompatibly: %s in %s, previously %s in %s"
msgstr ""
-#: elf64-sparc.c:1450
+#: elf64-sparc.c:1451
#, c-format
msgid "Symbol `%s' has differing types: REGISTER in %s, previously %s in %s"
msgstr ""
-#: elf64-sparc.c:1496
+#: elf64-sparc.c:1497
#, c-format
msgid "Symbol `%s' has differing types: %s in %s, previously REGISTER in %s"
msgstr ""
-#: elf64-sparc.c:3053
+#: elf64-sparc.c:3009
#, c-format
msgid "%s: linking UltraSPARC specific with HAL specific code"
msgstr ""
-#: elf64-x86-64.c:739
+#: elf64-x86-64.c:732
#, c-format
msgid "%s: %s' accessed both as normal and thread local symbol"
msgstr ""
-#: elf.c:372
+#: elf.c:295
#, c-format
msgid "%s: invalid string offset %u >= %lu for section `%s'"
msgstr ""
-#: elf.c:624
+#: elf.c:538
#, c-format
msgid "%s: invalid SHT_GROUP entry"
msgstr ""
-#: elf.c:695
+#: elf.c:609
#, c-format
msgid "%s: no group info for section %s"
msgstr ""
-#: elf.c:1055
+#: elf.c:952
+#, c-format
msgid ""
"\n"
"Program Header:\n"
msgstr ""
-#: elf.c:1106
+#: elf.c:1003
+#, c-format
msgid ""
"\n"
"Dynamic Section:\n"
msgstr ""
-#: elf.c:1235
+#: elf.c:1131
+#, c-format
msgid ""
"\n"
"Version definitions:\n"
msgstr ""
-#: elf.c:1258
+#: elf.c:1154
+#, c-format
msgid ""
"\n"
"Version References:\n"
msgstr ""
-#: elf.c:1263
+#: elf.c:1159
#, c-format
msgid " required from %s:\n"
msgstr ""
-#: elf.c:1944
+#: elf.c:1826
#, c-format
msgid "%s: invalid link %lu for reloc section %s (index %u)"
msgstr ""
-#: elf.c:3686
+#: elf.c:3684
#, c-format
msgid "%s: Not enough room for program headers (allocated %u, need %u)"
msgstr ""
@@ -1730,271 +1904,311 @@ msgstr ""
msgid "%s: Not enough room for program headers, try linking with -N"
msgstr ""
-#: elf.c:3922
+#: elf.c:3924
#, c-format
msgid ""
"Error: First section in segment (%s) starts at 0x%x whereas the segment "
"starts at 0x%x"
msgstr ""
-#: elf.c:4242
+#: elf.c:4243
#, c-format
msgid "%s: warning: allocated section `%s' not in segment"
msgstr ""
-#: elf.c:4566
+#: elf.c:4557
#, c-format
msgid "%s: symbol `%s' required but not present"
msgstr ""
-#: elf.c:4854
+#: elf.c:4845
#, c-format
msgid "%s: warning: Empty loadable segment detected, is this intentional ?\n"
msgstr ""
-#: elf.c:5485
+#: elf.c:5479
#, c-format
msgid ""
"Unable to find equivalent output section for symbol '%s' from section '%s'"
msgstr ""
-#: elf.c:6298
+#: elf.c:6264
#, c-format
msgid "%s: unsupported relocation type %s"
msgstr ""
-#: elfcode.h:1113
+#: elfcode.h:1050
#, c-format
msgid "%s: version count (%ld) does not match symbol count (%ld)"
msgstr ""
-#: elfcode.h:1342
+#: elfcode.h:1276
#, c-format
msgid "%s(%s): relocation %d has invalid symbol index %ld"
msgstr ""
-#: elflink.c:1456
+#: elflink.c:1350
#, c-format
msgid "%s: warning: unexpected redefinition of indirect versioned symbol `%s'"
msgstr ""
-#: elflink.c:1807
+#: elflink.c:1669
#, c-format
msgid "%s: undefined versioned symbol name %s"
msgstr ""
-#: elflink.c:2142
+#: 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:2007
#, c-format
msgid "%s: relocation size mismatch in %s section %s"
msgstr ""
-#: elflink.c:2434
+#: elflink.c:2296
#, c-format
msgid "warning: type and size of dynamic symbol `%s' are not defined"
msgstr ""
-#: elflink.h:1022
+#: elflink.c:2917
+msgid "warning: "
+msgstr ""
+
+#: elflink.c:3411
#, c-format
msgid "%s: %s: invalid version %u (max %d)"
msgstr ""
-#: elflink.h:1063
+#: elflink.c:3452
#, c-format
msgid "%s: %s: invalid needed version %d"
msgstr ""
-#: elflink.h:1238
+#: elflink.c:3627
#, c-format
msgid "Warning: alignment %u of symbol `%s' in %s is smaller than %u in %s"
msgstr ""
-#: elflink.h:1252
+#: elflink.c:3641
#, c-format
msgid "Warning: size of symbol `%s' changed from %lu in %s to %lu in %s"
msgstr ""
-#: elflink.h:2160
+#: elflink.c:4837
#, c-format
msgid "%s: undefined version: %s"
msgstr ""
-#: elflink.h:2226
+#: elflink.c:4903
#, c-format
msgid "%s: .preinit_array section is not allowed in DSO"
msgstr ""
-#: elflink.h:3078
+#: elflink.c:5594
msgid "Not enough memory to sort relocations"
msgstr ""
-#: elflink.h:3958 elflink.h:4001
+#: 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:3964
+#: 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:4483
+#: 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:4564
+#: elflink.c:6575 elflink.c:6616
+msgid "%T: discarded in section `%s' from %s\n"
+msgstr ""
+
+#: elflink.c:7870 elflink.c:7912
#, c-format
-msgid "%s: could not find output section %s for input section %s"
+msgid "%s: could not find output section %s"
msgstr ""
-#: elflink.h:4666
+#: elflink.c:7876
#, c-format
-msgid "%s: %s symbol `%s' isn't defined"
+msgid "warning: %s section has zero size"
msgstr ""
-#: elflink.h:5053 elflink.h:5095
-msgid "%T: discarded in section `%s' from %s\n"
+#: elflink.c:8427
+msgid "Warning: gc-sections option ignored"
msgstr ""
-#: elfxx-mips.c:887
+#: elfxx-mips.c:890
msgid "static procedure (no name)"
msgstr ""
-#: elfxx-mips.c:1897
+#: elfxx-mips.c:2028
msgid "not enough GOT space for local GOT entries"
msgstr ""
-#: elfxx-mips.c:3691
+#: elfxx-mips.c:3775
#, c-format
msgid "%s: %s+0x%lx: jump to stub routine which is not jal"
msgstr ""
-#: elfxx-mips.c:5192
+#: elfxx-mips.c:5260
#, c-format
msgid "%s: Malformed reloc detected for section %s"
msgstr ""
-#: elfxx-mips.c:5266
+#: elfxx-mips.c:5334
#, c-format
msgid "%s: CALL16 reloc at 0x%lx not against global symbol"
msgstr ""
-#: elfxx-mips.c:8693
+#: elfxx-mips.c:8631
#, c-format
msgid "%s: illegal section name `%s'"
msgstr ""
-#: elfxx-mips.c:9027
+#: elfxx-mips.c:8954
#, c-format
msgid "%s: endianness incompatible with that of the selected emulation"
msgstr ""
-#: elfxx-mips.c:9039
+#: elfxx-mips.c:8966
#, c-format
msgid "%s: ABI is incompatible with that of the selected emulation"
msgstr ""
-#: elfxx-mips.c:9106
+#: elfxx-mips.c:9038
#, c-format
msgid "%s: warning: linking PIC files with non-PIC files"
msgstr ""
-#: elfxx-mips.c:9123
+#: elfxx-mips.c:9055
#, c-format
msgid "%s: linking 32-bit code with 64-bit code"
msgstr ""
-#: elfxx-mips.c:9151
+#: elfxx-mips.c:9083
#, c-format
msgid "%s: linking %s module with previous %s modules"
msgstr ""
-#: elfxx-mips.c:9174
+#: elfxx-mips.c:9106
#, c-format
msgid "%s: ABI mismatch: linking %s module with previous %s modules"
msgstr ""
-#: elfxx-mips.c:9243
+#: elfxx-mips.c:9171
+#, c-format
msgid " [abi=O32]"
msgstr ""
-#: elfxx-mips.c:9245
+#: elfxx-mips.c:9173
+#, c-format
msgid " [abi=O64]"
msgstr ""
-#: elfxx-mips.c:9247
+#: elfxx-mips.c:9175
+#, c-format
msgid " [abi=EABI32]"
msgstr ""
-#: elfxx-mips.c:9249
+#: elfxx-mips.c:9177
+#, c-format
msgid " [abi=EABI64]"
msgstr ""
-#: elfxx-mips.c:9251
+#: elfxx-mips.c:9179
+#, c-format
msgid " [abi unknown]"
msgstr ""
-#: elfxx-mips.c:9253
+#: elfxx-mips.c:9181
+#, c-format
msgid " [abi=N32]"
msgstr ""
-#: elfxx-mips.c:9255
+#: elfxx-mips.c:9183
+#, c-format
msgid " [abi=64]"
msgstr ""
-#: elfxx-mips.c:9257
+#: elfxx-mips.c:9185
+#, c-format
msgid " [no abi set]"
msgstr ""
-#: elfxx-mips.c:9260
+#: elfxx-mips.c:9188
+#, c-format
msgid " [mips1]"
msgstr ""
-#: elfxx-mips.c:9262
+#: elfxx-mips.c:9190
+#, c-format
msgid " [mips2]"
msgstr ""
-#: elfxx-mips.c:9264
+#: elfxx-mips.c:9192
+#, c-format
msgid " [mips3]"
msgstr ""
-#: elfxx-mips.c:9266
+#: elfxx-mips.c:9194
+#, c-format
msgid " [mips4]"
msgstr ""
-#: elfxx-mips.c:9268
+#: elfxx-mips.c:9196
+#, c-format
msgid " [mips5]"
msgstr ""
-#: elfxx-mips.c:9270
+#: elfxx-mips.c:9198
+#, c-format
msgid " [mips32]"
msgstr ""
-#: elfxx-mips.c:9272
+#: elfxx-mips.c:9200
+#, c-format
msgid " [mips64]"
msgstr ""
-#: elfxx-mips.c:9274
+#: elfxx-mips.c:9202
+#, c-format
msgid " [mips32r2]"
msgstr ""
-#: elfxx-mips.c:9276
+#: elfxx-mips.c:9204
+#, c-format
+msgid " [mips64r2]"
+msgstr ""
+
+#: elfxx-mips.c:9206
+#, c-format
msgid " [unknown ISA]"
msgstr ""
-#: elfxx-mips.c:9279
+#: elfxx-mips.c:9209
+#, c-format
msgid " [mdmx]"
msgstr ""
-#: elfxx-mips.c:9282
+#: elfxx-mips.c:9212
+#, c-format
msgid " [mips16]"
msgstr ""
-#: elfxx-mips.c:9285
+#: elfxx-mips.c:9215
+#, c-format
msgid " [32bitmode]"
msgstr ""
-#: elfxx-mips.c:9287
+#: elfxx-mips.c:9217
+#, c-format
msgid " [not 32bitmode]"
msgstr ""
@@ -2093,27 +2307,27 @@ msgstr ""
msgid "%s: address 0x%s out of range for Intel Hex file"
msgstr ""
-#: libbfd.c:861
+#: libbfd.c:851
#, c-format
msgid "Deprecated %s called at %s line %d in %s\n"
msgstr ""
-#: libbfd.c:864
+#: libbfd.c:854
#, c-format
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 ""
-#: merge.c:896
+#: merge.c:797
#, c-format
msgid "%s: access beyond end of merged section (%ld + %ld)"
msgstr ""
@@ -2286,24 +2500,24 @@ msgstr ""
msgid "%s: Unrecognised import name type; %x"
msgstr ""
-#: peicode.h:1164
+#: peicode.h:1194
#, c-format
msgid "%s: Unrecognised machine type (0x%x) in Import Library Format archive"
msgstr ""
-#: peicode.h:1176
+#: peicode.h:1206
#, c-format
msgid ""
"%s: Recognised but unhandled machine type (0x%x) in Import Library Format "
"archive"
msgstr ""
-#: peicode.h:1193
+#: peicode.h:1223
#, c-format
msgid "%s: size field is zero in Import Library Format header"
msgstr ""
-#: peicode.h:1224
+#: peicode.h:1254
#, c-format
msgid "%s: string not null terminated in ILF object file."
msgstr ""
@@ -2334,6 +2548,7 @@ msgid "%s: bad pair/reflo after refhi\n"
msgstr ""
#: ppcboot.c:416
+#, c-format
msgid ""
"\n"
"ppcboot header:\n"
@@ -2390,7 +2605,7 @@ msgstr ""
msgid "%s:%d: Unexpected character `%s' in S-record file\n"
msgstr ""
-#: stabs.c:319
+#: stabs.c:326
#, c-format
msgid "%s(%s+0x%lx): Stabs entry has invalid string index."
msgstr ""
@@ -2642,224 +2857,230 @@ msgstr ""
msgid "%s: loader reloc in read-only section %s"
msgstr ""
-#: elf32-ia64.c:2271 elf64-ia64.c:2271
+#: elf32-ia64.c:2363 elf64-ia64.c:2363
msgid "@pltoff reloc against local symbol"
msgstr ""
-#: elf32-ia64.c:3663 elf64-ia64.c:3663
+#: elf32-ia64.c:3768 elf64-ia64.c:3768
#, c-format
msgid "%s: short data segment overflowed (0x%lx >= 0x400000)"
msgstr ""
-#: elf32-ia64.c:3674 elf64-ia64.c:3674
+#: elf32-ia64.c:3779 elf64-ia64.c:3779
#, c-format
msgid "%s: __gp does not cover short data segment"
msgstr ""
-#: elf32-ia64.c:3986 elf64-ia64.c:3986
+#: elf32-ia64.c:4027 elf64-ia64.c:4027
#, c-format
-msgid "%s: linking non-pic code in a shared library"
+msgid "%s: non-pic code with imm relocation against dynamic symbol `%s'"
msgstr ""
-#: elf32-ia64.c:4017 elf64-ia64.c:4017
+#: elf32-ia64.c:4092 elf64-ia64.c:4092
#, c-format
msgid "%s: @gprel relocation against dynamic symbol %s"
msgstr ""
-#: elf32-ia64.c:4077 elf64-ia64.c:4077
+#: 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:4214 elf64-ia64.c:4214
+#: elf32-ia64.c:4289 elf64-ia64.c:4289
#, c-format
msgid "%s: @internal branch to dynamic symbol %s"
msgstr ""
-#: elf32-ia64.c:4216 elf64-ia64.c:4216
+#: elf32-ia64.c:4291 elf64-ia64.c:4291
#, c-format
msgid "%s: speculation fixup to dynamic symbol %s"
msgstr ""
-#: elf32-ia64.c:4218 elf64-ia64.c:4218
+#: elf32-ia64.c:4293 elf64-ia64.c:4293
#, c-format
msgid "%s: @pcrel relocation against dynamic symbol %s"
msgstr ""
-#: elf32-ia64.c:4430 elf64-ia64.c:4430
+#: elf32-ia64.c:4505 elf64-ia64.c:4505
msgid "unsupported reloc"
msgstr ""
-#: elf32-ia64.c:4709 elf64-ia64.c:4709
+#: 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:4718 elf64-ia64.c:4718
+#: elf32-ia64.c:4793 elf64-ia64.c:4793
#, c-format
msgid "%s: linking big-endian files with little-endian files"
msgstr ""
-#: elf32-ia64.c:4727 elf64-ia64.c:4727
+#: elf32-ia64.c:4802 elf64-ia64.c:4802
#, c-format
msgid "%s: linking 64-bit files with 32-bit files"
msgstr ""
-#: elf32-ia64.c:4736 elf64-ia64.c:4736
+#: 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:4746 elf64-ia64.c:4746
+#: elf32-ia64.c:4821 elf64-ia64.c:4821
#, c-format
msgid "%s: linking auto-pic files with non-auto-pic files"
msgstr ""
-#: peigen.c:985 pepigen.c:985
+#: peigen.c:1031 pepigen.c:1031
#, c-format
msgid "%s: line number overflow: 0x%lx > 0xffff"
msgstr ""
-#: peigen.c:1002 pepigen.c:1002
+#: peigen.c:1052 pepigen.c:1052
#, c-format
msgid "%s: reloc overflow 1: 0x%lx > 0xffff"
msgstr ""
-#: peigen.c:1016 pepigen.c:1016
+#: peigen.c:1066 pepigen.c:1066
msgid "Export Directory [.edata (or where ever we found it)]"
msgstr ""
-#: peigen.c:1017 pepigen.c:1017
+#: peigen.c:1067 pepigen.c:1067
msgid "Import Directory [parts of .idata]"
msgstr ""
-#: peigen.c:1018 pepigen.c:1018
+#: peigen.c:1068 pepigen.c:1068
msgid "Resource Directory [.rsrc]"
msgstr ""
-#: peigen.c:1019 pepigen.c:1019
+#: peigen.c:1069 pepigen.c:1069
msgid "Exception Directory [.pdata]"
msgstr ""
-#: peigen.c:1020 pepigen.c:1020
+#: peigen.c:1070 pepigen.c:1070
msgid "Security Directory"
msgstr ""
-#: peigen.c:1021 pepigen.c:1021
+#: peigen.c:1071 pepigen.c:1071
msgid "Base Relocation Directory [.reloc]"
msgstr ""
-#: peigen.c:1022 pepigen.c:1022
+#: peigen.c:1072 pepigen.c:1072
msgid "Debug Directory"
msgstr ""
-#: peigen.c:1023 pepigen.c:1023
+#: peigen.c:1073 pepigen.c:1073
msgid "Description Directory"
msgstr ""
-#: peigen.c:1024 pepigen.c:1024
+#: peigen.c:1074 pepigen.c:1074
msgid "Special Directory"
msgstr ""
-#: peigen.c:1025 pepigen.c:1025
+#: peigen.c:1075 pepigen.c:1075
msgid "Thread Storage Directory [.tls]"
msgstr ""
-#: peigen.c:1026 pepigen.c:1026
+#: peigen.c:1076 pepigen.c:1076
msgid "Load Configuration Directory"
msgstr ""
-#: peigen.c:1027 pepigen.c:1027
+#: peigen.c:1077 pepigen.c:1077
msgid "Bound Import Directory"
msgstr ""
-#: peigen.c:1028 pepigen.c:1028
+#: peigen.c:1078 pepigen.c:1078
msgid "Import Address Table Directory"
msgstr ""
-#: peigen.c:1029 pepigen.c:1029
+#: peigen.c:1079 pepigen.c:1079
msgid "Delay Import Directory"
msgstr ""
-#: peigen.c:1030 peigen.c:1031 pepigen.c:1030 pepigen.c:1031
+#: peigen.c:1080 peigen.c:1081 pepigen.c:1080 pepigen.c:1081
msgid "Reserved"
msgstr ""
-#: peigen.c:1094 pepigen.c:1094
+#: peigen.c:1144 pepigen.c:1144
+#, c-format
msgid ""
"\n"
"There is an import table, but the section containing it could not be found\n"
msgstr ""
-#: peigen.c:1099 pepigen.c:1099
+#: peigen.c:1149 pepigen.c:1149
#, c-format
msgid ""
"\n"
"There is an import table in %s at 0x%lx\n"
msgstr ""
-#: peigen.c:1136 pepigen.c:1136
+#: peigen.c:1186 pepigen.c:1186
#, c-format
msgid ""
"\n"
"Function descriptor located at the start address: %04lx\n"
msgstr ""
-#: peigen.c:1139 pepigen.c:1139
+#: peigen.c:1189 pepigen.c:1189
#, c-format
msgid "\tcode-base %08lx toc (loadable/actual) %08lx/%08lx\n"
msgstr ""
-#: peigen.c:1145 pepigen.c:1145
+#: peigen.c:1195 pepigen.c:1195
+#, c-format
msgid ""
"\n"
"No reldata section! Function descriptor not decoded.\n"
msgstr ""
-#: peigen.c:1150 pepigen.c:1150
+#: peigen.c:1200 pepigen.c:1200
#, c-format
msgid ""
"\n"
"The Import Tables (interpreted %s section contents)\n"
msgstr ""
-#: peigen.c:1153 pepigen.c:1153
+#: peigen.c:1203 pepigen.c:1203
+#, c-format
msgid ""
" vma: Hint Time Forward DLL First\n"
" Table Stamp Chain Name Thunk\n"
msgstr ""
-#: peigen.c:1204 pepigen.c:1204
+#: peigen.c:1254 pepigen.c:1254
#, c-format
msgid ""
"\n"
"\tDLL Name: %s\n"
msgstr ""
-#: peigen.c:1215 pepigen.c:1215
+#: peigen.c:1265 pepigen.c:1265
+#, c-format
msgid "\tvma: Hint/Ord Member-Name Bound-To\n"
msgstr ""
-#: peigen.c:1240 pepigen.c:1240
+#: peigen.c:1290 pepigen.c:1290
+#, c-format
msgid ""
"\n"
"There is a first thunk, but the section containing it could not be found\n"
msgstr ""
-#: peigen.c:1380 pepigen.c:1380
+#: peigen.c:1430 pepigen.c:1430
+#, c-format
msgid ""
"\n"
"There is an export table, but the section containing it could not be found\n"
msgstr ""
-#: peigen.c:1385 pepigen.c:1385
+#: peigen.c:1435 pepigen.c:1435
#, c-format
msgid ""
"\n"
"There is an export table in %s at 0x%lx\n"
msgstr ""
-#: peigen.c:1416 pepigen.c:1416
+#: peigen.c:1466 pepigen.c:1466
#, c-format
msgid ""
"\n"
@@ -2867,129 +3088,143 @@ msgid ""
"\n"
msgstr ""
-#: peigen.c:1420 pepigen.c:1420
+#: peigen.c:1470 pepigen.c:1470
#, c-format
msgid "Export Flags \t\t\t%lx\n"
msgstr ""
-#: peigen.c:1423 pepigen.c:1423
+#: peigen.c:1473 pepigen.c:1473
#, c-format
msgid "Time/Date stamp \t\t%lx\n"
msgstr ""
-#: peigen.c:1426 pepigen.c:1426
+#: peigen.c:1476 pepigen.c:1476
#, c-format
msgid "Major/Minor \t\t\t%d/%d\n"
msgstr ""
-#: peigen.c:1429 pepigen.c:1429
+#: peigen.c:1479 pepigen.c:1479
+#, c-format
msgid "Name \t\t\t\t"
msgstr ""
-#: peigen.c:1435 pepigen.c:1435
+#: peigen.c:1485 pepigen.c:1485
#, c-format
msgid "Ordinal Base \t\t\t%ld\n"
msgstr ""
-#: peigen.c:1438 pepigen.c:1438
+#: peigen.c:1488 pepigen.c:1488
+#, c-format
msgid "Number in:\n"
msgstr ""
-#: peigen.c:1441 pepigen.c:1441
+#: peigen.c:1491 pepigen.c:1491
#, c-format
msgid "\tExport Address Table \t\t%08lx\n"
msgstr ""
-#: peigen.c:1445 pepigen.c:1445
+#: peigen.c:1495 pepigen.c:1495
#, c-format
msgid "\t[Name Pointer/Ordinal] Table\t%08lx\n"
msgstr ""
-#: peigen.c:1448 pepigen.c:1448
+#: peigen.c:1498 pepigen.c:1498
+#, c-format
msgid "Table Addresses\n"
msgstr ""
-#: peigen.c:1451 pepigen.c:1451
+#: peigen.c:1501 pepigen.c:1501
+#, c-format
msgid "\tExport Address Table \t\t"
msgstr ""
-#: peigen.c:1456 pepigen.c:1456
+#: peigen.c:1506 pepigen.c:1506
+#, c-format
msgid "\tName Pointer Table \t\t"
msgstr ""
-#: peigen.c:1461 pepigen.c:1461
+#: peigen.c:1511 pepigen.c:1511
+#, c-format
msgid "\tOrdinal Table \t\t\t"
msgstr ""
-#: peigen.c:1476 pepigen.c:1476
+#: peigen.c:1526 pepigen.c:1526
#, c-format
msgid ""
"\n"
"Export Address Table -- Ordinal Base %ld\n"
msgstr ""
-#: peigen.c:1495 pepigen.c:1495
+#: peigen.c:1545 pepigen.c:1545
msgid "Forwarder RVA"
msgstr ""
-#: peigen.c:1506 pepigen.c:1506
+#: peigen.c:1556 pepigen.c:1556
msgid "Export RVA"
msgstr ""
-#: peigen.c:1513 pepigen.c:1513
+#: peigen.c:1563 pepigen.c:1563
+#, c-format
msgid ""
"\n"
"[Ordinal/Name Pointer] Table\n"
msgstr ""
-#: peigen.c:1568 pepigen.c:1568
+#: peigen.c:1618 pepigen.c:1618
#, c-format
msgid "Warning, .pdata section size (%ld) is not a multiple of %d\n"
msgstr ""
-#: peigen.c:1572 pepigen.c:1572
+#: peigen.c:1622 pepigen.c:1622
+#, c-format
msgid ""
"\n"
"The Function Table (interpreted .pdata section contents)\n"
msgstr ""
-#: peigen.c:1575 pepigen.c:1575
+#: peigen.c:1625 pepigen.c:1625
+#, c-format
msgid " vma:\t\t\tBegin Address End Address Unwind Info\n"
msgstr ""
-#: peigen.c:1577 pepigen.c:1577
+#: peigen.c:1627 pepigen.c:1627
+#, c-format
msgid ""
" vma:\t\tBegin End EH EH PrologEnd Exception\n"
" \t\tAddress Address Handler Data Address Mask\n"
msgstr ""
-#: peigen.c:1647 pepigen.c:1647
+#: peigen.c:1697 pepigen.c:1697
+#, c-format
msgid " Register save millicode"
msgstr ""
-#: peigen.c:1650 pepigen.c:1650
+#: peigen.c:1700 pepigen.c:1700
+#, c-format
msgid " Register restore millicode"
msgstr ""
-#: peigen.c:1653 pepigen.c:1653
+#: peigen.c:1703 pepigen.c:1703
+#, c-format
msgid " Glue code sequence"
msgstr ""
-#: peigen.c:1705 pepigen.c:1705
+#: peigen.c:1755 pepigen.c:1755
+#, c-format
msgid ""
"\n"
"\n"
"PE File Base Relocations (interpreted .reloc section contents)\n"
msgstr ""
-#: peigen.c:1735 pepigen.c:1735
+#: peigen.c:1785 pepigen.c:1785
#, c-format
msgid ""
"\n"
"Virtual Address: %08lx Chunk size %ld (0x%lx) Number of fixups %ld\n"
msgstr ""
-#: peigen.c:1748 pepigen.c:1748
+#: peigen.c:1798 pepigen.c:1798
#, c-format
msgid "\treloc %4d offset %4x [%4lx] %s"
msgstr ""
@@ -2997,7 +3232,7 @@ msgstr ""
#. The MS dumpbin program reportedly ands with 0xff0f before
#. printing the characteristics field. Not sure why. No reason to
#. emulate it here.
-#: peigen.c:1788 pepigen.c:1788
+#: peigen.c:1838 pepigen.c:1838
#, c-format
msgid ""
"\n"
diff --git a/bfd/ppcboot.c b/bfd/ppcboot.c
index 05fb7de..d34f1a2 100644
--- a/bfd/ppcboot.c
+++ b/bfd/ppcboot.c
@@ -1,5 +1,5 @@
/* BFD back-end for PPCbug boot records.
- 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 Michael Meissner, Cygnus Support, <meissner@cygnus.com>
@@ -469,6 +469,7 @@ ppcboot_bfd_print_private_bfd_data (abfd, farg)
#define ppcboot_bfd_relax_section bfd_generic_relax_section
#define ppcboot_bfd_gc_sections bfd_generic_gc_sections
#define ppcboot_bfd_merge_sections bfd_generic_merge_sections
+#define ppcboot_bfd_is_group_section bfd_generic_is_group_section
#define ppcboot_bfd_discard_group bfd_generic_discard_group
#define ppcboot_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
#define ppcboot_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
diff --git a/bfd/reloc.c b/bfd/reloc.c
index 9bffaa3..bc8d13b 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -1647,6 +1647,11 @@ the section containing the relocation. It depends on the specific target.
The 24-bit relocation is used in some Intel 960 configurations.
ENUM
+ BFD_RELOC_32_SECREL
+ENUMDOC
+ Section relative relocations. Some targets need this for DWARF2.
+
+ENUM
BFD_RELOC_32_GOT_PCREL
ENUMX
BFD_RELOC_16_GOT_PCREL
@@ -2061,14 +2066,6 @@ ENUM
BFD_RELOC_LO16
ENUMDOC
Low 16 bits.
-ENUM
- BFD_RELOC_PCREL_HI16_S
-ENUMDOC
- Like BFD_RELOC_HI16_S, but PC relative.
-ENUM
- BFD_RELOC_PCREL_LO16
-ENUMDOC
- Like BFD_RELOC_LO16, but PC relative.
ENUM
BFD_RELOC_MIPS_LITERAL
@@ -3771,6 +3768,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/section.c b/bfd/section.c
index fce8e1e..7f5365b 100644
--- a/bfd/section.c
+++ b/bfd/section.c
@@ -1,6 +1,6 @@
/* Object file "section" support for the BFD library.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003
+ 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Written by Cygnus Support.
@@ -801,6 +801,57 @@ bfd_get_section_by_name (bfd *abfd, const char *name)
/*
FUNCTION
+ bfd_get_section_by_name_if
+
+SYNOPSIS
+ asection *bfd_get_section_by_name_if
+ (bfd *abfd,
+ const char *name,
+ bfd_boolean (*func) (bfd *abfd, asection *sect, void *obj),
+ void *obj);
+
+DESCRIPTION
+ Call the provided function @var{func} for each section
+ attached to the BFD @var{abfd} whose name matches @var{name},
+ passing @var{obj} as an argument. The function will be called
+ as if by
+
+| func (abfd, the_section, obj);
+
+ It returns the first section for which @var{func} returns true,
+ otherwise <<NULL>>.
+
+*/
+
+asection *
+bfd_get_section_by_name_if (bfd *abfd, const char *name,
+ bfd_boolean (*operation) (bfd *,
+ asection *,
+ void *),
+ void *user_storage)
+{
+ struct section_hash_entry *sh;
+ unsigned long hash;
+
+ sh = section_hash_lookup (&abfd->section_htab, name, FALSE, FALSE);
+ if (sh == NULL)
+ return NULL;
+
+ hash = sh->root.hash;
+ do
+ {
+ if ((*operation) (abfd, &sh->section, user_storage))
+ return &sh->section;
+ sh = (struct section_hash_entry *) sh->root.next;
+ }
+ while (sh != NULL && sh->root.hash == hash
+ && strcmp (sh->root.string, name) == 0);
+
+ return NULL;
+}
+
+/*
+FUNCTION
bfd_get_unique_section_name
SYNOPSIS
@@ -945,13 +996,19 @@ bfd_make_section_anyway (bfd *abfd, const char *name)
newsect = &sh->section;
if (newsect->name != NULL)
{
- /* We are making a section of the same name. It can't go in
- section_htab without generating a unique section name and
- that would be pointless; We don't need to traverse the
- hash table. */
- newsect = bfd_zalloc (abfd, sizeof (asection));
- if (newsect == NULL)
+ /* We are making a section of the same name. Put it in the
+ section hash table. Even though we can't find it directly by a
+ hash lookup, we'll be able to find the section by traversing
+ sh->root.next quicker than looking at all the bfd sections. */
+ struct section_hash_entry *new_sh;
+ new_sh = (struct section_hash_entry *)
+ bfd_section_hash_newfunc (NULL, &abfd->section_htab, name);
+ if (new_sh == NULL)
return NULL;
+
+ new_sh->root = sh->root;
+ sh->root.next = &new_sh->root;
+ newsect = &new_sh->section;
}
newsect->name = name;
@@ -1090,6 +1147,41 @@ bfd_map_over_sections (bfd *abfd,
/*
FUNCTION
+ bfd_sections_find_if
+
+SYNOPSIS
+ asection *bfd_sections_find_if
+ (bfd *abfd,
+ bfd_boolean (*func) (bfd *abfd, asection *sect, void *obj),
+ void *obj);
+
+DESCRIPTION
+ Call the provided function @var{func} for each section
+ attached to the BFD @var{abfd}, passing @var{obj} as an
+ argument. The function will be called as if by
+
+| func (abfd, the_section, obj);
+
+ It returns the first section for which @var{func} returns true.
+
+*/
+
+asection *
+bfd_sections_find_if (bfd *abfd,
+ bfd_boolean (*operation) (bfd *, asection *, void *),
+ void *user_storage)
+{
+ asection *sect;
+
+ for (sect = abfd->sections; sect != NULL; sect = sect->next)
+ if ((*operation) (abfd, sect, user_storage))
+ break;
+
+ return sect;
+}
+
+/*
+FUNCTION
bfd_set_section_size
SYNOPSIS
@@ -1351,6 +1443,24 @@ _bfd_strip_section_from_output (struct bfd_link_info *info, asection *s)
/*
FUNCTION
+ bfd_generic_is_group_section
+
+SYNOPSIS
+ bfd_boolean bfd_generic_is_group_section (bfd *, const asection *sec);
+
+DESCRIPTION
+ Returns TRUE if @var{sec} is a member of a group.
+*/
+
+bfd_boolean
+bfd_generic_is_group_section (bfd *abfd ATTRIBUTE_UNUSED,
+ const asection *sec ATTRIBUTE_UNUSED)
+{
+ return FALSE;
+}
+
+/*
+FUNCTION
bfd_generic_discard_group
SYNOPSIS
diff --git a/bfd/simple.c b/bfd/simple.c
index 4b597a4..fc2472e 100644
--- a/bfd/simple.c
+++ b/bfd/simple.c
@@ -1,5 +1,5 @@
/* simple.c -- BFD simple client routines
- Copyright 2002, 2003
+ Copyright 2002, 2003, 2004
Free Software Foundation, Inc.
Contributed by MontaVista Software, Inc.
@@ -140,28 +140,7 @@ bfd_simple_get_relocated_section_contents (bfd *abfd,
bfd_byte *contents, *data;
int storage_needed;
void *saved_offsets;
- bfd_boolean saved_reloc_done = sec->reloc_done;
-
-#undef RETURN
-#define RETURN(x) \
- do \
- { \
- sec->reloc_done = saved_reloc_done; \
- return (x); \
- } \
- while (0)
-
- /* Foul hack to prevent bfd_section_size aborts. The reloc_done flag
- only controls that macro (and the related size macros), selecting
- between _raw_size and _cooked_size. We may be called with relocation
- done or not, so we need to save the done-flag and mark the section as
- not relocated.
-
- Debug sections won't change size while we're only relocating. There
- may be trouble here someday if it tries to run relaxation
- unexpectedly, so make sure. */
- BFD_ASSERT (sec->_raw_size == sec->_cooked_size);
- sec->reloc_done = 0;
+ bfd_size_type old_cooked_size;
if (! (sec->flags & SEC_RELOC))
{
@@ -175,7 +154,7 @@ bfd_simple_get_relocated_section_contents (bfd *abfd,
if (contents)
bfd_get_section_contents (abfd, sec, contents, 0, size);
- RETURN (contents);
+ return contents;
}
/* In order to use bfd_get_relocated_section_contents, we need
@@ -205,7 +184,7 @@ bfd_simple_get_relocated_section_contents (bfd *abfd,
{
data = bfd_malloc (bfd_section_size (abfd, sec));
if (data == NULL)
- RETURN (NULL);
+ return NULL;
outbuf = data;
}
@@ -224,7 +203,7 @@ bfd_simple_get_relocated_section_contents (bfd *abfd,
{
if (data)
free (data);
- RETURN (NULL);
+ return NULL;
}
bfd_map_over_sections (abfd, simple_save_output_info, saved_offsets);
@@ -239,6 +218,12 @@ bfd_simple_get_relocated_section_contents (bfd *abfd,
else
storage_needed = 0;
+ /* This function might be called before _cooked_size has been set, and
+ bfd_perform_relocation needs _cooked_size to be valid. */
+ old_cooked_size = sec->_cooked_size;
+ if (old_cooked_size == 0)
+ sec->_cooked_size = sec->_raw_size;
+
contents = bfd_get_relocated_section_contents (abfd,
&link_info,
&link_order,
@@ -262,10 +247,11 @@ bfd_simple_get_relocated_section_contents (bfd *abfd,
free (symbol_table);
#endif
+ sec->_cooked_size = old_cooked_size;
bfd_map_over_sections (abfd, simple_restore_output_info, saved_offsets);
free (saved_offsets);
_bfd_generic_link_hash_table_free (link_info.hash);
- RETURN (contents);
+ return contents;
}
diff --git a/bfd/som.c b/bfd/som.c
index 9066257..11766c1 100644
--- a/bfd/som.c
+++ b/bfd/som.c
@@ -1,6 +1,6 @@
/* bfd back-end for HP PA-RISC SOM objects.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003
+ 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Contributed by the Center for Software Science at the
@@ -146,6 +146,9 @@ struct som_misc_symbol_info {
unsigned int symbol_value;
unsigned int priv_level;
unsigned int secondary_def;
+ unsigned int is_comdat;
+ unsigned int is_common;
+ unsigned int dup_common;
};
/* Forward declarations. */
@@ -194,7 +197,7 @@ static bfd_boolean som_bfd_copy_private_bfd_data
static bfd_boolean som_bfd_is_local_label_name
PARAMS ((bfd *, const char *));
static bfd_boolean som_set_section_contents
- PARAMS ((bfd *, sec_ptr, PTR, file_ptr, bfd_size_type));
+ PARAMS ((bfd *, sec_ptr, const PTR, file_ptr, bfd_size_type));
static bfd_boolean som_get_section_contents
PARAMS ((bfd *, sec_ptr, PTR, file_ptr, bfd_size_type));
static bfd_boolean som_set_arch_mach
@@ -1589,6 +1592,11 @@ hppa_som_gen_reloc_type (abfd, base_type, format, field, sym_diff, sym)
final_types[3] = NULL;
*final_type = base_type;
break;
+
+ /* FIXME: These two field selectors are not currently supported. */
+ case e_ltpsel:
+ case e_rtpsel:
+ abort ();
}
switch (base_type)
@@ -1820,10 +1828,13 @@ som_object_setup (abfd, file_hdrp, aux_hdrp, current_offset)
found = 0;
for (section = abfd->sections; section; section = section->next)
{
+ bfd_vma entry;
+
if ((section->flags & SEC_CODE) == 0)
continue;
- if (aux_hdrp->exec_entry >= section->vma
- && aux_hdrp->exec_entry < section->vma + section->_cooked_size)
+ entry = aux_hdrp->exec_entry;
+ if (entry >= section->vma
+ && entry < section->vma + section->_cooked_size)
found = 1;
}
if (aux_hdrp->exec_entry == 0
@@ -1897,8 +1908,8 @@ setup_sections (abfd, file_hdr, current_offset)
for (space_index = 0; space_index < file_hdr->space_total; space_index++)
{
struct space_dictionary_record space;
- struct subspace_dictionary_record subspace, save_subspace;
- int subspace_index;
+ struct som_subspace_dictionary_record subspace, save_subspace;
+ unsigned int subspace_index;
asection *space_asect;
char *newname;
@@ -1965,7 +1976,7 @@ setup_sections (abfd, file_hdr, current_offset)
/* Initialize save_subspace so we can reliably determine if this
loop placed any useful values into it. */
- memset (&save_subspace, 0, sizeof (struct subspace_dictionary_record));
+ memset (&save_subspace, 0, sizeof (save_subspace));
/* Loop over the rest of the subspaces, building up more sections. */
for (subspace_index = 0; subspace_index < space.subspace_quantity;
@@ -1996,7 +2007,10 @@ setup_sections (abfd, file_hdr, current_offset)
if (! bfd_som_set_subsection_attributes (subspace_asect, space_asect,
subspace.access_control_bits,
subspace.sort_key,
- subspace.quadrant))
+ subspace.quadrant,
+ subspace.is_comdat,
+ subspace.is_common,
+ subspace.dup_common))
goto error_return;
/* Keep an easy mapping between subspaces and sections.
@@ -2042,9 +2056,10 @@ setup_sections (abfd, file_hdr, current_offset)
break;
}
- if (subspace.dup_common || subspace.is_common)
- subspace_asect->flags |= SEC_IS_COMMON;
- else if (subspace.subspace_length > 0)
+ if (subspace.is_comdat || subspace.is_common || subspace.dup_common)
+ subspace_asect->flags |= SEC_LINK_ONCE;
+
+ if (subspace.subspace_length > 0)
subspace_asect->flags |= SEC_HAS_CONTENTS;
if (subspace.is_loadable)
@@ -2394,21 +2409,15 @@ som_prep_headers (abfd)
else
{
/* Allocate space for the subspace dictionary. */
- amt = sizeof (struct subspace_dictionary_record);
+ amt = sizeof (struct som_subspace_dictionary_record);
som_section_data (section)->subspace_dict =
- (struct subspace_dictionary_record *) bfd_zalloc (abfd, amt);
+ (struct som_subspace_dictionary_record *) bfd_zalloc (abfd, amt);
if (som_section_data (section)->subspace_dict == NULL)
return FALSE;
/* Set subspace attributes. Basic stuff is done here, additional
attributes are filled in later as more information becomes
available. */
- if (section->flags & SEC_IS_COMMON)
- {
- som_section_data (section)->subspace_dict->dup_common = 1;
- som_section_data (section)->subspace_dict->is_common = 1;
- }
-
if (section->flags & SEC_ALLOC)
som_section_data (section)->subspace_dict->is_loadable = 1;
@@ -2431,6 +2440,12 @@ som_prep_headers (abfd)
som_section_data (section)->copy_data->access_control_bits;
som_section_data (section)->subspace_dict->quadrant =
som_section_data (section)->copy_data->quadrant;
+ som_section_data (section)->subspace_dict->is_comdat =
+ som_section_data (section)->copy_data->is_comdat;
+ som_section_data (section)->subspace_dict->is_common =
+ som_section_data (section)->copy_data->is_common;
+ som_section_data (section)->subspace_dict->dup_common =
+ som_section_data (section)->copy_data->dup_common;
}
}
return TRUE;
@@ -2725,7 +2740,7 @@ som_write_fixups (abfd, current_offset, total_reloc_sizep)
int reloc_offset;
unsigned int current_rounding_mode;
#ifndef NO_PCREL_MODES
- int current_call_mode;
+ unsigned int current_call_mode;
#endif
/* Find a subspace of this space. */
@@ -3466,7 +3481,8 @@ som_begin_writing (abfd)
num_subspaces = som_count_subspaces (abfd);
obj_som_file_hdr (abfd)->subspace_location = current_offset;
obj_som_file_hdr (abfd)->subspace_total = num_subspaces;
- current_offset += num_subspaces * sizeof (struct subspace_dictionary_record);
+ current_offset
+ += num_subspaces * sizeof (struct som_subspace_dictionary_record);
/* Next is the string table for the space/subspace names. We will
build and write the string table on the fly. At the same time
@@ -3841,7 +3857,7 @@ som_finish_writing (abfd)
som_section_data (subsection)->subspace_dict->space_index = i;
/* Dump the current subspace header. */
- amt = sizeof (struct subspace_dictionary_record);
+ amt = sizeof (struct som_subspace_dictionary_record);
if (bfd_bwrite ((PTR) som_section_data (subsection)->subspace_dict,
amt, abfd) != amt)
return FALSE;
@@ -3897,7 +3913,7 @@ som_finish_writing (abfd)
som_section_data (subsection)->subspace_dict->space_index = i;
/* Dump this subspace header. */
- amt = sizeof (struct subspace_dictionary_record);
+ amt = sizeof (struct som_subspace_dictionary_record);
if (bfd_bwrite ((PTR) som_section_data (subsection)->subspace_dict,
amt, abfd) != amt)
return FALSE;
@@ -4045,12 +4061,12 @@ som_bfd_derive_misc_symbol_info (abfd, sym, info)
info->symbol_type = ST_DATA;
else
{
- /* Common symbols must have scope SS_UNSAT and type
- ST_STORAGE or the linker will choke. */
+ /* For BFD style common, the linker will choke unless we set the
+ type and scope to ST_STORAGE and SS_UNSAT, respectively. */
if (bfd_is_com_section (sym->section))
{
- info->symbol_scope = SS_UNSAT;
info->symbol_type = ST_STORAGE;
+ info->symbol_scope = SS_UNSAT;
}
/* It is possible to have a symbol without an associated
@@ -4089,9 +4105,6 @@ som_bfd_derive_misc_symbol_info (abfd, sym, info)
info->symbol_type = ST_DATA;
}
- else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_UNKNOWN)
- info->symbol_type = ST_DATA;
-
/* From now on it's a very simple mapping. */
else if (som_symbol_data (sym)->som_type == SYMBOL_TYPE_ABSOLUTE)
info->symbol_type = ST_ABSOLUTE;
@@ -4112,14 +4125,15 @@ som_bfd_derive_misc_symbol_info (abfd, sym, info)
/* Now handle the symbol's scope. Exported data which is not
in the common section has scope SS_UNIVERSAL. Note scope
of common symbols was handled earlier! */
- if (bfd_is_und_section (sym->section))
+ if (bfd_is_com_section (sym->section))
+ ;
+ else if (bfd_is_und_section (sym->section))
info->symbol_scope = SS_UNSAT;
- else if (sym->flags & (BSF_EXPORT | BSF_WEAK)
- && ! bfd_is_com_section (sym->section))
+ else if (sym->flags & (BSF_EXPORT | BSF_WEAK))
info->symbol_scope = SS_UNIVERSAL;
/* Anything else which is not in the common section has scope
SS_LOCAL. */
- else if (! bfd_is_com_section (sym->section))
+ else
info->symbol_scope = SS_LOCAL;
/* Now set the symbol_info field. It has no real meaning
@@ -4138,12 +4152,49 @@ som_bfd_derive_misc_symbol_info (abfd, sym, info)
/* Set the symbol's value. */
info->symbol_value = sym->value + sym->section->vma;
- /* The secondary_def field is for weak symbols. */
+ /* The secondary_def field is for "weak" symbols. */
if (sym->flags & BSF_WEAK)
info->secondary_def = TRUE;
else
info->secondary_def = FALSE;
+ /* The is_comdat, is_common and dup_common fields provide various
+ flavors of common.
+
+ For data symbols, setting IS_COMMON provides Fortran style common
+ (duplicate definitions and overlapped initialization). Setting both
+ IS_COMMON and DUP_COMMON provides Cobol style common (duplicate
+ definitions as long as they are all the same length). In a shared
+ link data symbols retain their IS_COMMON and DUP_COMMON flags.
+ An IS_COMDAT data symbol is similar to a IS_COMMON | DUP_COMMON
+ symbol except in that it loses its IS_COMDAT flag in a shared link.
+
+ For code symbols, IS_COMDAT and DUP_COMMON have effect. Universal
+ DUP_COMMON code symbols are not exported from shared libraries.
+ IS_COMDAT symbols are exported but they lose their IS_COMDAT flag.
+
+ We take a simplified approach to setting the is_comdat, is_common
+ and dup_common flags in symbols based on the flag settings of their
+ subspace. This avoids having to add directives like `.comdat' but
+ the linker behavior is probably undefined if there is more than one
+ universal symbol (comdat key sysmbol) in a subspace.
+
+ The behavior of these flags is not well documentmented, so there
+ may be bugs and some surprising interactions with other flags. */
+ if (som_section_data (sym->section)
+ && som_section_data (sym->section)->subspace_dict
+ && info->symbol_scope == SS_UNIVERSAL
+ && (info->symbol_type == ST_ENTRY
+ || info->symbol_type == ST_CODE
+ || info->symbol_type == ST_DATA))
+ {
+ info->is_comdat
+ = som_section_data (sym->section)->subspace_dict->is_comdat;
+ info->is_common
+ = som_section_data (sym->section)->subspace_dict->is_common;
+ info->dup_common
+ = som_section_data (sym->section)->subspace_dict->dup_common;
+ }
}
/* Build and write, in one big chunk, the entire symbol table for
@@ -4189,6 +4240,9 @@ som_build_and_write_symbol_table (abfd)
som_symtab[i].xleast = 3;
som_symtab[i].symbol_value = info.symbol_value | info.priv_level;
som_symtab[i].secondary_def = info.secondary_def;
+ som_symtab[i].is_comdat = info.is_comdat;
+ som_symtab[i].is_common = info.is_common;
+ som_symtab[i].dup_common = info.dup_common;
}
/* Everything is ready, seek to the right location and
@@ -4298,7 +4352,7 @@ bfd_section_from_som_symbol (abfd, symbol)
&& symbol->symbol_type != ST_SEC_PROG
&& symbol->symbol_type != ST_MILLICODE))
{
- unsigned int index = symbol->symbol_info;
+ int index = symbol->symbol_info;
for (section = abfd->sections; section != NULL; section = section->next)
if (section->target_index == index && som_is_subspace (section))
return section;
@@ -5212,12 +5266,13 @@ bfd_som_set_section_attributes (section, defined, private, sort_key, spnum)
bfd_boolean
bfd_som_set_subsection_attributes (section, container, access,
- sort_key, quadrant)
+ sort_key, quadrant, comdat,
+ common, dup_common)
asection *section;
asection *container;
int access;
unsigned int sort_key;
- int quadrant;
+ int quadrant, comdat, common, dup_common;
{
/* Allocate memory to hold the magic information. */
if (som_section_data (section)->copy_data == NULL)
@@ -5233,6 +5288,9 @@ bfd_som_set_subsection_attributes (section, container, access,
som_section_data (section)->copy_data->access_control_bits = access;
som_section_data (section)->copy_data->quadrant = quadrant;
som_section_data (section)->copy_data->container = container;
+ som_section_data (section)->copy_data->is_comdat = comdat;
+ som_section_data (section)->copy_data->is_common = common;
+ som_section_data (section)->copy_data->dup_common = dup_common;
return TRUE;
}
@@ -5358,7 +5416,7 @@ static bfd_boolean
som_set_section_contents (abfd, section, location, offset, count)
bfd *abfd;
sec_ptr section;
- PTR location;
+ const PTR location;
file_ptr offset;
bfd_size_type count;
{
@@ -5385,7 +5443,7 @@ som_set_section_contents (abfd, section, location, offset, count)
if (bfd_seek (abfd, offset, SEEK_SET) != 0)
return FALSE;
- if (bfd_bwrite ((PTR) location, count, abfd) != count)
+ if (bfd_bwrite (location, count, abfd) != count)
return FALSE;
return TRUE;
}
@@ -6036,7 +6094,7 @@ som_bfd_ar_write_symbol_stuff (abfd, nsyms, string_size, lst, elength)
curr_lst_sym->initially_frozen = 0;
curr_lst_sym->memory_resident = 0;
curr_lst_sym->is_common = bfd_is_com_section (sym->symbol.section);
- curr_lst_sym->dup_common = 0;
+ curr_lst_sym->dup_common = info.dup_common;
curr_lst_sym->xleast = 3;
curr_lst_sym->arg_reloc = info.arg_reloc;
curr_lst_sym->name.n_strx = p - strings + 4;
@@ -6352,6 +6410,7 @@ som_bfd_link_split_section (abfd, sec)
#define som_bfd_gc_sections bfd_generic_gc_sections
#define som_bfd_merge_sections bfd_generic_merge_sections
+#define som_bfd_is_group_section bfd_generic_is_group_section
#define som_bfd_discard_group bfd_generic_discard_group
const bfd_target som_vec = {
@@ -6362,7 +6421,7 @@ const bfd_target som_vec = {
(HAS_RELOC | EXEC_P | /* object flags */
HAS_LINENO | HAS_DEBUG |
HAS_SYMS | HAS_LOCALS | WP_TEXT | D_PAGED | DYNAMIC),
- (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS
+ (SEC_CODE | SEC_DATA | SEC_ROM | SEC_HAS_CONTENTS | SEC_LINK_ONCE
| SEC_ALLOC | SEC_LOAD | SEC_RELOC), /* section flags */
/* leading_symbol_char: is the first char of a user symbol
diff --git a/bfd/som.h b/bfd/som.h
index 537ddaa..3954855 100644
--- a/bfd/som.h
+++ b/bfd/som.h
@@ -27,7 +27,7 @@
#include "libhppa.h"
-/* Enable PA2.0 if available */
+/* We want reloc.h to provide PA 2.0 defines. */
#define PA_2_0
#include <a.out.h>
@@ -143,6 +143,35 @@ struct som_data_struct
struct somdata a;
};
+struct som_subspace_dictionary_record
+ {
+ int space_index;
+ unsigned int access_control_bits : 7;
+ unsigned int memory_resident : 1;
+ unsigned int dup_common : 1;
+ unsigned int is_common : 1;
+ unsigned int is_loadable : 1;
+ unsigned int quadrant : 2;
+ unsigned int initially_frozen : 1;
+ unsigned int is_first : 1;
+ unsigned int code_only : 1;
+ unsigned int sort_key : 8;
+ unsigned int replicate_init : 1;
+ unsigned int continuation : 1;
+ unsigned int is_tspecific : 1;
+ unsigned int is_comdat : 1;
+ unsigned int reserved : 4;
+ int file_loc_init_value;
+ unsigned int initialization_length;
+ unsigned int subspace_start;
+ unsigned int subspace_length;
+ unsigned int reserved2 : 5;
+ unsigned int alignment :27;
+ union name_pt name;
+ int fixup_request_index;
+ unsigned int fixup_request_quantity;
+ };
+
/* Substructure of som_section_data_struct used to hold information
which can't be represented by the generic BFD section structure,
but which must be copied during objcopy or strip. */
@@ -155,6 +184,9 @@ struct som_copyable_section_data_struct
unsigned int is_defined : 1;
unsigned int is_private : 1;
unsigned int quadrant : 2;
+ unsigned int is_comdat : 1;
+ unsigned int is_common : 1;
+ unsigned int dup_common : 1;
/* For subspaces, this points to the section which represents the
space in which the subspace is contained. For spaces it points
@@ -184,7 +216,7 @@ struct som_section_data_struct
unsigned int reloc_size;
char *reloc_stream;
struct space_dictionary_record *space_dict;
- struct subspace_dictionary_record *subspace_dict;
+ struct som_subspace_dictionary_record *subspace_dict;
};
#define somdata(bfd) ((bfd)->tdata.som_data->a)
@@ -231,7 +263,7 @@ struct som_section_data_struct
bfd_boolean bfd_som_set_section_attributes
PARAMS ((asection *, int, int, unsigned int, int));
bfd_boolean bfd_som_set_subsection_attributes
- PARAMS ((asection *, asection *, int, unsigned int, int));
+ PARAMS ((asection *, asection *, int, unsigned int, int, int, int, int));
void bfd_som_set_symbol_type PARAMS ((asymbol *, unsigned int));
bfd_boolean bfd_som_attach_aux_hdr PARAMS ((bfd *, int, char *));
int ** hppa_som_gen_reloc_type
diff --git a/bfd/srec.c b/bfd/srec.c
index c0a3d58..2eba70d 100644
--- a/bfd/srec.c
+++ b/bfd/srec.c
@@ -1,6 +1,6 @@
/* BFD back-end for s-record objects.
Copyright 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
- 2000, 2001, 2002, 2003
+ 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>.
@@ -1284,6 +1284,7 @@ srec_print_symbol (abfd, afile, symbol, how)
#define srec_bfd_relax_section bfd_generic_relax_section
#define srec_bfd_gc_sections bfd_generic_gc_sections
#define srec_bfd_merge_sections bfd_generic_merge_sections
+#define srec_bfd_is_group_section bfd_generic_is_group_section
#define srec_bfd_discard_group bfd_generic_discard_group
#define srec_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
#define srec_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
diff --git a/bfd/stabs.c b/bfd/stabs.c
index 42944a4..04b91f6 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/sunos.c b/bfd/sunos.c
index 5b1b18b..4d5099a 100644
--- a/bfd/sunos.c
+++ b/bfd/sunos.c
@@ -73,6 +73,7 @@ static bfd_boolean sunos_finish_dynamic_link
#define MY_get_dynamic_symtab_upper_bound sunos_get_dynamic_symtab_upper_bound
#define MY_canonicalize_dynamic_symtab sunos_canonicalize_dynamic_symtab
+#define MY_get_synthetic_symtab _bfd_nodynamic_get_synthetic_symtab
#define MY_get_dynamic_reloc_upper_bound sunos_get_dynamic_reloc_upper_bound
#define MY_canonicalize_dynamic_reloc sunos_canonicalize_dynamic_reloc
#define MY_bfd_link_hash_table_create sunos_link_hash_table_create
diff --git a/bfd/targets.c b/bfd/targets.c
index 9d81c56..29e3f62 100644
--- a/bfd/targets.c
+++ b/bfd/targets.c
@@ -406,6 +406,7 @@ BFD_JUMP_TABLE macros.
. NAME##_bfd_link_split_section, \
. NAME##_bfd_gc_sections, \
. NAME##_bfd_merge_sections, \
+. NAME##_bfd_is_group_section, \
. NAME##_bfd_discard_group
.
. int (*_bfd_sizeof_headers) (bfd *, bfd_boolean);
@@ -443,6 +444,9 @@ BFD_JUMP_TABLE macros.
. {* Attempt to merge SEC_MERGE sections. *}
. bfd_boolean (*_bfd_merge_sections) (bfd *, struct bfd_link_info *);
.
+. {* Is this section a member of a group? *}
+. bfd_boolean (*_bfd_is_group_section) (bfd *, const struct bfd_section *);
+.
. {* Discard members of a group. *}
. bfd_boolean (*_bfd_discard_group) (bfd *, struct bfd_section *);
.
@@ -450,6 +454,7 @@ BFD_JUMP_TABLE macros.
.#define BFD_JUMP_TABLE_DYNAMIC(NAME) \
. NAME##_get_dynamic_symtab_upper_bound, \
. NAME##_canonicalize_dynamic_symtab, \
+. NAME##_get_synthetic_symtab, \
. NAME##_get_dynamic_reloc_upper_bound, \
. NAME##_canonicalize_dynamic_reloc
.
@@ -458,6 +463,9 @@ BFD_JUMP_TABLE macros.
. {* Read in the dynamic symbols. *}
. long (*_bfd_canonicalize_dynamic_symtab)
. (bfd *, struct bfd_symbol **);
+. {* Create synthetized symbols. *}
+. long (*_bfd_get_synthetic_symtab)
+. (bfd *, struct bfd_symbol **, struct bfd_symbol **);
. {* Get the amount of memory required to hold the dynamic relocs. *}
. long (*_bfd_get_dynamic_reloc_upper_bound) (bfd *);
. {* Read in the dynamic relocs. *}
@@ -517,6 +525,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 +816,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/tekhex.c b/bfd/tekhex.c
index f828fe7..278e303 100644
--- a/bfd/tekhex.c
+++ b/bfd/tekhex.c
@@ -1,6 +1,6 @@
/* BFD backend for Extended Tektronix Hex Format objects.
- Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003
- Free Software Foundation, Inc.
+ Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002,
+ 2003, 2004 Free Software Foundation, Inc.
Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>.
This file is part of BFD, the Binary File Descriptor library.
@@ -1001,6 +1001,7 @@ tekhex_print_symbol (abfd, filep, symbol, how)
#define tekhex_bfd_relax_section bfd_generic_relax_section
#define tekhex_bfd_gc_sections bfd_generic_gc_sections
#define tekhex_bfd_merge_sections bfd_generic_merge_sections
+#define tekhex_bfd_is_group_section bfd_generic_is_group_section
#define tekhex_bfd_discard_group bfd_generic_discard_group
#define tekhex_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
#define tekhex_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
diff --git a/bfd/versados.c b/bfd/versados.c
index 19df300..cd5926e 100644
--- a/bfd/versados.c
+++ b/bfd/versados.c
@@ -1,5 +1,5 @@
/* BFD back-end for VERSAdos-E objects.
- Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003
+ Copyright 1995, 1996, 1998, 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
Written by Steve Chamberlain of Cygnus Support <sac@cygnus.com>.
@@ -872,6 +872,7 @@ versados_canonicalize_reloc (abfd, section, relptr, symbols)
#define versados_bfd_relax_section bfd_generic_relax_section
#define versados_bfd_gc_sections bfd_generic_gc_sections
#define versados_bfd_merge_sections bfd_generic_merge_sections
+#define versados_bfd_is_group_section bfd_generic_is_group_section
#define versados_bfd_discard_group bfd_generic_discard_group
#define versados_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
#define versados_bfd_link_hash_table_free _bfd_generic_link_hash_table_free
diff --git a/bfd/version.h b/bfd/version.h
index 483bae0..b9237fa 100644
--- a/bfd/version.h
+++ b/bfd/version.h
@@ -1,3 +1,3 @@
-#define BFD_VERSION_DATE 20040322
+#define BFD_VERSION_DATE 20040504
#define BFD_VERSION @bfd_version@
#define BFD_VERSION_STRING @bfd_version_string@
diff --git a/bfd/vms.c b/bfd/vms.c
index a55b94b..329b056 100644
--- a/bfd/vms.c
+++ b/bfd/vms.c
@@ -1,6 +1,6 @@
/* vms.c -- BFD back-end for VAX (openVMS/VAX) and
EVAX (openVMS/Alpha) files.
- 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 Klaus K"ampf (kkaempf@rmi.de)
@@ -154,6 +154,7 @@ static long vms_get_dynamic_symtab_upper_bound
PARAMS ((bfd *abfd));
static long vms_canonicalize_dynamic_symtab
PARAMS ((bfd *abfd, asymbol **symbols));
+#define vms_get_synthetic_symtab _bfd_nodynamic_get_synthetic_symtab
static long vms_get_dynamic_reloc_upper_bound
PARAMS ((bfd *abfd));
static long vms_canonicalize_dynamic_reloc
@@ -165,6 +166,7 @@ static bfd_boolean vms_bfd_set_private_flags
#define vms_make_empty_symbol _bfd_generic_make_empty_symbol
#define vms_bfd_link_just_syms _bfd_generic_link_just_syms
+#define vms_bfd_is_group_section bfd_generic_is_group_section
#define vms_bfd_discard_group bfd_generic_discard_group
/*===========================================================================*/
diff --git a/bfd/xsym.c b/bfd/xsym.c
index a4058dd..e5889d4 100644
--- a/bfd/xsym.c
+++ b/bfd/xsym.c
@@ -1,5 +1,5 @@
/* xSYM symbol-file support for BFD.
- Copyright 1999, 2000, 2001, 2002, 2003
+ Copyright 1999, 2000, 2001, 2002, 2003, 2004
Free Software Foundation, Inc.
This file is part of BFD, the Binary File Descriptor library.
@@ -42,6 +42,7 @@
#define bfd_sym_bfd_relax_section bfd_generic_relax_section
#define bfd_sym_bfd_gc_sections bfd_generic_gc_sections
#define bfd_sym_bfd_merge_sections bfd_generic_merge_sections
+#define bfd_sym_bfd_is_group_section bfd_generic_is_group_section
#define bfd_sym_bfd_discard_group bfd_generic_discard_group
#define bfd_sym_bfd_link_hash_table_create _bfd_generic_link_hash_table_create
#define bfd_sym_bfd_link_hash_table_free _bfd_generic_link_hash_table_free