[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] readelf: dump the value contained in offset on Rel relocs when -
From: |
Andrea Monaco |
Subject: |
[PATCH] readelf: dump the value contained in offset on Rel relocs when -AW are passed |
Date: |
Fri, 14 Jan 2022 16:35:46 +0100 |
> 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;