[PATCH] D151308: -fsanitize=function: fix alignment fault on Arm targets.
Simon Tatham via Phabricator via cfe-commits
cfe-commits at lists.llvm.org
Wed May 24 01:49:55 PDT 2023
simon_tatham updated this revision to Diff 525065.
simon_tatham added a comment.
(oops, forgot to clang-format)
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D151308/new/
https://reviews.llvm.org/D151308
Files:
clang/lib/CodeGen/CGExpr.cpp
clang/test/CodeGen/ubsan-function.cpp
Index: clang/test/CodeGen/ubsan-function.cpp
===================================================================
--- clang/test/CodeGen/ubsan-function.cpp
+++ clang/test/CodeGen/ubsan-function.cpp
@@ -1,11 +1,15 @@
// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s -fsanitize=function -fno-sanitize-recover=all | FileCheck %s
// RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm -o - %s -fsanitize=function -fno-sanitize-recover=all | FileCheck %s
// RUN: %clang_cc1 -triple aarch64_be-linux-gnu -emit-llvm -o - %s -fsanitize=function -fno-sanitize-recover=all | FileCheck %s
+// RUN: %clang_cc1 -triple arm-none-eabi -emit-llvm -o - %s -fsanitize=function -fno-sanitize-recover=all | FileCheck %s --check-prefixes=CHECK,ARM
// CHECK: define{{.*}} void @_Z3funv() #0 !func_sanitize ![[FUNCSAN:.*]] {
void fun() {}
// CHECK-LABEL: define{{.*}} void @_Z6callerPFvvE(ptr noundef %f)
+// ARM: ptrtoint ptr {{.*}} to i32, !nosanitize !5
+// ARM: and i32 {{.*}}, -2, !nosanitize !5
+// ARM: inttoptr i32 {{.*}} to ptr, !nosanitize !5
// CHECK: getelementptr <{ i32, i32 }>, ptr {{.*}}, i32 -1, i32 0, !nosanitize
// CHECK: load i32, ptr {{.*}}, align {{.*}}, !nosanitize
// CHECK: icmp eq i32 {{.*}}, -1056584962, !nosanitize
@@ -16,7 +20,7 @@
// CHECK: icmp eq i32 {{.*}}, -1522505972, !nosanitize
// CHECK: br i1 {{.*}}, label %[[LABEL3:.*]], label %[[LABEL2:[^,]*]], {{.*}}!nosanitize
// CHECK: [[LABEL2]]:
-// CHECK: call void @__ubsan_handle_function_type_mismatch_abort(ptr @[[#]], i64 %[[#]]) #[[#]], !nosanitize
+// CHECK: call void @__ubsan_handle_function_type_mismatch_abort(ptr @[[#]], {{i64|i32}} %[[#]]) #[[#]], !nosanitize
// CHECK-NEXT: unreachable, !nosanitize
// CHECK-EMPTY:
// CHECK-NEXT: [[LABEL3]]:
Index: clang/lib/CodeGen/CGExpr.cpp
===================================================================
--- clang/lib/CodeGen/CGExpr.cpp
+++ clang/lib/CodeGen/CGExpr.cpp
@@ -5364,8 +5364,26 @@
llvm::Value *CalleePtr = Callee.getFunctionPointer();
+ // On 32-bit Arm, the low bit of a function pointer indicates whether
+ // it's using the Arm or Thumb instruction set. The actual first
+ // instruction lives at the same address either way, so we must clear
+ // that low bit before using the function address to find the prefix
+ // structure.
+ //
+ // This applies to both Arm and Thumb target triples, because
+ // either one could be used in an interworking context where it
+ // might be passed function pointers of both types.
+ llvm::Value *AlignedCalleePtr;
+ if (CGM.getTriple().isARM() || CGM.getTriple().isThumb()) {
+ llvm::Value *CalleeAddress = Builder.CreatePtrToInt(CalleePtr, IntPtrTy);
+ llvm::Value *AlignedCalleeAddress = Builder.CreateAnd(CalleeAddress, llvm::ConstantInt::get(IntPtrTy, -2));
+ AlignedCalleePtr = Builder.CreateIntToPtr(AlignedCalleeAddress, CalleePtr->getType());
+ } else {
+ AlignedCalleePtr = CalleePtr;
+ }
+
llvm::Value *CalleePrefixStruct = Builder.CreateBitCast(
- CalleePtr, llvm::PointerType::getUnqual(PrefixStructTy));
+ AlignedCalleePtr, llvm::PointerType::getUnqual(PrefixStructTy));
llvm::Value *CalleeSigPtr =
Builder.CreateConstGEP2_32(PrefixStructTy, CalleePrefixStruct, -1, 0);
llvm::Value *CalleeSig =
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D151308.525065.patch
Type: text/x-patch
Size: 3379 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20230524/3b705ca2/attachment-0001.bin>
More information about the cfe-commits
mailing list