llvmbot wrote:
@llvm/pr-subscribers-bolt
Author: Amir Ayupov (aaupov)
Changes
Detect and support fixed PIC indirect jumps of the following form:
```
movslq En(%rip), %r1
leaq PIC_JUMP_TABLE(%rip), %r2
addq %r2, %r1
jmpq *%r1
```
with PIC_JUMP_TABLE that looks like following:
```
JT: --
E1:| L1 - JT |
|--|
E2:| L2 - JT |
|--|
| |
..
En:| Ln - JT |
--
```
The code could be produced by compilers, see
https://github.com/llvm/llvm-project/issues/91648.
Test Plan: updated jump-table-fixed-ref-pic.test
---
Full diff: https://github.com/llvm/llvm-project/pull/91667.diff
8 Files Affected:
- (modified) bolt/include/bolt/Core/BinaryContext.h (+5)
- (modified) bolt/include/bolt/Core/MCPlusBuilder.h (+4-1)
- (modified) bolt/lib/Core/BinaryFunction.cpp (+45-2)
- (modified) bolt/lib/Passes/IndirectCallPromotion.cpp (+2-1)
- (modified) bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp (+9-5)
- (modified) bolt/lib/Target/X86/X86MCPlusBuilder.cpp (+60-28)
- (modified) bolt/test/X86/Inputs/jump-table-fixed-ref-pic.s (+1-1)
- (modified) bolt/test/X86/jump-table-fixed-ref-pic.test (+11-4)
``diff
diff --git a/bolt/include/bolt/Core/BinaryContext.h
b/bolt/include/bolt/Core/BinaryContext.h
index 4a59a581dfedb..f8bf29c674b54 100644
--- a/bolt/include/bolt/Core/BinaryContext.h
+++ b/bolt/include/bolt/Core/BinaryContext.h
@@ -430,6 +430,11 @@ class BinaryContext {
return nullptr;
}
+ /// Deregister JumpTable registered at a given \p Address.
+ bool deregisterJumpTable(uint64_t Address) {
+return JumpTables.erase(Address);
+ }
+
unsigned getDWARFEncodingSize(unsigned Encoding) {
if (Encoding == dwarf::DW_EH_PE_omit)
return 0;
diff --git a/bolt/include/bolt/Core/MCPlusBuilder.h
b/bolt/include/bolt/Core/MCPlusBuilder.h
index f7614cf9ac977..42ec006fba9f1 100644
--- a/bolt/include/bolt/Core/MCPlusBuilder.h
+++ b/bolt/include/bolt/Core/MCPlusBuilder.h
@@ -58,6 +58,8 @@ enum class IndirectBranchType : char {
POSSIBLE_PIC_JUMP_TABLE, /// Possibly a jump table for PIC.
POSSIBLE_GOTO, /// Possibly a gcc's computed goto.
POSSIBLE_FIXED_BRANCH, /// Possibly an indirect branch to a fixed location.
+ POSSIBLE_PIC_FIXED_BRANCH, /// Possibly an indirect jump to a fixed entry in
a
+ /// PIC jump table.
};
class MCPlusBuilder {
@@ -1472,7 +1474,8 @@ class MCPlusBuilder {
InstructionIterator End, const unsigned PtrSize,
MCInst *, unsigned ,
unsigned , int64_t ,
-const MCExpr *, MCInst *) const {
+const MCExpr *, MCInst *,
+MCInst *) const {
llvm_unreachable("not implemented");
return IndirectBranchType::UNKNOWN;
}
diff --git a/bolt/lib/Core/BinaryFunction.cpp b/bolt/lib/Core/BinaryFunction.cpp
index f74ecea8ac0a1..799065a6f194e 100644
--- a/bolt/lib/Core/BinaryFunction.cpp
+++ b/bolt/lib/Core/BinaryFunction.cpp
@@ -779,6 +779,9 @@ BinaryFunction::processIndirectBranch(MCInst ,
unsigned Size,
// setting the value of the register used by the branch.
MCInst *MemLocInstr;
+ // The instruction loading the fixed PIC jump table entry value.
+ MCInst *FixedEntryLoadInstr;
+
// Address of the table referenced by MemLocInstr. Could be either an
// array of function pointers, or a jump table.
uint64_t ArrayStart = 0;
@@ -810,7 +813,7 @@ BinaryFunction::processIndirectBranch(MCInst ,
unsigned Size,
IndirectBranchType BranchType = BC.MIB->analyzeIndirectBranch(
Instruction, Begin, Instructions.end(), PtrSize, MemLocInstr, BaseRegNum,
- IndexRegNum, DispValue, DispExpr, PCRelBaseInstr);
+ IndexRegNum, DispValue, DispExpr, PCRelBaseInstr, FixedEntryLoadInstr);
if (BranchType == IndirectBranchType::UNKNOWN && !MemLocInstr)
return BranchType;
@@ -876,6 +879,43 @@ BinaryFunction::processIndirectBranch(MCInst ,
unsigned Size,
if (BaseRegNum == BC.MRI->getProgramCounter())
ArrayStart += getAddress() + Offset + Size;
+ if (FixedEntryLoadInstr) {
+assert(BranchType == IndirectBranchType::POSSIBLE_PIC_FIXED_BRANCH &&
+ "Invalid IndirectBranch type");
+const MCExpr *FixedEntryDispExpr =
+BC.MIB->getMemOperandDisp(*FixedEntryLoadInstr)->getExpr();
+const uint64_t EntryAddress = getExprValue(FixedEntryDispExpr);
+uint64_t EntrySize = BC.getJumpTableEntrySize(JumpTable::JTT_PIC);
+ErrorOr Value = BC.getSignedValueAtAddress(EntryAddress,
EntrySize);
+if (!Value)
+ return IndirectBranchType::UNKNOWN;
+
+BC.outs() << "BOLT-INFO: fixed PIC indirect branch detected in " << *this
+ << " at 0x" << Twine::utohexstr(getAddress() + Offset)
+ << " referencing data at 0x" << Twine::utohexstr(EntryAddress)
+ << " the destination value is 0x"
+ <<