16
16
#include " llvm/ADT/SmallVector.h"
17
17
#include " llvm/ADT/StringSet.h"
18
18
#include " llvm/BinaryFormat/MachO.h"
19
+ #include " llvm/DebugInfo/DWARF/DWARFContext.h"
20
+ #include " llvm/DebugInfo/DWARF/DWARFDebugLine.h"
21
+
22
+ #include < chrono>
19
23
20
24
#define DEBUG_TYPE " orc"
21
25
@@ -97,8 +101,6 @@ class MachODebugObjectSynthesizer : public MachODebugObjectSynthesizerBase {
97
101
<< " \n " ;
98
102
});
99
103
100
- auto &SDOSec = G.createSection (SynthDebugSectionName, MemProt::Read);
101
-
102
104
for (auto &Sec : G.sections ()) {
103
105
if (Sec.blocks ().empty ())
104
106
continue ;
@@ -114,6 +116,10 @@ class MachODebugObjectSynthesizer : public MachODebugObjectSynthesizerBase {
114
116
NonDebugSections.push_back ({&Sec, nullptr });
115
117
}
116
118
119
+ // Bail out early if no debug sections.
120
+ if (DebugSections.empty ())
121
+ return Error::success ();
122
+
117
123
// Write MachO header and debug section load commands.
118
124
Builder.Header .filetype = MachO::MH_OBJECT;
119
125
switch (G.getTargetTriple ().getArch ()) {
@@ -131,15 +137,51 @@ class MachODebugObjectSynthesizer : public MachODebugObjectSynthesizerBase {
131
137
132
138
Seg = &Builder.addSegment (" " );
133
139
140
+ StringMap<std::unique_ptr<MemoryBuffer>> DebugSectionMap;
141
+ StringRef DebugLineSectionData;
134
142
for (auto &DSec : DebugSections) {
135
143
auto [SegName, SecName] = DSec.GraphSec ->getName ().split (' ,' );
136
144
DSec.BuilderSec = &Seg->addSection (SecName, SegName);
137
145
138
146
SectionRange SR (*DSec.GraphSec );
139
147
DSec.BuilderSec ->Content .Size = SR.getSize ();
140
- if (!SR.empty ())
148
+ if (!SR.empty ()) {
141
149
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 );
142
180
}
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);
143
185
144
186
for (auto &NDSP : NonDebugSections) {
145
187
auto [SegName, SecName] = NDSP.GraphSec ->getName ().split (' ,' );
@@ -164,8 +206,12 @@ class MachODebugObjectSynthesizer : public MachODebugObjectSynthesizerBase {
164
206
}
165
207
}
166
208
209
+ Builder.addSymbol (" " , MachO::N_SO, 1 , 0 , 0 );
210
+
211
+ // Lay out the debug object, create a section and block for it.
167
212
size_t DebugObjectSize = Builder.layout ();
168
213
214
+ auto &SDOSec = G.createSection (SynthDebugSectionName, MemProt::Read);
169
215
MachOContainerBlock = &G.createMutableContentBlock (
170
216
SDOSec, G.allocateBuffer (DebugObjectSize), orc::ExecutorAddr (), 8 , 0 );
171
217
0 commit comments