aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--binutils/ChangeLog8
-rw-r--r--binutils/readelf.c90
2 files changed, 59 insertions, 39 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 7a93260..fe24e9f 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,11 @@
+2003-03-31 H.J. Lu <hjl@gnu.org>
+
+ * readelf.c: Include "libiberty.h".
+ (dynamic_relocations): New.
+ (process_relocs): Properly handle dynamic relocation.
+ (process_dynamic_segment): Fill relocation elements in
+ dynamic_info.
+
2003-03-31 Kevin Buettner <kevinb@redhat.com>
* readelf.c (read_and_display_attr, read_and_display_attr_value):
diff --git a/binutils/readelf.c b/binutils/readelf.c
index af3b14b..00672c1 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -91,6 +91,7 @@
#include "bucomm.h"
#include "getopt.h"
+#include "libiberty.h"
char *program_name = "readelf";
unsigned long dynamic_addr;
@@ -3798,6 +3799,19 @@ process_section_headers (file)
return 1;
}
+struct
+{
+ const char *name;
+ int reloc;
+ int size;
+ int rela;
+} dynamic_relocations [] =
+{
+ { "REL", DT_REL, DT_RELSZ, FALSE },
+ { "RELA", DT_RELA, DT_RELASZ, TRUE },
+ { "PLT", DT_JMPREL, DT_PLTRELSZ, UNKNOWN }
+};
+
/* Process the reloc section. */
static int
process_relocs (file)
@@ -3812,53 +3826,49 @@ process_relocs (file)
if (do_using_dynamic)
{
- int is_rela = FALSE;
-
- rel_size = 0;
- rel_offset = 0;
+ int is_rela;
+ const char *name;
+ int has_dynamic_reloc;
+ unsigned int i;
+
+ has_dynamic_reloc = 0;
- if (dynamic_info[DT_REL])
+ for (i = 0; i < ARRAY_SIZE (dynamic_relocations); i++)
{
- rel_offset = dynamic_info[DT_REL];
- rel_size = dynamic_info[DT_RELSZ];
- is_rela = FALSE;
- }
- else if (dynamic_info[DT_RELA])
- {
- rel_offset = dynamic_info[DT_RELA];
- rel_size = dynamic_info[DT_RELASZ];
- is_rela = TRUE;
- }
- else if (dynamic_info[DT_JMPREL])
- {
- rel_offset = dynamic_info[DT_JMPREL];
- rel_size = dynamic_info[DT_PLTRELSZ];
+ is_rela = dynamic_relocations [i].rela;
+ name = dynamic_relocations [i].name;
+ rel_size = dynamic_info [dynamic_relocations [i].size];
+ rel_offset = dynamic_info [dynamic_relocations [i].reloc];
- switch (dynamic_info[DT_PLTREL])
+ has_dynamic_reloc |= rel_size;
+
+ if (is_rela == UNKNOWN)
{
- case DT_REL:
- is_rela = FALSE;
- break;
- case DT_RELA:
- is_rela = TRUE;
- break;
- default:
- is_rela = UNKNOWN;
- break;
+ if (dynamic_relocations [i].reloc == DT_JMPREL)
+ switch (dynamic_info[DT_PLTREL])
+ {
+ case DT_REL:
+ is_rela = FALSE;
+ break;
+ case DT_RELA:
+ is_rela = TRUE;
+ break;
+ }
}
- }
- if (rel_size)
- {
- printf
- (_("\nRelocation section at offset 0x%lx contains %ld bytes:\n"),
- rel_offset, rel_size);
+ if (rel_size)
+ {
+ printf
+ (_("\n'%s' relocation section at offset 0x%lx contains %ld bytes:\n"),
+ name, rel_offset, rel_size);
- dump_relocations (file, rel_offset - loadaddr, rel_size,
- dynamic_symbols, num_dynamic_syms, dynamic_strings,
- is_rela);
+ dump_relocations (file, rel_offset - loadaddr, rel_size,
+ dynamic_symbols, num_dynamic_syms,
+ dynamic_strings, is_rela);
+ }
}
- else
+
+ if (! has_dynamic_reloc)
printf (_("\nThere are no dynamic relocations in this file.\n"));
}
else
@@ -5001,6 +5011,7 @@ process_dynamic_segment (file)
break;
case DT_PLTREL:
+ dynamic_info[entry->d_tag] = entry->d_un.d_val;
if (do_dynamic)
puts (get_dynamic_type (entry->d_un.d_val));
break;
@@ -5075,6 +5086,7 @@ process_dynamic_segment (file)
case DT_RELAENT :
case DT_SYMENT :
case DT_RELENT :
+ dynamic_info[entry->d_tag] = entry->d_un.d_val;
case DT_PLTPADSZ:
case DT_MOVEENT :
case DT_MOVESZ :