With Control-Flow Integrity (CFI), the LowerTypeTests pass replaces function references with CFI jump table references, which is a problem for low-level code that needs the address of the actual function body. For example, in the Linux kernel, the code that sets up interrupt handlers needs to take the address of the interrupt handler function instead of the CFI jump table, as the jump table may not even be mapped into memory when an interrupt is triggered. This change adds the no_cfi constant type, which wraps function references in a value that LowerTypeTestsModule::replaceCfiUses does not replace. Link: https://github.com/ClangBuiltLinux/linux/issues/1353 Reviewed By: nickdesaulniers, pcc Differential Revision: https://reviews.llvm.org/D108478
44 lines
1.1 KiB
LLVM
44 lines
1.1 KiB
LLVM
; RUN: llvm-as < %s | llvm-dis | FileCheck %s
|
|
; RUN: verify-uselistorder %s
|
|
|
|
; CHECK: @a = global [4 x void ()*] [void ()* no_cfi @f1, void ()* @f1, void ()* @f2, void ()* no_cfi @f2]
|
|
@a = global [4 x void ()*] [void ()* no_cfi @f1, void ()* @f1, void ()* @f2, void ()* no_cfi @f2]
|
|
; CHECK: @b = constant void ()* no_cfi @f3
|
|
@b = constant void ()* no_cfi @f3
|
|
; CHECK: @c = constant void ()* @f3
|
|
@c = constant void ()* @f3
|
|
|
|
; CHECK: declare void @f1()
|
|
declare void @f1()
|
|
|
|
; CHECK: declare void @f2()
|
|
declare void @f2()
|
|
|
|
; CHECK: define void @f3()
|
|
define void @f3() {
|
|
; CHECK: call void no_cfi @f4()
|
|
call void no_cfi @f4()
|
|
; CHECK: call void @f4()
|
|
call void @f4()
|
|
; CHECK: call void no_cfi @f5()
|
|
call void no_cfi @f5()
|
|
; CHECK: call void @f5()
|
|
call void @f5()
|
|
ret void
|
|
}
|
|
|
|
; CHECK: declare void @f4()
|
|
declare void @f4()
|
|
|
|
; CHECK: declare void @f5()
|
|
declare void @f5()
|
|
|
|
define void @g() {
|
|
%n = alloca void ()*, align 8
|
|
; CHECK: store void ()* no_cfi @f5, void ()** %n, align 8
|
|
store void ()* no_cfi @f5, void ()** %n, align 8
|
|
%1 = load void ()*, void ()** %n
|
|
call void %1()
|
|
ret void
|
|
}
|