[PATCH] D152484: [KCFI] Fix hash offset calculation in Thumb mode
Sami Tolvanen via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Thu Jun 8 16:19:00 PDT 2023
samitolvanen created this revision.
Herald added subscribers: Enna1, hiraditya, kristof.beyls.
Herald added a project: All.
samitolvanen requested review of this revision.
Herald added a project: LLVM.
Herald added a subscriber: llvm-commits.
ARM stores the Thumb state in the least significant bit of the
function pointers. When compiling for ARM or Thumb, as all
instructions are at least 16-bit aligned, ignore the LSB when
computing the prefix hash location, so we can support both
pure Thumb and mixed ARM/Thumb binaries.
Repository:
rG LLVM Github Monorepo
https://reviews.llvm.org/D152484
Files:
llvm/lib/Transforms/Instrumentation/KCFI.cpp
llvm/test/Transforms/KCFI/kcfi.ll
Index: llvm/test/Transforms/KCFI/kcfi.ll
===================================================================
--- llvm/test/Transforms/KCFI/kcfi.ll
+++ llvm/test/Transforms/KCFI/kcfi.ll
@@ -1,8 +1,13 @@
-; RUN: opt -S -passes=kcfi %s | FileCheck %s
+; RUN: opt -S -passes=kcfi %s | FileCheck --check-prefixes=CHECK,NOARM %s
+; RUN: %if arm-registered-target %{ opt -S -passes=kcfi -mtriple=thumbv7m-unknown-linux-gnu %s | FileCheck --check-prefixes=CHECK,ARM %s %}
; CHECK-LABEL: define void @f1(
define void @f1(ptr noundef %x) {
- ; CHECK: %[[#GEPI:]] = getelementptr inbounds i32, ptr %x, i32 -1
+ ; ARM: %[[#FINT:]] = ptrtoint ptr %x to i32
+ ; ARM-NEXT: %[[#FAND:]] = and i32 %[[#FINT]], -2
+ ; ARM-NEXT: %[[#FPTR:]] = inttoptr i32 %[[#FAND]] to ptr
+ ; ARM-NEXT: %[[#GEPI:]] = getelementptr inbounds i32, ptr %[[#FPTR]], i32 -1
+ ; NOARM: %[[#GEPI:]] = getelementptr inbounds i32, ptr %x, i32 -1
; CHECK-NEXT: %[[#LOAD:]] = load i32, ptr %[[#GEPI]], align 4
; CHECK-NEXT: %[[#ICMP:]] = icmp ne i32 %[[#LOAD]], 12345678
; CHECK-NEXT: br i1 %[[#ICMP]], label %[[#TRAP:]], label %[[#CALL:]], !prof ![[#WEIGHTS:]]
Index: llvm/lib/Transforms/Instrumentation/KCFI.cpp
===================================================================
--- llvm/lib/Transforms/Instrumentation/KCFI.cpp
+++ llvm/lib/Transforms/Instrumentation/KCFI.cpp
@@ -73,6 +73,7 @@
IntegerType *Int32Ty = Type::getInt32Ty(Ctx);
MDNode *VeryUnlikelyWeights =
MDBuilder(Ctx).createBranchWeights(1, (1U << 20) - 1);
+ Triple T(M.getTargetTriple());
for (CallInst *CI : KCFICalls) {
// Get the expected hash value.
@@ -93,8 +94,18 @@
// Emit a check and trap if the target hash doesn't match.
IRBuilder<> Builder(Call);
- Value *HashPtr = Builder.CreateConstInBoundsGEP1_32(
- Int32Ty, Call->getCalledOperand(), -1);
+ Value *FuncPtr = Call->getCalledOperand();
+ // ARM uses the least significant bit of the function pointer to select
+ // between ARM and Thumb modes for the callee. Instructions are always
+ // at least 16-bit aligned, so clear the LSB before we compute the hash
+ // location.
+ if (T.isARM() || T.isThumb()) {
+ FuncPtr = Builder.CreateIntToPtr(
+ Builder.CreateAnd(Builder.CreatePtrToInt(FuncPtr, Int32Ty),
+ ConstantInt::get(Int32Ty, -2)),
+ FuncPtr->getType());
+ }
+ Value *HashPtr = Builder.CreateConstInBoundsGEP1_32(Int32Ty, FuncPtr, -1);
Value *Test = Builder.CreateICmpNE(Builder.CreateLoad(Int32Ty, HashPtr),
ConstantInt::get(Int32Ty, ExpectedHash));
Instruction *ThenTerm =
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D152484.529770.patch
Type: text/x-patch
Size: 2684 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230608/31812dd0/attachment.bin>
More information about the llvm-commits
mailing list