diff options
author | Andreas Krebbel <krebbel@linux.vnet.ibm.com> | 2017-12-21 13:12:03 +0100 |
---|---|---|
committer | Andreas Krebbel <krebbel@linux.ibm.com> | 2018-07-18 13:20:06 +0200 |
commit | afca762f598d453c563f244cd3777715b1a0cb72 (patch) | |
tree | 92e833006f40885640255ed17a2c5d46e7057f64 /ld | |
parent | a38137289e91fd548fc27fb6566a439233b94d65 (diff) | |
download | gdb-afca762f598d453c563f244cd3777715b1a0cb72.zip gdb-afca762f598d453c563f244cd3777715b1a0cb72.tar.gz gdb-afca762f598d453c563f244cd3777715b1a0cb72.tar.bz2 |
S/390: Improve partial relro support for 64 bit
Currently on S/390 the .got.plt always comes first which prevents the
GNU_RELRO segment from being extended across the non-plt GOT entries.
Just swapping both unfortunately is not that simple since our ABI
requires the _GLOBAL_OFFSET_TABLE_ symbol to point to the very
beginning of the entire GOT. Of the 3 magic GOT entries the first is
accessed via got pointer while second and third are being accessed via
DT_PLTGOT. In order to keep them together we make DT_PLTGOT to point
to the .got instead of .got.plt. However, this violates an assumption
in the dynamic linker prelink undo code about the GOTPLT entries
starting at DT_PLTGOT + 3. We got rid of this requirement with a
Glibc patch already in version 2.24:
https://sourceware.org/ml/libc-alpha/2016-06/msg01302.html
So the S/390 relro GOT layout will look like this with this patch:
+----------------------------------+
|got[0]: DYNAMIC | <--- _GLOBAL_OFFSET_TABLE_ == DT_PLTGOT .got
|got[1]: link_map parm |
|got[2]: &_dl_runtime_resolve |
+----------------------------------+
| | non-plt GOT entries
| |
| |
+----------------------------------+
| | <--- .gotplt, PLT GOT entries
| |
| |
| |
+----------------------------------+
The patch detects the current layout in size_dynamic_section in order
to deal also with linker scripts not generated by this ld version.
With partial relro enabled we pick a linker script where .got and
.got.plt are swapped which then triggers the rest of the logic.
ld/ChangeLog:
2018-07-18 Andreas Krebbel <krebbel@linux.ibm.com>
* emulparams/elf64_s390.sh: Define GENERATE_RELRO_SCRIPT and
SEPARATE_GOTPLT.
* testsuite/ld-s390/gotreloc_64-relro-1.dd: New test.
* testsuite/ld-s390/gotreloc_64-norelro-1.dd: Renamed from ...
* testsuite/ld-s390/gotreloc_64-1.dd: ... this.
* testsuite/ld-s390/s390.exp: Split the GOT testcase into two.
bfd/ChangeLog:
2018-07-18 Andreas Krebbel <krebbel@linux.ibm.com>
* elf-s390-common.c (s390_gotplt_after_got_p): New function.
(s390_got_pointer): New function.
(s390_got_offset): New function.
(s390_gotplt_offset): New function.
* elf64-s390.c (allocate_dynrelocs): Adjust comment.
(elf_s390_size_dynamic_sections): Move space for magic GOT entries
from .got.plt to .got if necessary and pick the right location for
_GLOBAL_OFFSET_TABLE_.
(elf_s390_relocate_section): Use the wrapper functions from
elf-s390-common.c to deal with both possible layouts (either .got
or .got.plt first).
(elf_s390_finish_dynamic_sections): Likewise.
(elf_s390_finish_dynamic_symbol): Make the location of the GOT
magic entries conditional.
Diffstat (limited to 'ld')
-rw-r--r-- | ld/emulparams/elf64_s390.sh | 3 | ||||
-rw-r--r-- | ld/testsuite/ld-s390/gotreloc_64-norelro-1.dd (renamed from ld/testsuite/ld-s390/gotreloc_64-1.dd) | 0 | ||||
-rw-r--r-- | ld/testsuite/ld-s390/gotreloc_64-relro-1.dd | 12 | ||||
-rw-r--r-- | ld/testsuite/ld-s390/s390.exp | 11 |
4 files changed, 23 insertions, 3 deletions
diff --git a/ld/emulparams/elf64_s390.sh b/ld/emulparams/elf64_s390.sh index 5309774..8d02042 100644 --- a/ld/emulparams/elf64_s390.sh +++ b/ld/emulparams/elf64_s390.sh @@ -11,9 +11,12 @@ NOP=0x07070707 TEMPLATE_NAME=elf32 GENERATE_SHLIB_SCRIPT=yes GENERATE_PIE_SCRIPT=yes +GENERATE_RELRO_SCRIPT=yes NO_SMALL_DATA=yes EXTRA_EM_FILE=s390 IREL_IN_PLT= +SEPARATE_GOTPLT=0 +test -z "$RELRO" && unset SEPARATE_GOTPLT # Treat a host that matches the target with the possible exception of "x" # in the name as if it were native. diff --git a/ld/testsuite/ld-s390/gotreloc_64-1.dd b/ld/testsuite/ld-s390/gotreloc_64-norelro-1.dd index 8c8c619..8c8c619 100644 --- a/ld/testsuite/ld-s390/gotreloc_64-1.dd +++ b/ld/testsuite/ld-s390/gotreloc_64-norelro-1.dd diff --git a/ld/testsuite/ld-s390/gotreloc_64-relro-1.dd b/ld/testsuite/ld-s390/gotreloc_64-relro-1.dd new file mode 100644 index 0000000..36f5001 --- /dev/null +++ b/ld/testsuite/ld-s390/gotreloc_64-relro-1.dd @@ -0,0 +1,12 @@ +tmpdir/gotreloc_64-1: file format elf64-s390 + +Disassembly of section .text: + +.* <foo>: +.*: c0 10 00 00 00 0e [ ]*larl %r1,.* <bar> +.*: c0 10 00 00 00 0b [ ]*larl %r1,.* <bar> +.*: c4 1d 00 00 0f 1a [ ]*lrl %r1,.* <_GLOBAL_OFFSET_TABLE_\+0x18> +.*: 58 10 c0 18 [ ]*l %r1,24\(%r12\) +.*: e3 10 c0 18 00 58 [ ]*ly %r1,24\(%r12\) +.* <bar>: +.*: 00 00 01 23 .long 0x00000123 diff --git a/ld/testsuite/ld-s390/s390.exp b/ld/testsuite/ld-s390/s390.exp index e391841..1934d92 100644 --- a/ld/testsuite/ld-s390/s390.exp +++ b/ld/testsuite/ld-s390/s390.exp @@ -70,10 +70,15 @@ set s390xtests { {{readelf -WSsrl tlsbin_64.rd} {objdump -dzrj.text tlsbin_64.dd} {objdump -sj.got tlsbin_64.sd} {objdump -sj.tdata tlsbin_64.td}} "tlsbin_64"} - {"GOT: symbol address load from got to larl" - "-shared -melf64_s390 --hash-style=sysv --version-script=gotreloc-1.ver" "" + {"GOT: norelro symbol address load from got to larl" + "-shared -melf64_s390 -z norelro --hash-style=sysv --version-script=gotreloc-1.ver" "" + "-m64" {gotreloc-1.s} + {{objdump -dzrj.text gotreloc_64-norelro-1.dd}} + "gotreloc_64-1"} + {"GOT: relro symbol address load from got to larl" + "-shared -melf64_s390 -z relro --hash-style=sysv --version-script=gotreloc-1.ver" "" "-m64" {gotreloc-1.s} - {{objdump -dzrj.text gotreloc_64-1.dd}} + {{objdump -dzrj.text gotreloc_64-relro-1.dd}} "gotreloc_64-1"} {"PLT: offset test" "-shared -m elf64_s390 -dT pltoffset-1.ld" "" |