binutils/
authorRichard Sandiford <rdsandiford@googlemail.com>
Thu, 20 Mar 2008 10:53:11 +0000 (10:53 +0000)
committerRichard Sandiford <rdsandiford@googlemail.com>
Thu, 20 Mar 2008 10:53:11 +0000 (10:53 +0000)
* readelf.c (print_mips_got_entry): New function.
(process_mips_specific): Print GOT information.

ld/testsuite/
* ld-mips-elf/got-dump-1.d, ld-mips-elf/got-dump-1.s,
ld-mips-elf/got-dump-1.ld, ld-mips-elf/got-dump-2.d,
ld-mips-elf/got-dump-2.s, ld-mips-elf/got-dump-2.ld: New tests.
* ld-mips-elf/mips-elf.exp: Run them.

binutils/ChangeLog
binutils/readelf.c
ld/testsuite/ChangeLog
ld/testsuite/ld-mips-elf/got-dump-1.d [new file with mode: 0644]
ld/testsuite/ld-mips-elf/got-dump-1.ld [new file with mode: 0644]
ld/testsuite/ld-mips-elf/got-dump-1.s [new file with mode: 0644]
ld/testsuite/ld-mips-elf/got-dump-2.d [new file with mode: 0644]
ld/testsuite/ld-mips-elf/got-dump-2.ld [new file with mode: 0644]
ld/testsuite/ld-mips-elf/got-dump-2.s [new file with mode: 0644]
ld/testsuite/ld-mips-elf/mips-elf.exp

index d3dc8b681c6245d41c2f169a6197b2e2c6484cfd..f7dedebccab67d64bba5fac73299d5ca601a8e6f 100644 (file)
@@ -1,3 +1,8 @@
+2008-03-20  Richard Sandiford  <rsandifo@nildram.co.uk>
+
+       * readelf.c (print_mips_got_entry): New function.
+       (process_mips_specific): Print GOT information.
+
 2008-03-17  Ralf Wildenhues  <Ralf.Wildenhues@gmx.de>
 
        * aclocal.m4: Regenerate.
index e9c380ff3a58ff70802fc1adeba0a5291cbec3f2..2807f268332925c605bcaadb4b49eef1f8b671df 100644 (file)
@@ -9125,6 +9125,33 @@ process_power_specific (FILE *file)
                             display_power_gnu_attribute);
 }
 
+/* DATA points to the contents of a MIPS GOT that starts at VMA PLTGOT.
+   Print the Address, Access and Initial fields of an entry at VMA ADDR
+   and return the VMA of the next entry.  */
+
+static bfd_vma
+print_mips_got_entry (unsigned char *data, bfd_vma pltgot, bfd_vma addr)
+{
+  printf ("  ");
+  print_vma (addr, LONG_HEX);
+  printf (" ");
+  if (addr < pltgot + 0xfff0)
+    printf ("%6d(gp)", (int) (addr - pltgot - 0x7ff0));
+  else
+    printf ("%10s", "");
+  printf (" ");
+  if (data == NULL)
+    printf ("%*s", is_32bit_elf ? 8 : 16, "<unknown>");
+  else
+    {
+      bfd_vma entry;
+
+      entry = byte_get (data + addr - pltgot, is_32bit_elf ? 4 : 8);
+      print_vma (entry, LONG_HEX);
+    }
+  return addr + (is_32bit_elf ? 4 : 8);
+}
+
 static int
 process_mips_specific (FILE *file)
 {
@@ -9134,6 +9161,10 @@ process_mips_specific (FILE *file)
   size_t conflictsno = 0;
   size_t options_offset = 0;
   size_t conflicts_offset = 0;
+  bfd_vma pltgot = 0;
+  bfd_vma local_gotno = 0;
+  bfd_vma gotsym = 0;
+  bfd_vma symtabno = 0;
 
   process_attributes (file, NULL, SHT_GNU_ATTRIBUTES, NULL,
                      display_mips_gnu_attribute);
@@ -9165,6 +9196,17 @@ process_mips_specific (FILE *file)
       case DT_MIPS_CONFLICTNO:
        conflictsno = entry->d_un.d_val;
        break;
+      case DT_PLTGOT:
+       pltgot = entry->d_un.d_val;
+      case DT_MIPS_LOCAL_GOTNO:
+       local_gotno = entry->d_un.d_val;
+       break;
+      case DT_MIPS_GOTSYM:
+       gotsym = entry->d_un.d_val;
+       break;
+      case DT_MIPS_SYMTABNO:
+       symtabno = entry->d_un.d_val;
+       break;
       default:
        break;
       }
@@ -9515,6 +9557,87 @@ process_mips_specific (FILE *file)
       free (iconf);
     }
 
