LLVM: lib/DWARFLinker/Parallel/DebugLineSectionEmitter.h Source File (original) (raw)
25public:
27 : TheTriple(TheTriple), U(U) {}
28
30
31
32
33 if (Error Err = init(TheTriple))
34 return Err;
35
36
39
40
42 uint64_t OffsetAfterUnitLength = OutSection.OS.tell();
43
44
45 emitLineTablePrologue(LineTable.Prologue, OutSection);
46
47
48 emitLineTableRows(LineTable, OutSection);
50
51
52 assert(OffsetAfterUnitLength -
54 OffsetAfterUnitLength);
55 OutSection.apply(OffsetAfterUnitLength -
57 dwarf::DW_FORM_sec_offset,
58 OffsetAfterEnd - OffsetAfterUnitLength);
59
61 }
62
63private:
65 std::string ErrorStr;
66 std::string TripleName;
67
68
69 const Target *TheTarget =
71 if (!TheTarget)
72 return createStringError(std::errc::invalid_argument, ErrorStr.c_str());
73 TripleName = TheTriple.getTriple();
74
75
79 "no register info for target %s",
80 TripleName.c_str());
81
84 if (!MAI)
86 "no asm info for target %s", TripleName.c_str());
87
89 if (!MSTI)
91 "no subtarget info for target %s",
92 TripleName.c_str());
93
94 MC.reset(new MCContext(TheTriple, MAI.get(), MRI.get(), MSTI.get(), nullptr,
95 nullptr, true, "__DWARF"));
96
98 }
99
101 SectionDescriptor &Section) {
102
103 Section.emitIntVal(P.getVersion(), 2);
104 if (P.getVersion() == 5) {
105
106 Section.emitIntVal(P.getAddressSize(), 1);
107
108
109 Section.emitIntVal(P.SegSelectorSize, 1);
110 }
111
112
113 Section.emitOffset(0xBADDEF);
114
115 uint64_t OffsetAfterPrologueLength = Section.OS.tell();
116 emitLineTableProloguePayload(P, Section);
117 uint64_t OffsetAfterPrologueEnd = Section.OS.tell();
118
119
120 Section.apply(OffsetAfterPrologueLength -
121 Section.getFormParams().getDwarfOffsetByteSize(),
122 dwarf::DW_FORM_sec_offset,
123 OffsetAfterPrologueEnd - OffsetAfterPrologueLength);
124 }
125
126 void
127 emitLineTablePrologueV2IncludeAndFileTable(const DWARFDebugLine::Prologue &P,
128 SectionDescriptor &Section) {
129
130 for (const DWARFFormValue &Include : P.IncludeDirectories) {
132 if (!IncludeStr) {
133 U.warn("cann't read string from line table.");
134 return;
135 }
136
138 }
139
140 Section.emitIntVal(0, 1);
141
142
143 for (const DWARFDebugLine::FileNameEntry &File : P.FileNames) {
145 if (!FileNameStr) {
146 U.warn("cann't read string from line table.");
147 return;
148 }
149
150
151
152 Section.emitString(File.Name.getForm(), *FileNameStr);
153
154
155
157
158
160
161
163 }
164
165 Section.emitIntVal(0, 1);
166 }
167
168 void
169 emitLineTablePrologueV5IncludeAndFileTable(const DWARFDebugLine::Prologue &P,
170 SectionDescriptor &Section) {
171 if (P.IncludeDirectories.empty()) {
172
173 Section.emitIntVal(0, 1);
174 } else {
175
176 Section.emitIntVal(1, 1);
177
178
181 }
182
183
185
186 for (auto Include : P.IncludeDirectories) {
188 if (!IncludeStr) {
189 U.warn("cann't read string from line table.");
190 return;
191 }
192
194 }
195
196 bool HasChecksums = P.ContentTypes.HasMD5;
197 bool HasInlineSources = P.ContentTypes.HasSource;
198
199 dwarf::Form FileNameForm = dwarf::DW_FORM_string;
200 dwarf::Form LLVMSourceForm = dwarf::DW_FORM_string;
201
202 if (P.FileNames.empty()) {
203
204 Section.emitIntVal(0, 1);
205 } else {
206 FileNameForm = P.FileNames[0].Name.getForm();
207 LLVMSourceForm = P.FileNames[0].Source.getForm();
208
209
211 2 + (HasChecksums ? 1 : 0) + (HasInlineSources ? 1 : 0), 1);
212
213
216
219
220 if (HasChecksums) {
223 }
224
225 if (HasInlineSources) {
228 }
229 }
230
231
233
234
235 for (auto File : P.FileNames) {
237 if (!FileNameStr) {
238 U.warn("cann't read string from line table.");
239 return;
240 }
241
242
243
244 Section.emitString(FileNameForm, *FileNameStr);
246
247 if (HasChecksums) {
248 assert((File.Checksum.size() == 16) &&
249 "checksum size is not equal to 16 bytes.");
251 StringRef(reinterpret_cast<const char *>(File.Checksum.data()),
252 File.Checksum.size()));
253 }
254
255 if (HasInlineSources) {
256 std::optional<const char *> FileSourceStr =
258 if (!FileSourceStr) {
259 U.warn("cann't read string from line table.");
260 return;
261 }
262
263 Section.emitString(LLVMSourceForm, *FileSourceStr);
264 }
265 }
266 }
267
268 void emitLineTableProloguePayload(const DWARFDebugLine::Prologue &P,
269 SectionDescriptor &Section) {
270
271 Section.emitIntVal(P.MinInstLength, 1);
272 if (P.FormParams.Version >= 4) {
273
274 Section.emitIntVal(P.MaxOpsPerInst, 1);
275 }
276
277 Section.emitIntVal(P.DefaultIsStmt, 1);
278
279 Section.emitIntVal(P.LineBase, 1);
280
281 Section.emitIntVal(P.LineRange, 1);
282
283 Section.emitIntVal(P.OpcodeBase, 1);
284
285
286 for (auto Length : P.StandardOpcodeLengths)
288
289 if (P.FormParams.Version < 5)
290 emitLineTablePrologueV2IncludeAndFileTable(P, Section);
291 else
292 emitLineTablePrologueV5IncludeAndFileTable(P, Section);
293 }
294
295 void emitLineTableRows(const DWARFDebugLine::LineTable &LineTable,
296 SectionDescriptor &Section) {
297
298 MCDwarfLineTableParams Params;
299 Params.DWARF2LineOpcodeBase = LineTable.Prologue.OpcodeBase;
300 Params.DWARF2LineBase = LineTable.Prologue.LineBase;
301 Params.DWARF2LineRange = LineTable.Prologue.LineRange;
302
303 SmallString<128> EncodingBuffer;
304
305 if (LineTable.Rows.empty()) {
306
307
309 0, EncodingBuffer);
310 Section.OS.write(EncodingBuffer.c_str(), EncodingBuffer.size());
311 return;
312 }
313
314
315 unsigned FileNum = 1;
316 unsigned LastLine = 1;
317 unsigned Column = 0;
319 unsigned IsStatement = 1;
320 unsigned Isa = 0;
321 uint64_t Address = -1ULL;
322
323 unsigned RowsSinceLastSequence = 0;
324
325 for (const DWARFDebugLine::Row &Row : LineTable.Rows) {
328 Section.emitIntVal(dwarf::DW_LNS_extended_op, 1);
330 Section.emitIntVal(dwarf::DW_LNE_set_address, 1);
331 Section.emitIntVal(Row.Address.Address,
332 Section.getFormParams().AddrSize);
334 } else {
336 (Row.Address.Address - Address) / LineTable.Prologue.MinInstLength;
337 }
338
339
340
341
342
343
344 if (FileNum != Row.File) {
345 FileNum = Row.File;
346 Section.emitIntVal(dwarf::DW_LNS_set_file, 1);
348 }
349 if (Column != Row.Column) {
350 Column = Row.Column;
351 Section.emitIntVal(dwarf::DW_LNS_set_column, 1);
353 }
354 if (Discriminator != Row.Discriminator && MC->getDwarfVersion() >= 4) {
357 Section.emitIntVal(dwarf::DW_LNS_extended_op, 1);
359 Section.emitIntVal(dwarf::DW_LNE_set_discriminator, 1);
361 }
363
364 if (Isa != Row.Isa) {
365 Isa = Row.Isa;
366 Section.emitIntVal(dwarf::DW_LNS_set_isa, 1);
368 }
369 if (IsStatement != Row.IsStmt) {
370 IsStatement = Row.IsStmt;
371 Section.emitIntVal(dwarf::DW_LNS_negate_stmt, 1);
372 }
373 if (Row.BasicBlock)
374 Section.emitIntVal(dwarf::DW_LNS_set_basic_block, 1);
375
376 if (Row.PrologueEnd)
377 Section.emitIntVal(dwarf::DW_LNS_set_prologue_end, 1);
378
379 if (Row.EpilogueBegin)
380 Section.emitIntVal(dwarf::DW_LNS_set_epilogue_begin, 1);
381
382 int64_t LineDelta = int64_t(Row.Line) - LastLine;
383 if (!Row.EndSequence) {
385 EncodingBuffer);
386 Section.OS.write(EncodingBuffer.c_str(), EncodingBuffer.size());
387 EncodingBuffer.resize(0);
388 Address = Row.Address.Address;
389 LastLine = Row.Line;
390 RowsSinceLastSequence++;
391 } else {
392 if (LineDelta) {
393 Section.emitIntVal(dwarf::DW_LNS_advance_line, 1);
395 }
397 Section.emitIntVal(dwarf::DW_LNS_advance_pc, 1);
399 }
401 std::numeric_limits<int64_t>::max(), 0,
402 EncodingBuffer);
403 Section.OS.write(EncodingBuffer.c_str(), EncodingBuffer.size());
404 EncodingBuffer.resize(0);
406 LastLine = FileNum = IsStatement = 1;
407 RowsSinceLastSequence = Column = Discriminator = Isa = 0;
408 }
409 }
410
411 if (RowsSinceLastSequence) {
413 0, EncodingBuffer);
414 Section.OS.write(EncodingBuffer.c_str(), EncodingBuffer.size());
415 EncodingBuffer.resize(0);
416 }
417 }
418
419 Triple TheTriple;
420 DwarfUnit &U;
421
422 std::unique_ptr MRI;
423 std::unique_ptr MAI;
424 std::unique_ptr MC;
425 std::unique_ptr MSTI;
426};