Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[JITLink] Some cleanups to EHFrameSupport #66707

Merged
merged 3 commits into from
Oct 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
142 changes: 52 additions & 90 deletions llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,71 +138,52 @@ Error EHFrameEdgeFixer::processBlock(ParseContext &PC, Block &B) {
BlockEdges[E.getOffset()] = EdgeTarget(E);
}

CIEInfosMap CIEInfos;
BinaryStreamReader BlockReader(
StringRef(B.getContent().data(), B.getContent().size()),
PC.G.getEndianness());
while (!BlockReader.empty()) {
size_t RecordStartOffset = BlockReader.getOffset();

LLVM_DEBUG({
dbgs() << " Processing CFI record at "
<< (B.getAddress() + RecordStartOffset) << "\n";
});

// Get the record length.
Expected<size_t> RecordRemaining = readCFIRecordLength(B, BlockReader);
if (!RecordRemaining)
return RecordRemaining.takeError();

if (BlockReader.bytesRemaining() < *RecordRemaining)
return make_error<JITLinkError>(
"Incomplete CFI record at " +
formatv("{0:x16}", B.getAddress() + RecordStartOffset));
// Get the record length.
Expected<size_t> RecordRemaining = readCFIRecordLength(B, BlockReader);
if (!RecordRemaining)
return RecordRemaining.takeError();

// We expect DWARFRecordSectionSplitter to split each CFI record into its own
// block.
if (BlockReader.bytesRemaining() != *RecordRemaining)
return make_error<JITLinkError>("Incomplete CFI record at " +
formatv("{0:x16}", B.getAddress()));

// Read the CIE delta for this record.
uint64_t CIEDeltaFieldOffset = BlockReader.getOffset();
uint32_t CIEDelta;
if (auto Err = BlockReader.readInteger(CIEDelta))
return Err;

// Read the CIE delta for this record.
uint64_t CIEDeltaFieldOffset = BlockReader.getOffset() - RecordStartOffset;
uint32_t CIEDelta;
if (auto Err = BlockReader.readInteger(CIEDelta))
if (CIEDelta == 0) {
if (auto Err = processCIE(PC, B, CIEDeltaFieldOffset, BlockEdges))
return Err;
} else {
if (auto Err = processFDE(PC, B, CIEDeltaFieldOffset, CIEDelta, BlockEdges))
return Err;

if (CIEDelta == 0) {
if (auto Err = processCIE(PC, B, RecordStartOffset,
CIEDeltaFieldOffset + *RecordRemaining,
CIEDeltaFieldOffset, BlockEdges))
return Err;
} else {
if (auto Err = processFDE(PC, B, RecordStartOffset,
CIEDeltaFieldOffset + *RecordRemaining,
CIEDeltaFieldOffset, CIEDelta, BlockEdges))
return Err;
}

// Move to the next record.
BlockReader.setOffset(RecordStartOffset + CIEDeltaFieldOffset +
*RecordRemaining);
}

return Error::success();
}

