Skip to content

Commit

Permalink
[X86] Fix fentry handling in X86IndirectBranchTracking.cpp
Browse files Browse the repository at this point in the history
When compiling with indirect branch tracking and fentry (-fcf-protection=branch -mfentry -pg) the X86IndirectBranchTrackingPass will attempt to place endbr in basic blocks, checking for Calls/IsCallReturnTwice. For calling the function IsCallReturnTwice(), the pass attempts to retrieve the first operand of the respective machine instruction. Since FENTRY_CALL is considered a call, and it does not have any argument, the condition inside the pass will attempt to call IsCallReturnTwice on the machine instruction, but since it does not have operands, it will lead into a crash.

Kudos to Alyssa Milburn for helping in the issue triage. The diff brings a test, but to reproduce the problem, follow the steps below.

```
echo "int main() {};" > repro.c
clang repro.c -fcf-protection=branch -mfentry -pg
```

Reviewed By: craig.topper

Differential Revision: https://reviews.llvm.org/D111108
  • Loading branch information
Joao Moreira authored and phoebewang committed Dec 7, 2021
1 parent 2bd7384 commit dfcf697
Show file tree
Hide file tree
Showing 2 changed files with 20 additions and 1 deletion.
4 changes: 3 additions & 1 deletion llvm/lib/Target/X86/X86IndirectBranchTracking.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,10 @@ bool X86IndirectBranchTrackingPass::runOnMachineFunction(MachineFunction &MF) {
Changed |= addENDBR(MBB, MBB.begin());

for (MachineBasicBlock::iterator I = MBB.begin(); I != MBB.end(); ++I) {
if (I->isCall() && IsCallReturnTwice(I->getOperand(0)))
if (I->isCall() && I->getNumOperands() > 0 &&
IsCallReturnTwice(I->getOperand(0))) {
Changed |= addENDBR(MBB, std::next(I));
}
}

// Exception handle may indirectly jump to catch pad, So we should add
Expand Down
17 changes: 17 additions & 0 deletions llvm/test/CodeGen/X86/fentry-ibt.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
; RUN: llc %s -o - -verify-machineinstrs | FileCheck %s

define void @test1() #0 {
entry:
ret void

; CHECK-LABEL: @test1
; CHECK: endbr64
; CHECK: callq __fentry__
; CHECK-NOT: mcount
; CHECK: retq
}

!llvm.module.flags = !{!0}

attributes #0 = { "fentry-call"="true" }
!0 = !{i32 4, !"cf-protection-branch", i32 1}

0 comments on commit dfcf697

Please sign in to comment.