Skip to content

Commit

Permalink
[BOLT][AArch64] Fix PLT optimization (#124192)
Browse files Browse the repository at this point in the history
Preserve C++ exception metadata while running PLT optimization on
AArch64.
  • Loading branch information
maksfb authored Jan 24, 2025
1 parent 77c23fd commit 34c6c5e
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 9 deletions.
7 changes: 4 additions & 3 deletions bolt/include/bolt/Core/MCPlusBuilder.h
Original file line number Diff line number Diff line change
Expand Up @@ -1426,11 +1426,12 @@ class MCPlusBuilder {
}

/// Creates an indirect call to the function within the \p DirectCall PLT
/// stub. The function's memory location is pointed by the \p TargetLocation
/// stub. The function's address location is pointed by the \p TargetLocation
/// symbol.
/// Move instruction annotations from \p DirectCall to the indirect call.
virtual InstructionListType
createIndirectPltCall(const MCInst &DirectCall,
const MCSymbol *TargetLocation, MCContext *Ctx) {
createIndirectPLTCall(MCInst &&DirectCall, const MCSymbol *TargetLocation,
MCContext *Ctx) {
llvm_unreachable("not implemented");
return {};
}
Expand Down
4 changes: 2 additions & 2 deletions bolt/lib/Passes/PLTCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ Error PLTCall::runOnFunctions(BinaryContext &BC) {
const BinaryFunction *CalleeBF = BC.getFunctionForSymbol(CallSymbol);
if (!CalleeBF || !CalleeBF->isPLTFunction())
continue;
const InstructionListType NewCode = BC.MIB->createIndirectPltCall(
*II, CalleeBF->getPLTSymbol(), BC.Ctx.get());
const InstructionListType NewCode = BC.MIB->createIndirectPLTCall(
std::move(*II), CalleeBF->getPLTSymbol(), BC.Ctx.get());
II = BB.replaceInstruction(II, NewCode);
assert(!NewCode.empty() && "PLT Call replacement must be non-empty");
std::advance(II, NewCode.size() - 1);
Expand Down
5 changes: 2 additions & 3 deletions bolt/lib/Target/AArch64/AArch64MCPlusBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1263,7 +1263,7 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
return true;
}

InstructionListType createIndirectPltCall(const MCInst &DirectCall,
InstructionListType createIndirectPLTCall(MCInst &&DirectCall,
const MCSymbol *TargetLocation,
MCContext *Ctx) override {
const bool IsTailCall = isTailCall(DirectCall);
Expand Down Expand Up @@ -1297,8 +1297,7 @@ class AArch64MCPlusBuilder : public MCPlusBuilder {
MCInst InstCall;
InstCall.setOpcode(IsTailCall ? AArch64::BR : AArch64::BLR);
InstCall.addOperand(MCOperand::createReg(AArch64::X17));
if (IsTailCall)
setTailCall(InstCall);
moveAnnotations(std::move(DirectCall), InstCall);
Code.emplace_back(InstCall);

return Code;
Expand Down
2 changes: 1 addition & 1 deletion bolt/lib/Target/X86/X86MCPlusBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1605,7 +1605,7 @@ class X86MCPlusBuilder : public MCPlusBuilder {
return true;
}

InstructionListType createIndirectPltCall(const MCInst &DirectCall,
InstructionListType createIndirectPLTCall(MCInst &&DirectCall,
const MCSymbol *TargetLocation,
MCContext *Ctx) override {
assert((DirectCall.getOpcode() == X86::CALL64pcrel32 ||
Expand Down
21 changes: 21 additions & 0 deletions bolt/test/AArch64/exceptions-plt.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// Verify that PLT optimization in BOLT preserves exception-handling info.

// REQUIRES: system-linux

// RUN: %clangxx %cxxflags -O1 -Wl,-q,-znow %s -o %t.exe
// RUN: llvm-bolt %t.exe -o %t.bolt.exe --plt=all --print-only=.*main.* \
// RUN: --print-finalized 2>&1 | FileCheck %s

// CHECK-LABEL: Binary Function
// CHECK: adrp {{.*}}__cxa_throw
// CHECK-NEXT: ldr {{.*}}__cxa_throw
// CHECK-NEXT: blr x17 {{.*}} handler: {{.*}} PLTCall:

int main() {
try {
throw new int;
} catch (...) {
return 0;
}
return 1;
}
16 changes: 16 additions & 0 deletions bolt/test/runtime/exceptions-plt.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Verify that PLT optimization in BOLT preserves exception-handling info.

// REQUIRES: system-linux

// RUN: %clangxx %cxxflags -O1 -Wl,-q,-znow %s -o %t.exe
// RUN: llvm-bolt %t.exe -o %t.bolt.exe --plt=all
// RUN: %t.bolt.exe

int main() {
try {
throw new int;
} catch (...) {
return 0;
}
return 1;
}

0 comments on commit 34c6c5e

Please sign in to comment.