Error EHFrameEdgeFixer::processCIE(ParseContext &PC, Block &B,
size_t RecordOffset, size_t RecordLength,
size_t CIEDeltaFieldOffset,
const BlockEdgeMap &BlockEdges) {

LLVM_DEBUG(dbgs() << " Record is CIE\n");
LLVM_DEBUG(dbgs() << " Record is CIE\n");

auto RecordContent = B.getContent().slice(RecordOffset, RecordLength);
BinaryStreamReader RecordReader(
StringRef(RecordContent.data(), RecordContent.size()),
StringRef(B.getContent().data(), B.getContent().size()),
PC.G.getEndianness());

// Skip past the CIE delta field: we've already processed this far.
RecordReader.setOffset(CIEDeltaFieldOffset + 4);

auto &CIESymbol =
PC.G.addAnonymousSymbol(B, RecordOffset, RecordLength, false, false);
auto &CIESymbol = PC.G.addAnonymousSymbol(B, 0, B.getSize(), false, false);
CIEInformation CIEInfo(CIESymbol);

uint8_t Version = 0;
Expand Down Expand Up @@ -268,7 +249,7 @@ Error EHFrameEdgeFixer::processCIE(ParseContext &PC, Block &B,
if (auto Err =
getOrCreateEncodedPointerEdge(
PC, BlockEdges, *PersonalityPointerEncoding, RecordReader,
B, RecordOffset + RecordReader.getOffset(), "personality")
B, RecordReader.getOffset(), "personality")
.takeError())
return Err;
break;
Expand All @@ -279,7 +260,7 @@ Error EHFrameEdgeFixer::processCIE(ParseContext &PC, Block &B,
if (CIEInfo.AddressEncoding == dwarf::DW_EH_PE_omit)
return make_error<JITLinkError>(
"Invalid address encoding DW_EH_PE_omit in CIE at " +
formatv("{0:x}", (B.getAddress() + RecordOffset).getValue()));
formatv("{0:x}", B.getAddress().getValue()));
} else
return PE.takeError();
break;
Expand All @@ -302,69 +283,50 @@ Error EHFrameEdgeFixer::processCIE(ParseContext &PC, Block &B,
}

Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B,
size_t RecordOffset, size_t RecordLength,
size_t CIEDeltaFieldOffset,
uint32_t CIEDelta,
const BlockEdgeMap &BlockEdges) {
LLVM_DEBUG(dbgs() << " Record is FDE\n");
LLVM_DEBUG(dbgs() << " Record is FDE\n");

orc::ExecutorAddr RecordAddress = B.getAddress() + RecordOffset;
orc::ExecutorAddr RecordAddress = B.getAddress();

auto RecordContent = B.getContent().slice(RecordOffset, RecordLength);
BinaryStreamReader RecordReader(
StringRef(RecordContent.data(), RecordContent.size()),
StringRef(B.getContent().data(), B.getContent().size()),
PC.G.getEndianness());

// Skip past the CIE delta field: we've already read this far.
RecordReader.setOffset(CIEDeltaFieldOffset + 4);

auto &FDESymbol =
PC.G.addAnonymousSymbol(B, RecordOffset, RecordLength, false, false);
auto &FDESymbol = PC.G.addAnonymousSymbol(B, 0, B.getSize(), false, false);

CIEInformation *CIEInfo = nullptr;

{
// Process the CIE pointer field.
auto CIEEdgeItr = BlockEdges.find(RecordOffset + CIEDeltaFieldOffset);
auto CIEEdgeItr = BlockEdges.find(CIEDeltaFieldOffset);
if (CIEEdgeItr != BlockEdges.end())
return make_error<JITLinkError>(
"CIE pointer field already has edge at " +
formatv("{0:x16}", RecordAddress + CIEDeltaFieldOffset));

orc::ExecutorAddr CIEAddress =
RecordAddress + orc::ExecutorAddrDiff(CIEDeltaFieldOffset) -
orc::ExecutorAddrDiff(CIEDelta);
if (CIEEdgeItr == BlockEdges.end()) {

LLVM_DEBUG({
dbgs() << " Adding edge at "
<< (RecordAddress + CIEDeltaFieldOffset)
<< " to CIE at: " << CIEAddress << "\n";
});
if (auto CIEInfoOrErr = PC.findCIEInfo(CIEAddress))
CIEInfo = *CIEInfoOrErr;
else
return CIEInfoOrErr.takeError();
assert(CIEInfo->CIESymbol && "CIEInfo has no CIE symbol set");
B.addEdge(NegDelta32, RecordOffset + CIEDeltaFieldOffset,
*CIEInfo->CIESymbol, 0);
} else {
LLVM_DEBUG({
dbgs() << " Already has edge at "
<< (RecordAddress + CIEDeltaFieldOffset) << " to CIE at "
<< CIEAddress << "\n";
});
auto &EI = CIEEdgeItr->second;
if (EI.Addend)
return make_error<JITLinkError>(
"CIE edge at " +
formatv("{0:x16}", RecordAddress + CIEDeltaFieldOffset) +
" has non-zero addend");
if (auto CIEInfoOrErr = PC.findCIEInfo(EI.Target->getAddress()))
CIEInfo = *CIEInfoOrErr;
else
return CIEInfoOrErr.takeError();
}
LLVM_DEBUG({
dbgs() << " Adding edge at " << (RecordAddress + CIEDeltaFieldOffset)
<< " to CIE at: " << CIEAddress << "\n";
});
if (auto CIEInfoOrErr = PC.findCIEInfo(CIEAddress))
CIEInfo = *CIEInfoOrErr;
else
return CIEInfoOrErr.takeError();
assert(CIEInfo->CIESymbol && "CIEInfo has no CIE symbol set");
B.addEdge(NegDelta32, CIEDeltaFieldOffset, *CIEInfo->CIESymbol, 0);
}

// Process the PC-Begin field.
LLVM_DEBUG({
dbgs() << " Processing PC-begin at "
dbgs() << " Processing PC-begin at "
<< (RecordAddress + RecordReader.getOffset()) << "\n";
});
if (auto PCBegin = getOrCreateEncodedPointerEdge(
Expand All @@ -375,14 +337,14 @@ Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B,
// Add a keep-alive edge from the FDE target to the FDE to ensure that the
// FDE is kept alive if its target is.
LLVM_DEBUG({
dbgs() << " Adding keep-alive edge from target at "
dbgs() << " Adding keep-alive edge from target at "
<< (*PCBegin)->getBlock().getAddress() << " to FDE at "
<< RecordAddress << "\n";
});
(*PCBegin)->getBlock().addEdge(Edge::KeepAlive, 0, FDESymbol, 0);
} else {
LLVM_DEBUG({
dbgs() << " WARNING: Not adding keep-alive edge to FDE at "
dbgs() << " WARNING: Not adding keep-alive edge to FDE at "
<< RecordAddress << ", which points to "
<< ((*PCBegin)->isExternal() ? "external" : "absolute")
<< " symbol \"" << (*PCBegin)->getName()
Expand All @@ -409,7 +371,7 @@ Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B,
.takeError())
return Err;
} else {
LLVM_DEBUG(dbgs() << " Record does not have LSDA field.\n");
LLVM_DEBUG(dbgs() << " Record does not have LSDA field.\n");
}

return Error::success();
Expand Down Expand Up @@ -534,7 +496,7 @@ Expected<Symbol *> EHFrameEdgeFixer::getOrCreateEncodedPointerEdge(
auto EdgeI = BlockEdges.find(PointerFieldOffset);
if (EdgeI != BlockEdges.end()) {
LLVM_DEBUG({
dbgs() << " Existing edge at "
dbgs() << " Existing edge at "
<< (BlockToFix.getAddress() + PointerFieldOffset) << " to "
<< FieldName << " at " << EdgeI->second.Target->getAddress();
if (EdgeI->second.Target->hasName())
Expand Down Expand Up @@ -596,7 +558,7 @@ Expected<Symbol *> EHFrameEdgeFixer::getOrCreateEncodedPointerEdge(
BlockToFix.addEdge(PtrEdgeKind, PointerFieldOffset, *TargetSym, 0);

LLVM_DEBUG({
dbgs() << " Adding edge at "
dbgs() << " Adding edge at "
<< (BlockToFix.getAddress() + PointerFieldOffset) << " to "
<< FieldName << " at " << TargetSym->getAddress();
if (TargetSym->hasName())
Expand Down
6 changes: 2 additions & 4 deletions llvm/lib/ExecutionEngine/JITLink/EHFrameSupportImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,11 +81,9 @@ class EHFrameEdgeFixer {
};

Error processBlock(ParseContext &PC, Block &B);
Error processCIE(ParseContext &PC, Block &B, size_t RecordOffset,
size_t RecordLength, size_t CIEDeltaFieldOffset,
Error processCIE(ParseContext &PC, Block &B, size_t CIEDeltaFieldOffset,
const BlockEdgeMap &BlockEdges);
Error processFDE(ParseContext &PC, Block &B, size_t RecordOffset,
size_t RecordLength, size_t CIEDeltaFieldOffset,
Error processFDE(ParseContext &PC, Block &B, size_t CIEDeltaFieldOffset,
uint32_t CIEDelta, const BlockEdgeMap &BlockEdges);

Expected<AugmentationInfo>
Expand Down
21 changes: 9 additions & 12 deletions llvm/test/ExecutionEngine/JITLink/AArch64/ELF_ehframe.s
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,17 @@
# CHECK: Extracted {{.*}} section = .eh_frame
# CHECK: EHFrameEdgeFixer: Processing .eh_frame in "{{.*}}"...
# CHECK: Processing block at
# CHECK: Processing CFI record at
# CHECK: Record is CIE
# CHECK: Record is CIE
# CHECK: Processing block at
# CHECK: Processing CFI record at
# CHECK: Record is FDE
# CHECK: Adding edge at {{.*}} to CIE at: {{.*}}
# CHECK: Existing edge at {{.*}} to PC begin at {{.*}}
# CHECK: Adding keep-alive edge from target at {{.*}} to FDE at {{.*}}
# CHECK: Record is FDE
# CHECK: Adding edge at {{.*}} to CIE at: {{.*}}
# CHECK: Existing edge at {{.*}} to PC begin at {{.*}}
# CHECK: Adding keep-alive edge from target at {{.*}} to FDE at {{.*}}
# CHECK: Processing block at
# CHECK: Processing CFI record at
# CHECK: Record is FDE
# CHECK: Adding edge at {{.*}} to CIE at: {{.*}}
# CHECK: Existing edge at {{.*}} to PC begin at {{.*}}
# CHECK: Adding keep-alive edge from target at {{.*}} to FDE at {{.*}}
# CHECK: Record is FDE
# CHECK: Adding edge at {{.*}} to CIE at: {{.*}}
# CHECK: Existing edge at {{.*}} to PC begin at {{.*}}
# CHECK: Adding keep-alive edge from target at {{.*}} to FDE at {{.*}}

.text
.globl main
Expand Down
14 changes: 6 additions & 8 deletions llvm/test/ExecutionEngine/JITLink/AArch64/MachO_ehframe.s
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,13 @@
# CHECK: Extracted {{.*}} section = __TEXT,__eh_frame
# CHECK: EHFrameEdgeFixer: Processing __TEXT,__eh_frame in "{{.*}}"...
# CHECK: Processing block at
# CHECK: Processing CFI record at
# CHECK: Record is CIE
# CHECK: Record is CIE
# CHECK: Processing block at
# CHECK: Processing CFI record at
# CHECK: Record is FDE
# CHECK: Adding edge at {{.*}} to CIE at: {{.*}}
# CHECK: Existing edge at {{.*}} to PC begin at {{.*}}
# CHECK: Adding keep-alive edge from target at {{.*}} to FDE at {{.*}}
# CHECK: Existing edge at {{.*}} to LSDA at {{.*}}
# CHECK: Record is FDE
# CHECK: Adding edge at {{.*}} to CIE at: {{.*}}
# CHECK: Existing edge at {{.*}} to PC begin at {{.*}}
# CHECK: Adding keep-alive edge from target at {{.*}} to FDE at {{.*}}
# CHECK: Existing edge at {{.*}} to LSDA at {{.*}}

.section __TEXT,__text,regular,pure_instructions
.globl _main
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,20 +13,17 @@
# CHECK: Extracted {{.*}} section = .eh_frame
# CHECK: EHFrameEdgeFixer: Processing .eh_frame in "{{.*}}"...
# CHECK: Processing block at
# CHECK: Processing CFI record at
# CHECK: Record is CIE
# CHECK: Record is CIE
# CHECK: Processing block at
# CHECK: Processing CFI record at
# CHECK: Record is FDE
# CHECK: Adding edge at {{.*}} to CIE at: {{.*}}
# CHECK: Existing edge at {{.*}} to PC begin at {{.*}}
# CHECK: Adding keep-alive edge from target at {{.*}} to FDE at {{.*}}
# CHECK: Record is FDE
# CHECK: Adding edge at {{.*}} to CIE at: {{.*}}
# CHECK: Existing edge at {{.*}} to PC begin at {{.*}}
# CHECK: Adding keep-alive edge from target at {{.*}} to FDE at {{.*}}
# CHECK: Processing block at
# CHECK: Processing CFI record at
# CHECK: Record is FDE
# CHECK: Adding edge at {{.*}} to CIE at: {{.*}}
# CHECK: Existing edge at {{.*}} to PC begin at {{.*}}
# CHECK: Adding keep-alive edge from target at {{.*}} to FDE at {{.*}}
# CHECK: Record is FDE
# CHECK: Adding edge at {{.*}} to CIE at: {{.*}}
# CHECK: Existing edge at {{.*}} to PC begin at {{.*}}
# CHECK: Adding keep-alive edge from target at {{.*}} to FDE at {{.*}}

.text
.globl main
Expand Down
14 changes: 6 additions & 8 deletions llvm/test/ExecutionEngine/JITLink/ppc64/ELF_ppc64_ehframe.s
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,13 @@
# CHECK: Extracted {{.*}} section = .eh_frame
# CHECK: EHFrameEdgeFixer: Processing .eh_frame in "{{.*}}"...
# CHECK: Processing block at
# CHECK: Processing CFI record at
# CHECK: Record is CIE
# CHECK: Record is CIE
# CHECK: Processing block at
# CHECK: Processing CFI record at
# CHECK: Record is FDE
# CHECK: Adding edge at {{.*}} to CIE at: {{.*}}
# CHECK: Processing PC-begin at
# CHECK: Existing edge at {{.*}} to PC begin at {{.*}}
# CHECK: Adding keep-alive edge from target at {{.*}} to FDE at {{.*}}
# CHECK: Record is FDE
# CHECK: Adding edge at {{.*}} to CIE at: {{.*}}
# CHECK: Processing PC-begin at
# CHECK: Existing edge at {{.*}} to PC begin at {{.*}}
# CHECK: Adding keep-alive edge from target at {{.*}} to FDE at {{.*}}

.text
.abiversion 2
Expand Down