From: Lang Hames Date: Tue, 26 Jan 2021 00:24:55 +0000 (+1100) Subject: [JITLink] Re-apply 6884fbc2c4f (ELF eh support) with fix for broken test case. X-Git-Tag: llvmorg-13-init~137 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=cda4d3d37f1490e2586ba9147f94e87bc860fa78;p=platform%2Fupstream%2Fllvm.git [JITLink] Re-apply 6884fbc2c4f (ELF eh support) with fix for broken test case. --- diff --git a/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp b/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp index 8b730bc..3602601 100644 --- a/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/EHFrameSupport.cpp @@ -119,9 +119,10 @@ Error EHFrameSplitter::processBlock(LinkGraph &G, Block &B, } EHFrameEdgeFixer::EHFrameEdgeFixer(StringRef EHFrameSectionName, - Edge::Kind Delta64, Edge::Kind NegDelta32) - : EHFrameSectionName(EHFrameSectionName), Delta64(Delta64), - NegDelta32(NegDelta32) {} + unsigned PointerSize, Edge::Kind Delta64, + Edge::Kind Delta32, Edge::Kind NegDelta32) + : EHFrameSectionName(EHFrameSectionName), PointerSize(PointerSize), + Delta64(Delta64), Delta32(Delta32), NegDelta32(NegDelta32) {} Error EHFrameEdgeFixer::operator()(LinkGraph &G) { auto *EHFrame = G.findSectionByName(EHFrameSectionName); @@ -134,6 +135,11 @@ Error EHFrameEdgeFixer::operator()(LinkGraph &G) { return Error::success(); } + // Check that we support the graph's pointer size. + if (G.getPointerSize() != 4 && G.getPointerSize() != 8) + return make_error( + "EHFrameEdgeFixer only supports 32 and 64 bit targets"); + LLVM_DEBUG({ dbgs() << "EHFrameEdgeFixer: Processing " << EHFrameSectionName << "...\n"; }); @@ -258,7 +264,6 @@ Error EHFrameEdgeFixer::processBlock(ParseContext &PC, Block &B) { Error EHFrameEdgeFixer::processCIE(ParseContext &PC, Block &B, size_t RecordOffset, size_t RecordLength, size_t CIEDeltaFieldOffset) { - using namespace dwarf; LLVM_DEBUG(dbgs() << " Record is CIE\n"); @@ -329,11 +334,12 @@ Error EHFrameEdgeFixer::processCIE(ParseContext &PC, Block &B, uint8_t LSDAPointerEncoding; if (auto Err = RecordReader.readInteger(LSDAPointerEncoding)) return Err; - if (LSDAPointerEncoding != (DW_EH_PE_pcrel | DW_EH_PE_absptr)) + if (!isSupportedPointerEncoding(LSDAPointerEncoding)) return make_error( "Unsupported LSDA pointer encoding " + formatv("{0:x2}", LSDAPointerEncoding) + " in CIE at " + formatv("{0:x16}", CIESymbol.getAddress())); + CIEInfo.LSDAPointerEncoding = LSDAPointerEncoding; break; } case 'P': { @@ -341,7 +347,8 @@ Error EHFrameEdgeFixer::processCIE(ParseContext &PC, Block &B, if (auto Err = RecordReader.readInteger(PersonalityPointerEncoding)) return Err; if (PersonalityPointerEncoding != - (DW_EH_PE_indirect | DW_EH_PE_pcrel | DW_EH_PE_sdata4)) + (dwarf::DW_EH_PE_indirect | dwarf::DW_EH_PE_pcrel | + dwarf::DW_EH_PE_sdata4)) return make_error( "Unspported personality pointer " "encoding " + @@ -356,12 +363,12 @@ Error EHFrameEdgeFixer::processCIE(ParseContext &PC, Block &B, uint8_t FDEPointerEncoding; if (auto Err = RecordReader.readInteger(FDEPointerEncoding)) return Err; - if (FDEPointerEncoding != (DW_EH_PE_pcrel | DW_EH_PE_absptr)) + if (!isSupportedPointerEncoding(FDEPointerEncoding)) return make_error( - "Unsupported FDE address pointer " - "encoding " + + "Unsupported FDE pointer encoding " + formatv("{0:x2}", FDEPointerEncoding) + " in CIE at " + formatv("{0:x16}", CIESymbol.getAddress())); + CIEInfo.FDEPointerEncoding = FDEPointerEncoding; break; } default: @@ -445,11 +452,13 @@ Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B, JITTargetAddress PCBeginFieldOffset = RecordReader.getOffset(); auto PCEdgeItr = BlockEdges.find(RecordOffset + PCBeginFieldOffset); if (PCEdgeItr == BlockEdges.end()) { - auto PCBeginDelta = readAbsolutePointer(PC.G, RecordReader); - if (!PCBeginDelta) - return PCBeginDelta.takeError(); - JITTargetAddress PCBegin = - RecordAddress + PCBeginFieldOffset + *PCBeginDelta; + auto PCBeginPtrInfo = + readEncodedPointer(CIEInfo->FDEPointerEncoding, + RecordAddress + PCBeginFieldOffset, RecordReader); + if (!PCBeginPtrInfo) + return PCBeginPtrInfo.takeError(); + JITTargetAddress PCBegin = PCBeginPtrInfo->first; + Edge::Kind PCBeginEdgeKind = PCBeginPtrInfo->second; LLVM_DEBUG({ dbgs() << " Adding edge at " << formatv("{0:x16}", RecordAddress + PCBeginFieldOffset) @@ -458,7 +467,8 @@ Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B, auto PCBeginSym = getOrCreateSymbol(PC, PCBegin); if (!PCBeginSym) return PCBeginSym.takeError(); - B.addEdge(Delta64, RecordOffset + PCBeginFieldOffset, *PCBeginSym, 0); + B.addEdge(PCBeginEdgeKind, RecordOffset + PCBeginFieldOffset, *PCBeginSym, + 0); PCBeginBlock = &PCBeginSym->getBlock(); } else { auto &EI = PCEdgeItr->second; @@ -479,38 +489,42 @@ Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B, " points at external block"); } PCBeginBlock = &EI.Target->getBlock(); - if (auto Err = RecordReader.skip(PC.G.getPointerSize())) + if (auto Err = RecordReader.skip( + getPointerEncodingDataSize(CIEInfo->FDEPointerEncoding))) return Err; } // Add a keep-alive edge from the FDE target to the FDE to ensure that the // FDE is kept alive if its target is. assert(PCBeginBlock && "PC-begin block not recorded"); + LLVM_DEBUG({ + dbgs() << " Adding keep-alive edge from target at " + << formatv("{0:x16}", PCBeginBlock->getAddress()) << " to FDE at " + << formatv("{0:x16}", RecordAddress) << "\n"; + }); PCBeginBlock->addEdge(Edge::KeepAlive, 0, FDESymbol, 0); } // Skip over the PC range size field. - if (auto Err = RecordReader.skip(PC.G.getPointerSize())) + if (auto Err = RecordReader.skip( + getPointerEncodingDataSize(CIEInfo->FDEPointerEncoding))) return Err; if (CIEInfo->FDEsHaveLSDAField) { uint64_t AugmentationDataSize; if (auto Err = RecordReader.readULEB128(AugmentationDataSize)) return Err; - if (AugmentationDataSize != PC.G.getPointerSize()) - return make_error( - "Unexpected FDE augmentation data size (expected " + - Twine(PC.G.getPointerSize()) + ", got " + - Twine(AugmentationDataSize) + ") for FDE at " + - formatv("{0:x16}", RecordAddress)); JITTargetAddress LSDAFieldOffset = RecordReader.getOffset(); auto LSDAEdgeItr = BlockEdges.find(RecordOffset + LSDAFieldOffset); if (LSDAEdgeItr == BlockEdges.end()) { - auto LSDADelta = readAbsolutePointer(PC.G, RecordReader); - if (!LSDADelta) - return LSDADelta.takeError(); - JITTargetAddress LSDA = RecordAddress + LSDAFieldOffset + *LSDADelta; + auto LSDAPointerInfo = + readEncodedPointer(CIEInfo->LSDAPointerEncoding, + RecordAddress + LSDAFieldOffset, RecordReader); + if (!LSDAPointerInfo) + return LSDAPointerInfo.takeError(); + JITTargetAddress LSDA = LSDAPointerInfo->first; + Edge::Kind LSDAEdgeKind = LSDAPointerInfo->second; auto LSDASym = getOrCreateSymbol(PC, LSDA); if (!LSDASym) return LSDASym.takeError(); @@ -519,7 +533,7 @@ Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B, << formatv("{0:x16}", RecordAddress + LSDAFieldOffset) << " to LSDA at " << formatv("{0:x16}", LSDA) << "\n"; }); - B.addEdge(Delta64, RecordOffset + LSDAFieldOffset, *LSDASym, 0); + B.addEdge(LSDAEdgeKind, RecordOffset + LSDAFieldOffset, *LSDASym, 0); } else { LLVM_DEBUG({ auto &EI = LSDAEdgeItr->second; @@ -530,7 +544,7 @@ Error EHFrameEdgeFixer::processFDE(ParseContext &PC, Block &B, dbgs() << " + " << formatv("{0:x16}", EI.Addend); dbgs() << "\n"; }); - if (auto Err = RecordReader.skip(PC.G.getPointerSize())) + if (auto Err = RecordReader.skip(AugmentationDataSize)) return Err; } } else { @@ -581,23 +595,110 @@ EHFrameEdgeFixer::parseAugmentationString(BinaryStreamReader &RecordReader) { return std::move(AugInfo); } -Expected -EHFrameEdgeFixer::readAbsolutePointer(LinkGraph &G, - BinaryStreamReader &RecordReader) { +bool EHFrameEdgeFixer::isSupportedPointerEncoding(uint8_t PointerEncoding) { + using namespace dwarf; + + // We only support PC-rel for now. + if ((PointerEncoding & 0x70) != DW_EH_PE_pcrel) + return false; + + // readEncodedPointer does not handle indirect. + if (PointerEncoding & DW_EH_PE_indirect) + return false; + + // Supported datatypes. + switch (PointerEncoding & 0xf) { + case DW_EH_PE_absptr: + case DW_EH_PE_udata4: + case DW_EH_PE_udata8: + case DW_EH_PE_sdata4: + case DW_EH_PE_sdata8: + return true; + } + + return false; +} + +unsigned EHFrameEdgeFixer::getPointerEncodingDataSize(uint8_t PointerEncoding) { + using namespace dwarf; + + assert(isSupportedPointerEncoding(PointerEncoding) && + "Unsupported pointer encoding"); + switch (PointerEncoding & 0xf) { + case DW_EH_PE_absptr: + return PointerSize; + case DW_EH_PE_udata4: + case DW_EH_PE_sdata4: + return 4; + case DW_EH_PE_udata8: + case DW_EH_PE_sdata8: + return 8; + default: + llvm_unreachable("Unsupported encoding"); + } +} + +Expected> +EHFrameEdgeFixer::readEncodedPointer(uint8_t PointerEncoding, + JITTargetAddress PointerFieldAddress, + BinaryStreamReader &RecordReader) { static_assert(sizeof(JITTargetAddress) == sizeof(uint64_t), "Result must be able to hold a uint64_t"); + assert(isSupportedPointerEncoding(PointerEncoding) && + "Unsupported pointer encoding"); + + using namespace dwarf; + + // Isolate data type, remap absptr to udata4 or udata8. This relies on us + // having verified that the graph uses 32-bit or 64-bit pointers only at the + // start of this pass. + uint8_t EffectiveType = PointerEncoding & 0xf; + if (EffectiveType == DW_EH_PE_absptr) + EffectiveType = (PointerSize == 8) ? DW_EH_PE_udata8 : DW_EH_PE_udata4; + JITTargetAddress Addr; - if (G.getPointerSize() == 8) { - if (auto Err = RecordReader.readInteger(Addr)) + Edge::Kind PointerEdgeKind; + switch (EffectiveType) { + case DW_EH_PE_udata4: { + uint32_t Val; + if (auto Err = RecordReader.readInteger(Val)) return std::move(Err); - } else if (G.getPointerSize() == 4) { - uint32_t Addr32; - if (auto Err = RecordReader.readInteger(Addr32)) + Addr = PointerFieldAddress + Val; + PointerEdgeKind = Delta32; + break; + } + case DW_EH_PE_udata8: { + uint64_t Val; + if (auto Err = RecordReader.readInteger(Val)) return std::move(Err); - Addr = Addr32; - } else - llvm_unreachable("Pointer size is not 32-bit or 64-bit"); - return Addr; + Addr = PointerFieldAddress + Val; + PointerEdgeKind = Delta64; + break; + } + case DW_EH_PE_sdata4: { + int32_t Val; + if (auto Err = RecordReader.readInteger(Val)) + return std::move(Err); + Addr = PointerFieldAddress + Val; + PointerEdgeKind = Delta32; + break; + } + case DW_EH_PE_sdata8: { + int64_t Val; + if (auto Err = RecordReader.readInteger(Val)) + return std::move(Err); + Addr = PointerFieldAddress + Val; + PointerEdgeKind = Delta64; + break; + } + } + + if (PointerEdgeKind == Edge::Invalid) + return make_error( + "Unspported edge kind for encoded pointer at " + + formatv("{0:x}", PointerFieldAddress)); + + return std::make_pair(Addr, Delta64); } Expected EHFrameEdgeFixer::getOrCreateSymbol(ParseContext &PC, diff --git a/llvm/lib/ExecutionEngine/JITLink/EHFrameSupportImpl.h b/llvm/lib/ExecutionEngine/JITLink/EHFrameSupportImpl.h index 83f27a2..5e68e72 100644 --- a/llvm/lib/ExecutionEngine/JITLink/EHFrameSupportImpl.h +++ b/llvm/lib/ExecutionEngine/JITLink/EHFrameSupportImpl.h @@ -40,7 +40,8 @@ private: /// edges. class EHFrameEdgeFixer { public: - EHFrameEdgeFixer(StringRef EHFrameSectionName, Edge::Kind Delta64, + EHFrameEdgeFixer(StringRef EHFrameSectionName, unsigned PointerSize, + Edge::Kind Delta64, Edge::Kind Delta32, Edge::Kind NegDelta32); Error operator()(LinkGraph &G); @@ -57,6 +58,8 @@ private: CIEInformation(Symbol &CIESymbol) : CIESymbol(&CIESymbol) {} Symbol *CIESymbol = nullptr; bool FDEsHaveLSDAField = false; + uint8_t FDEPointerEncoding = 0; + uint8_t LSDAPointerEncoding = 0; }; struct EdgeTarget { @@ -96,12 +99,20 @@ private: Expected parseAugmentationString(BinaryStreamReader &RecordReader); - Expected - readAbsolutePointer(LinkGraph &G, BinaryStreamReader &RecordReader); + + static bool isSupportedPointerEncoding(uint8_t PointerEncoding); + unsigned getPointerEncodingDataSize(uint8_t PointerEncoding); + Expected> + readEncodedPointer(uint8_t PointerEncoding, + JITTargetAddress PointerFieldAddress, + BinaryStreamReader &RecordReader); + Expected getOrCreateSymbol(ParseContext &PC, JITTargetAddress Addr); StringRef EHFrameSectionName; + unsigned PointerSize; Edge::Kind Delta64; + Edge::Kind Delta32; Edge::Kind NegDelta32; }; diff --git a/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp b/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp index 0ca2130..2a92f28 100644 --- a/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/ELF_x86_64.cpp @@ -11,12 +11,14 @@ //===----------------------------------------------------------------------===// #include "llvm/ExecutionEngine/JITLink/ELF_x86_64.h" -#include "BasicGOTAndStubsBuilder.h" -#include "JITLinkGeneric.h" #include "llvm/ExecutionEngine/JITLink/JITLink.h" #include "llvm/Object/ELFObjectFile.h" #include "llvm/Support/Endian.h" +#include "BasicGOTAndStubsBuilder.h" +#include "EHFrameSupportImpl.h" +#include "JITLinkGeneric.h" + #define DEBUG_TYPE "jitlink" using namespace llvm; @@ -238,6 +240,8 @@ private: switch (Type) { case ELF::R_X86_64_PC32: return ELF_x86_64_Edges::ELFX86RelocationKind::PCRel32; + case ELF::R_X86_64_PC64: + return ELF_x86_64_Edges::ELFX86RelocationKind::Delta64; case ELF::R_X86_64_64: return ELF_x86_64_Edges::ELFX86RelocationKind::Pointer64; case ELF::R_X86_64_GOTPCREL: @@ -404,9 +408,6 @@ private: LLVM_DEBUG({ dbgs() << "Adding relocations from section " << *RelSectName << "\n"; }); - // Deal with .eh_frame later - if (*RelSectName == StringRef(".rela.eh_frame")) - continue; auto UpdateSection = Obj.getSection(SecRef.sh_info); if (!UpdateSection) @@ -734,6 +735,11 @@ private: *(ulittle64_t *)FixupPtr = Value; break; } + case ELFX86RelocationKind::Delta64: { + int64_t Value = E.getTarget().getAddress() + E.getAddend() - FixupAddress; + *(little64_t *)FixupPtr = Value; + break; + } } return Error::success(); } @@ -760,21 +766,28 @@ void link_ELF_x86_64(std::unique_ptr G, std::unique_ptr Ctx) { PassConfiguration Config; - // Construct a JITLinker and run the link function. - // Add a mark-live pass. - if (auto MarkLive = Ctx->getMarkLivePass(G->getTargetTriple())) - Config.PrePrunePasses.push_back(std::move(MarkLive)); - else - Config.PrePrunePasses.push_back(markAllSymbolsLive); + if (Ctx->shouldAddDefaultTargetPasses(G->getTargetTriple())) { - // Add an in-place GOT/Stubs pass. - Config.PostPrunePasses.push_back([](LinkGraph &G) -> Error { - ELF_x86_64_GOTAndStubsBuilder(G).run(); - return Error::success(); - }); + Config.PrePrunePasses.push_back(EHFrameSplitter(".eh_frame")); + Config.PrePrunePasses.push_back(EHFrameEdgeFixer( + ".eh_frame", G->getPointerSize(), Delta64, Delta32, NegDelta32)); - // Add GOT/Stubs optimizer pass. - Config.PreFixupPasses.push_back(optimizeELF_x86_64_GOTAndStubs); + // Construct a JITLinker and run the link function. + // Add a mark-live pass. + if (auto MarkLive = Ctx->getMarkLivePass(G->getTargetTriple())) + Config.PrePrunePasses.push_back(std::move(MarkLive)); + else + Config.PrePrunePasses.push_back(markAllSymbolsLive); + + // Add an in-place GOT/Stubs pass. + Config.PostPrunePasses.push_back([](LinkGraph &G) -> Error { + ELF_x86_64_GOTAndStubsBuilder(G).run(); + return Error::success(); + }); + + // Add GOT/Stubs optimizer pass. + Config.PreFixupPasses.push_back(optimizeELF_x86_64_GOTAndStubs); + } if (auto Err = Ctx->modifyPassConfig(G->getTargetTriple(), Config)) return Ctx->notifyFailed(std::move(Err)); diff --git a/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.h b/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.h index 3555d66..26e6859 100644 --- a/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.h +++ b/llvm/lib/ExecutionEngine/JITLink/MachOLinkGraphBuilder.h @@ -16,10 +16,10 @@ #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/StringMap.h" #include "llvm/ExecutionEngine/JITLink/JITLink.h" +#include "llvm/Object/MachO.h" #include "EHFrameSupportImpl.h" #include "JITLinkGeneric.h" -#include "llvm/Object/MachO.h" #include diff --git a/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp b/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp index 24559cc..bde4a19 100644 --- a/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp +++ b/llvm/lib/ExecutionEngine/JITLink/MachO_x86_64.cpp @@ -669,8 +669,8 @@ void link_MachO_x86_64(std::unique_ptr G, if (Ctx->shouldAddDefaultTargetPasses(G->getTargetTriple())) { // Add eh-frame passses. Config.PrePrunePasses.push_back(EHFrameSplitter("__eh_frame")); - Config.PrePrunePasses.push_back( - EHFrameEdgeFixer("__eh_frame", Delta64, NegDelta32)); + Config.PrePrunePasses.push_back(EHFrameEdgeFixer( + "__eh_frame", G->getPointerSize(), Delta64, Delta32, NegDelta32)); // Add a mark-live pass. if (auto MarkLive = Ctx->getMarkLivePass(G->getTargetTriple())) diff --git a/llvm/test/ExecutionEngine/JITLink/X86/ELF_ehframe_basic.s b/llvm/test/ExecutionEngine/JITLink/X86/ELF_ehframe_basic.s new file mode 100644 index 0000000..0f09ec8 --- /dev/null +++ b/llvm/test/ExecutionEngine/JITLink/X86/ELF_ehframe_basic.s @@ -0,0 +1,115 @@ +# REQUIRES: asserts +# RUN: llvm-mc -triple=x86_64-unknown-linux -position-independent \ +# RUN: -filetype=obj -o %t %s +# RUN: llvm-jitlink -debug-only=jitlink -define-abs bar=0x01 \ +# RUN: -define-abs _ZTIi=0x02 -noexec %t 2>&1 | FileCheck %s +# +# Check that a basic .eh-frame section is recognized and parsed. We +# Expect to see two FDEs with corresponding keep-alive edges. +# +# CHECK: Adding keep-alive edge from target at {{.*}} to FDE at +# CHECK: Adding keep-alive edge from target at {{.*}} to FDE at + + .text + .file "exceptions.cpp" + .globl foo + .p2align 4, 0x90 + .type foo,@function +foo: + .cfi_startproc + + pushq %rax + .cfi_def_cfa_offset 16 + movl $4, %edi + callq __cxa_allocate_exception@PLT + movl $1, (%rax) + movq _ZTIi@GOTPCREL(%rip), %rsi + movq %rax, %rdi + xorl %edx, %edx + callq __cxa_throw@PLT +.Lfunc_end0: + .size foo, .Lfunc_end0-foo + .cfi_endproc + + .globl main + .p2align 4, 0x90 + .type main,@function +main: +.Lfunc_begin0: + .cfi_startproc + .cfi_personality 155, DW.ref.__gxx_personality_v0 + .cfi_lsda 27, .Lexception0 + + pushq %rbx + .cfi_def_cfa_offset 16 + .cfi_offset %rbx, -16 + xorl %ebx, %ebx +.Ltmp0: + callq bar@PLT +.Ltmp1: + + movl %ebx, %eax + popq %rbx + .cfi_def_cfa_offset 8 + retq +.LBB1_1: + .cfi_def_cfa_offset 16 +.Ltmp2: + movq %rax, %rdi + callq __cxa_begin_catch@PLT + callq __cxa_end_catch@PLT + movl $1, %ebx + movl %ebx, %eax + popq %rbx + .cfi_def_cfa_offset 8 + retq +.Lfunc_end1: + .size main, .Lfunc_end1-main + .cfi_endproc + .section .gcc_except_table,"a",@progbits + .p2align 2 +GCC_except_table1: +.Lexception0: + .byte 255 + .byte 156 + .uleb128 .Lttbase0-.Lttbaseref0 +.Lttbaseref0: + .byte 1 + .uleb128 .Lcst_end0-.Lcst_begin0 +.Lcst_begin0: + .uleb128 .Ltmp0-.Lfunc_begin0 + .uleb128 .Ltmp1-.Ltmp0 + .uleb128 .Ltmp2-.Lfunc_begin0 + .byte 1 + .uleb128 .Ltmp1-.Lfunc_begin0 + .uleb128 .Lfunc_end1-.Ltmp1 + .byte 0 + .byte 0 +.Lcst_end0: + .byte 1 + + .byte 0 + .p2align 2 + +.Ltmp3: + .quad .L_ZTIi.DW.stub-.Ltmp3 +.Lttbase0: + .p2align 2 + + .data + .p2align 3 +.L_ZTIi.DW.stub: + .quad _ZTIi + .hidden DW.ref.__gxx_personality_v0 + .weak DW.ref.__gxx_personality_v0 + .section .data.DW.ref.__gxx_personality_v0,"aGw",@progbits,DW.ref.__gxx_personality_v0,comdat + .p2align 3 + .type DW.ref.__gxx_personality_v0,@object + .size DW.ref.__gxx_personality_v0, 8 +DW.ref.__gxx_personality_v0: + .quad __gxx_personality_v0 + .ident "clang version 12.0.0 (git@github.com:llvm/llvm-project.git afd483e57d166418e94a65bd9716e7dc4c114eed)" + .section ".note.GNU-stack","",@progbits + .addrsig + .addrsig_sym __gxx_personality_v0 + .addrsig_sym _ZTIi