diff options
Diffstat (limited to 'bfd/elf64-hppa.c')
-rw-r--r-- | bfd/elf64-hppa.c | 93 |
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; |