From afb77092bf94e0deb83f684b9aae53e3a63dd66d Mon Sep 17 00:00:00 2001 From: Jonas Hahnfeld Date: Mon, 18 Sep 2023 21:53:21 +0200 Subject: [PATCH 1/3] [JITLink][EHFrameSupport] Remove unused variable --- llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp b/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp index 86249591a9be05..63ba765c8620ed 100644 --- a/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp @@ -138,7 +138,6 @@ 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()); From fa4ea1497bc39d4c0001e96cfbf8afb40d82e992 Mon Sep 17 00:00:00 2001 From: Jonas Hahnfeld Date: Mon, 18 Sep 2023 21:22:53 +0200 Subject: [PATCH 2/3] [JITLink][EHFrameSupport] Error on existing edge at CIE pointer field --- .../JITLink/EHFrameSupport.cpp | 48 +++++++------------ 1 file changed, 17 insertions(+), 31 deletions(-) diff --git a/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp b/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp index 63ba765c8620ed..7b2af45ad3ce66 100644 --- a/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp @@ -325,40 +325,26 @@ Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B, { // Process the CIE pointer field. auto CIEEdgeItr = BlockEdges.find(RecordOffset + CIEDeltaFieldOffset); + if (CIEEdgeItr != BlockEdges.end()) + return make_error( + "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( - "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, RecordOffset + CIEDeltaFieldOffset, + *CIEInfo->CIESymbol, 0); } // Process the PC-Begin field. From 124eca11f17e8b7a3203aa3fd3b3794e4e28f0db Mon Sep 17 00:00:00 2001 From: Jonas Hahnfeld Date: Mon, 18 Sep 2023 23:49:04 +0200 Subject: [PATCH 3/3] [JITLink] 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. --- .../JITLink/EHFrameSupport.cpp | 101 +++++++----------- .../JITLink/EHFrameSupportImpl.h | 6 +- .../JITLink/AArch64/ELF_ehframe.s | 21 ++-- .../JITLink/AArch64/MachO_ehframe.s | 14 ++- .../LoongArch/ELF_loongarch64_ehframe.s | 21 ++-- .../JITLink/ppc64/ELF_ppc64_ehframe.s | 14 ++- 6 files changed, 71 insertions(+), 106 deletions(-) diff --git a/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp b/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp index 7b2af45ad3ce66..c095b13e8c30c5 100644 --- a/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp @@ -141,67 +141,49 @@ Error EHFrameEdgeFixer::processBlock(ParseContext &PC, Block &B) { 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 RecordRemaining = readCFIRecordLength(B, BlockReader); - if (!RecordRemaining) - return RecordRemaining.takeError(); - - if (BlockReader.bytesRemaining() < *RecordRemaining) - return make_error( - "Incomplete CFI record at " + - formatv("{0:x16}", B.getAddress() + RecordStartOffset)); + // Get the record length. + Expected 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("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; @@ -267,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; @@ -278,7 +260,7 @@ Error EHFrameEdgeFixer::processCIE(ParseContext &PC, Block &B, if (CIEInfo.AddressEncoding == dwarf::DW_EH_PE_omit) return make_error( "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; @@ -301,30 +283,27 @@ 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( "CIE pointer field already has edge at " + @@ -334,8 +313,7 @@ Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B, RecordAddress + orc::ExecutorAddrDiff(CIEDeltaFieldOffset) - orc::ExecutorAddrDiff(CIEDelta); LLVM_DEBUG({ - dbgs() << " Adding edge at " - << (RecordAddress + CIEDeltaFieldOffset) + dbgs() << " Adding edge at " << (RecordAddress + CIEDeltaFieldOffset) << " to CIE at: " << CIEAddress << "\n"; }); if (auto CIEInfoOrErr = PC.findCIEInfo(CIEAddress)) @@ -343,13 +321,12 @@ Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B, else return CIEInfoOrErr.takeError(); assert(CIEInfo->CIESymbol && "CIEInfo has no CIE symbol set"); - B.addEdge(NegDelta32, RecordOffset + CIEDeltaFieldOffset, - *CIEInfo->CIESymbol, 0); + 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( @@ -360,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() @@ -394,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(); @@ -519,7 +496,7 @@ Expected 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()) @@ -581,7 +558,7 @@ Expected 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()) diff --git a/llvm/lib/ExecutionEngine/JITLink/EHFrameSupportImpl.h b/llvm/lib/ExecutionEngine/JITLink/EHFrameSupportImpl.h index 55cf7fc63ee795..cc3c24cc85ead0 100644 --- a/llvm/lib/ExecutionEngine/JITLink/EHFrameSupportImpl.h +++ b/llvm/lib/ExecutionEngine/JITLink/EHFrameSupportImpl.h @@ -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 diff --git a/llvm/test/ExecutionEngine/JITLink/AArch64/ELF_ehframe.s b/llvm/test/ExecutionEngine/JITLink/AArch64/ELF_ehframe.s index 770cd60a1d70d7..716c4e5abd3fb9 100644 --- a/llvm/test/ExecutionEngine/JITLink/AArch64/ELF_ehframe.s +++ b/llvm/test/ExecutionEngine/JITLink/AArch64/ELF_ehframe.s @@ -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 diff --git a/llvm/test/ExecutionEngine/JITLink/AArch64/MachO_ehframe.s b/llvm/test/ExecutionEngine/JITLink/AArch64/MachO_ehframe.s index 5f821276288617..4bc006a9a7a2a9 100644 --- a/llvm/test/ExecutionEngine/JITLink/AArch64/MachO_ehframe.s +++ b/llvm/test/ExecutionEngine/JITLink/AArch64/MachO_ehframe.s @@ -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 diff --git a/llvm/test/ExecutionEngine/JITLink/LoongArch/ELF_loongarch64_ehframe.s b/llvm/test/ExecutionEngine/JITLink/LoongArch/ELF_loongarch64_ehframe.s index 4a1a1649508eb6..3eb3cba11da262 100644 --- a/llvm/test/ExecutionEngine/JITLink/LoongArch/ELF_loongarch64_ehframe.s +++ b/llvm/test/ExecutionEngine/JITLink/LoongArch/ELF_loongarch64_ehframe.s @@ -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 diff --git a/llvm/test/ExecutionEngine/JITLink/ppc64/ELF_ppc64_ehframe.s b/llvm/test/ExecutionEngine/JITLink/ppc64/ELF_ppc64_ehframe.s index 3b84768ce78665..13e9006b7a8a81 100644 --- a/llvm/test/ExecutionEngine/JITLink/ppc64/ELF_ppc64_ehframe.s +++ b/llvm/test/ExecutionEngine/JITLink/ppc64/ELF_ppc64_ehframe.s @@ -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