mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-29 18:41:27 +00: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:
137
bfd/elfcode.h
137
bfd/elfcode.h
@@ -1133,10 +1133,12 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic)
|
||||
unsigned long symcount; /* Number of external ELF symbols */
|
||||
elf_symbol_type *sym; /* Pointer to current bfd symbol */
|
||||
elf_symbol_type *symbase; /* Buffer for generated bfd symbols */
|
||||
Elf_Internal_Sym i_sym;
|
||||
Elf_External_Sym *x_symp = NULL;
|
||||
Elf_External_Sym_Shndx *x_shndx = NULL;
|
||||
Elf_External_Versym *x_versymp = NULL;
|
||||
Elf_Internal_Sym *isym;
|
||||
Elf_Internal_Sym *isymend;
|
||||
Elf_Internal_Sym *isymbuf = NULL;
|
||||
Elf_External_Versym *xver;
|
||||
Elf_External_Versym *xverbuf = NULL;
|
||||
struct elf_backend_data *ebd;
|
||||
bfd_size_type amt;
|
||||
|
||||
/* Read each raw ELF symbol, converting from external ELF form to
|
||||
@@ -1151,24 +1153,8 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic)
|
||||
|
||||
if (! dynamic)
|
||||
{
|
||||
Elf_Internal_Shdr *shndx_hdr;
|
||||
|
||||
hdr = &elf_tdata (abfd)->symtab_hdr;
|
||||
shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
|
||||
verhdr = NULL;
|
||||
|
||||
/* If we have a SHT_SYMTAB_SHNDX section for the symbol table,
|
||||
read the raw contents. */
|
||||
if (elf_elfsections (abfd) != NULL
|
||||
&& elf_elfsections (abfd)[shndx_hdr->sh_link] == hdr)
|
||||
{
|
||||
amt = shndx_hdr->sh_size;
|
||||
x_shndx = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
|
||||
if (x_shndx == NULL
|
||||
|| bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
|
||||
|| bfd_bread ((PTR) x_shndx, amt, abfd) != amt)
|
||||
goto error_return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1187,39 +1173,24 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic)
|
||||
}
|
||||
}
|
||||
|
||||
if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0)
|
||||
goto error_return;
|
||||
|
||||
ebd = get_elf_backend_data (abfd);
|
||||
symcount = hdr->sh_size / sizeof (Elf_External_Sym);
|
||||
|
||||
if (symcount == 0)
|
||||
sym = symbase = NULL;
|
||||
else
|
||||
{
|
||||
unsigned long i;
|
||||
|
||||
if (bfd_seek (abfd, hdr->sh_offset, SEEK_SET) != 0)
|
||||
goto error_return;
|
||||
isymbuf = bfd_elf_get_elf_syms (abfd, hdr, symcount, 0,
|
||||
NULL, NULL, NULL);
|
||||
if (isymbuf == NULL)
|
||||
return -1;
|
||||
|
||||
amt = symcount;
|
||||
amt *= sizeof (elf_symbol_type);
|
||||
symbase = (elf_symbol_type *) bfd_zalloc (abfd, amt);
|
||||
if (symbase == (elf_symbol_type *) NULL)
|
||||
goto error_return;
|
||||
sym = symbase;
|
||||
|
||||
/* Temporarily allocate room for the raw ELF symbols. */
|
||||
amt = symcount;
|
||||
amt *= sizeof (Elf_External_Sym);
|
||||
x_symp = (Elf_External_Sym *) bfd_malloc (amt);
|
||||
if (x_symp == NULL)
|
||||
goto error_return;
|
||||
|
||||
if (bfd_bread ((PTR) x_symp, amt, abfd) != amt)
|
||||
goto error_return;
|
||||
|
||||
/* Read the raw ELF version symbol information. */
|
||||
|
||||
if (verhdr != NULL
|
||||
&& verhdr->sh_size / sizeof (Elf_External_Versym) != symcount)
|
||||
{
|
||||
@@ -1239,42 +1210,40 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic)
|
||||
if (bfd_seek (abfd, verhdr->sh_offset, SEEK_SET) != 0)
|
||||
goto error_return;
|
||||
|
||||
x_versymp = (Elf_External_Versym *) bfd_malloc (verhdr->sh_size);
|
||||
if (x_versymp == NULL && verhdr->sh_size != 0)
|
||||
xverbuf = (Elf_External_Versym *) bfd_malloc (verhdr->sh_size);
|
||||
if (xverbuf == NULL && verhdr->sh_size != 0)
|
||||
goto error_return;
|
||||
|
||||
if (bfd_bread ((PTR) x_versymp, verhdr->sh_size, abfd)
|
||||
if (bfd_bread ((PTR) xverbuf, verhdr->sh_size, abfd)
|
||||
!= verhdr->sh_size)
|
||||
goto error_return;
|
||||
}
|
||||
|
||||
/* Skip first symbol, which is a null dummy. */
|
||||
for (i = 1; i < symcount; i++)
|
||||
xver = xverbuf;
|
||||
if (xver != NULL)
|
||||
++xver;
|
||||
isymend = isymbuf + symcount;
|
||||
for (isym = isymbuf + 1, sym = symbase; isym < isymend; isym++, sym++)
|
||||
{
|
||||
elf_swap_symbol_in (abfd, (const PTR) (x_symp + i),
|
||||
(const PTR) (x_shndx + (x_shndx ? i : 0)),
|
||||
&i_sym);
|
||||
memcpy (&sym->internal_elf_sym, &i_sym, sizeof (Elf_Internal_Sym));
|
||||
#ifdef ELF_KEEP_EXTSYM
|
||||
memcpy (&sym->native_elf_sym, x_symp + i, sizeof (Elf_External_Sym));
|
||||
#endif
|
||||
memcpy (&sym->internal_elf_sym, isym, sizeof (Elf_Internal_Sym));
|
||||
sym->symbol.the_bfd = abfd;
|
||||
|
||||
sym->symbol.name = bfd_elf_string_from_elf_section (abfd,
|
||||
hdr->sh_link,
|
||||
i_sym.st_name);
|
||||
isym->st_name);
|
||||
|
||||
sym->symbol.value = i_sym.st_value;
|
||||
sym->symbol.value = isym->st_value;
|
||||
|
||||
if (i_sym.st_shndx == SHN_UNDEF)
|
||||
if (isym->st_shndx == SHN_UNDEF)
|
||||
{
|
||||
sym->symbol.section = bfd_und_section_ptr;
|
||||
}
|
||||
else if (i_sym.st_shndx < SHN_LORESERVE
|
||||
|| i_sym.st_shndx > SHN_HIRESERVE)
|
||||
else if (isym->st_shndx < SHN_LORESERVE
|
||||
|| isym->st_shndx > SHN_HIRESERVE)
|
||||
{
|
||||
sym->symbol.section = section_from_elf_index (abfd,
|
||||
i_sym.st_shndx);
|
||||
isym->st_shndx);
|
||||
if (sym->symbol.section == NULL)
|
||||
{
|
||||
/* This symbol is in a section for which we did not
|
||||
@@ -1283,18 +1252,18 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic)
|
||||
sym->symbol.section = bfd_abs_section_ptr;
|
||||
}
|
||||
}
|
||||
else if (i_sym.st_shndx == SHN_ABS)
|
||||
else if (isym->st_shndx == SHN_ABS)
|
||||
{
|
||||
sym->symbol.section = bfd_abs_section_ptr;
|
||||
}
|
||||
else if (i_sym.st_shndx == SHN_COMMON)
|
||||
else if (isym->st_shndx == SHN_COMMON)
|
||||
{
|
||||
sym->symbol.section = bfd_com_section_ptr;
|
||||
/* Elf puts the alignment into the `value' field, and
|
||||
the size into the `size' field. BFD wants to see the
|
||||
size in the value field, and doesn't care (at the
|
||||
moment) about the alignment. */
|
||||
sym->symbol.value = i_sym.st_size;
|
||||
sym->symbol.value = isym->st_size;
|
||||
}
|
||||
else
|
||||
sym->symbol.section = bfd_abs_section_ptr;
|
||||
@@ -1304,14 +1273,13 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic)
|
||||
if ((abfd->flags & (EXEC_P | DYNAMIC)) != 0)
|
||||
sym->symbol.value -= sym->symbol.section->vma;
|
||||
|
||||
switch (ELF_ST_BIND (i_sym.st_info))
|
||||
switch (ELF_ST_BIND (isym->st_info))
|
||||
{
|
||||
case STB_LOCAL:
|
||||
sym->symbol.flags |= BSF_LOCAL;
|
||||
break;
|
||||
case STB_GLOBAL:
|
||||
if (i_sym.st_shndx != SHN_UNDEF
|
||||
&& i_sym.st_shndx != SHN_COMMON)
|
||||
if (isym->st_shndx != SHN_UNDEF && isym->st_shndx != SHN_COMMON)
|
||||
sym->symbol.flags |= BSF_GLOBAL;
|
||||
break;
|
||||
case STB_WEAK:
|
||||
@@ -1319,7 +1287,7 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic)
|
||||
break;
|
||||
}
|
||||
|
||||
switch (ELF_ST_TYPE (i_sym.st_info))
|
||||
switch (ELF_ST_TYPE (isym->st_info))
|
||||
{
|
||||
case STT_SECTION:
|
||||
sym->symbol.flags |= BSF_SECTION_SYM | BSF_DEBUGGING;
|
||||
@@ -1338,31 +1306,24 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic)
|
||||
if (dynamic)
|
||||
sym->symbol.flags |= BSF_DYNAMIC;
|
||||
|
||||
if (x_versymp != NULL)
|
||||
if (xver != NULL)
|
||||
{
|
||||
Elf_Internal_Versym iversym;
|
||||
|
||||
_bfd_elf_swap_versym_in (abfd, x_versymp + i, &iversym);
|
||||
_bfd_elf_swap_versym_in (abfd, xver, &iversym);
|
||||
sym->version = iversym.vs_vers;
|
||||
xver++;
|
||||
}
|
||||
|
||||
/* Do some backend-specific processing on this symbol. */
|
||||
{
|
||||
struct elf_backend_data *ebd = get_elf_backend_data (abfd);
|
||||
if (ebd->elf_backend_symbol_processing)
|
||||
(*ebd->elf_backend_symbol_processing) (abfd, &sym->symbol);
|
||||
}
|
||||
|
||||
sym++;
|
||||
if (ebd->elf_backend_symbol_processing)
|
||||
(*ebd->elf_backend_symbol_processing) (abfd, &sym->symbol);
|
||||
}
|
||||
}
|
||||
|
||||
/* Do some backend-specific processing on this symbol table. */
|
||||
{
|
||||
struct elf_backend_data *ebd = get_elf_backend_data (abfd);
|
||||
if (ebd->elf_backend_symbol_table_processing)
|
||||
(*ebd->elf_backend_symbol_table_processing) (abfd, symbase, symcount);
|
||||
}
|
||||
if (ebd->elf_backend_symbol_table_processing)
|
||||
(*ebd->elf_backend_symbol_table_processing) (abfd, symbase, symcount);
|
||||
|
||||
/* We rely on the zalloc to clear out the final symbol entry. */
|
||||
|
||||
@@ -1382,21 +1343,17 @@ elf_slurp_symbol_table (abfd, symptrs, dynamic)
|
||||
*symptrs = 0; /* Final null pointer */
|
||||
}
|
||||
|
||||
if (x_shndx != NULL)
|
||||
free (x_shndx);
|
||||
if (x_versymp != NULL)
|
||||
free (x_versymp);
|
||||
if (x_symp != NULL)
|
||||
free (x_symp);
|
||||
if (xverbuf != NULL)
|
||||
free (xverbuf);
|
||||
if (isymbuf != NULL && hdr->contents != (unsigned char *) isymbuf)
|
||||
free (isymbuf);
|
||||
return symcount;
|
||||
|
||||
error_return:
|
||||
if (x_shndx != NULL)
|
||||
free (x_shndx);
|
||||
if (x_versymp != NULL)
|
||||
free (x_versymp);
|
||||
if (x_symp != NULL)
|
||||
free (x_symp);
|
||||
if (xverbuf != NULL)
|
||||
free (xverbuf);
|
||||
if (isymbuf != NULL && hdr->contents != (unsigned char *) isymbuf)
|
||||
free (isymbuf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user