aboutsummaryrefslogtreecommitdiff
path: root/ld/testsuite/ld-mips-elf
diff options
context:
space:
mode:
authorMaciej W. Rozycki <macro@mips.com>2018-06-20 00:37:51 +0100
committerMaciej W. Rozycki <macro@mips.com>2018-06-20 00:37:51 +0100
commit789ff5b6c26ce7e4ebfcfa5a9a695407c17fa4ea (patch)
treece7958d48139f89d91d1137fdeebe4df2c040c27 /ld/testsuite/ld-mips-elf
parent6a382bceadc7228d20746079570a15f115e55d0c (diff)
downloadfsf-binutils-gdb-789ff5b6c26ce7e4ebfcfa5a9a695407c17fa4ea.zip
fsf-binutils-gdb-789ff5b6c26ce7e4ebfcfa5a9a695407c17fa4ea.tar.gz
fsf-binutils-gdb-789ff5b6c26ce7e4ebfcfa5a9a695407c17fa4ea.tar.bz2
PR ld/22966: Fix n64 MIPS `.got.plt' range checks
The addressable signed 32-bit range for n64 MIPS `.got.plt' references is from 0xffffffff7fff8000 to 0x7fff7fff, due to how the composition of an LUI and an LD instruction works for address calculation in the 64-bit addressing mode, such as when CP0.Status.UX=1. We currently have a range check in `mips_finish_exec_plt', however it is not correct as it verifies that the `.got.plt' start address referred is between 0xffffffff80000000 and 0x7fffffff. It is also implemented as an assertion rather than a proper error message despite that the situation can be triggered by user input. Additionally there is no check made for individual `.got.plt' entries referred even though they can be out of range while the `.got.plt' start address is not. Fix all these problems and use the correct range for the check, limiting it to n64 output files, and then issue a proper error message both in `mips_finish_exec_plt' and in `_bfd_mips_elf_finish_dynamic_symbol', suggesting the use of the `-Ttext-segment=...' option that will often work and with the default linker scripts in particular. Add suitable tests covering boundary cases. bfd/ PR ld/22966 * elfxx-mips.c (_bfd_mips_elf_finish_dynamic_symbol): Verify the `.got.plt' entry referred is in range. (mips_finish_exec_plt): Correct the range check for `.got.plt' start. Replace the assertion used for that with a proper error message. ld/ PR ld/22966 * testsuite/ld-mips-elf/n64-plt-1.dd: New test. * testsuite/ld-mips-elf/n64-plt-1.gd: New test. * testsuite/ld-mips-elf/n64-plt-2.ed: New test. * testsuite/ld-mips-elf/n64-plt-3.ed: New test. * testsuite/ld-mips-elf/n64-plt-4.dd: New test. * testsuite/ld-mips-elf/n64-plt-4.gd: New test. * testsuite/ld-mips-elf/n64-plt-1.ld: New test linker script. * testsuite/ld-mips-elf/n64-plt-2.ld: New test linker script. * testsuite/ld-mips-elf/n64-plt-3.ld: New test linker script. * testsuite/ld-mips-elf/n64-plt-4.ld: New test linker script. * testsuite/ld-mips-elf/n64-plt.s: New test source. * testsuite/ld-mips-elf/n64-plt-lib.s: New test source. * testsuite/ld-mips-elf/mips-elf.exp: Run the new tests.
Diffstat (limited to 'ld/testsuite/ld-mips-elf')
-rw-r--r--ld/testsuite/ld-mips-elf/mips-elf.exp44
-rw-r--r--ld/testsuite/ld-mips-elf/n64-plt-1.dd26
-rw-r--r--ld/testsuite/ld-mips-elf/n64-plt-1.gd18
-rw-r--r--ld/testsuite/ld-mips-elf/n64-plt-1.ld22
-rw-r--r--ld/testsuite/ld-mips-elf/n64-plt-2.ed1
-rw-r--r--ld/testsuite/ld-mips-elf/n64-plt-2.ld23
-rw-r--r--ld/testsuite/ld-mips-elf/n64-plt-3.ed1
-rw-r--r--ld/testsuite/ld-mips-elf/n64-plt-3.ld23
-rw-r--r--ld/testsuite/ld-mips-elf/n64-plt-4.dd26
-rw-r--r--ld/testsuite/ld-mips-elf/n64-plt-4.gd18
-rw-r--r--ld/testsuite/ld-mips-elf/n64-plt-4.ld23
-rw-r--r--ld/testsuite/ld-mips-elf/n64-plt-lib.s11
-rw-r--r--ld/testsuite/ld-mips-elf/n64-plt.s9
13 files changed, 245 insertions, 0 deletions
diff --git a/ld/testsuite/ld-mips-elf/mips-elf.exp b/ld/testsuite/ld-mips-elf/mips-elf.exp
index 29e2274..1631d85 100644
--- a/ld/testsuite/ld-mips-elf/mips-elf.exp
+++ b/ld/testsuite/ld-mips-elf/mips-elf.exp
@@ -1167,6 +1167,50 @@ if { $linux_gnu } {
}
}
+# Verify graceful handling of n64 PLT 32-bit range overflows. Given
+# that the alignment of `.got.plt' is 8 the highest usable positive
+# address is 0x7fff7ff8 and the lowest usable negative address is
+# 0xffffffff7fff8000.
+if { $linux_gnu } {
+ run_ld_link_tests [list \
+ [list "Shared library for MIPS n64 PLT 32-bit range tests" \
+ "-shared $abi_ldflags(n64)" "" \
+ "$abi_asflags(n64)" \
+ { n64-plt-lib.s } \
+ {} \
+ "n64-plt-lib.so"] \
+ [list "MIPS n64 PLT 32-bit range test 1" \
+ "$abi_ldflags(n64) -T n64-plt-1.ld -e foo" \
+ "tmpdir/n64-plt-lib.so" \
+ "$abi_asflags(n64)" \
+ { n64-plt.s } \
+ { { objdump -d n64-plt-1.dd } \
+ { readelf -A n64-plt-1.gd } } \
+ "n64-plt-1"] \
+ [list "MIPS n64 PLT 32-bit range test 2" \
+ "$abi_ldflags(n64) -T n64-plt-2.ld -e foo" \
+ "tmpdir/n64-plt-lib.so" \
+ "$abi_asflags(n64)" \
+ { n64-plt.s } \
+ { { ld n64-plt-2.ed } } \
+ "n64-plt-2"] \
+ [list "MIPS n64 PLT 32-bit range test 3" \
+ "$abi_ldflags(n64) -T n64-plt-3.ld -e foo" \
+ "tmpdir/n64-plt-lib.so" \
+ "$abi_asflags(n64)" \
+ { n64-plt.s } \
+ { { ld n64-plt-3.ed } } \
+ "n64-plt-3"] \
+ [list "MIPS n64 PLT 32-bit range test 4" \
+ "$abi_ldflags(n64) -T n64-plt-4.ld -e foo" \
+ "tmpdir/n64-plt-lib.so" \
+ "$abi_asflags(n64)" \
+ { n64-plt.s } \
+ { { objdump -d n64-plt-4.dd } \
+ { readelf -A n64-plt-4.gd } } \
+ "n64-plt-4"]]
+}
+
# PR ld/19908 export class tests.
if { $linux_gnu } {
run_ld_link_tests [list \
diff --git a/ld/testsuite/ld-mips-elf/n64-plt-1.dd b/ld/testsuite/ld-mips-elf/n64-plt-1.dd
new file mode 100644
index 0000000..4c24a9a
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/n64-plt-1.dd
@@ -0,0 +1,26 @@
+.*: +file format .*mips.*
+
+Disassembly of section \.plt:
+
+0000000010000280 <_PROCEDURE_LINKAGE_TABLE_>:
+ 10000280: 3c0e7fff lui t2,0x7fff
+ 10000284: ddd97fe8 ld t9,32744\(t2\)
+ 10000288: 25ce7fe8 addiu t2,t2,32744
+ 1000028c: 030ec023 subu t8,t8,t2
+ 10000290: 03e07825 move t3,ra
+ 10000294: 0018c0c2 srl t8,t8,0x3
+ 10000298: 0320f809 jalr t9
+ 1000029c: 2718fffe addiu t8,t8,-2
+
+00000000100002a0 <bar@plt>:
+ 100002a0: 3c0f7fff lui t3,0x7fff
+ 100002a4: ddf97ff8 ld t9,32760\(t3\)
+ 100002a8: 03200008 jr t9
+ 100002ac: 25f87ff8 addiu t8,t3,32760
+
+Disassembly of section \.text:
+
+00000000100002b0 <foo>:
+ 100002b0: 080000a8 j 100002a0 <bar@plt>
+ 100002b4: 00000000 nop
+ \.\.\.
diff --git a/ld/testsuite/ld-mips-elf/n64-plt-1.gd b/ld/testsuite/ld-mips-elf/n64-plt-1.gd
new file mode 100644
index 0000000..5804e66
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/n64-plt-1.gd
@@ -0,0 +1,18 @@
+Primary GOT:
+ Canonical gp value: 000000007ffffff0
+
+ Reserved entries:
+ Address Access Initial Purpose
+ 000000007fff8000 -32752\(gp\) 0000000000000000 Lazy resolver
+ 000000007fff8008 -32744\(gp\) 8000000000000000 Module pointer \(GNU extension\)
+
+PLT GOT:
+
+ Reserved entries:
+ Address Initial Purpose
+ 000000007fff7fe8 0000000000000000 PLT lazy resolver
+ 000000007fff7ff0 0000000000000000 Module pointer
+
+ Entries:
+ Address Initial Sym\.Val\. Type Ndx Name
+ 000000007fff7ff8 0000000010000280 0000000000000000 FUNC UND bar
diff --git a/ld/testsuite/ld-mips-elf/n64-plt-1.ld b/ld/testsuite/ld-mips-elf/n64-plt-1.ld
new file mode 100644
index 0000000..1ef3106
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/n64-plt-1.ld
@@ -0,0 +1,22 @@
+MEMORY
+{
+ text (rx) : ORIGIN = 0x10000000, LENGTH = 0x10000
+ data (w) : ORIGIN = 0x7fff7fe8, LENGTH = 0x10000
+}
+SECTIONS
+{
+ .dynamic : { *(.dynamic) } >text
+ .hash : { *(.hash) } >text
+ .dynsym : { *(.dynsym) } >text
+ .dynstr : { *(.dynstr) } >text
+ .rel.plt : { *(.rel.plt) } >text
+ .plt : { *(.plt) } >text
+ .text : { *(.text) } >text
+ .interp : { *(.interp) } >text
+ .got.plt : { *(.got.plt) } >data
+ .got : { *(.got) } >data
+ .symtab : { *(.symtab) }
+ .strtab : { *(.strtab) }
+ .shstrtab : { *(.shstrtab) }
+ /DISCARD/ : { *(*) }
+}
diff --git a/ld/testsuite/ld-mips-elf/n64-plt-2.ed b/ld/testsuite/ld-mips-elf/n64-plt-2.ed
new file mode 100644
index 0000000..4a42ec1
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/n64-plt-2.ed
@@ -0,0 +1 @@
+[^\n]*: `\.got\.plt' entry VMA of 0x7fff8000 outside the 32-bit range supported; consider using `-Ttext-segment=\.\.\.'
diff --git a/ld/testsuite/ld-mips-elf/n64-plt-2.ld b/ld/testsuite/ld-mips-elf/n64-plt-2.ld
new file mode 100644
index 0000000..4d2ab48
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/n64-plt-2.ld
@@ -0,0 +1,23 @@
+MEMORY
+{
+ text (rx) : ORIGIN = 0x10000000, LENGTH = 0x10000
+ data (w) : ORIGIN = 0x7fff7ff0, LENGTH = 0x10000
+}
+SECTIONS
+{
+ .dynamic : { *(.dynamic) } >text
+ .hash : { *(.hash) } >text
+ .dynsym : { *(.dynsym) } >text
+ .dynstr : { *(.dynstr) } >text
+ .rel.plt : { *(.rel.plt) } >text
+ .plt : { *(.plt) } >text
+ .text : { *(.text) } >text
+ .interp : { *(.interp) } >text
+ .got.plt : { *(.got.plt) } >data
+ .rld.map : { *(.rld.map) } >data
+ .got : { *(.got) } >data
+ .symtab : { *(.symtab) }
+ .strtab : { *(.strtab) }
+ .shstrtab : { *(.shstrtab) }
+ /DISCARD/ : { *(*) }
+}
diff --git a/ld/testsuite/ld-mips-elf/n64-plt-3.ed b/ld/testsuite/ld-mips-elf/n64-plt-3.ed
new file mode 100644
index 0000000..29a346b
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/n64-plt-3.ed
@@ -0,0 +1 @@
+[^\n]*: `\.got\.plt' start VMA of 0xffffffff7fff7ff0 outside the 32-bit range supported; consider using `-Ttext-segment=\.\.\.'
diff --git a/ld/testsuite/ld-mips-elf/n64-plt-3.ld b/ld/testsuite/ld-mips-elf/n64-plt-3.ld
new file mode 100644
index 0000000..be88c49
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/n64-plt-3.ld
@@ -0,0 +1,23 @@
+MEMORY
+{
+ text (rx) : ORIGIN = 0xffffffff10000000, LENGTH = 0x10000
+ data (w) : ORIGIN = 0xffffffff7fff7ff0, LENGTH = 0x10000
+}
+SECTIONS
+{
+ .dynamic : { *(.dynamic) } >text
+ .hash : { *(.hash) } >text
+ .dynsym : { *(.dynsym) } >text
+ .dynstr : { *(.dynstr) } >text
+ .rel.plt : { *(.rel.plt) } >text
+ .plt : { *(.plt) } >text
+ .text : { *(.text) } >text
+ .interp : { *(.interp) } >text
+ .got.plt : { *(.got.plt) } >data
+ .rld.map : { *(.rld.map) } >data
+ .got : { *(.got) } >data
+ .symtab : { *(.symtab) }
+ .strtab : { *(.strtab) }
+ .shstrtab : { *(.shstrtab) }
+ /DISCARD/ : { *(*) }
+}
diff --git a/ld/testsuite/ld-mips-elf/n64-plt-4.dd b/ld/testsuite/ld-mips-elf/n64-plt-4.dd
new file mode 100644
index 0000000..01c5025
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/n64-plt-4.dd
@@ -0,0 +1,26 @@
+.*: +file format .*mips.*
+
+Disassembly of section \.plt:
+
+ffffffff10000280 <_PROCEDURE_LINKAGE_TABLE_>:
+ffffffff10000280: 3c0e8000 lui t2,0x8000
+ffffffff10000284: ddd98000 ld t9,-32768\(t2\)
+ffffffff10000288: 25ce8000 addiu t2,t2,-32768
+ffffffff1000028c: 030ec023 subu t8,t8,t2
+ffffffff10000290: 03e07825 move t3,ra
+ffffffff10000294: 0018c0c2 srl t8,t8,0x3
+ffffffff10000298: 0320f809 jalr t9
+ffffffff1000029c: 2718fffe addiu t8,t8,-2
+
+ffffffff100002a0 <bar@plt>:
+ffffffff100002a0: 3c0f8000 lui t3,0x8000
+ffffffff100002a4: ddf98010 ld t9,-32752\(t3\)
+ffffffff100002a8: 03200008 jr t9
+ffffffff100002ac: 25f88010 addiu t8,t3,-32752
+
+Disassembly of section \.text:
+
+ffffffff100002b0 <foo>:
+ffffffff100002b0: 080000a8 j ffffffff100002a0 <bar@plt>
+ffffffff100002b4: 00000000 nop
+ \.\.\.
diff --git a/ld/testsuite/ld-mips-elf/n64-plt-4.gd b/ld/testsuite/ld-mips-elf/n64-plt-4.gd
new file mode 100644
index 0000000..f9d1ac9
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/n64-plt-4.gd
@@ -0,0 +1,18 @@
+Primary GOT:
+ Canonical gp value: ffffffff80000010
+
+ Reserved entries:
+ Address Access Initial Purpose
+ ffffffff7fff8020 -32752\(gp\) 0000000000000000 Lazy resolver
+ ffffffff7fff8028 -32744\(gp\) 8000000000000000 Module pointer \(GNU extension\)
+
+PLT GOT:
+
+ Reserved entries:
+ Address Initial Purpose
+ ffffffff7fff8000 0000000000000000 PLT lazy resolver
+ ffffffff7fff8008 0000000000000000 Module pointer
+
+ Entries:
+ Address Initial Sym\.Val\. Type Ndx Name
+ ffffffff7fff8010 ffffffff10000280 0000000000000000 FUNC UND bar
diff --git a/ld/testsuite/ld-mips-elf/n64-plt-4.ld b/ld/testsuite/ld-mips-elf/n64-plt-4.ld
new file mode 100644
index 0000000..e1f602d
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/n64-plt-4.ld
@@ -0,0 +1,23 @@
+MEMORY
+{
+ text (rx) : ORIGIN = 0xffffffff10000000, LENGTH = 0x10000
+ data (w) : ORIGIN = 0xffffffff7fff8000, LENGTH = 0x10000
+}
+SECTIONS
+{
+ .dynamic : { *(.dynamic) } >text
+ .hash : { *(.hash) } >text
+ .dynsym : { *(.dynsym) } >text
+ .dynstr : { *(.dynstr) } >text
+ .rel.plt : { *(.rel.plt) } >text
+ .plt : { *(.plt) } >text
+ .text : { *(.text) } >text
+ .interp : { *(.interp) } >text
+ .got.plt : { *(.got.plt) } >data
+ .rld.map : { *(.rld.map) } >data
+ .got : { *(.got) } >data
+ .symtab : { *(.symtab) }
+ .strtab : { *(.strtab) }
+ .shstrtab : { *(.shstrtab) }
+ /DISCARD/ : { *(*) }
+}
diff --git a/ld/testsuite/ld-mips-elf/n64-plt-lib.s b/ld/testsuite/ld-mips-elf/n64-plt-lib.s
new file mode 100644
index 0000000..40409af
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/n64-plt-lib.s
@@ -0,0 +1,11 @@
+ .abicalls
+ .text
+
+ .globl bar
+ .ent bar
+bar:
+ .frame $sp, 0, $31
+ .mask 0x00000000, 0
+ .fmask 0x00000000, 0
+ jr $31
+ .end bar
diff --git a/ld/testsuite/ld-mips-elf/n64-plt.s b/ld/testsuite/ld-mips-elf/n64-plt.s
new file mode 100644
index 0000000..9732044
--- /dev/null
+++ b/ld/testsuite/ld-mips-elf/n64-plt.s
@@ -0,0 +1,9 @@
+ .abicalls
+ .option pic0
+ .text
+
+ .globl foo
+ .ent foo
+foo:
+ j bar
+ .end foo