aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bfd/ChangeLog13
-rw-r--r--bfd/bfd-in2.h8
-rw-r--r--bfd/bfd.c5
-rw-r--r--bfd/elf-bfd.h2
-rw-r--r--bfd/elf.c9
-rw-r--r--bfd/elf64-ppc.c127
-rw-r--r--bfd/libbfd-in.h2
-rw-r--r--bfd/libbfd.h2
-rw-r--r--bfd/targets.c3
-rw-r--r--binutils/ChangeLog5
-rw-r--r--binutils/objdump.c16
11 files changed, 97 insertions, 95 deletions
diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 1db8b5f..1a123f5 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,18 @@
2004-08-28 Alan Modra <amodra@bigpond.net.au>
+ * 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 <amodra@bigpond.net.au>
+
* elf64-ppc.c (ppc64_elf_branch_reloc): Check .opd is in a regular
object file.
(struct sfpr_def_parms): Save some space.
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index ddcef01..3998a7f 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 dc30cfe..e6f54c6 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 336b94f..12d0f86 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 d1fa2c0..8c1afb9 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 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;
}
diff --git a/bfd/libbfd-in.h b/bfd/libbfd-in.h
index 826aaf4..7b6ca76 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 4fe194e..6456532 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 e3357c5..bcb5715 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 958a26a..5b87074 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,8 @@
+2004-08-28 Alan Modra <amodra@bigpond.net.au>
+
+ * objdump.c (dump_bfd): Pass both symbol tables to
+ bfd_get_synthetic_symtab.
+
2004-08-17 Jakub Jelinek <jakub@redhat.com>
* objdump.c (dump_bfd): For relocatable objects, pass syms instead
diff --git a/binutils/objdump.c b/binutils/objdump.c
index af04b70..e56bf36 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)