aboutsummaryrefslogtreecommitdiff
path: root/binutils
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@imgtec.com>2017-04-24 20:41:33 +0100
committerMaciej W. Rozycki <macro@imgtec.com>2017-04-26 13:11:20 +0100
commitbbdd9a6894d7875407da59d490faf5588163d21c (patch)
treef58c3dba9123790524df71b86b69e0267aa6402a /binutils
parente63d123268f23a4cbc45ee55fb6dbc7d84729da3 (diff)
downloadgdb-bbdd9a6894d7875407da59d490faf5588163d21c.zip
gdb-bbdd9a6894d7875407da59d490faf5588163d21c.tar.gz
gdb-bbdd9a6894d7875407da59d490faf5588163d21c.tar.bz2
MIPS/readelf: With `-A' also dump GOT in static binaries
A static, non-relocated global offset table will be embedded in static binaries produced from objects containing any kind of GOT relocations, generally PIC code. All symbols will have been resolved in static link in such binaries making all GOT entries local and their values final as there is no run-time load processing further performed. Dump such GOT with `readelf -A' like already done with regular GOT, to make it easier to examine static code that uses accesses via the GOT pointer. There will be no dynamic segment or section in a static binary to get the GOT pointer (DT_PLTGOT) from, so use section headers to find a `.got' section instead. binutils/ * readelf.c (process_mips_specific): Add static GOT support.
Diffstat (limited to 'binutils')
-rw-r--r--binutils/ChangeLog4
-rw-r--r--binutils/readelf.c89
2 files changed, 91 insertions, 2 deletions
diff --git a/binutils/ChangeLog b/binutils/ChangeLog
index 7f8e29d..d2ddf41 100644
--- a/binutils/ChangeLog
+++ b/binutils/ChangeLog
@@ -1,3 +1,7 @@
+2017-04-26 Maciej W. Rozycki <macro@imgtec.com>
+
+ * readelf.c (process_mips_specific): Add static GOT support.
+
2017-04-25 Maciej W. Rozycki <macro@imgtec.com>
* readelf.c (process_mips_specific): Remove error reporting from
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 1139f71..2d3ef27 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -15007,8 +15007,93 @@ process_mips_specific (FILE * file)
/* We have a lot of special sections. Thanks SGI! */
if (dynamic_section == NULL)
- /* No information available. */
- return res;
+ {
+ /* No dynamic information available. See if there is static GOT. */
+ sect = find_section (".got");
+ if (sect != NULL)
+ {
+ unsigned char *data_end;
+ unsigned char *data;
+ bfd_vma ent, end;
+ int addr_size;
+
+ pltgot = sect->sh_addr;
+
+ ent = pltgot;
+ addr_size = (is_32bit_elf ? 4 : 8);
+ end = pltgot + sect->sh_size;
+
+ data = (unsigned char *) get_data (NULL, file, sect->sh_offset,
+ end - pltgot, 1,
+ _("Global Offset Table data"));
+ /* PR 12855: Null data is handled gracefully throughout. */
+ data_end = data + (end - pltgot);
+
+ printf (_("\nStatic GOT:\n"));
+ printf (_(" Canonical gp value: "));
+ print_vma (ent + 0x7ff0, LONG_HEX);
+ printf ("\n\n");
+
+ /* In a dynamic binary GOT[0] is reserved for the dynamic
+ loader to store the lazy resolver pointer, however in
+ a static binary it may well have been omitted and GOT
+ reduced to a table of addresses.
+ PR 21344: Check for the entry being fully available
+ before fetching it. */
+ if (data
+ && data + ent - pltgot + addr_size <= data_end
+ && byte_get (data + ent - pltgot, addr_size) == 0)
+ {
+ printf (_(" Reserved entries:\n"));
+ printf (_(" %*s %10s %*s\n"),
+ addr_size * 2, _("Address"), _("Access"),
+ addr_size * 2, _("Value"));
+ ent = print_mips_got_entry (data, pltgot, ent, data_end);
+ printf ("\n");
+ if (ent == (bfd_vma) -1)
+ goto sgot_print_fail;
+
+ /* Check for the MSB of GOT[1] being set, identifying a
+ GNU object. This entry will be used by some runtime
+ loaders, to store the module pointer. Otherwise this
+ is an ordinary local entry.
+ PR 21344: Check for the entry being fully available
+ before fetching it. */
+ if (data
+ && data + ent - pltgot + addr_size <= data_end
+ && (byte_get (data + ent - pltgot, addr_size)
+ >> (addr_size * 8 - 1)) != 0)
+ {
+ ent = print_mips_got_entry (data, pltgot, ent, data_end);
+ printf ("\n");
+ if (ent == (bfd_vma) -1)
+ goto sgot_print_fail;
+ }
+ printf ("\n");
+ }
+
+ if (ent < end)
+ {
+ printf (_(" Local entries:\n"));
+ printf (" %*s %10s %*s\n",
+ addr_size * 2, _("Address"), _("Access"),
+ addr_size * 2, _("Value"));
+ while (ent < end)
+ {
+ ent = print_mips_got_entry (data, pltgot, ent, data_end);
+ printf ("\n");
+ if (ent == (bfd_vma) -1)
+ goto sgot_print_fail;
+ }
+ printf ("\n");
+ }
+
+ sgot_print_fail:
+ if (data)
+ free (data);
+ }
+ return res;
+ }
for (entry = dynamic_section;
/* PR 17531 file: 012-50589-0.004. */