diff options
author | Alan Modra <amodra@gmail.com> | 2004-08-28 03:05:18 +0000 |
---|---|---|
committer | Alan Modra <amodra@gmail.com> | 2004-08-28 03:05:18 +0000 |
commit | c9727e01b54c4b1913366933a2f32c7a6a03da7f (patch) | |
tree | c760fd32252388b9f7648ca1a8bfcb47535577f4 /bfd/elf64-ppc.c | |
parent | 0756fc55061311d060c72c9e9b8535b1668d2c84 (diff) | |
download | gdb-c9727e01b54c4b1913366933a2f32c7a6a03da7f.zip gdb-c9727e01b54c4b1913366933a2f32c7a6a03da7f.tar.gz gdb-c9727e01b54c4b1913366933a2f32c7a6a03da7f.tar.bz2 |
bfd/
* bfd.c (bfd_get_synthetic_symtab): Pass counts and both symbol tables.
* elf-bfd.h (_bfd_elf_get_synthetic_symtab): Adjust.
* elf.c (_bfd_elf_get_synthetic_symtab): Adjust.
* libbfd-in.h (_bfd_nodynamic_get_synthetic_symtab): Adjust.
* targets.c (struct bfd_target <_bfd_get_synthetic_symtab>): Adjust.
* elf64-ppc.c (ppc64_elf_get_synthetic_symtab): Don't read symbols.
Use both symbol tables on non-relocatable objects. Use a common
error exit. Fix "mid" warning.
* libbfd.h: Regenerate.
* bfd-in2.h: Regenerate.
binutils/
* objdump.c (dump_bfd): Pass both symbol tables to
bfd_get_synthetic_symtab.
Diffstat (limited to 'bfd/elf64-ppc.c')
-rw-r--r-- | bfd/elf64-ppc.c | 127 |
1 files changed, 55 insertions, 72 deletions
diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 61a42cb..0ad50be 100644 --- a/bfd/elf64-ppc.c +++ b/bfd/elf64-ppc.c @@ -2645,16 +2645,18 @@ sym_exists_at (asymbol **syms, long lo, long hi, int id, bfd_vma value) entry syms. */ static long -ppc64_elf_get_synthetic_symtab (bfd *abfd, asymbol **relsyms, asymbol **ret) +ppc64_elf_get_synthetic_symtab (bfd *abfd, long symcount, asymbol **syms, + long dynsymcount, asymbol **dynsyms, + asymbol **ret) { asymbol *s; long i; long count; char *names; - asymbol **syms = NULL; - long symcount = 0, codesecsym, codesecsymend, secsymend, opdsymend; + long codesecsym, codesecsymend, secsymend, opdsymend; asection *opd; bfd_boolean relocatable = (abfd->flags & (EXEC_P | DYNAMIC)) == 0; + asymbol **sy = NULL; *ret = NULL; @@ -2662,61 +2664,46 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd, asymbol **relsyms, asymbol **ret) if (opd == NULL) return 0; - if ((bfd_get_file_flags (abfd) & HAS_SYMS)) + if (!relocatable) { - long storage; - storage = bfd_get_symtab_upper_bound (abfd); - if (storage < 0) - return 0; - - if (storage) + if (symcount != 0 && dynsymcount != 0) { - syms = bfd_malloc (storage); - if (syms == NULL) + /* Use both symbol tables. */ + sy = bfd_malloc ((symcount + dynsymcount + 1) * sizeof (*syms)); + if (sy == NULL) return 0; + memcpy (sy, syms, symcount * sizeof (*syms)); + memcpy (sy + symcount, dynsyms, (dynsymcount + 1) * sizeof (*syms)); + syms = sy; + symcount = symcount + dynsymcount; } - - symcount = bfd_canonicalize_symtab (abfd, syms); - if (symcount < 0) - { - free (syms); - return 0; - } - - if (symcount == 0) + else if (symcount == 0) { - free (syms); - syms = NULL; + syms = dynsyms; + symcount = dynsymcount; } } if (symcount == 0) - { - long storage; - - storage = bfd_get_dynamic_symtab_upper_bound (abfd); - if (storage < 0) - return 0; - - if (storage) - { - syms = bfd_malloc (storage); - if (syms == NULL) - return 0; - } - - symcount = bfd_canonicalize_dynamic_symtab (abfd, syms); - if (symcount < 0) - { - free (syms); - return 0; - } - } + return 0; synthetic_opd = opd; synthetic_relocatable = relocatable; qsort (syms, symcount, sizeof (asymbol *), compare_symbols); + if (!relocatable && symcount > 1) + { + long j; + /* Trim duplicate syms, since we may have merged the normal and + dynamic symbols. Actually, we only care about syms that have + different values, so trim any with the same value. */ + for (i = 1, j = 1; i < symcount; ++i) + if (syms[i - 1]->value + syms[i - 1]->section->vma + != syms[i]->value + syms[i]->section->vma) + syms[j++] = syms[i]; + symcount = j; + } + i = 0; if (syms[i]->section == opd) ++i; @@ -2745,13 +2732,10 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd, asymbol **relsyms, asymbol **ret) break; symcount = i; + count = 0; if (opdsymend == secsymend) - { - free (syms); - return 0; - } + goto done; - count = 0; if (relocatable) { bfd_boolean (*slurp_relocs) (bfd *, asection *, asymbol **, bfd_boolean); @@ -2765,11 +2749,8 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd, asymbol **relsyms, asymbol **ret) relcount = (opd->flags & SEC_RELOC) ? opd->reloc_count : 0; if (! relcount - || ! (*slurp_relocs) (abfd, relopd, relsyms, FALSE)) - { - free (syms); - return 0; - } + || ! (*slurp_relocs) (abfd, relopd, syms, FALSE)) + goto done; size = 0; for (i = secsymend, r = relopd->relocation; i < opdsymend; ++i) @@ -2802,8 +2783,8 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd, asymbol **relsyms, asymbol **ret) s = *ret = bfd_malloc (size); if (s == NULL) { - free (syms); - return 0; + count = 0; + goto done; } names = (char *) (s + count); @@ -2851,9 +2832,11 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd, asymbol **relsyms, asymbol **ret) if (!bfd_malloc_and_get_section (abfd, opd, &contents)) { if (contents) - free (contents); - free (syms); - return 0; + { + free_contents_and_exit: + free (contents); + } + goto done; } size = 0; @@ -2873,9 +2856,8 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd, asymbol **relsyms, asymbol **ret) s = *ret = bfd_malloc (size); if (s == NULL) { - free (contents); - free (syms); - return 0; + count = 0; + goto free_contents_and_exit; } names = (char *) (s + count); @@ -2887,30 +2869,29 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd, asymbol **relsyms, asymbol **ret) ent = bfd_get_64 (abfd, contents + syms[i]->value); if (!sym_exists_at (syms, opdsymend, symcount, -1, ent)) { - long lo, hi, mid; + long lo, hi; size_t len; - asection *sec; + asection *sec = abfd->sections; *s = *syms[i]; lo = codesecsym; hi = codesecsymend; while (lo < hi) { - mid = (lo + hi) >> 1; + long mid = (lo + hi) >> 1; if (syms[mid]->section->vma < ent) lo = mid + 1; else if (syms[mid]->section->vma > ent) hi = mid; else - break; + { + sec = syms[mid]->section; + break; + } } - if (lo < hi) - sec = syms[mid]->section; - else if (lo > codesecsym) + if (lo >= hi && lo > codesecsym) sec = syms[lo - 1]->section; - else - sec = abfd->sections; for (; sec != NULL; sec = sec->next) { @@ -2934,7 +2915,9 @@ ppc64_elf_get_synthetic_symtab (bfd *abfd, asymbol **relsyms, asymbol **ret) free (contents); } - free (syms); + done: + if (sy != NULL) + free (sy); return count; } |