+  if (pltgot != 0 && local_gotno != 0)
+    {
+      bfd_vma entry, local_end, global_end;
+      size_t addr_size, i, offset;
+      unsigned char *data;
+
+      entry = pltgot;
+      addr_size = (is_32bit_elf ? 4 : 8);
+      local_end = pltgot + local_gotno * addr_size;
+      global_end = local_end + (symtabno - gotsym) * addr_size;
+
+      offset = offset_from_vma (file, pltgot, global_end - pltgot);
+      data = get_data (NULL, file, offset, global_end - pltgot, 1, _("GOT"));
+      printf (_("\nPrimary GOT:\n"));
+      printf (_(" Canonical gp value: "));
+      print_vma (pltgot + 0x7ff0, LONG_HEX);
+      printf ("\n\n");
+
+      printf (_(" Reserved entries:\n"));
+      printf (_("  %*s %10s %*s Purpose\n"),
+             addr_size * 2, "Address", "Access",
+             addr_size * 2, "Initial");
+      entry = print_mips_got_entry (data, pltgot, entry);
+      printf (" Lazy resolver\n");
+      if (data
+         && (byte_get (data + entry - pltgot, addr_size)
+             >> (addr_size * 8 - 1)) != 0)
+       {
+         entry = print_mips_got_entry (data, pltgot, entry);
+         printf (" Module pointer (GNU extension)\n");
+       }
+      printf ("\n");
+
+      if (entry < local_end)
+       {
+         printf (_(" Local entries:\n"));
+         printf (_("  %*s %10s %*s\n"),
+                 addr_size * 2, "Address", "Access",
+                 addr_size * 2, "Initial");
+         while (entry < local_end)
+           {
+             entry = print_mips_got_entry (data, pltgot, entry);
+             printf ("\n");
+           }
+         printf ("\n");
+       }
+
+      if (gotsym < symtabno)
+       {
+         int sym_width;
+
+         printf (_(" Global entries:\n"));
+         printf (_("  %*s %10s %*s %*s %-7s %3s %s\n"),
+                 addr_size * 2, "Address", "Access",
+                 addr_size * 2, "Initial",
+                 addr_size * 2, "Sym.Val.", "Type", "Ndx", "Name");
+         sym_width = (is_32bit_elf ? 80 : 160) - 28 - addr_size * 6 - 1;
+         for (i = gotsym; i < symtabno; i++)
+           {
+             Elf_Internal_Sym *psym;
+
+             psym = dynamic_symbols + i;
+             entry = print_mips_got_entry (data, pltgot, entry);
+             printf (" ");
+             print_vma (psym->st_value, LONG_HEX);
+             printf (" %-7s %3s ",
+                     get_symbol_type (ELF_ST_TYPE (psym->st_info)),
+                     get_symbol_index_type (psym->st_shndx));
+             if (VALID_DYNAMIC_NAME (psym->st_name))
+               print_symbol (sym_width, GET_DYNAMIC_NAME (psym->st_name));
+             else
+               printf ("<corrupt: %14ld>", psym->st_name);
+             printf ("\n");
+           }
+         printf ("\n");
+       }
+
+      if (data)
+       free (data);
+    }
+
   return 1;
 }
 
index 2068cb9a1e52f7c913d0555bd13c57b377e355eb..92a4488deb0ce765ab90069aba5319c34b29a36e 100644 (file)
@@ -1,3 +1,10 @@
+2008-03-20  Richard Sandiford  <rsandifo@nildram.co.uk>
+
+       * ld-mips-elf/got-dump-1.d, ld-mips-elf/got-dump-1.s,
+       ld-mips-elf/got-dump-1.ld, ld-mips-elf/got-dump-2.d,
+       ld-mips-elf/got-dump-2.s, ld-mips-elf/got-dump-2.ld: New tests.
+       * ld-mips-elf/mips-elf.exp: Run them.
+
 2008-03-20  Richard Sandiford  <rsandifo@nildram.co.uk>
 
        * ld-mips-elf/elf-rel-got-n64-linux.d: Expect bit 63 rather than
