diff options
author | Alan Modra <amodra@gmail.com> | 2002-07-01 08:06:47 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2002-07-01 08:06:47 +0000 |
commit | 1e2f5b6e6b11ff65094876b8a8066a59a880a56d (patch) | |
tree | a6237f9481cee6183b3b8b76314528f736550d28 /bfd | |
parent | 7815cf4fc37ab0dc2602572ba2731545b20e7288 (diff) | |
download | fsf-binutils-gdb-1e2f5b6e6b11ff65094876b8a8066a59a880a56d.zip fsf-binutils-gdb-1e2f5b6e6b11ff65094876b8a8066a59a880a56d.tar.gz fsf-binutils-gdb-1e2f5b6e6b11ff65094876b8a8066a59a880a56d.tar.bz2 |
* elflink.h (elf_gc_mark): Pass in the section whose relocs we are
examining to gc_mark_hook, rather than the bfd.
(elf_gc_sections): Adjust.
* elf-bfd.h (struct elf_backend_data <gc_mark_hook>): Likewise.
* elf-m10300.c (mn10300_elf_gc_mark_hook): Likewise.
* elf32-arm.h (elf32_arm_gc_mark_hook): Likewise.
* elf32-avr.c (elf32_avr_gc_mark_hook): Likewise.
* elf32-cris.c (cris_elf_gc_mark_hook): Likewise.
* elf32-d10v.c (elf32_d10v_gc_mark_hook): Likewise.
* elf32-fr30.c (fr30_elf_gc_mark_hook): Likewise.
* elf32-hppa.c (elf32_hppa_gc_mark_hook): Likewise.
* elf32-i386.c (elf_i386_gc_mark_hook): Likewise.
* elf32-m32r.c (m32r_elf_gc_mark_hook): Likewise.
* elf32-m68k.c (elf_m68k_gc_mark_hook): Likewise.
* elf32-mcore.c (mcore_elf_gc_mark_hook): Likewise.
* elf32-openrisc.c (openrisc_elf_gc_mark_hook): Likewise.
* elf32-ppc.c (ppc_elf_gc_mark_hook): Likewise.
* elf32-s390.c (elf_s390_gc_mark_hook): Likewise.
* elf32-sh.c (sh_elf_gc_mark_hook): Likewise.
* elf32-sparc.c (elf32_sparc_gc_mark_hook): Likewise.
* elf32-v850.c (v850_elf_gc_mark_hook): Likewise.
* elf32-vax.c (elf_vax_gc_mark_hook): Likewise.
* elf32-xstormy16.c (xstormy16_elf_gc_mark_hook): Likewise.
* elf64-mmix.c (mmix_elf_gc_mark_hook): Likewise.
* elf64-ppc.c (ppc64_elf_gc_mark_hook): Likewise.
* elf64-s390.c (elf_s390_gc_mark_hook): Likewise.
* elf64-sh64.c (sh_elf64_gc_mark_hook): Likewise.
* elfxx-mips.c (_bfd_mips_elf_gc_mark_hook): Likewise.
* elfxx-mips.h (_bfd_mips_elf_gc_mark_hook): Likewise.
* elf64-x86-64.c (elf64_x86_64_gc_mark_hook): Likewise.
* elf32-frv.c (elf32_frv_gc_mark_hook): Likewise. Also remove
redundant local sym tests.
* elf64-ppc.c (struct ppc_link_hash_entry): Add is_entry.
(link_hash_newfunc): Init is_entry.
(ppc64_elf_copy_indirect_symbol): Copy is_entry.
(ppc64_elf_link_hash_table_create): Init all_local_syms.
(create_linkage_sections): Use bfd_make_section_anyway rather than
bfd_make_section.
(ppc64_elf_mark_entry_syms): New function.
(ppc64_elf_check_relocs): Don't bother testing elf_bad_symtab. Set
up opd entry to function section map.
(ppc64_elf_gc_mark_hook): Special case opd section relocs, and
relocs that reference the opd section.
(edit_opd): New function.
(ppc64_elf_size_dynamic_sections): Call get_local_syms and edit_opd.
(ppc64_elf_setup_section_lists): Don't calculate htab->bfd_count here.
(get_local_syms): Do so here. Exit if we already have local syms.
Remove bogus comment imported from elf32-hppa.c. Don't attempt to
read local syms on non-ELF input.
(ppc64_elf_size_stubs): Call _bfd_elf64_link_read_relocs rather
than duplicating it's function here. Adjust free of internal
relocs to suit.
(ppc64_elf_relocate_section): Adjust local syms in opd section.
* elf64-ppc.h (ppc64_elf_mark_entry_syms): Declare.
* elf32-hppa.c (elf32_hppa_size_stubs): Call
_bfd_elf32_link_read_relocs rather than duplicating it's function
here. Adjust free of internal relocs to suit.
Diffstat (limited to 'bfd')
-rw-r--r-- | bfd/ChangeLog | 60 | ||||
-rw-r--r-- | bfd/elf-bfd.h | 5 | ||||
-rw-r--r-- | bfd/elf-m10300.c | 10 | ||||
-rw-r--r-- | bfd/elf32-arm.h | 10 | ||||
-rw-r--r-- | bfd/elf32-avr.c | 12 | ||||
-rw-r--r-- | bfd/elf32-cris.c | 10 | ||||
-rw-r--r-- | bfd/elf32-d10v.c | 19 | ||||
-rw-r--r-- | bfd/elf32-fr30.c | 10 | ||||
-rw-r--r-- | bfd/elf32-frv.c | 14 | ||||
-rw-r--r-- | bfd/elf32-hppa.c | 69 | ||||
-rw-r--r-- | bfd/elf32-i386.c | 10 | ||||
-rw-r--r-- | bfd/elf32-m32r.c | 21 | ||||
-rw-r--r-- | bfd/elf32-m68k.c | 10 | ||||
-rw-r--r-- | bfd/elf32-mcore.c | 10 | ||||
-rw-r--r-- | bfd/elf32-openrisc.c | 10 | ||||
-rw-r--r-- | bfd/elf32-ppc.c | 10 | ||||
-rw-r--r-- | bfd/elf32-s390.c | 10 | ||||
-rw-r--r-- | bfd/elf32-sh.c | 10 | ||||
-rw-r--r-- | bfd/elf32-sparc.c | 13 | ||||
-rw-r--r-- | bfd/elf32-v850.c | 10 | ||||
-rw-r--r-- | bfd/elf32-vax.c | 10 | ||||
-rw-r--r-- | bfd/elf32-xstormy16.c | 10 | ||||
-rw-r--r-- | bfd/elf64-mmix.c | 10 | ||||
-rw-r--r-- | bfd/elf64-ppc.c | 495 | ||||
-rw-r--r-- | bfd/elf64-ppc.h | 2 | ||||
-rw-r--r-- | bfd/elf64-s390.c | 10 | ||||
-rw-r--r-- | bfd/elf64-sh64.c | 18 | ||||
-rw-r--r-- | bfd/elf64-x86-64.c | 10 | ||||
-rw-r--r-- | bfd/elflink.h | 14 | ||||
-rw-r--r-- | bfd/elfxx-mips.c | 10 | ||||
-rw-r--r-- | bfd/elfxx-mips.h | 2 |
31 files changed, 619 insertions, 305 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 5e45aa5..834d2a7 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,63 @@ +2002-07-01 Alan Modra <amodra@bigpond.net.au> + + * elflink.h (elf_gc_mark): Pass in the section whose relocs we are + examining to gc_mark_hook, rather than the bfd. + (elf_gc_sections): Adjust. + * elf-bfd.h (struct elf_backend_data <gc_mark_hook>): Likewise. + * elf-m10300.c (mn10300_elf_gc_mark_hook): Likewise. + * elf32-arm.h (elf32_arm_gc_mark_hook): Likewise. + * elf32-avr.c (elf32_avr_gc_mark_hook): Likewise. + * elf32-cris.c (cris_elf_gc_mark_hook): Likewise. + * elf32-d10v.c (elf32_d10v_gc_mark_hook): Likewise. + * elf32-fr30.c (fr30_elf_gc_mark_hook): Likewise. + * elf32-hppa.c (elf32_hppa_gc_mark_hook): Likewise. + * elf32-i386.c (elf_i386_gc_mark_hook): Likewise. + * elf32-m32r.c (m32r_elf_gc_mark_hook): Likewise. + * elf32-m68k.c (elf_m68k_gc_mark_hook): Likewise. + * elf32-mcore.c (mcore_elf_gc_mark_hook): Likewise. + * elf32-openrisc.c (openrisc_elf_gc_mark_hook): Likewise. + * elf32-ppc.c (ppc_elf_gc_mark_hook): Likewise. + * elf32-s390.c (elf_s390_gc_mark_hook): Likewise. + * elf32-sh.c (sh_elf_gc_mark_hook): Likewise. + * elf32-sparc.c (elf32_sparc_gc_mark_hook): Likewise. + * elf32-v850.c (v850_elf_gc_mark_hook): Likewise. + * elf32-vax.c (elf_vax_gc_mark_hook): Likewise. + * elf32-xstormy16.c (xstormy16_elf_gc_mark_hook): Likewise. + * elf64-mmix.c (mmix_elf_gc_mark_hook): Likewise. + * elf64-ppc.c (ppc64_elf_gc_mark_hook): Likewise. + * elf64-s390.c (elf_s390_gc_mark_hook): Likewise. + * elf64-sh64.c (sh_elf64_gc_mark_hook): Likewise. + * elfxx-mips.c (_bfd_mips_elf_gc_mark_hook): Likewise. + * elfxx-mips.h (_bfd_mips_elf_gc_mark_hook): Likewise. + * elf64-x86-64.c (elf64_x86_64_gc_mark_hook): Likewise. + * elf32-frv.c (elf32_frv_gc_mark_hook): Likewise. Also remove + redundant local sym tests. + * elf64-ppc.c (struct ppc_link_hash_entry): Add is_entry. + (link_hash_newfunc): Init is_entry. + (ppc64_elf_copy_indirect_symbol): Copy is_entry. + (ppc64_elf_link_hash_table_create): Init all_local_syms. + (create_linkage_sections): Use bfd_make_section_anyway rather than + bfd_make_section. + (ppc64_elf_mark_entry_syms): New function. + (ppc64_elf_check_relocs): Don't bother testing elf_bad_symtab. Set + up opd entry to function section map. + (ppc64_elf_gc_mark_hook): Special case opd section relocs, and + relocs that reference the opd section. + (edit_opd): New function. + (ppc64_elf_size_dynamic_sections): Call get_local_syms and edit_opd. + (ppc64_elf_setup_section_lists): Don't calculate htab->bfd_count here. + (get_local_syms): Do so here. Exit if we already have local syms. + Remove bogus comment imported from elf32-hppa.c. Don't attempt to + read local syms on non-ELF input. + (ppc64_elf_size_stubs): Call _bfd_elf64_link_read_relocs rather + than duplicating it's function here. Adjust free of internal + relocs to suit. + (ppc64_elf_relocate_section): Adjust local syms in opd section. + * elf64-ppc.h (ppc64_elf_mark_entry_syms): Declare. + * elf32-hppa.c (elf32_hppa_size_stubs): Call + _bfd_elf32_link_read_relocs rather than duplicating it's function + here. Adjust free of internal relocs to suit. + 2002-07-01 Andreas Jaeger <aj@suse.de> * elf64-x86-64.c (elf64_x86_64_check_relocs): Certain relocations diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 2bfde1c..b264d56 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -680,10 +680,9 @@ struct elf_backend_data PARAMS ((bfd *)); /* This function is called during section gc to discover the section a - particular relocation refers to. It need not be defined for hosts - that have no queer relocation types. */ + particular relocation refers to. */ asection * (*gc_mark_hook) - PARAMS ((bfd *abfd, struct bfd_link_info *, Elf_Internal_Rela *, + PARAMS ((asection *sec, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *h, Elf_Internal_Sym *)); /* This function, if defined, is called during the sweep phase of gc diff --git a/bfd/elf-m10300.c b/bfd/elf-m10300.c index 56350e5..501c3dd 100644 --- a/bfd/elf-m10300.c +++ b/bfd/elf-m10300.c @@ -122,7 +122,7 @@ static boolean mn10300_elf_check_relocs PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *)); static asection *mn10300_elf_gc_mark_hook - PARAMS ((bfd *, struct bfd_link_info *info, Elf_Internal_Rela *, + PARAMS ((asection *, struct bfd_link_info *info, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *)); static boolean mn10300_elf_relax_delete_bytes PARAMS ((bfd *, asection *, bfd_vma, int)); @@ -397,8 +397,8 @@ mn10300_elf_check_relocs (abfd, info, sec, relocs) relocation. */ static asection * -mn10300_elf_gc_mark_hook (abfd, info, rel, h, sym) - bfd *abfd; +mn10300_elf_gc_mark_hook (sec, info, rel, h, sym) + asection *sec; struct bfd_link_info *info ATTRIBUTE_UNUSED; Elf_Internal_Rela *rel; struct elf_link_hash_entry *h; @@ -428,9 +428,7 @@ mn10300_elf_gc_mark_hook (abfd, info, rel, h, sym) } } else - { - return bfd_section_from_elf_index (abfd, sym->st_shndx); - } + return bfd_section_from_elf_index (sec->owner, sym->st_shndx); return NULL; } diff --git a/bfd/elf32-arm.h b/bfd/elf32-arm.h index c97e13d..d1b8fa7 100644 --- a/bfd/elf32-arm.h +++ b/bfd/elf32-arm.h @@ -58,7 +58,7 @@ static boolean elf32_arm_relocate_section PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); static asection * elf32_arm_gc_mark_hook - PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *, + PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *)); static boolean elf32_arm_gc_sweep_hook PARAMS ((bfd *, struct bfd_link_info *, asection *, @@ -2529,8 +2529,8 @@ elf32_arm_get_symbol_type (elf_sym, type) } static asection * -elf32_arm_gc_mark_hook (abfd, info, rel, h, sym) - bfd *abfd; +elf32_arm_gc_mark_hook (sec, info, rel, h, sym) + asection *sec; struct bfd_link_info *info ATTRIBUTE_UNUSED; Elf_Internal_Rela *rel; struct elf_link_hash_entry *h; @@ -2560,9 +2560,7 @@ elf32_arm_gc_mark_hook (abfd, info, rel, h, sym) } } else - { - return bfd_section_from_elf_index (abfd, sym->st_shndx); - } + return bfd_section_from_elf_index (sec->owner, sym->st_shndx); return NULL; } diff --git a/bfd/elf32-avr.c b/bfd/elf32-avr.c index 61f28e6..bef8c7f 100644 --- a/bfd/elf32-avr.c +++ b/bfd/elf32-avr.c @@ -1,5 +1,5 @@ /* AVR-specific support for 32-bit ELF - Copyright 1999, 2000, 2001 Free Software Foundation, Inc. + Copyright 1999, 2000, 2001, 2002 Free Software Foundation, Inc. Contributed by Denis Chertykov <denisc@overta.ru> This file is part of BFD, the Binary File Descriptor library. @@ -29,7 +29,7 @@ static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup static void avr_info_to_howto_rela PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *)); static asection *elf32_avr_gc_mark_hook - PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *, + PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *)); static boolean elf32_avr_gc_sweep_hook PARAMS ((bfd *, struct bfd_link_info *, asection *, @@ -399,8 +399,8 @@ avr_info_to_howto_rela (abfd, cache_ptr, dst) } static asection * -elf32_avr_gc_mark_hook (abfd, info, rel, h, sym) - bfd *abfd; +elf32_avr_gc_mark_hook (sec, info, rel, h, sym) + asection *sec; struct bfd_link_info *info ATTRIBUTE_UNUSED; Elf_Internal_Rela *rel; struct elf_link_hash_entry *h; @@ -426,9 +426,7 @@ elf32_avr_gc_mark_hook (abfd, info, rel, h, sym) } } else - { - return bfd_section_from_elf_index (abfd, sym->st_shndx); - } + return bfd_section_from_elf_index (sec->owner, sym->st_shndx); return NULL; } diff --git a/bfd/elf32-cris.c b/bfd/elf32-cris.c index 1692cda..38d94f0 100644 --- a/bfd/elf32-cris.c +++ b/bfd/elf32-cris.c @@ -52,7 +52,7 @@ static boolean cris_elf_gc_sweep_hook const Elf_Internal_Rela *)); static asection * cris_elf_gc_mark_hook - PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *, + PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *)); static boolean cris_elf_object_p PARAMS ((bfd *)); @@ -1770,8 +1770,8 @@ elf_cris_finish_dynamic_sections (output_bfd, info) relocation. */ static asection * -cris_elf_gc_mark_hook (abfd, info, rel, h, sym) - bfd * abfd; +cris_elf_gc_mark_hook (sec, info, rel, h, sym) + asection * sec; struct bfd_link_info * info ATTRIBUTE_UNUSED; Elf_Internal_Rela * rel; struct elf_link_hash_entry * h; @@ -1801,9 +1801,7 @@ cris_elf_gc_mark_hook (abfd, info, rel, h, sym) } } else - { - return bfd_section_from_elf_index (abfd, sym->st_shndx); - } + return bfd_section_from_elf_index (sec->owner, sym->st_shndx); return NULL; } diff --git a/bfd/elf32-d10v.c b/bfd/elf32-d10v.c index 6ac5e2d..1dec0b0 100644 --- a/bfd/elf32-d10v.c +++ b/bfd/elf32-d10v.c @@ -29,7 +29,7 @@ static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup static void d10v_info_to_howto_rel PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *)); static asection * elf32_d10v_gc_mark_hook - PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *, + PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *)); static boolean elf32_d10v_gc_sweep_hook PARAMS ((bfd *, struct bfd_link_info *, asection *, @@ -240,12 +240,12 @@ d10v_info_to_howto_rel (abfd, cache_ptr, dst) } static asection * -elf32_d10v_gc_mark_hook (abfd, info, rel, h, sym) - bfd *abfd; - struct bfd_link_info *info ATTRIBUTE_UNUSED; - Elf_Internal_Rela *rel; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; +elf32_d10v_gc_mark_hook (sec, info, rel, h, sym) + 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) { @@ -271,9 +271,8 @@ elf32_d10v_gc_mark_hook (abfd, info, rel, h, sym) } } else - { - return bfd_section_from_elf_index (abfd, sym->st_shndx); - } + return bfd_section_from_elf_index (sec->owner, sym->st_shndx); + return NULL; } diff --git a/bfd/elf32-fr30.c b/bfd/elf32-fr30.c index e1bc741..5f033ef 100644 --- a/bfd/elf32-fr30.c +++ b/bfd/elf32-fr30.c @@ -42,7 +42,7 @@ static boolean fr30_elf_gc_sweep_hook PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *)); static asection * fr30_elf_gc_mark_hook - PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *, + PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *)); static boolean fr30_elf_check_relocs PARAMS ((bfd *, struct bfd_link_info *, asection *, @@ -664,8 +664,8 @@ fr30_elf_relocate_section (output_bfd, info, input_bfd, input_section, relocation. */ static asection * -fr30_elf_gc_mark_hook (abfd, info, rel, h, sym) - bfd * abfd; +fr30_elf_gc_mark_hook (sec, info, rel, h, sym) + asection * sec; struct bfd_link_info * info ATTRIBUTE_UNUSED; Elf_Internal_Rela * rel; struct elf_link_hash_entry * h; @@ -695,9 +695,7 @@ fr30_elf_gc_mark_hook (abfd, info, rel, h, sym) } } else - { - return bfd_section_from_elf_index (abfd, sym->st_shndx); - } + return bfd_section_from_elf_index (sec->owner, sym->st_shndx); return NULL; } diff --git a/bfd/elf32-frv.c b/bfd/elf32-frv.c index cc26b96..8cab505 100644 --- a/bfd/elf32-frv.c +++ b/bfd/elf32-frv.c @@ -51,7 +51,7 @@ static bfd_reloc_status_type frv_final_link_relocate static boolean elf32_frv_gc_sweep_hook PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *)); static asection * elf32_frv_gc_mark_hook - PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *)); + PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *)); static boolean elf32_frv_check_relocs PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *)); static int elf32_frv_machine PARAMS ((bfd *)); @@ -838,8 +838,8 @@ elf32_frv_relocate_section (output_bfd, info, input_bfd, input_section, relocation. */ static asection * -elf32_frv_gc_mark_hook (abfd, info, rel, h, sym) - bfd * abfd; +elf32_frv_gc_mark_hook (sec, info, rel, h, sym) + asection * sec; struct bfd_link_info * info ATTRIBUTE_UNUSED; Elf_Internal_Rela * rel; struct elf_link_hash_entry * h; @@ -869,13 +869,7 @@ elf32_frv_gc_mark_hook (abfd, info, rel, h, sym) } } else - { - if (!(elf_bad_symtab (abfd) - && ELF_ST_BIND (sym->st_info) != STB_LOCAL) - && ! ((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE) - && sym->st_shndx != SHN_COMMON)) - return bfd_section_from_elf_index (abfd, sym->st_shndx); - } + return bfd_section_from_elf_index (sec->owner, sym->st_shndx); return NULL; } diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c index 432ec1d..8bea3c6 100644 --- a/bfd/elf32-hppa.c +++ b/bfd/elf32-hppa.c @@ -334,7 +334,7 @@ static boolean elf32_hppa_check_relocs asection *, const Elf_Internal_Rela *)); static asection *elf32_hppa_gc_mark_hook - PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *, + PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *)); static boolean elf32_hppa_gc_sweep_hook @@ -1632,8 +1632,8 @@ elf32_hppa_check_relocs (abfd, info, sec, relocs) for a given relocation. */ static asection * -elf32_hppa_gc_mark_hook (abfd, info, rel, h, sym) - bfd *abfd; +elf32_hppa_gc_mark_hook (sec, info, rel, h, sym) + asection *sec; struct bfd_link_info *info ATTRIBUTE_UNUSED; Elf_Internal_Rela *rel; struct elf_link_hash_entry *h; @@ -1663,9 +1663,7 @@ elf32_hppa_gc_mark_hook (abfd, info, rel, h, sym) } } else - { - return bfd_section_from_elf_index (abfd, sym->st_shndx); - } + return bfd_section_from_elf_index (sec->owner, sym->st_shndx); return NULL; } @@ -2996,10 +2994,7 @@ elf32_hppa_size_stubs (output_bfd, stub_bfd, info, multi_subspace, group_size, section != NULL; section = section->next) { - Elf_Internal_Shdr *input_rel_hdr; - Elf32_External_Rela *external_relocs, *erelaend, *erela; Elf_Internal_Rela *internal_relocs, *irelaend, *irela; - bfd_size_type amt; /* If there aren't any relocs, then there's nothing more to do. */ @@ -3013,47 +3008,13 @@ elf32_hppa_size_stubs (output_bfd, stub_bfd, info, multi_subspace, group_size, || section->output_section->owner != output_bfd) continue; - /* Allocate space for the external relocations. */ - amt = section->reloc_count; - amt *= sizeof (Elf32_External_Rela); - external_relocs = (Elf32_External_Rela *) bfd_malloc (amt); - if (external_relocs == NULL) - { - goto error_ret_free_local; - } - - /* Likewise for the internal relocations. */ - amt = section->reloc_count; - amt *= sizeof (Elf_Internal_Rela); - internal_relocs = (Elf_Internal_Rela *) bfd_malloc (amt); + /* Get the relocs. */ + internal_relocs + = _bfd_elf32_link_read_relocs (input_bfd, section, NULL, + (Elf_Internal_Rela *) NULL, + info->keep_memory); if (internal_relocs == NULL) - { - free (external_relocs); - goto error_ret_free_local; - } - - /* Read in the external relocs. */ - input_rel_hdr = &elf_section_data (section)->rel_hdr; - if (bfd_seek (input_bfd, input_rel_hdr->sh_offset, SEEK_SET) != 0 - || bfd_bread ((PTR) external_relocs, - input_rel_hdr->sh_size, - input_bfd) != input_rel_hdr->sh_size) - { - free (external_relocs); - error_ret_free_internal: - free (internal_relocs); - goto error_ret_free_local; - } - - /* Swap in the relocs. */ - erela = external_relocs; - erelaend = erela + section->reloc_count; - irela = internal_relocs; - for (; erela < erelaend; erela++, irela++) - bfd_elf32_swap_reloca_in (input_bfd, erela, irela); - - /* We're done with the external relocs, free them. */ - free (external_relocs); + goto error_ret_free_local; /* Now examine each relocation. */ irela = internal_relocs; @@ -3076,7 +3037,10 @@ elf32_hppa_size_stubs (output_bfd, stub_bfd, info, multi_subspace, group_size, if (r_type >= (unsigned int) R_PARISC_UNIMPLEMENTED) { bfd_set_error (bfd_error_bad_value); - goto error_ret_free_internal; + error_ret_free_internal: + if (elf_section_data (section)->relocs == NULL) + free (internal_relocs); + goto error_ret_free_local; } /* Only look for stubs on call instructions. */ @@ -3179,7 +3143,7 @@ elf32_hppa_size_stubs (output_bfd, stub_bfd, info, multi_subspace, group_size, if (stub_entry == NULL) { free (stub_name); - goto error_ret_free_local; + goto error_ret_free_internal; } stub_entry->target_value = sym_value; @@ -3197,7 +3161,8 @@ elf32_hppa_size_stubs (output_bfd, stub_bfd, info, multi_subspace, group_size, } /* We're done with the internal relocs, free them. */ - free (internal_relocs); + if (elf_section_data (section)->relocs == NULL) + free (internal_relocs); } } diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index e7c6b93..1e886a5 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -57,7 +57,7 @@ static boolean elf_i386_check_relocs PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *)); static asection *elf_i386_gc_mark_hook - PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *, + PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *)); static boolean elf_i386_gc_sweep_hook PARAMS ((bfd *, struct bfd_link_info *, asection *, @@ -1174,8 +1174,8 @@ elf_i386_check_relocs (abfd, info, sec, relocs) relocation. */ static asection * -elf_i386_gc_mark_hook (abfd, info, rel, h, sym) - bfd *abfd; +elf_i386_gc_mark_hook (sec, info, rel, h, sym) + asection *sec; struct bfd_link_info *info ATTRIBUTE_UNUSED; Elf_Internal_Rela *rel; struct elf_link_hash_entry *h; @@ -1205,9 +1205,7 @@ elf_i386_gc_mark_hook (abfd, info, rel, h, sym) } } else - { - return bfd_section_from_elf_index (abfd, sym->st_shndx); - } + return bfd_section_from_elf_index (sec->owner, sym->st_shndx); return NULL; } diff --git a/bfd/elf32-m32r.c b/bfd/elf32-m32r.c index e8015a9..b3f8736 100644 --- a/bfd/elf32-m32r.c +++ b/bfd/elf32-m32r.c @@ -1,5 +1,5 @@ /* M32R-specific support for 32-bit ELF. - Copyright 1996, 1997, 1998, 1999, 2000, 2001 + Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -78,7 +78,7 @@ static boolean m32r_elf_check_relocs const Elf_Internal_Rela *)); asection * m32r_elf_gc_mark_hook - PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *, + PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *)); #define NOP_INSN 0x7000 @@ -2033,12 +2033,12 @@ m32r_elf_print_private_bfd_data (abfd, ptr) } asection * -m32r_elf_gc_mark_hook (abfd, info, rel, h, sym) - bfd *abfd; - struct bfd_link_info *info ATTRIBUTE_UNUSED; - Elf_Internal_Rela *rel; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; +m32r_elf_gc_mark_hook (sec, info, rel, h, sym) + 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) { @@ -2064,9 +2064,8 @@ m32r_elf_gc_mark_hook (abfd, info, rel, h, sym) } } else - { - return bfd_section_from_elf_index (abfd, sym->st_shndx); - } + return bfd_section_from_elf_index (sec->owner, sym->st_shndx); + return NULL; } diff --git a/bfd/elf32-m68k.c b/bfd/elf32-m68k.c index 2006652..0b97cb5 100644 --- a/bfd/elf32-m68k.c +++ b/bfd/elf32-m68k.c @@ -37,7 +37,7 @@ static boolean elf_m68k_check_relocs PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *)); static asection *elf_m68k_gc_mark_hook - PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *, + PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *)); static boolean elf_m68k_gc_sweep_hook PARAMS ((bfd *, struct bfd_link_info *, asection *, @@ -754,8 +754,8 @@ elf_m68k_check_relocs (abfd, info, sec, relocs) relocation. */ static asection * -elf_m68k_gc_mark_hook (abfd, info, rel, h, sym) - bfd *abfd; +elf_m68k_gc_mark_hook (sec, info, rel, h, sym) + asection *sec; struct bfd_link_info *info ATTRIBUTE_UNUSED; Elf_Internal_Rela *rel; struct elf_link_hash_entry *h; @@ -785,9 +785,7 @@ elf_m68k_gc_mark_hook (abfd, info, rel, h, sym) } } else - { - return bfd_section_from_elf_index (abfd, sym->st_shndx); - } + return bfd_section_from_elf_index (sec->owner, sym->st_shndx); return NULL; } diff --git a/bfd/elf32-mcore.c b/bfd/elf32-mcore.c index 44ef340..e840e3b 100644 --- a/bfd/elf32-mcore.c +++ b/bfd/elf32-mcore.c @@ -48,7 +48,7 @@ static boolean mcore_elf_relocate_section PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *, Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); static asection * mcore_elf_gc_mark_hook - PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *, + PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *)); static boolean mcore_elf_gc_sweep_hook PARAMS ((bfd *, struct bfd_link_info *, asection *, @@ -573,8 +573,8 @@ mcore_elf_relocate_section (output_bfd, info, input_bfd, input_section, relocation. */ static asection * -mcore_elf_gc_mark_hook (abfd, info, rel, h, sym) - bfd * abfd; +mcore_elf_gc_mark_hook (sec, info, rel, h, sym) + asection * sec; struct bfd_link_info * info ATTRIBUTE_UNUSED; Elf_Internal_Rela * rel; struct elf_link_hash_entry * h; @@ -604,9 +604,7 @@ mcore_elf_gc_mark_hook (abfd, info, rel, h, sym) } } else - { - return bfd_section_from_elf_index (abfd, sym->st_shndx); - } + return bfd_section_from_elf_index (sec->owner, sym->st_shndx); return NULL; } diff --git a/bfd/elf32-openrisc.c b/bfd/elf32-openrisc.c index 2dd7fb7..f0f8b87 100644 --- a/bfd/elf32-openrisc.c +++ b/bfd/elf32-openrisc.c @@ -41,7 +41,7 @@ static boolean openrisc_elf_gc_sweep_hook PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *)); static asection * openrisc_elf_gc_mark_hook - PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *, + PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *)); static boolean openrisc_elf_check_relocs PARAMS ((bfd *, struct bfd_link_info *, asection *, @@ -468,8 +468,8 @@ openrisc_elf_relocate_section (output_bfd, info, input_bfd, input_section, relocation. */ static asection * -openrisc_elf_gc_mark_hook (abfd, info, rel, h, sym) - bfd *abfd; +openrisc_elf_gc_mark_hook (sec, info, rel, h, sym) + asection *sec; struct bfd_link_info *info ATTRIBUTE_UNUSED; Elf_Internal_Rela *rel; struct elf_link_hash_entry *h; @@ -499,9 +499,7 @@ openrisc_elf_gc_mark_hook (abfd, info, rel, h, sym) } } else - { - return bfd_section_from_elf_index (abfd, sym->st_shndx); - } + return bfd_section_from_elf_index (sec->owner, sym->st_shndx); return NULL; } diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index 984a486..1745ef5 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -71,7 +71,7 @@ static boolean ppc_elf_check_relocs PARAMS ((bfd *, asection *, const Elf_Internal_Rela *)); -static asection * ppc_elf_gc_mark_hook PARAMS ((bfd *abfd, +static asection * ppc_elf_gc_mark_hook PARAMS ((asection *sec, struct bfd_link_info *info, Elf_Internal_Rela *rel, struct elf_link_hash_entry *h, @@ -2481,8 +2481,8 @@ ppc_elf_check_relocs (abfd, info, sec, relocs) relocation. */ static asection * -ppc_elf_gc_mark_hook (abfd, info, rel, h, sym) - bfd *abfd; +ppc_elf_gc_mark_hook (sec, info, rel, h, sym) + asection *sec; struct bfd_link_info *info ATTRIBUTE_UNUSED; Elf_Internal_Rela *rel; struct elf_link_hash_entry *h; @@ -2512,9 +2512,7 @@ ppc_elf_gc_mark_hook (abfd, info, rel, h, sym) } } else - { - return bfd_section_from_elf_index (abfd, sym->st_shndx); - } + return bfd_section_from_elf_index (sec->owner, sym->st_shndx); return NULL; } diff --git a/bfd/elf32-s390.c b/bfd/elf32-s390.c index cdbdcba..d6d7ada 100644 --- a/bfd/elf32-s390.c +++ b/bfd/elf32-s390.c @@ -45,7 +45,7 @@ static boolean elf_s390_check_relocs PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *)); static asection *elf_s390_gc_mark_hook - PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *, + PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *)); static boolean elf_s390_gc_sweep_hook PARAMS ((bfd *, struct bfd_link_info *, asection *, @@ -903,8 +903,8 @@ elf_s390_check_relocs (abfd, info, sec, relocs) relocation. */ static asection * -elf_s390_gc_mark_hook (abfd, info, rel, h, sym) - bfd *abfd; +elf_s390_gc_mark_hook (sec, info, rel, h, sym) + asection *sec; struct bfd_link_info *info ATTRIBUTE_UNUSED; Elf_Internal_Rela *rel; struct elf_link_hash_entry *h; @@ -934,9 +934,7 @@ elf_s390_gc_mark_hook (abfd, info, rel, h, sym) } } else - { - return bfd_section_from_elf_index (abfd, sym->st_shndx); - } + return bfd_section_from_elf_index (sec->owner, sym->st_shndx); return NULL; } diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c index 7ff0f82..fdadb6d 100644 --- a/bfd/elf32-sh.c +++ b/bfd/elf32-sh.c @@ -78,7 +78,7 @@ static bfd_reloc_status_type sh_elf_reloc_loop static boolean sh_elf_create_dynamic_sections PARAMS ((bfd *, struct bfd_link_info *)); static asection * sh_elf_gc_mark_hook - PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *, + PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *)); static boolean sh_elf_gc_sweep_hook PARAMS ((bfd *, struct bfd_link_info *, asection *, @@ -4978,8 +4978,8 @@ sh_elf_get_relocated_section_contents (output_bfd, link_info, link_order, } static asection * -sh_elf_gc_mark_hook (abfd, info, rel, h, sym) - bfd *abfd; +sh_elf_gc_mark_hook (sec, info, rel, h, sym) + asection *sec; struct bfd_link_info *info ATTRIBUTE_UNUSED; Elf_Internal_Rela *rel; struct elf_link_hash_entry *h; @@ -5009,9 +5009,7 @@ sh_elf_gc_mark_hook (abfd, info, rel, h, sym) } } else - { - return bfd_section_from_elf_index (abfd, sym->st_shndx); - } + return bfd_section_from_elf_index (sec->owner, sym->st_shndx); return NULL; } diff --git a/bfd/elf32-sparc.c b/bfd/elf32-sparc.c index a11db81..3a78f5f 100644 --- a/bfd/elf32-sparc.c +++ b/bfd/elf32-sparc.c @@ -1,5 +1,5 @@ /* SPARC-specific support for 32-bit ELF - Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 + Copyright 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc. This file is part of BFD, the Binary File Descriptor library. @@ -55,7 +55,7 @@ static void elf32_sparc_final_write_processing static enum elf_reloc_type_class elf32_sparc_reloc_type_class PARAMS ((const Elf_Internal_Rela *)); static asection * elf32_sparc_gc_mark_hook - PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *, + PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *)); static boolean elf32_sparc_gc_sweep_hook PARAMS ((bfd *, struct bfd_link_info *, asection *, @@ -637,14 +637,13 @@ elf32_sparc_check_relocs (abfd, info, sec, relocs) } static asection * -elf32_sparc_gc_mark_hook (abfd, info, rel, h, sym) - bfd *abfd; +elf32_sparc_gc_mark_hook (sec, info, rel, h, sym) + 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)) @@ -669,9 +668,7 @@ elf32_sparc_gc_mark_hook (abfd, info, rel, h, sym) } } else - { - return bfd_section_from_elf_index (abfd, sym->st_shndx); - } + return bfd_section_from_elf_index (sec->owner, sym->st_shndx); return NULL; } diff --git a/bfd/elf32-v850.c b/bfd/elf32-v850.c index ad6807f..6762190 100644 --- a/bfd/elf32-v850.c +++ b/bfd/elf32-v850.c @@ -84,7 +84,7 @@ static boolean v850_elf_gc_sweep_hook PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *)); static asection * v850_elf_gc_mark_hook - PARAMS ((bfd *, struct bfd_link_info *, + PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *)); @@ -1740,8 +1740,8 @@ v850_elf_gc_sweep_hook (abfd, info, sec, relocs) } static asection * -v850_elf_gc_mark_hook (abfd, info, rel, h, sym) - bfd *abfd; +v850_elf_gc_mark_hook (sec, info, rel, h, sym) + asection *sec; struct bfd_link_info *info ATTRIBUTE_UNUSED; Elf_Internal_Rela *rel; struct elf_link_hash_entry *h; @@ -1771,9 +1771,7 @@ v850_elf_gc_mark_hook (abfd, info, rel, h, sym) } } else - { - return bfd_section_from_elf_index (abfd, sym->st_shndx); - } + return bfd_section_from_elf_index (sec->owner, sym->st_shndx); return NULL; } diff --git a/bfd/elf32-vax.c b/bfd/elf32-vax.c index 8901188..bb5ee0be 100644 --- a/bfd/elf32-vax.c +++ b/bfd/elf32-vax.c @@ -38,7 +38,7 @@ static boolean elf_vax_check_relocs PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *)); static asection *elf_vax_gc_mark_hook - PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *, + PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *)); static boolean elf_vax_gc_sweep_hook PARAMS ((bfd *, struct bfd_link_info *, asection *, @@ -855,8 +855,8 @@ elf_vax_check_relocs (abfd, info, sec, relocs) relocation. */ static asection * -elf_vax_gc_mark_hook (abfd, info, rel, h, sym) - bfd *abfd; +elf_vax_gc_mark_hook (sec, info, rel, h, sym) + asection *sec; struct bfd_link_info *info ATTRIBUTE_UNUSED; Elf_Internal_Rela *rel; struct elf_link_hash_entry *h; @@ -886,9 +886,7 @@ elf_vax_gc_mark_hook (abfd, info, rel, h, sym) } } else - { - return bfd_section_from_elf_index (abfd, sym->st_shndx); - } + return bfd_section_from_elf_index (sec->owner, sym->st_shndx); return NULL; } diff --git a/bfd/elf32-xstormy16.c b/bfd/elf32-xstormy16.c index d58ea9c..8f83f31 100644 --- a/bfd/elf32-xstormy16.c +++ b/bfd/elf32-xstormy16.c @@ -54,7 +54,7 @@ static boolean xstormy16_elf_gc_sweep_hook PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *)); static asection * xstormy16_elf_gc_mark_hook - PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *, + PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *)); static reloc_howto_type xstormy16_elf_howto_table [] = @@ -1021,8 +1021,8 @@ xstormy16_elf_finish_dynamic_sections (abfd, info) relocation. */ static asection * -xstormy16_elf_gc_mark_hook (abfd, info, rel, h, sym) - bfd * abfd; +xstormy16_elf_gc_mark_hook (sec, info, rel, h, sym) + asection * sec; struct bfd_link_info * info ATTRIBUTE_UNUSED; Elf_Internal_Rela * rel; struct elf_link_hash_entry * h; @@ -1052,9 +1052,7 @@ xstormy16_elf_gc_mark_hook (abfd, info, rel, h, sym) } } else - { - return bfd_section_from_elf_index (abfd, sym->st_shndx); - } + return bfd_section_from_elf_index (sec->owner, sym->st_shndx); return NULL; } diff --git a/bfd/elf64-mmix.c b/bfd/elf64-mmix.c index 0dc6655..9dc2d74 100644 --- a/bfd/elf64-mmix.c +++ b/bfd/elf64-mmix.c @@ -148,7 +148,7 @@ static boolean mmix_elf_relocate_section Elf_Internal_Rela *, Elf_Internal_Sym *, asection **)); static asection * mmix_elf_gc_mark_hook - PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *, + PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *)); static boolean mmix_elf_gc_sweep_hook @@ -1524,8 +1524,8 @@ mmix_final_link_relocate (howto, input_section, contents, relocation. */ static asection * -mmix_elf_gc_mark_hook (abfd, info, rel, h, sym) - bfd *abfd; +mmix_elf_gc_mark_hook (sec, info, rel, h, sym) + asection *sec; struct bfd_link_info *info ATTRIBUTE_UNUSED; Elf_Internal_Rela *rel; struct elf_link_hash_entry *h; @@ -1555,9 +1555,7 @@ mmix_elf_gc_mark_hook (abfd, info, rel, h, sym) } } else - { - return bfd_section_from_elf_index (abfd, sym->st_shndx); - } + return bfd_section_from_elf_index (sec->owner, sym->st_shndx); return NULL; } diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index ac52ae1..ca39bd4 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -127,8 +127,7 @@ static boolean ppc64_elf_section_from_shdr /* Since .opd is an array of descriptors and each entry will end up with identical R_PPC64_RELATIVE relocs, there is really no need to propagate .opd relocs; The dynamic linker should be taught to - relocate .opd without reloc entries. FIXME: .opd should be trimmed - of unused values. */ + relocate .opd without reloc entries. */ #ifndef NO_OPD_RELOCS #define NO_OPD_RELOCS 0 #endif @@ -2005,6 +2004,7 @@ struct ppc_link_hash_entry /* Flag function code and descriptor symbols. */ unsigned int is_func:1; unsigned int is_func_descriptor:1; + unsigned int is_entry:1; }; /* ppc64 ELF linker hash table. */ @@ -2100,11 +2100,11 @@ static boolean ppc64_elf_check_relocs PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *)); static asection * ppc64_elf_gc_mark_hook - PARAMS ((bfd *abfd, struct bfd_link_info *info, Elf_Internal_Rela *rel, - struct elf_link_hash_entry *h, Elf_Internal_Sym *sym)); + PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, + struct elf_link_hash_entry *, Elf_Internal_Sym *)); static boolean ppc64_elf_gc_sweep_hook - PARAMS ((bfd *abfd, struct bfd_link_info *info, asection *sec, - const Elf_Internal_Rela *relocs)); + PARAMS ((bfd *, struct bfd_link_info *, asection *, + const Elf_Internal_Rela *)); static boolean func_desc_adjust PARAMS ((struct elf_link_hash_entry *, PTR)); static boolean ppc64_elf_func_desc_adjust @@ -2113,6 +2113,8 @@ static boolean ppc64_elf_adjust_dynamic_symbol PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *)); static void ppc64_elf_hide_symbol PARAMS ((struct bfd_link_info *, struct elf_link_hash_entry *, boolean)); +static boolean edit_opd + PARAMS ((bfd *, struct bfd_link_info *)); static boolean allocate_dynrelocs PARAMS ((struct elf_link_hash_entry *, PTR)); static boolean readonly_dynrelocs @@ -2256,6 +2258,7 @@ link_hash_newfunc (entry, table, string) eh->oh = NULL; eh->is_func = 0; eh->is_func_descriptor = 0; + eh->is_entry = 0; } return entry; @@ -2292,6 +2295,7 @@ ppc64_elf_link_hash_table_create (abfd) htab->add_stub_section = NULL; htab->layout_sections_again = NULL; htab->stub_group = NULL; + htab->all_local_syms = NULL; htab->sgot = NULL; htab->srelgot = NULL; htab->splt = NULL; @@ -2514,7 +2518,7 @@ create_linkage_sections (dynobj, info) { flags = (SEC_ALLOC | SEC_LOAD | SEC_READONLY | SEC_HAS_CONTENTS | SEC_IN_MEMORY | SEC_LINKER_CREATED); - htab->srelbrlt = bfd_make_section (dynobj, ".rela.branch_lt"); + htab->srelbrlt = bfd_make_section_anyway (dynobj, ".rela.branch_lt"); if (!htab->srelbrlt || ! bfd_set_section_flags (dynobj, htab->srelbrlt, flags) || ! bfd_set_section_alignment (dynobj, htab->srelbrlt, 3)) @@ -2628,10 +2632,33 @@ ppc64_elf_copy_indirect_symbol (dir, ind) edir->is_func |= eind->is_func; edir->is_func_descriptor |= eind->is_func_descriptor; + edir->is_entry |= eind->is_entry; _bfd_elf_link_hash_copy_indirect (dir, ind); } +/* Set a flag, used by ppc64_elf_gc_mark_hook, on the entry symbol and + symbols undefined on the command-line. */ + +boolean +ppc64_elf_mark_entry_syms (info) + struct bfd_link_info *info; +{ + struct ppc_link_hash_table *htab; + struct bfd_sym_chain *sym; + + htab = ppc_hash_table (info); + for (sym = info->gc_sym_list; sym; sym = sym->next) + { + struct elf_link_hash_entry *h; + + h = elf_link_hash_lookup (&htab->elf, sym->name, false, false, false); + if (h != NULL) + ((struct ppc_link_hash_entry *) h)->is_entry = 1; + } + return true; +} + /* Look through the relocs for a section during the first phase, and calculate needed space in the global offset table, procedure linkage table, and dynamic reloc sections. */ @@ -2649,7 +2676,7 @@ ppc64_elf_check_relocs (abfd, info, sec, relocs) const Elf_Internal_Rela *rel; const Elf_Internal_Rela *rel_end; asection *sreloc; - boolean is_opd; + asection **opd_sym_map; if (info->relocateable) return true; @@ -2659,12 +2686,34 @@ ppc64_elf_check_relocs (abfd, info, sec, relocs) sym_hashes = elf_sym_hashes (abfd); sym_hashes_end = (sym_hashes - + symtab_hdr->sh_size / sizeof (Elf64_External_Sym)); - if (!elf_bad_symtab (abfd)) - sym_hashes_end -= symtab_hdr->sh_info; + + symtab_hdr->sh_size / sizeof (Elf64_External_Sym) + - symtab_hdr->sh_info); sreloc = NULL; - is_opd = strcmp (bfd_get_section_name (abfd, sec), ".opd") == 0; + opd_sym_map = NULL; + if (strcmp (bfd_get_section_name (abfd, sec), ".opd") == 0) + { + /* Garbage collection needs some extra help with .opd sections. + We don't want to necessarily keep everything referenced by + relocs in .opd, as that would keep all functions. Instead, + if we reference an .opd symbol (a function descriptor), we + want to keep the function code symbol's section. This is + easy for global symbols, but for local syms we need to keep + information about the associated function section. Later, if + edit_opd deletes entries, we'll use this array to adjust + local syms in .opd. */ + union opd_info { + asection *func_section; + long entry_adjust; + }; + bfd_size_type amt; + + amt = sec->_raw_size * sizeof (union opd_info) / 24; + opd_sym_map = (asection **) bfd_zalloc (abfd, amt); + if (opd_sym_map == NULL) + return false; + elf_section_data (sec)->tdata = opd_sym_map; + } if (htab->elf.dynobj == NULL) htab->elf.dynobj = abfd; @@ -2801,7 +2850,7 @@ ppc64_elf_check_relocs (abfd, info, sec, relocs) break; case R_PPC64_ADDR64: - if (is_opd + if (opd_sym_map != NULL && h != NULL && h->root.root.string[0] == '.' && h->root.root.string[1] != 0) @@ -2818,6 +2867,21 @@ ppc64_elf_check_relocs (abfd, info, sec, relocs) ((struct ppc_link_hash_entry *) h)->oh = fdh; } } + if (opd_sym_map != NULL + && h == NULL + && rel + 1 < rel_end + && ((enum elf_ppc_reloc_type) ELF64_R_TYPE ((rel + 1)->r_info) + == R_PPC64_TOC)) + { + asection *s; + + s = bfd_section_from_r_symndx (abfd, &htab->sym_sec, sec, + r_symndx); + if (s == NULL) + return false; + else if (s != sec) + opd_sym_map[rel->r_offset / 24] = s; + } /* Fall through. */ case R_PPC64_REL64: @@ -2843,7 +2907,7 @@ ppc64_elf_check_relocs (abfd, info, sec, relocs) case R_PPC64_UADDR64: case R_PPC64_TOC: /* Don't propagate .opd relocs. */ - if (NO_OPD_RELOCS && is_opd) + if (NO_OPD_RELOCS && opd_sym_map != NULL) break; /* If we are creating a shared library, and this is a reloc @@ -2984,16 +3048,19 @@ ppc64_elf_check_relocs (abfd, info, sec, relocs) relocation. */ static asection * -ppc64_elf_gc_mark_hook (abfd, info, rel, h, sym) - bfd *abfd; +ppc64_elf_gc_mark_hook (sec, info, rel, h, sym) + asection *sec; struct bfd_link_info *info ATTRIBUTE_UNUSED; Elf_Internal_Rela *rel; struct elf_link_hash_entry *h; Elf_Internal_Sym *sym; { + asection *rsec = NULL; + if (h != NULL) { enum elf_ppc_reloc_type r_type; + struct ppc_link_hash_entry *fdh; r_type = (enum elf_ppc_reloc_type) ELF64_R_TYPE (rel->r_info); switch (r_type) @@ -3007,10 +3074,26 @@ ppc64_elf_gc_mark_hook (abfd, info, rel, h, sym) { case bfd_link_hash_defined: case bfd_link_hash_defweak: - return h->root.u.def.section; + fdh = (struct ppc_link_hash_entry *) h; + + /* Function descriptor syms cause the associated + function code sym section to be marked. */ + if (fdh->is_func_descriptor) + rsec = fdh->oh->root.u.def.section; + + /* Function entry syms return NULL if they are in .opd + and are not ._start (or others undefined on the ld + command line). Thus we avoid marking all function + sections, as all functions are referenced in .opd. */ + else if ((fdh->oh != NULL + && ((struct ppc_link_hash_entry *) fdh->oh)->is_entry) + || elf_section_data (sec)->tdata == NULL) + rsec = h->root.u.def.section; + break; case bfd_link_hash_common: - return h->root.u.c.p->section; + rsec = h->root.u.c.p->section; + break; default: break; @@ -3019,10 +3102,17 @@ ppc64_elf_gc_mark_hook (abfd, info, rel, h, sym) } else { - return bfd_section_from_elf_index (abfd, sym->st_shndx); + asection **opd_sym_section; + + rsec = bfd_section_from_elf_index (sec->owner, sym->st_shndx); + opd_sym_section = (asection **) elf_section_data (rsec)->tdata; + if (opd_sym_section != NULL) + rsec = opd_sym_section[sym->st_value / 24]; + else if (elf_section_data (sec)->tdata != NULL) + rsec = NULL; } - return NULL; + return rsec; } /* Update the .got, .plt. and dynamic reloc reference counts for the @@ -3592,6 +3682,268 @@ ppc64_elf_hide_symbol (info, h, force_local) } } +static boolean +edit_opd (obfd, info) + bfd *obfd; + struct bfd_link_info *info; +{ + bfd *ibfd; + unsigned int bfd_indx; + struct ppc_link_hash_table *htab = ppc_hash_table (info); + + for (bfd_indx = 0, ibfd = info->input_bfds; + ibfd != NULL; + ibfd = ibfd->link_next, bfd_indx++) + { + asection *sec; + Elf_Internal_Rela *relstart, *rel, *relend; + Elf_Internal_Shdr *symtab_hdr; + struct elf_link_hash_entry **sym_hashes; + bfd_vma offset; + long *adjust; + boolean need_edit; + + sec = bfd_get_section_by_name (ibfd, ".opd"); + if (sec == NULL) + continue; + + adjust = (long *) elf_section_data (sec)->tdata; + BFD_ASSERT (adjust != NULL); + memset (adjust, 0, (size_t) sec->_raw_size * sizeof (long) / 24); + + if (sec->output_section == bfd_abs_section_ptr) + continue; + + /* Look through the section relocs. */ + if ((sec->flags & SEC_RELOC) == 0 || sec->reloc_count == 0) + continue; + + symtab_hdr = &elf_tdata (ibfd)->symtab_hdr; + sym_hashes = elf_sym_hashes (ibfd); + + /* Read the relocations. */ + relstart = _bfd_elf64_link_read_relocs (obfd, sec, (PTR) NULL, + (Elf_Internal_Rela *) NULL, + info->keep_memory); + if (relstart == NULL) + return false; + + /* First run through the relocs to check they are sane, and to + determine whether we need to edit this opd section. */ + need_edit = false; + offset = 0; + relend = relstart + sec->reloc_count; + for (rel = relstart; rel < relend; rel++) + { + enum elf_ppc_reloc_type r_type; + unsigned long r_symndx; + asection *sym_sec; + struct elf_link_hash_entry *h; + Elf_Internal_Sym *sym; + + /* .opd contains a regular array of 24 byte entries. We're + only interested in the reloc pointing to a function entry + point. */ + r_type = (enum elf_ppc_reloc_type) ELF64_R_TYPE (rel->r_info); + if (r_type == R_PPC64_TOC) + continue; + + if (r_type != R_PPC64_ADDR64) + { + (*_bfd_error_handler) + (_("%s: unexpected reloc type %u in .opd section"), + bfd_archive_filename (ibfd), r_type); + need_edit = false; + break; + } + + if (rel + 1 >= relend) + continue; + r_type = (enum elf_ppc_reloc_type) ELF64_R_TYPE ((rel + 1)->r_info); + if (r_type != R_PPC64_TOC) + continue; + + if (rel->r_offset != offset) + { + /* If someone messes with .opd alignment then after a + "ld -r" we might have padding in the middle of .opd. + Also, there's nothing to prevent someone putting + something silly in .opd with the assembler. No .opd + optimization for them! */ + (*_bfd_error_handler) + (_("%s: .opd is not a regular array of opd entries"), + bfd_archive_filename (ibfd)); + need_edit = false; + break; + } + + r_symndx = ELF64_R_SYM (rel->r_info); + sym_sec = NULL; + h = NULL; + sym = NULL; + if (r_symndx >= symtab_hdr->sh_info) + { + 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) + sym_sec = h->root.u.def.section; + } + else + { + sym = htab->all_local_syms[bfd_indx] + r_symndx; + if ((sym->st_shndx != SHN_UNDEF + && sym->st_shndx < SHN_LORESERVE) + || sym->st_shndx > SHN_HIRESERVE) + sym_sec = bfd_section_from_elf_index (ibfd, sym->st_shndx); + } + + if (sym_sec == NULL || sym_sec->owner == NULL) + { + (*_bfd_error_handler) + (_("%s: undefined sym `%s' in .opd section"), + bfd_archive_filename (ibfd), + h != NULL ? h->root.root.string : "<local symbol>"); + need_edit = false; + break; + } + + if (sym_sec->output_section == bfd_abs_section_ptr) + { + /* OK, we've found a function that's excluded from the + link. */ + need_edit = true; + } + + offset += 24; + } + + if (need_edit) + { + Elf_Internal_Rela *write_rel; + bfd_byte *rptr, *wptr; + boolean skip; + + /* This seems a waste of time as input .opd sections are all + zeros as generated by gcc, but I suppose there's no reason + this will always be so. We might start putting something in + the third word of .opd entries. */ + if ((sec->flags & SEC_IN_MEMORY) == 0) + { + bfd_byte *loc = bfd_alloc (ibfd, sec->_raw_size); + if (loc == NULL) + return false; + if (! bfd_get_section_contents (ibfd, sec, loc, (bfd_vma) 0, + sec->_raw_size)) + return false; + sec->contents = loc; + sec->flags |= (SEC_IN_MEMORY | SEC_HAS_CONTENTS); + } + + elf_section_data (sec)->relocs = relstart; + + wptr = sec->contents; + rptr = sec->contents; + write_rel = relstart; + skip = false; + offset = 0; + for (rel = relstart; rel < relend; rel++) + { + if (rel->r_offset == offset) + { + unsigned long r_symndx; + asection *sym_sec; + struct elf_link_hash_entry *h; + Elf_Internal_Sym *sym; + + r_symndx = ELF64_R_SYM (rel->r_info); + sym_sec = NULL; + h = NULL; + sym = NULL; + if (r_symndx >= symtab_hdr->sh_info) + { + 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) + sym_sec = h->root.u.def.section; + } + else + { + sym = htab->all_local_syms[bfd_indx] + r_symndx; + if ((sym->st_shndx != SHN_UNDEF + && sym->st_shndx < SHN_LORESERVE) + || sym->st_shndx > SHN_HIRESERVE) + sym_sec = bfd_section_from_elf_index (ibfd, + sym->st_shndx); + } + + skip = sym_sec->output_section == bfd_abs_section_ptr; + if (!skip) + { + /* We'll be keeping this opd entry. */ + + if (h != NULL) + { + /* Redefine the function descriptor symbol + to this location in the opd section. + We've checked above that opd relocs are + ordered. */ + struct elf_link_hash_entry *fdh; + struct ppc_link_hash_entry *fh; + + fh = (struct ppc_link_hash_entry *) h; + BFD_ASSERT (fh->is_func); + fdh = fh->oh; + fdh->root.u.def.value = wptr - sec->contents; + } + else + { + /* Local syms are a bit tricky. Other parts + of the linker re-read them so it's not + possible to tweak local sym values. In + any case, we'd need to look through the + local syms for the function descriptor + sym which we don't have at the moment. + So keep an array of adjustments. */ + adjust[(rel->r_offset + wptr - rptr) / 24] + = wptr - rptr; + } + + if (wptr != rptr) + memcpy (wptr, rptr, 24); + wptr += 24; + } + rptr += 24; + offset += 24; + } + + /* We need to adjust any reloc offsets to point to the + new opd entries. While we're at it, we may as well + remove redundant relocs. */ + if (!skip) + { + rel->r_offset += wptr - rptr; + if (write_rel != rel) + memcpy (write_rel, rel, sizeof (*rel)); + ++write_rel; + } + } + + sec->_cooked_size = wptr - sec->contents; + sec->reloc_count = write_rel - relstart; + } + else if (elf_section_data (sec)->relocs == NULL) + free (relstart); + } + + 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 @@ -3890,6 +4242,12 @@ ppc64_elf_size_dynamic_sections (output_bfd, info) } } + if (!get_local_syms (info->input_bfds, htab)) + return false; + + if (!edit_opd (output_bfd, info)) + return false; + /* Allocate global sym .plt and .got entries, and space for global sym dynamic relocs. */ elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, (PTR) info); @@ -4365,7 +4723,6 @@ ppc64_elf_setup_section_lists (output_bfd, info) struct bfd_link_info *info; { bfd *input_bfd; - unsigned int bfd_count; int top_id, top_index; asection *section; asection **input_list, **list; @@ -4376,12 +4733,11 @@ ppc64_elf_setup_section_lists (output_bfd, info) || htab->sbrlt == NULL) return 0; - /* Count the number of input BFDs and find the top input section id. */ - for (input_bfd = info->input_bfds, bfd_count = 0, top_id = 0; + /* Find the top input section id. */ + for (input_bfd = info->input_bfds, top_id = 0; input_bfd != NULL; input_bfd = input_bfd->link_next) { - bfd_count += 1; for (section = input_bfd->sections; section != NULL; section = section->next) @@ -4390,7 +4746,6 @@ ppc64_elf_setup_section_lists (output_bfd, info) top_id = section->id; } } - htab->bfd_count = bfd_count; amt = sizeof (struct map_stub) * (top_id + 1); htab->stub_group = (struct map_stub *) bfd_zmalloc (amt); @@ -4543,20 +4898,26 @@ get_local_syms (input_bfd, htab) struct ppc_link_hash_table *htab; { unsigned int bfd_indx; + bfd *ibfd; Elf_Internal_Sym *local_syms, **all_local_syms; + bfd_size_type amt; + + if (htab->all_local_syms != NULL) + return true; /* We want to read in symbol extension records only once. To do this we need to read in the local symbols in parallel and save them for later use; so hold pointers to the local symbols in an array. */ - bfd_size_type amt = sizeof (Elf_Internal_Sym *) * htab->bfd_count; + for (ibfd = input_bfd, bfd_indx = 0; ibfd != NULL; ibfd = ibfd->link_next) + bfd_indx += 1; + htab->bfd_count = bfd_indx; + amt = sizeof (Elf_Internal_Sym *) * bfd_indx; all_local_syms = (Elf_Internal_Sym **) bfd_zmalloc (amt); htab->all_local_syms = all_local_syms; if (all_local_syms == NULL) return false; - /* Walk over all the input BFDs, swapping in local symbols. - If we are creating a shared library, create hash entries for the - export stubs. */ + /* Walk over all the input BFDs, swapping in local symbols. */ for (bfd_indx = 0; input_bfd != NULL; input_bfd = input_bfd->link_next, bfd_indx++) @@ -4568,6 +4929,9 @@ get_local_syms (input_bfd, htab) Elf_External_Sym_Shndx *shndx_buf, *shndx; bfd_size_type sec_size; + if (bfd_get_flavour (input_bfd) != bfd_target_elf_flavour) + continue; + /* We'll need the symbol table in a second. */ symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; if (symtab_hdr->sh_info == 0) @@ -4707,10 +5071,7 @@ ppc64_elf_size_stubs (output_bfd, stub_bfd, info, group_size, section != NULL; section = section->next) { - Elf_Internal_Shdr *input_rel_hdr; - Elf64_External_Rela *external_relocs, *erelaend, *erela; Elf_Internal_Rela *internal_relocs, *irelaend, *irela; - bfd_size_type amt; /* If there aren't any relocs, then there's nothing more to do. */ @@ -4724,47 +5085,13 @@ ppc64_elf_size_stubs (output_bfd, stub_bfd, info, group_size, || section->output_section->owner != output_bfd) continue; - /* Allocate space for the external relocations. */ - amt = section->reloc_count; - amt *= sizeof (Elf64_External_Rela); - external_relocs = (Elf64_External_Rela *) bfd_malloc (amt); - if (external_relocs == NULL) - { - goto error_ret_free_local; - } - - /* Likewise for the internal relocations. */ - amt = section->reloc_count; - amt *= sizeof (Elf_Internal_Rela); - internal_relocs = (Elf_Internal_Rela *) bfd_malloc (amt); + /* Get the relocs. */ + internal_relocs + = _bfd_elf64_link_read_relocs (input_bfd, section, NULL, + (Elf_Internal_Rela *) NULL, + info->keep_memory); if (internal_relocs == NULL) - { - free (external_relocs); - goto error_ret_free_local; - } - - /* Read in the external relocs. */ - input_rel_hdr = &elf_section_data (section)->rel_hdr; - if (bfd_seek (input_bfd, input_rel_hdr->sh_offset, SEEK_SET) != 0 - || bfd_bread ((PTR) external_relocs, - input_rel_hdr->sh_size, - input_bfd) != input_rel_hdr->sh_size) - { - free (external_relocs); - error_ret_free_internal: - free (internal_relocs); - goto error_ret_free_local; - } - - /* Swap in the relocs. */ - erela = external_relocs; - erelaend = erela + section->reloc_count; - irela = internal_relocs; - for (; erela < erelaend; erela++, irela++) - bfd_elf64_swap_reloca_in (input_bfd, erela, irela); - - /* We're done with the external relocs, free them. */ - free (external_relocs); + goto error_ret_free_local; /* Now examine each relocation. */ irela = internal_relocs; @@ -4787,7 +5114,10 @@ ppc64_elf_size_stubs (output_bfd, stub_bfd, info, group_size, if (r_type >= (unsigned int) R_PPC_max) { bfd_set_error (bfd_error_bad_value); - goto error_ret_free_internal; + error_ret_free_internal: + if (elf_section_data (section)->relocs == NULL) + free (internal_relocs); + goto error_ret_free_local; } /* Only look for stubs on branch instructions. */ @@ -4880,7 +5210,7 @@ ppc64_elf_size_stubs (output_bfd, stub_bfd, info, group_size, if (stub_entry == NULL) { free (stub_name); - goto error_ret_free_local; + goto error_ret_free_internal; } stub_entry->target_value = sym_value; @@ -4891,7 +5221,8 @@ ppc64_elf_size_stubs (output_bfd, stub_bfd, info, group_size, } /* We're done with the internal relocs, free them. */ - free (internal_relocs); + if (elf_section_data (section)->relocs == NULL) + free (internal_relocs); } } @@ -5151,7 +5482,7 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section, TOCstart = elf_gp (output_bfd); symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr; sym_hashes = elf_sym_hashes (input_bfd); - is_opd = strcmp (bfd_get_section_name (abfd, input_section), ".opd") == 0; + is_opd = elf_section_data (input_section)->tdata != NULL; rel = relocs; relend = relocs + input_section->reloc_count; @@ -5202,6 +5533,15 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section, relocation = _bfd_elf_rela_local_sym (output_bfd, sym, sec, rel); /* rel may have changed, update our copy of addend. */ addend = rel->r_addend; + + if (elf_section_data (sec) != NULL) + { + long *opd_sym_adjust; + + opd_sym_adjust = (long *) elf_section_data (sec)->tdata; + if (opd_sym_adjust != NULL && sym->st_value % 24 == 0) + relocation += opd_sym_adjust[sym->st_value / 24]; + } } else { @@ -5650,8 +5990,7 @@ ppc64_elf_relocate_section (output_bfd, info, input_bfd, input_section, shared lib. (I believe this is a generic bug in binutils handling of weak syms.) In these cases we won't use the opd - entry in this lib; We ought to edit the - opd section to remove unused entries. */ + entry in this lib. */ unresolved_reloc = false; } outrel.r_info = ELF64_R_INFO (0, R_PPC64_RELATIVE); diff --git a/bfd/elf64-ppc.h b/bfd/elf64-ppc.h index 86f687e..cabc388 100644 --- a/bfd/elf64-ppc.h +++ b/bfd/elf64-ppc.h @@ -17,6 +17,8 @@ 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. */ +boolean ppc64_elf_mark_entry_syms + PARAMS ((struct bfd_link_info *)); bfd_vma ppc64_elf_toc PARAMS ((bfd *)); int ppc64_elf_setup_section_lists diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c index abbd4cc..0934bfb 100644 --- a/bfd/elf64-s390.c +++ b/bfd/elf64-s390.c @@ -45,7 +45,7 @@ static boolean elf_s390_check_relocs PARAMS ((bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *)); static asection *elf_s390_gc_mark_hook - PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *, + PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *)); static boolean elf_s390_gc_sweep_hook PARAMS ((bfd *, struct bfd_link_info *, asection *, @@ -855,8 +855,8 @@ elf_s390_check_relocs (abfd, info, sec, relocs) relocation. */ static asection * -elf_s390_gc_mark_hook (abfd, info, rel, h, sym) - bfd *abfd; +elf_s390_gc_mark_hook (sec, info, rel, h, sym) + asection *sec; struct bfd_link_info *info ATTRIBUTE_UNUSED; Elf_Internal_Rela *rel; struct elf_link_hash_entry *h; @@ -886,9 +886,7 @@ elf_s390_gc_mark_hook (abfd, info, rel, h, sym) } } else - { - return bfd_section_from_elf_index (abfd, sym->st_shndx); - } + return bfd_section_from_elf_index (sec->owner, sym->st_shndx); return NULL; } diff --git a/bfd/elf64-sh64.c b/bfd/elf64-sh64.c index fb9b539..1e5e12b 100644 --- a/bfd/elf64-sh64.c +++ b/bfd/elf64-sh64.c @@ -127,7 +127,7 @@ static bfd_byte *sh_elf64_get_relocated_section_contents static boolean sh_elf64_set_mach_from_flags PARAMS ((bfd *)); static boolean sh_elf64_set_private_flags PARAMS ((bfd *, flagword)); static asection *sh_elf64_gc_mark_hook - PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *, + PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *)); static boolean sh_elf64_gc_sweep_hook PARAMS ((bfd *, struct bfd_link_info *, asection *, @@ -2450,12 +2450,12 @@ sh_elf64_merge_private_data (ibfd, obfd) relocation. */ static asection * -sh_elf64_gc_mark_hook (abfd, info, rel, h, sym) - bfd *abfd; - struct bfd_link_info *info ATTRIBUTE_UNUSED; - Elf_Internal_Rela *rel; - struct elf_link_hash_entry *h; - Elf_Internal_Sym *sym; +sh_elf64_gc_mark_hook (sec, info, rel, h, sym) + 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) { @@ -2481,9 +2481,7 @@ sh_elf64_gc_mark_hook (abfd, info, rel, h, sym) } } else - { - return bfd_section_from_elf_index (abfd, sym->st_shndx); - } + return bfd_section_from_elf_index (sec->owner, sym->st_shndx); return NULL; } diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 314b070..9c1bfdb 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -142,7 +142,7 @@ static boolean elf64_x86_64_check_relocs PARAMS ((bfd *, struct bfd_link_info *, asection *sec, const Elf_Internal_Rela *)); static asection *elf64_x86_64_gc_mark_hook - PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *, + PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *)); static boolean elf64_x86_64_gc_sweep_hook @@ -856,8 +856,8 @@ elf64_x86_64_check_relocs (abfd, info, sec, relocs) relocation. */ static asection * -elf64_x86_64_gc_mark_hook (abfd, info, rel, h, sym) - bfd *abfd; +elf64_x86_64_gc_mark_hook (sec, info, rel, h, sym) + asection *sec; struct bfd_link_info *info ATTRIBUTE_UNUSED; Elf_Internal_Rela *rel; struct elf_link_hash_entry *h; @@ -887,9 +887,7 @@ elf64_x86_64_gc_mark_hook (abfd, info, rel, h, sym) } } else - { - return bfd_section_from_elf_index (abfd, sym->st_shndx); - } + return bfd_section_from_elf_index (sec->owner, sym->st_shndx); return NULL; } diff --git a/bfd/elflink.h b/bfd/elflink.h index 293e20a..2a6428f 100644 --- a/bfd/elflink.h +++ b/bfd/elflink.h @@ -7729,7 +7729,7 @@ elf_finish_pointer_linker_section (output_bfd, input_bfd, info, lsect, h, static boolean elf_gc_mark PARAMS ((struct bfd_link_info *info, asection *sec, asection * (*gc_mark_hook) - PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *, + PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *)))); static boolean elf_gc_sweep @@ -7759,7 +7759,7 @@ elf_gc_mark (info, sec, gc_mark_hook) struct bfd_link_info *info; asection *sec; asection * (*gc_mark_hook) - PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *, + PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *)); { boolean ret; @@ -7862,17 +7862,17 @@ elf_gc_mark (info, sec, gc_mark_hook) (const PTR) locshndx, &s); if (ELF_ST_BIND (s.st_info) == STB_LOCAL) - rsec = (*gc_mark_hook) (sec->owner, info, rel, NULL, &s); + rsec = (*gc_mark_hook) (sec, info, rel, NULL, &s); else { h = sym_hashes[r_symndx - extsymoff]; - rsec = (*gc_mark_hook) (sec->owner, info, rel, h, NULL); + rsec = (*gc_mark_hook) (sec, info, rel, h, NULL); } } else if (r_symndx >= nlocsyms) { h = sym_hashes[r_symndx - extsymoff]; - rsec = (*gc_mark_hook) (sec->owner, info, rel, h, NULL); + rsec = (*gc_mark_hook) (sec, info, rel, h, NULL); } else { @@ -7881,7 +7881,7 @@ elf_gc_mark (info, sec, gc_mark_hook) (const PTR) (locsyms + r_symndx), (const PTR) locshndx, &s); - rsec = (*gc_mark_hook) (sec->owner, info, rel, NULL, &s); + rsec = (*gc_mark_hook) (sec, info, rel, NULL, &s); } if (rsec && !rsec->gc_mark) @@ -8129,7 +8129,7 @@ elf_gc_sections (abfd, info) boolean ok = true; bfd *sub; asection * (*gc_mark_hook) - PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *, + PARAMS ((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 diff --git a/bfd/elfxx-mips.c b/bfd/elfxx-mips.c index f470734..bbcce61 100644 --- a/bfd/elfxx-mips.c +++ b/bfd/elfxx-mips.c @@ -6274,8 +6274,8 @@ _bfd_mips_elf_modify_segment_map (abfd) relocation. */ asection * -_bfd_mips_elf_gc_mark_hook (abfd, info, rel, h, sym) - bfd *abfd; +_bfd_mips_elf_gc_mark_hook (sec, info, rel, h, sym) + asection *sec; struct bfd_link_info *info ATTRIBUTE_UNUSED; Elf_Internal_Rela *rel; struct elf_link_hash_entry *h; @@ -6285,7 +6285,7 @@ _bfd_mips_elf_gc_mark_hook (abfd, info, rel, h, sym) if (h != NULL) { - switch (ELF_R_TYPE (abfd, rel->r_info)) + switch (ELF_R_TYPE (sec->owner, rel->r_info)) { case R_MIPS_GNU_VTINHERIT: case R_MIPS_GNU_VTENTRY: @@ -6307,9 +6307,7 @@ _bfd_mips_elf_gc_mark_hook (abfd, info, rel, h, sym) } } else - { - return bfd_section_from_elf_index (abfd, sym->st_shndx); - } + return bfd_section_from_elf_index (sec->owner, sym->st_shndx); return NULL; } diff --git a/bfd/elfxx-mips.h b/bfd/elfxx-mips.h index b081265..47c8c89 100644 --- a/bfd/elfxx-mips.h +++ b/bfd/elfxx-mips.h @@ -62,7 +62,7 @@ extern int _bfd_mips_elf_additional_program_headers extern boolean _bfd_mips_elf_modify_segment_map PARAMS ((bfd *)); extern asection * _bfd_mips_elf_gc_mark_hook - PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *, + PARAMS ((asection *, struct bfd_link_info *, Elf_Internal_Rela *, struct elf_link_hash_entry *, Elf_Internal_Sym *)); extern boolean _bfd_mips_elf_gc_sweep_hook PARAMS ((bfd *, struct bfd_link_info *, asection *, |