From bd7ab16b4537788ad53521c45469a1bdae84ad4a Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Tue, 13 Feb 2018 07:34:22 -0800 Subject: x86-64: Generate branch with PLT32 relocation Since there is no need to prepare for PLT branch on x86-64, generate R_X86_64_PLT32, instead of R_X86_64_PC32, if possible, which can be used as a marker for 32-bit PC-relative branches. To compile Linux kernel, this patch: From: "H.J. Lu" Subject: [PATCH] x86: Treat R_X86_64_PLT32 as R_X86_64_PC32 On i386, there are 2 types of PLTs, PIC and non-PIC. PIE and shared objects must use PIC PLT. To use PIC PLT, you need to load _GLOBAL_OFFSET_TABLE_ into EBX first. There is no need for that on x86-64 since x86-64 uses PC-relative PLT. On x86-64, for 32-bit PC-relative branches, we can generate PLT32 relocation, instead of PC32 relocation, which can also be used as a marker for 32-bit PC-relative branches. Linker can always reduce PLT32 relocation to PC32 if function is defined locally. Local functions should use PC32 relocation. As far as Linux kernel is concerned, R_X86_64_PLT32 can be treated the same as R_X86_64_PC32 since Linux kernel doesn't use PLT. is needed. It is available on hjl/plt32/master branch at https://github.com/hjl-tools/linux bfd/ PR gas/22791 * elf64-x86-64.c (is_32bit_relative_branch): Removed. (elf_x86_64_relocate_section): Check PIC relocations in PIE. Remove is_32bit_relative_branch usage. Disallow PC32 reloc against protected function in shared object. gas/ PR gas/22791 * config/tc-i386.c (need_plt32_p): New function. (output_jump): Generate BFD_RELOC_X86_64_PLT32 if possible. (md_estimate_size_before_relax): Likewise. * testsuite/gas/i386/reloc64.d: Updated. * testsuite/gas/i386/x86-64-jump.d: Likewise. * testsuite/gas/i386/x86-64-mpx-branch-1.d: Likewise. * testsuite/gas/i386/x86-64-mpx-branch-2.d: Likewise. * testsuite/gas/i386/x86-64-relax-2.d: Likewise. * testsuite/gas/i386/x86-64-relax-3.d: Likewise. * testsuite/gas/i386/ilp32/reloc64.d: Likewise. * testsuite/gas/i386/ilp32/x86-64-branch.d: Likewise. ld/ PR gas/22791 * testsuite/ld-x86-64/mpx1c.rd: Updated. * testsuite/ld-x86-64/pr22791-1.err: New file. * testsuite/ld-x86-64/pr22791-1a.c: Likewise. * testsuite/ld-x86-64/pr22791-1b.s: Likewise. * testsuite/ld-x86-64/pr22791-2.rd: Likewise. * testsuite/ld-x86-64/pr22791-2a.s: Likewise. * testsuite/ld-x86-64/pr22791-2b.c: Likewise. * testsuite/ld-x86-64/pr22791-2c.s: Likewise. * testsuite/ld-x86-64/x86-64.exp: Run PR ld/22791 tests. --- ld/ChangeLog | 13 ++++++++++ ld/testsuite/ld-x86-64/mpx1c.rd | 2 +- ld/testsuite/ld-x86-64/pr22791-1.err | 2 ++ ld/testsuite/ld-x86-64/pr22791-1a.c | 4 +++ ld/testsuite/ld-x86-64/pr22791-1b.s | 6 +++++ ld/testsuite/ld-x86-64/pr22791-2.rd | 6 +++++ ld/testsuite/ld-x86-64/pr22791-2a.s | 8 ++++++ ld/testsuite/ld-x86-64/pr22791-2b.c | 7 ++++++ ld/testsuite/ld-x86-64/pr22791-2c.s | 12 +++++++++ ld/testsuite/ld-x86-64/x86-64.exp | 47 ++++++++++++++++++++++++++++++++++++ 10 files changed, 106 insertions(+), 1 deletion(-) create mode 100644 ld/testsuite/ld-x86-64/pr22791-1.err create mode 100644 ld/testsuite/ld-x86-64/pr22791-1a.c create mode 100644 ld/testsuite/ld-x86-64/pr22791-1b.s create mode 100644 ld/testsuite/ld-x86-64/pr22791-2.rd create mode 100644 ld/testsuite/ld-x86-64/pr22791-2a.s create mode 100644 ld/testsuite/ld-x86-64/pr22791-2b.c create mode 100644 ld/testsuite/ld-x86-64/pr22791-2c.s (limited to 'ld') diff --git a/ld/ChangeLog b/ld/ChangeLog index c5b35e6..a173b62 100644 --- a/ld/ChangeLog +++ b/ld/ChangeLog @@ -1,3 +1,16 @@ +2018-02-13 H.J. Lu + + PR gas/22791 + * testsuite/ld-x86-64/mpx1c.rd: Updated. + * testsuite/ld-x86-64/pr22791-1.err: New file. + * testsuite/ld-x86-64/pr22791-1a.c: Likewise. + * testsuite/ld-x86-64/pr22791-1b.s: Likewise. + * testsuite/ld-x86-64/pr22791-2.rd: Likewise. + * testsuite/ld-x86-64/pr22791-2a.s: Likewise. + * testsuite/ld-x86-64/pr22791-2b.c: Likewise. + * testsuite/ld-x86-64/pr22791-2c.s: Likewise. + * testsuite/ld-x86-64/x86-64.exp: Run PR ld/22791 tests. + 2018-02-13 Alan Modra PR 22836 diff --git a/ld/testsuite/ld-x86-64/mpx1c.rd b/ld/testsuite/ld-x86-64/mpx1c.rd index d3b292c..d66524c 100644 --- a/ld/testsuite/ld-x86-64/mpx1c.rd +++ b/ld/testsuite/ld-x86-64/mpx1c.rd @@ -1,3 +1,3 @@ #... -[0-9a-f ]+R_X86_64_PC32 +0+ +.* +[0-9a-f ]+R_X86_64_PLT32 +0+ +.* #... diff --git a/ld/testsuite/ld-x86-64/pr22791-1.err b/ld/testsuite/ld-x86-64/pr22791-1.err new file mode 100644 index 0000000..5500fa5 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr22791-1.err @@ -0,0 +1,2 @@ +.*relocation R_X86_64_PC32 against symbol `foo' can not be used when making a PIE object; recompile with -fPIC +#... diff --git a/ld/testsuite/ld-x86-64/pr22791-1a.c b/ld/testsuite/ld-x86-64/pr22791-1a.c new file mode 100644 index 0000000..cd0130c --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr22791-1a.c @@ -0,0 +1,4 @@ +void +foo (void) +{ +} diff --git a/ld/testsuite/ld-x86-64/pr22791-1b.s b/ld/testsuite/ld-x86-64/pr22791-1b.s new file mode 100644 index 0000000..9751db4 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr22791-1b.s @@ -0,0 +1,6 @@ + .text + .globl main + .type main, @function +main: + movl foo(%rip), %eax + .size main, .-main diff --git a/ld/testsuite/ld-x86-64/pr22791-2.rd b/ld/testsuite/ld-x86-64/pr22791-2.rd new file mode 100644 index 0000000..70deb30 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr22791-2.rd @@ -0,0 +1,6 @@ +#failif +#... +.*\(TEXTREL\).* +#... +[0-9a-f ]+R_X86_64_NONE.* +#... diff --git a/ld/testsuite/ld-x86-64/pr22791-2a.s b/ld/testsuite/ld-x86-64/pr22791-2a.s new file mode 100644 index 0000000..0a85502 --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr22791-2a.s @@ -0,0 +1,8 @@ + .text + .p2align 4,,15 + .globl foo + .type foo, @function +foo: + jmp bar + .size foo, .-foo + .section .note.GNU-stack,"",@progbits diff --git a/ld/testsuite/ld-x86-64/pr22791-2b.c b/ld/testsuite/ld-x86-64/pr22791-2b.c new file mode 100644 index 0000000..79ef27c --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr22791-2b.c @@ -0,0 +1,7 @@ +#include + +void +bar (void) +{ + puts ("PASS"); +} diff --git a/ld/testsuite/ld-x86-64/pr22791-2c.s b/ld/testsuite/ld-x86-64/pr22791-2c.s new file mode 100644 index 0000000..1460d1b --- /dev/null +++ b/ld/testsuite/ld-x86-64/pr22791-2c.s @@ -0,0 +1,12 @@ + .text + .p2align 4,,15 + .globl main + .type main, @function +main: + subq $8, %rsp + call foo + xorl %eax, %eax + addq $8, %rsp + ret + .size main, .-main + .section .note.GNU-stack,"",@progbits diff --git a/ld/testsuite/ld-x86-64/x86-64.exp b/ld/testsuite/ld-x86-64/x86-64.exp index af3afcc..a649de8 100644 --- a/ld/testsuite/ld-x86-64/x86-64.exp +++ b/ld/testsuite/ld-x86-64/x86-64.exp @@ -1152,6 +1152,44 @@ if { [isnative] && [which $CC] != 0 } { {readelf -lW pr22393-3b.rd}} \ "pr22393-3-static" \ ] \ + [list \ + "Build pr22791-1.so" \ + "-shared" \ + "-fPIC" \ + { pr22791-1a.c } \ + {} \ + "pr22791-1.so" \ + ] \ + [list \ + "Build pr22791-1" \ + "-pie -Wl,--no-as-needed tmpdir/pr22791-1.so" \ + "$NOPIE_CFLAGS" \ + { pr22791-1b.s } \ + {{error_output "pr22791-1.err"}} \ + "pr22791-1" \ + ] \ + [list \ + "Build pr22791-2a.o" \ + "" \ + "$NOPIE_CFLAGS" \ + { pr22791-2a.s } \ + ] \ + [list \ + "Build pr22791-2.so" \ + "-shared tmpdir/pr22791-2a.o" \ + "-fPIC" \ + { pr22791-2b.c } \ + {{readelf -drW pr22791-2.rd}} \ + "pr22791-2.so" \ + ] \ + [list \ + "Build pr22791-2" \ + "-pie -Wl,--no-as-needed tmpdir/pr22791-2.so" \ + "$NOPIE_CFLAGS" \ + { pr22791-2c.s } \ + {{readelf -drW pr22791-2.rd}} \ + "pr22791-2" \ + ] \ ] if {[istarget "x86_64-*-linux*-gnux32"]} { @@ -1477,6 +1515,15 @@ if { [isnative] && [which $CC] != 0 } { "pr22393-3-static" \ "pass.out" \ ] \ + [list \ + "Run pr22791-2" \ + "-pie -Wl,--no-as-needed tmpdir/pr22791-2.so" \ + "" \ + { pr22791-2c.s } \ + "pr22791-2" \ + "pass.out" \ + "$NOPIE_CFLAGS" \ + ] \ ] # Run-time tests which require working ifunc attribute support. -- cgit v1.1