27 : TheTriple(TheTriple), U(U) {}
35 if (
Error Err = init(TheTriple))
47 emitLineTablePrologue(LineTable.
Prologue, OutSection);
50 emitLineTableRows(LineTable, OutSection, OrigRowIndices,
51 RowIndexToSeqStartOffset);
55 assert(OffsetAfterUnitLength -
57 OffsetAfterUnitLength);
58 OutSection.
apply(OffsetAfterUnitLength -
60 dwarf::DW_FORM_sec_offset,
61 OffsetAfterEnd - OffsetAfterUnitLength);
69 std::string TripleName;
82 "no register info for target %s",
89 "no asm info for target %s", TripleName.c_str());
94 "no subtarget info for target %s",
98 new MCContext(TheTriple, *MAI, *MRI, *MSTI,
nullptr,
true,
"__DWARF"));
104 SectionDescriptor &Section) {
106 Section.emitIntVal(
P.getVersion(), 2);
107 if (
P.getVersion() == 5) {
109 Section.emitIntVal(
P.getAddressSize(), 1);
112 Section.emitIntVal(
P.SegSelectorSize, 1);
116 Section.emitOffset(0xBADDEF);
118 uint64_t OffsetAfterPrologueLength = Section.OS.tell();
119 emitLineTableProloguePayload(
P, Section);
120 uint64_t OffsetAfterPrologueEnd = Section.OS.tell();
123 Section.apply(OffsetAfterPrologueLength -
124 Section.getFormParams().getDwarfOffsetByteSize(),
125 dwarf::DW_FORM_sec_offset,
126 OffsetAfterPrologueEnd - OffsetAfterPrologueLength);
130 emitLineTablePrologueV2IncludeAndFileTable(
const DWARFDebugLine::Prologue &
P,
131 SectionDescriptor &Section) {
133 for (
const DWARFFormValue &
Include :
P.IncludeDirectories) {
136 U.warn(
"cann't read string from line table.");
146 for (
const DWARFDebugLine::FileNameEntry &File :
P.FileNames) {
149 U.warn(
"cann't read string from line table.");
155 Section.emitString(
File.Name.getForm(), *FileNameStr);
172 emitLineTablePrologueV5IncludeAndFileTable(
const DWARFDebugLine::Prologue &
P,
173 SectionDescriptor &Section) {
174 if (
P.IncludeDirectories.empty()) {
189 for (
auto Include :
P.IncludeDirectories) {
192 U.warn(
"cann't read string from line table.");
199 bool HasChecksums =
P.ContentTypes.HasMD5;
200 bool HasInlineSources =
P.ContentTypes.HasSource;
203 dwarf::Form LLVMSourceForm = dwarf::DW_FORM_string;
205 if (
P.FileNames.empty()) {
209 FileNameForm =
P.FileNames[0].Name.getForm();
210 LLVMSourceForm =
P.FileNames[0].Source.getForm();
214 2 + (HasChecksums ? 1 : 0) + (HasInlineSources ? 1 : 0), 1);
228 if (HasInlineSources) {
238 for (
auto File :
P.FileNames) {
241 U.warn(
"cann't read string from line table.");
247 Section.emitString(FileNameForm, *FileNameStr);
252 "checksum size is not equal to 16 bytes.");
254 StringRef(
reinterpret_cast<const char *
>(
File.Checksum.data()),
255 File.Checksum.size()));
258 if (HasInlineSources) {
259 std::optional<const char *> FileSourceStr =
261 if (!FileSourceStr) {
262 U.warn(
"cann't read string from line table.");
266 Section.emitString(LLVMSourceForm, *FileSourceStr);
271 void emitLineTableProloguePayload(
const DWARFDebugLine::Prologue &
P,
272 SectionDescriptor &Section) {
274 Section.emitIntVal(
P.MinInstLength, 1);
275 if (
P.FormParams.Version >= 4) {
277 Section.emitIntVal(
P.MaxOpsPerInst, 1);
280 Section.emitIntVal(
P.DefaultIsStmt, 1);
286 Section.emitIntVal(
P.OpcodeBase, 1);
289 for (
auto Length :
P.StandardOpcodeLengths)
292 if (
P.FormParams.Version < 5)
293 emitLineTablePrologueV2IncludeAndFileTable(
P, Section);
295 emitLineTablePrologueV5IncludeAndFileTable(
P, Section);
298 void emitLineTableRows(
299 const DWARFDebugLine::LineTable &LineTable, SectionDescriptor &Section,
300 ArrayRef<uint64_t> OrigRowIndices = {},
301 DenseMap<uint64_t, uint64_t> *RowIndexToSeqStartOffset =
nullptr) {
303 MCDwarfLineTableParams Params;
304 Params.DWARF2LineOpcodeBase = LineTable.Prologue.OpcodeBase;
305 Params.DWARF2LineBase = LineTable.Prologue.LineBase;
306 Params.DWARF2LineRange = LineTable.Prologue.LineRange;
308 SmallString<128> EncodingBuffer;
310 if (LineTable.Rows.empty()) {
315 Section.OS.write(EncodingBuffer.c_str(), EncodingBuffer.size());
320 unsigned FileNum = 1;
321 unsigned LastLine = 1;
324 unsigned IsStatement = 1;
328 unsigned RowsSinceLastSequence = 0;
333 uint64_t CurrentSeqStartOffset = 0;
334 constexpr uint64_t InvalidRowIndex = std::numeric_limits<uint64_t>::max();
336 (!RowIndexToSeqStartOffset ||
337 OrigRowIndices.size() == LineTable.Rows.size()) &&
338 "OrigRowIndices must be supplied alongside RowIndexToSeqStartOffset");
343 CurrentSeqStartOffset =
Section.OS.tell();
344 Section.emitIntVal(dwarf::DW_LNS_extended_op, 1);
346 Section.emitIntVal(dwarf::DW_LNE_set_address, 1);
347 Section.emitIntVal(Row.Address.Address,
348 Section.getFormParams().AddrSize);
352 (Row.Address.Address -
Address) / LineTable.Prologue.MinInstLength;
354 if (RowIndexToSeqStartOffset) {
355 uint64_t InputRowIdx = OrigRowIndices[Idx];
356 if (InputRowIdx != InvalidRowIndex)
357 (*RowIndexToSeqStartOffset)[InputRowIdx] = CurrentSeqStartOffset;
365 if (FileNum != Row.File) {
367 Section.emitIntVal(dwarf::DW_LNS_set_file, 1);
370 if (Column != Row.Column) {
372 Section.emitIntVal(dwarf::DW_LNS_set_column, 1);
375 if (Discriminator != Row.Discriminator && MC->getDwarfVersion() >= 4) {
378 Section.emitIntVal(dwarf::DW_LNS_extended_op, 1);
380 Section.emitIntVal(dwarf::DW_LNE_set_discriminator, 1);
385 if (Isa != Row.Isa) {
387 Section.emitIntVal(dwarf::DW_LNS_set_isa, 1);
390 if (IsStatement != Row.IsStmt) {
391 IsStatement = Row.IsStmt;
392 Section.emitIntVal(dwarf::DW_LNS_negate_stmt, 1);
395 Section.emitIntVal(dwarf::DW_LNS_set_basic_block, 1);
398 Section.emitIntVal(dwarf::DW_LNS_set_prologue_end, 1);
400 if (Row.EpilogueBegin)
401 Section.emitIntVal(dwarf::DW_LNS_set_epilogue_begin, 1);
403 int64_t LineDelta = int64_t(Row.Line) - LastLine;
404 if (!Row.EndSequence) {
407 Section.OS.write(EncodingBuffer.c_str(), EncodingBuffer.size());
408 EncodingBuffer.resize(0);
411 RowsSinceLastSequence++;
414 Section.emitIntVal(dwarf::DW_LNS_advance_line, 1);
418 Section.emitIntVal(dwarf::DW_LNS_advance_pc, 1);
422 std::numeric_limits<int64_t>::max(), 0,
424 Section.OS.write(EncodingBuffer.c_str(), EncodingBuffer.size());
425 EncodingBuffer.resize(0);
427 LastLine = FileNum = IsStatement = 1;
432 if (RowsSinceLastSequence) {
435 Section.OS.write(EncodingBuffer.c_str(), EncodingBuffer.size());
436 EncodingBuffer.resize(0);
443 MCTargetOptions MCOptions;
444 std::unique_ptr<MCRegisterInfo> MRI;
445 std::unique_ptr<MCAsmInfo> MAI;
446 std::unique_ptr<MCContext> MC;
447 std::unique_ptr<MCSubtargetInfo> MSTI;