diff --git a/ld/testsuite/ld-mips-elf/got-dump-1.d b/ld/testsuite/ld-mips-elf/got-dump-1.d
new file mode 100644 (file)
index 0000000..eaf9c6b
--- /dev/null
@@ -0,0 +1,25 @@
+#name: GOT dump (readelf -A) test 1
+#source: got-dump-1.s
+#as: -mips3
+#ld: -Tgot-dump-1.ld -shared
+#readelf: -A
+
+Primary GOT:
+ Canonical gp value: 00068000
+
+ Reserved entries:
+   Address     Access  Initial Purpose
+  00060010 -32752\(gp\) 00000000 Lazy resolver
+  00060014 -32748\(gp\) 80000000 Module pointer \(GNU extension\)
+
+ Local entries:
+   Address     Access  Initial
+  00060018 -32744\(gp\) 00060000
+  0006001c -32740\(gp\) 00060004
+
+ Global entries:
+   Address     Access  Initial Sym.Val. Type    Ndx Name
+  00060020 -32736\(gp\) 00050020 00050020 FUNC    UND extern
+  00060024 -32732\(gp\) 00000000 00000000 NOTYPE  UND undef
+  00060028 -32728\(gp\) 00050000 00050000 FUNC      7 glob
+
diff --git a/ld/testsuite/ld-mips-elf/got-dump-1.ld b/ld/testsuite/ld-mips-elf/got-dump-1.ld
new file mode 100644 (file)
index 0000000..4fe5c1a
--- /dev/null
@@ -0,0 +1,19 @@
+SECTIONS
+{
+  . = 0x40000;
+  .reginfo : { *(.reginfo) }
+  .dynamic : { *(.dynamic) }
+  .hash : { *(.hash) }
+  .dynsym : { *(.dynsym) }
+  .dynstr : { *(.dynstr) }
+  .rel.dyn : { *(.rel.dyn) }
+
+  . = 0x50000;
+  .text : { *(.text) }
+  .MIPS.stubs : { *(.MIPS.stubs) }
+
+  . = 0x60000;
+  .data : { *(.data) }
+  _gp = ALIGN (16) + 0x7ff0;
+  .got : { *(.got) }
+}
diff --git a/ld/testsuite/ld-mips-elf/got-dump-1.s b/ld/testsuite/ld-mips-elf/got-dump-1.s
new file mode 100644 (file)
index 0000000..d6c318e
--- /dev/null
@@ -0,0 +1,22 @@
+       .global glob
+       .ent    glob
+glob:
+       lw      $4,%got(local)($28)
+       addiu   $4,$4,%lo(local)
+       lw      $4,%got(hidden)($28)
+       lw      $4,%call16(glob)($28)
+       lw      $4,%call16(extern)($28)
+       .end    glob
+
+       .data
+       .type   local,%object
+       .size   local,4
+local:
+       .word   undef
+
+       .globl  hidden
+       .hidden hidden
+       .type   hidden,%object
+       .size   hidden,4
+hidden:
+       .word   0
diff --git a/ld/testsuite/ld-mips-elf/got-dump-2.d b/ld/testsuite/ld-mips-elf/got-dump-2.d
new file mode 100644 (file)
index 0000000..1e656f0
--- /dev/null
@@ -0,0 +1,25 @@
+#name: GOT dump (readelf -A) test 2
+#source: got-dump-2.s
+#as: -mips3 -EB -64
+#ld: -Tgot-dump-2.ld -shared -melf64btsmip
+#readelf: -A
+
+Primary GOT:
+ Canonical gp value: 0001236000008000
+
+ Reserved entries:
+           Address     Access          Initial Purpose
+  0001236000000010 -32752\(gp\) 0000000000000000 Lazy resolver
+  0001236000000018 -32744\(gp\) 8000000000000000 Module pointer \(GNU extension\)
+
+ Local entries:
+           Address     Access          Initial
+  0001236000000020 -32736\(gp\) 0001236000000000
+  0001236000000028 -32728\(gp\) 0001236000000008
+
+ Global entries:
+           Address     Access          Initial         Sym.Val. Type    Ndx Name
+  0001236000000030 -32720\(gp\) 0001235000000020 0001235000000020 FUNC    UND extern
+  0001236000000038 -32712\(gp\) 0000000000000000 0000000000000000 NOTYPE  UND undef
+  0001236000000040 -32704\(gp\) 0001235000000000 0001235000000000 FUNC      7 glob
+
diff --git a/ld/testsuite/ld-mips-elf/got-dump-2.ld b/ld/testsuite/ld-mips-elf/got-dump-2.ld
new file mode 100644 (file)
index 0000000..cab0f4b
--- /dev/null
@@ -0,0 +1,18 @@
+SECTIONS
+{
+  . = 0x1234000000000;
+  .dynamic : { *(.dynamic) }
+  .hash : { *(.hash) }
+  .dynsym : { *(.dynsym) }
+  .dynstr : { *(.dynstr) }
+  .rel.dyn : { *(.rel.dyn) }
+
+  . = 0x1235000000000;
+  .text : { *(.text) }
+  .MIPS.stubs : { *(.MIPS.stubs) }
+
+  . = 0x1236000000000;
+  .data : { *(.data) }
+  _gp = ALIGN (16) + 0x7ff0;
+  .got : { *(.got) }
+}
diff --git a/ld/testsuite/ld-mips-elf/got-dump-2.s b/ld/testsuite/ld-mips-elf/got-dump-2.s
new file mode 100644 (file)
index 0000000..5a237fe
--- /dev/null
@@ -0,0 +1,22 @@
+       .global glob
+       .ent    glob
+glob:
+       ld      $4,%got_page(local)($28)
+       daddiu  $4,$4,%got_ofst(local)
+       ld      $4,%got_disp(hidden)($28)
+       ld      $4,%call16(glob)($28)
+       ld      $4,%call16(extern)($28)
+       .end    glob
+
+       .data
+       .type   local,%object
+       .size   local,8
+local:
+       .dword  undef
+
+       .globl  hidden
+       .hidden hidden
+       .type   hidden,%object
+       .size   hidden,8
+hidden:
+       .dword  0
index 404ee2a74ae66dfab20ec2fb4665d4645e39480c..96e42a9da54ddaae59a5f5cf98113b47897593cf 100644 (file)
@@ -156,6 +156,10 @@ if { $linux_gnu } {
        run_dump_test "got-page-2"
     }
     run_dump_test "got-page-3"
+    run_dump_test "got-dump-1"
+    if $has_newabi {
+       run_dump_test "got-dump-2"
+    }
 }
 
 if $has_newabi {