Skip to content

Commit b9383a8

Browse files
authored
[JITLink] Some cleanups to EHFrameSupport (#66707)
* Remove unused variable. * Error on existing edge at CIE pointer field. * Simplify CFI processing in `EHFrameEdgeFixer`: The code expects `DWARFRecordSectionSplitter` to split each CFI record into its own block, so remove loop over possibly multiple entries in one block.
1 parent 13ffc61 commit b9383a8

File tree

6 files changed

+84
-134
lines changed

6 files changed

+84
-134
lines changed

llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp

+52-90
Original file line numberDiff line numberDiff line change
@@ -138,71 +138,52 @@ Error EHFrameEdgeFixer::processBlock(ParseContext &PC, Block &B) {
138138
BlockEdges[E.getOffset()] = EdgeTarget(E);
139139
}
140140

141-
CIEInfosMap CIEInfos;
142141
BinaryStreamReader BlockReader(
143142
StringRef(B.getContent().data(), B.getContent().size()),
144143
PC.G.getEndianness());
145-
while (!BlockReader.empty()) {
146-
size_t RecordStartOffset = BlockReader.getOffset();
147144

148-
LLVM_DEBUG({
149-
dbgs() << " Processing CFI record at "
150-
<< (B.getAddress() + RecordStartOffset) << "\n";
151-
});
152-
153-
// Get the record length.
154-
Expected<size_t> RecordRemaining = readCFIRecordLength(B, BlockReader);
155-
if (!RecordRemaining)
156-
return RecordRemaining.takeError();
157-
158-
if (BlockReader.bytesRemaining() < *RecordRemaining)
159-
return make_error<JITLinkError>(
160-
"Incomplete CFI record at " +
161-
formatv("{0:x16}", B.getAddress() + RecordStartOffset));
145+
// Get the record length.
146+
Expected<size_t> RecordRemaining = readCFIRecordLength(B, BlockReader);
147+
if (!RecordRemaining)
148+
return RecordRemaining.takeError();
149+
150+
// We expect DWARFRecordSectionSplitter to split each CFI record into its own
151+
// block.
152+
if (BlockReader.bytesRemaining() != *RecordRemaining)
153+
return make_error<JITLinkError>("Incomplete CFI record at " +
154+
formatv("{0:x16}", B.getAddress()));
155+
156+
// Read the CIE delta for this record.
157+
uint64_t CIEDeltaFieldOffset = BlockReader.getOffset();
158+
uint32_t CIEDelta;
159+
if (auto Err = BlockReader.readInteger(CIEDelta))
160+
return Err;
162161

163-
// Read the CIE delta for this record.
164-
uint64_t CIEDeltaFieldOffset = BlockReader.getOffset() - RecordStartOffset;
165-
uint32_t CIEDelta;
166-
if (auto Err = BlockReader.readInteger(CIEDelta))
162+
if (CIEDelta == 0) {
163+
if (auto Err = processCIE(PC, B, CIEDeltaFieldOffset, BlockEdges))
164+
return Err;
165+
} else {
166+
if (auto Err = processFDE(PC, B, CIEDeltaFieldOffset, CIEDelta, BlockEdges))
167167
return Err;
168-
169-
if (CIEDelta == 0) {
170-
if (auto Err = processCIE(PC, B, RecordStartOffset,
171-
CIEDeltaFieldOffset + *RecordRemaining,
172-
CIEDeltaFieldOffset, BlockEdges))
173-
return Err;
174-
} else {
175-
if (auto Err = processFDE(PC, B, RecordStartOffset,
176-
CIEDeltaFieldOffset + *RecordRemaining,
177-
CIEDeltaFieldOffset, CIEDelta, BlockEdges))
178-
return Err;
179-
}
180-
181-
// Move to the next record.
182-
BlockReader.setOffset(RecordStartOffset + CIEDeltaFieldOffset +
183-
*RecordRemaining);
184168
}
185169

186170
return Error::success();
187171
}
188172

189173
Error EHFrameEdgeFixer::processCIE(ParseContext &PC, Block &B,
190-
size_t RecordOffset, size_t RecordLength,
191174
size_t CIEDeltaFieldOffset,
192175
const BlockEdgeMap &BlockEdges) {
193176

194-
LLVM_DEBUG(dbgs() << " Record is CIE\n");
177+
LLVM_DEBUG(dbgs() << " Record is CIE\n");
195178

196-
auto RecordContent = B.getContent().slice(RecordOffset, RecordLength);
197179
BinaryStreamReader RecordReader(
198-
StringRef(RecordContent.data(), RecordContent.size()),
180+
StringRef(B.getContent().data(), B.getContent().size()),
199181
PC.G.getEndianness());
200182

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

204-
auto &CIESymbol =
205-
PC.G.addAnonymousSymbol(B, RecordOffset, RecordLength, false, false);
186+
auto &CIESymbol = PC.G.addAnonymousSymbol(B, 0, B.getSize(), false, false);
206187
CIEInformation CIEInfo(CIESymbol);
207188

208189
uint8_t Version = 0;
@@ -268,7 +249,7 @@ Error EHFrameEdgeFixer::processCIE(ParseContext &PC, Block &B,
268249
if (auto Err =
269250
getOrCreateEncodedPointerEdge(
270251
PC, BlockEdges, *PersonalityPointerEncoding, RecordReader,
271-
B, RecordOffset + RecordReader.getOffset(), "personality")
252+
B, RecordReader.getOffset(), "personality")
272253
.takeError())
273254
return Err;
274255
break;
@@ -279,7 +260,7 @@ Error EHFrameEdgeFixer::processCIE(ParseContext &PC, Block &B,
279260
if (CIEInfo.AddressEncoding == dwarf::DW_EH_PE_omit)
280261
return make_error<JITLinkError>(
281262
"Invalid address encoding DW_EH_PE_omit in CIE at " +
282-
formatv("{0:x}", (B.getAddress() + RecordOffset).getValue()));
263+
formatv("{0:x}", B.getAddress().getValue()));
283264
} else
284265
return PE.takeError();
285266
break;
@@ -302,69 +283,50 @@ Error EHFrameEdgeFixer::processCIE(ParseContext &PC, Block &B,
302283
}
303284

304285
Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B,
305-
size_t RecordOffset, size_t RecordLength,
306286
size_t CIEDeltaFieldOffset,
307287
uint32_t CIEDelta,
308288
const BlockEdgeMap &BlockEdges) {
309-
LLVM_DEBUG(dbgs() << " Record is FDE\n");
289+
LLVM_DEBUG(dbgs() << " Record is FDE\n");
310290

311-
orc::ExecutorAddr RecordAddress = B.getAddress() + RecordOffset;
291+
orc::ExecutorAddr RecordAddress = B.getAddress();
312292

313-
auto RecordContent = B.getContent().slice(RecordOffset, RecordLength);
314293
BinaryStreamReader RecordReader(
315-
StringRef(RecordContent.data(), RecordContent.size()),
294+
StringRef(B.getContent().data(), B.getContent().size()),
316295
PC.G.getEndianness());
317296

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

321-
auto &FDESymbol =
322-
PC.G.addAnonymousSymbol(B, RecordOffset, RecordLength, false, false);
300+
auto &FDESymbol = PC.G.addAnonymousSymbol(B, 0, B.getSize(), false, false);
323301

324302
CIEInformation *CIEInfo = nullptr;
325303

326304
{
327305
// Process the CIE pointer field.
328-
auto CIEEdgeItr = BlockEdges.find(RecordOffset + CIEDeltaFieldOffset);
306+
auto CIEEdgeItr = BlockEdges.find(CIEDeltaFieldOffset);
307+
if (CIEEdgeItr != BlockEdges.end())
308+
return make_error<JITLinkError>(
309+
"CIE pointer field already has edge at " +
310+
formatv("{0:x16}", RecordAddress + CIEDeltaFieldOffset));
311+
329312
orc::ExecutorAddr CIEAddress =
330313
RecordAddress + orc::ExecutorAddrDiff(CIEDeltaFieldOffset) -
331314
orc::ExecutorAddrDiff(CIEDelta);
332-
if (CIEEdgeItr == BlockEdges.end()) {
333-
334-
LLVM_DEBUG({
335-
dbgs() << " Adding edge at "
336-
<< (RecordAddress + CIEDeltaFieldOffset)
337-
<< " to CIE at: " << CIEAddress << "\n";
338-
});
339-
if (auto CIEInfoOrErr = PC.findCIEInfo(CIEAddress))
340-
CIEInfo = *CIEInfoOrErr;
341-
else
342-
return CIEInfoOrErr.takeError();
343-
assert(CIEInfo->CIESymbol && "CIEInfo has no CIE symbol set");
344-
B.addEdge(NegDelta32, RecordOffset + CIEDeltaFieldOffset,
345-
*CIEInfo->CIESymbol, 0);
346-
} else {
347-
LLVM_DEBUG({
348-
dbgs() << " Already has edge at "
349-
<< (RecordAddress + CIEDeltaFieldOffset) << " to CIE at "
350-
<< CIEAddress << "\n";
351-
});
352-
auto &EI = CIEEdgeItr->second;
353-
if (EI.Addend)
354-
return make_error<JITLinkError>(
355-
"CIE edge at " +
356-
formatv("{0:x16}", RecordAddress + CIEDeltaFieldOffset) +
357-
" has non-zero addend");
358-
if (auto CIEInfoOrErr = PC.findCIEInfo(EI.Target->getAddress()))
359-
CIEInfo = *CIEInfoOrErr;
360-
else
361-
return CIEInfoOrErr.takeError();
362-
}
315+
LLVM_DEBUG({
316+
dbgs() << " Adding edge at " << (RecordAddress + CIEDeltaFieldOffset)
317+
<< " to CIE at: " << CIEAddress << "\n";
318+
});
319+
if (auto CIEInfoOrErr = PC.findCIEInfo(CIEAddress))
320+
CIEInfo = *CIEInfoOrErr;
321+
else
322+
return CIEInfoOrErr.takeError();
323+
assert(CIEInfo->CIESymbol && "CIEInfo has no CIE symbol set");
324+
B.addEdge(NegDelta32, CIEDeltaFieldOffset, *CIEInfo->CIESymbol, 0);
363325
}
364326

365327
// Process the PC-Begin field.
366328
LLVM_DEBUG({
367-
dbgs() << " Processing PC-begin at "
329+
dbgs() << " Processing PC-begin at "
368330
<< (RecordAddress + RecordReader.getOffset()) << "\n";
369331
});
370332
if (auto PCBegin = getOrCreateEncodedPointerEdge(
@@ -375,14 +337,14 @@ Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B,
375337
// Add a keep-alive edge from the FDE target to the FDE to ensure that the
376338
// FDE is kept alive if its target is.
377339
LLVM_DEBUG({
378-
dbgs() << " Adding keep-alive edge from target at "
340+
dbgs() << " Adding keep-alive edge from target at "
379341
<< (*PCBegin)->getBlock().getAddress() << " to FDE at "
380342
<< RecordAddress << "\n";
381343
});
382344
(*PCBegin)->getBlock().addEdge(Edge::KeepAlive, 0, FDESymbol, 0);
383345
} else {
384346
LLVM_DEBUG({
385-
dbgs() << " WARNING: Not adding keep-alive edge to FDE at "
347+
dbgs() << " WARNING: Not adding keep-alive edge to FDE at "
386348
<< RecordAddress << ", which points to "
387349
<< ((*PCBegin)->isExternal() ? "external" : "absolute")
388350
<< " symbol \"" << (*PCBegin)->getName()
@@ -409,7 +371,7 @@ Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B,
409371
.takeError())
410372
return Err;
411373
} else {
412-
LLVM_DEBUG(dbgs() << " Record does not have LSDA field.\n");
374+
LLVM_DEBUG(dbgs() << " Record does not have LSDA field.\n");
413375
}
414376

415377
return Error::success();
@@ -534,7 +496,7 @@ Expected<Symbol *> EHFrameEdgeFixer::getOrCreateEncodedPointerEdge(
534496
auto EdgeI = BlockEdges.find(PointerFieldOffset);
535497
if (EdgeI != BlockEdges.end()) {
536498
LLVM_DEBUG({
537-
dbgs() << " Existing edge at "
499+
dbgs() << " Existing edge at "
538500
<< (BlockToFix.getAddress() + PointerFieldOffset) << " to "
539501
<< FieldName << " at " << EdgeI->second.Target->getAddress();
540502
if (EdgeI->second.Target->hasName())
@@ -596,7 +558,7 @@ Expected<Symbol *> EHFrameEdgeFixer::getOrCreateEncodedPointerEdge(
596558
BlockToFix.addEdge(PtrEdgeKind, PointerFieldOffset, *TargetSym, 0);
597559

598560
LLVM_DEBUG({
599-
dbgs() << " Adding edge at "
561+
dbgs() << " Adding edge at "
600562
<< (BlockToFix.getAddress() + PointerFieldOffset) << " to "
601563
<< FieldName << " at " << TargetSym->getAddress();
602564
if (TargetSym->hasName())

llvm/lib/ExecutionEngine/JITLink/EHFrameSupportImpl.h

+2-4
Original file line numberDiff line numberDiff line change
@@ -81,11 +81,9 @@ class EHFrameEdgeFixer {
8181
};
8282

8383
Error processBlock(ParseContext &PC, Block &B);
84-
Error processCIE(ParseContext &PC, Block &B, size_t RecordOffset,
85-
size_t RecordLength, size_t CIEDeltaFieldOffset,
84+
Error processCIE(ParseContext &PC, Block &B, size_t CIEDeltaFieldOffset,
8685
const BlockEdgeMap &BlockEdges);
87-
Error processFDE(ParseContext &PC, Block &B, size_t RecordOffset,
88-
size_t RecordLength, size_t CIEDeltaFieldOffset,
86+
Error processFDE(ParseContext &PC, Block &B, size_t CIEDeltaFieldOffset,
8987
uint32_t CIEDelta, const BlockEdgeMap &BlockEdges);
9088

9189
Expected<AugmentationInfo>

llvm/test/ExecutionEngine/JITLink/AArch64/ELF_ehframe.s

+9-12
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,17 @@
1313
# CHECK: Extracted {{.*}} section = .eh_frame
1414
# CHECK: EHFrameEdgeFixer: Processing .eh_frame in "{{.*}}"...
1515
# CHECK: Processing block at
16-
# CHECK: Processing CFI record at
17-
# CHECK: Record is CIE
16+
# CHECK: Record is CIE
1817
# CHECK: Processing block at
19-
# CHECK: Processing CFI record at
20-
# CHECK: Record is FDE
21-
# CHECK: Adding edge at {{.*}} to CIE at: {{.*}}
22-
# CHECK: Existing edge at {{.*}} to PC begin at {{.*}}
23-
# CHECK: Adding keep-alive edge from target at {{.*}} to FDE at {{.*}}
18+
# CHECK: Record is FDE
19+
# CHECK: Adding edge at {{.*}} to CIE at: {{.*}}
20+
# CHECK: Existing edge at {{.*}} to PC begin at {{.*}}
21+
# CHECK: Adding keep-alive edge from target at {{.*}} to FDE at {{.*}}
2422
# CHECK: Processing block at
25-
# CHECK: Processing CFI record at
26-
# CHECK: Record is FDE
27-
# CHECK: Adding edge at {{.*}} to CIE at: {{.*}}
28-
# CHECK: Existing edge at {{.*}} to PC begin at {{.*}}
29-
# CHECK: Adding keep-alive edge from target at {{.*}} to FDE at {{.*}}
23+
# CHECK: Record is FDE
24+
# CHECK: Adding edge at {{.*}} to CIE at: {{.*}}
25+
# CHECK: Existing edge at {{.*}} to PC begin at {{.*}}
26+
# CHECK: Adding keep-alive edge from target at {{.*}} to FDE at {{.*}}
3027

3128
.text
3229
.globl main

llvm/test/ExecutionEngine/JITLink/AArch64/MachO_ehframe.s

+6-8
Original file line numberDiff line numberDiff line change
@@ -13,15 +13,13 @@
1313
# CHECK: Extracted {{.*}} section = __TEXT,__eh_frame
1414
# CHECK: EHFrameEdgeFixer: Processing __TEXT,__eh_frame in "{{.*}}"...
1515
# CHECK: Processing block at
16-
# CHECK: Processing CFI record at
17-
# CHECK: Record is CIE
16+
# CHECK: Record is CIE
1817
# CHECK: Processing block at
19-
# CHECK: Processing CFI record at
20-
# CHECK: Record is FDE
21-
# CHECK: Adding edge at {{.*}} to CIE at: {{.*}}
22-
# CHECK: Existing edge at {{.*}} to PC begin at {{.*}}
23-
# CHECK: Adding keep-alive edge from target at {{.*}} to FDE at {{.*}}
24-
# CHECK: Existing edge at {{.*}} to LSDA at {{.*}}
18+
# CHECK: Record is FDE
19+
# CHECK: Adding edge at {{.*}} to CIE at: {{.*}}
20+
# CHECK: Existing edge at {{.*}} to PC begin at {{.*}}
21+
# CHECK: Adding keep-alive edge from target at {{.*}} to FDE at {{.*}}
22+
# CHECK: Existing edge at {{.*}} to LSDA at {{.*}}
2523

2624
.section __TEXT,__text,regular,pure_instructions
2725
.globl _main

llvm/test/ExecutionEngine/JITLink/LoongArch/ELF_loongarch64_ehframe.s

+9-12
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,17 @@
1313
# CHECK: Extracted {{.*}} section = .eh_frame
1414
# CHECK: EHFrameEdgeFixer: Processing .eh_frame in "{{.*}}"...
1515
# CHECK: Processing block at
16-
# CHECK: Processing CFI record at
17-
# CHECK: Record is CIE
16+
# CHECK: Record is CIE
1817
# CHECK: Processing block at
19-
# CHECK: Processing CFI record at
20-
# CHECK: Record is FDE
21-
# CHECK: Adding edge at {{.*}} to CIE at: {{.*}}
22-
# CHECK: Existing edge at {{.*}} to PC begin at {{.*}}
23-
# CHECK: Adding keep-alive edge from target at {{.*}} to FDE at {{.*}}
18+
# CHECK: Record is FDE
19+
# CHECK: Adding edge at {{.*}} to CIE at: {{.*}}
20+
# CHECK: Existing edge at {{.*}} to PC begin at {{.*}}
21+
# CHECK: Adding keep-alive edge from target at {{.*}} to FDE at {{.*}}
2422
# CHECK: Processing block at
25-
# CHECK: Processing CFI record at
26-
# CHECK: Record is FDE
27-
# CHECK: Adding edge at {{.*}} to CIE at: {{.*}}
28-
# CHECK: Existing edge at {{.*}} to PC begin at {{.*}}
29-
# CHECK: Adding keep-alive edge from target at {{.*}} to FDE at {{.*}}
23+
# CHECK: Record is FDE
24+
# CHECK: Adding edge at {{.*}} to CIE at: {{.*}}
25+
# CHECK: Existing edge at {{.*}} to PC begin at {{.*}}
26+
# CHECK: Adding keep-alive edge from target at {{.*}} to FDE at {{.*}}
3027

3128
.text
3229
.globl main

llvm/test/ExecutionEngine/JITLink/ppc64/ELF_ppc64_ehframe.s

+6-8
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,13 @@
1616
# CHECK: Extracted {{.*}} section = .eh_frame
1717
# CHECK: EHFrameEdgeFixer: Processing .eh_frame in "{{.*}}"...
1818
# CHECK: Processing block at
19-
# CHECK: Processing CFI record at
20-
# CHECK: Record is CIE
19+
# CHECK: Record is CIE
2120
# CHECK: Processing block at
22-
# CHECK: Processing CFI record at
23-
# CHECK: Record is FDE
24-
# CHECK: Adding edge at {{.*}} to CIE at: {{.*}}
25-
# CHECK: Processing PC-begin at
26-
# CHECK: Existing edge at {{.*}} to PC begin at {{.*}}
27-
# CHECK: Adding keep-alive edge from target at {{.*}} to FDE at {{.*}}
21+
# CHECK: Record is FDE
22+
# CHECK: Adding edge at {{.*}} to CIE at: {{.*}}
23+
# CHECK: Processing PC-begin at
24+
# CHECK: Existing edge at {{.*}} to PC begin at {{.*}}
25+
# CHECK: Adding keep-alive edge from target at {{.*}} to FDE at {{.*}}
2826

2927
.text
3028
.abiversion 2

0 commit comments

Comments
 (0)