diff options
-rw-r--r-- | binutils/ChangeLog | 8 | ||||
-rw-r--r-- | binutils/readelf.c | 90 |
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 : |