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