From: Alan Modra Date: Sat, 28 Aug 2004 03:05:18 +0000 (+0000) Subject: bfd/ X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=c9727e01b54c4b1913366933a2f32c7a6a03da7f;p=binutils-gdb.git 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. --- diff --git a/bfd/ChangeLog b/bfd/ChangeLog index 1db8b5f8b1b..1a123f5b511 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,3 +1,16 @@ +2004-08-28 Alan Modra + + * targets.c (struct bfd_target <_bfd_get_synthetic_symtab>): Pass + symbol counts and both symbol tables. + * bfd.c (bfd_get_synthetic_symtab): Adjust. + * 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. + * elf64-ppc.c (ppc64_elf_get_synthetic_symtab): Adjust. Use both + symbol tables on non-relocatable objects. + * libbfd.h: Regenerate. + * bfd-in2.h: Regenerate. + 2004-08-28 Alan Modra * elf64-ppc.c (ppc64_elf_branch_reloc): Check .opd is in a regular diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h index ddcef0145fc..3998a7fc5d7 100644 --- a/bfd/bfd-in2.h +++ b/bfd/bfd-in2.h @@ -4111,8 +4111,9 @@ bfd_boolean bfd_set_private_flags (bfd *abfd, flagword flags); #define bfd_canonicalize_dynamic_symtab(abfd, asymbols) \ BFD_SEND (abfd, _bfd_canonicalize_dynamic_symtab, (abfd, asymbols)) -#define bfd_get_synthetic_symtab(abfd, relsyms, ret) \ - BFD_SEND (abfd, _bfd_get_synthetic_symtab, (abfd, relsyms, ret)) +#define bfd_get_synthetic_symtab(abfd, count, syms, dyncount, dynsyms, ret) \ + BFD_SEND (abfd, _bfd_get_synthetic_symtab, (abfd, count, syms, \ + dyncount, dynsyms, ret)) #define bfd_get_dynamic_reloc_upper_bound(abfd) \ BFD_SEND (abfd, _bfd_get_dynamic_reloc_upper_bound, (abfd)) @@ -4520,7 +4521,8 @@ typedef struct bfd_target (bfd *, struct bfd_symbol **); /* Create synthetized symbols. */ long (*_bfd_get_synthetic_symtab) - (bfd *, struct bfd_symbol **, struct bfd_symbol **); + (bfd *, long, struct bfd_symbol **, long, struct bfd_symbol **, + struct bfd_symbol **); /* Get the amount of memory required to hold the dynamic relocs. */ long (*_bfd_get_dynamic_reloc_upper_bound) (bfd *); /* Read in the dynamic relocs. */ diff --git a/bfd/bfd.c b/bfd/bfd.c index dc30cfeeff1..e6f54c699da 100644 --- a/bfd/bfd.c +++ b/bfd/bfd.c @@ -1218,8 +1218,9 @@ DESCRIPTION .#define bfd_canonicalize_dynamic_symtab(abfd, asymbols) \ . BFD_SEND (abfd, _bfd_canonicalize_dynamic_symtab, (abfd, asymbols)) . -.#define bfd_get_synthetic_symtab(abfd, relsyms, ret) \ -. BFD_SEND (abfd, _bfd_get_synthetic_symtab, (abfd, relsyms, ret)) +.#define bfd_get_synthetic_symtab(abfd, count, syms, dyncount, dynsyms, ret) \ +. BFD_SEND (abfd, _bfd_get_synthetic_symtab, (abfd, count, syms, \ +. dyncount, dynsyms, ret)) . .#define bfd_get_dynamic_reloc_upper_bound(abfd) \ . BFD_SEND (abfd, _bfd_get_dynamic_reloc_upper_bound, (abfd)) diff --git a/bfd/elf-bfd.h b/bfd/elf-bfd.h index 336b94fc8fe..12d0f86e714 100644 --- a/bfd/elf-bfd.h +++ b/bfd/elf-bfd.h @@ -1438,7 +1438,7 @@ extern long _bfd_elf_get_dynamic_symtab_upper_bound extern long _bfd_elf_canonicalize_dynamic_symtab (bfd *, asymbol **); extern long _bfd_elf_get_synthetic_symtab - (bfd *, asymbol **, asymbol **); + (bfd *, long, asymbol **, long, asymbol **, asymbol **); extern long _bfd_elf_get_reloc_upper_bound (bfd *, sec_ptr); extern long _bfd_elf_canonicalize_reloc diff --git a/bfd/elf.c b/bfd/elf.c index d1fa2c0c907..8c1afb9de4e 100644 --- a/bfd/elf.c +++ b/bfd/elf.c @@ -7744,7 +7744,12 @@ bfd_elf_bfd_from_remote_memory } long -_bfd_elf_get_synthetic_symtab (bfd *abfd, asymbol **relsyms, asymbol **ret) +_bfd_elf_get_synthetic_symtab (bfd *abfd, + long symcount ATTRIBUTE_UNUSED, + asymbol **syms ATTRIBUTE_UNUSED, + long dynsymcount ATTRIBUTE_UNUSED, + asymbol **dynsyms, + asymbol **ret) { const struct elf_backend_data *bed = get_elf_backend_data (abfd); asection *relplt; @@ -7782,7 +7787,7 @@ _bfd_elf_get_synthetic_symtab (bfd *abfd, asymbol **relsyms, asymbol **ret) return 0; slurp_relocs = get_elf_backend_data (abfd)->s->slurp_reloc_table; - if (! (*slurp_relocs) (abfd, relplt, relsyms, TRUE)) + if (! (*slurp_relocs) (abfd, relplt, dynsyms, TRUE)) return -1; count = relplt->size / hdr->sh_entsize; diff --git a/bfd/elf64-ppc.c b/bfd/elf64-ppc.c index 61a42cb3d4a..0ad50be8c96 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; } diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h index 826aaf473fb..7b6ca76e05a 100644 --- a/bfd/libbfd-in.h +++ b/bfd/libbfd-in.h @@ -387,7 +387,7 @@ extern bfd_boolean _bfd_generic_set_section_contents #define _bfd_nodynamic_canonicalize_dynamic_symtab \ ((long (*) (bfd *, asymbol **)) _bfd_n1) #define _bfd_nodynamic_get_synthetic_symtab \ - ((long (*) (bfd *, asymbol **, asymbol **)) _bfd_n1) + ((long (*) (bfd *, long, asymbol **, long, asymbol **, asymbol **)) _bfd_n1) #define _bfd_nodynamic_get_dynamic_reloc_upper_bound _bfd_n1 #define _bfd_nodynamic_canonicalize_dynamic_reloc \ ((long (*) (bfd *, arelent **, asymbol **)) _bfd_n1) diff --git a/bfd/libbfd.h b/bfd/libbfd.h index 4fe194ee8ed..64565326a62 100644 --- a/bfd/libbfd.h +++ b/bfd/libbfd.h @@ -392,7 +392,7 @@ extern bfd_boolean _bfd_generic_set_section_contents #define _bfd_nodynamic_canonicalize_dynamic_symtab \ ((long (*) (bfd *, asymbol **)) _bfd_n1) #define _bfd_nodynamic_get_synthetic_symtab \ - ((long (*) (bfd *, asymbol **, asymbol **)) _bfd_n1) + ((long (*) (bfd *, long, asymbol **, long, asymbol **, asymbol **)) _bfd_n1) #define _bfd_nodynamic_get_dynamic_reloc_upper_bound _bfd_n1 #define _bfd_nodynamic_canonicalize_dynamic_reloc \ ((long (*) (bfd *, arelent **, asymbol **)) _bfd_n1) diff --git a/bfd/targets.c b/bfd/targets.c index e3357c59f60..bcb57151901 100644 --- a/bfd/targets.c +++ b/bfd/targets.c @@ -475,7 +475,8 @@ BFD_JUMP_TABLE macros. . (bfd *, struct bfd_symbol **); . {* Create synthetized symbols. *} . long (*_bfd_get_synthetic_symtab) -. (bfd *, struct bfd_symbol **, struct bfd_symbol **); +. (bfd *, long, struct bfd_symbol **, long, struct bfd_symbol **, +. struct bfd_symbol **); . {* Get the amount of memory required to hold the dynamic relocs. *} . long (*_bfd_get_dynamic_reloc_upper_bound) (bfd *); . {* Read in the dynamic relocs. *} diff --git a/binutils/ChangeLog b/binutils/ChangeLog index 958a26aa8d6..5b8707423ff 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,8 @@ +2004-08-28 Alan Modra + + * objdump.c (dump_bfd): Pass both symbol tables to + bfd_get_synthetic_symtab. + 2004-08-17 Jakub Jelinek * objdump.c (dump_bfd): For relocatable objects, pass syms instead diff --git a/binutils/objdump.c b/binutils/objdump.c index af04b703776..e56bf36db20 100644 --- a/binutils/objdump.c +++ b/binutils/objdump.c @@ -2566,18 +2566,10 @@ dump_bfd (bfd *abfd) dynsyms = slurp_dynamic_symtab (abfd); if (disassemble) { - synthcount = 0; - if (bfd_get_file_flags (abfd) & (DYNAMIC | EXEC_P)) - { - if (dynsymcount > 0) - synthcount = bfd_get_synthetic_symtab (abfd, dynsyms, &synthsyms); - } - else - { - if (symcount > 0) - synthcount = bfd_get_synthetic_symtab (abfd, syms, &synthsyms); - } - if (synthcount < 0) synthcount = 0; + synthcount = bfd_get_synthetic_symtab (abfd, symcount, syms, + dynsymcount, dynsyms, &synthsyms); + if (synthcount < 0) + synthcount = 0; } if (dump_symtab)