xref: /freebsd-src/contrib/llvm-project/llvm/lib/DWARFLinker/Parallel/DebugLineSectionEmitter.h (revision 1db9f3b21e39176dd5b67cf8ac378633b172463e)
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