> Also, this looks like it might be a suitable project for someone > interested in learning about the binutils. So I am hoping that you, > or someone else will volunteer to have a go ... :-)
Here is the suggested patch. It will print the value at offset on Rel relocs; for simplicity, it only does it on 32-bit files, because that's what I need, but I can easily extend it; also, 64-bit ELFs tend to use Rela relocs where this feature does not make sense. The additional column is displayed when -A (--arch-specific) is passed, as suggested, together with -W for wide mode (I can remove this last requirement). There's an ad-hoc flag called show_value_at_off, so we can bind it to different command line options if needed. The patch seems to work correctly for me, but feedback is much appreciated. Test with "readelf -rAW". Andrea Monaco diff --git a/binutils/readelf.c b/binutils/readelf.c index b45683cd571..92830174c27 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -235,6 +235,7 @@ static bool do_notes = false; static bool do_archive_index = false; static bool check_all = false; static bool is_32bit_elf = false; +static bool show_value_at_off = false; /* On REL relocations, show the value at offset */ static bool decompress_dumps = false; static bool do_not_show_symbol_truncation = false; static bool do_demangle = false; /* Pretty print C++ symbol names. */ @@ -1531,10 +1532,12 @@ dump_relocations (Filedata * filedata, } else { - if (do_wide) - printf (_(" Offset Info Type Sym. Value Symbol's Name\n")); + if (do_wide && show_value_at_off) + printf (_(" Offset Value Info Type Sym. Value Symbol's Name\n")); + else if (do_wide) + printf (_(" Offset Info Type Sym. Value Symbol's Name\n")); else - printf (_(" Offset Info Type Sym.Value Sym. Name\n")); + printf (_(" Offset Info Type Sym. Value Sym. Name\n")); } } else @@ -1559,6 +1562,8 @@ dump_relocations (Filedata * filedata, { const char * rtype; bfd_vma offset; + bfd_vma file_offset; + bfd_vma value; bfd_vma inf; bfd_vma symtab_index; bfd_vma type; @@ -1571,9 +1576,32 @@ dump_relocations (Filedata * filedata, if (is_32bit_elf) { - printf ("%8.8lx %8.8lx ", - (unsigned long) offset & 0xffffffff, - (unsigned long) inf & 0xffffffff); + if (show_value_at_off && do_wide && rel_type == reltype_rel) + { + /* offset is an address in memory after loading, now we convert to an offset in the file */ + + Elf_Internal_Shdr *sec = find_section_by_address (filedata, offset); + value = 0; + + if (sec) + { + file_offset = offset - sec->sh_addr + sec->sh_offset; + + /* Now read value, or set to zero on failure */ + if (!fseek (filedata->handle, file_offset, SEEK_SET)) + if (fread (&value, sizeof (value), 1, filedata->handle) != 1) + value = 0; + } + + printf ("%8.8lx %8.8lx %8.8lx ", + (unsigned long) offset & 0xffffffff, + (unsigned long) value & 0xffffffff, + (unsigned long) inf & 0xffffffff); + } + else + printf ("%8.8lx %8.8lx ", + (unsigned long) offset & 0xffffffff, + (unsigned long) inf & 0xffffffff); } else { @@ -5292,6 +5320,7 @@ parse_args (struct dump_data *dumpdata, int argc, char ** argv) break; case 'A': do_arch = true; + show_value_at_off = true; break; case 'D': do_using_dynamic = true;