aboutsummaryrefslogtreecommitdiff
path: root/bfd/elf64-hppa.c
diff options
context:
space:
mode:
Diffstat (limited to 'bfd/elf64-hppa.c')
-rw-r--r--bfd/elf64-hppa.c93
1 files changed, 28 insertions, 65 deletions
diff --git a/bfd/elf64-hppa.c b/bfd/elf64-hppa.c
index 929cacd..7ebbb52 100644
--- a/bfd/elf64-hppa.c
+++ b/bfd/elf64-hppa.c
@@ -591,7 +591,6 @@ elf64_hppa_check_relocs (abfd, info, sec, relocs)
struct elf64_hppa_link_hash_table *hppa_info;
const Elf_Internal_Rela *relend;
Elf_Internal_Shdr *symtab_hdr;
- Elf_Internal_Shdr *shndx_hdr;
const Elf_Internal_Rela *rel;
asection *dlt, *plt, *stubs;
char *buf;
@@ -613,15 +612,14 @@ elf64_hppa_check_relocs (abfd, info, sec, relocs)
symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
/* If necessary, build a new table holding section symbols indices
- for this BFD. This is disgusting. */
+ for this BFD. */
if (info->shared && hppa_info->section_syms_bfd != abfd)
{
unsigned long i;
unsigned int highest_shndx;
- Elf_Internal_Sym *local_syms, *isym;
- Elf64_External_Sym *ext_syms, *esym;
- Elf_External_Sym_Shndx *shndx_buf, *shndx;
+ Elf_Internal_Sym *local_syms = NULL;
+ Elf_Internal_Sym *isym, *isymend;
bfd_size_type amt;
/* We're done with the old cache of section index to section symbol
@@ -632,72 +630,27 @@ elf64_hppa_check_relocs (abfd, info, sec, relocs)
if (hppa_info->section_syms)
free (hppa_info->section_syms);
- /* Allocate memory for the internal and external symbols. */
- amt = symtab_hdr->sh_info;
- amt *= sizeof (Elf_Internal_Sym);
- local_syms = (Elf_Internal_Sym *) bfd_malloc (amt);
- if (local_syms == NULL)
- return false;
-
- amt = symtab_hdr->sh_info;
- amt *= sizeof (Elf64_External_Sym);
- ext_syms = (Elf64_External_Sym *) bfd_malloc (amt);
- if (ext_syms == NULL)
- {
- free (local_syms);
- return false;
- }
-
- /* Read in the local symbols. */
- if (bfd_seek (abfd, symtab_hdr->sh_offset, SEEK_SET) != 0
- || bfd_bread (ext_syms, amt, abfd) != amt)
+ /* Read this BFD's local symbols. */
+ if (symtab_hdr->sh_info != 0)
{
- free (ext_syms);
- free (local_syms);
- return false;
- }
-
- shndx_buf = NULL;
- shndx_hdr = &elf_tdata (abfd)->symtab_shndx_hdr;
- if (shndx_hdr->sh_size != 0)
- {
- amt = symtab_hdr->sh_info;
- amt *= sizeof (Elf_External_Sym_Shndx);
- shndx_buf = (Elf_External_Sym_Shndx *) bfd_malloc (amt);
- if (shndx_buf == NULL)
- {
- free (ext_syms);
- free (local_syms);
- return false;
- }
-
- if (bfd_seek (abfd, shndx_hdr->sh_offset, SEEK_SET) != 0
- || bfd_bread (shndx_buf, amt, abfd) != amt)
- {
- free (shndx_buf);
- free (ext_syms);
- free (local_syms);
- return false;
- }
+ local_syms = (Elf_Internal_Sym *) symtab_hdr->contents;
+ if (local_syms == NULL)
+ local_syms = bfd_elf_get_elf_syms (abfd, symtab_hdr,
+ symtab_hdr->sh_info, 0,
+ NULL, NULL, NULL);
+ if (local_syms == NULL)
+ return false;
}
- /* Swap in the local symbols, also record the highest section index
- referenced by the local symbols. */
+ /* Record the highest section index referenced by the local symbols. */
highest_shndx = 0;
- for (i = 0, isym = local_syms, esym = ext_syms, shndx = shndx_buf;
- i < symtab_hdr->sh_info;
- i++, esym++, isym++, shndx = (shndx != NULL ? shndx + 1 : NULL))
+ isymend = local_syms + symtab_hdr->sh_info;
+ for (isym = local_syms; isym < isymend; isym++)
{
- bfd_elf64_swap_symbol_in (abfd, (const PTR) esym, (const PTR) shndx,
- isym);
if (isym->st_shndx > highest_shndx)
highest_shndx = isym->st_shndx;
}
- /* Now we can free the external symbols. */
- free (shndx_buf);
- free (ext_syms);
-
/* Allocate an array to hold the section index to section symbol index
mapping. Bump by one since we start counting at zero. */
highest_shndx++;
@@ -707,14 +660,24 @@ elf64_hppa_check_relocs (abfd, info, sec, relocs)
/* Now walk the local symbols again. If we find a section symbol,
record the index of the symbol into the section_syms array. */
- for (isym = local_syms, i = 0; i < symtab_hdr->sh_info; i++, isym++)
+ for (i = 0, isym = local_syms; isym < isymend; i++, isym++)
{
if (ELF_ST_TYPE (isym->st_info) == STT_SECTION)
hppa_info->section_syms[isym->st_shndx] = i;
}
- /* We are finished with the local symbols. Get rid of them. */
- free (local_syms);
+ /* We are finished with the local symbols. */
+ if (local_syms != NULL
+ && symtab_hdr->contents != (unsigned char *) local_syms)
+ {
+ if (! info->keep_memory)
+ free (local_syms);
+ else
+ {
+ /* Cache the symbols for elf_link_input_bfd. */
+ symtab_hdr->contents = (unsigned char *) local_syms;
+ }
+ }
/* Record which BFD we built the section_syms mapping for. */
hppa_info->section_syms_bfd = abfd;