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,15 +137,51 @@ 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+ }
157+ }
158+
159+ if (DebugLineSectionData.empty ())
160+ return make_error<StringError>(G.getName () +
161+ " has debug info but no line table" ,
162+ inconvertibleErrorCode ());
163+
164+ // Add Stabs.
165+ auto DWARFCtx = DWARFContext::create (DebugSectionMap, G.getPointerSize (),
166+ G.getEndianness ());
167+ DWARFDataExtractor DebugLineData (
168+ DebugLineSectionData, G.getEndianness () == support::endianness::little,
169+ G.getPointerSize ());
170+ uint64_t Offset = 0 ;
171+ DWARFDebugLine::LineTable LineTable;
172+ if (auto Err = LineTable.parse (DebugLineData, &Offset, *DWARFCtx, nullptr ,
173+ consumeError))
174+ return Err;
175+
176+ Builder.addSymbol (" " , MachO::N_SO, 0 , 0 , 0 );
177+ for (auto &FN : LineTable.Prologue .FileNames ) {
178+ if (auto Name = dwarf::toString (FN.Name ))
179+ Builder.addSymbol (*Name, MachO::N_SO, 0 , 0 , 0 );
142180 }
181+ auto TimeStamp = std::chrono::duration_cast<std::chrono::seconds>(
182+ std::chrono::system_clock::now ().time_since_epoch ())
183+ .count ();
184+ Builder.addSymbol (" " , MachO::N_OSO, 3 , 1 , TimeStamp);
143185
144186 for (auto &NDSP : NonDebugSections) {
145187 auto [SegName, SecName] = NDSP.GraphSec ->getName ().split (' ,' );
@@ -164,8 +206,12 @@ class MachODebugObjectSynthesizer : public MachODebugObjectSynthesizerBase {
164206 }
165207 }
166208
209+ Builder.addSymbol (" " , MachO::N_SO, 1 , 0 , 0 );
210+
211+ // Lay out the debug object, create a section and block for it.
167212 size_t DebugObjectSize = Builder.layout ();
168213
214+ auto &SDOSec = G.createSection (SynthDebugSectionName, MemProt::Read);
169215 MachOContainerBlock = &G.createMutableContentBlock (
170216 SDOSec, G.allocateBuffer (DebugObjectSize), orc::ExecutorAddr (), 8 , 0 );
171217
0 commit comments