From 87d72d41b073d51b7409d2b0e7f0bbb7b840e1e6 Mon Sep 17 00:00:00 2001 From: Alan Modra Date: Thu, 18 Jun 2009 14:18:29 +0000 Subject: [PATCH] * elf-bfd.h (struct sym_sec_cache): Delete. (struct sym_cache): New. (bfd_section_from_r_symndx): Delete prototype. (bfd_sym_from_r_symndx): Define prototype. * elf.c (bfd_section_from_r_symndx): Delete, replace with.. (bfd_sym_from_r_symndx): ..new function. * elf32-arm.c: Update all uses of struct sym_sec_cache and bfd_section_from_r_symndx to new struct and function. * elf32-bfin.c: Likewise. * elf32-hppa.c: Likewise. * elf32-i386.c: Likewise. * elf32-m32r.c: Likewise. * elf32-m68hc1x.c: Likewise. * elf32-m68hc1x.h: Likewise. * elf32-m68k.c: Likewise. * elf32-ppc.c: Likewise. * elf32-s390.c: Likewise. * elf32-sh.c: Likewise. * elf64-ppc.c: Likewise. * elf64-s390.c: Likewise. * elf64-x86-64.c: Likewise. * elfxx-sparc.c: Likewise. * elfxx-sparc.h: Likewise. --- bfd/ChangeLog | 26 ++++++++++++++++++++++++++ bfd/elf-bfd.h | 12 ++++++------ bfd/elf.c | 23 +++++++---------------- bfd/elf32-arm.c | 18 +++++++++++------- bfd/elf32-bfin.c | 6 +++--- bfd/elf32-hppa.c | 18 +++++++++++------- bfd/elf32-i386.c | 21 +++++++++++++-------- bfd/elf32-m32r.c | 21 +++++++++++++-------- bfd/elf32-m68hc1x.c | 2 +- bfd/elf32-m68hc1x.h | 4 ++-- bfd/elf32-m68k.c | 18 +++++++++++------- bfd/elf32-ppc.c | 25 +++++++++++++++++-------- bfd/elf32-s390.c | 17 +++++++++++------ bfd/elf32-sh.c | 19 ++++++++++++------- bfd/elf64-ppc.c | 40 ++++++++++++++++++++++++++++------------ bfd/elf64-s390.c | 18 +++++++++++------- bfd/elf64-x86-64.c | 21 +++++++++++++-------- bfd/elfxx-sparc.c | 12 ++++++++---- bfd/elfxx-sparc.h | 4 ++-- 19 files changed, 206 insertions(+), 119 deletions(-) diff --git a/bfd/ChangeLog b/bfd/ChangeLog index edfe50f07b..2ff97ef023 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,29 @@ +2009-06-18 Alan Modra + + * elf-bfd.h (struct sym_sec_cache): Delete. + (struct sym_cache): New. + (bfd_section_from_r_symndx): Delete prototype. + (bfd_sym_from_r_symndx): Define prototype. + * elf.c (bfd_section_from_r_symndx): Delete, replace with.. + (bfd_sym_from_r_symndx): ..new function. + * elf32-arm.c: Update all uses of struct sym_sec_cache and + bfd_section_from_r_symndx to new struct and function. + * elf32-bfin.c: Likewise. + * elf32-hppa.c: Likewise. + * elf32-i386.c: Likewise. + * elf32-m32r.c: Likewise. + * elf32-m68hc1x.c: Likewise. + * elf32-m68hc1x.h: Likewise. + * elf32-m68k.c: Likewise. + * elf32-ppc.c: Likewise. + * elf32-s390.c: Likewise. + * elf32-sh.c: Likewise. + * elf64-ppc.c: Likewise. + * elf64-s390.c: Likewise. + * elf64-x86-64.c: Likewise. + * elfxx-sparc.c: Likewise. + * elfxx-sparc.h: Likewise. + 2009-06-18 H.J. Lu * elf32-i386.c (elf_i386_check_relocs): Cache or free isymbuf. diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index d1a23ad999..764ee68b2a 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -493,14 +493,14 @@ struct elf_link_hash_table #define is_elf_hash_table(htab) \ (((struct bfd_link_hash_table *) (htab))->type == bfd_link_elf_hash_table) -/* Used by bfd_section_from_r_symndx to cache a small number of local - symbol to section mappings. */ +/* Used by bfd_sym_from_r_symndx to cache a small number of local + symbols. */ #define LOCAL_SYM_CACHE_SIZE 32 -struct sym_sec_cache +struct sym_cache { bfd *abfd; unsigned long indx[LOCAL_SYM_CACHE_SIZE]; - unsigned int shndx[LOCAL_SYM_CACHE_SIZE]; + Elf_Internal_Sym sym[LOCAL_SYM_CACHE_SIZE]; }; /* Constant information held for an ELF backend. */ @@ -1807,8 +1807,8 @@ extern bfd_boolean bfd_section_from_phdr extern int _bfd_elf_symbol_from_bfd_symbol (bfd *, asymbol **); -extern asection *bfd_section_from_r_symndx - (bfd *, struct sym_sec_cache *, asection *, unsigned long); +extern Elf_Internal_Sym *bfd_sym_from_r_symndx + (struct sym_cache *, bfd *, unsigned long); extern asection *bfd_section_from_elf_index (bfd *, unsigned int); extern struct bfd_strtab_hash *_bfd_elf_stringtab_init diff --git a/bfd/elf.c b/bfd/elf.c index c7151be4dd..e377d68fa4 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -1921,28 +1921,24 @@ bfd_section_from_shdr (bfd *abfd, unsigned int shindex) return TRUE; } -/* Return the section for the local symbol specified by ABFD, R_SYMNDX. - Return SEC for sections that have no elf section, and NULL on error. */ +/* Return the local symbol specified by ABFD, R_SYMNDX. */ -asection * -bfd_section_from_r_symndx (bfd *abfd, - struct sym_sec_cache *cache, - asection *sec, - unsigned long r_symndx) +Elf_Internal_Sym * +bfd_sym_from_r_symndx (struct sym_cache *cache, + bfd *abfd, + unsigned long r_symndx) { unsigned int ent = r_symndx % LOCAL_SYM_CACHE_SIZE; - asection *s; if (cache->abfd != abfd || cache->indx[ent] != r_symndx) { Elf_Internal_Shdr *symtab_hdr; unsigned char esym[sizeof (Elf64_External_Sym)]; Elf_External_Sym_Shndx eshndx; - Elf_Internal_Sym isym; symtab_hdr = &elf_tdata (abfd)->symtab_hdr; if (bfd_elf_get_elf_syms (abfd, symtab_hdr, 1, r_symndx, - &isym, esym, &eshndx) == NULL) + &cache->sym[ent], esym, &eshndx) == NULL) return NULL; if (cache->abfd != abfd) @@ -1951,14 +1947,9 @@ bfd_section_from_r_symndx (bfd *abfd, cache->abfd = abfd; } cache->indx[ent] = r_symndx; - cache->shndx[ent] = isym.st_shndx; } - s = bfd_section_from_elf_index (abfd, cache->shndx[ent]); - if (s != NULL) - return s; - - return sec; + return &cache->sym[ent]; } /* Given an ELF section number, retrieve the corresponding BFD diff --git a/bfd/elf32-arm.c b/bfd/elf32-arm.c index 45a94c7015..bdb895af60 100644 --- a/bfd/elf32-arm.c +++ b/bfd/elf32-arm.c @@ -2618,8 +2618,8 @@ struct elf32_arm_link_hash_table bfd_vma offset; } tls_ldm_got; - /* Small local sym to section mapping cache. */ - struct sym_sec_cache sym_sec; + /* Small local sym cache. */ + struct sym_cache sym_cache; /* For convenience in allocate_dynrelocs. */ bfd * obfd; @@ -2921,7 +2921,7 @@ elf32_arm_link_hash_table_create (bfd *abfd) ret->vxworks_p = 0; ret->symbian_p = 0; ret->use_rel = 1; - ret->sym_sec.abfd = NULL; + ret->sym_cache.abfd = NULL; ret->obfd = abfd; ret->tls_ldm_got.refcount = 0; ret->stub_bfd = NULL; @@ -10836,15 +10836,19 @@ elf32_arm_check_relocs (bfd *abfd, struct bfd_link_info *info, /* Track dynamic relocs needed for local syms too. We really need local syms available to do this easily. Oh well. */ - asection *s; void *vpp; + Elf_Internal_Sym *isym; - s = bfd_section_from_r_symndx (abfd, &htab->sym_sec, - sec, r_symndx); - if (s == NULL) + isym = bfd_sym_from_r_symndx (&htab->sym_cache, + abfd, r_symndx); + if (isym == NULL) return FALSE; + s = bfd_section_from_elf_index (abfd, isym->st_shndx); + if (s == NULL) + s = sec; + vpp = &elf_section_data (s)->local_dynrel; head = (struct elf32_arm_relocs_copied **) vpp; } diff --git a/bfd/elf32-bfin.c b/bfd/elf32-bfin.c index c7ce2584f0..647087a9a8 100644 --- a/bfd/elf32-bfin.c +++ b/bfd/elf32-bfin.c @@ -4966,8 +4966,8 @@ struct bfin_link_hash_table { struct elf_link_hash_table root; - /* Small local sym to section mapping cache. */ - struct sym_sec_cache sym_sec; + /* Small local sym cache. */ + struct sym_cache sym_cache; }; #define bfin_hash_entry(ent) ((struct bfin_link_hash_entry *) (ent)) @@ -5013,7 +5013,7 @@ bfin_link_hash_table_create (bfd * abfd) return NULL; } - ret->sym_sec.abfd = NULL; + ret->sym_cache.abfd = NULL; return &ret->root.root; } diff --git a/bfd/elf32-hppa.c b/bfd/elf32-hppa.c index 20be2e7952..cac0a215f4 100644 --- a/bfd/elf32-hppa.c +++ b/bfd/elf32-hppa.c @@ -301,8 +301,8 @@ struct elf32_hppa_link_hash_table /* Set if we need a .plt stub to support lazy dynamic linking. */ unsigned int need_plt_stub:1; - /* Small local sym to section mapping cache. */ - struct sym_sec_cache sym_sec; + /* Small local sym cache. */ + struct sym_cache sym_cache; /* Data for LDM relocations. */ union @@ -460,7 +460,7 @@ elf32_hppa_link_hash_table_create (bfd *abfd) htab->has_17bit_branch = 0; htab->has_22bit_branch = 0; htab->need_plt_stub = 0; - htab->sym_sec.abfd = NULL; + htab->sym_cache.abfd = NULL; htab->tls_ldm_got.refcount = 0; return &htab->etab.root; @@ -1522,15 +1522,19 @@ elf32_hppa_check_relocs (bfd *abfd, /* Track dynamic relocs needed for local syms too. We really need local syms available to do this easily. Oh well. */ - asection *sr; void *vpp; + Elf_Internal_Sym *isym; - sr = bfd_section_from_r_symndx (abfd, &htab->sym_sec, - sec, r_symndx); - if (sr == NULL) + isym = bfd_sym_from_r_symndx (&htab->sym_cache, + abfd, r_symndx); + if (isym == NULL) return FALSE; + sr = bfd_section_from_elf_index (abfd, isym->st_shndx); + if (sr == NULL) + sr = sec; + vpp = &elf_section_data (sr)->local_dynrel; hdh_head = (struct elf32_hppa_dyn_reloc_entry **) vpp; } diff --git a/bfd/elf32-i386.c b/bfd/elf32-i386.c index 8dd3b8a68c..ab4f53dbe4 100644 --- a/bfd/elf32-i386.c +++ b/bfd/elf32-i386.c @@ -674,8 +674,8 @@ struct elf_i386_link_hash_table section, plus whatever space is used by the jump slots. */ bfd_vma sgotplt_jump_table_size; - /* Small local sym to section mapping cache. */ - struct sym_sec_cache sym_sec; + /* Small local sym cache. */ + struct sym_cache sym_cache; /* _TLS_MODULE_BASE_ symbol. */ struct bfd_link_hash_entry *tls_module_base; @@ -819,7 +819,7 @@ elf_i386_link_hash_table_create (bfd *abfd) ret->tls_ldm_got.refcount = 0; ret->next_tls_desc_index = 0; ret->sgotplt_jump_table_size = 0; - ret->sym_sec.abfd = NULL; + ret->sym_cache.abfd = NULL; ret->is_vxworks = 0; ret->srelplt2 = NULL; ret->plt0_pad_byte = 0; @@ -1650,16 +1650,21 @@ elf_i386_check_relocs (bfd *abfd, } else { - void **vpp; /* Track dynamic relocs needed for local syms too. We really need local syms available to do this easily. Oh well. */ - + void **vpp; asection *s; - s = bfd_section_from_r_symndx (abfd, &htab->sym_sec, - sec, r_symndx); + Elf_Internal_Sym *isym; + + isym = bfd_sym_from_r_symndx (&htab->sym_cache, + abfd, r_symndx); + if (isym == NULL) + return FALSE; + + s = bfd_section_from_elf_index (abfd, isym->st_shndx); if (s == NULL) - goto error_return; + s = sec; vpp = &elf_section_data (s)->local_dynrel; head = (struct elf_dyn_relocs **)vpp; diff --git a/bfd/elf32-m32r.c b/bfd/elf32-m32r.c index fd67e057d7..651e6d5383 100644 --- a/bfd/elf32-m32r.c +++ b/bfd/elf32-m32r.c @@ -1526,8 +1526,8 @@ struct elf_m32r_link_hash_table asection *sdynbss; asection *srelbss; - /* Small local sym to section mapping cache. */ - struct sym_sec_cache sym_sec; + /* Small local sym cache. */ + struct sym_cache sym_cache; }; /* Traverse an m32r ELF linker hash table. */ @@ -1604,7 +1604,7 @@ m32r_elf_link_hash_table_create (bfd *abfd) ret->srelplt = NULL; ret->sdynbss = NULL; ret->srelbss = NULL; - ret->sym_sec.abfd = NULL; + ret->sym_cache.abfd = NULL; return &ret->root.root; } @@ -3941,14 +3941,19 @@ m32r_elf_check_relocs (bfd *abfd, head = &((struct elf_m32r_link_hash_entry *) h)->dyn_relocs; else { + /* Track dynamic relocs needed for local syms too. */ asection *s; void *vpp; + Elf_Internal_Sym *isym; - /* Track dynamic relocs needed for local syms too. */ - s = bfd_section_from_r_symndx (abfd, &htab->sym_sec, - sec, r_symndx); - if (s == NULL) - return FALSE; + isym = bfd_sym_from_r_symndx (&htab->sym_cache, + abfd, r_symndx); + if (isym == NULL) + return FALSE; + + s = bfd_section_from_elf_index (abfd, isym->st_shndx); + if (s == NULL) + s = sec; vpp = &elf_section_data (s)->local_dynrel; head = (struct elf_m32r_dyn_relocs **) vpp; diff --git a/bfd/elf32-m68hc1x.c b/bfd/elf32-m68hc1x.c index bcc0b87b95..544db35b7d 100644 --- a/bfd/elf32-m68hc1x.c +++ b/bfd/elf32-m68hc1x.c @@ -95,7 +95,7 @@ m68hc11_elf_hash_table_create (bfd *abfd) ret->stub_bfd = NULL; ret->stub_section = 0; ret->add_stub_section = NULL; - ret->sym_sec.abfd = NULL; + ret->sym_cache.abfd = NULL; return ret; } diff --git a/bfd/elf32-m68hc1x.h b/bfd/elf32-m68hc1x.h index 2bf636d6db..677dab1c3e 100644 --- a/bfd/elf32-m68hc1x.h +++ b/bfd/elf32-m68hc1x.h @@ -120,8 +120,8 @@ struct m68hc11_elf_link_hash_table int top_index; asection **input_list; - /* Small local sym to section mapping cache. */ - struct sym_sec_cache sym_sec; + /* Small local sym cache. */ + struct sym_cache sym_cache; bfd_boolean (* size_one_stub) PARAMS((struct bfd_hash_entry*, void*)); bfd_boolean (* build_one_stub) PARAMS((struct bfd_hash_entry*, void*)); diff --git a/bfd/elf32-m68k.c b/bfd/elf32-m68k.c index 542501bbf8..2957db0740 100644 --- a/bfd/elf32-m68k.c +++ b/bfd/elf32-m68k.c @@ -909,8 +909,8 @@ struct elf_m68k_link_hash_table { struct elf_link_hash_table root; - /* Small local sym to section mapping cache. */ - struct sym_sec_cache sym_sec; + /* Small local sym cache. */ + struct sym_cache sym_cache; /* The PLT format used by this link, or NULL if the format has not yet been chosen. */ @@ -989,7 +989,7 @@ elf_m68k_link_hash_table_create (abfd) return NULL; } - ret->sym_sec.abfd = NULL; + ret->sym_cache.abfd = NULL; ret->plt_info = NULL; ret->local_gp_p = FALSE; ret->use_neg_got_offsets_p = FALSE; @@ -2793,13 +2793,17 @@ elf_m68k_check_relocs (abfd, info, sec, relocs) { asection *s; void *vpp; + Elf_Internal_Sym *isym; - s = (bfd_section_from_r_symndx - (abfd, &elf_m68k_hash_table (info)->sym_sec, - sec, r_symndx)); - if (s == NULL) + isym = bfd_sym_from_r_symndx (&elf_m68k_hash_table (info)->sym_cache, + abfd, r_symndx); + if (isym == NULL) return FALSE; + s = bfd_section_from_elf_index (abfd, isym->st_shndx); + if (s == NULL) + s = sec; + vpp = &elf_section_data (s)->local_dynrel; head = (struct elf_m68k_pcrel_relocs_copied **) vpp; } diff --git a/bfd/elf32-ppc.c b/bfd/elf32-ppc.c index c7ac2a134d..4210e24d89 100644 --- a/bfd/elf32-ppc.c +++ b/bfd/elf32-ppc.c @@ -2735,8 +2735,8 @@ struct ppc_elf_link_hash_table /* The size of the first PLT entry. */ int plt_initial_entry_size; - /* Small local sym to section mapping cache. */ - struct sym_sec_cache sym_sec; + /* Small local sym cache. */ + struct sym_cache sym_cache; }; /* Get the PPC ELF linker hash table from a link_info structure. */ @@ -3713,9 +3713,14 @@ ppc_elf_check_relocs (bfd *abfd, reliably deduce the GOT pointer value needed for PLT call stubs. */ asection *s; + Elf_Internal_Sym *isym; - s = bfd_section_from_r_symndx (abfd, &htab->sym_sec, sec, - r_symndx); + isym = bfd_sym_from_r_symndx (&htab->sym_cache, + abfd, r_symndx); + if (isym == NULL) + return FALSE; + + s = bfd_section_from_elf_index (abfd, isym->st_shndx); if (s == got2) { htab->plt_type = PLT_OLD; @@ -3843,15 +3848,19 @@ ppc_elf_check_relocs (bfd *abfd, /* Track dynamic relocs needed for local syms too. We really need local syms available to do this easily. Oh well. */ - asection *s; void *vpp; + Elf_Internal_Sym *isym; - s = bfd_section_from_r_symndx (abfd, &htab->sym_sec, - sec, r_symndx); - if (s == NULL) + isym = bfd_sym_from_r_symndx (&htab->sym_cache, + abfd, r_symndx); + if (isym == NULL) return FALSE; + s = bfd_section_from_elf_index (abfd, isym->st_shndx); + if (s == NULL) + s = sec; + vpp = &elf_section_data (s)->local_dynrel; head = (struct ppc_elf_dyn_relocs **) vpp; } diff --git a/bfd/elf32-s390.c b/bfd/elf32-s390.c index 531f9e6a85..170b1f9daf 100644 --- a/bfd/elf32-s390.c +++ b/bfd/elf32-s390.c @@ -730,8 +730,8 @@ struct elf_s390_link_hash_table bfd_vma offset; } tls_ldm_got; - /* Small local sym to section mapping cache. */ - struct sym_sec_cache sym_sec; + /* Small local sym cache. */ + struct sym_cache sym_cache; }; /* Get the s390 ELF linker hash table from a link_info structure. */ @@ -800,7 +800,7 @@ elf_s390_link_hash_table_create (abfd) ret->sdynbss = NULL; ret->srelbss = NULL; ret->tls_ldm_got.refcount = 0; - ret->sym_sec.abfd = NULL; + ret->sym_cache.abfd = NULL; return &ret->elf.root; } @@ -1294,12 +1294,17 @@ elf_s390_check_relocs (abfd, info, sec, relocs) easily. Oh well. */ asection *s; void *vpp; + Elf_Internal_Sym *isym; - s = bfd_section_from_r_symndx (abfd, &htab->sym_sec, - sec, r_symndx); - if (s == NULL) + isym = bfd_sym_from_r_symndx (&htab->sym_cache, + abfd, r_symndx); + if (isym == NULL) return FALSE; + s = bfd_section_from_elf_index (abfd, isym->st_shndx); + if (s == NULL) + s = sec; + vpp = &elf_section_data (s)->local_dynrel; head = (struct elf_s390_dyn_relocs **) vpp; } diff --git a/bfd/elf32-sh.c b/bfd/elf32-sh.c index 555d900f64..eeeca5422c 100644 --- a/bfd/elf32-sh.c +++ b/bfd/elf32-sh.c @@ -2187,8 +2187,8 @@ struct elf_sh_link_hash_table /* The (unloaded but important) VxWorks .rela.plt.unloaded section. */ asection *srelplt2; - /* Small local sym to section mapping cache. */ - struct sym_sec_cache sym_sec; + /* Small local sym cache. */ + struct sym_cache sym_cache; /* A counter or offset to track a TLS got entry. */ union @@ -2281,7 +2281,7 @@ sh_elf_link_hash_table_create (bfd *abfd) ret->sdynbss = NULL; ret->srelbss = NULL; ret->srelplt2 = NULL; - ret->sym_sec.abfd = NULL; + ret->sym_cache.abfd = NULL; ret->tls_ldm_got.refcount = 0; ret->plt_info = NULL; ret->vxworks_p = vxworks_object_p (abfd); @@ -5203,15 +5203,20 @@ sh_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, asection *sec, head = &((struct elf_sh_link_hash_entry *) h)->dyn_relocs; else { + /* Track dynamic relocs needed for local syms too. */ asection *s; void *vpp; + Elf_Internal_Sym *isym; - /* Track dynamic relocs needed for local syms too. */ - s = bfd_section_from_r_symndx (abfd, &htab->sym_sec, - sec, r_symndx); - if (s == NULL) + isym = bfd_sym_from_r_symndx (&htab->sym_cache, + abfd, r_symndx); + if (isym == NULL) return FALSE; + s = bfd_section_from_elf_index (abfd, isym->st_shndx); + if (s == NULL) + s = sec; + vpp = &elf_section_data (s)->local_dynrel; head = (struct elf_sh_dyn_relocs **) vpp; } diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index e68edf1d37..04f21eeeaf 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -3671,8 +3671,8 @@ struct ppc_link_hash_table /* Incremented every time we size stubs. */ unsigned int stub_iteration; - /* Small local sym to section mapping cache. */ - struct sym_sec_cache sym_sec; + /* Small local sym cache. */ + struct sym_cache sym_cache; }; /* Rename some of the generic section flags to better document how they @@ -4897,8 +4897,17 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, dest = h->root.u.def.section; } else - dest = bfd_section_from_r_symndx (abfd, &htab->sym_sec, - sec, r_symndx); + { + Elf_Internal_Sym *isym; + + isym = bfd_sym_from_r_symndx (&htab->sym_cache, + abfd, r_symndx); + if (isym == NULL) + return FALSE; + + dest = bfd_section_from_elf_index (abfd, isym->st_shndx); + } + if (dest != sec) ppc64_elf_section_data (sec)->has_14bit_branch = 1; } @@ -5018,12 +5027,15 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, else { asection *s; + Elf_Internal_Sym *isym; - s = bfd_section_from_r_symndx (abfd, &htab->sym_sec, sec, - r_symndx); - if (s == NULL) + isym = bfd_sym_from_r_symndx (&htab->sym_cache, + abfd, r_symndx); + if (isym == NULL) return FALSE; - else if (s != sec) + + s = bfd_section_from_elf_index (abfd, isym->st_shndx); + if (s != NULL && s != sec) opd_sym_map[rel->r_offset / 8] = s; } } @@ -5119,15 +5131,19 @@ ppc64_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, /* Track dynamic relocs needed for local syms too. We really need local syms available to do this easily. Oh well. */ - asection *s; void *vpp; + Elf_Internal_Sym *isym; - s = bfd_section_from_r_symndx (abfd, &htab->sym_sec, - sec, r_symndx); - if (s == NULL) + isym = bfd_sym_from_r_symndx (&htab->sym_cache, + abfd, r_symndx); + if (isym == NULL) return FALSE; + s = bfd_section_from_elf_index (abfd, isym->st_shndx); + if (s == NULL) + s = sec; + vpp = &elf_section_data (s)->local_dynrel; head = (struct ppc_dyn_relocs **) vpp; } diff --git a/bfd/elf64-s390.c b/bfd/elf64-s390.c index c9bd764a44..eef92d0310 100644 --- a/bfd/elf64-s390.c +++ b/bfd/elf64-s390.c @@ -685,8 +685,8 @@ struct elf_s390_link_hash_table bfd_vma offset; } tls_ldm_got; - /* Small local sym to section mapping cache. */ - struct sym_sec_cache sym_sec; + /* Small local sym cache. */ + struct sym_cache sym_cache; }; /* Get the s390 ELF linker hash table from a link_info structure. */ @@ -755,7 +755,7 @@ elf_s390_link_hash_table_create (abfd) ret->sdynbss = NULL; ret->srelbss = NULL; ret->tls_ldm_got.refcount = 0; - ret->sym_sec.abfd = NULL; + ret->sym_cache.abfd = NULL; return &ret->elf.root; } @@ -1258,15 +1258,19 @@ elf_s390_check_relocs (abfd, info, sec, relocs) /* Track dynamic relocs needed for local syms too. We really need local syms available to do this easily. Oh well. */ - asection *s; void *vpp; + Elf_Internal_Sym *isym; - s = bfd_section_from_r_symndx (abfd, &htab->sym_sec, - sec, r_symndx); - if (s == NULL) + isym = bfd_sym_from_r_symndx (&htab->sym_cache, + abfd, r_symndx); + if (isym == NULL) return FALSE; + s = bfd_section_from_elf_index (abfd, isym->st_shndx); + if (s == NULL) + s = sec; + vpp = &elf_section_data (s)->local_dynrel; head = (struct elf_s390_dyn_relocs **) vpp; } diff --git a/bfd/elf64-x86-64.c b/bfd/elf64-x86-64.c index 581d544013..f1cf825d29 100644 --- a/bfd/elf64-x86-64.c +++ b/bfd/elf64-x86-64.c @@ -487,8 +487,8 @@ struct elf64_x86_64_link_hash_table /* The amount of space used by the jump slots in the GOT. */ bfd_vma sgotplt_jump_table_size; - /* Small local sym to section mapping cache. */ - struct sym_sec_cache sym_sec; + /* Small local sym cache. */ + struct sym_cache sym_cache; /* _TLS_MODULE_BASE_ symbol. */ struct bfd_link_hash_entry *tls_module_base; @@ -629,7 +629,7 @@ elf64_x86_64_link_hash_table_create (bfd *abfd) ret->sdynbss = NULL; ret->srelbss = NULL; - ret->sym_sec.abfd = NULL; + ret->sym_cache.abfd = NULL; ret->tlsdesc_plt = 0; ret->tlsdesc_got = 0; ret->tls_ld_got.refcount = 0; @@ -1478,16 +1478,21 @@ elf64_x86_64_check_relocs (bfd *abfd, struct bfd_link_info *info, } else { - void **vpp; /* Track dynamic relocs needed for local syms too. We really need local syms available to do this easily. Oh well. */ - asection *s; - s = bfd_section_from_r_symndx (abfd, &htab->sym_sec, - sec, r_symndx); + void **vpp; + Elf_Internal_Sym *isym; + + isym = bfd_sym_from_r_symndx (&htab->sym_cache, + abfd, r_symndx); + if (isym == NULL) + return FALSE; + + s = bfd_section_from_elf_index (abfd, isym->st_shndx); if (s == NULL) - goto error_return; + s = sec; /* Beware of type punned pointers vs strict aliasing rules. */ diff --git a/bfd/elfxx-sparc.c b/bfd/elfxx-sparc.c index 9ec46179be..f5fe41fcbc 100644 --- a/bfd/elfxx-sparc.c +++ b/bfd/elfxx-sparc.c @@ -1465,15 +1465,19 @@ _bfd_sparc_elf_check_relocs (bfd *abfd, struct bfd_link_info *info, /* Track dynamic relocs needed for local syms too. We really need local syms available to do this easily. Oh well. */ - asection *s; void *vpp; + Elf_Internal_Sym *isym; - s = bfd_section_from_r_symndx (abfd, &htab->sym_sec, - sec, r_symndx); - if (s == NULL) + isym = bfd_sym_from_r_symndx (&htab->sym_cache, + abfd, r_symndx); + if (isym == NULL) return FALSE; + s = bfd_section_from_elf_index (abfd, isym->st_shndx); + if (s == NULL) + s = sec; + vpp = &elf_section_data (s)->local_dynrel; head = (struct _bfd_sparc_elf_dyn_relocs **) vpp; } diff --git a/bfd/elfxx-sparc.h b/bfd/elfxx-sparc.h index 87ec62a718..505f134a7b 100644 --- a/bfd/elfxx-sparc.h +++ b/bfd/elfxx-sparc.h @@ -59,8 +59,8 @@ struct _bfd_sparc_elf_link_hash_table bfd_vma offset; } tls_ldm_got; - /* Small local sym to section mapping cache. */ - struct sym_sec_cache sym_sec; + /* Small local sym cache. */ + struct sym_cache sym_cache; /* True if the target system is VxWorks. */ int is_vxworks;