1*1db9f3b2SDimitry Andric //===- DebugLineSectionEmitter.h --------------------------------*- C++ -*-===// 2*1db9f3b2SDimitry Andric // 3*1db9f3b2SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*1db9f3b2SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*1db9f3b2SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*1db9f3b2SDimitry Andric // 7*1db9f3b2SDimitry Andric //===----------------------------------------------------------------------===// 8*1db9f3b2SDimitry Andric 9*1db9f3b2SDimitry Andric #ifndef LLVM_LIB_DWARFLINKER_PARALLEL_DEBUGLINESECTIONEMITTER_H 10*1db9f3b2SDimitry Andric #define LLVM_LIB_DWARFLINKER_PARALLEL_DEBUGLINESECTIONEMITTER_H 11*1db9f3b2SDimitry Andric 12*1db9f3b2SDimitry Andric #include "DWARFEmitterImpl.h" 13*1db9f3b2SDimitry Andric #include "llvm/DWARFLinker/AddressesMap.h" 14*1db9f3b2SDimitry Andric #include "llvm/DWARFLinker/Parallel/DWARFLinker.h" 15*1db9f3b2SDimitry Andric #include "llvm/DebugInfo/DWARF/DWARFObject.h" 16*1db9f3b2SDimitry Andric #include "llvm/MC/MCTargetOptionsCommandFlags.h" 17*1db9f3b2SDimitry Andric #include "llvm/MC/TargetRegistry.h" 18*1db9f3b2SDimitry Andric 19*1db9f3b2SDimitry Andric namespace llvm { 20*1db9f3b2SDimitry Andric namespace dwarf_linker { 21*1db9f3b2SDimitry Andric namespace parallel { 22*1db9f3b2SDimitry Andric 23*1db9f3b2SDimitry Andric /// This class emits specified line table into the .debug_line section. 24*1db9f3b2SDimitry Andric class DebugLineSectionEmitter { 25*1db9f3b2SDimitry Andric public: 26*1db9f3b2SDimitry Andric DebugLineSectionEmitter(const Triple &TheTriple, DwarfUnit &U) 27*1db9f3b2SDimitry Andric : TheTriple(TheTriple), U(U) {} 28*1db9f3b2SDimitry Andric 29*1db9f3b2SDimitry Andric Error emit(const DWARFDebugLine::LineTable &LineTable) { 30*1db9f3b2SDimitry Andric // FIXME: remove dependence on MCDwarfLineAddr::encode. 31*1db9f3b2SDimitry Andric // As we reuse MCDwarfLineAddr::encode, we need to create/initialize 32*1db9f3b2SDimitry Andric // some MC* classes. 33*1db9f3b2SDimitry Andric if (Error Err = init(TheTriple)) 34*1db9f3b2SDimitry Andric return Err; 35*1db9f3b2SDimitry Andric 36*1db9f3b2SDimitry Andric // Get descriptor for output .debug_line section. 37*1db9f3b2SDimitry Andric SectionDescriptor &OutSection = 38*1db9f3b2SDimitry Andric U.getOrCreateSectionDescriptor(DebugSectionKind::DebugLine); 39*1db9f3b2SDimitry Andric 40*1db9f3b2SDimitry Andric // unit_length. 41*1db9f3b2SDimitry Andric OutSection.emitUnitLength(0xBADDEF); 42*1db9f3b2SDimitry Andric uint64_t OffsetAfterUnitLength = OutSection.OS.tell(); 43*1db9f3b2SDimitry Andric 44*1db9f3b2SDimitry Andric // Emit prologue. 45*1db9f3b2SDimitry Andric emitLineTablePrologue(LineTable.Prologue, OutSection); 46*1db9f3b2SDimitry Andric 47*1db9f3b2SDimitry Andric // Emit rows. 48*1db9f3b2SDimitry Andric emitLineTableRows(LineTable, OutSection); 49*1db9f3b2SDimitry Andric uint64_t OffsetAfterEnd = OutSection.OS.tell(); 50*1db9f3b2SDimitry Andric 51*1db9f3b2SDimitry Andric // Update unit length field with actual length value. 52*1db9f3b2SDimitry Andric assert(OffsetAfterUnitLength - 53*1db9f3b2SDimitry Andric OutSection.getFormParams().getDwarfOffsetByteSize() < 54*1db9f3b2SDimitry Andric OffsetAfterUnitLength); 55*1db9f3b2SDimitry Andric OutSection.apply(OffsetAfterUnitLength - 56*1db9f3b2SDimitry Andric OutSection.getFormParams().getDwarfOffsetByteSize(), 57*1db9f3b2SDimitry Andric dwarf::DW_FORM_sec_offset, 58*1db9f3b2SDimitry Andric OffsetAfterEnd - OffsetAfterUnitLength); 59*1db9f3b2SDimitry Andric 60*1db9f3b2SDimitry Andric return Error::success(); 61*1db9f3b2SDimitry Andric } 62*1db9f3b2SDimitry Andric 63*1db9f3b2SDimitry Andric private: 64*1db9f3b2SDimitry Andric Error init(Triple TheTriple) { 65*1db9f3b2SDimitry Andric std::string ErrorStr; 66*1db9f3b2SDimitry Andric std::string TripleName; 67*1db9f3b2SDimitry Andric 68*1db9f3b2SDimitry Andric // Get the target. 69*1db9f3b2SDimitry Andric const Target *TheTarget = 70*1db9f3b2SDimitry Andric TargetRegistry::lookupTarget(TripleName, TheTriple, ErrorStr); 71*1db9f3b2SDimitry Andric if (!TheTarget) 72*1db9f3b2SDimitry Andric return createStringError(std::errc::invalid_argument, ErrorStr.c_str()); 73*1db9f3b2SDimitry Andric TripleName = TheTriple.getTriple(); 74*1db9f3b2SDimitry Andric 75*1db9f3b2SDimitry Andric // Create all the MC Objects. 76*1db9f3b2SDimitry Andric MRI.reset(TheTarget->createMCRegInfo(TripleName)); 77*1db9f3b2SDimitry Andric if (!MRI) 78*1db9f3b2SDimitry Andric return createStringError(std::errc::invalid_argument, 79*1db9f3b2SDimitry Andric "no register info for target %s", 80*1db9f3b2SDimitry Andric TripleName.c_str()); 81*1db9f3b2SDimitry Andric 82*1db9f3b2SDimitry Andric MCTargetOptions MCOptions = mc::InitMCTargetOptionsFromFlags(); 83*1db9f3b2SDimitry Andric MAI.reset(TheTarget->createMCAsmInfo(*MRI, TripleName, MCOptions)); 84*1db9f3b2SDimitry Andric if (!MAI) 85*1db9f3b2SDimitry Andric return createStringError(std::errc::invalid_argument, 86*1db9f3b2SDimitry Andric "no asm info for target %s", TripleName.c_str()); 87*1db9f3b2SDimitry Andric 88*1db9f3b2SDimitry Andric MSTI.reset(TheTarget->createMCSubtargetInfo(TripleName, "", "")); 89*1db9f3b2SDimitry Andric if (!MSTI) 90*1db9f3b2SDimitry Andric return createStringError(std::errc::invalid_argument, 91*1db9f3b2SDimitry Andric "no subtarget info for target %s", 92*1db9f3b2SDimitry Andric TripleName.c_str()); 93*1db9f3b2SDimitry Andric 94*1db9f3b2SDimitry Andric MC.reset(new MCContext(TheTriple, MAI.get(), MRI.get(), MSTI.get(), nullptr, 95*1db9f3b2SDimitry Andric nullptr, true, "__DWARF")); 96*1db9f3b2SDimitry Andric 97*1db9f3b2SDimitry Andric return Error::success(); 98*1db9f3b2SDimitry Andric } 99*1db9f3b2SDimitry Andric 100*1db9f3b2SDimitry Andric void emitLineTablePrologue(const DWARFDebugLine::Prologue &P, 101*1db9f3b2SDimitry Andric SectionDescriptor &Section) { 102*1db9f3b2SDimitry Andric // version (uhalf). 103*1db9f3b2SDimitry Andric Section.emitIntVal(P.getVersion(), 2); 104*1db9f3b2SDimitry Andric if (P.getVersion() == 5) { 105*1db9f3b2SDimitry Andric // address_size (ubyte). 106*1db9f3b2SDimitry Andric Section.emitIntVal(P.getAddressSize(), 1); 107*1db9f3b2SDimitry Andric 108*1db9f3b2SDimitry Andric // segment_selector_size (ubyte). 109*1db9f3b2SDimitry Andric Section.emitIntVal(P.SegSelectorSize, 1); 110*1db9f3b2SDimitry Andric } 111*1db9f3b2SDimitry Andric 112*1db9f3b2SDimitry Andric // header_length. 113*1db9f3b2SDimitry Andric Section.emitOffset(0xBADDEF); 114*1db9f3b2SDimitry Andric 115*1db9f3b2SDimitry Andric uint64_t OffsetAfterPrologueLength = Section.OS.tell(); 116*1db9f3b2SDimitry Andric emitLineTableProloguePayload(P, Section); 117*1db9f3b2SDimitry Andric uint64_t OffsetAfterPrologueEnd = Section.OS.tell(); 118*1db9f3b2SDimitry Andric 119*1db9f3b2SDimitry Andric // Update prologue length field with actual length value. 120*1db9f3b2SDimitry Andric Section.apply(OffsetAfterPrologueLength - 121*1db9f3b2SDimitry Andric Section.getFormParams().getDwarfOffsetByteSize(), 122*1db9f3b2SDimitry Andric dwarf::DW_FORM_sec_offset, 123*1db9f3b2SDimitry Andric OffsetAfterPrologueEnd - OffsetAfterPrologueLength); 124*1db9f3b2SDimitry Andric } 125*1db9f3b2SDimitry Andric 126*1db9f3b2SDimitry Andric void 127*1db9f3b2SDimitry Andric emitLineTablePrologueV2IncludeAndFileTable(const DWARFDebugLine::Prologue &P, 128*1db9f3b2SDimitry Andric SectionDescriptor &Section) { 129*1db9f3b2SDimitry Andric // include_directories (sequence of path names). 130*1db9f3b2SDimitry Andric for (const DWARFFormValue &Include : P.IncludeDirectories) { 131*1db9f3b2SDimitry Andric std::optional<const char *> IncludeStr = dwarf::toString(Include); 132*1db9f3b2SDimitry Andric if (!IncludeStr) { 133*1db9f3b2SDimitry Andric U.warn("cann't read string from line table."); 134*1db9f3b2SDimitry Andric return; 135*1db9f3b2SDimitry Andric } 136*1db9f3b2SDimitry Andric 137*1db9f3b2SDimitry Andric Section.emitString(Include.getForm(), *IncludeStr); 138*1db9f3b2SDimitry Andric } 139*1db9f3b2SDimitry Andric // The last entry is followed by a single null byte. 140*1db9f3b2SDimitry Andric Section.emitIntVal(0, 1); 141*1db9f3b2SDimitry Andric 142*1db9f3b2SDimitry Andric // file_names (sequence of file entries). 143*1db9f3b2SDimitry Andric for (const DWARFDebugLine::FileNameEntry &File : P.FileNames) { 144*1db9f3b2SDimitry Andric std::optional<const char *> FileNameStr = dwarf::toString(File.Name); 145*1db9f3b2SDimitry Andric if (!FileNameStr) { 146*1db9f3b2SDimitry Andric U.warn("cann't read string from line table."); 147*1db9f3b2SDimitry Andric return; 148*1db9f3b2SDimitry Andric } 149*1db9f3b2SDimitry Andric 150*1db9f3b2SDimitry Andric // A null-terminated string containing the full or relative path name of a 151*1db9f3b2SDimitry Andric // source file. 152*1db9f3b2SDimitry Andric Section.emitString(File.Name.getForm(), *FileNameStr); 153*1db9f3b2SDimitry Andric 154*1db9f3b2SDimitry Andric // An unsigned LEB128 number representing the directory index of a 155*1db9f3b2SDimitry Andric // directory in the include_directories section. 156*1db9f3b2SDimitry Andric encodeULEB128(File.DirIdx, Section.OS); 157*1db9f3b2SDimitry Andric // An unsigned LEB128 number representing the (implementation-defined) 158*1db9f3b2SDimitry Andric // time of last modification for the file, or 0 if not available. 159*1db9f3b2SDimitry Andric encodeULEB128(File.ModTime, Section.OS); 160*1db9f3b2SDimitry Andric // An unsigned LEB128 number representing the length in bytes of the file, 161*1db9f3b2SDimitry Andric // or 0 if not available. 162*1db9f3b2SDimitry Andric encodeULEB128(File.Length, Section.OS); 163*1db9f3b2SDimitry Andric } 164*1db9f3b2SDimitry Andric // The last entry is followed by a single null byte. 165*1db9f3b2SDimitry Andric Section.emitIntVal(0, 1); 166*1db9f3b2SDimitry Andric } 167*1db9f3b2SDimitry Andric 168*1db9f3b2SDimitry Andric void 169*1db9f3b2SDimitry Andric emitLineTablePrologueV5IncludeAndFileTable(const DWARFDebugLine::Prologue &P, 170*1db9f3b2SDimitry Andric SectionDescriptor &Section) { 171*1db9f3b2SDimitry Andric if (P.IncludeDirectories.empty()) { 172*1db9f3b2SDimitry Andric // directory_entry_format_count(ubyte). 173*1db9f3b2SDimitry Andric Section.emitIntVal(0, 1); 174*1db9f3b2SDimitry Andric } else { 175*1db9f3b2SDimitry Andric // directory_entry_format_count(ubyte). 176*1db9f3b2SDimitry Andric Section.emitIntVal(1, 1); 177*1db9f3b2SDimitry Andric 178*1db9f3b2SDimitry Andric // directory_entry_format (sequence of ULEB128 pairs). 179*1db9f3b2SDimitry Andric encodeULEB128(dwarf::DW_LNCT_path, Section.OS); 180*1db9f3b2SDimitry Andric encodeULEB128(P.IncludeDirectories[0].getForm(), Section.OS); 181*1db9f3b2SDimitry Andric } 182*1db9f3b2SDimitry Andric 183*1db9f3b2SDimitry Andric // directories_count (ULEB128). 184*1db9f3b2SDimitry Andric encodeULEB128(P.IncludeDirectories.size(), Section.OS); 185*1db9f3b2SDimitry Andric // directories (sequence of directory names). 186*1db9f3b2SDimitry Andric for (auto Include : P.IncludeDirectories) { 187*1db9f3b2SDimitry Andric std::optional<const char *> IncludeStr = dwarf::toString(Include); 188*1db9f3b2SDimitry Andric if (!IncludeStr) { 189*1db9f3b2SDimitry Andric U.warn("cann't read string from line table."); 190*1db9f3b2SDimitry Andric return; 191*1db9f3b2SDimitry Andric } 192*1db9f3b2SDimitry Andric 193*1db9f3b2SDimitry Andric Section.emitString(Include.getForm(), *IncludeStr); 194*1db9f3b2SDimitry Andric } 195*1db9f3b2SDimitry Andric 196*1db9f3b2SDimitry Andric if (P.FileNames.empty()) { 197*1db9f3b2SDimitry Andric // file_name_entry_format_count (ubyte). 198*1db9f3b2SDimitry Andric Section.emitIntVal(0, 1); 199*1db9f3b2SDimitry Andric } else { 200*1db9f3b2SDimitry Andric // file_name_entry_format_count (ubyte). 201*1db9f3b2SDimitry Andric Section.emitIntVal(2 + (P.ContentTypes.HasMD5 ? 1 : 0), 1); 202*1db9f3b2SDimitry Andric 203*1db9f3b2SDimitry Andric // file_name_entry_format (sequence of ULEB128 pairs). 204*1db9f3b2SDimitry Andric encodeULEB128(dwarf::DW_LNCT_path, Section.OS); 205*1db9f3b2SDimitry Andric encodeULEB128(P.FileNames[0].Name.getForm(), Section.OS); 206*1db9f3b2SDimitry Andric 207*1db9f3b2SDimitry Andric encodeULEB128(dwarf::DW_LNCT_directory_index, Section.OS); 208*1db9f3b2SDimitry Andric encodeULEB128(dwarf::DW_FORM_data1, Section.OS); 209*1db9f3b2SDimitry Andric 210*1db9f3b2SDimitry Andric if (P.ContentTypes.HasMD5) { 211*1db9f3b2SDimitry Andric encodeULEB128(dwarf::DW_LNCT_MD5, Section.OS); 212*1db9f3b2SDimitry Andric encodeULEB128(dwarf::DW_FORM_data16, Section.OS); 213*1db9f3b2SDimitry Andric } 214*1db9f3b2SDimitry Andric } 215*1db9f3b2SDimitry Andric 216*1db9f3b2SDimitry Andric // file_names_count (ULEB128). 217*1db9f3b2SDimitry Andric encodeULEB128(P.FileNames.size(), Section.OS); 218*1db9f3b2SDimitry Andric 219*1db9f3b2SDimitry Andric // file_names (sequence of file name entries). 220*1db9f3b2SDimitry Andric for (auto File : P.FileNames) { 221*1db9f3b2SDimitry Andric std::optional<const char *> FileNameStr = dwarf::toString(File.Name); 222*1db9f3b2SDimitry Andric if (!FileNameStr) { 223*1db9f3b2SDimitry Andric U.warn("cann't read string from line table."); 224*1db9f3b2SDimitry Andric return; 225*1db9f3b2SDimitry Andric } 226*1db9f3b2SDimitry Andric 227*1db9f3b2SDimitry Andric // A null-terminated string containing the full or relative path name of a 228*1db9f3b2SDimitry Andric // source file. 229*1db9f3b2SDimitry Andric Section.emitString(File.Name.getForm(), *FileNameStr); 230*1db9f3b2SDimitry Andric Section.emitIntVal(File.DirIdx, 1); 231*1db9f3b2SDimitry Andric 232*1db9f3b2SDimitry Andric if (P.ContentTypes.HasMD5) { 233*1db9f3b2SDimitry Andric Section.emitBinaryData( 234*1db9f3b2SDimitry Andric StringRef(reinterpret_cast<const char *>(File.Checksum.data()), 235*1db9f3b2SDimitry Andric File.Checksum.size())); 236*1db9f3b2SDimitry Andric } 237*1db9f3b2SDimitry Andric } 238*1db9f3b2SDimitry Andric } 239*1db9f3b2SDimitry Andric 240*1db9f3b2SDimitry Andric void emitLineTableProloguePayload(const DWARFDebugLine::Prologue &P, 241*1db9f3b2SDimitry Andric SectionDescriptor &Section) { 242*1db9f3b2SDimitry Andric // minimum_instruction_length (ubyte). 243*1db9f3b2SDimitry Andric Section.emitIntVal(P.MinInstLength, 1); 244*1db9f3b2SDimitry Andric if (P.FormParams.Version >= 4) { 245*1db9f3b2SDimitry Andric // maximum_operations_per_instruction (ubyte). 246*1db9f3b2SDimitry Andric Section.emitIntVal(P.MaxOpsPerInst, 1); 247*1db9f3b2SDimitry Andric } 248*1db9f3b2SDimitry Andric // default_is_stmt (ubyte). 249*1db9f3b2SDimitry Andric Section.emitIntVal(P.DefaultIsStmt, 1); 250*1db9f3b2SDimitry Andric // line_base (sbyte). 251*1db9f3b2SDimitry Andric Section.emitIntVal(P.LineBase, 1); 252*1db9f3b2SDimitry Andric // line_range (ubyte). 253*1db9f3b2SDimitry Andric Section.emitIntVal(P.LineRange, 1); 254*1db9f3b2SDimitry Andric // opcode_base (ubyte). 255*1db9f3b2SDimitry Andric Section.emitIntVal(P.OpcodeBase, 1); 256*1db9f3b2SDimitry Andric 257*1db9f3b2SDimitry Andric // standard_opcode_lengths (array of ubyte). 258*1db9f3b2SDimitry Andric for (auto Length : P.StandardOpcodeLengths) 259*1db9f3b2SDimitry Andric Section.emitIntVal(Length, 1); 260*1db9f3b2SDimitry Andric 261*1db9f3b2SDimitry Andric if (P.FormParams.Version < 5) 262*1db9f3b2SDimitry Andric emitLineTablePrologueV2IncludeAndFileTable(P, Section); 263*1db9f3b2SDimitry Andric else 264*1db9f3b2SDimitry Andric emitLineTablePrologueV5IncludeAndFileTable(P, Section); 265*1db9f3b2SDimitry Andric } 266*1db9f3b2SDimitry Andric 267*1db9f3b2SDimitry Andric void emitLineTableRows(const DWARFDebugLine::LineTable &LineTable, 268*1db9f3b2SDimitry Andric SectionDescriptor &Section) { 269*1db9f3b2SDimitry Andric 270*1db9f3b2SDimitry Andric MCDwarfLineTableParams Params; 271*1db9f3b2SDimitry Andric Params.DWARF2LineOpcodeBase = LineTable.Prologue.OpcodeBase; 272*1db9f3b2SDimitry Andric Params.DWARF2LineBase = LineTable.Prologue.LineBase; 273*1db9f3b2SDimitry Andric Params.DWARF2LineRange = LineTable.Prologue.LineRange; 274*1db9f3b2SDimitry Andric 275*1db9f3b2SDimitry Andric SmallString<128> EncodingBuffer; 276*1db9f3b2SDimitry Andric 277*1db9f3b2SDimitry Andric if (LineTable.Rows.empty()) { 278*1db9f3b2SDimitry Andric // We only have the dummy entry, dsymutil emits an entry with a 0 279*1db9f3b2SDimitry Andric // address in that case. 280*1db9f3b2SDimitry Andric MCDwarfLineAddr::encode(*MC, Params, std::numeric_limits<int64_t>::max(), 281*1db9f3b2SDimitry Andric 0, EncodingBuffer); 282*1db9f3b2SDimitry Andric Section.OS.write(EncodingBuffer.c_str(), EncodingBuffer.size()); 283*1db9f3b2SDimitry Andric return; 284*1db9f3b2SDimitry Andric } 285*1db9f3b2SDimitry Andric 286*1db9f3b2SDimitry Andric // Line table state machine fields 287*1db9f3b2SDimitry Andric unsigned FileNum = 1; 288*1db9f3b2SDimitry Andric unsigned LastLine = 1; 289*1db9f3b2SDimitry Andric unsigned Column = 0; 290*1db9f3b2SDimitry Andric unsigned IsStatement = 1; 291*1db9f3b2SDimitry Andric unsigned Isa = 0; 292*1db9f3b2SDimitry Andric uint64_t Address = -1ULL; 293*1db9f3b2SDimitry Andric 294*1db9f3b2SDimitry Andric unsigned RowsSinceLastSequence = 0; 295*1db9f3b2SDimitry Andric 296*1db9f3b2SDimitry Andric for (const DWARFDebugLine::Row &Row : LineTable.Rows) { 297*1db9f3b2SDimitry Andric int64_t AddressDelta; 298*1db9f3b2SDimitry Andric if (Address == -1ULL) { 299*1db9f3b2SDimitry Andric Section.emitIntVal(dwarf::DW_LNS_extended_op, 1); 300*1db9f3b2SDimitry Andric encodeULEB128(Section.getFormParams().AddrSize + 1, Section.OS); 301*1db9f3b2SDimitry Andric Section.emitIntVal(dwarf::DW_LNE_set_address, 1); 302*1db9f3b2SDimitry Andric Section.emitIntVal(Row.Address.Address, 303*1db9f3b2SDimitry Andric Section.getFormParams().AddrSize); 304*1db9f3b2SDimitry Andric AddressDelta = 0; 305*1db9f3b2SDimitry Andric } else { 306*1db9f3b2SDimitry Andric AddressDelta = 307*1db9f3b2SDimitry Andric (Row.Address.Address - Address) / LineTable.Prologue.MinInstLength; 308*1db9f3b2SDimitry Andric } 309*1db9f3b2SDimitry Andric 310*1db9f3b2SDimitry Andric // FIXME: code copied and transformed from 311*1db9f3b2SDimitry Andric // MCDwarf.cpp::EmitDwarfLineTable. We should find a way to share this 312*1db9f3b2SDimitry Andric // code, but the current compatibility requirement with classic dsymutil 313*1db9f3b2SDimitry Andric // makes it hard. Revisit that once this requirement is dropped. 314*1db9f3b2SDimitry Andric 315*1db9f3b2SDimitry Andric if (FileNum != Row.File) { 316*1db9f3b2SDimitry Andric FileNum = Row.File; 317*1db9f3b2SDimitry Andric Section.emitIntVal(dwarf::DW_LNS_set_file, 1); 318*1db9f3b2SDimitry Andric encodeULEB128(FileNum, Section.OS); 319*1db9f3b2SDimitry Andric } 320*1db9f3b2SDimitry Andric if (Column != Row.Column) { 321*1db9f3b2SDimitry Andric Column = Row.Column; 322*1db9f3b2SDimitry Andric Section.emitIntVal(dwarf::DW_LNS_set_column, 1); 323*1db9f3b2SDimitry Andric encodeULEB128(Column, Section.OS); 324*1db9f3b2SDimitry Andric } 325*1db9f3b2SDimitry Andric 326*1db9f3b2SDimitry Andric // FIXME: We should handle the discriminator here, but dsymutil doesn't 327*1db9f3b2SDimitry Andric // consider it, thus ignore it for now. 328*1db9f3b2SDimitry Andric 329*1db9f3b2SDimitry Andric if (Isa != Row.Isa) { 330*1db9f3b2SDimitry Andric Isa = Row.Isa; 331*1db9f3b2SDimitry Andric Section.emitIntVal(dwarf::DW_LNS_set_isa, 1); 332*1db9f3b2SDimitry Andric encodeULEB128(Isa, Section.OS); 333*1db9f3b2SDimitry Andric } 334*1db9f3b2SDimitry Andric if (IsStatement != Row.IsStmt) { 335*1db9f3b2SDimitry Andric IsStatement = Row.IsStmt; 336*1db9f3b2SDimitry Andric Section.emitIntVal(dwarf::DW_LNS_negate_stmt, 1); 337*1db9f3b2SDimitry Andric } 338*1db9f3b2SDimitry Andric if (Row.BasicBlock) 339*1db9f3b2SDimitry Andric Section.emitIntVal(dwarf::DW_LNS_set_basic_block, 1); 340*1db9f3b2SDimitry Andric 341*1db9f3b2SDimitry Andric if (Row.PrologueEnd) 342*1db9f3b2SDimitry Andric Section.emitIntVal(dwarf::DW_LNS_set_prologue_end, 1); 343*1db9f3b2SDimitry Andric 344*1db9f3b2SDimitry Andric if (Row.EpilogueBegin) 345*1db9f3b2SDimitry Andric Section.emitIntVal(dwarf::DW_LNS_set_epilogue_begin, 1); 346*1db9f3b2SDimitry Andric 347*1db9f3b2SDimitry Andric int64_t LineDelta = int64_t(Row.Line) - LastLine; 348*1db9f3b2SDimitry Andric if (!Row.EndSequence) { 349*1db9f3b2SDimitry Andric MCDwarfLineAddr::encode(*MC, Params, LineDelta, AddressDelta, 350*1db9f3b2SDimitry Andric EncodingBuffer); 351*1db9f3b2SDimitry Andric Section.OS.write(EncodingBuffer.c_str(), EncodingBuffer.size()); 352*1db9f3b2SDimitry Andric EncodingBuffer.resize(0); 353*1db9f3b2SDimitry Andric Address = Row.Address.Address; 354*1db9f3b2SDimitry Andric LastLine = Row.Line; 355*1db9f3b2SDimitry Andric RowsSinceLastSequence++; 356*1db9f3b2SDimitry Andric } else { 357*1db9f3b2SDimitry Andric if (LineDelta) { 358*1db9f3b2SDimitry Andric Section.emitIntVal(dwarf::DW_LNS_advance_line, 1); 359*1db9f3b2SDimitry Andric encodeSLEB128(LineDelta, Section.OS); 360*1db9f3b2SDimitry Andric } 361*1db9f3b2SDimitry Andric if (AddressDelta) { 362*1db9f3b2SDimitry Andric Section.emitIntVal(dwarf::DW_LNS_advance_pc, 1); 363*1db9f3b2SDimitry Andric encodeULEB128(AddressDelta, Section.OS); 364*1db9f3b2SDimitry Andric } 365*1db9f3b2SDimitry Andric MCDwarfLineAddr::encode(*MC, Params, 366*1db9f3b2SDimitry Andric std::numeric_limits<int64_t>::max(), 0, 367*1db9f3b2SDimitry Andric EncodingBuffer); 368*1db9f3b2SDimitry Andric Section.OS.write(EncodingBuffer.c_str(), EncodingBuffer.size()); 369*1db9f3b2SDimitry Andric EncodingBuffer.resize(0); 370*1db9f3b2SDimitry Andric Address = -1ULL; 371*1db9f3b2SDimitry Andric LastLine = FileNum = IsStatement = 1; 372*1db9f3b2SDimitry Andric RowsSinceLastSequence = Column = Isa = 0; 373*1db9f3b2SDimitry Andric } 374*1db9f3b2SDimitry Andric } 375*1db9f3b2SDimitry Andric 376*1db9f3b2SDimitry Andric if (RowsSinceLastSequence) { 377*1db9f3b2SDimitry Andric MCDwarfLineAddr::encode(*MC, Params, std::numeric_limits<int64_t>::max(), 378*1db9f3b2SDimitry Andric 0, EncodingBuffer); 379*1db9f3b2SDimitry Andric Section.OS.write(EncodingBuffer.c_str(), EncodingBuffer.size()); 380*1db9f3b2SDimitry Andric EncodingBuffer.resize(0); 381*1db9f3b2SDimitry Andric } 382*1db9f3b2SDimitry Andric } 383*1db9f3b2SDimitry Andric 384*1db9f3b2SDimitry Andric Triple TheTriple; 385*1db9f3b2SDimitry Andric DwarfUnit &U; 386*1db9f3b2SDimitry Andric 387*1db9f3b2SDimitry Andric std::unique_ptr<MCRegisterInfo> MRI; 388*1db9f3b2SDimitry Andric std::unique_ptr<MCAsmInfo> MAI; 389*1db9f3b2SDimitry Andric std::unique_ptr<MCContext> MC; 390*1db9f3b2SDimitry Andric std::unique_ptr<MCSubtargetInfo> MSTI; 391*1db9f3b2SDimitry Andric }; 392*1db9f3b2SDimitry Andric 393*1db9f3b2SDimitry Andric } // end of namespace parallel 394*1db9f3b2SDimitry Andric } // end of namespace dwarf_linker 395*1db9f3b2SDimitry Andric } // end of namespace llvm 396*1db9f3b2SDimitry Andric 397*1db9f3b2SDimitry Andric #endif // LLVM_LIB_DWARFLINKER_PARALLEL_DEBUGLINESECTIONEMITTER_H 398