27 : TheTriple(TheTriple), U(U) {}
33 if (
Error Err = init(TheTriple))
45 emitLineTablePrologue(LineTable.
Prologue, OutSection);
48 emitLineTableRows(LineTable, OutSection);
52 assert(OffsetAfterUnitLength -
54 OffsetAfterUnitLength);
55 OutSection.
apply(OffsetAfterUnitLength -
57 dwarf::DW_FORM_sec_offset,
58 OffsetAfterEnd - OffsetAfterUnitLength);
66 std::string TripleName;
79 "no register info for target %s",
86 "no asm info for target %s", TripleName.c_str());
91 "no subtarget info for target %s",
94 MC.reset(
new MCContext(TheTriple, MAI.get(),
MRI.get(), MSTI.get(),
nullptr,
95 nullptr,
true,
"__DWARF"));
101 SectionDescriptor &Section) {
103 Section.emitIntVal(
P.getVersion(), 2);
104 if (
P.getVersion() == 5) {
106 Section.emitIntVal(
P.getAddressSize(), 1);
109 Section.emitIntVal(
P.SegSelectorSize, 1);
113 Section.emitOffset(0xBADDEF);
115 uint64_t OffsetAfterPrologueLength = Section.OS.tell();
116 emitLineTableProloguePayload(
P, Section);
117 uint64_t OffsetAfterPrologueEnd = Section.OS.tell();
120 Section.apply(OffsetAfterPrologueLength -
121 Section.getFormParams().getDwarfOffsetByteSize(),
122 dwarf::DW_FORM_sec_offset,
123 OffsetAfterPrologueEnd - OffsetAfterPrologueLength);
127 emitLineTablePrologueV2IncludeAndFileTable(
const DWARFDebugLine::Prologue &
P,
128 SectionDescriptor &Section) {
130 for (
const DWARFFormValue &
Include :
P.IncludeDirectories) {
133 U.warn(
"cann't read string from line table.");
143 for (
const DWARFDebugLine::FileNameEntry &File :
P.FileNames) {
146 U.warn(
"cann't read string from line table.");
152 Section.emitString(
File.Name.getForm(), *FileNameStr);
169 emitLineTablePrologueV5IncludeAndFileTable(
const DWARFDebugLine::Prologue &
P,
170 SectionDescriptor &Section) {
171 if (
P.IncludeDirectories.empty()) {
186 for (
auto Include :
P.IncludeDirectories) {
189 U.warn(
"cann't read string from line table.");
196 bool HasChecksums =
P.ContentTypes.HasMD5;
197 bool HasInlineSources =
P.ContentTypes.HasSource;
200 dwarf::Form LLVMSourceForm = dwarf::DW_FORM_string;
202 if (
P.FileNames.empty()) {
206 FileNameForm =
P.FileNames[0].Name.getForm();
207 LLVMSourceForm =
P.FileNames[0].Source.getForm();
211 2 + (HasChecksums ? 1 : 0) + (HasInlineSources ? 1 : 0), 1);
225 if (HasInlineSources) {
235 for (
auto File :
P.FileNames) {
238 U.warn(
"cann't read string from line table.");
244 Section.emitString(FileNameForm, *FileNameStr);
249 "checksum size is not equal to 16 bytes.");
251 StringRef(
reinterpret_cast<const char *
>(
File.Checksum.data()),
252 File.Checksum.size()));
255 if (HasInlineSources) {
256 std::optional<const char *> FileSourceStr =
258 if (!FileSourceStr) {
259 U.warn(
"cann't read string from line table.");
263 Section.emitString(LLVMSourceForm, *FileSourceStr);
268 void emitLineTableProloguePayload(
const DWARFDebugLine::Prologue &
P,
269 SectionDescriptor &Section) {
271 Section.emitIntVal(
P.MinInstLength, 1);
272 if (
P.FormParams.Version >= 4) {
274 Section.emitIntVal(
P.MaxOpsPerInst, 1);
277 Section.emitIntVal(
P.DefaultIsStmt, 1);
283 Section.emitIntVal(
P.OpcodeBase, 1);
286 for (
auto Length :
P.StandardOpcodeLengths)
289 if (
P.FormParams.Version < 5)
290 emitLineTablePrologueV2IncludeAndFileTable(
P, Section);
292 emitLineTablePrologueV5IncludeAndFileTable(
P, Section);
295 void emitLineTableRows(
const DWARFDebugLine::LineTable &LineTable,
296 SectionDescriptor &Section) {
298 MCDwarfLineTableParams Params;
299 Params.DWARF2LineOpcodeBase = LineTable.Prologue.OpcodeBase;
300 Params.DWARF2LineBase = LineTable.Prologue.LineBase;
301 Params.DWARF2LineRange = LineTable.Prologue.LineRange;
303 SmallString<128> EncodingBuffer;
305 if (LineTable.Rows.empty()) {
310 Section.OS.write(EncodingBuffer.c_str(), EncodingBuffer.size());
315 unsigned FileNum = 1;
316 unsigned LastLine = 1;
319 unsigned IsStatement = 1;
323 unsigned RowsSinceLastSequence = 0;
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);
336 (Row.Address.Address -
Address) / LineTable.Prologue.MinInstLength;
344 if (FileNum != Row.File) {
346 Section.emitIntVal(dwarf::DW_LNS_set_file, 1);
349 if (Column != Row.Column) {
351 Section.emitIntVal(dwarf::DW_LNS_set_column, 1);
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);
364 if (Isa != Row.Isa) {
366 Section.emitIntVal(dwarf::DW_LNS_set_isa, 1);
369 if (IsStatement != Row.IsStmt) {
370 IsStatement = Row.IsStmt;
371 Section.emitIntVal(dwarf::DW_LNS_negate_stmt, 1);
374 Section.emitIntVal(dwarf::DW_LNS_set_basic_block, 1);
377 Section.emitIntVal(dwarf::DW_LNS_set_prologue_end, 1);
379 if (Row.EpilogueBegin)
380 Section.emitIntVal(dwarf::DW_LNS_set_epilogue_begin, 1);
382 int64_t LineDelta = int64_t(Row.Line) - LastLine;
383 if (!Row.EndSequence) {
386 Section.OS.write(EncodingBuffer.c_str(), EncodingBuffer.size());
387 EncodingBuffer.resize(0);
390 RowsSinceLastSequence++;
393 Section.emitIntVal(dwarf::DW_LNS_advance_line, 1);
397 Section.emitIntVal(dwarf::DW_LNS_advance_pc, 1);
401 std::numeric_limits<int64_t>::max(), 0,
403 Section.OS.write(EncodingBuffer.c_str(), EncodingBuffer.size());
404 EncodingBuffer.resize(0);
406 LastLine = FileNum = IsStatement = 1;
411 if (RowsSinceLastSequence) {
414 Section.OS.write(EncodingBuffer.c_str(), EncodingBuffer.size());
415 EncodingBuffer.resize(0);
422 std::unique_ptr<MCRegisterInfo> MRI;
423 std::unique_ptr<MCAsmInfo> MAI;
424 std::unique_ptr<MCContext> MC;
425 std::unique_ptr<MCSubtargetInfo> MSTI;