9#ifndef LLVM_LIB_DWARFLINKER_PARALLEL_DEBUGLINESECTIONEMITTER_H
10#define LLVM_LIB_DWARFLINKER_PARALLEL_DEBUGLINESECTIONEMITTER_H
20namespace dwarf_linker {
27 : TheTriple(TheTriple), U(U) {}
33 if (
Error Err = init(TheTriple))
45 emitLineTablePrologue(LineTable.
Prologue, OutSection);
48 emitLineTableRows(LineTable, OutSection);
52 assert(OffsetAfterUnitLength -
54 OffsetAfterUnitLength);
55 OutSection.
apply(OffsetAfterUnitLength -
57 dwarf::DW_FORM_sec_offset,
58 OffsetAfterEnd - OffsetAfterUnitLength);
66 std::string TripleName;
79 "no register info for target %s",
86 "no asm info for target %s", TripleName.c_str());
91 "no subtarget info for target %s",
94 MC.reset(
new MCContext(TheTriple, MAI.get(), MRI.get(), MSTI.get(),
nullptr,
95 nullptr,
true,
"__DWARF"));
101 SectionDescriptor &Section) {
103 Section.emitIntVal(
P.getVersion(), 2);
104 if (
P.getVersion() == 5) {
106 Section.emitIntVal(
P.getAddressSize(), 1);
109 Section.emitIntVal(
P.SegSelectorSize, 1);
113 Section.emitOffset(0xBADDEF);
115 uint64_t OffsetAfterPrologueLength = Section.OS.tell();
116 emitLineTableProloguePayload(
P, Section);
117 uint64_t OffsetAfterPrologueEnd = Section.OS.tell();
120 Section.apply(OffsetAfterPrologueLength -
121 Section.getFormParams().getDwarfOffsetByteSize(),
122 dwarf::DW_FORM_sec_offset,
123 OffsetAfterPrologueEnd - OffsetAfterPrologueLength);
127 emitLineTablePrologueV2IncludeAndFileTable(
const DWARFDebugLine::Prologue &
P,
128 SectionDescriptor &Section) {
130 for (
const DWARFFormValue &
Include :
P.IncludeDirectories) {
133 U.
warn(
"cann't read string from line table.");
143 for (
const DWARFDebugLine::FileNameEntry &File :
P.FileNames) {
146 U.
warn(
"cann't read string from line table.");
152 Section.emitString(
File.Name.getForm(), *FileNameStr);
169 emitLineTablePrologueV5IncludeAndFileTable(
const DWARFDebugLine::Prologue &
P,
170 SectionDescriptor &Section) {
171 if (
P.IncludeDirectories.empty()) {
186 for (
auto Include :
P.IncludeDirectories) {
189 U.
warn(
"cann't read string from line table.");
196 bool HasChecksums =
P.ContentTypes.HasMD5;
197 bool HasInlineSources =
P.ContentTypes.HasSource;
200 dwarf::Form LLVMSourceForm = dwarf::DW_FORM_string;
202 if (
P.FileNames.empty()) {
206 FileNameForm =
P.FileNames[0].Name.getForm();
207 LLVMSourceForm =
P.FileNames[0].Source.getForm();
211 2 + (HasChecksums ? 1 : 0) + (HasInlineSources ? 1 : 0), 1);
225 if (HasInlineSources) {
235 for (
auto File :
P.FileNames) {
238 U.
warn(
"cann't read string from line table.");
244 Section.emitString(FileNameForm, *FileNameStr);
249 "checksum size is not equal to 16 bytes.");
251 StringRef(
reinterpret_cast<const char *
>(
File.Checksum.data()),
252 File.Checksum.size()));
255 if (HasInlineSources) {
256 std::optional<const char *> FileSourceStr =
258 if (!FileSourceStr) {
259 U.
warn(
"cann't read string from line table.");
263 Section.emitString(LLVMSourceForm, *FileSourceStr);
268 void emitLineTableProloguePayload(
const DWARFDebugLine::Prologue &
P,
269 SectionDescriptor &Section) {
271 Section.emitIntVal(
P.MinInstLength, 1);
272 if (
P.FormParams.Version >= 4) {
274 Section.emitIntVal(
P.MaxOpsPerInst, 1);
277 Section.emitIntVal(
P.DefaultIsStmt, 1);
283 Section.emitIntVal(
P.OpcodeBase, 1);
286 for (
auto Length :
P.StandardOpcodeLengths)
289 if (
P.FormParams.Version < 5)
290 emitLineTablePrologueV2IncludeAndFileTable(
P, Section);
292 emitLineTablePrologueV5IncludeAndFileTable(
P, Section);
295 void emitLineTableRows(
const DWARFDebugLine::LineTable &LineTable,
296 SectionDescriptor &Section) {
298 MCDwarfLineTableParams Params;
299 Params.DWARF2LineOpcodeBase = LineTable.Prologue.OpcodeBase;
300 Params.DWARF2LineBase = LineTable.Prologue.LineBase;
301 Params.DWARF2LineRange = LineTable.Prologue.LineRange;
303 SmallString<128> EncodingBuffer;
305 if (LineTable.Rows.empty()) {
310 Section.OS.write(EncodingBuffer.c_str(), EncodingBuffer.size());
315 unsigned FileNum = 1;
316 unsigned LastLine = 1;
319 unsigned IsStatement = 1;
323 unsigned RowsSinceLastSequence = 0;
325 for (
const DWARFDebugLine::Row &Row : LineTable.Rows) {
328 Section.emitIntVal(dwarf::DW_LNS_extended_op, 1);
330 Section.emitIntVal(dwarf::DW_LNE_set_address, 1);
331 Section.emitIntVal(Row.Address.Address,
332 Section.getFormParams().AddrSize);
336 (Row.Address.Address -
Address) / LineTable.Prologue.MinInstLength;
344 if (FileNum != Row.File) {
346 Section.emitIntVal(dwarf::DW_LNS_set_file, 1);
349 if (Column != Row.Column) {
351 Section.emitIntVal(dwarf::DW_LNS_set_column, 1);
354 if (Discriminator != Row.Discriminator && MC->getDwarfVersion() >= 4) {
357 Section.emitIntVal(dwarf::DW_LNS_extended_op, 1);
359 Section.emitIntVal(dwarf::DW_LNE_set_discriminator, 1);
364 if (Isa != Row.Isa) {
366 Section.emitIntVal(dwarf::DW_LNS_set_isa, 1);
369 if (IsStatement != Row.IsStmt) {
370 IsStatement = Row.IsStmt;
371 Section.emitIntVal(dwarf::DW_LNS_negate_stmt, 1);
374 Section.emitIntVal(dwarf::DW_LNS_set_basic_block, 1);
377 Section.emitIntVal(dwarf::DW_LNS_set_prologue_end, 1);
379 if (Row.EpilogueBegin)
380 Section.emitIntVal(dwarf::DW_LNS_set_epilogue_begin, 1);
382 int64_t LineDelta = int64_t(Row.Line) - LastLine;
383 if (!Row.EndSequence) {
386 Section.OS.write(EncodingBuffer.c_str(), EncodingBuffer.size());
387 EncodingBuffer.resize(0);
390 RowsSinceLastSequence++;
393 Section.emitIntVal(dwarf::DW_LNS_advance_line, 1);
397 Section.emitIntVal(dwarf::DW_LNS_advance_pc, 1);
401 std::numeric_limits<int64_t>::max(), 0,
403 Section.OS.write(EncodingBuffer.c_str(), EncodingBuffer.size());
404 EncodingBuffer.resize(0);
406 LastLine = FileNum = IsStatement = 1;
411 if (RowsSinceLastSequence) {
414 Section.OS.write(EncodingBuffer.c_str(), EncodingBuffer.size());
415 EncodingBuffer.resize(0);
422 std::unique_ptr<MCRegisterInfo> MRI;
423 std::unique_ptr<MCAsmInfo> MAI;
424 std::unique_ptr<MCContext> MC;
425 std::unique_ptr<MCSubtargetInfo> MSTI;
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Context object for machine code objects.
static void encode(MCContext &Context, MCDwarfLineTableParams Params, int64_t LineDelta, uint64_t AddrDelta, SmallVectorImpl< char > &OS)
Utility function to encode a Dwarf pair of LineDelta and AddrDeltas.
Target - Wrapper for Target specific information.
MCSubtargetInfo * createMCSubtargetInfo(StringRef TheTriple, StringRef CPU, StringRef Features) const
createMCSubtargetInfo - Create a MCSubtargetInfo implementation.
MCRegisterInfo * createMCRegInfo(StringRef TT) const
createMCRegInfo - Create a MCRegisterInfo implementation.
MCAsmInfo * createMCAsmInfo(const MCRegisterInfo &MRI, StringRef TheTriple, const MCTargetOptions &Options) const
createMCAsmInfo - Create a MCAsmInfo implementation for the specified target triple.
Triple - Helper class for working with autoconf configuration names.
const std::string & getTriple() const
This class emits specified line table into the .debug_line section.
Error emit(const DWARFDebugLine::LineTable &LineTable)
DebugLineSectionEmitter(const Triple &TheTriple, DwarfUnit &U)
Base class for all Dwarf units(Compile unit/Type table unit).
SectionDescriptor & getOrCreateSectionDescriptor(DebugSectionKind SectionKind)
Returns descriptor for the specified section of SectionKind.
uint64_t tell() const
tell - Return the current offset with the file.
void warn(const Twine &Warning)
std::optional< const char * > toString(const std::optional< DWARFFormValue > &V)
Take an optional DWARFFormValue and try to extract a string value from it.
MCTargetOptions InitMCTargetOptionsFromFlags()
This is an optimization pass for GlobalISel generic memory operations.
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
unsigned getULEB128Size(uint64_t Value)
Utility function to get the size of the ULEB128-encoded value.
unsigned encodeSLEB128(int64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a SLEB128 value to an output stream.
unsigned encodeULEB128(uint64_t Value, raw_ostream &OS, unsigned PadTo=0)
Utility function to encode a ULEB128 value to an output stream.
static const Target * lookupTarget(StringRef Triple, std::string &Error)
lookupTarget - Lookup a target based on a target triple.
dwarf::FormParams getFormParams() const
Returns FormParams used by section.
This structure is used to keep data of the concrete section.
raw_svector_ostream OS
Stream which stores data to the Contents.
void emitUnitLength(uint64_t Length)
Emit unit length into the current section contents.
void apply(uint64_t PatchOffset, dwarf::Form AttrForm, uint64_t Val)
Write specified Value of AttrForm to the PatchOffset.