This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[PATCH] Fix readelf -sI (or -a)
- From: Jakub Jelinek <jakub at redhat dot com>
- To: binutils at sources dot redhat dot com
- Date: Thu, 11 Jun 2009 21:24:43 +0200
- Subject: [PATCH] Fix readelf -sI (or -a)
- Reply-to: Jakub Jelinek <jakub at redhat dot com>
Hi!
Recently I've noticed that while readelf -WS shows .symtab/.dynsym just
fine, for certain executables readelf -Wa doesn't print any symbol
information at all. The problem is that if histogram is supposed to
be printed as well and readelf encounters empty .gnu.hash section (or some
errors while looking at .hash/.gnu.hash), process_symbol_table just returns
without printing any symbol information, even when not using -D (i.e. when
.hash/.gnu.hash isn't relevant to symbol table printing at all).
Fixed thusly, tested on x86_64-linux. Ok for trunk?
2009-06-11 Jakub Jelinek <jakub@redhat.com>
* readelf.c (process_symbol_table): Don't return early if
.hash/.gnu.hash is empty/unusable and not -D.
--- binutils/readelf.c.jj 2009-05-28 19:35:03.000000000 +0200
+++ binutils/readelf.c 2009-06-10 19:57:20.000000000 +0200
@@ -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;
Jakub