* 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:
Alan Modra
2002-07-07 09:10:41 +00:00
parent d8462f1281
commit 6cdc0ccc12
22 changed files with 1432 additions and 2704 deletions

View File

@@ -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;
}