1b2518971SLang Hames //===------- DebuggerSupportPlugin.cpp - Utils for debugger support -------===// 2b2518971SLang Hames // 3b2518971SLang Hames // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4b2518971SLang Hames // See https://llvm.org/LICENSE.txt for license information. 5b2518971SLang Hames // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6b2518971SLang Hames // 7b2518971SLang Hames //===----------------------------------------------------------------------===// 8b2518971SLang Hames // 9b2518971SLang Hames // 10b2518971SLang Hames //===----------------------------------------------------------------------===// 11b2518971SLang Hames 12b2518971SLang Hames #include "llvm/ExecutionEngine/Orc/Debugging/DebuggerSupportPlugin.h" 13b2518971SLang Hames #include "llvm/ExecutionEngine/Orc/MachOBuilder.h" 14b2518971SLang Hames 15b2518971SLang Hames #include "llvm/ADT/SmallSet.h" 16b2518971SLang Hames #include "llvm/ADT/SmallVector.h" 17b2518971SLang Hames #include "llvm/BinaryFormat/MachO.h" 18b2518971SLang Hames #include "llvm/DebugInfo/DWARF/DWARFContext.h" 19b2518971SLang Hames #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h" 20b2518971SLang Hames 21b2518971SLang Hames #include <chrono> 22b2518971SLang Hames 23b2518971SLang Hames #define DEBUG_TYPE "orc" 24b2518971SLang Hames 25b2518971SLang Hames using namespace llvm; 26b2518971SLang Hames using namespace llvm::jitlink; 27b2518971SLang Hames using namespace llvm::orc; 28b2518971SLang Hames 29b2518971SLang Hames static const char *SynthDebugSectionName = "__jitlink_synth_debug_object"; 30b2518971SLang Hames 31b2518971SLang Hames namespace { 32b2518971SLang Hames 33b2518971SLang Hames class MachODebugObjectSynthesizerBase 34b2518971SLang Hames : public GDBJITDebugInfoRegistrationPlugin::DebugSectionSynthesizer { 35b2518971SLang Hames public: 36b2518971SLang Hames static bool isDebugSection(Section &Sec) { 37586ecdf2SKazu Hirata return Sec.getName().starts_with("__DWARF,"); 38b2518971SLang Hames } 39b2518971SLang Hames 40b2518971SLang Hames MachODebugObjectSynthesizerBase(LinkGraph &G, ExecutorAddr RegisterActionAddr) 41b2518971SLang Hames : G(G), RegisterActionAddr(RegisterActionAddr) {} 42b2518971SLang Hames virtual ~MachODebugObjectSynthesizerBase() = default; 43b2518971SLang Hames 44b2518971SLang Hames Error preserveDebugSections() { 45b2518971SLang Hames if (G.findSectionByName(SynthDebugSectionName)) { 46b2518971SLang Hames LLVM_DEBUG({ 47b2518971SLang Hames dbgs() << "MachODebugObjectSynthesizer skipping graph " << G.getName() 48b2518971SLang Hames << " which contains an unexpected existing " 49b2518971SLang Hames << SynthDebugSectionName << " section.\n"; 50b2518971SLang Hames }); 51b2518971SLang Hames return Error::success(); 52b2518971SLang Hames } 53b2518971SLang Hames 54b2518971SLang Hames LLVM_DEBUG({ 55b2518971SLang Hames dbgs() << "MachODebugObjectSynthesizer visiting graph " << G.getName() 56b2518971SLang Hames << "\n"; 57b2518971SLang Hames }); 58b2518971SLang Hames for (auto &Sec : G.sections()) { 59b2518971SLang Hames if (!isDebugSection(Sec)) 60b2518971SLang Hames continue; 61b2518971SLang Hames // Preserve blocks in this debug section by marking one existing symbol 62b2518971SLang Hames // live for each block, and introducing a new live, anonymous symbol for 63b2518971SLang Hames // each currently unreferenced block. 64b2518971SLang Hames LLVM_DEBUG({ 65b2518971SLang Hames dbgs() << " Preserving debug section " << Sec.getName() << "\n"; 66b2518971SLang Hames }); 67b2518971SLang Hames SmallSet<Block *, 8> PreservedBlocks; 68b2518971SLang Hames for (auto *Sym : Sec.symbols()) { 69b2518971SLang Hames bool NewPreservedBlock = 70b2518971SLang Hames PreservedBlocks.insert(&Sym->getBlock()).second; 71b2518971SLang Hames if (NewPreservedBlock) 72b2518971SLang Hames Sym->setLive(true); 73b2518971SLang Hames } 74b2518971SLang Hames for (auto *B : Sec.blocks()) 75b2518971SLang Hames if (!PreservedBlocks.count(B)) 76b2518971SLang Hames G.addAnonymousSymbol(*B, 0, 0, false, true); 77b2518971SLang Hames } 78b2518971SLang Hames 79b2518971SLang Hames return Error::success(); 80b2518971SLang Hames } 81b2518971SLang Hames 82b2518971SLang Hames protected: 83b2518971SLang Hames LinkGraph &G; 84b2518971SLang Hames ExecutorAddr RegisterActionAddr; 85b2518971SLang Hames }; 86b2518971SLang Hames 87b2518971SLang Hames template <typename MachOTraits> 88b2518971SLang Hames class MachODebugObjectSynthesizer : public MachODebugObjectSynthesizerBase { 89b2518971SLang Hames public: 90b2518971SLang Hames MachODebugObjectSynthesizer(ExecutionSession &ES, LinkGraph &G, 91b2518971SLang Hames ExecutorAddr RegisterActionAddr) 92b2518971SLang Hames : MachODebugObjectSynthesizerBase(G, RegisterActionAddr), 93b2518971SLang Hames Builder(ES.getPageSize()) {} 94b2518971SLang Hames 95b2518971SLang Hames using MachODebugObjectSynthesizerBase::MachODebugObjectSynthesizerBase; 96b2518971SLang Hames 97b2518971SLang Hames Error startSynthesis() override { 98b2518971SLang Hames LLVM_DEBUG({ 99b2518971SLang Hames dbgs() << "Creating " << SynthDebugSectionName << " for " << G.getName() 100b2518971SLang Hames << "\n"; 101b2518971SLang Hames }); 102b2518971SLang Hames 103b2518971SLang Hames for (auto &Sec : G.sections()) { 104b2518971SLang Hames if (Sec.blocks().empty()) 105b2518971SLang Hames continue; 106b2518971SLang Hames 107b2518971SLang Hames // Skip sections whose name's don't fit the MachO standard. 108b2518971SLang Hames if (Sec.getName().empty() || Sec.getName().size() > 33 || 109b2518971SLang Hames Sec.getName().find(',') > 16) 110b2518971SLang Hames continue; 111b2518971SLang Hames 112b2518971SLang Hames if (isDebugSection(Sec)) 113b2518971SLang Hames DebugSections.push_back({&Sec, nullptr}); 114b2518971SLang Hames else if (Sec.getMemLifetime() != MemLifetime::NoAlloc) 115b2518971SLang Hames NonDebugSections.push_back({&Sec, nullptr}); 116b2518971SLang Hames } 117b2518971SLang Hames 118b2518971SLang Hames // Bail out early if no debug sections. 119b2518971SLang Hames if (DebugSections.empty()) 120b2518971SLang Hames return Error::success(); 121b2518971SLang Hames 122b2518971SLang Hames // Write MachO header and debug section load commands. 123b2518971SLang Hames Builder.Header.filetype = MachO::MH_OBJECT; 124*63013946SLang Hames if (auto CPUType = MachO::getCPUType(G.getTargetTriple())) 125*63013946SLang Hames Builder.Header.cputype = *CPUType; 126*63013946SLang Hames else 127*63013946SLang Hames return CPUType.takeError(); 128*63013946SLang Hames if (auto CPUSubType = MachO::getCPUSubType(G.getTargetTriple())) 129*63013946SLang Hames Builder.Header.cpusubtype = *CPUSubType; 130*63013946SLang Hames else 131*63013946SLang Hames return CPUSubType.takeError(); 132b2518971SLang Hames 133b2518971SLang Hames Seg = &Builder.addSegment(""); 134b2518971SLang Hames 135b2518971SLang Hames StringMap<std::unique_ptr<MemoryBuffer>> DebugSectionMap; 136b2518971SLang Hames StringRef DebugLineSectionData; 137b2518971SLang Hames for (auto &DSec : DebugSections) { 138b2518971SLang Hames auto [SegName, SecName] = DSec.GraphSec->getName().split(','); 139b2518971SLang Hames DSec.BuilderSec = &Seg->addSection(SecName, SegName); 140b2518971SLang Hames 141b2518971SLang Hames SectionRange SR(*DSec.GraphSec); 142b2518971SLang Hames DSec.BuilderSec->Content.Size = SR.getSize(); 143b2518971SLang Hames if (!SR.empty()) { 144b2518971SLang Hames DSec.BuilderSec->align = Log2_64(SR.getFirstBlock()->getAlignment()); 145b2518971SLang Hames StringRef SectionData(SR.getFirstBlock()->getContent().data(), 146b2518971SLang Hames SR.getFirstBlock()->getSize()); 147b6c06d1aSLang Hames DebugSectionMap[SecName.drop_front(2)] = // drop "__" prefix. 148b2518971SLang Hames MemoryBuffer::getMemBuffer(SectionData, G.getName(), false); 149b2518971SLang Hames if (SecName == "__debug_line") 150b2518971SLang Hames DebugLineSectionData = SectionData; 151b2518971SLang Hames } 152b2518971SLang Hames } 153b2518971SLang Hames 1544b13c86dSMogball std::optional<StringRef> FileName; 155b2518971SLang Hames if (!DebugLineSectionData.empty()) { 156b05dbc4dSKazu Hirata assert((G.getEndianness() == llvm::endianness::big || 157b05dbc4dSKazu Hirata G.getEndianness() == llvm::endianness::little) && 1588de2ecc2SKazu Hirata "G.getEndianness() must be either big or little"); 159b05dbc4dSKazu Hirata auto DWARFCtx = 160b05dbc4dSKazu Hirata DWARFContext::create(DebugSectionMap, G.getPointerSize(), 161b05dbc4dSKazu Hirata G.getEndianness() == llvm::endianness::little); 162b2518971SLang Hames DWARFDataExtractor DebugLineData( 163b05dbc4dSKazu Hirata DebugLineSectionData, G.getEndianness() == llvm::endianness::little, 164b05dbc4dSKazu Hirata G.getPointerSize()); 165b2518971SLang Hames uint64_t Offset = 0; 166b6c06d1aSLang Hames DWARFDebugLine::Prologue P; 167b2518971SLang Hames 168b2518971SLang Hames // Try to parse line data. Consume error on failure. 169b6c06d1aSLang Hames if (auto Err = P.parse(DebugLineData, &Offset, consumeError, *DWARFCtx)) { 1704b13c86dSMogball handleAllErrors(std::move(Err), [&](ErrorInfoBase &EIB) { 171b2518971SLang Hames LLVM_DEBUG({ 172b2518971SLang Hames dbgs() << "Cannot parse line table for \"" << G.getName() << "\": "; 173b2518971SLang Hames EIB.log(dbgs()); 174b2518971SLang Hames dbgs() << "\n"; 175b2518971SLang Hames }); 176b2518971SLang Hames }); 177b2518971SLang Hames } else { 178b6c06d1aSLang Hames for (auto &FN : P.FileNames) 179b6c06d1aSLang Hames if ((FileName = dwarf::toString(FN.Name))) { 180b6c06d1aSLang Hames LLVM_DEBUG({ 181b6c06d1aSLang Hames dbgs() << "Using FileName = \"" << *FileName 182b6c06d1aSLang Hames << "\" from DWARF line table\n"; 183b6c06d1aSLang Hames }); 184b6c06d1aSLang Hames break; 185b6c06d1aSLang Hames } 186b2518971SLang Hames } 187b2518971SLang Hames } 188b2518971SLang Hames 189b2518971SLang Hames // If no line table (or unable to use) then use graph name. 190b2518971SLang Hames // FIXME: There are probably other debug sections we should look in first. 191b6c06d1aSLang Hames if (!FileName) { 192b6c06d1aSLang Hames LLVM_DEBUG({ 193b6c06d1aSLang Hames dbgs() << "Could not find source name from DWARF line table. " 194b6c06d1aSLang Hames "Using FileName = \"\"\n"; 195b6c06d1aSLang Hames }); 196b6c06d1aSLang Hames FileName = ""; 197b6c06d1aSLang Hames } 198b2518971SLang Hames 199b2518971SLang Hames Builder.addSymbol("", MachO::N_SO, 0, 0, 0); 200b2518971SLang Hames Builder.addSymbol(*FileName, MachO::N_SO, 0, 0, 0); 201b2518971SLang Hames auto TimeStamp = std::chrono::duration_cast<std::chrono::seconds>( 202b2518971SLang Hames std::chrono::system_clock::now().time_since_epoch()) 203b2518971SLang Hames .count(); 204b2518971SLang Hames Builder.addSymbol("", MachO::N_OSO, 3, 1, TimeStamp); 205b2518971SLang Hames 206b2518971SLang Hames for (auto &NDSP : NonDebugSections) { 207b2518971SLang Hames auto [SegName, SecName] = NDSP.GraphSec->getName().split(','); 208b2518971SLang Hames NDSP.BuilderSec = &Seg->addSection(SecName, SegName); 209b2518971SLang Hames SectionRange SR(*NDSP.GraphSec); 210b2518971SLang Hames if (!SR.empty()) 211b2518971SLang Hames NDSP.BuilderSec->align = Log2_64(SR.getFirstBlock()->getAlignment()); 212b2518971SLang Hames 213b2518971SLang Hames // Add stabs. 214b2518971SLang Hames for (auto *Sym : NDSP.GraphSec->symbols()) { 215b2518971SLang Hames // Skip anonymous symbols. 216b2518971SLang Hames if (!Sym->hasName()) 217b2518971SLang Hames continue; 218b2518971SLang Hames 219b2518971SLang Hames uint8_t SymType = Sym->isCallable() ? MachO::N_FUN : MachO::N_GSYM; 220b2518971SLang Hames 221b2518971SLang Hames Builder.addSymbol("", MachO::N_BNSYM, 1, 0, 0); 222b2518971SLang Hames StabSymbols.push_back( 2232ccf7ed2SJared Wyles {*Sym, Builder.addSymbol(*Sym->getName(), SymType, 1, 0, 0), 2242ccf7ed2SJared Wyles Builder.addSymbol(*Sym->getName(), SymType, 0, 0, 0)}); 225b2518971SLang Hames Builder.addSymbol("", MachO::N_ENSYM, 1, 0, 0); 226b2518971SLang Hames } 227b2518971SLang Hames } 228b2518971SLang Hames 229b2518971SLang Hames Builder.addSymbol("", MachO::N_SO, 1, 0, 0); 230b2518971SLang Hames 231b2518971SLang Hames // Lay out the debug object, create a section and block for it. 232b2518971SLang Hames size_t DebugObjectSize = Builder.layout(); 233b2518971SLang Hames 234b2518971SLang Hames auto &SDOSec = G.createSection(SynthDebugSectionName, MemProt::Read); 235b2518971SLang Hames MachOContainerBlock = &G.createMutableContentBlock( 236b2518971SLang Hames SDOSec, G.allocateBuffer(DebugObjectSize), orc::ExecutorAddr(), 8, 0); 237b2518971SLang Hames 238b2518971SLang Hames return Error::success(); 239b2518971SLang Hames } 240b2518971SLang Hames 241b2518971SLang Hames Error completeSynthesisAndRegister() override { 242b2518971SLang Hames if (!MachOContainerBlock) { 243b2518971SLang Hames LLVM_DEBUG({ 244b2518971SLang Hames dbgs() << "Not writing MachO debug object header for " << G.getName() 245b2518971SLang Hames << " since createDebugSection failed\n"; 246b2518971SLang Hames }); 247b2518971SLang Hames 248b2518971SLang Hames return Error::success(); 249b2518971SLang Hames } 250b2518971SLang Hames ExecutorAddr MaxAddr; 251b2518971SLang Hames for (auto &NDSec : NonDebugSections) { 252b2518971SLang Hames SectionRange SR(*NDSec.GraphSec); 253b2518971SLang Hames NDSec.BuilderSec->addr = SR.getStart().getValue(); 254b2518971SLang Hames NDSec.BuilderSec->size = SR.getSize(); 255b2518971SLang Hames NDSec.BuilderSec->offset = SR.getStart().getValue(); 256b2518971SLang Hames if (SR.getEnd() > MaxAddr) 257b2518971SLang Hames MaxAddr = SR.getEnd(); 258b2518971SLang Hames } 259b2518971SLang Hames 260b2518971SLang Hames for (auto &DSec : DebugSections) { 261b2518971SLang Hames if (DSec.GraphSec->blocks_size() != 1) 262b2518971SLang Hames return make_error<StringError>( 263b2518971SLang Hames "Unexpected number of blocks in debug info section", 264b2518971SLang Hames inconvertibleErrorCode()); 265b2518971SLang Hames 266b2518971SLang Hames if (ExecutorAddr(DSec.BuilderSec->addr) + DSec.BuilderSec->size > MaxAddr) 267b2518971SLang Hames MaxAddr = ExecutorAddr(DSec.BuilderSec->addr) + DSec.BuilderSec->size; 268b2518971SLang Hames 269b2518971SLang Hames auto &B = **DSec.GraphSec->blocks().begin(); 270b2518971SLang Hames DSec.BuilderSec->Content.Data = B.getContent().data(); 271b2518971SLang Hames DSec.BuilderSec->Content.Size = B.getContent().size(); 272b2518971SLang Hames DSec.BuilderSec->flags |= MachO::S_ATTR_DEBUG; 273b2518971SLang Hames } 274b2518971SLang Hames 275b2518971SLang Hames LLVM_DEBUG({ 276b2518971SLang Hames dbgs() << "Writing MachO debug object header for " << G.getName() << "\n"; 277b2518971SLang Hames }); 278b2518971SLang Hames 279b2518971SLang Hames // Update stab symbol addresses. 280b2518971SLang Hames for (auto &SS : StabSymbols) { 281b2518971SLang Hames SS.StartStab.nlist().n_value = SS.Sym.getAddress().getValue(); 282b2518971SLang Hames SS.EndStab.nlist().n_value = SS.Sym.getSize(); 283b2518971SLang Hames } 284b2518971SLang Hames 285b2518971SLang Hames Builder.write(MachOContainerBlock->getAlreadyMutableContent()); 286b2518971SLang Hames 287b2518971SLang Hames static constexpr bool AutoRegisterCode = true; 288b2518971SLang Hames SectionRange R(MachOContainerBlock->getSection()); 289b2518971SLang Hames G.allocActions().push_back( 290b2518971SLang Hames {cantFail(shared::WrapperFunctionCall::Create< 291b2518971SLang Hames shared::SPSArgList<shared::SPSExecutorAddrRange, bool>>( 292b2518971SLang Hames RegisterActionAddr, R.getRange(), AutoRegisterCode)), 293b2518971SLang Hames {}}); 294b2518971SLang Hames 295b2518971SLang Hames return Error::success(); 296b2518971SLang Hames } 297b2518971SLang Hames 298b2518971SLang Hames private: 299b2518971SLang Hames struct SectionPair { 300b2518971SLang Hames Section *GraphSec = nullptr; 301b2518971SLang Hames typename MachOBuilder<MachOTraits>::Section *BuilderSec = nullptr; 302b2518971SLang Hames }; 303b2518971SLang Hames 304b2518971SLang Hames struct StabSymbolsEntry { 305b2518971SLang Hames using RelocTarget = typename MachOBuilder<MachOTraits>::RelocTarget; 306b2518971SLang Hames 307b2518971SLang Hames StabSymbolsEntry(Symbol &Sym, RelocTarget StartStab, RelocTarget EndStab) 308b2518971SLang Hames : Sym(Sym), StartStab(StartStab), EndStab(EndStab) {} 309b2518971SLang Hames 310b2518971SLang Hames Symbol &Sym; 311b2518971SLang Hames RelocTarget StartStab, EndStab; 312b2518971SLang Hames }; 313b2518971SLang Hames 314b2518971SLang Hames using BuilderType = MachOBuilder<MachOTraits>; 315b2518971SLang Hames 316b2518971SLang Hames Block *MachOContainerBlock = nullptr; 317b2518971SLang Hames MachOBuilder<MachOTraits> Builder; 318b2518971SLang Hames typename MachOBuilder<MachOTraits>::Segment *Seg = nullptr; 319b2518971SLang Hames std::vector<StabSymbolsEntry> StabSymbols; 320b2518971SLang Hames SmallVector<SectionPair, 16> DebugSections; 321b2518971SLang Hames SmallVector<SectionPair, 16> NonDebugSections; 322b2518971SLang Hames }; 323b2518971SLang Hames 324b2518971SLang Hames } // end anonymous namespace 325b2518971SLang Hames 326b2518971SLang Hames namespace llvm { 327b2518971SLang Hames namespace orc { 328b2518971SLang Hames 329b2518971SLang Hames Expected<std::unique_ptr<GDBJITDebugInfoRegistrationPlugin>> 330b2518971SLang Hames GDBJITDebugInfoRegistrationPlugin::Create(ExecutionSession &ES, 331b2518971SLang Hames JITDylib &ProcessJD, 332b2518971SLang Hames const Triple &TT) { 333b2518971SLang Hames auto RegisterActionAddr = 334b2518971SLang Hames TT.isOSBinFormatMachO() 335b2518971SLang Hames ? ES.intern("_llvm_orc_registerJITLoaderGDBAllocAction") 336b2518971SLang Hames : ES.intern("llvm_orc_registerJITLoaderGDBAllocAction"); 337b2518971SLang Hames 338b2518971SLang Hames if (auto RegisterSym = ES.lookup({&ProcessJD}, RegisterActionAddr)) 339b2518971SLang Hames return std::make_unique<GDBJITDebugInfoRegistrationPlugin>( 340b2518971SLang Hames RegisterSym->getAddress()); 341b2518971SLang Hames else 342b2518971SLang Hames return RegisterSym.takeError(); 343b2518971SLang Hames } 344b2518971SLang Hames 345b2518971SLang Hames Error GDBJITDebugInfoRegistrationPlugin::notifyFailed( 346b2518971SLang Hames MaterializationResponsibility &MR) { 347b2518971SLang Hames return Error::success(); 348b2518971SLang Hames } 349b2518971SLang Hames 350b2518971SLang Hames Error GDBJITDebugInfoRegistrationPlugin::notifyRemovingResources( 351b2518971SLang Hames JITDylib &JD, ResourceKey K) { 352b2518971SLang Hames return Error::success(); 353b2518971SLang Hames } 354b2518971SLang Hames 355b2518971SLang Hames void GDBJITDebugInfoRegistrationPlugin::notifyTransferringResources( 356b2518971SLang Hames JITDylib &JD, ResourceKey DstKey, ResourceKey SrcKey) {} 357b2518971SLang Hames 358b2518971SLang Hames void GDBJITDebugInfoRegistrationPlugin::modifyPassConfig( 359b2518971SLang Hames MaterializationResponsibility &MR, LinkGraph &LG, 360b2518971SLang Hames PassConfiguration &PassConfig) { 361b2518971SLang Hames 362b2518971SLang Hames if (LG.getTargetTriple().getObjectFormat() == Triple::MachO) 363b2518971SLang Hames modifyPassConfigForMachO(MR, LG, PassConfig); 364b2518971SLang Hames else { 365b2518971SLang Hames LLVM_DEBUG({ 366b2518971SLang Hames dbgs() << "GDBJITDebugInfoRegistrationPlugin skipping unspported graph " 367b2518971SLang Hames << LG.getName() << "(triple = " << LG.getTargetTriple().str() 368b2518971SLang Hames << "\n"; 369b2518971SLang Hames }); 370b2518971SLang Hames } 371b2518971SLang Hames } 372b2518971SLang Hames 373b2518971SLang Hames void GDBJITDebugInfoRegistrationPlugin::modifyPassConfigForMachO( 374b2518971SLang Hames MaterializationResponsibility &MR, jitlink::LinkGraph &LG, 375b2518971SLang Hames jitlink::PassConfiguration &PassConfig) { 376b2518971SLang Hames 377b2518971SLang Hames switch (LG.getTargetTriple().getArch()) { 378b2518971SLang Hames case Triple::x86_64: 379b2518971SLang Hames case Triple::aarch64: 380b2518971SLang Hames // Supported, continue. 381b2518971SLang Hames assert(LG.getPointerSize() == 8 && "Graph has incorrect pointer size"); 3824a0ccfa8SKazu Hirata assert(LG.getEndianness() == llvm::endianness::little && 383b2518971SLang Hames "Graph has incorrect endianness"); 384b2518971SLang Hames break; 385b2518971SLang Hames default: 386b2518971SLang Hames // Unsupported. 387b2518971SLang Hames LLVM_DEBUG({ 388b2518971SLang Hames dbgs() << "GDBJITDebugInfoRegistrationPlugin skipping unsupported " 389b2518971SLang Hames << "MachO graph " << LG.getName() 390b2518971SLang Hames << "(triple = " << LG.getTargetTriple().str() 391b2518971SLang Hames << ", pointer size = " << LG.getPointerSize() << ", endianness = " 3924a0ccfa8SKazu Hirata << (LG.getEndianness() == llvm::endianness::big ? "big" : "little") 393b2518971SLang Hames << ")\n"; 394b2518971SLang Hames }); 395b2518971SLang Hames return; 396b2518971SLang Hames } 397b2518971SLang Hames 398b2518971SLang Hames // Scan for debug sections. If we find one then install passes. 399b2518971SLang Hames bool HasDebugSections = false; 400b2518971SLang Hames for (auto &Sec : LG.sections()) 401b2518971SLang Hames if (MachODebugObjectSynthesizerBase::isDebugSection(Sec)) { 402b2518971SLang Hames HasDebugSections = true; 403b2518971SLang Hames break; 404b2518971SLang Hames } 405b2518971SLang Hames 406b2518971SLang Hames if (HasDebugSections) { 407b2518971SLang Hames LLVM_DEBUG({ 408b2518971SLang Hames dbgs() << "GDBJITDebugInfoRegistrationPlugin: Graph " << LG.getName() 409b2518971SLang Hames << " contains debug info. Installing debugger support passes.\n"; 410b2518971SLang Hames }); 411b2518971SLang Hames 412b2518971SLang Hames auto MDOS = std::make_shared<MachODebugObjectSynthesizer<MachO64LE>>( 413b2518971SLang Hames MR.getTargetJITDylib().getExecutionSession(), LG, RegisterActionAddr); 414b2518971SLang Hames PassConfig.PrePrunePasses.push_back( 415b2518971SLang Hames [=](LinkGraph &G) { return MDOS->preserveDebugSections(); }); 416b2518971SLang Hames PassConfig.PostPrunePasses.push_back( 417b2518971SLang Hames [=](LinkGraph &G) { return MDOS->startSynthesis(); }); 418b2518971SLang Hames PassConfig.PostFixupPasses.push_back( 419b2518971SLang Hames [=](LinkGraph &G) { return MDOS->completeSynthesisAndRegister(); }); 420b2518971SLang Hames } else { 421b2518971SLang Hames LLVM_DEBUG({ 422b2518971SLang Hames dbgs() << "GDBJITDebugInfoRegistrationPlugin: Graph " << LG.getName() 423b2518971SLang Hames << " contains no debug info. Skipping.\n"; 424b2518971SLang Hames }); 425b2518971SLang Hames } 426b2518971SLang Hames } 427b2518971SLang Hames 428b2518971SLang Hames } // namespace orc 429b2518971SLang Hames } // namespace llvm 430