mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-08-06 06:45:56 +08:00
* elf-bfd.h (struct elf_reloc_cookie): Remove locsym_shndx,
change type of locsyms. (bfd_elf_get_elf_syms): Declare. * elf.c (bfd_elf_get_elf_syms): New function. (group_signature): Use bfd_elf_get_elf_syms. (bfd_section_from_r_symndx): Likewise. * elfcode.h (elf_slurp_symbol_table): Likewise. * elflink.h (elf_link_is_defined_archive_symbol): Likewise. (elf_link_add_object_symbols): Likewise. Reorganise to increase locality of various data structures. Properly free internal relocs. (elf_bfd_final_link): Properly free internal relocs. (elf_link_check_versioned_symbol): Use bfd_elf_get_elf_syms. (elf_link_input_bfd): Likewise. (elf_gc_mark): Likewise. Properly free internal relocs. (elf_gc_sweep): Properly free internal relocs. (elf_reloc_symbol_deleted_p): No need to swap syms in. (elf_bfd_discard_info): Use bfd_elf_get_elf_syms. Properly free internal relocs. * elf-m10200.c (mn10200_elf_relax_section): Use bfd_elf_get_elf_syms. Properly free possibly cached info. (mn10200_elf_relax_delete_bytes): Remove symbol swapping code. (mn10200_elf_symbol_address_p): Pass in internal syms. Remove symbol swapping code. (mn10200_elf_get_relocated_section_contents): Use bfd_elf_get_elf_syms. Properly free possibly cached info. * elf-m10300.c (mn10300_elf_relax_section): As above for elf-m10200.c. (mn10300_elf_relax_delete_bytes): Likewise. (mn10300_elf_symbol_address_p): Likewise. (mn10300_elf_get_relocated_section_contents): Likewise. * elf32-h8300.c (elf32_h8_relax_section): As above for elf-m10200.c. (elf32_h8_relax_delete_bytes): Likewise. (elf32_h8_symbol_address_p): Likewise. (elf32_h8_get_relocated_section_contents): Likewise. * elf32-m32r.c (m32r_elf_relax_section): As above for elf-m10200.c. (m32r_elf_relax_delete_bytes): Likewise. (m32r_elf_get_relocated_section_contents): Likewise. * elf32-sh.c (sh_elf_reloc_loop): Free section contents using elf_section_data to determine whether cached. (sh_elf_relax_section): As above for elf-m10200.c. (sh_elf_relax_delete_bytes): Likewise. (sh_elf_get_relocated_section_contents): Likewise. * elf32-xstormy16.c (xstormy16_elf_relax_section): As above. * elf64-alpha.c (elf64_alpha_relax_section): As above. Also delay reading of local syms. * elf64-mmix.c (mmix_elf_relax_section): Likewise. * elf64-sh64.c (sh_elf64_get_relocated_section_contents): As above. * elfxx-ia64.c (elfNN_ia64_relax_section): As above. * elfxx-mips.c (_bfd_mips_elf_check_relocs): Properly free internal relocs. * elf32-arm.h (bfd_elf32_arm_process_before_allocation): Properly free internal relocs and section contents. Don't read symbols. * elf32-hppa.c (get_local_syms): Use bfd_elf_get_elf_syms. (elf32_hppa_size_stubs): Don't free local syms. * elf32-m68k.c (bfd_m68k_elf32_create_embedded_relocs): Delay reading of local syms. Use bfd_elf_get_elf_syms. Properly free possibly cached info. * elf32-mips.c (bfd_mips_elf32_create_embedded_relocs): Likewise. * elf64-hppa.c (elf64_hppa_check_relocs): Use bfd_elf_get_elf_syms. * elf64-ppc.c (struct ppc_link_hash_table): Delete bfd_count and all_local_syms. (get_local_syms): Delete function. (edit_opd): Use bfd_elf_get_elf_syms. Free on error exit. Cache on exit. (ppc64_elf_size_stubs): Use bfd_elf_get_elf_syms. Free/cache on exit.
This commit is contained in:
173
bfd/elf.c
173
bfd/elf.c
@ -352,6 +352,107 @@ bfd_elf_string_from_elf_section (abfd, shindex, strindex)
|
||||
return ((char *) hdr->contents) + strindex;
|
||||
}
|
||||
|
||||
/* Read and convert symbols to internal format.
|
||||
SYMCOUNT specifies the number of symbols to read, starting from
|
||||
symbol SYMOFFSET. If any of INTSYM_BUF, EXTSYM_BUF or EXTSHNDX_BUF
|
||||
are non-NULL, they are used to store the internal symbols, external
|
||||
symbols, and symbol section index extensions, respectively. */
|
||||
|
||||
Elf_Internal_Sym *
|
||||
bfd_elf_get_elf_syms (ibfd, symtab_hdr, symcount, symoffset,
|
||||
intsym_buf, extsym_buf, extshndx_buf)
|
||||
bfd *ibfd;
|
||||
Elf_Internal_Shdr *symtab_hdr;
|
||||
size_t symcount;
|
||||
size_t symoffset;
|
||||
Elf_Internal_Sym *intsym_buf;
|
||||
PTR extsym_buf;
|
||||
Elf_External_Sym_Shndx *extshndx_buf;
|
||||
{
|
||||
Elf_Internal_Shdr *shndx_hdr;
|
||||
PTR alloc_ext;
|
||||
const PTR esym;
|
||||
Elf_External_Sym_Shndx *alloc_extshndx;
|
||||
Elf_External_Sym_Shndx *shndx;
|
||||
Elf_Internal_Sym *isym;
|
||||
Elf_Internal_Sym *isymend;
|
||||
struct elf_backend_data *bed;
|
||||
size_t extsym_size;
|
||||
bfd_size_type amt;
|
||||
file_ptr pos;
|
||||
|
||||
if (symcount == 0)
|
||||
return intsym_buf;
|
||||
|
||||
/* Normal syms might have section extension entries. */
|
||||
shndx_hdr = NULL;
|
||||
if (symtab_hdr == &elf_tdata (ibfd)->symtab_hdr)
|
||||
shndx_hdr = &elf_tdata (ibfd)->symtab_shndx_hdr;
|
||||
|
||||
/* Read the symbols. */
|
||||
alloc_ext = NULL;
|
||||
alloc_extshndx = NULL;
|
||||
bed = get_elf_backend_data (ibfd);
|
||||
extsym_size = bed->s->sizeof_sym;
|
||||
amt = symcount * extsym_size;
|
||||
pos = symtab_hdr->sh_offset + symoffset * extsym_size;
|
||||
if (extsym_buf == NULL)
|
||||
{
|
||||
alloc_ext = bfd_malloc (amt);
|
||||
extsym_buf = alloc_ext;
|
||||
}
|
||||
if (extsym_buf == NULL
|
||||
|| bfd_seek (ibfd, pos, SEEK_SET) != 0
|
||||
|| bfd_bread (extsym_buf, amt, ibfd) != amt)
|
||||
{
|
||||
intsym_buf = NULL;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (shndx_hdr == NULL || shndx_hdr->sh_size == 0)
|
||||
extshndx_buf = NULL;
|
||||
else
|
||||
{
|
||||
amt = symcount * sizeof (Elf_External_Sym_Shndx);
|
||||
pos = shndx_hdr->sh_offset + symoffset * sizeof (Elf_External_Sym_Shndx);
|
||||
if (extshndx_buf == NULL)
|
||||
{
|
||||
alloc_extshndx = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
|
||||
extshndx_buf = alloc_extshndx;
|
||||
}
|
||||
if (extshndx_buf == NULL
|
||||
|| bfd_seek (ibfd, pos, SEEK_SET) != 0
|
||||
|| bfd_bread (extshndx_buf, amt, ibfd) != amt)
|
||||
{
|
||||
intsym_buf = NULL;
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
if (intsym_buf == NULL)
|
||||
{
|
||||
bfd_size_type amt = symcount * sizeof (Elf_Internal_Sym);
|
||||
intsym_buf = (Elf_Internal_Sym *) bfd_malloc (amt);
|
||||
if (intsym_buf == NULL)
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Convert the symbols to internal form. */
|
||||
isymend = intsym_buf + symcount;
|
||||
for (esym = extsym_buf, isym = intsym_buf, shndx = extshndx_buf;
|
||||
isym < isymend;
|
||||
esym += extsym_size, isym++, shndx = shndx != NULL ? shndx + 1 : NULL)
|
||||
(*bed->s->swap_symbol_in) (ibfd, esym, (const PTR) shndx, isym);
|
||||
|
||||
out:
|
||||
if (alloc_ext != NULL)
|
||||
free (alloc_ext);
|
||||
if (alloc_extshndx != NULL)
|
||||
free (alloc_extshndx);
|
||||
|
||||
return intsym_buf;
|
||||
}
|
||||
|
||||
/* Elf_Internal_Shdr->contents is an array of these for SHT_GROUP
|
||||
sections. The first element is the flags, the rest are section
|
||||
pointers. */
|
||||
@ -369,11 +470,7 @@ group_signature (abfd, ghdr)
|
||||
bfd *abfd;
|
||||
Elf_Internal_Shdr *ghdr;
|
||||
{
|
||||
struct elf_backend_data *bed;
|
||||
file_ptr pos;
|
||||
bfd_size_type amt;
|
||||
Elf_Internal_Shdr *hdr;
|
||||
Elf_Internal_Shdr *shndx_hdr;
|
||||
unsigned char esym[sizeof (Elf64_External_Sym)];
|
||||
Elf_External_Sym_Shndx eshndx;
|
||||
Elf_Internal_Sym isym;
|
||||
@ -386,29 +483,10 @@ group_signature (abfd, ghdr)
|
||||
|
||||
/* Go read the symbol. */
|
||||
hdr = &elf_tdata (abfd)->symtab_hdr;
|
||||
bed = get_elf_backend_data (abfd);
|
||||
amt = bed->s->sizeof_sym;
|
||||
pos = hdr->sh_offset + ghdr->sh_info * amt;
|
||||
if (bfd_seek (abfd, pos, SEEK_SET) != 0
|
||||
|| bfd_bread (esym, amt, abfd) != amt)
|
||||
if (bfd_elf_get_elf_syms (abfd, hdr, 1, ghdr->sh_info,
|
||||
&isym, esym, &eshndx) == NULL)
|
||||
return NULL;
|
||||
|
||||
/* And possibly the symbol section index extension. */
|
||||
shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
|
||||
if (elf_elfsections (abfd) != NULL
|
||||
&& elf_elfsections (abfd)[shndx_hdr->sh_link] == hdr)
|
||||
{
|
||||
amt = sizeof (Elf_External_Sym_Shndx);
|
||||
pos = shndx_hdr->sh_offset + ghdr->sh_info * amt;
|
||||
if (bfd_seek (abfd, pos, SEEK_SET) != 0
|
||||
|| bfd_bread ((PTR) &eshndx, amt, abfd) != amt)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Convert to internal format. */
|
||||
(*bed->s->swap_symbol_in) (abfd, (const PTR *) &esym, (const PTR *) &eshndx,
|
||||
&isym);
|
||||
|
||||
/* Look up the symbol name. */
|
||||
iname = isym.st_name;
|
||||
shindex = hdr->sh_link;
|
||||
@ -1976,50 +2054,19 @@ bfd_section_from_r_symndx (abfd, cache, sec, r_symndx)
|
||||
asection *sec;
|
||||
unsigned long r_symndx;
|
||||
{
|
||||
unsigned char esym_shndx[4];
|
||||
unsigned int isym_shndx;
|
||||
Elf_Internal_Shdr *symtab_hdr;
|
||||
file_ptr pos;
|
||||
bfd_size_type amt;
|
||||
unsigned char esym[sizeof (Elf64_External_Sym)];
|
||||
Elf_External_Sym_Shndx eshndx;
|
||||
Elf_Internal_Sym isym;
|
||||
unsigned int ent = r_symndx % LOCAL_SYM_CACHE_SIZE;
|
||||
|
||||
if (cache->abfd == abfd && cache->indx[ent] == r_symndx)
|
||||
return cache->sec[ent];
|
||||
|
||||
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
|
||||
pos = symtab_hdr->sh_offset;
|
||||
if (get_elf_backend_data (abfd)->s->sizeof_sym
|
||||
== sizeof (Elf64_External_Sym))
|
||||
{
|
||||
pos += r_symndx * sizeof (Elf64_External_Sym);
|
||||
pos += offsetof (Elf64_External_Sym, st_shndx);
|
||||
amt = sizeof (((Elf64_External_Sym *) 0)->st_shndx);
|
||||
}
|
||||
else
|
||||
{
|
||||
pos += r_symndx * sizeof (Elf32_External_Sym);
|
||||
pos += offsetof (Elf32_External_Sym, st_shndx);
|
||||
amt = sizeof (((Elf32_External_Sym *) 0)->st_shndx);
|
||||
}
|
||||
if (bfd_seek (abfd, pos, SEEK_SET) != 0
|
||||
|| bfd_bread ((PTR) esym_shndx, amt, abfd) != amt)
|
||||
if (bfd_elf_get_elf_syms (abfd, symtab_hdr, 1, r_symndx,
|
||||
&isym, esym, &eshndx) == NULL)
|
||||
return NULL;
|
||||
isym_shndx = H_GET_16 (abfd, esym_shndx);
|
||||
|
||||
if (isym_shndx == SHN_XINDEX)
|
||||
{
|
||||
Elf_Internal_Shdr *shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
|
||||
if (shndx_hdr->sh_size != 0)
|
||||
{
|
||||
pos = shndx_hdr->sh_offset;
|
||||
pos += r_symndx * sizeof (Elf_External_Sym_Shndx);
|
||||
amt = sizeof (Elf_External_Sym_Shndx);
|
||||
if (bfd_seek (abfd, pos, SEEK_SET) != 0
|
||||
|| bfd_bread ((PTR) esym_shndx, amt, abfd) != amt)
|
||||
return NULL;
|
||||
isym_shndx = H_GET_32 (abfd, esym_shndx);
|
||||
}
|
||||
}
|
||||
|
||||
if (cache->abfd != abfd)
|
||||
{
|
||||
@ -2028,10 +2075,10 @@ bfd_section_from_r_symndx (abfd, cache, sec, r_symndx)
|
||||
}
|
||||
cache->indx[ent] = r_symndx;
|
||||
cache->sec[ent] = sec;
|
||||
if (isym_shndx < SHN_LORESERVE || isym_shndx > SHN_HIRESERVE)
|
||||
if (isym.st_shndx < SHN_LORESERVE || isym.st_shndx > SHN_HIRESERVE)
|
||||
{
|
||||
asection *s;
|
||||
s = bfd_section_from_elf_index (abfd, isym_shndx);
|
||||
s = bfd_section_from_elf_index (abfd, isym.st_shndx);
|
||||
if (s != NULL)
|
||||
cache->sec[ent] = s;
|
||||
}
|
||||
|
Reference in New Issue
Block a user