99//
1010// ===----------------------------------------------------------------------===//
1111
12- #include " llvm/ExecutionEngine/Orc/DebuggerSupportPlugin.h"
12+ #include " llvm/ExecutionEngine/Orc/Debugging/ DebuggerSupportPlugin.h"
1313#include " llvm/ExecutionEngine/Orc/MachOBuilder.h"
1414
1515#include " llvm/ADT/SmallSet.h"
1616#include " llvm/ADT/SmallVector.h"
1717#include " llvm/ADT/StringSet.h"
1818#include " llvm/BinaryFormat/MachO.h"
19+ #include " llvm/DebugInfo/DWARF/DWARFContext.h"
20+ #include " llvm/DebugInfo/DWARF/DWARFDebugLine.h"
21+
22+ #include < chrono>
1923
2024#define DEBUG_TYPE " orc"
2125
@@ -97,8 +101,6 @@ class MachODebugObjectSynthesizer : public MachODebugObjectSynthesizerBase {
97101 << " \n " ;
98102 });
99103
100- auto &SDOSec = G.createSection (SynthDebugSectionName, MemProt::Read);
101-
102104 for (auto &Sec : G.sections ()) {
103105 if (Sec.blocks ().empty ())
104106 continue ;
@@ -114,6 +116,10 @@ class MachODebugObjectSynthesizer : public MachODebugObjectSynthesizerBase {
114116 NonDebugSections.push_back ({&Sec, nullptr });
115117 }
116118
119+ // Bail out early if no debug sections.
120+ if (DebugSections.empty ())
121+ return Error::success ();
122+
117123 // Write MachO header and debug section load commands.
118124 Builder.Header .filetype = MachO::MH_OBJECT;
119125 switch (G.getTargetTriple ().getArch ()) {
@@ -131,16 +137,65 @@ class MachODebugObjectSynthesizer : public MachODebugObjectSynthesizerBase {
131137
132138 Seg = &Builder.addSegment (" " );
133139
140+ StringMap<std::unique_ptr<MemoryBuffer>> DebugSectionMap;
141+ StringRef DebugLineSectionData;
134142 for (auto &DSec : DebugSections) {
135143 auto [SegName, SecName] = DSec.GraphSec ->getName ().split (' ,' );
136144 DSec.BuilderSec = &Seg->addSection (SecName, SegName);
137145
138146 SectionRange SR (*DSec.GraphSec );
139147 DSec.BuilderSec ->Content .Size = SR.getSize ();
140- if (!SR.empty ())
148+ if (!SR.empty ()) {
141149 DSec.BuilderSec ->align = Log2_64 (SR.getFirstBlock ()->getAlignment ());
150+ StringRef SectionData (SR.getFirstBlock ()->getContent ().data (),
151+ SR.getFirstBlock ()->getSize ());
152+ DebugSectionMap[SecName] =
153+ MemoryBuffer::getMemBuffer (SectionData, G.getName (), false );
154+ if (SecName == " __debug_line" )
155+ DebugLineSectionData = SectionData;
156+ }
142157 }
143158
159+ std::optional<std::string> FileName;
160+ if (!DebugLineSectionData.empty ()) {
161+ auto DWARFCtx = DWARFContext::create (DebugSectionMap, G.getPointerSize (),
162+ G.getEndianness ());
163+ DWARFDataExtractor DebugLineData (
164+ DebugLineSectionData,
165+ G.getEndianness () == support::endianness::little, G.getPointerSize ());
166+ uint64_t Offset = 0 ;
167+ DWARFDebugLine::LineTable LineTable;
168+
169+ // Try to parse line data. Consume error on failure.
170+ if (auto Err = LineTable.parse (DebugLineData, &Offset, *DWARFCtx, nullptr ,
171+ consumeError)) {
172+ handleAllErrors (
173+ std::move (Err),
174+ [&](ErrorInfoBase &EIB) {
175+ LLVM_DEBUG ({
176+ dbgs () << " Cannot parse line table for \" " << G.getName () << " \" : " ;
177+ EIB.log (dbgs ());
178+ dbgs () << " \n " ;
179+ });
180+ });
181+ } else {
182+ if (!LineTable.Prologue .FileNames .empty ())
183+ FileName = *dwarf::toString (LineTable.Prologue .FileNames [0 ].Name );
184+ }
185+ }
186+
187+ // If no line table (or unable to use) then use graph name.
188+ // FIXME: There are probably other debug sections we should look in first.
189+ if (!FileName)
190+ FileName = G.getName ();
191+
192+ Builder.addSymbol (" " , MachO::N_SO, 0 , 0 , 0 );
193+ Builder.addSymbol (*FileName, MachO::N_SO, 0 , 0 , 0 );
194+ auto TimeStamp = std::chrono::duration_cast<std::chrono::seconds>(
195+ std::chrono::system_clock::now ().time_since_epoch ())
196+ .count ();
197+ Builder.addSymbol (" " , MachO::N_OSO, 3 , 1 , TimeStamp);
198+
144199 for (auto &NDSP : NonDebugSections) {
145200 auto [SegName, SecName] = NDSP.GraphSec ->getName ().split (' ,' );
146201 NDSP.BuilderSec = &Seg->addSection (SecName, SegName);
@@ -164,8 +219,12 @@ class MachODebugObjectSynthesizer : public MachODebugObjectSynthesizerBase {
164219 }
165220 }
166221
222+ Builder.addSymbol (" " , MachO::N_SO, 1 , 0 , 0 );
223+
224+ // Lay out the debug object, create a section and block for it.
167225 size_t DebugObjectSize = Builder.layout ();
168226
227+ auto &SDOSec = G.createSection (SynthDebugSectionName, MemProt::Read);
169228 MachOContainerBlock = &G.createMutableContentBlock (
170229 SDOSec, G.allocateBuffer (DebugObjectSize), orc::ExecutorAddr (), 8 , 0 );
171230
0 commit comments