1 //===- DWARFDebugLine.cpp -------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
10 #include "llvm/ADT/SmallString.h"
11 #include "llvm/ADT/SmallVector.h"
12 #include "llvm/ADT/StringRef.h"
13 #include "llvm/BinaryFormat/Dwarf.h"
14 #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
15 #include "llvm/DebugInfo/DWARF/DWARFDie.h"
16 #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
17 #include "llvm/Support/Errc.h"
18 #include "llvm/Support/Format.h"
19 #include "llvm/Support/FormatVariadic.h"
20 #include "llvm/Support/raw_ostream.h"
29 using namespace dwarf
;
31 using FileLineInfoKind
= DILineInfoSpecifier::FileLineInfoKind
;
35 struct ContentDescriptor
{
36 dwarf::LineNumberEntryFormat Type
;
40 using ContentDescriptors
= SmallVector
<ContentDescriptor
, 4>;
42 } // end anonymous namespace
44 static bool versionIsSupported(uint16_t Version
) {
45 return Version
>= 2 && Version
<= 5;
48 void DWARFDebugLine::ContentTypeTracker::trackContentType(
49 dwarf::LineNumberEntryFormat ContentType
) {
50 switch (ContentType
) {
51 case dwarf::DW_LNCT_timestamp
:
54 case dwarf::DW_LNCT_size
:
57 case dwarf::DW_LNCT_MD5
:
60 case dwarf::DW_LNCT_LLVM_source
:
64 // We only care about values we consider optional, and new values may be
65 // added in the vendor extension range, so we do not match exhaustively.
70 DWARFDebugLine::Prologue::Prologue() { clear(); }
72 bool DWARFDebugLine::Prologue::hasFileAtIndex(uint64_t FileIndex
) const {
73 uint16_t DwarfVersion
= getVersion();
74 assert(DwarfVersion
!= 0 &&
75 "line table prologue has no dwarf version information");
76 if (DwarfVersion
>= 5)
77 return FileIndex
< FileNames
.size();
78 return FileIndex
!= 0 && FileIndex
<= FileNames
.size();
81 std::optional
<uint64_t>
82 DWARFDebugLine::Prologue::getLastValidFileIndex() const {
83 if (FileNames
.empty())
85 uint16_t DwarfVersion
= getVersion();
86 assert(DwarfVersion
!= 0 &&
87 "line table prologue has no dwarf version information");
88 // In DWARF v5 the file names are 0-indexed.
89 if (DwarfVersion
>= 5)
90 return FileNames
.size() - 1;
91 return FileNames
.size();
94 const llvm::DWARFDebugLine::FileNameEntry
&
95 DWARFDebugLine::Prologue::getFileNameEntry(uint64_t Index
) const {
96 uint16_t DwarfVersion
= getVersion();
97 assert(DwarfVersion
!= 0 &&
98 "line table prologue has no dwarf version information");
99 // In DWARF v5 the file names are 0-indexed.
100 if (DwarfVersion
>= 5)
101 return FileNames
[Index
];
102 return FileNames
[Index
- 1];
105 void DWARFDebugLine::Prologue::clear() {
106 TotalLength
= PrologueLength
= 0;
108 MinInstLength
= MaxOpsPerInst
= DefaultIsStmt
= LineBase
= LineRange
= 0;
110 FormParams
= dwarf::FormParams({0, 0, DWARF32
});
111 ContentTypes
= ContentTypeTracker();
112 StandardOpcodeLengths
.clear();
113 IncludeDirectories
.clear();
117 void DWARFDebugLine::Prologue::dump(raw_ostream
&OS
,
118 DIDumpOptions DumpOptions
) const {
119 if (!totalLengthIsValid())
121 int OffsetDumpWidth
= 2 * dwarf::getDwarfOffsetByteSize(FormParams
.Format
);
122 OS
<< "Line table prologue:\n"
123 << format(" total_length: 0x%0*" PRIx64
"\n", OffsetDumpWidth
,
125 << " format: " << dwarf::FormatString(FormParams
.Format
) << "\n"
126 << format(" version: %u\n", getVersion());
127 if (!versionIsSupported(getVersion()))
129 if (getVersion() >= 5)
130 OS
<< format(" address_size: %u\n", getAddressSize())
131 << format(" seg_select_size: %u\n", SegSelectorSize
);
132 OS
<< format(" prologue_length: 0x%0*" PRIx64
"\n", OffsetDumpWidth
,
134 << format(" min_inst_length: %u\n", MinInstLength
)
135 << format(getVersion() >= 4 ? "max_ops_per_inst: %u\n" : "", MaxOpsPerInst
)
136 << format(" default_is_stmt: %u\n", DefaultIsStmt
)
137 << format(" line_base: %i\n", LineBase
)
138 << format(" line_range: %u\n", LineRange
)
139 << format(" opcode_base: %u\n", OpcodeBase
);
141 for (uint32_t I
= 0; I
!= StandardOpcodeLengths
.size(); ++I
)
142 OS
<< formatv("standard_opcode_lengths[{0}] = {1}\n",
143 static_cast<dwarf::LineNumberOps
>(I
+ 1),
144 StandardOpcodeLengths
[I
]);
146 if (!IncludeDirectories
.empty()) {
147 // DWARF v5 starts directory indexes at 0.
148 uint32_t DirBase
= getVersion() >= 5 ? 0 : 1;
149 for (uint32_t I
= 0; I
!= IncludeDirectories
.size(); ++I
) {
150 OS
<< format("include_directories[%3u] = ", I
+ DirBase
);
151 IncludeDirectories
[I
].dump(OS
, DumpOptions
);
156 if (!FileNames
.empty()) {
157 // DWARF v5 starts file indexes at 0.
158 uint32_t FileBase
= getVersion() >= 5 ? 0 : 1;
159 for (uint32_t I
= 0; I
!= FileNames
.size(); ++I
) {
160 const FileNameEntry
&FileEntry
= FileNames
[I
];
161 OS
<< format("file_names[%3u]:\n", I
+ FileBase
);
163 FileEntry
.Name
.dump(OS
, DumpOptions
);
165 << format(" dir_index: %" PRIu64
"\n", FileEntry
.DirIdx
);
166 if (ContentTypes
.HasMD5
)
167 OS
<< " md5_checksum: " << FileEntry
.Checksum
.digest() << '\n';
168 if (ContentTypes
.HasModTime
)
169 OS
<< format(" mod_time: 0x%8.8" PRIx64
"\n", FileEntry
.ModTime
);
170 if (ContentTypes
.HasLength
)
171 OS
<< format(" length: 0x%8.8" PRIx64
"\n", FileEntry
.Length
);
172 if (ContentTypes
.HasSource
) {
173 auto Source
= FileEntry
.Source
.getAsCString();
175 consumeError(Source
.takeError());
176 else if ((*Source
)[0]) {
178 FileEntry
.Source
.dump(OS
, DumpOptions
);
186 // Parse v2-v4 directory and file tables.
188 parseV2DirFileTables(const DWARFDataExtractor
&DebugLineData
,
190 DWARFDebugLine::ContentTypeTracker
&ContentTypes
,
191 std::vector
<DWARFFormValue
> &IncludeDirectories
,
192 std::vector
<DWARFDebugLine::FileNameEntry
> &FileNames
) {
194 Error Err
= Error::success();
195 StringRef S
= DebugLineData
.getCStrRef(OffsetPtr
, &Err
);
197 consumeError(std::move(Err
));
198 return createStringError(errc::invalid_argument
,
199 "include directories table was not null "
200 "terminated before the end of the prologue");
205 DWARFFormValue::createFromPValue(dwarf::DW_FORM_string
, S
.data());
206 IncludeDirectories
.push_back(Dir
);
209 ContentTypes
.HasModTime
= true;
210 ContentTypes
.HasLength
= true;
213 Error Err
= Error::success();
214 StringRef Name
= DebugLineData
.getCStrRef(OffsetPtr
, &Err
);
215 if (!Err
&& Name
.empty())
218 DWARFDebugLine::FileNameEntry FileEntry
;
220 DWARFFormValue::createFromPValue(dwarf::DW_FORM_string
, Name
.data());
221 FileEntry
.DirIdx
= DebugLineData
.getULEB128(OffsetPtr
, &Err
);
222 FileEntry
.ModTime
= DebugLineData
.getULEB128(OffsetPtr
, &Err
);
223 FileEntry
.Length
= DebugLineData
.getULEB128(OffsetPtr
, &Err
);
226 consumeError(std::move(Err
));
227 return createStringError(
228 errc::invalid_argument
,
229 "file names table was not null terminated before "
230 "the end of the prologue");
232 FileNames
.push_back(FileEntry
);
235 return Error::success();
238 // Parse v5 directory/file entry content descriptions.
239 // Returns the descriptors, or an error if we did not find a path or ran off
240 // the end of the prologue.
241 static llvm::Expected
<ContentDescriptors
>
242 parseV5EntryFormat(const DWARFDataExtractor
&DebugLineData
, uint64_t *OffsetPtr
,
243 DWARFDebugLine::ContentTypeTracker
*ContentTypes
) {
244 Error Err
= Error::success();
245 ContentDescriptors Descriptors
;
246 int FormatCount
= DebugLineData
.getU8(OffsetPtr
, &Err
);
247 bool HasPath
= false;
248 for (int I
= 0; I
!= FormatCount
&& !Err
; ++I
) {
249 ContentDescriptor Descriptor
;
251 dwarf::LineNumberEntryFormat(DebugLineData
.getULEB128(OffsetPtr
, &Err
));
252 Descriptor
.Form
= dwarf::Form(DebugLineData
.getULEB128(OffsetPtr
, &Err
));
253 if (Descriptor
.Type
== dwarf::DW_LNCT_path
)
256 ContentTypes
->trackContentType(Descriptor
.Type
);
257 Descriptors
.push_back(Descriptor
);
261 return createStringError(errc::invalid_argument
,
262 "failed to parse entry content descriptors: %s",
263 toString(std::move(Err
)).c_str());
266 return createStringError(errc::invalid_argument
,
267 "failed to parse entry content descriptions"
268 " because no path was found");
273 parseV5DirFileTables(const DWARFDataExtractor
&DebugLineData
,
274 uint64_t *OffsetPtr
, const dwarf::FormParams
&FormParams
,
275 const DWARFContext
&Ctx
, const DWARFUnit
*U
,
276 DWARFDebugLine::ContentTypeTracker
&ContentTypes
,
277 std::vector
<DWARFFormValue
> &IncludeDirectories
,
278 std::vector
<DWARFDebugLine::FileNameEntry
> &FileNames
) {
279 // Get the directory entry description.
280 llvm::Expected
<ContentDescriptors
> DirDescriptors
=
281 parseV5EntryFormat(DebugLineData
, OffsetPtr
, nullptr);
283 return DirDescriptors
.takeError();
285 // Get the directory entries, according to the format described above.
286 uint64_t DirEntryCount
= DebugLineData
.getULEB128(OffsetPtr
);
287 for (uint64_t I
= 0; I
!= DirEntryCount
; ++I
) {
288 for (auto Descriptor
: *DirDescriptors
) {
289 DWARFFormValue
Value(Descriptor
.Form
);
290 switch (Descriptor
.Type
) {
292 if (!Value
.extractValue(DebugLineData
, OffsetPtr
, FormParams
, &Ctx
, U
))
293 return createStringError(errc::invalid_argument
,
294 "failed to parse directory entry because "
295 "extracting the form value failed");
296 IncludeDirectories
.push_back(Value
);
299 if (!Value
.skipValue(DebugLineData
, OffsetPtr
, FormParams
))
300 return createStringError(errc::invalid_argument
,
301 "failed to parse directory entry because "
302 "skipping the form value failed");
307 // Get the file entry description.
308 llvm::Expected
<ContentDescriptors
> FileDescriptors
=
309 parseV5EntryFormat(DebugLineData
, OffsetPtr
, &ContentTypes
);
310 if (!FileDescriptors
)
311 return FileDescriptors
.takeError();
313 // Get the file entries, according to the format described above.
314 uint64_t FileEntryCount
= DebugLineData
.getULEB128(OffsetPtr
);
315 for (uint64_t I
= 0; I
!= FileEntryCount
; ++I
) {
316 DWARFDebugLine::FileNameEntry FileEntry
;
317 for (auto Descriptor
: *FileDescriptors
) {
318 DWARFFormValue
Value(Descriptor
.Form
);
319 if (!Value
.extractValue(DebugLineData
, OffsetPtr
, FormParams
, &Ctx
, U
))
320 return createStringError(errc::invalid_argument
,
321 "failed to parse file entry because "
322 "extracting the form value failed");
323 switch (Descriptor
.Type
) {
325 FileEntry
.Name
= Value
;
327 case DW_LNCT_LLVM_source
:
328 FileEntry
.Source
= Value
;
330 case DW_LNCT_directory_index
:
331 FileEntry
.DirIdx
= *Value
.getAsUnsignedConstant();
333 case DW_LNCT_timestamp
:
334 FileEntry
.ModTime
= *Value
.getAsUnsignedConstant();
337 FileEntry
.Length
= *Value
.getAsUnsignedConstant();
340 if (!Value
.getAsBlock() || Value
.getAsBlock()->size() != 16)
341 return createStringError(
342 errc::invalid_argument
,
343 "failed to parse file entry because the MD5 hash is invalid");
344 std::uninitialized_copy_n(Value
.getAsBlock()->begin(), 16,
345 FileEntry
.Checksum
.begin());
351 FileNames
.push_back(FileEntry
);
353 return Error::success();
356 uint64_t DWARFDebugLine::Prologue::getLength() const {
357 uint64_t Length
= PrologueLength
+ sizeofTotalLength() +
358 sizeof(getVersion()) + sizeofPrologueLength();
359 if (getVersion() >= 5)
360 Length
+= 2; // Address + Segment selector sizes.
364 Error
DWARFDebugLine::Prologue::parse(
365 DWARFDataExtractor DebugLineData
, uint64_t *OffsetPtr
,
366 function_ref
<void(Error
)> RecoverableErrorHandler
, const DWARFContext
&Ctx
,
367 const DWARFUnit
*U
) {
368 const uint64_t PrologueOffset
= *OffsetPtr
;
371 DataExtractor::Cursor
Cursor(*OffsetPtr
);
372 std::tie(TotalLength
, FormParams
.Format
) =
373 DebugLineData
.getInitialLength(Cursor
);
376 DWARFDataExtractor(DebugLineData
, Cursor
.tell() + TotalLength
);
377 FormParams
.Version
= DebugLineData
.getU16(Cursor
);
378 if (Cursor
&& !versionIsSupported(getVersion())) {
379 // Treat this error as unrecoverable - we cannot be sure what any of
380 // the data represents including the length field, so cannot skip it or make
381 // any reasonable assumptions.
382 *OffsetPtr
= Cursor
.tell();
383 return createStringError(
385 "parsing line table prologue at offset 0x%8.8" PRIx64
386 ": unsupported version %" PRIu16
,
387 PrologueOffset
, getVersion());
390 if (getVersion() >= 5) {
391 FormParams
.AddrSize
= DebugLineData
.getU8(Cursor
);
392 assert((!Cursor
|| DebugLineData
.getAddressSize() == 0 ||
393 DebugLineData
.getAddressSize() == getAddressSize()) &&
394 "Line table header and data extractor disagree");
395 SegSelectorSize
= DebugLineData
.getU8(Cursor
);
399 DebugLineData
.getRelocatedValue(Cursor
, sizeofPrologueLength());
400 const uint64_t EndPrologueOffset
= PrologueLength
+ Cursor
.tell();
401 DebugLineData
= DWARFDataExtractor(DebugLineData
, EndPrologueOffset
);
402 MinInstLength
= DebugLineData
.getU8(Cursor
);
403 if (getVersion() >= 4)
404 MaxOpsPerInst
= DebugLineData
.getU8(Cursor
);
405 DefaultIsStmt
= DebugLineData
.getU8(Cursor
);
406 LineBase
= DebugLineData
.getU8(Cursor
);
407 LineRange
= DebugLineData
.getU8(Cursor
);
408 OpcodeBase
= DebugLineData
.getU8(Cursor
);
410 if (Cursor
&& OpcodeBase
== 0) {
411 // If the opcode base is 0, we cannot read the standard opcode lengths (of
412 // which there are supposed to be one fewer than the opcode base). Assume
413 // there are no standard opcodes and continue parsing.
414 RecoverableErrorHandler(createStringError(
415 errc::invalid_argument
,
416 "parsing line table prologue at offset 0x%8.8" PRIx64
417 " found opcode base of 0. Assuming no standard opcodes",
420 StandardOpcodeLengths
.reserve(OpcodeBase
- 1);
421 for (uint32_t I
= 1; I
< OpcodeBase
; ++I
) {
422 uint8_t OpLen
= DebugLineData
.getU8(Cursor
);
423 StandardOpcodeLengths
.push_back(OpLen
);
427 *OffsetPtr
= Cursor
.tell();
428 // A corrupt file name or directory table does not prevent interpretation of
429 // the main line program, so check the cursor state now so that its errors can
430 // be handled separately.
432 return createStringError(
433 errc::invalid_argument
,
434 "parsing line table prologue at offset 0x%8.8" PRIx64
": %s",
435 PrologueOffset
, toString(Cursor
.takeError()).c_str());
439 ? parseV5DirFileTables(DebugLineData
, OffsetPtr
, FormParams
, Ctx
, U
,
440 ContentTypes
, IncludeDirectories
, FileNames
)
441 : parseV2DirFileTables(DebugLineData
, OffsetPtr
, ContentTypes
,
442 IncludeDirectories
, FileNames
);
444 RecoverableErrorHandler(joinErrors(
446 errc::invalid_argument
,
447 "parsing line table prologue at 0x%8.8" PRIx64
448 " found an invalid directory or file table description at"
450 PrologueOffset
, *OffsetPtr
),
452 return Error::success();
455 assert(*OffsetPtr
<= EndPrologueOffset
);
456 if (*OffsetPtr
!= EndPrologueOffset
) {
457 RecoverableErrorHandler(createStringError(
458 errc::invalid_argument
,
459 "unknown data in line table prologue at offset 0x%8.8" PRIx64
460 ": parsing ended (at offset 0x%8.8" PRIx64
461 ") before reaching the prologue end at offset 0x%8.8" PRIx64
,
462 PrologueOffset
, *OffsetPtr
, EndPrologueOffset
));
464 return Error::success();
467 DWARFDebugLine::Row::Row(bool DefaultIsStmt
) { reset(DefaultIsStmt
); }
469 void DWARFDebugLine::Row::postAppend() {
473 EpilogueBegin
= false;
476 void DWARFDebugLine::Row::reset(bool DefaultIsStmt
) {
478 Address
.SectionIndex
= object::SectionedAddress::UndefSection
;
484 IsStmt
= DefaultIsStmt
;
489 EpilogueBegin
= false;
492 void DWARFDebugLine::Row::dumpTableHeader(raw_ostream
&OS
, unsigned Indent
) {
494 << "Address Line Column File ISA Discriminator OpIndex "
497 << "------------------ ------ ------ ------ --- ------------- ------- "
501 void DWARFDebugLine::Row::dump(raw_ostream
&OS
) const {
502 OS
<< format("0x%16.16" PRIx64
" %6u %6u", Address
.Address
, Line
, Column
)
503 << format(" %6u %3u %13u %7u ", File
, Isa
, Discriminator
, OpIndex
)
504 << (IsStmt
? " is_stmt" : "") << (BasicBlock
? " basic_block" : "")
505 << (PrologueEnd
? " prologue_end" : "")
506 << (EpilogueBegin
? " epilogue_begin" : "")
507 << (EndSequence
? " end_sequence" : "") << '\n';
510 DWARFDebugLine::Sequence::Sequence() { reset(); }
512 void DWARFDebugLine::Sequence::reset() {
515 SectionIndex
= object::SectionedAddress::UndefSection
;
521 DWARFDebugLine::LineTable::LineTable() { clear(); }
523 void DWARFDebugLine::LineTable::dump(raw_ostream
&OS
,
524 DIDumpOptions DumpOptions
) const {
525 Prologue
.dump(OS
, DumpOptions
);
529 Row::dumpTableHeader(OS
, 0);
530 for (const Row
&R
: Rows
) {
535 // Terminate the table with a final blank line to clearly delineate it from
540 void DWARFDebugLine::LineTable::clear() {
546 DWARFDebugLine::ParsingState::ParsingState(
547 struct LineTable
*LT
, uint64_t TableOffset
,
548 function_ref
<void(Error
)> ErrorHandler
)
549 : LineTable(LT
), LineTableOffset(TableOffset
), ErrorHandler(ErrorHandler
) {
550 resetRowAndSequence();
553 void DWARFDebugLine::ParsingState::resetRowAndSequence() {
554 Row
.reset(LineTable
->Prologue
.DefaultIsStmt
);
558 void DWARFDebugLine::ParsingState::appendRowToMatrix() {
559 unsigned RowNumber
= LineTable
->Rows
.size();
560 if (Sequence
.Empty
) {
561 // Record the beginning of instruction sequence.
562 Sequence
.Empty
= false;
563 Sequence
.LowPC
= Row
.Address
.Address
;
564 Sequence
.FirstRowIndex
= RowNumber
;
566 LineTable
->appendRow(Row
);
567 if (Row
.EndSequence
) {
568 // Record the end of instruction sequence.
569 Sequence
.HighPC
= Row
.Address
.Address
;
570 Sequence
.LastRowIndex
= RowNumber
+ 1;
571 Sequence
.SectionIndex
= Row
.Address
.SectionIndex
;
572 if (Sequence
.isValid())
573 LineTable
->appendSequence(Sequence
);
579 const DWARFDebugLine::LineTable
*
580 DWARFDebugLine::getLineTable(uint64_t Offset
) const {
581 LineTableConstIter Pos
= LineTableMap
.find(Offset
);
582 if (Pos
!= LineTableMap
.end())
587 Expected
<const DWARFDebugLine::LineTable
*> DWARFDebugLine::getOrParseLineTable(
588 DWARFDataExtractor
&DebugLineData
, uint64_t Offset
, const DWARFContext
&Ctx
,
589 const DWARFUnit
*U
, function_ref
<void(Error
)> RecoverableErrorHandler
) {
590 if (!DebugLineData
.isValidOffset(Offset
))
591 return createStringError(errc::invalid_argument
, "offset 0x%8.8" PRIx64
592 " is not a valid debug line section offset",
595 std::pair
<LineTableIter
, bool> Pos
=
596 LineTableMap
.insert(LineTableMapTy::value_type(Offset
, LineTable()));
597 LineTable
*LT
= &Pos
.first
->second
;
600 LT
->parse(DebugLineData
, &Offset
, Ctx
, U
, RecoverableErrorHandler
))
601 return std::move(Err
);
607 void DWARFDebugLine::clearLineTable(uint64_t Offset
) {
608 LineTableMap
.erase(Offset
);
611 static StringRef
getOpcodeName(uint8_t Opcode
, uint8_t OpcodeBase
) {
613 if (Opcode
< OpcodeBase
)
614 return LNStandardString(Opcode
);
618 DWARFDebugLine::ParsingState::AddrOpIndexDelta
619 DWARFDebugLine::ParsingState::advanceAddrOpIndex(uint64_t OperationAdvance
,
621 uint64_t OpcodeOffset
) {
622 StringRef OpcodeName
= getOpcodeName(Opcode
, LineTable
->Prologue
.OpcodeBase
);
623 // For versions less than 4, the MaxOpsPerInst member is set to 0, as the
624 // maximum_operations_per_instruction field wasn't introduced until DWARFv4.
625 // Don't warn about bad values in this situation.
626 if (ReportAdvanceAddrProblem
&& LineTable
->Prologue
.getVersion() >= 4 &&
627 LineTable
->Prologue
.MaxOpsPerInst
== 0)
628 ErrorHandler(createStringError(
629 errc::invalid_argument
,
630 "line table program at offset 0x%8.8" PRIx64
631 " contains a %s opcode at offset 0x%8.8" PRIx64
632 ", but the prologue maximum_operations_per_instruction value is 0"
633 ", which is invalid. Assuming a value of 1 instead",
634 LineTableOffset
, OpcodeName
.data(), OpcodeOffset
));
635 // Although we are able to correctly parse line number programs with
636 // MaxOpsPerInst > 1, the rest of DWARFDebugLine and its
637 // users have not been updated to handle line information for all operations
638 // in a multi-operation instruction, so warn about potentially incorrect
640 if (ReportAdvanceAddrProblem
&& LineTable
->Prologue
.MaxOpsPerInst
> 1)
641 ErrorHandler(createStringError(
643 "line table program at offset 0x%8.8" PRIx64
644 " contains a %s opcode at offset 0x%8.8" PRIx64
645 ", but the prologue maximum_operations_per_instruction value is %" PRId8
646 ", which is experimentally supported, so line number information "
648 LineTableOffset
, OpcodeName
.data(), OpcodeOffset
,
649 LineTable
->Prologue
.MaxOpsPerInst
));
650 if (ReportAdvanceAddrProblem
&& LineTable
->Prologue
.MinInstLength
== 0)
652 createStringError(errc::invalid_argument
,
653 "line table program at offset 0x%8.8" PRIx64
654 " contains a %s opcode at offset 0x%8.8" PRIx64
655 ", but the prologue minimum_instruction_length value "
656 "is 0, which prevents any address advancing",
657 LineTableOffset
, OpcodeName
.data(), OpcodeOffset
));
658 ReportAdvanceAddrProblem
= false;
660 // Advances the address and op_index according to DWARFv5, section 6.2.5.1:
662 // new address = address +
663 // minimum_instruction_length *
664 // ((op_index + operation advance) / maximum_operations_per_instruction)
667 // (op_index + operation advance) % maximum_operations_per_instruction
669 // For versions less than 4, the MaxOpsPerInst member is set to 0, as the
670 // maximum_operations_per_instruction field wasn't introduced until DWARFv4.
671 uint8_t MaxOpsPerInst
=
672 std::max(LineTable
->Prologue
.MaxOpsPerInst
, uint8_t{1});
674 uint64_t AddrOffset
= ((Row
.OpIndex
+ OperationAdvance
) / MaxOpsPerInst
) *
675 LineTable
->Prologue
.MinInstLength
;
676 Row
.Address
.Address
+= AddrOffset
;
678 uint8_t PrevOpIndex
= Row
.OpIndex
;
679 Row
.OpIndex
= (Row
.OpIndex
+ OperationAdvance
) % MaxOpsPerInst
;
680 int16_t OpIndexDelta
= static_cast<int16_t>(Row
.OpIndex
) - PrevOpIndex
;
682 return {AddrOffset
, OpIndexDelta
};
685 DWARFDebugLine::ParsingState::OpcodeAdvanceResults
686 DWARFDebugLine::ParsingState::advanceForOpcode(uint8_t Opcode
,
687 uint64_t OpcodeOffset
) {
688 assert(Opcode
== DW_LNS_const_add_pc
||
689 Opcode
>= LineTable
->Prologue
.OpcodeBase
);
690 if (ReportBadLineRange
&& LineTable
->Prologue
.LineRange
== 0) {
691 StringRef OpcodeName
=
692 getOpcodeName(Opcode
, LineTable
->Prologue
.OpcodeBase
);
694 createStringError(errc::not_supported
,
695 "line table program at offset 0x%8.8" PRIx64
696 " contains a %s opcode at offset 0x%8.8" PRIx64
697 ", but the prologue line_range value is 0. The "
698 "address and line will not be adjusted",
699 LineTableOffset
, OpcodeName
.data(), OpcodeOffset
));
700 ReportBadLineRange
= false;
703 uint8_t OpcodeValue
= Opcode
;
704 if (Opcode
== DW_LNS_const_add_pc
)
706 uint8_t AdjustedOpcode
= OpcodeValue
- LineTable
->Prologue
.OpcodeBase
;
707 uint64_t OperationAdvance
=
708 LineTable
->Prologue
.LineRange
!= 0
709 ? AdjustedOpcode
/ LineTable
->Prologue
.LineRange
711 AddrOpIndexDelta Advance
=
712 advanceAddrOpIndex(OperationAdvance
, Opcode
, OpcodeOffset
);
713 return {Advance
.AddrOffset
, Advance
.OpIndexDelta
, AdjustedOpcode
};
716 DWARFDebugLine::ParsingState::SpecialOpcodeDelta
717 DWARFDebugLine::ParsingState::handleSpecialOpcode(uint8_t Opcode
,
718 uint64_t OpcodeOffset
) {
719 // A special opcode value is chosen based on the amount that needs
720 // to be added to the line and address registers. The maximum line
721 // increment for a special opcode is the value of the line_base
722 // field in the header, plus the value of the line_range field,
723 // minus 1 (line base + line range - 1). If the desired line
724 // increment is greater than the maximum line increment, a standard
725 // opcode must be used instead of a special opcode. The "address
726 // advance" is calculated by dividing the desired address increment
727 // by the minimum_instruction_length field from the header. The
728 // special opcode is then calculated using the following formula:
730 // opcode = (desired line increment - line_base) +
731 // (line_range * address advance) + opcode_base
733 // If the resulting opcode is greater than 255, a standard opcode
734 // must be used instead.
736 // To decode a special opcode, subtract the opcode_base from the
737 // opcode itself to give the adjusted opcode. The amount to
738 // increment the address register is the result of the adjusted
739 // opcode divided by the line_range multiplied by the
740 // minimum_instruction_length field from the header. That is:
742 // address increment = (adjusted opcode / line_range) *
743 // minimum_instruction_length
745 // The amount to increment the line register is the line_base plus
746 // the result of the adjusted opcode modulo the line_range. That is:
748 // line increment = line_base + (adjusted opcode % line_range)
750 DWARFDebugLine::ParsingState::OpcodeAdvanceResults AddrAdvanceResult
=
751 advanceForOpcode(Opcode
, OpcodeOffset
);
752 int32_t LineOffset
= 0;
753 if (LineTable
->Prologue
.LineRange
!= 0)
755 LineTable
->Prologue
.LineBase
+
756 (AddrAdvanceResult
.AdjustedOpcode
% LineTable
->Prologue
.LineRange
);
757 Row
.Line
+= LineOffset
;
758 return {AddrAdvanceResult
.AddrDelta
, LineOffset
,
759 AddrAdvanceResult
.OpIndexDelta
};
762 /// Parse a ULEB128 using the specified \p Cursor. \returns the parsed value on
763 /// success, or std::nullopt if \p Cursor is in a failing state.
764 template <typename T
>
765 static std::optional
<T
> parseULEB128(DWARFDataExtractor
&Data
,
766 DataExtractor::Cursor
&Cursor
) {
767 T Value
= Data
.getULEB128(Cursor
);
773 Error
DWARFDebugLine::LineTable::parse(
774 DWARFDataExtractor
&DebugLineData
, uint64_t *OffsetPtr
,
775 const DWARFContext
&Ctx
, const DWARFUnit
*U
,
776 function_ref
<void(Error
)> RecoverableErrorHandler
, raw_ostream
*OS
,
778 assert((OS
|| !Verbose
) && "cannot have verbose output without stream");
779 const uint64_t DebugLineOffset
= *OffsetPtr
;
784 Prologue
.parse(DebugLineData
, OffsetPtr
, RecoverableErrorHandler
, Ctx
, U
);
787 DIDumpOptions DumpOptions
;
788 DumpOptions
.Verbose
= Verbose
;
789 Prologue
.dump(*OS
, DumpOptions
);
793 // Ensure there is a blank line after the prologue to clearly delineate it
800 uint64_t ProgramLength
= Prologue
.TotalLength
+ Prologue
.sizeofTotalLength();
801 if (!DebugLineData
.isValidOffsetForDataOfSize(DebugLineOffset
,
803 assert(DebugLineData
.size() > DebugLineOffset
&&
804 "prologue parsing should handle invalid offset");
805 uint64_t BytesRemaining
= DebugLineData
.size() - DebugLineOffset
;
806 RecoverableErrorHandler(
807 createStringError(errc::invalid_argument
,
808 "line table program with offset 0x%8.8" PRIx64
809 " has length 0x%8.8" PRIx64
" but only 0x%8.8" PRIx64
810 " bytes are available",
811 DebugLineOffset
, ProgramLength
, BytesRemaining
));
812 // Continue by capping the length at the number of remaining bytes.
813 ProgramLength
= BytesRemaining
;
816 // Create a DataExtractor which can only see the data up to the end of the
817 // table, to prevent reading past the end.
818 const uint64_t EndOffset
= DebugLineOffset
+ ProgramLength
;
819 DWARFDataExtractor
TableData(DebugLineData
, EndOffset
);
821 // See if we should tell the data extractor the address size.
822 if (TableData
.getAddressSize() == 0)
823 TableData
.setAddressSize(Prologue
.getAddressSize());
825 assert(Prologue
.getAddressSize() == 0 ||
826 Prologue
.getAddressSize() == TableData
.getAddressSize());
828 ParsingState
State(this, DebugLineOffset
, RecoverableErrorHandler
);
830 *OffsetPtr
= DebugLineOffset
+ Prologue
.getLength();
831 if (OS
&& *OffsetPtr
< EndOffset
) {
833 Row::dumpTableHeader(*OS
, /*Indent=*/Verbose
? 12 : 0);
835 bool TombstonedAddress
= false;
837 if (!TombstonedAddress
) {
844 State
.appendRowToMatrix();
847 while (*OffsetPtr
< EndOffset
) {
848 DataExtractor::Cursor
Cursor(*OffsetPtr
);
851 *OS
<< format("0x%08.08" PRIx64
": ", *OffsetPtr
);
853 uint64_t OpcodeOffset
= *OffsetPtr
;
854 uint8_t Opcode
= TableData
.getU8(Cursor
);
855 size_t RowCount
= Rows
.size();
857 if (Cursor
&& Verbose
)
858 *OS
<< format("%02.02" PRIx8
" ", Opcode
);
861 // Extended Opcodes always start with a zero opcode followed by
862 // a uleb128 length so you can skip ones you don't know about
863 uint64_t Len
= TableData
.getULEB128(Cursor
);
864 uint64_t ExtOffset
= Cursor
.tell();
866 // Tolerate zero-length; assume length is correct and soldier on.
868 if (Cursor
&& Verbose
)
869 *OS
<< "Badly formed extended line op (length 0)\n";
873 RecoverableErrorHandler(Cursor
.takeError());
875 *OffsetPtr
= Cursor
.tell();
879 uint8_t SubOpcode
= TableData
.getU8(Cursor
);
880 // OperandOffset will be the same as ExtOffset, if it was not possible to
881 // read the SubOpcode.
882 uint64_t OperandOffset
= Cursor
.tell();
884 *OS
<< LNExtendedString(SubOpcode
);
886 case DW_LNE_end_sequence
:
887 // Set the end_sequence register of the state machine to true and
888 // append a row to the matrix using the current values of the
889 // state-machine registers. Then reset the registers to the initial
890 // values specified above. Every statement program sequence must end
891 // with a DW_LNE_end_sequence instruction which creates a row whose
892 // address is that of the byte after the last target machine instruction
894 State
.Row
.EndSequence
= true;
895 // No need to test the Cursor is valid here, since it must be to get
896 // into this code path - if it were invalid, the default case would be
899 State
.resetRowAndSequence();
902 case DW_LNE_set_address
:
903 // Takes a single relocatable address as an operand. The size of the
904 // operand is the size appropriate to hold an address on the target
905 // machine. Set the address register to the value given by the
906 // relocatable address and set the op_index register to 0. All of the
907 // other statement program opcodes that affect the address register
908 // add a delta to it. This instruction stores a relocatable value into
911 // Make sure the extractor knows the address size. If not, infer it
912 // from the size of the operand.
914 uint8_t ExtractorAddressSize
= TableData
.getAddressSize();
915 uint64_t OpcodeAddressSize
= Len
- 1;
916 if (ExtractorAddressSize
!= OpcodeAddressSize
&&
917 ExtractorAddressSize
!= 0)
918 RecoverableErrorHandler(createStringError(
919 errc::invalid_argument
,
920 "mismatching address size at offset 0x%8.8" PRIx64
921 " expected 0x%2.2" PRIx8
" found 0x%2.2" PRIx64
,
922 ExtOffset
, ExtractorAddressSize
, Len
- 1));
924 // Assume that the line table is correct and temporarily override the
925 // address size. If the size is unsupported, give up trying to read
926 // the address and continue to the next opcode.
927 if (OpcodeAddressSize
!= 1 && OpcodeAddressSize
!= 2 &&
928 OpcodeAddressSize
!= 4 && OpcodeAddressSize
!= 8) {
929 RecoverableErrorHandler(createStringError(
930 errc::invalid_argument
,
931 "address size 0x%2.2" PRIx64
932 " of DW_LNE_set_address opcode at offset 0x%8.8" PRIx64
934 OpcodeAddressSize
, ExtOffset
));
935 TableData
.skip(Cursor
, OpcodeAddressSize
);
937 TableData
.setAddressSize(OpcodeAddressSize
);
938 State
.Row
.Address
.Address
= TableData
.getRelocatedAddress(
939 Cursor
, &State
.Row
.Address
.SectionIndex
);
940 State
.Row
.OpIndex
= 0;
943 dwarf::computeTombstoneAddress(OpcodeAddressSize
);
944 TombstonedAddress
= State
.Row
.Address
.Address
== Tombstone
;
946 // Restore the address size if the extractor already had it.
947 if (ExtractorAddressSize
!= 0)
948 TableData
.setAddressSize(ExtractorAddressSize
);
951 if (Cursor
&& Verbose
) {
953 DWARFFormValue::dumpAddress(*OS
, OpcodeAddressSize
, State
.Row
.Address
.Address
);
959 case DW_LNE_define_file
:
960 // Takes 4 arguments. The first is a null terminated string containing
961 // a source file name. The second is an unsigned LEB128 number
962 // representing the directory index of the directory in which the file
963 // was found. The third is an unsigned LEB128 number representing the
964 // time of last modification of the file. The fourth is an unsigned
965 // LEB128 number representing the length in bytes of the file. The time
966 // and length fields may contain LEB128(0) if the information is not
969 // The directory index represents an entry in the include_directories
970 // section of the statement program prologue. The index is LEB128(0)
971 // if the file was found in the current directory of the compilation,
972 // LEB128(1) if it was found in the first directory in the
973 // include_directories section, and so on. The directory index is
974 // ignored for file names that represent full path names.
976 // The files are numbered, starting at 1, in the order in which they
977 // appear; the names in the prologue come before names defined by
978 // the DW_LNE_define_file instruction. These numbers are used in the
979 // the file register of the state machine.
981 FileNameEntry FileEntry
;
982 const char *Name
= TableData
.getCStr(Cursor
);
984 DWARFFormValue::createFromPValue(dwarf::DW_FORM_string
, Name
);
985 FileEntry
.DirIdx
= TableData
.getULEB128(Cursor
);
986 FileEntry
.ModTime
= TableData
.getULEB128(Cursor
);
987 FileEntry
.Length
= TableData
.getULEB128(Cursor
);
988 Prologue
.FileNames
.push_back(FileEntry
);
989 if (Cursor
&& Verbose
)
990 *OS
<< " (" << Name
<< ", dir=" << FileEntry
.DirIdx
<< ", mod_time="
991 << format("(0x%16.16" PRIx64
")", FileEntry
.ModTime
)
992 << ", length=" << FileEntry
.Length
<< ")";
996 case DW_LNE_set_discriminator
:
997 State
.Row
.Discriminator
= TableData
.getULEB128(Cursor
);
998 if (Cursor
&& Verbose
)
999 *OS
<< " (" << State
.Row
.Discriminator
<< ")";
1003 if (Cursor
&& Verbose
)
1004 *OS
<< format("Unrecognized extended op 0x%02.02" PRIx8
, SubOpcode
)
1005 << format(" length %" PRIx64
, Len
);
1006 // Len doesn't include the zero opcode byte or the length itself, but
1007 // it does include the sub_opcode, so we have to adjust for that.
1008 TableData
.skip(Cursor
, Len
- 1);
1011 // Make sure the length as recorded in the table and the standard length
1012 // for the opcode match. If they don't, continue from the end as claimed
1013 // by the table. Similarly, continue from the claimed end in the event of
1015 uint64_t End
= ExtOffset
+ Len
;
1016 if (Cursor
&& Cursor
.tell() != End
)
1017 RecoverableErrorHandler(createStringError(
1018 errc::illegal_byte_sequence
,
1019 "unexpected line op length at offset 0x%8.8" PRIx64
1020 " expected 0x%2.2" PRIx64
" found 0x%2.2" PRIx64
,
1021 ExtOffset
, Len
, Cursor
.tell() - ExtOffset
));
1022 if (!Cursor
&& Verbose
) {
1023 DWARFDataExtractor::Cursor
ByteCursor(OperandOffset
);
1024 uint8_t Byte
= TableData
.getU8(ByteCursor
);
1026 *OS
<< " (<parsing error>";
1028 *OS
<< format(" %2.2" PRIx8
, Byte
);
1029 Byte
= TableData
.getU8(ByteCursor
);
1030 } while (ByteCursor
);
1034 // The only parse failure in this case should be if the end was reached.
1035 // In that case, throw away the error, as the main Cursor's error will
1037 consumeError(ByteCursor
.takeError());
1040 } else if (Opcode
< Prologue
.OpcodeBase
) {
1042 *OS
<< LNStandardString(Opcode
);
1046 // Takes no arguments. Append a row to the matrix using the
1047 // current values of the state-machine registers.
1051 case DW_LNS_advance_pc
:
1052 // Takes a single unsigned LEB128 operand as the operation advance
1053 // and modifies the address and op_index registers of the state machine
1054 // according to that.
1055 if (std::optional
<uint64_t> Operand
=
1056 parseULEB128
<uint64_t>(TableData
, Cursor
)) {
1057 ParsingState::AddrOpIndexDelta Advance
=
1058 State
.advanceAddrOpIndex(*Operand
, Opcode
, OpcodeOffset
);
1060 *OS
<< " (addr += " << Advance
.AddrOffset
1061 << ", op-index += " << Advance
.OpIndexDelta
<< ")";
1065 case DW_LNS_advance_line
:
1066 // Takes a single signed LEB128 operand and adds that value to
1067 // the line register of the state machine.
1069 int64_t LineDelta
= TableData
.getSLEB128(Cursor
);
1071 State
.Row
.Line
+= LineDelta
;
1073 *OS
<< " (" << State
.Row
.Line
<< ")";
1078 case DW_LNS_set_file
:
1079 // Takes a single unsigned LEB128 operand and stores it in the file
1080 // register of the state machine.
1081 if (std::optional
<uint16_t> File
=
1082 parseULEB128
<uint16_t>(TableData
, Cursor
)) {
1083 State
.Row
.File
= *File
;
1085 *OS
<< " (" << State
.Row
.File
<< ")";
1089 case DW_LNS_set_column
:
1090 // Takes a single unsigned LEB128 operand and stores it in the
1091 // column register of the state machine.
1092 if (std::optional
<uint16_t> Column
=
1093 parseULEB128
<uint16_t>(TableData
, Cursor
)) {
1094 State
.Row
.Column
= *Column
;
1096 *OS
<< " (" << State
.Row
.Column
<< ")";
1100 case DW_LNS_negate_stmt
:
1101 // Takes no arguments. Set the is_stmt register of the state
1102 // machine to the logical negation of its current value.
1103 State
.Row
.IsStmt
= !State
.Row
.IsStmt
;
1106 case DW_LNS_set_basic_block
:
1107 // Takes no arguments. Set the basic_block register of the
1108 // state machine to true
1109 State
.Row
.BasicBlock
= true;
1112 case DW_LNS_const_add_pc
:
1113 // Takes no arguments. Advance the address and op_index registers of
1114 // the state machine by the increments corresponding to special
1115 // opcode 255. The motivation for DW_LNS_const_add_pc is this:
1116 // when the statement program needs to advance the address by a
1117 // small amount, it can use a single special opcode, which occupies
1118 // a single byte. When it needs to advance the address by up to
1119 // twice the range of the last special opcode, it can use
1120 // DW_LNS_const_add_pc followed by a special opcode, for a total
1121 // of two bytes. Only if it needs to advance the address by more
1122 // than twice that range will it need to use both DW_LNS_advance_pc
1123 // and a special opcode, requiring three or more bytes.
1125 ParsingState::OpcodeAdvanceResults Advance
=
1126 State
.advanceForOpcode(Opcode
, OpcodeOffset
);
1128 *OS
<< format(" (addr += 0x%16.16" PRIx64
", op-index += %" PRIu8
1130 Advance
.AddrDelta
, Advance
.OpIndexDelta
);
1134 case DW_LNS_fixed_advance_pc
:
1135 // Takes a single uhalf operand. Add to the address register of
1136 // the state machine the value of the (unencoded) operand and set
1137 // the op_index register to 0. This is the only extended opcode that
1138 // takes an argument that is not a variable length number.
1139 // The motivation for DW_LNS_fixed_advance_pc is this: existing
1140 // assemblers cannot emit DW_LNS_advance_pc or special opcodes because
1141 // they cannot encode LEB128 numbers or judge when the computation
1142 // of a special opcode overflows and requires the use of
1143 // DW_LNS_advance_pc. Such assemblers, however, can use
1144 // DW_LNS_fixed_advance_pc instead, sacrificing compression.
1147 TableData
.getRelocatedValue(Cursor
, 2);
1149 State
.Row
.Address
.Address
+= PCOffset
;
1150 State
.Row
.OpIndex
= 0;
1152 *OS
<< format(" (addr += 0x%4.4" PRIx16
", op-index = 0)",
1158 case DW_LNS_set_prologue_end
:
1159 // Takes no arguments. Set the prologue_end register of the
1160 // state machine to true
1161 State
.Row
.PrologueEnd
= true;
1164 case DW_LNS_set_epilogue_begin
:
1165 // Takes no arguments. Set the basic_block register of the
1166 // state machine to true
1167 State
.Row
.EpilogueBegin
= true;
1170 case DW_LNS_set_isa
:
1171 // Takes a single unsigned LEB128 operand and stores it in the
1172 // ISA register of the state machine.
1173 if (std::optional
<uint8_t> Isa
=
1174 parseULEB128
<uint8_t>(TableData
, Cursor
)) {
1175 State
.Row
.Isa
= *Isa
;
1177 *OS
<< " (" << (uint64_t)State
.Row
.Isa
<< ")";
1182 // Handle any unknown standard opcodes here. We know the lengths
1183 // of such opcodes because they are specified in the prologue
1184 // as a multiple of LEB128 operands for each opcode.
1186 assert(Opcode
- 1U < Prologue
.StandardOpcodeLengths
.size());
1188 *OS
<< "Unrecognized standard opcode";
1189 uint8_t OpcodeLength
= Prologue
.StandardOpcodeLengths
[Opcode
- 1];
1190 std::vector
<uint64_t> Operands
;
1191 for (uint8_t I
= 0; I
< OpcodeLength
; ++I
) {
1192 if (std::optional
<uint64_t> Value
=
1193 parseULEB128
<uint64_t>(TableData
, Cursor
))
1194 Operands
.push_back(*Value
);
1198 if (Verbose
&& !Operands
.empty()) {
1199 *OS
<< " (operands: ";
1201 for (uint64_t Value
: Operands
) {
1205 *OS
<< format("0x%16.16" PRIx64
, Value
);
1214 *OffsetPtr
= Cursor
.tell();
1217 ParsingState::SpecialOpcodeDelta Delta
=
1218 State
.handleSpecialOpcode(Opcode
, OpcodeOffset
);
1221 *OS
<< "address += " << Delta
.Address
<< ", line += " << Delta
.Line
1222 << ", op-index += " << Delta
.OpIndex
;
1224 *OffsetPtr
= Cursor
.tell();
1227 // When a row is added to the matrix, it is also dumped, which includes a
1228 // new line already, so don't add an extra one.
1229 if (Verbose
&& Rows
.size() == RowCount
)
1232 // Most parse failures other than when parsing extended opcodes are due to
1233 // failures to read ULEBs. Bail out of parsing, since we don't know where to
1234 // continue reading from as there is no stated length for such byte
1235 // sequences. Print the final trailing new line if needed before doing so.
1236 if (!Cursor
&& Opcode
!= 0) {
1239 return Cursor
.takeError();
1243 RecoverableErrorHandler(Cursor
.takeError());
1246 if (!State
.Sequence
.Empty
)
1247 RecoverableErrorHandler(createStringError(
1248 errc::illegal_byte_sequence
,
1249 "last sequence in debug line table at offset 0x%8.8" PRIx64
1250 " is not terminated",
1253 // Sort all sequences so that address lookup will work faster.
1254 if (!Sequences
.empty()) {
1255 llvm::sort(Sequences
, Sequence::orderByHighPC
);
1256 // Note: actually, instruction address ranges of sequences should not
1257 // overlap (in shared objects and executables). If they do, the address
1258 // lookup would still work, though, but result would be ambiguous.
1259 // We don't report warning in this case. For example,
1260 // sometimes .so compiled from multiple object files contains a few
1261 // rudimentary sequences for address ranges [0x0, 0xsomething).
1264 // Terminate the table with a final blank line to clearly delineate it from
1269 return Error::success();
1272 uint32_t DWARFDebugLine::LineTable::findRowInSeq(
1273 const DWARFDebugLine::Sequence
&Seq
,
1274 object::SectionedAddress Address
) const {
1275 if (!Seq
.containsPC(Address
))
1276 return UnknownRowIndex
;
1277 assert(Seq
.SectionIndex
== Address
.SectionIndex
);
1278 // In some cases, e.g. first instruction in a function, the compiler generates
1279 // two entries, both with the same address. We want the last one.
1281 // In general we want a non-empty range: the last row whose address is less
1282 // than or equal to Address. This can be computed as upper_bound - 1.
1284 // TODO: This function, and its users, needs to be update to return multiple
1285 // rows for bundles with multiple op-indexes.
1286 DWARFDebugLine::Row Row
;
1287 Row
.Address
= Address
;
1288 RowIter FirstRow
= Rows
.begin() + Seq
.FirstRowIndex
;
1289 RowIter LastRow
= Rows
.begin() + Seq
.LastRowIndex
;
1290 assert(FirstRow
->Address
.Address
<= Row
.Address
.Address
&&
1291 Row
.Address
.Address
< LastRow
[-1].Address
.Address
);
1292 RowIter RowPos
= std::upper_bound(FirstRow
+ 1, LastRow
- 1, Row
,
1293 DWARFDebugLine::Row::orderByAddress
) -
1295 assert(Seq
.SectionIndex
== RowPos
->Address
.SectionIndex
);
1296 return RowPos
- Rows
.begin();
1299 uint32_t DWARFDebugLine::LineTable::lookupAddress(
1300 object::SectionedAddress Address
) const {
1302 // Search for relocatable addresses
1303 uint32_t Result
= lookupAddressImpl(Address
);
1305 if (Result
!= UnknownRowIndex
||
1306 Address
.SectionIndex
== object::SectionedAddress::UndefSection
)
1309 // Search for absolute addresses
1310 Address
.SectionIndex
= object::SectionedAddress::UndefSection
;
1311 return lookupAddressImpl(Address
);
1314 uint32_t DWARFDebugLine::LineTable::lookupAddressImpl(
1315 object::SectionedAddress Address
) const {
1316 // First, find an instruction sequence containing the given address.
1317 DWARFDebugLine::Sequence Sequence
;
1318 Sequence
.SectionIndex
= Address
.SectionIndex
;
1319 Sequence
.HighPC
= Address
.Address
;
1320 SequenceIter It
= llvm::upper_bound(Sequences
, Sequence
,
1321 DWARFDebugLine::Sequence::orderByHighPC
);
1322 if (It
== Sequences
.end() || It
->SectionIndex
!= Address
.SectionIndex
)
1323 return UnknownRowIndex
;
1324 return findRowInSeq(*It
, Address
);
1327 bool DWARFDebugLine::LineTable::lookupAddressRange(
1328 object::SectionedAddress Address
, uint64_t Size
,
1329 std::vector
<uint32_t> &Result
) const {
1331 // Search for relocatable addresses
1332 if (lookupAddressRangeImpl(Address
, Size
, Result
))
1335 if (Address
.SectionIndex
== object::SectionedAddress::UndefSection
)
1338 // Search for absolute addresses
1339 Address
.SectionIndex
= object::SectionedAddress::UndefSection
;
1340 return lookupAddressRangeImpl(Address
, Size
, Result
);
1343 bool DWARFDebugLine::LineTable::lookupAddressRangeImpl(
1344 object::SectionedAddress Address
, uint64_t Size
,
1345 std::vector
<uint32_t> &Result
) const {
1346 if (Sequences
.empty())
1348 uint64_t EndAddr
= Address
.Address
+ Size
;
1349 // First, find an instruction sequence containing the given address.
1350 DWARFDebugLine::Sequence Sequence
;
1351 Sequence
.SectionIndex
= Address
.SectionIndex
;
1352 Sequence
.HighPC
= Address
.Address
;
1353 SequenceIter LastSeq
= Sequences
.end();
1354 SequenceIter SeqPos
= llvm::upper_bound(
1355 Sequences
, Sequence
, DWARFDebugLine::Sequence::orderByHighPC
);
1356 if (SeqPos
== LastSeq
|| !SeqPos
->containsPC(Address
))
1359 SequenceIter StartPos
= SeqPos
;
1361 // Add the rows from the first sequence to the vector, starting with the
1362 // index we just calculated
1364 while (SeqPos
!= LastSeq
&& SeqPos
->LowPC
< EndAddr
) {
1365 const DWARFDebugLine::Sequence
&CurSeq
= *SeqPos
;
1366 // For the first sequence, we need to find which row in the sequence is the
1367 // first in our range.
1368 uint32_t FirstRowIndex
= CurSeq
.FirstRowIndex
;
1369 if (SeqPos
== StartPos
)
1370 FirstRowIndex
= findRowInSeq(CurSeq
, Address
);
1372 // Figure out the last row in the range.
1373 uint32_t LastRowIndex
=
1374 findRowInSeq(CurSeq
, {EndAddr
- 1, Address
.SectionIndex
});
1375 if (LastRowIndex
== UnknownRowIndex
)
1376 LastRowIndex
= CurSeq
.LastRowIndex
- 1;
1378 assert(FirstRowIndex
!= UnknownRowIndex
);
1379 assert(LastRowIndex
!= UnknownRowIndex
);
1381 for (uint32_t I
= FirstRowIndex
; I
<= LastRowIndex
; ++I
) {
1382 Result
.push_back(I
);
1391 std::optional
<StringRef
>
1392 DWARFDebugLine::LineTable::getSourceByIndex(uint64_t FileIndex
,
1393 FileLineInfoKind Kind
) const {
1394 if (Kind
== FileLineInfoKind::None
|| !Prologue
.hasFileAtIndex(FileIndex
))
1395 return std::nullopt
;
1396 const FileNameEntry
&Entry
= Prologue
.getFileNameEntry(FileIndex
);
1397 if (auto E
= dwarf::toString(Entry
.Source
))
1398 return StringRef(*E
);
1399 return std::nullopt
;
1402 static bool isPathAbsoluteOnWindowsOrPosix(const Twine
&Path
) {
1403 // Debug info can contain paths from any OS, not necessarily
1404 // an OS we're currently running on. Moreover different compilation units can
1405 // be compiled on different operating systems and linked together later.
1406 return sys::path::is_absolute(Path
, sys::path::Style::posix
) ||
1407 sys::path::is_absolute(Path
, sys::path::Style::windows
);
1410 bool DWARFDebugLine::Prologue::getFileNameByIndex(
1411 uint64_t FileIndex
, StringRef CompDir
, FileLineInfoKind Kind
,
1412 std::string
&Result
, sys::path::Style Style
) const {
1413 if (Kind
== FileLineInfoKind::None
|| !hasFileAtIndex(FileIndex
))
1415 const FileNameEntry
&Entry
= getFileNameEntry(FileIndex
);
1416 auto E
= dwarf::toString(Entry
.Name
);
1419 StringRef FileName
= *E
;
1420 if (Kind
== FileLineInfoKind::RawValue
||
1421 isPathAbsoluteOnWindowsOrPosix(FileName
)) {
1422 Result
= std::string(FileName
);
1425 if (Kind
== FileLineInfoKind::BaseNameOnly
) {
1426 Result
= std::string(llvm::sys::path::filename(FileName
));
1430 SmallString
<16> FilePath
;
1431 StringRef IncludeDir
;
1432 // Be defensive about the contents of Entry.
1433 if (getVersion() >= 5) {
1434 // DirIdx 0 is the compilation directory, so don't include it for
1436 if ((Entry
.DirIdx
!= 0 || Kind
!= FileLineInfoKind::RelativeFilePath
) &&
1437 Entry
.DirIdx
< IncludeDirectories
.size())
1438 IncludeDir
= dwarf::toStringRef(IncludeDirectories
[Entry
.DirIdx
]);
1440 if (0 < Entry
.DirIdx
&& Entry
.DirIdx
<= IncludeDirectories
.size())
1441 IncludeDir
= dwarf::toStringRef(IncludeDirectories
[Entry
.DirIdx
- 1]);
1444 // For absolute paths only, include the compilation directory of compile unit,
1445 // unless v5 DirIdx == 0 (IncludeDir indicates the compilation directory). We
1446 // know that FileName is not absolute, the only way to have an absolute path
1447 // at this point would be if IncludeDir is absolute.
1448 if (Kind
== FileLineInfoKind::AbsoluteFilePath
&&
1449 (getVersion() < 5 || Entry
.DirIdx
!= 0) && !CompDir
.empty() &&
1450 !isPathAbsoluteOnWindowsOrPosix(IncludeDir
))
1451 sys::path::append(FilePath
, Style
, CompDir
);
1453 assert((Kind
== FileLineInfoKind::AbsoluteFilePath
||
1454 Kind
== FileLineInfoKind::RelativeFilePath
) &&
1455 "invalid FileLineInfo Kind");
1457 // sys::path::append skips empty strings.
1458 sys::path::append(FilePath
, Style
, IncludeDir
, FileName
);
1459 Result
= std::string(FilePath
);
1463 bool DWARFDebugLine::LineTable::getFileLineInfoForAddress(
1464 object::SectionedAddress Address
, const char *CompDir
,
1465 FileLineInfoKind Kind
, DILineInfo
&Result
) const {
1466 // Get the index of row we're looking for in the line table.
1467 uint32_t RowIndex
= lookupAddress(Address
);
1468 if (RowIndex
== -1U)
1470 // Take file number and line/column from the row.
1471 const auto &Row
= Rows
[RowIndex
];
1472 if (!getFileNameByIndex(Row
.File
, CompDir
, Kind
, Result
.FileName
))
1474 Result
.Line
= Row
.Line
;
1475 Result
.Column
= Row
.Column
;
1476 Result
.Discriminator
= Row
.Discriminator
;
1477 Result
.Source
= getSourceByIndex(Row
.File
, Kind
);
1481 bool DWARFDebugLine::LineTable::getDirectoryForEntry(
1482 const FileNameEntry
&Entry
, std::string
&Directory
) const {
1483 if (Prologue
.getVersion() >= 5) {
1484 if (Entry
.DirIdx
< Prologue
.IncludeDirectories
.size()) {
1486 dwarf::toString(Prologue
.IncludeDirectories
[Entry
.DirIdx
], "");
1491 if (0 < Entry
.DirIdx
&& Entry
.DirIdx
<= Prologue
.IncludeDirectories
.size()) {
1493 dwarf::toString(Prologue
.IncludeDirectories
[Entry
.DirIdx
- 1], "");
1499 // We want to supply the Unit associated with a .debug_line[.dwo] table when
1500 // we dump it, if possible, but still dump the table even if there isn't a Unit.
1501 // Therefore, collect up handles on all the Units that point into the
1502 // line-table section.
1503 static DWARFDebugLine::SectionParser::LineToUnitMap
1504 buildLineToUnitMap(DWARFUnitVector::iterator_range Units
) {
1505 DWARFDebugLine::SectionParser::LineToUnitMap LineToUnit
;
1506 for (const auto &U
: Units
)
1507 if (auto CUDIE
= U
->getUnitDIE())
1508 if (auto StmtOffset
= toSectionOffset(CUDIE
.find(DW_AT_stmt_list
)))
1509 LineToUnit
.insert(std::make_pair(*StmtOffset
, &*U
));
1513 DWARFDebugLine::SectionParser::SectionParser(
1514 DWARFDataExtractor
&Data
, const DWARFContext
&C
,
1515 DWARFUnitVector::iterator_range Units
)
1516 : DebugLineData(Data
), Context(C
) {
1517 LineToUnit
= buildLineToUnitMap(Units
);
1518 if (!DebugLineData
.isValidOffset(Offset
))
1522 bool DWARFDebugLine::Prologue::totalLengthIsValid() const {
1523 return TotalLength
!= 0u;
1526 DWARFDebugLine::LineTable
DWARFDebugLine::SectionParser::parseNext(
1527 function_ref
<void(Error
)> RecoverableErrorHandler
,
1528 function_ref
<void(Error
)> UnrecoverableErrorHandler
, raw_ostream
*OS
,
1530 assert(DebugLineData
.isValidOffset(Offset
) &&
1531 "parsing should have terminated");
1532 DWARFUnit
*U
= prepareToParse(Offset
);
1533 uint64_t OldOffset
= Offset
;
1535 if (Error Err
= LT
.parse(DebugLineData
, &Offset
, Context
, U
,
1536 RecoverableErrorHandler
, OS
, Verbose
))
1537 UnrecoverableErrorHandler(std::move(Err
));
1538 moveToNextTable(OldOffset
, LT
.Prologue
);
1542 void DWARFDebugLine::SectionParser::skip(
1543 function_ref
<void(Error
)> RecoverableErrorHandler
,
1544 function_ref
<void(Error
)> UnrecoverableErrorHandler
) {
1545 assert(DebugLineData
.isValidOffset(Offset
) &&
1546 "parsing should have terminated");
1547 DWARFUnit
*U
= prepareToParse(Offset
);
1548 uint64_t OldOffset
= Offset
;
1550 if (Error Err
= LT
.Prologue
.parse(DebugLineData
, &Offset
,
1551 RecoverableErrorHandler
, Context
, U
))
1552 UnrecoverableErrorHandler(std::move(Err
));
1553 moveToNextTable(OldOffset
, LT
.Prologue
);
1556 DWARFUnit
*DWARFDebugLine::SectionParser::prepareToParse(uint64_t Offset
) {
1557 DWARFUnit
*U
= nullptr;
1558 auto It
= LineToUnit
.find(Offset
);
1559 if (It
!= LineToUnit
.end())
1561 DebugLineData
.setAddressSize(U
? U
->getAddressByteSize() : 0);
1565 bool DWARFDebugLine::SectionParser::hasValidVersion(uint64_t Offset
) {
1566 DataExtractor::Cursor
Cursor(Offset
);
1567 auto [TotalLength
, _
] = DebugLineData
.getInitialLength(Cursor
);
1568 DWARFDataExtractor
HeaderData(DebugLineData
, Cursor
.tell() + TotalLength
);
1569 uint16_t Version
= HeaderData
.getU16(Cursor
);
1571 // Ignore any error here.
1572 // If this is not the end of the section parseNext() will still be
1573 // attempted, where this error will occur again (and can be handled).
1574 consumeError(Cursor
.takeError());
1577 return versionIsSupported(Version
);
1580 void DWARFDebugLine::SectionParser::moveToNextTable(uint64_t OldOffset
,
1581 const Prologue
&P
) {
1582 // If the length field is not valid, we don't know where the next table is, so
1583 // cannot continue to parse. Mark the parser as done, and leave the Offset
1584 // value as it currently is. This will be the end of the bad length field.
1585 if (!P
.totalLengthIsValid()) {
1590 Offset
= OldOffset
+ P
.TotalLength
+ P
.sizeofTotalLength();
1591 if (!DebugLineData
.isValidOffset(Offset
)) {
1596 // Heuristic: If the version is valid, then this is probably a line table.
1597 // Otherwise, the offset might need alignment (to a 4 or 8 byte boundary).
1598 if (hasValidVersion(Offset
))
1601 // ARM C/C++ Compiler aligns each line table to word boundaries and pads out
1602 // the .debug_line section to a word multiple. Note that in the specification
1603 // this does not seem forbidden since each unit has a DW_AT_stmt_list.
1604 for (unsigned Align
: {4, 8}) {
1605 uint64_t AlignedOffset
= alignTo(Offset
, Align
);
1606 if (!DebugLineData
.isValidOffset(AlignedOffset
)) {
1607 // This is almost certainly not another line table but some alignment
1608 // padding. This assumes the alignments tested are ordered, and are
1609 // smaller than the header size (which is true for 4 and 8).
1613 if (hasValidVersion(AlignedOffset
)) {
1614 Offset
= AlignedOffset
;