xref: /freebsd-src/contrib/llvm-project/llvm/lib/DWARFLinker/Parallel/DebugLineSectionEmitter.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
11db9f3b2SDimitry Andric //===- DebugLineSectionEmitter.h --------------------------------*- C++ -*-===//
21db9f3b2SDimitry Andric //
31db9f3b2SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
41db9f3b2SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
51db9f3b2SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
61db9f3b2SDimitry Andric //
71db9f3b2SDimitry Andric //===----------------------------------------------------------------------===//
81db9f3b2SDimitry Andric 
91db9f3b2SDimitry Andric #ifndef LLVM_LIB_DWARFLINKER_PARALLEL_DEBUGLINESECTIONEMITTER_H
101db9f3b2SDimitry Andric #define LLVM_LIB_DWARFLINKER_PARALLEL_DEBUGLINESECTIONEMITTER_H
111db9f3b2SDimitry Andric 
121db9f3b2SDimitry Andric #include "DWARFEmitterImpl.h"
131db9f3b2SDimitry Andric #include "llvm/DWARFLinker/AddressesMap.h"
141db9f3b2SDimitry Andric #include "llvm/DWARFLinker/Parallel/DWARFLinker.h"
151db9f3b2SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFObject.h"
161db9f3b2SDimitry Andric #include "llvm/MC/MCTargetOptionsCommandFlags.h"
171db9f3b2SDimitry Andric #include "llvm/MC/TargetRegistry.h"
181db9f3b2SDimitry Andric 
191db9f3b2SDimitry Andric namespace llvm {
201db9f3b2SDimitry Andric namespace dwarf_linker {
211db9f3b2SDimitry Andric namespace parallel {
221db9f3b2SDimitry Andric 
231db9f3b2SDimitry Andric /// This class emits specified line table into the .debug_line section.
241db9f3b2SDimitry Andric class DebugLineSectionEmitter {
251db9f3b2SDimitry Andric public:
261db9f3b2SDimitry Andric   DebugLineSectionEmitter(const Triple &TheTriple, DwarfUnit &U)
271db9f3b2SDimitry Andric       : TheTriple(TheTriple), U(U) {}
281db9f3b2SDimitry Andric 
291db9f3b2SDimitry Andric   Error emit(const DWARFDebugLine::LineTable &LineTable) {
301db9f3b2SDimitry Andric     // FIXME: remove dependence on MCDwarfLineAddr::encode.
311db9f3b2SDimitry Andric     // As we reuse MCDwarfLineAddr::encode, we need to create/initialize
321db9f3b2SDimitry Andric     // some MC* classes.
331db9f3b2SDimitry Andric     if (Error Err = init(TheTriple))
341db9f3b2SDimitry Andric       return Err;
351db9f3b2SDimitry Andric 
361db9f3b2SDimitry Andric     // Get descriptor for output .debug_line section.
371db9f3b2SDimitry Andric     SectionDescriptor &OutSection =
381db9f3b2SDimitry Andric         U.getOrCreateSectionDescriptor(DebugSectionKind::DebugLine);
391db9f3b2SDimitry Andric 
401db9f3b2SDimitry Andric     // unit_length.
411db9f3b2SDimitry Andric     OutSection.emitUnitLength(0xBADDEF);
421db9f3b2SDimitry Andric     uint64_t OffsetAfterUnitLength = OutSection.OS.tell();
431db9f3b2SDimitry Andric 
441db9f3b2SDimitry Andric     // Emit prologue.
451db9f3b2SDimitry Andric     emitLineTablePrologue(LineTable.Prologue, OutSection);
461db9f3b2SDimitry Andric 
471db9f3b2SDimitry Andric     // Emit rows.
481db9f3b2SDimitry Andric     emitLineTableRows(LineTable, OutSection);
491db9f3b2SDimitry Andric     uint64_t OffsetAfterEnd = OutSection.OS.tell();
501db9f3b2SDimitry Andric 
511db9f3b2SDimitry Andric     // Update unit length field with actual length value.
521db9f3b2SDimitry Andric     assert(OffsetAfterUnitLength -
531db9f3b2SDimitry Andric                OutSection.getFormParams().getDwarfOffsetByteSize() <
541db9f3b2SDimitry Andric            OffsetAfterUnitLength);
551db9f3b2SDimitry Andric     OutSection.apply(OffsetAfterUnitLength -
561db9f3b2SDimitry Andric                          OutSection.getFormParams().getDwarfOffsetByteSize(),
571db9f3b2SDimitry Andric                      dwarf::DW_FORM_sec_offset,
581db9f3b2SDimitry Andric                      OffsetAfterEnd - OffsetAfterUnitLength);
591db9f3b2SDimitry Andric 
601db9f3b2SDimitry Andric     return Error::success();
611db9f3b2SDimitry Andric   }
621db9f3b2SDimitry Andric 
631db9f3b2SDimitry Andric private:
641db9f3b2SDimitry Andric   Error init(Triple TheTriple) {
651db9f3b2SDimitry Andric     std::string ErrorStr;
661db9f3b2SDimitry Andric     std::string TripleName;
671db9f3b2SDimitry Andric 
681db9f3b2SDimitry Andric     // Get the target.
691db9f3b2SDimitry Andric     const Target *TheTarget =
701db9f3b2SDimitry Andric         TargetRegistry::lookupTarget(TripleName, TheTriple, ErrorStr);
711db9f3b2SDimitry Andric     if (!TheTarget)
721db9f3b2SDimitry Andric       return createStringError(std::errc::invalid_argument, ErrorStr.c_str());
731db9f3b2SDimitry Andric     TripleName = TheTriple.getTriple();
741db9f3b2SDimitry Andric 
751db9f3b2SDimitry Andric     // Create all the MC Objects.
761db9f3b2SDimitry Andric     MRI.reset(TheTarget->createMCRegInfo(TripleName));
771db9f3b2SDimitry Andric     if (!MRI)
781db9f3b2SDimitry Andric       return createStringError(std::errc::invalid_argument,
791db9f3b2SDimitry Andric                                "no register info for target %s",
801db9f3b2SDimitry Andric                                TripleName.c_str());
811db9f3b2SDimitry Andric 
821db9f3b2SDimitry Andric     MCTargetOptions MCOptions = mc::InitMCTargetOptionsFromFlags();
831db9f3b2SDimitry Andric     MAI.reset(TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions));
841db9f3b2SDimitry Andric     if (!MAI)
851db9f3b2SDimitry Andric       return createStringError(std::errc::invalid_argument,
861db9f3b2SDimitry Andric                                "no asm info for target %s", TripleName.c_str());
871db9f3b2SDimitry Andric 
881db9f3b2SDimitry Andric     MSTI.reset(TheTarget->createMCSubtargetInfo(TripleName, "", ""));
891db9f3b2SDimitry Andric     if (!MSTI)
901db9f3b2SDimitry Andric       return createStringError(std::errc::invalid_argument,
911db9f3b2SDimitry Andric                                "no subtarget info for target %s",
921db9f3b2SDimitry Andric                                TripleName.c_str());
931db9f3b2SDimitry Andric 
941db9f3b2SDimitry Andric     MC.reset(new MCContext(TheTriple, MAI.get(), MRI.get(), MSTI.get(), nullptr,
951db9f3b2SDimitry Andric                            nullptr, true, "__DWARF"));
961db9f3b2SDimitry Andric 
971db9f3b2SDimitry Andric     return Error::success();
981db9f3b2SDimitry Andric   }
991db9f3b2SDimitry Andric 
1001db9f3b2SDimitry Andric   void emitLineTablePrologue(const DWARFDebugLine::Prologue &P,
1011db9f3b2SDimitry Andric                              SectionDescriptor &Section) {
1021db9f3b2SDimitry Andric     // version (uhalf).
1031db9f3b2SDimitry Andric     Section.emitIntVal(P.getVersion(), 2);
1041db9f3b2SDimitry Andric     if (P.getVersion() == 5) {
1051db9f3b2SDimitry Andric       // address_size (ubyte).
1061db9f3b2SDimitry Andric       Section.emitIntVal(P.getAddressSize(), 1);
1071db9f3b2SDimitry Andric 
1081db9f3b2SDimitry Andric       // segment_selector_size (ubyte).
1091db9f3b2SDimitry Andric       Section.emitIntVal(P.SegSelectorSize, 1);
1101db9f3b2SDimitry Andric     }
1111db9f3b2SDimitry Andric 
1121db9f3b2SDimitry Andric     // header_length.
1131db9f3b2SDimitry Andric     Section.emitOffset(0xBADDEF);
1141db9f3b2SDimitry Andric 
1151db9f3b2SDimitry Andric     uint64_t OffsetAfterPrologueLength = Section.OS.tell();
1161db9f3b2SDimitry Andric     emitLineTableProloguePayload(P, Section);
1171db9f3b2SDimitry Andric     uint64_t OffsetAfterPrologueEnd = Section.OS.tell();
1181db9f3b2SDimitry Andric 
1191db9f3b2SDimitry Andric     // Update prologue length field with actual length value.
1201db9f3b2SDimitry Andric     Section.apply(OffsetAfterPrologueLength -
1211db9f3b2SDimitry Andric                       Section.getFormParams().getDwarfOffsetByteSize(),
1221db9f3b2SDimitry Andric                   dwarf::DW_FORM_sec_offset,
1231db9f3b2SDimitry Andric                   OffsetAfterPrologueEnd - OffsetAfterPrologueLength);
1241db9f3b2SDimitry Andric   }
1251db9f3b2SDimitry Andric 
1261db9f3b2SDimitry Andric   void
1271db9f3b2SDimitry Andric   emitLineTablePrologueV2IncludeAndFileTable(const DWARFDebugLine::Prologue &P,
1281db9f3b2SDimitry Andric                                              SectionDescriptor &Section) {
1291db9f3b2SDimitry Andric     // include_directories (sequence of path names).
1301db9f3b2SDimitry Andric     for (const DWARFFormValue &Include : P.IncludeDirectories) {
1311db9f3b2SDimitry Andric       std::optional<const char *> IncludeStr = dwarf::toString(Include);
1321db9f3b2SDimitry Andric       if (!IncludeStr) {
1331db9f3b2SDimitry Andric         U.warn("cann't read string from line table.");
1341db9f3b2SDimitry Andric         return;
1351db9f3b2SDimitry Andric       }
1361db9f3b2SDimitry Andric 
1371db9f3b2SDimitry Andric       Section.emitString(Include.getForm(), *IncludeStr);
1381db9f3b2SDimitry Andric     }
1391db9f3b2SDimitry Andric     // The last entry is followed by a single null byte.
1401db9f3b2SDimitry Andric     Section.emitIntVal(0, 1);
1411db9f3b2SDimitry Andric 
1421db9f3b2SDimitry Andric     // file_names (sequence of file entries).
1431db9f3b2SDimitry Andric     for (const DWARFDebugLine::FileNameEntry &File : P.FileNames) {
1441db9f3b2SDimitry Andric       std::optional<const char *> FileNameStr = dwarf::toString(File.Name);
1451db9f3b2SDimitry Andric       if (!FileNameStr) {
1461db9f3b2SDimitry Andric         U.warn("cann't read string from line table.");
1471db9f3b2SDimitry Andric         return;
1481db9f3b2SDimitry Andric       }
1491db9f3b2SDimitry Andric 
1501db9f3b2SDimitry Andric       // A null-terminated string containing the full or relative path name of a
1511db9f3b2SDimitry Andric       // source file.
1521db9f3b2SDimitry Andric       Section.emitString(File.Name.getForm(), *FileNameStr);
1531db9f3b2SDimitry Andric 
1541db9f3b2SDimitry Andric       // An unsigned LEB128 number representing the directory index of a
1551db9f3b2SDimitry Andric       // directory in the include_directories section.
1561db9f3b2SDimitry Andric       encodeULEB128(File.DirIdx, Section.OS);
1571db9f3b2SDimitry Andric       // An unsigned LEB128 number representing the (implementation-defined)
1581db9f3b2SDimitry Andric       // time of last modification for the file, or 0 if not available.
1591db9f3b2SDimitry Andric       encodeULEB128(File.ModTime, Section.OS);
1601db9f3b2SDimitry Andric       // An unsigned LEB128 number representing the length in bytes of the file,
1611db9f3b2SDimitry Andric       // or 0 if not available.
1621db9f3b2SDimitry Andric       encodeULEB128(File.Length, Section.OS);
1631db9f3b2SDimitry Andric     }
1641db9f3b2SDimitry Andric     // The last entry is followed by a single null byte.
1651db9f3b2SDimitry Andric     Section.emitIntVal(0, 1);
1661db9f3b2SDimitry Andric   }
1671db9f3b2SDimitry Andric 
1681db9f3b2SDimitry Andric   void
1691db9f3b2SDimitry Andric   emitLineTablePrologueV5IncludeAndFileTable(const DWARFDebugLine::Prologue &P,
1701db9f3b2SDimitry Andric                                              SectionDescriptor &Section) {
1711db9f3b2SDimitry Andric     if (P.IncludeDirectories.empty()) {
1721db9f3b2SDimitry Andric       // directory_entry_format_count(ubyte).
1731db9f3b2SDimitry Andric       Section.emitIntVal(0, 1);
1741db9f3b2SDimitry Andric     } else {
1751db9f3b2SDimitry Andric       // directory_entry_format_count(ubyte).
1761db9f3b2SDimitry Andric       Section.emitIntVal(1, 1);
1771db9f3b2SDimitry Andric 
1781db9f3b2SDimitry Andric       // directory_entry_format (sequence of ULEB128 pairs).
1791db9f3b2SDimitry Andric       encodeULEB128(dwarf::DW_LNCT_path, Section.OS);
1801db9f3b2SDimitry Andric       encodeULEB128(P.IncludeDirectories[0].getForm(), Section.OS);
1811db9f3b2SDimitry Andric     }
1821db9f3b2SDimitry Andric 
1831db9f3b2SDimitry Andric     // directories_count (ULEB128).
1841db9f3b2SDimitry Andric     encodeULEB128(P.IncludeDirectories.size(), Section.OS);
1851db9f3b2SDimitry Andric     // directories (sequence of directory names).
1861db9f3b2SDimitry Andric     for (auto Include : P.IncludeDirectories) {
1871db9f3b2SDimitry Andric       std::optional<const char *> IncludeStr = dwarf::toString(Include);
1881db9f3b2SDimitry Andric       if (!IncludeStr) {
1891db9f3b2SDimitry Andric         U.warn("cann't read string from line table.");
1901db9f3b2SDimitry Andric         return;
1911db9f3b2SDimitry Andric       }
1921db9f3b2SDimitry Andric 
1931db9f3b2SDimitry Andric       Section.emitString(Include.getForm(), *IncludeStr);
1941db9f3b2SDimitry Andric     }
1951db9f3b2SDimitry Andric 
196297eecfbSDimitry Andric     bool HasChecksums = P.ContentTypes.HasMD5;
197297eecfbSDimitry Andric     bool HasInlineSources = P.ContentTypes.HasSource;
198297eecfbSDimitry Andric 
199297eecfbSDimitry Andric     dwarf::Form FileNameForm = dwarf::DW_FORM_string;
200297eecfbSDimitry Andric     dwarf::Form LLVMSourceForm = dwarf::DW_FORM_string;
201297eecfbSDimitry Andric 
2021db9f3b2SDimitry Andric     if (P.FileNames.empty()) {
2031db9f3b2SDimitry Andric       // file_name_entry_format_count (ubyte).
2041db9f3b2SDimitry Andric       Section.emitIntVal(0, 1);
2051db9f3b2SDimitry Andric     } else {
206297eecfbSDimitry Andric       FileNameForm = P.FileNames[0].Name.getForm();
207297eecfbSDimitry Andric       LLVMSourceForm = P.FileNames[0].Source.getForm();
208297eecfbSDimitry Andric 
2091db9f3b2SDimitry Andric       // file_name_entry_format_count (ubyte).
210297eecfbSDimitry Andric       Section.emitIntVal(
211297eecfbSDimitry Andric           2 + (HasChecksums ? 1 : 0) + (HasInlineSources ? 1 : 0), 1);
2121db9f3b2SDimitry Andric 
2131db9f3b2SDimitry Andric       // file_name_entry_format (sequence of ULEB128 pairs).
2141db9f3b2SDimitry Andric       encodeULEB128(dwarf::DW_LNCT_path, Section.OS);
215297eecfbSDimitry Andric       encodeULEB128(FileNameForm, Section.OS);
2161db9f3b2SDimitry Andric 
2171db9f3b2SDimitry Andric       encodeULEB128(dwarf::DW_LNCT_directory_index, Section.OS);
2181db9f3b2SDimitry Andric       encodeULEB128(dwarf::DW_FORM_data1, Section.OS);
2191db9f3b2SDimitry Andric 
220297eecfbSDimitry Andric       if (HasChecksums) {
2211db9f3b2SDimitry Andric         encodeULEB128(dwarf::DW_LNCT_MD5, Section.OS);
2221db9f3b2SDimitry Andric         encodeULEB128(dwarf::DW_FORM_data16, Section.OS);
2231db9f3b2SDimitry Andric       }
224297eecfbSDimitry Andric 
225297eecfbSDimitry Andric       if (HasInlineSources) {
226297eecfbSDimitry Andric         encodeULEB128(dwarf::DW_LNCT_LLVM_source, Section.OS);
227297eecfbSDimitry Andric         encodeULEB128(LLVMSourceForm, Section.OS);
228297eecfbSDimitry Andric       }
2291db9f3b2SDimitry Andric     }
2301db9f3b2SDimitry Andric 
2311db9f3b2SDimitry Andric     // file_names_count (ULEB128).
2321db9f3b2SDimitry Andric     encodeULEB128(P.FileNames.size(), Section.OS);
2331db9f3b2SDimitry Andric 
2341db9f3b2SDimitry Andric     // file_names (sequence of file name entries).
2351db9f3b2SDimitry Andric     for (auto File : P.FileNames) {
2361db9f3b2SDimitry Andric       std::optional<const char *> FileNameStr = dwarf::toString(File.Name);
2371db9f3b2SDimitry Andric       if (!FileNameStr) {
2381db9f3b2SDimitry Andric         U.warn("cann't read string from line table.");
2391db9f3b2SDimitry Andric         return;
2401db9f3b2SDimitry Andric       }
2411db9f3b2SDimitry Andric 
2421db9f3b2SDimitry Andric       // A null-terminated string containing the full or relative path name of a
2431db9f3b2SDimitry Andric       // source file.
244297eecfbSDimitry Andric       Section.emitString(FileNameForm, *FileNameStr);
2451db9f3b2SDimitry Andric       Section.emitIntVal(File.DirIdx, 1);
2461db9f3b2SDimitry Andric 
247297eecfbSDimitry Andric       if (HasChecksums) {
248297eecfbSDimitry Andric         assert((File.Checksum.size() == 16) &&
249297eecfbSDimitry Andric                "checksum size is not equal to 16 bytes.");
2501db9f3b2SDimitry Andric         Section.emitBinaryData(
2511db9f3b2SDimitry Andric             StringRef(reinterpret_cast<const char *>(File.Checksum.data()),
2521db9f3b2SDimitry Andric                       File.Checksum.size()));
2531db9f3b2SDimitry Andric       }
254297eecfbSDimitry Andric 
255297eecfbSDimitry Andric       if (HasInlineSources) {
256297eecfbSDimitry Andric         std::optional<const char *> FileSourceStr =
257297eecfbSDimitry Andric             dwarf::toString(File.Source);
258297eecfbSDimitry Andric         if (!FileSourceStr) {
259297eecfbSDimitry Andric           U.warn("cann't read string from line table.");
260297eecfbSDimitry Andric           return;
261297eecfbSDimitry Andric         }
262297eecfbSDimitry Andric 
263297eecfbSDimitry Andric         Section.emitString(LLVMSourceForm, *FileSourceStr);
264297eecfbSDimitry Andric       }
2651db9f3b2SDimitry Andric     }
2661db9f3b2SDimitry Andric   }
2671db9f3b2SDimitry Andric 
2681db9f3b2SDimitry Andric   void emitLineTableProloguePayload(const DWARFDebugLine::Prologue &P,
2691db9f3b2SDimitry Andric                                     SectionDescriptor &Section) {
2701db9f3b2SDimitry Andric     // minimum_instruction_length (ubyte).
2711db9f3b2SDimitry Andric     Section.emitIntVal(P.MinInstLength, 1);
2721db9f3b2SDimitry Andric     if (P.FormParams.Version >= 4) {
2731db9f3b2SDimitry Andric       // maximum_operations_per_instruction (ubyte).
2741db9f3b2SDimitry Andric       Section.emitIntVal(P.MaxOpsPerInst, 1);
2751db9f3b2SDimitry Andric     }
2761db9f3b2SDimitry Andric     // default_is_stmt (ubyte).
2771db9f3b2SDimitry Andric     Section.emitIntVal(P.DefaultIsStmt, 1);
2781db9f3b2SDimitry Andric     // line_base (sbyte).
2791db9f3b2SDimitry Andric     Section.emitIntVal(P.LineBase, 1);
2801db9f3b2SDimitry Andric     // line_range (ubyte).
2811db9f3b2SDimitry Andric     Section.emitIntVal(P.LineRange, 1);
2821db9f3b2SDimitry Andric     // opcode_base (ubyte).
2831db9f3b2SDimitry Andric     Section.emitIntVal(P.OpcodeBase, 1);
2841db9f3b2SDimitry Andric 
2851db9f3b2SDimitry Andric     // standard_opcode_lengths (array of ubyte).
2861db9f3b2SDimitry Andric     for (auto Length : P.StandardOpcodeLengths)
2871db9f3b2SDimitry Andric       Section.emitIntVal(Length, 1);
2881db9f3b2SDimitry Andric 
2891db9f3b2SDimitry Andric     if (P.FormParams.Version < 5)
2901db9f3b2SDimitry Andric       emitLineTablePrologueV2IncludeAndFileTable(P, Section);
2911db9f3b2SDimitry Andric     else
2921db9f3b2SDimitry Andric       emitLineTablePrologueV5IncludeAndFileTable(P, Section);
2931db9f3b2SDimitry Andric   }
2941db9f3b2SDimitry Andric 
2951db9f3b2SDimitry Andric   void emitLineTableRows(const DWARFDebugLine::LineTable &LineTable,
2961db9f3b2SDimitry Andric                          SectionDescriptor &Section) {
2971db9f3b2SDimitry Andric 
2981db9f3b2SDimitry Andric     MCDwarfLineTableParams Params;
2991db9f3b2SDimitry Andric     Params.DWARF2LineOpcodeBase = LineTable.Prologue.OpcodeBase;
3001db9f3b2SDimitry Andric     Params.DWARF2LineBase = LineTable.Prologue.LineBase;
3011db9f3b2SDimitry Andric     Params.DWARF2LineRange = LineTable.Prologue.LineRange;
3021db9f3b2SDimitry Andric 
3031db9f3b2SDimitry Andric     SmallString<128> EncodingBuffer;
3041db9f3b2SDimitry Andric 
3051db9f3b2SDimitry Andric     if (LineTable.Rows.empty()) {
3061db9f3b2SDimitry Andric       // We only have the dummy entry, dsymutil emits an entry with a 0
3071db9f3b2SDimitry Andric       // address in that case.
3081db9f3b2SDimitry Andric       MCDwarfLineAddr::encode(*MC, Params, std::numeric_limits<int64_t>::max(),
3091db9f3b2SDimitry Andric                               0, EncodingBuffer);
3101db9f3b2SDimitry Andric       Section.OS.write(EncodingBuffer.c_str(), EncodingBuffer.size());
3111db9f3b2SDimitry Andric       return;
3121db9f3b2SDimitry Andric     }
3131db9f3b2SDimitry Andric 
3141db9f3b2SDimitry Andric     // Line table state machine fields
3151db9f3b2SDimitry Andric     unsigned FileNum = 1;
3161db9f3b2SDimitry Andric     unsigned LastLine = 1;
3171db9f3b2SDimitry Andric     unsigned Column = 0;
318*0fca6ea1SDimitry Andric     unsigned Discriminator = 0;
3191db9f3b2SDimitry Andric     unsigned IsStatement = 1;
3201db9f3b2SDimitry Andric     unsigned Isa = 0;
3211db9f3b2SDimitry Andric     uint64_t Address = -1ULL;
3221db9f3b2SDimitry Andric 
3231db9f3b2SDimitry Andric     unsigned RowsSinceLastSequence = 0;
3241db9f3b2SDimitry Andric 
3251db9f3b2SDimitry Andric     for (const DWARFDebugLine::Row &Row : LineTable.Rows) {
3261db9f3b2SDimitry Andric       int64_t AddressDelta;
3271db9f3b2SDimitry Andric       if (Address == -1ULL) {
3281db9f3b2SDimitry Andric         Section.emitIntVal(dwarf::DW_LNS_extended_op, 1);
3291db9f3b2SDimitry Andric         encodeULEB128(Section.getFormParams().AddrSize + 1, Section.OS);
3301db9f3b2SDimitry Andric         Section.emitIntVal(dwarf::DW_LNE_set_address, 1);
3311db9f3b2SDimitry Andric         Section.emitIntVal(Row.Address.Address,
3321db9f3b2SDimitry Andric                            Section.getFormParams().AddrSize);
3331db9f3b2SDimitry Andric         AddressDelta = 0;
3341db9f3b2SDimitry Andric       } else {
3351db9f3b2SDimitry Andric         AddressDelta =
3361db9f3b2SDimitry Andric             (Row.Address.Address - Address) / LineTable.Prologue.MinInstLength;
3371db9f3b2SDimitry Andric       }
3381db9f3b2SDimitry Andric 
3391db9f3b2SDimitry Andric       // FIXME: code copied and transformed from
3401db9f3b2SDimitry Andric       // MCDwarf.cpp::EmitDwarfLineTable. We should find a way to share this
3411db9f3b2SDimitry Andric       // code, but the current compatibility requirement with classic dsymutil
3421db9f3b2SDimitry Andric       // makes it hard. Revisit that once this requirement is dropped.
3431db9f3b2SDimitry Andric 
3441db9f3b2SDimitry Andric       if (FileNum != Row.File) {
3451db9f3b2SDimitry Andric         FileNum = Row.File;
3461db9f3b2SDimitry Andric         Section.emitIntVal(dwarf::DW_LNS_set_file, 1);
3471db9f3b2SDimitry Andric         encodeULEB128(FileNum, Section.OS);
3481db9f3b2SDimitry Andric       }
3491db9f3b2SDimitry Andric       if (Column != Row.Column) {
3501db9f3b2SDimitry Andric         Column = Row.Column;
3511db9f3b2SDimitry Andric         Section.emitIntVal(dwarf::DW_LNS_set_column, 1);
3521db9f3b2SDimitry Andric         encodeULEB128(Column, Section.OS);
3531db9f3b2SDimitry Andric       }
354*0fca6ea1SDimitry Andric       if (Discriminator != Row.Discriminator && MC->getDwarfVersion() >= 4) {
355*0fca6ea1SDimitry Andric         Discriminator = Row.Discriminator;
356*0fca6ea1SDimitry Andric         unsigned Size = getULEB128Size(Discriminator);
357*0fca6ea1SDimitry Andric         Section.emitIntVal(dwarf::DW_LNS_extended_op, 1);
358*0fca6ea1SDimitry Andric         encodeULEB128(Size + 1, Section.OS);
359*0fca6ea1SDimitry Andric         Section.emitIntVal(dwarf::DW_LNE_set_discriminator, 1);
360*0fca6ea1SDimitry Andric         encodeULEB128(Discriminator, Section.OS);
361*0fca6ea1SDimitry Andric       }
362*0fca6ea1SDimitry Andric       Discriminator = 0;
3631db9f3b2SDimitry Andric 
3641db9f3b2SDimitry Andric       if (Isa != Row.Isa) {
3651db9f3b2SDimitry Andric         Isa = Row.Isa;
3661db9f3b2SDimitry Andric         Section.emitIntVal(dwarf::DW_LNS_set_isa, 1);
3671db9f3b2SDimitry Andric         encodeULEB128(Isa, Section.OS);
3681db9f3b2SDimitry Andric       }
3691db9f3b2SDimitry Andric       if (IsStatement != Row.IsStmt) {
3701db9f3b2SDimitry Andric         IsStatement = Row.IsStmt;
3711db9f3b2SDimitry Andric         Section.emitIntVal(dwarf::DW_LNS_negate_stmt, 1);
3721db9f3b2SDimitry Andric       }
3731db9f3b2SDimitry Andric       if (Row.BasicBlock)
3741db9f3b2SDimitry Andric         Section.emitIntVal(dwarf::DW_LNS_set_basic_block, 1);
3751db9f3b2SDimitry Andric 
3761db9f3b2SDimitry Andric       if (Row.PrologueEnd)
3771db9f3b2SDimitry Andric         Section.emitIntVal(dwarf::DW_LNS_set_prologue_end, 1);
3781db9f3b2SDimitry Andric 
3791db9f3b2SDimitry Andric       if (Row.EpilogueBegin)
3801db9f3b2SDimitry Andric         Section.emitIntVal(dwarf::DW_LNS_set_epilogue_begin, 1);
3811db9f3b2SDimitry Andric 
3821db9f3b2SDimitry Andric       int64_t LineDelta = int64_t(Row.Line) - LastLine;
3831db9f3b2SDimitry Andric       if (!Row.EndSequence) {
3841db9f3b2SDimitry Andric         MCDwarfLineAddr::encode(*MC, Params, LineDelta, AddressDelta,
3851db9f3b2SDimitry Andric                                 EncodingBuffer);
3861db9f3b2SDimitry Andric         Section.OS.write(EncodingBuffer.c_str(), EncodingBuffer.size());
3871db9f3b2SDimitry Andric         EncodingBuffer.resize(0);
3881db9f3b2SDimitry Andric         Address = Row.Address.Address;
3891db9f3b2SDimitry Andric         LastLine = Row.Line;
3901db9f3b2SDimitry Andric         RowsSinceLastSequence++;
3911db9f3b2SDimitry Andric       } else {
3921db9f3b2SDimitry Andric         if (LineDelta) {
3931db9f3b2SDimitry Andric           Section.emitIntVal(dwarf::DW_LNS_advance_line, 1);
3941db9f3b2SDimitry Andric           encodeSLEB128(LineDelta, Section.OS);
3951db9f3b2SDimitry Andric         }
3961db9f3b2SDimitry Andric         if (AddressDelta) {
3971db9f3b2SDimitry Andric           Section.emitIntVal(dwarf::DW_LNS_advance_pc, 1);
3981db9f3b2SDimitry Andric           encodeULEB128(AddressDelta, Section.OS);
3991db9f3b2SDimitry Andric         }
4001db9f3b2SDimitry Andric         MCDwarfLineAddr::encode(*MC, Params,
4011db9f3b2SDimitry Andric                                 std::numeric_limits<int64_t>::max(), 0,
4021db9f3b2SDimitry Andric                                 EncodingBuffer);
4031db9f3b2SDimitry Andric         Section.OS.write(EncodingBuffer.c_str(), EncodingBuffer.size());
4041db9f3b2SDimitry Andric         EncodingBuffer.resize(0);
4051db9f3b2SDimitry Andric         Address = -1ULL;
4061db9f3b2SDimitry Andric         LastLine = FileNum = IsStatement = 1;
407*0fca6ea1SDimitry Andric         RowsSinceLastSequence = Column = Discriminator = Isa = 0;
4081db9f3b2SDimitry Andric       }
4091db9f3b2SDimitry Andric     }
4101db9f3b2SDimitry Andric 
4111db9f3b2SDimitry Andric     if (RowsSinceLastSequence) {
4121db9f3b2SDimitry Andric       MCDwarfLineAddr::encode(*MC, Params, std::numeric_limits<int64_t>::max(),
4131db9f3b2SDimitry Andric                               0, EncodingBuffer);
4141db9f3b2SDimitry Andric       Section.OS.write(EncodingBuffer.c_str(), EncodingBuffer.size());
4151db9f3b2SDimitry Andric       EncodingBuffer.resize(0);
4161db9f3b2SDimitry Andric     }
4171db9f3b2SDimitry Andric   }
4181db9f3b2SDimitry Andric 
4191db9f3b2SDimitry Andric   Triple TheTriple;
4201db9f3b2SDimitry Andric   DwarfUnit &U;
4211db9f3b2SDimitry Andric 
4221db9f3b2SDimitry Andric   std::unique_ptr<MCRegisterInfo> MRI;
4231db9f3b2SDimitry Andric   std::unique_ptr<MCAsmInfo> MAI;
4241db9f3b2SDimitry Andric   std::unique_ptr<MCContext> MC;
4251db9f3b2SDimitry Andric   std::unique_ptr<MCSubtargetInfo> MSTI;
4261db9f3b2SDimitry Andric };
4271db9f3b2SDimitry Andric 
4281db9f3b2SDimitry Andric } // end of namespace parallel
4291db9f3b2SDimitry Andric } // end of namespace dwarf_linker
4301db9f3b2SDimitry Andric } // end of namespace llvm
4311db9f3b2SDimitry Andric 
4321db9f3b2SDimitry Andric #endif // LLVM_LIB_DWARFLINKER_PARALLEL_DEBUGLINESECTIONEMITTER_H
433