Skip to content

Commit b0a9d4b

Browse files
committed
[CrossDSO CFI] Make sure __cfi_check has BTI attribute.
When we're doing CrossDSO CFI, clang tries to generate a stub for __cfi_check so it has the correct attributes. However, this doesn't work in some scenarios: if you're doing ThinLTO, and some code is forced into the "fulllto" module, __cfi_check is generated in that module, and there is no stub. In this scenario, there's an inconsistency between the "branch-target-enforcement" module flag, and the function: the function is missing the attribute. So the "bti c" isn't generated, and it faults at runtime. This fix works around the issue by forcing the "branch-target-enforcement" attribute onto the function. See also c7cacb2.
1 parent aa612f3 commit b0a9d4b

File tree

2 files changed

+62
-0
lines changed

2 files changed

+62
-0
lines changed

llvm/lib/Transforms/IPO/CrossDSOCFI.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,15 @@ void CrossDSOCFI::buildCFICheck(Module &M) {
9494
Triple T(M.getTargetTriple());
9595
if (T.isARM() || T.isThumb())
9696
F->addFnAttr("target-features", "+thumb-mode");
97+
if (T.isAArch64()) {
98+
if (const auto *BTE = mdconst::extract_or_null<ConstantInt>(
99+
M.getModuleFlag("branch-target-enforcement"))) {
100+
if (BTE->getZExtValue() != 0) {
101+
F->addFnAttr("branch-target-enforcement");
102+
}
103+
}
104+
}
105+
97106

98107
auto args = F->arg_begin();
99108
Value &CallSiteTypeId = *(args++);
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
; RUN: opt -S -passes=cross-dso-cfi < %s | FileCheck %s
2+
3+
; CHECK: define void @__cfi_check({{.*}}) [[ATTR:#[0-9]+]] align 4096
4+
; CHECK: [[ATTR]] = { "branch-target-enforcement" }
5+
6+
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
7+
target triple = "aarch64-unknown-linux-gnu"
8+
9+
@_ZTV1A = constant i8 0, !type !4, !type !5
10+
@_ZTV1B = constant i8 0, !type !4, !type !5, !type !6, !type !7
11+
12+
define signext i8 @f11() "branch-target-enforcement" !type !0 !type !1 {
13+
entry:
14+
ret i8 1
15+
}
16+
17+
define signext i8 @f12() "branch-target-enforcement" !type !0 !type !1 {
18+
entry:
19+
ret i8 2
20+
}
21+
22+
define signext i8 @f13() "branch-target-enforcement" !type !0 !type !1 {
23+
entry:
24+
ret i8 3
25+
}
26+
27+
define i32 @f21() "branch-target-enforcement" !type !2 !type !3 {
28+
entry:
29+
ret i32 4
30+
}
31+
32+
define i32 @f22() "branch-target-enforcement" !type !2 !type !3 {
33+
entry:
34+
ret i32 5
35+
}
36+
37+
define weak_odr hidden void @__cfi_check_fail(ptr, ptr) "branch-target-enforcement" {
38+
entry:
39+
ret void
40+
}
41+
42+
!llvm.module.flags = !{!8, !9}
43+
44+
!0 = !{i64 0, !"_ZTSFcvE"}
45+
!1 = !{i64 0, i64 111}
46+
!2 = !{i64 0, !"_ZTSFivE"}
47+
!3 = !{i64 0, i64 222}
48+
!4 = !{i64 16, !"_ZTS1A"}
49+
!5 = !{i64 16, i64 333}
50+
!6 = !{i64 16, !"_ZTS1B"}
51+
!7 = !{i64 16, i64 444}
52+
!8 = !{i32 4, !"Cross-DSO CFI", i32 1}
53+
!9 = !{i32 8, !"branch-target-enforcement", i32 1}

0 commit comments

Comments
 (0)