summaryrefslogtreecommitdiffstats
path: root/llvm/test/Transforms
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2016-11-11 18:49:09 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2016-11-11 18:49:09 +0000
commitf48ffab554fa77306246eaac63970d53229b0c0d (patch)
tree6ba0f0313f89f1b277f04e6a72209dcd5d8fd51a /llvm/test/Transforms
parent6285f5b441bf602319c2bc3b4ed04a1450aa8247 (diff)
downloadbcm5719-llvm-f48ffab554fa77306246eaac63970d53229b0c0d.tar.gz
bcm5719-llvm-f48ffab554fa77306246eaac63970d53229b0c0d.zip
[cfi] Implement cfi-icall using inline assembly.
The current implementation is emitting a global constant that happens to evaluate to the same bytes + relocation as a jump instruction on X86. This does not work for PIE executables and shared libraries though, because we end up with a wrong relocation type. And it has no chance of working on ARM/AArch64 which use different relocation types for jump instructions (R_ARM_JUMP24) that is never generated for data. This change replaces the constant with module-level inline assembly followed by a hidden declaration of the jump table. Works fine for ARM/AArch64, but has some drawbacks. * Extra symbols are added to the static symbol table, which inflate the size of the unstripped binary a little. Stripped binaries are not affected. This happens because jump table declarations must be external (because their body is in the inline asm). * Original functions that were anonymous are now named <original name>.cfi, and it affects symbolization sometimes. This is necessary because the only user of these functions is the (inline asm) jump table, so they had to be added to @llvm.used, which does not allow unnamed functions. llvm-svn: 286611
Diffstat (limited to 'llvm/test/Transforms')
-rw-r--r--llvm/test/Transforms/LowerTypeTests/function-disjoint.ll38
-rw-r--r--llvm/test/Transforms/LowerTypeTests/function-ext.ll8
-rw-r--r--llvm/test/Transforms/LowerTypeTests/function.ll63
-rw-r--r--llvm/test/Transforms/LowerTypeTests/section.ll8
4 files changed, 93 insertions, 24 deletions
diff --git a/llvm/test/Transforms/LowerTypeTests/function-disjoint.ll b/llvm/test/Transforms/LowerTypeTests/function-disjoint.ll
index a5455a953fb..1d236877502 100644
--- a/llvm/test/Transforms/LowerTypeTests/function-disjoint.ll
+++ b/llvm/test/Transforms/LowerTypeTests/function-disjoint.ll
@@ -5,21 +5,36 @@
target datalayout = "e-p:64:64"
-; X64: @[[JT0:.*]] = private constant [1 x <{ i8, i32, i8, i8, i8 }>] [<{ i8, i32, i8, i8, i8 }> <{ i8 -23, i32 trunc (i64 sub (i64 sub (i64 ptrtoint (void ()* @[[FNAME:.*]] to i64), i64 ptrtoint ([1 x <{ i8, i32, i8, i8, i8 }>]* @[[JT0]] to i64)), i64 5) to i32), i8 -52, i8 -52, i8 -52 }>], section ".text"
-; X64: @[[JT1:.*]] = private constant [1 x <{ i8, i32, i8, i8, i8 }>] [<{ i8, i32, i8, i8, i8 }> <{ i8 -23, i32 trunc (i64 sub (i64 sub (i64 ptrtoint (void ()* @[[GNAME:.*]] to i64), i64 ptrtoint ([1 x <{ i8, i32, i8, i8, i8 }>]* @[[JT1]] to i64)), i64 5) to i32), i8 -52, i8 -52, i8 -52 }>], section ".text"
+; X64: module asm "f = .cfi.jumptable + 0"
+
+; X64: module asm ".cfi.jumptable:"
+; X64-NEXT: module asm "jmp f.cfi@plt"
+; X64-NEXT: module asm "int3"
+; X64-NEXT: module asm "int3"
+; X64-NEXT: module asm "int3"
+
+; X64: module asm "g = .cfi.jumptable.1 + 0"
+
+; X64: module asm ".cfi.jumptable.1:"
+; X64-NEXT: module asm "jmp g.cfi@plt"
+; X64-NEXT: module asm "int3"
+; X64-NEXT: module asm "int3"
+; X64-NEXT: module asm "int3"
+
+
+; X64: @.cfi.jumptable = external hidden constant [1 x [8 x i8]]
+; X64: @.cfi.jumptable.1 = external hidden constant [1 x [8 x i8]]
+
; WASM32: private constant [0 x i8] zeroinitializer
@0 = private unnamed_addr constant [2 x void ()*] [void ()* @f, void ()* @g], align 16
-; X64: @f = alias void (), bitcast ([1 x <{ i8, i32, i8, i8, i8 }>]* @[[JT0]] to void ()*)
-; X64: @g = alias void (), bitcast ([1 x <{ i8, i32, i8, i8, i8 }>]* @[[JT1]] to void ()*)
-
-; X64: define private void @[[FNAME]]()
+; X64: define internal void @f.cfi()
; WASM32: define void @f() !type !{{[0-9]+}} !wasm.index ![[I0:[0-9]+]]
define void @f() !type !0 {
ret void
}
-; X64: define private void @[[GNAME]]()
+; X64: define internal void @g.cfi()
; WASM32: define void @g() !type !{{[0-9]+}} !wasm.index ![[I1:[0-9]+]]
define void @g() !type !1 {
ret void
@@ -31,15 +46,18 @@ define void @g() !type !1 {
declare i1 @llvm.type.test(i8* %ptr, metadata %bitset) nounwind readnone
define i1 @foo(i8* %p) {
- ; X64: icmp eq i64 {{.*}}, ptrtoint ([1 x <{ i8, i32, i8, i8, i8 }>]* @[[JT0]] to i64)
+ ; X64: icmp eq i64 {{.*}}, ptrtoint ([1 x [8 x i8]]* @.cfi.jumptable to i64)
; WASM32: icmp eq i64 {{.*}}, 1
%x = call i1 @llvm.type.test(i8* %p, metadata !"typeid1")
- ; X64: icmp eq i64 {{.*}}, ptrtoint ([1 x <{ i8, i32, i8, i8, i8 }>]* @[[JT1]] to i64)
+ ; X64: icmp eq i64 {{.*}}, ptrtoint ([1 x [8 x i8]]* @.cfi.jumptable.1 to i64)
; WASM32: icmp eq i64 {{.*}}, 2
%y = call i1 @llvm.type.test(i8* %p, metadata !"typeid2")
%z = add i1 %x, %y
ret i1 %z
}
+; X64: declare void @f()
+; X64: declare void @g()
+
; WASM32: ![[I0]] = !{i64 1}
-; WASM32: ![[I1]] = !{i64 2}
+; WASM32: ![[I1]] = !{i64 2} \ No newline at end of file
diff --git a/llvm/test/Transforms/LowerTypeTests/function-ext.ll b/llvm/test/Transforms/LowerTypeTests/function-ext.ll
index 2e9ab9dba62..b3b1f776e12 100644
--- a/llvm/test/Transforms/LowerTypeTests/function-ext.ll
+++ b/llvm/test/Transforms/LowerTypeTests/function-ext.ll
@@ -4,14 +4,18 @@
; Tests that we correctly handle external references, including the case where
; all functions in a bitset are external references.
-; X64: @[[JT:.*]] = private constant [1 x <{ i8, i32, i8, i8, i8 }>] [<{ i8, i32, i8, i8, i8 }> <{ i8 -23, i32 trunc (i64 sub (i64 sub (i64 ptrtoint (void ()* @foo to i64), i64 ptrtoint ([1 x <{ i8, i32, i8, i8, i8 }>]* @[[JT]] to i64)), i64 5) to i32), i8 -52, i8 -52, i8 -52 }>], section ".text"
+; X64: module asm ".cfi.jumptable:"
+; X64-NEXT: module asm "jmp foo@plt"
+; X64-NOT: module asm "jmp {{.*}}@plt"
+
+; X64: @.cfi.jumptable = external hidden constant [1 x [8 x i8]]
; WASM32: private constant [0 x i8] zeroinitializer
; WASM32: declare !type !{{[0-9]+}} void @foo()
declare !type !0 void @foo()
define i1 @bar(i8* %ptr) {
- ; X64: icmp eq i64 {{.*}}, ptrtoint ([1 x <{ i8, i32, i8, i8, i8 }>]* @[[JT]] to i64)
+ ; X64: icmp eq i64 {{.*}}, ptrtoint ([1 x [8 x i8]]* @.cfi.jumptable to i64)
; WASM32: sub i64 {{.*}}, 0
; WASM32: icmp ult i64 {{.*}}, 1
%p = call i1 @llvm.type.test(i8* %ptr, metadata !"void")
diff --git a/llvm/test/Transforms/LowerTypeTests/function.ll b/llvm/test/Transforms/LowerTypeTests/function.ll
index a9ef84acff6..7b7a6af320a 100644
--- a/llvm/test/Transforms/LowerTypeTests/function.ll
+++ b/llvm/test/Transforms/LowerTypeTests/function.ll
@@ -1,26 +1,65 @@
-; RUN: opt -S -lowertypetests -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck --check-prefix=X64 %s
+; RUN: opt -S -lowertypetests -mtriple=i686-unknown-linux-gnu < %s | FileCheck --check-prefix=X86 %s
+; RUN: opt -S -lowertypetests -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck --check-prefix=X86 %s
+; RUN: opt -S -lowertypetests -mtriple=arm-unknown-linux-gnu < %s | FileCheck --check-prefix=ARM %s
+; RUN: opt -S -lowertypetests -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck --check-prefix=ARM %s
; RUN: opt -S -lowertypetests -mtriple=wasm32-unknown-unknown < %s | FileCheck --check-prefix=WASM32 %s
; Tests that we correctly handle bitsets containing 2 or more functions.
target datalayout = "e-p:64:64"
-; X64: @[[JT:.*]] = private constant [2 x <{ i8, i32, i8, i8, i8 }>] [<{ i8, i32, i8, i8, i8 }> <{ i8 -23, i32 trunc (i64 sub (i64 sub (i64 ptrtoint (void ()* @[[FNAME:.*]] to i64), i64 ptrtoint ([2 x <{ i8, i32, i8, i8, i8 }>]* @[[JT]] to i64)), i64 5) to i32), i8 -52, i8 -52, i8 -52 }>, <{ i8, i32, i8, i8, i8 }> <{ i8 -23, i32 trunc (i64 sub (i64 sub (i64 ptrtoint (void ()* @[[GNAME:.*]] to i64), i64 ptrtoint ([2 x <{ i8, i32, i8, i8, i8 }>]* @[[JT]] to i64)), i64 13) to i32), i8 -52, i8 -52, i8 -52 }>], section ".text"
+; X86: module asm ".globl f"
+; X86-NEXT: module asm ".type f, function"
+; X86-NEXT: module asm "f = .cfi.jumptable + 0"
+; X86-NEXT: module asm ".size f, 8"
+; X86-NEXT: module asm ".type g, function"
+; X86-NEXT: module asm "g = .cfi.jumptable + 8"
+; X86-NEXT: module asm ".size g, 8"
+; X86-NEXT: module asm ".section .text.cfi, \22ax\22, @progbits"
+; X86-NEXT: module asm ".balign 8"
+; X86-NEXT: module asm ".cfi.jumptable:"
+; X86-NEXT: module asm "jmp f.cfi@plt"
+; X86-NEXT: module asm "int3"
+; X86-NEXT: module asm "int3"
+; X86-NEXT: module asm "int3"
+; X86-NEXT: module asm "jmp g.cfi@plt"
+; X86-NEXT: module asm "int3"
+; X86-NEXT: module asm "int3"
+; X86-NEXT: module asm "int3"
+
+; ARM: module asm ".globl f"
+; ARM-NEXT: module asm ".type f, function"
+; ARM-NEXT: module asm "f = .cfi.jumptable + 0"
+; ARM-NEXT: module asm ".size f, 4"
+; ARM-NEXT: module asm ".type g, function"
+; ARM-NEXT: module asm "g = .cfi.jumptable + 4"
+; ARM-NEXT: module asm ".size g, 4"
+; ARM-NEXT: module asm ".section .text.cfi, \22ax\22, @progbits"
+; ARM-NEXT: module asm ".balign 4"
+; ARM-NEXT: module asm ".cfi.jumptable:"
+; ARM-NEXT: module asm "b f.cfi"
+; ARM-NEXT: module asm "b g.cfi"
+
+; X86: @.cfi.jumptable = external hidden constant [2 x [8 x i8]]
+; ARM: @.cfi.jumptable = external hidden constant [2 x [4 x i8]]
+
; WASM32: private constant [0 x i8] zeroinitializer
@0 = private unnamed_addr constant [2 x void (...)*] [void (...)* bitcast (void ()* @f to void (...)*), void (...)* bitcast (void ()* @g to void (...)*)], align 16
-; X64: @f = alias void (), bitcast ([2 x <{ i8, i32, i8, i8, i8 }>]* @[[JT]] to void ()*)
-; X64: @g = alias void (), bitcast (<{ i8, i32, i8, i8, i8 }>* getelementptr inbounds ([2 x <{ i8, i32, i8, i8, i8 }>], [2 x <{ i8, i32, i8, i8, i8 }>]* @[[JT]], i64 0, i64 1) to void ()*)
+; X86: @llvm.used = appending global [2 x i8*] [i8* bitcast (void ()* @f.cfi to i8*), i8* bitcast (void ()* @g.cfi to i8*)], section "llvm.metadata"
+; ARM: @llvm.used = appending global [2 x i8*] [i8* bitcast (void ()* @f.cfi to i8*), i8* bitcast (void ()* @g.cfi to i8*)], section "llvm.metadata"
-; X64: define private void @[[FNAME]]()
+; X86: define internal void @f.cfi()
+; ARM: define internal void @f.cfi()
; WASM32: define void @f() !type !{{[0-9]+}} !wasm.index ![[I0:[0-9]+]]
define void @f() !type !0 {
ret void
}
-; X64: define private void @[[GNAME]]()
-; WASM32: define void @g() !type !{{[0-9]+}} !wasm.index ![[I1:[0-9]+]]
-define void @g() !type !0 {
+; X86: define internal void @g.cfi()
+; ARM: define internal void @g.cfi()
+; WASM32: define internal void @g() !type !{{[0-9]+}} !wasm.index ![[I1:[0-9]+]]
+define internal void @g() !type !0 {
ret void
}
@@ -29,12 +68,18 @@ define void @g() !type !0 {
declare i1 @llvm.type.test(i8* %ptr, metadata %bitset) nounwind readnone
define i1 @foo(i8* %p) {
- ; X64: sub i64 {{.*}}, ptrtoint ([2 x <{ i8, i32, i8, i8, i8 }>]* @[[JT]] to i64)
+ ; X86: sub i64 {{.*}}, ptrtoint ([2 x [8 x i8]]* @.cfi.jumptable to i64)
+ ; ARM: sub i64 {{.*}}, ptrtoint ([2 x [4 x i8]]* @.cfi.jumptable to i64)
; WASM32: sub i64 {{.*}}, 1
; WASM32: icmp ult i64 {{.*}}, 2
%x = call i1 @llvm.type.test(i8* %p, metadata !"typeid1")
ret i1 %x
}
+; X86: declare void @f()
+; ARM: declare void @f()
+; X86: declare hidden void @g()
+; ARM: declare hidden void @g()
+
; WASM32: ![[I0]] = !{i64 1}
; WASM32: ![[I1]] = !{i64 2}
diff --git a/llvm/test/Transforms/LowerTypeTests/section.ll b/llvm/test/Transforms/LowerTypeTests/section.ll
index 7884acfaec3..9dfb173d04a 100644
--- a/llvm/test/Transforms/LowerTypeTests/section.ll
+++ b/llvm/test/Transforms/LowerTypeTests/section.ll
@@ -5,9 +5,11 @@
target triple = "x86_64-unknown-linux-gnu"
-; CHECK: @[[A:.*]] = private constant {{.*}} section ".text"
-; CHECK: @f = alias void (), bitcast ({{.*}}* @[[A]] to void ()*)
-; CHECK: define private void {{.*}} section "xxx"
+; CHECK: module asm ".section .text.cfi,
+; CHECK: module asm ".cfi.jumptable:"
+; CHECK-NEXT: module asm "jmp f.cfi@plt"
+
+; CHECK: define internal void @f.cfi() section "xxx"
define void @f() section "xxx" !type !0 {
entry:
OpenPOWER on IntegriCloud