aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2009-06-12 10:19:54 +0000
committerJakub Jelinek <jakub@redhat.com>2009-06-12 10:19:54 +0000
commitd3a44ec61fa6afe54544fca32485cc47921fe7dc (patch)
treecd7c10d6296a94ddf5672ae7806525f47a043e17
parent92bc0e8020921eaf7869df4d94c115b584b5c3f9 (diff)
downloadgdb-d3a44ec61fa6afe54544fca32485cc47921fe7dc.zip
gdb-d3a44ec61fa6afe54544fca32485cc47921fe7dc.tar.gz
gdb-d3a44ec61fa6afe54544fca32485cc47921fe7dc.tar.bz2
* readelf.c (process_symbol_table): Don't return early if
.hash/.gnu.hash is empty/unusable and not -D.
-rw-r--r--binutils/ChangeLog5
-rw-r--r--binutils/readelf.c47
2 files changed, 37 insertions, 15 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index b0a9be5..76bf2a9 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,8 @@
+2009-06-12 Jakub Jelinek <jakub@redhat.com>
+
+ * readelf.c (process_symbol_table): Don't return early if
+ .hash/.gnu.hash is empty/unusable and not -D.
+
2009-06-09 Tom Bramer <tjb@postpro.net>
PR 10165
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 4727a84..af372fd 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -7152,19 +7152,19 @@ process_symbol_table (FILE * file)
SEEK_SET))
{
error (_("Unable to seek to start of dynamic information\n"));
- return 0;
+ goto no_hash;
}
if (fread (nb, hash_ent_size, 1, file) != 1)
{
error (_("Failed to read in number of buckets\n"));
- return 0;
+ goto no_hash;
}
if (fread (nc, hash_ent_size, 1, file) != 1)
{
error (_("Failed to read in number of chains\n"));
- return 0;
+ goto no_hash;
}
nbuckets = byte_get (nb, hash_ent_size);
@@ -7173,8 +7173,18 @@ process_symbol_table (FILE * file)
buckets = get_dynamic_data (file, nbuckets, hash_ent_size);
chains = get_dynamic_data (file, nchains, hash_ent_size);
+ no_hash:
if (buckets == NULL || chains == NULL)
- return 0;
+ {
+ if (do_using_dynamic)
+ return 0;
+ free (buckets);
+ free (chains);
+ buckets = NULL;
+ chains = NULL;
+ nbuckets = 0;
+ nchains = 0;
+ }
}
if (dynamic_info_DT_GNU_HASH
@@ -7192,13 +7202,13 @@ process_symbol_table (FILE * file)
SEEK_SET))
{
error (_("Unable to seek to start of dynamic information\n"));
- return 0;
+ goto no_gnu_hash;
}
if (fread (nb, 16, 1, file) != 1)
{
error (_("Failed to read in number of buckets\n"));
- return 0;
+ goto no_gnu_hash;
}
ngnubuckets = byte_get (nb, 4);
@@ -7216,13 +7226,13 @@ process_symbol_table (FILE * file)
SEEK_SET))
{
error (_("Unable to seek to start of dynamic information\n"));
- return 0;
+ goto no_gnu_hash;
}
gnubuckets = get_dynamic_data (file, ngnubuckets, 4);
if (gnubuckets == NULL)
- return 0;
+ goto no_gnu_hash;
for (i = 0; i < ngnubuckets; i++)
if (gnubuckets[i] != 0)
@@ -7235,7 +7245,7 @@ process_symbol_table (FILE * file)
}
if (maxchain == 0xffffffff)
- return 0;
+ goto no_gnu_hash;
maxchain -= gnusymidx;
@@ -7246,7 +7256,7 @@ process_symbol_table (FILE * file)
SEEK_SET))
{
error (_("Unable to seek to start of dynamic information\n"));
- return 0;
+ goto no_gnu_hash;
}
do
@@ -7254,11 +7264,11 @@ process_symbol_table (FILE * file)
if (fread (nb, 4, 1, file) != 1)
{
error (_("Failed to determine last chain length\n"));
- return 0;
+ goto no_gnu_hash;
}
if (maxchain + 1 == 0)
- return 0;
+ goto no_gnu_hash;
++maxchain;
}
@@ -7270,13 +7280,20 @@ process_symbol_table (FILE * file)
SEEK_SET))
{
error (_("Unable to seek to start of dynamic information\n"));
- return 0;
+ goto no_gnu_hash;
}
gnuchains = get_dynamic_data (file, maxchain, 4);
+ no_gnu_hash:
if (gnuchains == NULL)
- return 0;
+ {
+ free (gnubuckets);
+ if (do_using_dynamic)
+ return 0;
+ gnubuckets = NULL;
+ ngnubuckets = 0;
+ }
}
if ((dynamic_info[DT_HASH] || dynamic_info_DT_GNU_HASH)
@@ -7608,7 +7625,7 @@ process_symbol_table (FILE * file)
free (chains);
}
- if (do_histogram && dynamic_info_DT_GNU_HASH)
+ if (do_histogram && gnubuckets != NULL)
{
unsigned long * lengths;
unsigned long * counts;