From ccb4c9519b8b4528411a85b654af60c7dd598894 Mon Sep 17 00:00:00 2001 From: Richard Sandiford Date: Thu, 20 Mar 2008 10:53:11 +0000 Subject: [PATCH] binutils/ * 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 | 5 + binutils/readelf.c | 123 +++++++++++++++++++++++++ ld/testsuite/ChangeLog | 7 ++ ld/testsuite/ld-mips-elf/got-dump-1.d | 25 +++++ ld/testsuite/ld-mips-elf/got-dump-1.ld | 19 ++++ ld/testsuite/ld-mips-elf/got-dump-1.s | 22 +++++ ld/testsuite/ld-mips-elf/got-dump-2.d | 25 +++++ ld/testsuite/ld-mips-elf/got-dump-2.ld | 18 ++++ ld/testsuite/ld-mips-elf/got-dump-2.s | 22 +++++ ld/testsuite/ld-mips-elf/mips-elf.exp | 4 + 10 files changed, 270 insertions(+) create mode 100644 ld/testsuite/ld-mips-elf/got-dump-1.d create mode 100644 ld/testsuite/ld-mips-elf/got-dump-1.ld create mode 100644 ld/testsuite/ld-mips-elf/got-dump-1.s create mode 100644 ld/testsuite/ld-mips-elf/got-dump-2.d create mode 100644 ld/testsuite/ld-mips-elf/got-dump-2.ld create mode 100644 ld/testsuite/ld-mips-elf/got-dump-2.s diff --git a/binutils/ChangeLog b/binutils/ChangeLog index d3dc8b681c6..f7dedebccab 100644 --- a/binutils/ChangeLog +++ b/binutils/ChangeLog @@ -1,3 +1,8 @@ +2008-03-20 Richard Sandiford + + * readelf.c (print_mips_got_entry): New function. + (process_mips_specific): Print GOT information. + 2008-03-17 Ralf Wildenhues * aclocal.m4: Regenerate. diff --git a/binutils/readelf.c b/binutils/readelf.c index e9c380ff3a5..2807f268332 100644 --- a/binutils/readelf.c +++ b/binutils/readelf.c @@ -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, ""); + 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 ("", psym->st_name); + printf ("\n"); + } + printf ("\n"); + } + + if (data) + free (data); + } + return 1; } diff --git a/ld/testsuite/ChangeLog b/ld/testsuite/ChangeLog index 2068cb9a1e5..92a4488deb0 100644 --- a/ld/testsuite/ChangeLog +++ b/ld/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2008-03-20 Richard Sandiford + + * 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 * 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 index 00000000000..eaf9c6b7c4f --- /dev/null +++ b/ld/testsuite/ld-mips-elf/got-dump-1.d @@ -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 index 00000000000..4fe5c1a2116 --- /dev/null +++ b/ld/testsuite/ld-mips-elf/got-dump-1.ld @@ -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 index 00000000000..d6c318ebb16 --- /dev/null +++ b/ld/testsuite/ld-mips-elf/got-dump-1.s @@ -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 index 00000000000..1e656f0484b --- /dev/null +++ b/ld/testsuite/ld-mips-elf/got-dump-2.d @@ -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 index 00000000000..cab0f4b2169 --- /dev/null +++ b/ld/testsuite/ld-mips-elf/got-dump-2.ld @@ -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 index 00000000000..5a237fed274 --- /dev/null +++ b/ld/testsuite/ld-mips-elf/got-dump-2.s @@ -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 diff --git a/ld/testsuite/ld-mips-elf/mips-elf.exp b/ld/testsuite/ld-mips-elf/mips-elf.exp index 404ee2a74ae..96e42a9da54 100644 --- a/ld/testsuite/ld-mips-elf/mips-elf.exp +++ b/ld/testsuite/ld-mips-elf/mips-elf.exp @@ -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 { -- 2.30.2