Skip to content

Commit 373d875

Browse files
kpdevNikolai Kholiavin
andauthored
[cfi][CodeGen] Call SetLLVMFunctionAttributes{,ForDefinition} on __cf… (#78253)
…i_check This causes __cfi_check, just as __cfi_check_fail, to get the proper target-specific attributes, in particular uwtable for unwind table generation. Previously, nounwind attribute could be inferred for __cfi_check, which caused it to lose its unwind table even with -funwind-table option. ~~ Huawei RRI, OS Lab Co-authored-by: Nikolai Kholiavin <[email protected]>
1 parent 54a9f0e commit 373d875

File tree

4 files changed

+29
-3
lines changed

4 files changed

+29
-3
lines changed

clang/docs/ReleaseNotes.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -626,6 +626,10 @@ Sanitizers
626626
manually disable potentially noisy signed integer overflow checks with
627627
``-fno-sanitize=signed-integer-overflow``
628628

629+
- ``-fsanitize=cfi -fsanitize-cfi-cross-dso`` (cross-DSO CFI instrumentation)
630+
now generates the ``__cfi_check`` function with proper target-specific
631+
attributes, for example allowing unwind table generation.
632+
629633
Python Binding Changes
630634
----------------------
631635

clang/lib/CodeGen/CGExpr.cpp

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3663,12 +3663,29 @@ void CodeGenFunction::EmitCfiSlowPathCheck(
36633663
// symbol in LTO mode.
36643664
void CodeGenFunction::EmitCfiCheckStub() {
36653665
llvm::Module *M = &CGM.getModule();
3666-
auto &Ctx = M->getContext();
3666+
ASTContext &C = getContext();
3667+
QualType QInt64Ty = C.getIntTypeForBitwidth(64, false);
3668+
3669+
FunctionArgList FnArgs;
3670+
ImplicitParamDecl ArgCallsiteTypeId(C, QInt64Ty, ImplicitParamKind::Other);
3671+
ImplicitParamDecl ArgAddr(C, C.VoidPtrTy, ImplicitParamKind::Other);
3672+
ImplicitParamDecl ArgCFICheckFailData(C, C.VoidPtrTy,
3673+
ImplicitParamKind::Other);
3674+
FnArgs.push_back(&ArgCallsiteTypeId);
3675+
FnArgs.push_back(&ArgAddr);
3676+
FnArgs.push_back(&ArgCFICheckFailData);
3677+
const CGFunctionInfo &FI =
3678+
CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, FnArgs);
3679+
36673680
llvm::Function *F = llvm::Function::Create(
3668-
llvm::FunctionType::get(VoidTy, {Int64Ty, Int8PtrTy, Int8PtrTy}, false),
3681+
llvm::FunctionType::get(VoidTy, {Int64Ty, VoidPtrTy, VoidPtrTy}, false),
36693682
llvm::GlobalValue::WeakAnyLinkage, "__cfi_check", M);
3683+
CGM.SetLLVMFunctionAttributes(GlobalDecl(), FI, F, /*IsThunk=*/false);
3684+
CGM.SetLLVMFunctionAttributesForDefinition(nullptr, F);
36703685
F->setAlignment(llvm::Align(4096));
36713686
CGM.setDSOLocal(F);
3687+
3688+
llvm::LLVMContext &Ctx = M->getContext();
36723689
llvm::BasicBlock *BB = llvm::BasicBlock::Create(Ctx, "entry", F);
36733690
// CrossDSOCFI pass is not executed if there is no executable code.
36743691
SmallVector<llvm::Value*> Args{F->getArg(2), F->getArg(1)};

clang/test/CodeGen/cfi-check-attrs.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// RUN: %clang_cc1 -triple arm-unknown-linux -funwind-tables=1 -fsanitize-cfi-cross-dso -emit-llvm -o - %s | FileCheck %s
2+
3+
// CHECK: define weak {{.*}}void @__cfi_check({{.*}} [[ATTR:#[0-9]*]]
4+
5+
// CHECK: attributes [[ATTR]] = {{.*}} uwtable(sync)

clang/test/CodeGen/cfi-check-fail.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ void caller(void (*f)(void)) {
7272
// CHECK: [[CONT5]]:
7373
// CHECK: ret void
7474

75-
// CHECK: define weak void @__cfi_check(i64 %[[TYPE:.*]], ptr %[[ADDR:.*]], ptr %[[DATA:.*]]) align 4096
75+
// CHECK: define weak void @__cfi_check(i64 noundef %[[TYPE:.*]], ptr noundef %[[ADDR:.*]], ptr noundef %[[DATA:.*]]){{.*}} align 4096
7676
// CHECK-NOT: }
7777
// CHECK: call void @__cfi_check_fail(ptr %[[DATA]], ptr %[[ADDR]])
7878
// CHECK-NEXT: ret void

0 commit comments

Comments
 (0)