diff options
| author | Fangrui Song <maskray@google.com> | 2019-12-10 18:05:36 -0800 |
|---|---|---|
| committer | Fangrui Song <maskray@google.com> | 2020-01-13 23:39:28 -0800 |
| commit | 7cd429f27d4886bb841ed0e3702e970f5f6cccd1 (patch) | |
| tree | 6898daed5534125751930b8aa00bd583186dae62 /lld/test | |
| parent | 0136f226c4e46258ea73fcb994f6559cec4a9aa2 (diff) | |
| download | bcm5719-llvm-7cd429f27d4886bb841ed0e3702e970f5f6cccd1.tar.gz bcm5719-llvm-7cd429f27d4886bb841ed0e3702e970f5f6cccd1.zip | |
[ELF] Add -z force-ibt and -z shstk for Intel Control-flow Enforcement Technology
This patch is a joint work by Rui Ueyama and me based on D58102 by Xiang Zhang.
It adds Intel CET (Control-flow Enforcement Technology) support to lld.
The implementation follows the draft version of psABI which you can
download from https://github.com/hjl-tools/x86-psABI/wiki/X86-psABI.
CET introduces a new restriction on indirect jump instructions so that
you can limit the places to which you can jump to using indirect jumps.
In order to use the feature, you need to compile source files with
-fcf-protection=full.
* IBT is enabled if all input files are compiled with the flag. To force enabling ibt, pass -z force-ibt.
* SHSTK is enabled if all input files are compiled with the flag, or if -z shstk is specified.
IBT-enabled executables/shared objects have two PLT sections, ".plt" and
".plt.sec". For the details as to why we have two sections, please read
the comments.
Reviewed By: xiangzhangllvm
Differential Revision: https://reviews.llvm.org/D59780
Diffstat (limited to 'lld/test')
| -rw-r--r-- | lld/test/ELF/i386-cet.s | 47 | ||||
| -rw-r--r-- | lld/test/ELF/i386-feature-cet.s | 93 | ||||
| -rw-r--r-- | lld/test/ELF/x86-64-cet.s | 48 | ||||
| -rw-r--r-- | lld/test/ELF/x86-64-feature-cet.s | 92 |
4 files changed, 185 insertions, 95 deletions
diff --git a/lld/test/ELF/i386-cet.s b/lld/test/ELF/i386-cet.s deleted file mode 100644 index 125c7977ee2..00000000000 --- a/lld/test/ELF/i386-cet.s +++ /dev/null @@ -1,47 +0,0 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=i386-unknown-linux %s -o %t.o -# RUN: llvm-mc -filetype=obj -triple=i386-unknown-linux %p/Inputs/i386-cet1.s -o %t1.o -# RUN: llvm-mc -filetype=obj -triple=i386-unknown-linux %p/Inputs/i386-cet2.s -o %t2.o -# RUN: llvm-mc -filetype=obj -triple=i386-unknown-linux %p/Inputs/i386-cet3.s -o %t3.o -# RUN: llvm-mc -filetype=obj -triple=i386-unknown-linux %p/Inputs/i386-cet4.s -o %t4.o - -# RUN: ld.lld -e func1 %t.o %t1.o -o %t -# RUN: llvm-readelf -n %t | FileCheck -check-prefix=CET -match-full-lines %s - -# RUN: ld.lld -e func1 %t.o %t2.o -o %t -# RUN: llvm-readelf -n %t | FileCheck -check-prefix=CET -match-full-lines %s - -# CET: Properties: x86 feature: IBT, SHSTK - -# RUN: ld.lld -e func1 %t.o %t3.o -o %t -# RUN: llvm-readelf -S %t | FileCheck -check-prefix=NOCET %s - -# NOCET: Section Headers -# NOCET-NOT: .note.gnu.property - -# RUN: not ld.lld -e func1 %t.o %t3.o -o %t --require-cet 2>&1 \ -# RUN: | FileCheck -check-prefix=ERROR %s -# ERROR: i386-cet.s.tmp3.o: --require-cet: file is not compatible with CET - -# RUN: ld.lld -e func1 %t.o %t4.o -o %t -# RUN: llvm-readelf -n %t | FileCheck -check-prefix=NOSHSTK -match-full-lines %s - -# Check .note.gnu.protery without property SHSTK. -# NOSHSTK: Properties: x86 feature: IBT - -.section ".note.gnu.property", "a" -.long 4 -.long 0xc -.long 0x5 -.asciz "GNU" - -.long 0xc0000002 -.long 4 -.long 3 - -.text -.globl func1 -.type func1,@function -func1: - call func2 - ret diff --git a/lld/test/ELF/i386-feature-cet.s b/lld/test/ELF/i386-feature-cet.s new file mode 100644 index 00000000000..1c59ffabd43 --- /dev/null +++ b/lld/test/ELF/i386-feature-cet.s @@ -0,0 +1,93 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=i386 %s -o %t.o +# RUN: llvm-mc -filetype=obj -triple=i386 %p/Inputs/i386-cet1.s -o %t1.o +# RUN: llvm-mc -filetype=obj -triple=i386 %p/Inputs/i386-cet2.s -o %t2.o +# RUN: llvm-mc -filetype=obj -triple=i386 %p/Inputs/i386-cet3.s -o %t3.o +# RUN: llvm-mc -filetype=obj -triple=i386 %p/Inputs/i386-cet4.s -o %t4.o + +# RUN: ld.lld -e func1 %t.o %t1.o -o %t +# RUN: llvm-readelf -n %t | FileCheck --check-prefix=CET --match-full-lines %s + +# RUN: ld.lld -e func1 %t.o %t2.o -o %t +# RUN: llvm-readelf -n %t | FileCheck --check-prefix=CET --match-full-lines %s + +# CET: Properties: x86 feature: IBT, SHSTK + +# RUN: ld.lld -e func1 %t.o %t3.o -o %t +# RUN: llvm-readelf -S %t | FileCheck --check-prefix=NOCET %s + +# NOCET: Section Headers +# NOCET-NOT: .note.gnu.property + +# RUN: ld.lld -e func1 %t.o %t3.o -o %t -z force-ibt 2>&1 \ +# RUN: | FileCheck --check-prefix=WARN %s +# WARN: {{.*}}.o: -z force-ibt: file does not have GNU_PROPERTY_X86_FEATURE_1_IBT property + +# RUN: ld.lld -e func1 %t.o %t4.o -o %t +# RUN: llvm-readelf -n %t | FileCheck --check-prefix=NOSHSTK %s + +# Check .note.gnu.protery without property SHSTK. +# NOSHSTK: Properties: x86 feature: IBT{{$}} + +# RUN: ld.lld -shared %t1.o -soname=so -o %t1.so +# RUN: ld.lld -e func1 %t.o %t1.so -o %t +# RUN: llvm-readelf -n %t | FileCheck --check-prefix=CET --match-full-lines %s +# RUN: llvm-readelf -x .got.plt %t | FileCheck --check-prefix=GOTPLT %s +# RUN: llvm-objdump -d --no-show-raw-insn --print-imm-hex %t | FileCheck --check-prefix=DISASM %s + +# GOTPLT: Hex dump of section '.got.plt': +# GOTPLT-NEXT: 0x004032d0 50224000 00000000 00000000 20124000 +# GOTPLT-NEXT: 0x004032e0 0b124000 + +# DISASM: Disassembly of section .text: +# DISASM: 00401200 func1: +# DISASM-NEXT: 401200: calll 0x2b <func2+0x401230> +# DISASM-NEXT: 401205: calll 0x36 <ifunc> +# DISASM-NEXT: retl + +# DISASM: Disassembly of section .plt: +# DISASM: 00401210 .plt: +# DISASM-NEXT: 401210: pushl 0x4032d4 +# DISASM-NEXT: jmpl *0x4032d8 +# DISASM-NEXT: nop +# DISASM-NEXT: nop +# DISASM-NEXT: nop +# DISASM-NEXT: nop +# DISASM-NEXT: endbr32 +# DISASM-NEXT: pushl $0x0 +# DISASM-NEXT: jmp -0x1e <.plt> +# DISASM-NEXT: nop + +# DISASM: Disassembly of section .plt.sec: +# DISASM: 00401230 .plt.sec: +# DISASM-NEXT: 401230: endbr32 +# DISASM-NEXT: jmpl *0x4032dc +# DISASM-NEXT: nopw (%eax,%eax) + +# DISASM: Disassembly of section .iplt: +# DISASM: 00401240 ifunc: +# DISASM-NEXT: 401240: endbr32 +# DISASM-NEXT: jmpl *0x4032e0 +# DISASM-NEXT: nopw (%eax,%eax) + +.section ".note.gnu.property", "a" +.long 4 +.long 0xc +.long 0x5 +.asciz "GNU" + +.long 0xc0000002 # GNU_PROPERTY_X86_FEATURE_1_AND +.long 4 +.long 3 # GNU_PROPERTY_X86_FEATURE_1_IBT and SHSTK + +.text +.globl func1 +.type func1,@function +func1: + call func2 + call ifunc + ret + +.type ifunc,@gnu_indirect_function +ifunc: + ret diff --git a/lld/test/ELF/x86-64-cet.s b/lld/test/ELF/x86-64-cet.s deleted file mode 100644 index 3fb3716ed4e..00000000000 --- a/lld/test/ELF/x86-64-cet.s +++ /dev/null @@ -1,48 +0,0 @@ -# REQUIRES: x86 -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %s -o %t.o -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/x86-64-cet1.s -o %t1.o -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/x86-64-cet2.s -o %t2.o -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/x86-64-cet3.s -o %t3.o -# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux %p/Inputs/x86-64-cet4.s -o %t4.o - -# RUN: ld.lld -e func1 %t.o %t1.o -o %t -# RUN: llvm-readelf -n %t | FileCheck -check-prefix=CET -match-full-lines %s - -# RUN: ld.lld -e func1 %t.o %t2.o -o %t -# RUN: llvm-readelf -n %t | FileCheck -check-prefix=CET -match-full-lines %s - -# CET: Properties: x86 feature: IBT, SHSTK - -# RUN: ld.lld -e func1 %t.o %t3.o -o %t -# RUN: llvm-readelf -S %t | FileCheck -check-prefix=NOCET %s - -# NOCET: Section Headers -# NOCET-NOT: .note.gnu.property - -# RUN: not ld.lld -e func1 %t.o %t3.o -o %t --require-cet 2>&1 \ -# RUN: | FileCheck -check-prefix=ERROR %s -# ERROR: x86-64-cet.s.tmp3.o: --require-cet: file is not compatible with CET - -# RUN: ld.lld -e func1 %t.o %t4.o -o %t -# RUN: llvm-readelf -n %t | FileCheck -check-prefix=NOSHSTK -match-full-lines %s - -# Check .note.gnu.protery without property SHSTK. -# NOSHSTK: Properties: x86 feature: IBT - -.section ".note.gnu.property", "a" -.long 4 -.long 0x10 -.long 0x5 -.asciz "GNU" - -.long 0xc0000002 -.long 4 -.long 3 -.long 0 - -.text -.globl func1 -.type func1,@function -func1: - call func2 - ret diff --git a/lld/test/ELF/x86-64-feature-cet.s b/lld/test/ELF/x86-64-feature-cet.s new file mode 100644 index 00000000000..9899bec1e08 --- /dev/null +++ b/lld/test/ELF/x86-64-feature-cet.s @@ -0,0 +1,92 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 %p/Inputs/x86-64-cet1.s -o %t1.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 %p/Inputs/x86-64-cet2.s -o %t2.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 %p/Inputs/x86-64-cet3.s -o %t3.o +# RUN: llvm-mc -filetype=obj -triple=x86_64 %p/Inputs/x86-64-cet4.s -o %t4.o + +# RUN: ld.lld -e func1 %t.o %t1.o -o %t +# RUN: llvm-readelf -n %t | FileCheck --check-prefix=CET --match-full-lines %s + +# RUN: ld.lld -e func1 %t.o %t2.o -o %t +# RUN: llvm-readelf -n %t | FileCheck --check-prefix=CET --match-full-lines %s + +# CET: Properties: x86 feature: IBT, SHSTK + +# RUN: ld.lld -e func1 %t.o %t3.o -o %t +# RUN: llvm-readelf -S %t | FileCheck --check-prefix=NOCET %s + +# NOCET: Section Headers +# NOCET-NOT: .note.gnu.property + +# RUN: ld.lld -e func1 %t.o %t3.o -o %t -z force-ibt 2>&1 \ +# RUN: | FileCheck --check-prefix=WARN %s +# WARN: {{.*}}.o: -z force-ibt: file does not have GNU_PROPERTY_X86_FEATURE_1_IBT property + +# RUN: ld.lld -e func1 %t.o %t4.o -o %t +# RUN: llvm-readelf -n %t | FileCheck --check-prefix=NOSHSTK %s + +# Check .note.gnu.protery without property SHSTK. +# NOSHSTK: Properties: x86 feature: IBT{{$}} + +# RUN: ld.lld -shared %t1.o -soname=so -o %t1.so +# RUN: ld.lld -e func1 %t.o %t1.so -o %t +# RUN: llvm-readelf -n %t | FileCheck --check-prefix=CET --match-full-lines %s +# RUN: llvm-readelf -x .got.plt %t | FileCheck --check-prefix=GOTPLT %s +# RUN: llvm-objdump -d --no-show-raw-insn --print-imm-hex %t | FileCheck --check-prefix=DISASM %s + +# GOTPLT: Hex dump of section '.got.plt': +# GOTPLT-NEXT: 203480 80232000 00000000 00000000 00000000 +# GOTPLT-NEXT: 203490 00000000 00000000 50132000 00000000 +# GOTPLT-NEXT: 2034a0 00000000 00000000 + +# DISASM: Disassembly of section .text: +# DISASM: 0000000000201330 func1: +# DISASM-NEXT: 201330: callq 0x2b <func2+0x201360> +# DISASM-NEXT: 201335: callq 0x36 <func2+0x201370> +# DISASM-NEXT: retq + +# DISASM: Disassembly of section .plt: +# DISASM: 0000000000201340 .plt: +# DISASM-NEXT: 201340: pushq 0x2142(%rip) +# DISASM-NEXT: jmpq *0x2144(%rip) +# DISASM-NEXT: nopl (%rax) +# DISASM-NEXT: endbr64 +# DISASM-NEXT: pushq $0x0 +# DISASM-NEXT: jmp -0x1e <.plt> +# DISASM-NEXT: nop + +# DISASM: Disassembly of section .plt.sec: +# DISASM: 0000000000201360 .plt.sec: +# DISASM-NEXT: 201360: endbr64 +# DISASM-NEXT: jmpq *0x212e(%rip) +# DISASM-NEXT: nopw (%rax,%rax) + +# DISASM: Disassembly of section .iplt: +# DISASM: 0000000000201370 .iplt: +# DISASM-NEXT: 201370: endbr64 +# DISASM-NEXT: jmpq *0x2126(%rip) +# DISASM-NEXT: nopw (%rax,%rax) + +.section ".note.gnu.property", "a" +.long 4 +.long 0x10 +.long 0x5 +.asciz "GNU" + +.long 0xc0000002 # GNU_PROPERTY_X86_FEATURE_1_AND +.long 4 +.long 3 # GNU_PROPERTY_X86_FEATURE_1_IBT and SHSTK +.long 0 + +.text +.globl func1 +.type func1,@function +func1: + call func2 + call ifunc + ret + +.type ifunc,@gnu_indirect_function +ifunc: + ret |

