(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 Alan Modra <amodra@bigpond.net.au>
+
+ * 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 <hongjiu.lu@intel.com>
* elf32-i386.c (elf_i386_check_relocs): Cache or free isymbuf.
#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];
};
\f
/* Constant information held for an ELF backend. */
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
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)
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
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;
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;
/* 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;
}
{
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))
return NULL;
}
- ret->sym_sec.abfd = NULL;
+ ret->sym_cache.abfd = NULL;
return &ret->root.root;
}
/* 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
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;
/* 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;
}
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;
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;
}
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;
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. */
ret->srelplt = NULL;
ret->sdynbss = NULL;
ret->srelbss = NULL;
- ret->sym_sec.abfd = NULL;
+ ret->sym_cache.abfd = NULL;
return &ret->root.root;
}
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;
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;
}
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*));
{
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. */
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;
{
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;
}
/* 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. */
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;
/* 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;
}
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. */
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;
}
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;
}
/* 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
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);
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;
}
/* 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
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;
}
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;
}
}
/* 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;
}
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. */
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;
}
/* 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;
}
/* 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;
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;
}
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. */
/* 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;
}
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;