Skip to content

Commit 913cd11

Browse files
authored
[llvm][fatlto] Drop any CFI related instrumentation after emitting bitcode (#112788)
We want to support CFI instrumentation for the bitcode section, without miscompiling the object code portion of a FatLTO object. We can reuse the existing mechanisms in the LowerTypeTestsPass to do that, by just adding the pass to the FatLTO pipeline after the EmbedBitcodePass with the correct options set. Fixes #112053
1 parent 5c1752e commit 913cd11

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed
+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// REQUIRES: x86-registered-target
2+
3+
// RUN: %clang_cc1 -triple x86_64-unknown-fuchsia -O2 -flto -ffat-lto-objects \
4+
// RUN: -fsanitize=cfi-icall -fsanitize-trap=cfi-icall -fvisibility=hidden -emit-llvm -o - %s \
5+
// RUN: | FileCheck %s
6+
7+
// CHECK: llvm.embedded.object
8+
// CHECK-SAME: section ".llvm.lto"
9+
10+
// CHECK-LABEL: define hidden void @foo
11+
// CHECK: entry:
12+
// CHECK-NEXT: %cmp14.not = icmp eq i64 %len, 0
13+
// CHECK-NEXT: br i1 %cmp14.not, label %for.end7, label %for.cond1.preheader.preheader
14+
// CHECK: for.cond1.preheader.preheader: ; preds = %entry
15+
// CHECK-NEXT: %arrayidx.1 = getelementptr inbounds nuw i8, ptr %ptr, i64 4
16+
// CHECK-NEXT: br label %for.cond1.preheader
17+
18+
// CHECK-NOT: @llvm.type.test
19+
20+
// The code below is a reduced case from https://github.com/llvm/llvm-project/issues/112053
21+
#define __PRINTFLIKE(__fmt, __varargs) __attribute__((__format__(__printf__, __fmt, __varargs)))
22+
typedef void func(void* arg, const char* fmt, ...) __PRINTFLIKE(2, 3);
23+
typedef __SIZE_TYPE__ size_t;
24+
typedef unsigned long uintptr_t;
25+
26+
extern "C"
27+
void foo(const void* ptr, size_t len, long disp_addr,
28+
func* printf_func, void* printf_arg) {
29+
uintptr_t address = (uintptr_t)ptr;
30+
size_t count;
31+
32+
for (count = 0; count < len; count += 16) {
33+
union {
34+
unsigned int buf[4];
35+
unsigned char cbuf[16];
36+
} u;
37+
size_t s = 10;
38+
size_t i;
39+
40+
for (i = 0; i < s / 4; i++) {
41+
u.buf[i] = ((const unsigned int*)address)[i];
42+
printf_func(printf_arg, "%08x ", static_cast<unsigned int>(u.buf[i]));
43+
}
44+
}
45+
}
46+

llvm/lib/Passes/PassBuilderPipelines.cpp

+7
Original file line numberDiff line numberDiff line change
@@ -1630,6 +1630,13 @@ PassBuilder::buildFatLTODefaultPipeline(OptimizationLevel Level, bool ThinLTO,
16301630
MPM.addPass(buildLTOPreLinkDefaultPipeline(Level));
16311631
MPM.addPass(EmbedBitcodePass(ThinLTO, EmitSummary));
16321632

1633+
// If we're doing FatLTO w/ CFI enabled, we don't want the type tests in the
1634+
// object code, only in the bitcode section, so drop it before we run
1635+
// module optimization and generate machine code. If llvm.type.test() isn't in
1636+
// the IR, this won't do anything.
1637+
MPM.addPass(
1638+
LowerTypeTestsPass(nullptr, nullptr, lowertypetests::DropTestKind::All));
1639+
16331640
// Use the ThinLTO post-link pipeline with sample profiling
16341641
if (ThinLTO && PGOOpt && PGOOpt->Action == PGOOptions::SampleUse)
16351642
MPM.addPass(buildThinLTODefaultPipeline(Level, /*ImportSummary=*/nullptr));

0 commit comments

Comments
 (0)