Skip to content

Commit bcb5399

Browse files
committed
[JITLink] Add a null-terminator to eh-frame sections on ELF/x86-64.
__register_ehframes on Linux requires a null terminator to identify the end of this section.
1 parent 714ec86 commit bcb5399

File tree

3 files changed

+35
-0
lines changed

3 files changed

+35
-0
lines changed

llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -730,6 +730,29 @@ Expected<Symbol &> EHFrameEdgeFixer::getOrCreateSymbol(ParseContext &PC,
730730
return PC.G.addAnonymousSymbol(*B, Addr - B->getAddress(), 0, false, false);
731731
}
732732

733+
char EHFrameNullTerminator::NullTerminatorBlockContent[] = {0, 0, 0, 0};
734+
735+
EHFrameNullTerminator::EHFrameNullTerminator(StringRef EHFrameSectionName)
736+
: EHFrameSectionName(EHFrameSectionName) {}
737+
738+
Error EHFrameNullTerminator::operator()(LinkGraph &G) {
739+
auto *EHFrame = G.findSectionByName(EHFrameSectionName);
740+
741+
if (!EHFrame)
742+
return Error::success();
743+
744+
LLVM_DEBUG({
745+
dbgs() << "EHFrameNullTerminator adding null terminator to "
746+
<< EHFrameSectionName << "\n";
747+
});
748+
749+
auto &NullTerminatorBlock =
750+
G.createContentBlock(*EHFrame, StringRef(NullTerminatorBlockContent, 4),
751+
0xfffffffffffffffc, 1, 0);
752+
G.addAnonymousSymbol(NullTerminatorBlock, 0, 4, false, true);
753+
return Error::success();
754+
}
755+
733756
EHFrameRegistrar::~EHFrameRegistrar() {}
734757

735758
Error InProcessEHFrameRegistrar::registerEHFrames(

llvm/lib/ExecutionEngine/JITLink/EHFrameSupportImpl.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,17 @@ class EHFrameEdgeFixer {
116116
Edge::Kind NegDelta32;
117117
};
118118

119+
/// Add a 32-bit null-terminator to the end of the eh-frame section.
120+
class EHFrameNullTerminator {
121+
public:
122+
EHFrameNullTerminator(StringRef EHFrameSectionName);
123+
Error operator()(LinkGraph &G);
124+
125+
private:
126+
static char NullTerminatorBlockContent[];
127+
StringRef EHFrameSectionName;
128+
};
129+
119130
} // end namespace jitlink
120131
} // end namespace llvm
121132

llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -768,6 +768,7 @@ void link_ELF_x86_64(std::unique_ptr<LinkGraph> G,
768768
Config.PrePrunePasses.push_back(EHFrameSplitter(".eh_frame"));
769769
Config.PrePrunePasses.push_back(EHFrameEdgeFixer(
770770
".eh_frame", G->getPointerSize(), Delta64, Delta32, NegDelta32));
771+
Config.PrePrunePasses.push_back(EHFrameNullTerminator(".eh_frame"));
771772

772773
// Construct a JITLinker and run the link function.
773774
// Add a mark-live pass.

0 commit comments

Comments
 (0)