106f32e7eSjoerg //===- DWARFDebugLine.cpp -------------------------------------------------===//
206f32e7eSjoerg //
306f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information.
506f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606f32e7eSjoerg //
706f32e7eSjoerg //===----------------------------------------------------------------------===//
806f32e7eSjoerg 
906f32e7eSjoerg #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
1006f32e7eSjoerg #include "llvm/ADT/Optional.h"
1106f32e7eSjoerg #include "llvm/ADT/SmallString.h"
1206f32e7eSjoerg #include "llvm/ADT/SmallVector.h"
1306f32e7eSjoerg #include "llvm/ADT/StringRef.h"
1406f32e7eSjoerg #include "llvm/BinaryFormat/Dwarf.h"
1506f32e7eSjoerg #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
1606f32e7eSjoerg #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
1706f32e7eSjoerg #include "llvm/Support/Errc.h"
1806f32e7eSjoerg #include "llvm/Support/Format.h"
19*da58b97aSjoerg #include "llvm/Support/FormatVariadic.h"
2006f32e7eSjoerg #include "llvm/Support/WithColor.h"
2106f32e7eSjoerg #include "llvm/Support/raw_ostream.h"
2206f32e7eSjoerg #include <algorithm>
2306f32e7eSjoerg #include <cassert>
2406f32e7eSjoerg #include <cinttypes>
2506f32e7eSjoerg #include <cstdint>
2606f32e7eSjoerg #include <cstdio>
2706f32e7eSjoerg #include <utility>
2806f32e7eSjoerg 
2906f32e7eSjoerg using namespace llvm;
3006f32e7eSjoerg using namespace dwarf;
3106f32e7eSjoerg 
3206f32e7eSjoerg using FileLineInfoKind = DILineInfoSpecifier::FileLineInfoKind;
3306f32e7eSjoerg 
3406f32e7eSjoerg namespace {
3506f32e7eSjoerg 
3606f32e7eSjoerg struct ContentDescriptor {
3706f32e7eSjoerg   dwarf::LineNumberEntryFormat Type;
3806f32e7eSjoerg   dwarf::Form Form;
3906f32e7eSjoerg };
4006f32e7eSjoerg 
4106f32e7eSjoerg using ContentDescriptors = SmallVector<ContentDescriptor, 4>;
4206f32e7eSjoerg 
43*da58b97aSjoerg } // end anonymous namespace
44*da58b97aSjoerg 
versionIsSupported(uint16_t Version)45*da58b97aSjoerg static bool versionIsSupported(uint16_t Version) {
46*da58b97aSjoerg   return Version >= 2 && Version <= 5;
47*da58b97aSjoerg }
4806f32e7eSjoerg 
trackContentType(dwarf::LineNumberEntryFormat ContentType)4906f32e7eSjoerg void DWARFDebugLine::ContentTypeTracker::trackContentType(
5006f32e7eSjoerg     dwarf::LineNumberEntryFormat ContentType) {
5106f32e7eSjoerg   switch (ContentType) {
5206f32e7eSjoerg   case dwarf::DW_LNCT_timestamp:
5306f32e7eSjoerg     HasModTime = true;
5406f32e7eSjoerg     break;
5506f32e7eSjoerg   case dwarf::DW_LNCT_size:
5606f32e7eSjoerg     HasLength = true;
5706f32e7eSjoerg     break;
5806f32e7eSjoerg   case dwarf::DW_LNCT_MD5:
5906f32e7eSjoerg     HasMD5 = true;
6006f32e7eSjoerg     break;
6106f32e7eSjoerg   case dwarf::DW_LNCT_LLVM_source:
6206f32e7eSjoerg     HasSource = true;
6306f32e7eSjoerg     break;
6406f32e7eSjoerg   default:
6506f32e7eSjoerg     // We only care about values we consider optional, and new values may be
6606f32e7eSjoerg     // added in the vendor extension range, so we do not match exhaustively.
6706f32e7eSjoerg     break;
6806f32e7eSjoerg   }
6906f32e7eSjoerg }
7006f32e7eSjoerg 
Prologue()7106f32e7eSjoerg DWARFDebugLine::Prologue::Prologue() { clear(); }
7206f32e7eSjoerg 
hasFileAtIndex(uint64_t FileIndex) const7306f32e7eSjoerg bool DWARFDebugLine::Prologue::hasFileAtIndex(uint64_t FileIndex) const {
7406f32e7eSjoerg   uint16_t DwarfVersion = getVersion();
7506f32e7eSjoerg   assert(DwarfVersion != 0 &&
7606f32e7eSjoerg          "line table prologue has no dwarf version information");
7706f32e7eSjoerg   if (DwarfVersion >= 5)
7806f32e7eSjoerg     return FileIndex < FileNames.size();
7906f32e7eSjoerg   return FileIndex != 0 && FileIndex <= FileNames.size();
8006f32e7eSjoerg }
8106f32e7eSjoerg 
getLastValidFileIndex() const82*da58b97aSjoerg Optional<uint64_t> DWARFDebugLine::Prologue::getLastValidFileIndex() const {
83*da58b97aSjoerg   if (FileNames.empty())
84*da58b97aSjoerg     return None;
85*da58b97aSjoerg   uint16_t DwarfVersion = getVersion();
86*da58b97aSjoerg   assert(DwarfVersion != 0 &&
87*da58b97aSjoerg          "line table prologue has no dwarf version information");
88*da58b97aSjoerg   // In DWARF v5 the file names are 0-indexed.
89*da58b97aSjoerg   if (DwarfVersion >= 5)
90*da58b97aSjoerg     return FileNames.size() - 1;
91*da58b97aSjoerg   return FileNames.size();
92*da58b97aSjoerg }
93*da58b97aSjoerg 
9406f32e7eSjoerg const llvm::DWARFDebugLine::FileNameEntry &
getFileNameEntry(uint64_t Index) const9506f32e7eSjoerg DWARFDebugLine::Prologue::getFileNameEntry(uint64_t Index) const {
9606f32e7eSjoerg   uint16_t DwarfVersion = getVersion();
9706f32e7eSjoerg   assert(DwarfVersion != 0 &&
9806f32e7eSjoerg          "line table prologue has no dwarf version information");
9906f32e7eSjoerg   // In DWARF v5 the file names are 0-indexed.
10006f32e7eSjoerg   if (DwarfVersion >= 5)
10106f32e7eSjoerg     return FileNames[Index];
10206f32e7eSjoerg   return FileNames[Index - 1];
10306f32e7eSjoerg }
10406f32e7eSjoerg 
clear()10506f32e7eSjoerg void DWARFDebugLine::Prologue::clear() {
10606f32e7eSjoerg   TotalLength = PrologueLength = 0;
10706f32e7eSjoerg   SegSelectorSize = 0;
10806f32e7eSjoerg   MinInstLength = MaxOpsPerInst = DefaultIsStmt = LineBase = LineRange = 0;
10906f32e7eSjoerg   OpcodeBase = 0;
11006f32e7eSjoerg   FormParams = dwarf::FormParams({0, 0, DWARF32});
11106f32e7eSjoerg   ContentTypes = ContentTypeTracker();
11206f32e7eSjoerg   StandardOpcodeLengths.clear();
11306f32e7eSjoerg   IncludeDirectories.clear();
11406f32e7eSjoerg   FileNames.clear();
11506f32e7eSjoerg }
11606f32e7eSjoerg 
dump(raw_ostream & OS,DIDumpOptions DumpOptions) const11706f32e7eSjoerg void DWARFDebugLine::Prologue::dump(raw_ostream &OS,
11806f32e7eSjoerg                                     DIDumpOptions DumpOptions) const {
119*da58b97aSjoerg   if (!totalLengthIsValid())
120*da58b97aSjoerg     return;
121*da58b97aSjoerg   int OffsetDumpWidth = 2 * dwarf::getDwarfOffsetByteSize(FormParams.Format);
12206f32e7eSjoerg   OS << "Line table prologue:\n"
123*da58b97aSjoerg      << format("    total_length: 0x%0*" PRIx64 "\n", OffsetDumpWidth,
124*da58b97aSjoerg                TotalLength)
125*da58b97aSjoerg      << "          format: " << dwarf::FormatString(FormParams.Format) << "\n"
12606f32e7eSjoerg      << format("         version: %u\n", getVersion());
127*da58b97aSjoerg   if (!versionIsSupported(getVersion()))
128*da58b97aSjoerg     return;
12906f32e7eSjoerg   if (getVersion() >= 5)
13006f32e7eSjoerg     OS << format("    address_size: %u\n", getAddressSize())
13106f32e7eSjoerg        << format(" seg_select_size: %u\n", SegSelectorSize);
132*da58b97aSjoerg   OS << format(" prologue_length: 0x%0*" PRIx64 "\n", OffsetDumpWidth,
133*da58b97aSjoerg                PrologueLength)
13406f32e7eSjoerg      << format(" min_inst_length: %u\n", MinInstLength)
13506f32e7eSjoerg      << format(getVersion() >= 4 ? "max_ops_per_inst: %u\n" : "", MaxOpsPerInst)
13606f32e7eSjoerg      << format(" default_is_stmt: %u\n", DefaultIsStmt)
13706f32e7eSjoerg      << format("       line_base: %i\n", LineBase)
13806f32e7eSjoerg      << format("      line_range: %u\n", LineRange)
13906f32e7eSjoerg      << format("     opcode_base: %u\n", OpcodeBase);
14006f32e7eSjoerg 
14106f32e7eSjoerg   for (uint32_t I = 0; I != StandardOpcodeLengths.size(); ++I)
142*da58b97aSjoerg     OS << formatv("standard_opcode_lengths[{0}] = {1}\n",
143*da58b97aSjoerg                   static_cast<dwarf::LineNumberOps>(I + 1),
144*da58b97aSjoerg                   StandardOpcodeLengths[I]);
14506f32e7eSjoerg 
14606f32e7eSjoerg   if (!IncludeDirectories.empty()) {
14706f32e7eSjoerg     // DWARF v5 starts directory indexes at 0.
14806f32e7eSjoerg     uint32_t DirBase = getVersion() >= 5 ? 0 : 1;
14906f32e7eSjoerg     for (uint32_t I = 0; I != IncludeDirectories.size(); ++I) {
15006f32e7eSjoerg       OS << format("include_directories[%3u] = ", I + DirBase);
15106f32e7eSjoerg       IncludeDirectories[I].dump(OS, DumpOptions);
15206f32e7eSjoerg       OS << '\n';
15306f32e7eSjoerg     }
15406f32e7eSjoerg   }
15506f32e7eSjoerg 
15606f32e7eSjoerg   if (!FileNames.empty()) {
15706f32e7eSjoerg     // DWARF v5 starts file indexes at 0.
15806f32e7eSjoerg     uint32_t FileBase = getVersion() >= 5 ? 0 : 1;
15906f32e7eSjoerg     for (uint32_t I = 0; I != FileNames.size(); ++I) {
16006f32e7eSjoerg       const FileNameEntry &FileEntry = FileNames[I];
16106f32e7eSjoerg       OS <<   format("file_names[%3u]:\n", I + FileBase);
16206f32e7eSjoerg       OS <<          "           name: ";
16306f32e7eSjoerg       FileEntry.Name.dump(OS, DumpOptions);
16406f32e7eSjoerg       OS << '\n'
16506f32e7eSjoerg          <<   format("      dir_index: %" PRIu64 "\n", FileEntry.DirIdx);
16606f32e7eSjoerg       if (ContentTypes.HasMD5)
16706f32e7eSjoerg         OS <<        "   md5_checksum: " << FileEntry.Checksum.digest() << '\n';
16806f32e7eSjoerg       if (ContentTypes.HasModTime)
16906f32e7eSjoerg         OS << format("       mod_time: 0x%8.8" PRIx64 "\n", FileEntry.ModTime);
17006f32e7eSjoerg       if (ContentTypes.HasLength)
17106f32e7eSjoerg         OS << format("         length: 0x%8.8" PRIx64 "\n", FileEntry.Length);
17206f32e7eSjoerg       if (ContentTypes.HasSource) {
17306f32e7eSjoerg         OS <<        "         source: ";
17406f32e7eSjoerg         FileEntry.Source.dump(OS, DumpOptions);
17506f32e7eSjoerg         OS << '\n';
17606f32e7eSjoerg       }
17706f32e7eSjoerg     }
17806f32e7eSjoerg   }
17906f32e7eSjoerg }
18006f32e7eSjoerg 
18106f32e7eSjoerg // Parse v2-v4 directory and file tables.
182*da58b97aSjoerg static Error
parseV2DirFileTables(const DWARFDataExtractor & DebugLineData,uint64_t * OffsetPtr,DWARFDebugLine::ContentTypeTracker & ContentTypes,std::vector<DWARFFormValue> & IncludeDirectories,std::vector<DWARFDebugLine::FileNameEntry> & FileNames)18306f32e7eSjoerg parseV2DirFileTables(const DWARFDataExtractor &DebugLineData,
184*da58b97aSjoerg                      uint64_t *OffsetPtr,
18506f32e7eSjoerg                      DWARFDebugLine::ContentTypeTracker &ContentTypes,
18606f32e7eSjoerg                      std::vector<DWARFFormValue> &IncludeDirectories,
18706f32e7eSjoerg                      std::vector<DWARFDebugLine::FileNameEntry> &FileNames) {
188*da58b97aSjoerg   while (true) {
189*da58b97aSjoerg     Error Err = Error::success();
190*da58b97aSjoerg     StringRef S = DebugLineData.getCStrRef(OffsetPtr, &Err);
191*da58b97aSjoerg     if (Err) {
192*da58b97aSjoerg       consumeError(std::move(Err));
193*da58b97aSjoerg       return createStringError(errc::invalid_argument,
194*da58b97aSjoerg                                "include directories table was not null "
195*da58b97aSjoerg                                "terminated before the end of the prologue");
196*da58b97aSjoerg     }
19706f32e7eSjoerg     if (S.empty())
19806f32e7eSjoerg       break;
19906f32e7eSjoerg     DWARFFormValue Dir =
20006f32e7eSjoerg         DWARFFormValue::createFromPValue(dwarf::DW_FORM_string, S.data());
20106f32e7eSjoerg     IncludeDirectories.push_back(Dir);
20206f32e7eSjoerg   }
20306f32e7eSjoerg 
204*da58b97aSjoerg   ContentTypes.HasModTime = true;
205*da58b97aSjoerg   ContentTypes.HasLength = true;
206*da58b97aSjoerg 
207*da58b97aSjoerg   while (true) {
208*da58b97aSjoerg     Error Err = Error::success();
209*da58b97aSjoerg     StringRef Name = DebugLineData.getCStrRef(OffsetPtr, &Err);
210*da58b97aSjoerg     if (!Err && Name.empty())
21106f32e7eSjoerg       break;
212*da58b97aSjoerg 
21306f32e7eSjoerg     DWARFDebugLine::FileNameEntry FileEntry;
21406f32e7eSjoerg     FileEntry.Name =
21506f32e7eSjoerg         DWARFFormValue::createFromPValue(dwarf::DW_FORM_string, Name.data());
216*da58b97aSjoerg     FileEntry.DirIdx = DebugLineData.getULEB128(OffsetPtr, &Err);
217*da58b97aSjoerg     FileEntry.ModTime = DebugLineData.getULEB128(OffsetPtr, &Err);
218*da58b97aSjoerg     FileEntry.Length = DebugLineData.getULEB128(OffsetPtr, &Err);
219*da58b97aSjoerg 
220*da58b97aSjoerg     if (Err) {
221*da58b97aSjoerg       consumeError(std::move(Err));
222*da58b97aSjoerg       return createStringError(
223*da58b97aSjoerg           errc::invalid_argument,
224*da58b97aSjoerg           "file names table was not null terminated before "
225*da58b97aSjoerg           "the end of the prologue");
226*da58b97aSjoerg     }
22706f32e7eSjoerg     FileNames.push_back(FileEntry);
22806f32e7eSjoerg   }
22906f32e7eSjoerg 
230*da58b97aSjoerg   return Error::success();
23106f32e7eSjoerg }
23206f32e7eSjoerg 
23306f32e7eSjoerg // Parse v5 directory/file entry content descriptions.
23406f32e7eSjoerg // Returns the descriptors, or an error if we did not find a path or ran off
23506f32e7eSjoerg // the end of the prologue.
23606f32e7eSjoerg static llvm::Expected<ContentDescriptors>
parseV5EntryFormat(const DWARFDataExtractor & DebugLineData,uint64_t * OffsetPtr,DWARFDebugLine::ContentTypeTracker * ContentTypes)23706f32e7eSjoerg parseV5EntryFormat(const DWARFDataExtractor &DebugLineData, uint64_t *OffsetPtr,
23806f32e7eSjoerg                    DWARFDebugLine::ContentTypeTracker *ContentTypes) {
239*da58b97aSjoerg   Error Err = Error::success();
24006f32e7eSjoerg   ContentDescriptors Descriptors;
241*da58b97aSjoerg   int FormatCount = DebugLineData.getU8(OffsetPtr, &Err);
24206f32e7eSjoerg   bool HasPath = false;
243*da58b97aSjoerg   for (int I = 0; I != FormatCount && !Err; ++I) {
24406f32e7eSjoerg     ContentDescriptor Descriptor;
24506f32e7eSjoerg     Descriptor.Type =
246*da58b97aSjoerg         dwarf::LineNumberEntryFormat(DebugLineData.getULEB128(OffsetPtr, &Err));
247*da58b97aSjoerg     Descriptor.Form = dwarf::Form(DebugLineData.getULEB128(OffsetPtr, &Err));
24806f32e7eSjoerg     if (Descriptor.Type == dwarf::DW_LNCT_path)
24906f32e7eSjoerg       HasPath = true;
25006f32e7eSjoerg     if (ContentTypes)
25106f32e7eSjoerg       ContentTypes->trackContentType(Descriptor.Type);
25206f32e7eSjoerg     Descriptors.push_back(Descriptor);
25306f32e7eSjoerg   }
25406f32e7eSjoerg 
255*da58b97aSjoerg   if (Err)
256*da58b97aSjoerg     return createStringError(errc::invalid_argument,
257*da58b97aSjoerg                              "failed to parse entry content descriptors: %s",
258*da58b97aSjoerg                              toString(std::move(Err)).c_str());
259*da58b97aSjoerg 
26006f32e7eSjoerg   if (!HasPath)
26106f32e7eSjoerg     return createStringError(errc::invalid_argument,
26206f32e7eSjoerg                              "failed to parse entry content descriptions"
26306f32e7eSjoerg                              " because no path was found");
26406f32e7eSjoerg   return Descriptors;
26506f32e7eSjoerg }
26606f32e7eSjoerg 
26706f32e7eSjoerg static Error
parseV5DirFileTables(const DWARFDataExtractor & DebugLineData,uint64_t * OffsetPtr,const dwarf::FormParams & FormParams,const DWARFContext & Ctx,const DWARFUnit * U,DWARFDebugLine::ContentTypeTracker & ContentTypes,std::vector<DWARFFormValue> & IncludeDirectories,std::vector<DWARFDebugLine::FileNameEntry> & FileNames)26806f32e7eSjoerg parseV5DirFileTables(const DWARFDataExtractor &DebugLineData,
269*da58b97aSjoerg                      uint64_t *OffsetPtr, const dwarf::FormParams &FormParams,
27006f32e7eSjoerg                      const DWARFContext &Ctx, const DWARFUnit *U,
27106f32e7eSjoerg                      DWARFDebugLine::ContentTypeTracker &ContentTypes,
27206f32e7eSjoerg                      std::vector<DWARFFormValue> &IncludeDirectories,
27306f32e7eSjoerg                      std::vector<DWARFDebugLine::FileNameEntry> &FileNames) {
27406f32e7eSjoerg   // Get the directory entry description.
27506f32e7eSjoerg   llvm::Expected<ContentDescriptors> DirDescriptors =
276*da58b97aSjoerg       parseV5EntryFormat(DebugLineData, OffsetPtr, nullptr);
27706f32e7eSjoerg   if (!DirDescriptors)
27806f32e7eSjoerg     return DirDescriptors.takeError();
27906f32e7eSjoerg 
28006f32e7eSjoerg   // Get the directory entries, according to the format described above.
281*da58b97aSjoerg   uint64_t DirEntryCount = DebugLineData.getULEB128(OffsetPtr);
282*da58b97aSjoerg   for (uint64_t I = 0; I != DirEntryCount; ++I) {
28306f32e7eSjoerg     for (auto Descriptor : *DirDescriptors) {
28406f32e7eSjoerg       DWARFFormValue Value(Descriptor.Form);
28506f32e7eSjoerg       switch (Descriptor.Type) {
28606f32e7eSjoerg       case DW_LNCT_path:
28706f32e7eSjoerg         if (!Value.extractValue(DebugLineData, OffsetPtr, FormParams, &Ctx, U))
28806f32e7eSjoerg           return createStringError(errc::invalid_argument,
28906f32e7eSjoerg                                    "failed to parse directory entry because "
290*da58b97aSjoerg                                    "extracting the form value failed");
29106f32e7eSjoerg         IncludeDirectories.push_back(Value);
29206f32e7eSjoerg         break;
29306f32e7eSjoerg       default:
29406f32e7eSjoerg         if (!Value.skipValue(DebugLineData, OffsetPtr, FormParams))
29506f32e7eSjoerg           return createStringError(errc::invalid_argument,
29606f32e7eSjoerg                                    "failed to parse directory entry because "
297*da58b97aSjoerg                                    "skipping the form value failed");
29806f32e7eSjoerg       }
29906f32e7eSjoerg     }
30006f32e7eSjoerg   }
30106f32e7eSjoerg 
30206f32e7eSjoerg   // Get the file entry description.
303*da58b97aSjoerg   llvm::Expected<ContentDescriptors> FileDescriptors =
304*da58b97aSjoerg       parseV5EntryFormat(DebugLineData, OffsetPtr, &ContentTypes);
30506f32e7eSjoerg   if (!FileDescriptors)
30606f32e7eSjoerg     return FileDescriptors.takeError();
30706f32e7eSjoerg 
30806f32e7eSjoerg   // Get the file entries, according to the format described above.
309*da58b97aSjoerg   uint64_t FileEntryCount = DebugLineData.getULEB128(OffsetPtr);
310*da58b97aSjoerg   for (uint64_t I = 0; I != FileEntryCount; ++I) {
31106f32e7eSjoerg     DWARFDebugLine::FileNameEntry FileEntry;
31206f32e7eSjoerg     for (auto Descriptor : *FileDescriptors) {
31306f32e7eSjoerg       DWARFFormValue Value(Descriptor.Form);
31406f32e7eSjoerg       if (!Value.extractValue(DebugLineData, OffsetPtr, FormParams, &Ctx, U))
31506f32e7eSjoerg         return createStringError(errc::invalid_argument,
31606f32e7eSjoerg                                  "failed to parse file entry because "
317*da58b97aSjoerg                                  "extracting the form value failed");
31806f32e7eSjoerg       switch (Descriptor.Type) {
31906f32e7eSjoerg       case DW_LNCT_path:
32006f32e7eSjoerg         FileEntry.Name = Value;
32106f32e7eSjoerg         break;
32206f32e7eSjoerg       case DW_LNCT_LLVM_source:
32306f32e7eSjoerg         FileEntry.Source = Value;
32406f32e7eSjoerg         break;
32506f32e7eSjoerg       case DW_LNCT_directory_index:
32606f32e7eSjoerg         FileEntry.DirIdx = Value.getAsUnsignedConstant().getValue();
32706f32e7eSjoerg         break;
32806f32e7eSjoerg       case DW_LNCT_timestamp:
32906f32e7eSjoerg         FileEntry.ModTime = Value.getAsUnsignedConstant().getValue();
33006f32e7eSjoerg         break;
33106f32e7eSjoerg       case DW_LNCT_size:
33206f32e7eSjoerg         FileEntry.Length = Value.getAsUnsignedConstant().getValue();
33306f32e7eSjoerg         break;
33406f32e7eSjoerg       case DW_LNCT_MD5:
33506f32e7eSjoerg         if (!Value.getAsBlock() || Value.getAsBlock().getValue().size() != 16)
33606f32e7eSjoerg           return createStringError(
33706f32e7eSjoerg               errc::invalid_argument,
33806f32e7eSjoerg               "failed to parse file entry because the MD5 hash is invalid");
33906f32e7eSjoerg         std::uninitialized_copy_n(Value.getAsBlock().getValue().begin(), 16,
34006f32e7eSjoerg                                   FileEntry.Checksum.Bytes.begin());
34106f32e7eSjoerg         break;
34206f32e7eSjoerg       default:
34306f32e7eSjoerg         break;
34406f32e7eSjoerg       }
34506f32e7eSjoerg     }
34606f32e7eSjoerg     FileNames.push_back(FileEntry);
34706f32e7eSjoerg   }
34806f32e7eSjoerg   return Error::success();
34906f32e7eSjoerg }
35006f32e7eSjoerg 
getLength() const351*da58b97aSjoerg uint64_t DWARFDebugLine::Prologue::getLength() const {
352*da58b97aSjoerg   uint64_t Length = PrologueLength + sizeofTotalLength() +
353*da58b97aSjoerg                     sizeof(getVersion()) + sizeofPrologueLength();
354*da58b97aSjoerg   if (getVersion() >= 5)
355*da58b97aSjoerg     Length += 2; // Address + Segment selector sizes.
356*da58b97aSjoerg   return Length;
357*da58b97aSjoerg }
358*da58b97aSjoerg 
parse(DWARFDataExtractor DebugLineData,uint64_t * OffsetPtr,function_ref<void (Error)> RecoverableErrorHandler,const DWARFContext & Ctx,const DWARFUnit * U)359*da58b97aSjoerg Error DWARFDebugLine::Prologue::parse(
360*da58b97aSjoerg     DWARFDataExtractor DebugLineData, uint64_t *OffsetPtr,
361*da58b97aSjoerg     function_ref<void(Error)> RecoverableErrorHandler, const DWARFContext &Ctx,
36206f32e7eSjoerg     const DWARFUnit *U) {
36306f32e7eSjoerg   const uint64_t PrologueOffset = *OffsetPtr;
36406f32e7eSjoerg 
36506f32e7eSjoerg   clear();
366*da58b97aSjoerg   DataExtractor::Cursor Cursor(*OffsetPtr);
367*da58b97aSjoerg   std::tie(TotalLength, FormParams.Format) =
368*da58b97aSjoerg       DebugLineData.getInitialLength(Cursor);
369*da58b97aSjoerg 
370*da58b97aSjoerg   DebugLineData =
371*da58b97aSjoerg       DWARFDataExtractor(DebugLineData, Cursor.tell() + TotalLength);
372*da58b97aSjoerg   FormParams.Version = DebugLineData.getU16(Cursor);
373*da58b97aSjoerg   if (Cursor && !versionIsSupported(getVersion())) {
374*da58b97aSjoerg     // Treat this error as unrecoverable - we cannot be sure what any of
375*da58b97aSjoerg     // the data represents including the length field, so cannot skip it or make
376*da58b97aSjoerg     // any reasonable assumptions.
377*da58b97aSjoerg     *OffsetPtr = Cursor.tell();
378*da58b97aSjoerg     return createStringError(
379*da58b97aSjoerg         errc::not_supported,
38006f32e7eSjoerg         "parsing line table prologue at offset 0x%8.8" PRIx64
381*da58b97aSjoerg         ": unsupported version %" PRIu16,
38206f32e7eSjoerg         PrologueOffset, getVersion());
383*da58b97aSjoerg   }
38406f32e7eSjoerg 
38506f32e7eSjoerg   if (getVersion() >= 5) {
386*da58b97aSjoerg     FormParams.AddrSize = DebugLineData.getU8(Cursor);
387*da58b97aSjoerg     assert((!Cursor || DebugLineData.getAddressSize() == 0 ||
38806f32e7eSjoerg             DebugLineData.getAddressSize() == getAddressSize()) &&
38906f32e7eSjoerg            "Line table header and data extractor disagree");
390*da58b97aSjoerg     SegSelectorSize = DebugLineData.getU8(Cursor);
39106f32e7eSjoerg   }
39206f32e7eSjoerg 
39306f32e7eSjoerg   PrologueLength =
394*da58b97aSjoerg       DebugLineData.getRelocatedValue(Cursor, sizeofPrologueLength());
395*da58b97aSjoerg   const uint64_t EndPrologueOffset = PrologueLength + Cursor.tell();
396*da58b97aSjoerg   DebugLineData = DWARFDataExtractor(DebugLineData, EndPrologueOffset);
397*da58b97aSjoerg   MinInstLength = DebugLineData.getU8(Cursor);
39806f32e7eSjoerg   if (getVersion() >= 4)
399*da58b97aSjoerg     MaxOpsPerInst = DebugLineData.getU8(Cursor);
400*da58b97aSjoerg   DefaultIsStmt = DebugLineData.getU8(Cursor);
401*da58b97aSjoerg   LineBase = DebugLineData.getU8(Cursor);
402*da58b97aSjoerg   LineRange = DebugLineData.getU8(Cursor);
403*da58b97aSjoerg   OpcodeBase = DebugLineData.getU8(Cursor);
40406f32e7eSjoerg 
405*da58b97aSjoerg   if (Cursor && OpcodeBase == 0) {
406*da58b97aSjoerg     // If the opcode base is 0, we cannot read the standard opcode lengths (of
407*da58b97aSjoerg     // which there are supposed to be one fewer than the opcode base). Assume
408*da58b97aSjoerg     // there are no standard opcodes and continue parsing.
409*da58b97aSjoerg     RecoverableErrorHandler(createStringError(
410*da58b97aSjoerg         errc::invalid_argument,
411*da58b97aSjoerg         "parsing line table prologue at offset 0x%8.8" PRIx64
412*da58b97aSjoerg         " found opcode base of 0. Assuming no standard opcodes",
413*da58b97aSjoerg         PrologueOffset));
414*da58b97aSjoerg   } else if (Cursor) {
41506f32e7eSjoerg     StandardOpcodeLengths.reserve(OpcodeBase - 1);
41606f32e7eSjoerg     for (uint32_t I = 1; I < OpcodeBase; ++I) {
417*da58b97aSjoerg       uint8_t OpLen = DebugLineData.getU8(Cursor);
41806f32e7eSjoerg       StandardOpcodeLengths.push_back(OpLen);
41906f32e7eSjoerg     }
420*da58b97aSjoerg   }
42106f32e7eSjoerg 
422*da58b97aSjoerg   *OffsetPtr = Cursor.tell();
423*da58b97aSjoerg   // A corrupt file name or directory table does not prevent interpretation of
424*da58b97aSjoerg   // the main line program, so check the cursor state now so that its errors can
425*da58b97aSjoerg   // be handled separately.
426*da58b97aSjoerg   if (!Cursor)
427*da58b97aSjoerg     return createStringError(
428*da58b97aSjoerg         errc::invalid_argument,
429*da58b97aSjoerg         "parsing line table prologue at offset 0x%8.8" PRIx64 ": %s",
430*da58b97aSjoerg         PrologueOffset, toString(Cursor.takeError()).c_str());
431*da58b97aSjoerg 
432*da58b97aSjoerg   Error E =
433*da58b97aSjoerg       getVersion() >= 5
434*da58b97aSjoerg           ? parseV5DirFileTables(DebugLineData, OffsetPtr, FormParams, Ctx, U,
435*da58b97aSjoerg                                  ContentTypes, IncludeDirectories, FileNames)
436*da58b97aSjoerg           : parseV2DirFileTables(DebugLineData, OffsetPtr, ContentTypes,
437*da58b97aSjoerg                                  IncludeDirectories, FileNames);
438*da58b97aSjoerg   if (E) {
439*da58b97aSjoerg     RecoverableErrorHandler(joinErrors(
44006f32e7eSjoerg         createStringError(
44106f32e7eSjoerg             errc::invalid_argument,
44206f32e7eSjoerg             "parsing line table prologue at 0x%8.8" PRIx64
44306f32e7eSjoerg             " found an invalid directory or file table description at"
44406f32e7eSjoerg             " 0x%8.8" PRIx64,
44506f32e7eSjoerg             PrologueOffset, *OffsetPtr),
446*da58b97aSjoerg         std::move(E)));
447*da58b97aSjoerg     return Error::success();
44806f32e7eSjoerg   }
44906f32e7eSjoerg 
450*da58b97aSjoerg   assert(*OffsetPtr <= EndPrologueOffset);
451*da58b97aSjoerg   if (*OffsetPtr != EndPrologueOffset) {
452*da58b97aSjoerg     RecoverableErrorHandler(createStringError(
453*da58b97aSjoerg         errc::invalid_argument,
454*da58b97aSjoerg         "unknown data in line table prologue at offset 0x%8.8" PRIx64
455*da58b97aSjoerg         ": parsing ended (at offset 0x%8.8" PRIx64
456*da58b97aSjoerg         ") before reaching the prologue end at offset 0x%8.8" PRIx64,
457*da58b97aSjoerg         PrologueOffset, *OffsetPtr, EndPrologueOffset));
458*da58b97aSjoerg   }
45906f32e7eSjoerg   return Error::success();
46006f32e7eSjoerg }
46106f32e7eSjoerg 
Row(bool DefaultIsStmt)46206f32e7eSjoerg DWARFDebugLine::Row::Row(bool DefaultIsStmt) { reset(DefaultIsStmt); }
46306f32e7eSjoerg 
postAppend()46406f32e7eSjoerg void DWARFDebugLine::Row::postAppend() {
46506f32e7eSjoerg   Discriminator = 0;
46606f32e7eSjoerg   BasicBlock = false;
46706f32e7eSjoerg   PrologueEnd = false;
46806f32e7eSjoerg   EpilogueBegin = false;
46906f32e7eSjoerg }
47006f32e7eSjoerg 
reset(bool DefaultIsStmt)47106f32e7eSjoerg void DWARFDebugLine::Row::reset(bool DefaultIsStmt) {
47206f32e7eSjoerg   Address.Address = 0;
47306f32e7eSjoerg   Address.SectionIndex = object::SectionedAddress::UndefSection;
47406f32e7eSjoerg   Line = 1;
47506f32e7eSjoerg   Column = 0;
47606f32e7eSjoerg   File = 1;
47706f32e7eSjoerg   Isa = 0;
47806f32e7eSjoerg   Discriminator = 0;
47906f32e7eSjoerg   IsStmt = DefaultIsStmt;
48006f32e7eSjoerg   BasicBlock = false;
48106f32e7eSjoerg   EndSequence = false;
48206f32e7eSjoerg   PrologueEnd = false;
48306f32e7eSjoerg   EpilogueBegin = false;
48406f32e7eSjoerg }
48506f32e7eSjoerg 
dumpTableHeader(raw_ostream & OS,unsigned Indent)486*da58b97aSjoerg void DWARFDebugLine::Row::dumpTableHeader(raw_ostream &OS, unsigned Indent) {
487*da58b97aSjoerg   OS.indent(Indent)
488*da58b97aSjoerg       << "Address            Line   Column File   ISA Discriminator Flags\n";
489*da58b97aSjoerg   OS.indent(Indent)
49006f32e7eSjoerg       << "------------------ ------ ------ ------ --- ------------- "
49106f32e7eSjoerg          "-------------\n";
49206f32e7eSjoerg }
49306f32e7eSjoerg 
dump(raw_ostream & OS) const49406f32e7eSjoerg void DWARFDebugLine::Row::dump(raw_ostream &OS) const {
49506f32e7eSjoerg   OS << format("0x%16.16" PRIx64 " %6u %6u", Address.Address, Line, Column)
49606f32e7eSjoerg      << format(" %6u %3u %13u ", File, Isa, Discriminator)
49706f32e7eSjoerg      << (IsStmt ? " is_stmt" : "") << (BasicBlock ? " basic_block" : "")
49806f32e7eSjoerg      << (PrologueEnd ? " prologue_end" : "")
49906f32e7eSjoerg      << (EpilogueBegin ? " epilogue_begin" : "")
50006f32e7eSjoerg      << (EndSequence ? " end_sequence" : "") << '\n';
50106f32e7eSjoerg }
50206f32e7eSjoerg 
Sequence()50306f32e7eSjoerg DWARFDebugLine::Sequence::Sequence() { reset(); }
50406f32e7eSjoerg 
reset()50506f32e7eSjoerg void DWARFDebugLine::Sequence::reset() {
50606f32e7eSjoerg   LowPC = 0;
50706f32e7eSjoerg   HighPC = 0;
50806f32e7eSjoerg   SectionIndex = object::SectionedAddress::UndefSection;
50906f32e7eSjoerg   FirstRowIndex = 0;
51006f32e7eSjoerg   LastRowIndex = 0;
51106f32e7eSjoerg   Empty = true;
51206f32e7eSjoerg }
51306f32e7eSjoerg 
LineTable()51406f32e7eSjoerg DWARFDebugLine::LineTable::LineTable() { clear(); }
51506f32e7eSjoerg 
dump(raw_ostream & OS,DIDumpOptions DumpOptions) const51606f32e7eSjoerg void DWARFDebugLine::LineTable::dump(raw_ostream &OS,
51706f32e7eSjoerg                                      DIDumpOptions DumpOptions) const {
51806f32e7eSjoerg   Prologue.dump(OS, DumpOptions);
51906f32e7eSjoerg 
52006f32e7eSjoerg   if (!Rows.empty()) {
521*da58b97aSjoerg     OS << '\n';
522*da58b97aSjoerg     Row::dumpTableHeader(OS, 0);
52306f32e7eSjoerg     for (const Row &R : Rows) {
52406f32e7eSjoerg       R.dump(OS);
52506f32e7eSjoerg     }
52606f32e7eSjoerg   }
527*da58b97aSjoerg 
528*da58b97aSjoerg   // Terminate the table with a final blank line to clearly delineate it from
529*da58b97aSjoerg   // later dumps.
530*da58b97aSjoerg   OS << '\n';
53106f32e7eSjoerg }
53206f32e7eSjoerg 
clear()53306f32e7eSjoerg void DWARFDebugLine::LineTable::clear() {
53406f32e7eSjoerg   Prologue.clear();
53506f32e7eSjoerg   Rows.clear();
53606f32e7eSjoerg   Sequences.clear();
53706f32e7eSjoerg }
53806f32e7eSjoerg 
ParsingState(struct LineTable * LT,uint64_t TableOffset,function_ref<void (Error)> ErrorHandler)539*da58b97aSjoerg DWARFDebugLine::ParsingState::ParsingState(
540*da58b97aSjoerg     struct LineTable *LT, uint64_t TableOffset,
541*da58b97aSjoerg     function_ref<void(Error)> ErrorHandler)
542*da58b97aSjoerg     : LineTable(LT), LineTableOffset(TableOffset), ErrorHandler(ErrorHandler) {
54306f32e7eSjoerg   resetRowAndSequence();
54406f32e7eSjoerg }
54506f32e7eSjoerg 
resetRowAndSequence()54606f32e7eSjoerg void DWARFDebugLine::ParsingState::resetRowAndSequence() {
54706f32e7eSjoerg   Row.reset(LineTable->Prologue.DefaultIsStmt);
54806f32e7eSjoerg   Sequence.reset();
54906f32e7eSjoerg }
55006f32e7eSjoerg 
appendRowToMatrix()55106f32e7eSjoerg void DWARFDebugLine::ParsingState::appendRowToMatrix() {
55206f32e7eSjoerg   unsigned RowNumber = LineTable->Rows.size();
55306f32e7eSjoerg   if (Sequence.Empty) {
55406f32e7eSjoerg     // Record the beginning of instruction sequence.
55506f32e7eSjoerg     Sequence.Empty = false;
55606f32e7eSjoerg     Sequence.LowPC = Row.Address.Address;
55706f32e7eSjoerg     Sequence.FirstRowIndex = RowNumber;
55806f32e7eSjoerg   }
55906f32e7eSjoerg   LineTable->appendRow(Row);
56006f32e7eSjoerg   if (Row.EndSequence) {
56106f32e7eSjoerg     // Record the end of instruction sequence.
56206f32e7eSjoerg     Sequence.HighPC = Row.Address.Address;
56306f32e7eSjoerg     Sequence.LastRowIndex = RowNumber + 1;
56406f32e7eSjoerg     Sequence.SectionIndex = Row.Address.SectionIndex;
56506f32e7eSjoerg     if (Sequence.isValid())
56606f32e7eSjoerg       LineTable->appendSequence(Sequence);
56706f32e7eSjoerg     Sequence.reset();
56806f32e7eSjoerg   }
56906f32e7eSjoerg   Row.postAppend();
57006f32e7eSjoerg }
57106f32e7eSjoerg 
57206f32e7eSjoerg const DWARFDebugLine::LineTable *
getLineTable(uint64_t Offset) const57306f32e7eSjoerg DWARFDebugLine::getLineTable(uint64_t Offset) const {
57406f32e7eSjoerg   LineTableConstIter Pos = LineTableMap.find(Offset);
57506f32e7eSjoerg   if (Pos != LineTableMap.end())
57606f32e7eSjoerg     return &Pos->second;
57706f32e7eSjoerg   return nullptr;
57806f32e7eSjoerg }
57906f32e7eSjoerg 
getOrParseLineTable(DWARFDataExtractor & DebugLineData,uint64_t Offset,const DWARFContext & Ctx,const DWARFUnit * U,function_ref<void (Error)> RecoverableErrorHandler)58006f32e7eSjoerg Expected<const DWARFDebugLine::LineTable *> DWARFDebugLine::getOrParseLineTable(
58106f32e7eSjoerg     DWARFDataExtractor &DebugLineData, uint64_t Offset, const DWARFContext &Ctx,
582*da58b97aSjoerg     const DWARFUnit *U, function_ref<void(Error)> RecoverableErrorHandler) {
58306f32e7eSjoerg   if (!DebugLineData.isValidOffset(Offset))
58406f32e7eSjoerg     return createStringError(errc::invalid_argument, "offset 0x%8.8" PRIx64
58506f32e7eSjoerg                        " is not a valid debug line section offset",
58606f32e7eSjoerg                        Offset);
58706f32e7eSjoerg 
58806f32e7eSjoerg   std::pair<LineTableIter, bool> Pos =
58906f32e7eSjoerg       LineTableMap.insert(LineTableMapTy::value_type(Offset, LineTable()));
59006f32e7eSjoerg   LineTable *LT = &Pos.first->second;
59106f32e7eSjoerg   if (Pos.second) {
59206f32e7eSjoerg     if (Error Err =
593*da58b97aSjoerg             LT->parse(DebugLineData, &Offset, Ctx, U, RecoverableErrorHandler))
59406f32e7eSjoerg       return std::move(Err);
59506f32e7eSjoerg     return LT;
59606f32e7eSjoerg   }
59706f32e7eSjoerg   return LT;
59806f32e7eSjoerg }
59906f32e7eSjoerg 
getOpcodeName(uint8_t Opcode,uint8_t OpcodeBase)600*da58b97aSjoerg static StringRef getOpcodeName(uint8_t Opcode, uint8_t OpcodeBase) {
601*da58b97aSjoerg   assert(Opcode != 0);
602*da58b97aSjoerg   if (Opcode < OpcodeBase)
603*da58b97aSjoerg     return LNStandardString(Opcode);
604*da58b97aSjoerg   return "special";
60506f32e7eSjoerg }
60606f32e7eSjoerg 
advanceAddr(uint64_t OperationAdvance,uint8_t Opcode,uint64_t OpcodeOffset)607*da58b97aSjoerg uint64_t DWARFDebugLine::ParsingState::advanceAddr(uint64_t OperationAdvance,
608*da58b97aSjoerg                                                    uint8_t Opcode,
609*da58b97aSjoerg                                                    uint64_t OpcodeOffset) {
610*da58b97aSjoerg   StringRef OpcodeName = getOpcodeName(Opcode, LineTable->Prologue.OpcodeBase);
611*da58b97aSjoerg   // For versions less than 4, the MaxOpsPerInst member is set to 0, as the
612*da58b97aSjoerg   // maximum_operations_per_instruction field wasn't introduced until DWARFv4.
613*da58b97aSjoerg   // Don't warn about bad values in this situation.
614*da58b97aSjoerg   if (ReportAdvanceAddrProblem && LineTable->Prologue.getVersion() >= 4 &&
615*da58b97aSjoerg       LineTable->Prologue.MaxOpsPerInst != 1)
616*da58b97aSjoerg     ErrorHandler(createStringError(
617*da58b97aSjoerg         errc::not_supported,
618*da58b97aSjoerg         "line table program at offset 0x%8.8" PRIx64
619*da58b97aSjoerg         " contains a %s opcode at offset 0x%8.8" PRIx64
620*da58b97aSjoerg         ", but the prologue maximum_operations_per_instruction value is %" PRId8
621*da58b97aSjoerg         ", which is unsupported. Assuming a value of 1 instead",
622*da58b97aSjoerg         LineTableOffset, OpcodeName.data(), OpcodeOffset,
623*da58b97aSjoerg         LineTable->Prologue.MaxOpsPerInst));
624*da58b97aSjoerg   if (ReportAdvanceAddrProblem && LineTable->Prologue.MinInstLength == 0)
625*da58b97aSjoerg     ErrorHandler(
626*da58b97aSjoerg         createStringError(errc::invalid_argument,
627*da58b97aSjoerg                           "line table program at offset 0x%8.8" PRIx64
628*da58b97aSjoerg                           " contains a %s opcode at offset 0x%8.8" PRIx64
629*da58b97aSjoerg                           ", but the prologue minimum_instruction_length value "
630*da58b97aSjoerg                           "is 0, which prevents any address advancing",
631*da58b97aSjoerg                           LineTableOffset, OpcodeName.data(), OpcodeOffset));
632*da58b97aSjoerg   ReportAdvanceAddrProblem = false;
633*da58b97aSjoerg   uint64_t AddrOffset = OperationAdvance * LineTable->Prologue.MinInstLength;
634*da58b97aSjoerg   Row.Address.Address += AddrOffset;
635*da58b97aSjoerg   return AddrOffset;
63606f32e7eSjoerg }
63706f32e7eSjoerg 
638*da58b97aSjoerg DWARFDebugLine::ParsingState::AddrAndAdjustedOpcode
advanceAddrForOpcode(uint8_t Opcode,uint64_t OpcodeOffset)639*da58b97aSjoerg DWARFDebugLine::ParsingState::advanceAddrForOpcode(uint8_t Opcode,
640*da58b97aSjoerg                                                    uint64_t OpcodeOffset) {
641*da58b97aSjoerg   assert(Opcode == DW_LNS_const_add_pc ||
642*da58b97aSjoerg          Opcode >= LineTable->Prologue.OpcodeBase);
643*da58b97aSjoerg   if (ReportBadLineRange && LineTable->Prologue.LineRange == 0) {
644*da58b97aSjoerg     StringRef OpcodeName =
645*da58b97aSjoerg         getOpcodeName(Opcode, LineTable->Prologue.OpcodeBase);
646*da58b97aSjoerg     ErrorHandler(
647*da58b97aSjoerg         createStringError(errc::not_supported,
648*da58b97aSjoerg                           "line table program at offset 0x%8.8" PRIx64
649*da58b97aSjoerg                           " contains a %s opcode at offset 0x%8.8" PRIx64
650*da58b97aSjoerg                           ", but the prologue line_range value is 0. The "
651*da58b97aSjoerg                           "address and line will not be adjusted",
652*da58b97aSjoerg                           LineTableOffset, OpcodeName.data(), OpcodeOffset));
653*da58b97aSjoerg     ReportBadLineRange = false;
65406f32e7eSjoerg   }
65506f32e7eSjoerg 
656*da58b97aSjoerg   uint8_t OpcodeValue = Opcode;
657*da58b97aSjoerg   if (Opcode == DW_LNS_const_add_pc)
658*da58b97aSjoerg     OpcodeValue = 255;
659*da58b97aSjoerg   uint8_t AdjustedOpcode = OpcodeValue - LineTable->Prologue.OpcodeBase;
660*da58b97aSjoerg   uint64_t OperationAdvance =
661*da58b97aSjoerg       LineTable->Prologue.LineRange != 0
662*da58b97aSjoerg           ? AdjustedOpcode / LineTable->Prologue.LineRange
663*da58b97aSjoerg           : 0;
664*da58b97aSjoerg   uint64_t AddrOffset = advanceAddr(OperationAdvance, Opcode, OpcodeOffset);
665*da58b97aSjoerg   return {AddrOffset, AdjustedOpcode};
66606f32e7eSjoerg }
66706f32e7eSjoerg 
668*da58b97aSjoerg DWARFDebugLine::ParsingState::AddrAndLineDelta
handleSpecialOpcode(uint8_t Opcode,uint64_t OpcodeOffset)669*da58b97aSjoerg DWARFDebugLine::ParsingState::handleSpecialOpcode(uint8_t Opcode,
670*da58b97aSjoerg                                                   uint64_t OpcodeOffset) {
67106f32e7eSjoerg   // A special opcode value is chosen based on the amount that needs
67206f32e7eSjoerg   // to be added to the line and address registers. The maximum line
67306f32e7eSjoerg   // increment for a special opcode is the value of the line_base
67406f32e7eSjoerg   // field in the header, plus the value of the line_range field,
67506f32e7eSjoerg   // minus 1 (line base + line range - 1). If the desired line
67606f32e7eSjoerg   // increment is greater than the maximum line increment, a standard
67706f32e7eSjoerg   // opcode must be used instead of a special opcode. The "address
67806f32e7eSjoerg   // advance" is calculated by dividing the desired address increment
67906f32e7eSjoerg   // by the minimum_instruction_length field from the header. The
68006f32e7eSjoerg   // special opcode is then calculated using the following formula:
68106f32e7eSjoerg   //
68206f32e7eSjoerg   //  opcode = (desired line increment - line_base) +
68306f32e7eSjoerg   //           (line_range * address advance) + opcode_base
68406f32e7eSjoerg   //
68506f32e7eSjoerg   // If the resulting opcode is greater than 255, a standard opcode
68606f32e7eSjoerg   // must be used instead.
68706f32e7eSjoerg   //
68806f32e7eSjoerg   // To decode a special opcode, subtract the opcode_base from the
68906f32e7eSjoerg   // opcode itself to give the adjusted opcode. The amount to
69006f32e7eSjoerg   // increment the address register is the result of the adjusted
69106f32e7eSjoerg   // opcode divided by the line_range multiplied by the
69206f32e7eSjoerg   // minimum_instruction_length field from the header. That is:
69306f32e7eSjoerg   //
69406f32e7eSjoerg   //  address increment = (adjusted opcode / line_range) *
69506f32e7eSjoerg   //                      minimum_instruction_length
69606f32e7eSjoerg   //
69706f32e7eSjoerg   // The amount to increment the line register is the line_base plus
69806f32e7eSjoerg   // the result of the adjusted opcode modulo the line_range. That is:
69906f32e7eSjoerg   //
70006f32e7eSjoerg   // line increment = line_base + (adjusted opcode % line_range)
70106f32e7eSjoerg 
702*da58b97aSjoerg   DWARFDebugLine::ParsingState::AddrAndAdjustedOpcode AddrAdvanceResult =
703*da58b97aSjoerg       advanceAddrForOpcode(Opcode, OpcodeOffset);
704*da58b97aSjoerg   int32_t LineOffset = 0;
705*da58b97aSjoerg   if (LineTable->Prologue.LineRange != 0)
706*da58b97aSjoerg     LineOffset =
707*da58b97aSjoerg         LineTable->Prologue.LineBase +
708*da58b97aSjoerg         (AddrAdvanceResult.AdjustedOpcode % LineTable->Prologue.LineRange);
709*da58b97aSjoerg   Row.Line += LineOffset;
710*da58b97aSjoerg   return {AddrAdvanceResult.AddrDelta, LineOffset};
711*da58b97aSjoerg }
712*da58b97aSjoerg 
713*da58b97aSjoerg /// Parse a ULEB128 using the specified \p Cursor. \returns the parsed value on
714*da58b97aSjoerg /// success, or None if \p Cursor is in a failing state.
715*da58b97aSjoerg template <typename T>
parseULEB128(DWARFDataExtractor & Data,DataExtractor::Cursor & Cursor)716*da58b97aSjoerg static Optional<T> parseULEB128(DWARFDataExtractor &Data,
717*da58b97aSjoerg                                 DataExtractor::Cursor &Cursor) {
718*da58b97aSjoerg   T Value = Data.getULEB128(Cursor);
719*da58b97aSjoerg   if (Cursor)
720*da58b97aSjoerg     return Value;
721*da58b97aSjoerg   return None;
722*da58b97aSjoerg }
723*da58b97aSjoerg 
parse(DWARFDataExtractor & DebugLineData,uint64_t * OffsetPtr,const DWARFContext & Ctx,const DWARFUnit * U,function_ref<void (Error)> RecoverableErrorHandler,raw_ostream * OS,bool Verbose)724*da58b97aSjoerg Error DWARFDebugLine::LineTable::parse(
725*da58b97aSjoerg     DWARFDataExtractor &DebugLineData, uint64_t *OffsetPtr,
726*da58b97aSjoerg     const DWARFContext &Ctx, const DWARFUnit *U,
727*da58b97aSjoerg     function_ref<void(Error)> RecoverableErrorHandler, raw_ostream *OS,
728*da58b97aSjoerg     bool Verbose) {
729*da58b97aSjoerg   assert((OS || !Verbose) && "cannot have verbose output without stream");
730*da58b97aSjoerg   const uint64_t DebugLineOffset = *OffsetPtr;
731*da58b97aSjoerg 
732*da58b97aSjoerg   clear();
733*da58b97aSjoerg 
734*da58b97aSjoerg   Error PrologueErr =
735*da58b97aSjoerg       Prologue.parse(DebugLineData, OffsetPtr, RecoverableErrorHandler, Ctx, U);
73606f32e7eSjoerg 
73706f32e7eSjoerg   if (OS) {
738*da58b97aSjoerg     DIDumpOptions DumpOptions;
739*da58b97aSjoerg     DumpOptions.Verbose = Verbose;
740*da58b97aSjoerg     Prologue.dump(*OS, DumpOptions);
74106f32e7eSjoerg   }
74206f32e7eSjoerg 
743*da58b97aSjoerg   if (PrologueErr) {
744*da58b97aSjoerg     // Ensure there is a blank line after the prologue to clearly delineate it
745*da58b97aSjoerg     // from later dumps.
74606f32e7eSjoerg     if (OS)
74706f32e7eSjoerg       *OS << "\n";
748*da58b97aSjoerg     return PrologueErr;
749*da58b97aSjoerg   }
750*da58b97aSjoerg 
751*da58b97aSjoerg   uint64_t ProgramLength = Prologue.TotalLength + Prologue.sizeofTotalLength();
752*da58b97aSjoerg   if (!DebugLineData.isValidOffsetForDataOfSize(DebugLineOffset,
753*da58b97aSjoerg                                                 ProgramLength)) {
754*da58b97aSjoerg     assert(DebugLineData.size() > DebugLineOffset &&
755*da58b97aSjoerg            "prologue parsing should handle invalid offset");
756*da58b97aSjoerg     uint64_t BytesRemaining = DebugLineData.size() - DebugLineOffset;
757*da58b97aSjoerg     RecoverableErrorHandler(
758*da58b97aSjoerg         createStringError(errc::invalid_argument,
759*da58b97aSjoerg                           "line table program with offset 0x%8.8" PRIx64
760*da58b97aSjoerg                           " has length 0x%8.8" PRIx64 " but only 0x%8.8" PRIx64
761*da58b97aSjoerg                           " bytes are available",
762*da58b97aSjoerg                           DebugLineOffset, ProgramLength, BytesRemaining));
763*da58b97aSjoerg     // Continue by capping the length at the number of remaining bytes.
764*da58b97aSjoerg     ProgramLength = BytesRemaining;
765*da58b97aSjoerg   }
766*da58b97aSjoerg 
767*da58b97aSjoerg   // Create a DataExtractor which can only see the data up to the end of the
768*da58b97aSjoerg   // table, to prevent reading past the end.
769*da58b97aSjoerg   const uint64_t EndOffset = DebugLineOffset + ProgramLength;
770*da58b97aSjoerg   DWARFDataExtractor TableData(DebugLineData, EndOffset);
771*da58b97aSjoerg 
772*da58b97aSjoerg   // See if we should tell the data extractor the address size.
773*da58b97aSjoerg   if (TableData.getAddressSize() == 0)
774*da58b97aSjoerg     TableData.setAddressSize(Prologue.getAddressSize());
775*da58b97aSjoerg   else
776*da58b97aSjoerg     assert(Prologue.getAddressSize() == 0 ||
777*da58b97aSjoerg            Prologue.getAddressSize() == TableData.getAddressSize());
778*da58b97aSjoerg 
779*da58b97aSjoerg   ParsingState State(this, DebugLineOffset, RecoverableErrorHandler);
780*da58b97aSjoerg 
781*da58b97aSjoerg   *OffsetPtr = DebugLineOffset + Prologue.getLength();
782*da58b97aSjoerg   if (OS && *OffsetPtr < EndOffset) {
783*da58b97aSjoerg     *OS << '\n';
784*da58b97aSjoerg     Row::dumpTableHeader(*OS, /*Indent=*/Verbose ? 12 : 0);
785*da58b97aSjoerg   }
786*da58b97aSjoerg   bool TombstonedAddress = false;
787*da58b97aSjoerg   auto EmitRow = [&] {
788*da58b97aSjoerg     if (!TombstonedAddress) {
789*da58b97aSjoerg       if (Verbose) {
790*da58b97aSjoerg         *OS << "\n";
791*da58b97aSjoerg         OS->indent(12);
792*da58b97aSjoerg       }
793*da58b97aSjoerg       if (OS)
794*da58b97aSjoerg         State.Row.dump(*OS);
795*da58b97aSjoerg       State.appendRowToMatrix();
796*da58b97aSjoerg     }
797*da58b97aSjoerg   };
798*da58b97aSjoerg   while (*OffsetPtr < EndOffset) {
799*da58b97aSjoerg     DataExtractor::Cursor Cursor(*OffsetPtr);
800*da58b97aSjoerg 
801*da58b97aSjoerg     if (Verbose)
802*da58b97aSjoerg       *OS << format("0x%08.08" PRIx64 ": ", *OffsetPtr);
803*da58b97aSjoerg 
804*da58b97aSjoerg     uint64_t OpcodeOffset = *OffsetPtr;
805*da58b97aSjoerg     uint8_t Opcode = TableData.getU8(Cursor);
806*da58b97aSjoerg     size_t RowCount = Rows.size();
807*da58b97aSjoerg 
808*da58b97aSjoerg     if (Cursor && Verbose)
809*da58b97aSjoerg       *OS << format("%02.02" PRIx8 " ", Opcode);
810*da58b97aSjoerg 
811*da58b97aSjoerg     if (Opcode == 0) {
812*da58b97aSjoerg       // Extended Opcodes always start with a zero opcode followed by
813*da58b97aSjoerg       // a uleb128 length so you can skip ones you don't know about
814*da58b97aSjoerg       uint64_t Len = TableData.getULEB128(Cursor);
815*da58b97aSjoerg       uint64_t ExtOffset = Cursor.tell();
816*da58b97aSjoerg 
817*da58b97aSjoerg       // Tolerate zero-length; assume length is correct and soldier on.
818*da58b97aSjoerg       if (Len == 0) {
819*da58b97aSjoerg         if (Cursor && Verbose)
820*da58b97aSjoerg           *OS << "Badly formed extended line op (length 0)\n";
821*da58b97aSjoerg         if (!Cursor) {
822*da58b97aSjoerg           if (Verbose)
823*da58b97aSjoerg             *OS << "\n";
824*da58b97aSjoerg           RecoverableErrorHandler(Cursor.takeError());
825*da58b97aSjoerg         }
826*da58b97aSjoerg         *OffsetPtr = Cursor.tell();
827*da58b97aSjoerg         continue;
828*da58b97aSjoerg       }
829*da58b97aSjoerg 
830*da58b97aSjoerg       uint8_t SubOpcode = TableData.getU8(Cursor);
831*da58b97aSjoerg       // OperandOffset will be the same as ExtOffset, if it was not possible to
832*da58b97aSjoerg       // read the SubOpcode.
833*da58b97aSjoerg       uint64_t OperandOffset = Cursor.tell();
834*da58b97aSjoerg       if (Verbose)
835*da58b97aSjoerg         *OS << LNExtendedString(SubOpcode);
836*da58b97aSjoerg       switch (SubOpcode) {
837*da58b97aSjoerg       case DW_LNE_end_sequence:
838*da58b97aSjoerg         // Set the end_sequence register of the state machine to true and
839*da58b97aSjoerg         // append a row to the matrix using the current values of the
840*da58b97aSjoerg         // state-machine registers. Then reset the registers to the initial
841*da58b97aSjoerg         // values specified above. Every statement program sequence must end
842*da58b97aSjoerg         // with a DW_LNE_end_sequence instruction which creates a row whose
843*da58b97aSjoerg         // address is that of the byte after the last target machine instruction
844*da58b97aSjoerg         // of the sequence.
845*da58b97aSjoerg         State.Row.EndSequence = true;
846*da58b97aSjoerg         // No need to test the Cursor is valid here, since it must be to get
847*da58b97aSjoerg         // into this code path - if it were invalid, the default case would be
848*da58b97aSjoerg         // followed.
849*da58b97aSjoerg         EmitRow();
850*da58b97aSjoerg         State.resetRowAndSequence();
851*da58b97aSjoerg         break;
852*da58b97aSjoerg 
853*da58b97aSjoerg       case DW_LNE_set_address:
854*da58b97aSjoerg         // Takes a single relocatable address as an operand. The size of the
855*da58b97aSjoerg         // operand is the size appropriate to hold an address on the target
856*da58b97aSjoerg         // machine. Set the address register to the value given by the
857*da58b97aSjoerg         // relocatable address. All of the other statement program opcodes
858*da58b97aSjoerg         // that affect the address register add a delta to it. This instruction
859*da58b97aSjoerg         // stores a relocatable value into it instead.
860*da58b97aSjoerg         //
861*da58b97aSjoerg         // Make sure the extractor knows the address size.  If not, infer it
862*da58b97aSjoerg         // from the size of the operand.
863*da58b97aSjoerg         {
864*da58b97aSjoerg           uint8_t ExtractorAddressSize = TableData.getAddressSize();
865*da58b97aSjoerg           uint64_t OpcodeAddressSize = Len - 1;
866*da58b97aSjoerg           if (ExtractorAddressSize != OpcodeAddressSize &&
867*da58b97aSjoerg               ExtractorAddressSize != 0)
868*da58b97aSjoerg             RecoverableErrorHandler(createStringError(
869*da58b97aSjoerg                 errc::invalid_argument,
870*da58b97aSjoerg                 "mismatching address size at offset 0x%8.8" PRIx64
871*da58b97aSjoerg                 " expected 0x%2.2" PRIx8 " found 0x%2.2" PRIx64,
872*da58b97aSjoerg                 ExtOffset, ExtractorAddressSize, Len - 1));
873*da58b97aSjoerg 
874*da58b97aSjoerg           // Assume that the line table is correct and temporarily override the
875*da58b97aSjoerg           // address size. If the size is unsupported, give up trying to read
876*da58b97aSjoerg           // the address and continue to the next opcode.
877*da58b97aSjoerg           if (OpcodeAddressSize != 1 && OpcodeAddressSize != 2 &&
878*da58b97aSjoerg               OpcodeAddressSize != 4 && OpcodeAddressSize != 8) {
879*da58b97aSjoerg             RecoverableErrorHandler(createStringError(
880*da58b97aSjoerg                 errc::invalid_argument,
881*da58b97aSjoerg                 "address size 0x%2.2" PRIx64
882*da58b97aSjoerg                 " of DW_LNE_set_address opcode at offset 0x%8.8" PRIx64
883*da58b97aSjoerg                 " is unsupported",
884*da58b97aSjoerg                 OpcodeAddressSize, ExtOffset));
885*da58b97aSjoerg             TableData.skip(Cursor, OpcodeAddressSize);
886*da58b97aSjoerg           } else {
887*da58b97aSjoerg             TableData.setAddressSize(OpcodeAddressSize);
888*da58b97aSjoerg             State.Row.Address.Address = TableData.getRelocatedAddress(
889*da58b97aSjoerg                 Cursor, &State.Row.Address.SectionIndex);
890*da58b97aSjoerg 
891*da58b97aSjoerg             uint64_t Tombstone =
892*da58b97aSjoerg                 dwarf::computeTombstoneAddress(OpcodeAddressSize);
893*da58b97aSjoerg             TombstonedAddress = State.Row.Address.Address == Tombstone;
894*da58b97aSjoerg 
895*da58b97aSjoerg             // Restore the address size if the extractor already had it.
896*da58b97aSjoerg             if (ExtractorAddressSize != 0)
897*da58b97aSjoerg               TableData.setAddressSize(ExtractorAddressSize);
898*da58b97aSjoerg           }
899*da58b97aSjoerg 
900*da58b97aSjoerg           if (Cursor && Verbose) {
901*da58b97aSjoerg             *OS << " (";
902*da58b97aSjoerg             DWARFFormValue::dumpAddress(*OS, OpcodeAddressSize, State.Row.Address.Address);
903*da58b97aSjoerg             *OS << ')';
904*da58b97aSjoerg           }
905*da58b97aSjoerg         }
906*da58b97aSjoerg         break;
907*da58b97aSjoerg 
908*da58b97aSjoerg       case DW_LNE_define_file:
909*da58b97aSjoerg         // Takes 4 arguments. The first is a null terminated string containing
910*da58b97aSjoerg         // a source file name. The second is an unsigned LEB128 number
911*da58b97aSjoerg         // representing the directory index of the directory in which the file
912*da58b97aSjoerg         // was found. The third is an unsigned LEB128 number representing the
913*da58b97aSjoerg         // time of last modification of the file. The fourth is an unsigned
914*da58b97aSjoerg         // LEB128 number representing the length in bytes of the file. The time
915*da58b97aSjoerg         // and length fields may contain LEB128(0) if the information is not
916*da58b97aSjoerg         // available.
917*da58b97aSjoerg         //
918*da58b97aSjoerg         // The directory index represents an entry in the include_directories
919*da58b97aSjoerg         // section of the statement program prologue. The index is LEB128(0)
920*da58b97aSjoerg         // if the file was found in the current directory of the compilation,
921*da58b97aSjoerg         // LEB128(1) if it was found in the first directory in the
922*da58b97aSjoerg         // include_directories section, and so on. The directory index is
923*da58b97aSjoerg         // ignored for file names that represent full path names.
924*da58b97aSjoerg         //
925*da58b97aSjoerg         // The files are numbered, starting at 1, in the order in which they
926*da58b97aSjoerg         // appear; the names in the prologue come before names defined by
927*da58b97aSjoerg         // the DW_LNE_define_file instruction. These numbers are used in the
928*da58b97aSjoerg         // the file register of the state machine.
929*da58b97aSjoerg         {
930*da58b97aSjoerg           FileNameEntry FileEntry;
931*da58b97aSjoerg           const char *Name = TableData.getCStr(Cursor);
932*da58b97aSjoerg           FileEntry.Name =
933*da58b97aSjoerg               DWARFFormValue::createFromPValue(dwarf::DW_FORM_string, Name);
934*da58b97aSjoerg           FileEntry.DirIdx = TableData.getULEB128(Cursor);
935*da58b97aSjoerg           FileEntry.ModTime = TableData.getULEB128(Cursor);
936*da58b97aSjoerg           FileEntry.Length = TableData.getULEB128(Cursor);
937*da58b97aSjoerg           Prologue.FileNames.push_back(FileEntry);
938*da58b97aSjoerg           if (Cursor && Verbose)
939*da58b97aSjoerg             *OS << " (" << Name << ", dir=" << FileEntry.DirIdx << ", mod_time="
940*da58b97aSjoerg                 << format("(0x%16.16" PRIx64 ")", FileEntry.ModTime)
941*da58b97aSjoerg                 << ", length=" << FileEntry.Length << ")";
942*da58b97aSjoerg         }
943*da58b97aSjoerg         break;
944*da58b97aSjoerg 
945*da58b97aSjoerg       case DW_LNE_set_discriminator:
946*da58b97aSjoerg         State.Row.Discriminator = TableData.getULEB128(Cursor);
947*da58b97aSjoerg         if (Cursor && Verbose)
948*da58b97aSjoerg           *OS << " (" << State.Row.Discriminator << ")";
949*da58b97aSjoerg         break;
950*da58b97aSjoerg 
951*da58b97aSjoerg       default:
952*da58b97aSjoerg         if (Cursor && Verbose)
953*da58b97aSjoerg           *OS << format("Unrecognized extended op 0x%02.02" PRIx8, SubOpcode)
954*da58b97aSjoerg               << format(" length %" PRIx64, Len);
955*da58b97aSjoerg         // Len doesn't include the zero opcode byte or the length itself, but
956*da58b97aSjoerg         // it does include the sub_opcode, so we have to adjust for that.
957*da58b97aSjoerg         TableData.skip(Cursor, Len - 1);
958*da58b97aSjoerg         break;
959*da58b97aSjoerg       }
960*da58b97aSjoerg       // Make sure the length as recorded in the table and the standard length
961*da58b97aSjoerg       // for the opcode match. If they don't, continue from the end as claimed
962*da58b97aSjoerg       // by the table. Similarly, continue from the claimed end in the event of
963*da58b97aSjoerg       // a parsing error.
964*da58b97aSjoerg       uint64_t End = ExtOffset + Len;
965*da58b97aSjoerg       if (Cursor && Cursor.tell() != End)
966*da58b97aSjoerg         RecoverableErrorHandler(createStringError(
967*da58b97aSjoerg             errc::illegal_byte_sequence,
968*da58b97aSjoerg             "unexpected line op length at offset 0x%8.8" PRIx64
969*da58b97aSjoerg             " expected 0x%2.2" PRIx64 " found 0x%2.2" PRIx64,
970*da58b97aSjoerg             ExtOffset, Len, Cursor.tell() - ExtOffset));
971*da58b97aSjoerg       if (!Cursor && Verbose) {
972*da58b97aSjoerg         DWARFDataExtractor::Cursor ByteCursor(OperandOffset);
973*da58b97aSjoerg         uint8_t Byte = TableData.getU8(ByteCursor);
974*da58b97aSjoerg         if (ByteCursor) {
975*da58b97aSjoerg           *OS << " (<parsing error>";
976*da58b97aSjoerg           do {
977*da58b97aSjoerg             *OS << format(" %2.2" PRIx8, Byte);
978*da58b97aSjoerg             Byte = TableData.getU8(ByteCursor);
979*da58b97aSjoerg           } while (ByteCursor);
980*da58b97aSjoerg           *OS << ")";
981*da58b97aSjoerg         }
982*da58b97aSjoerg 
983*da58b97aSjoerg         // The only parse failure in this case should be if the end was reached.
984*da58b97aSjoerg         // In that case, throw away the error, as the main Cursor's error will
985*da58b97aSjoerg         // be sufficient.
986*da58b97aSjoerg         consumeError(ByteCursor.takeError());
987*da58b97aSjoerg       }
988*da58b97aSjoerg       *OffsetPtr = End;
989*da58b97aSjoerg     } else if (Opcode < Prologue.OpcodeBase) {
990*da58b97aSjoerg       if (Verbose)
991*da58b97aSjoerg         *OS << LNStandardString(Opcode);
992*da58b97aSjoerg       switch (Opcode) {
993*da58b97aSjoerg       // Standard Opcodes
994*da58b97aSjoerg       case DW_LNS_copy:
995*da58b97aSjoerg         // Takes no arguments. Append a row to the matrix using the
996*da58b97aSjoerg         // current values of the state-machine registers.
997*da58b97aSjoerg         EmitRow();
998*da58b97aSjoerg         break;
999*da58b97aSjoerg 
1000*da58b97aSjoerg       case DW_LNS_advance_pc:
1001*da58b97aSjoerg         // Takes a single unsigned LEB128 operand, multiplies it by the
1002*da58b97aSjoerg         // min_inst_length field of the prologue, and adds the
1003*da58b97aSjoerg         // result to the address register of the state machine.
1004*da58b97aSjoerg         if (Optional<uint64_t> Operand =
1005*da58b97aSjoerg                 parseULEB128<uint64_t>(TableData, Cursor)) {
1006*da58b97aSjoerg           uint64_t AddrOffset =
1007*da58b97aSjoerg               State.advanceAddr(*Operand, Opcode, OpcodeOffset);
1008*da58b97aSjoerg           if (Verbose)
1009*da58b97aSjoerg             *OS << " (" << AddrOffset << ")";
1010*da58b97aSjoerg         }
1011*da58b97aSjoerg         break;
1012*da58b97aSjoerg 
1013*da58b97aSjoerg       case DW_LNS_advance_line:
1014*da58b97aSjoerg         // Takes a single signed LEB128 operand and adds that value to
1015*da58b97aSjoerg         // the line register of the state machine.
1016*da58b97aSjoerg         {
1017*da58b97aSjoerg           int64_t LineDelta = TableData.getSLEB128(Cursor);
1018*da58b97aSjoerg           if (Cursor) {
1019*da58b97aSjoerg             State.Row.Line += LineDelta;
1020*da58b97aSjoerg             if (Verbose)
1021*da58b97aSjoerg               *OS << " (" << State.Row.Line << ")";
1022*da58b97aSjoerg           }
1023*da58b97aSjoerg         }
1024*da58b97aSjoerg         break;
1025*da58b97aSjoerg 
1026*da58b97aSjoerg       case DW_LNS_set_file:
1027*da58b97aSjoerg         // Takes a single unsigned LEB128 operand and stores it in the file
1028*da58b97aSjoerg         // register of the state machine.
1029*da58b97aSjoerg         if (Optional<uint16_t> File =
1030*da58b97aSjoerg                 parseULEB128<uint16_t>(TableData, Cursor)) {
1031*da58b97aSjoerg           State.Row.File = *File;
1032*da58b97aSjoerg           if (Verbose)
1033*da58b97aSjoerg             *OS << " (" << State.Row.File << ")";
1034*da58b97aSjoerg         }
1035*da58b97aSjoerg         break;
1036*da58b97aSjoerg 
1037*da58b97aSjoerg       case DW_LNS_set_column:
1038*da58b97aSjoerg         // Takes a single unsigned LEB128 operand and stores it in the
1039*da58b97aSjoerg         // column register of the state machine.
1040*da58b97aSjoerg         if (Optional<uint16_t> Column =
1041*da58b97aSjoerg                 parseULEB128<uint16_t>(TableData, Cursor)) {
1042*da58b97aSjoerg           State.Row.Column = *Column;
1043*da58b97aSjoerg           if (Verbose)
1044*da58b97aSjoerg             *OS << " (" << State.Row.Column << ")";
1045*da58b97aSjoerg         }
1046*da58b97aSjoerg         break;
1047*da58b97aSjoerg 
1048*da58b97aSjoerg       case DW_LNS_negate_stmt:
1049*da58b97aSjoerg         // Takes no arguments. Set the is_stmt register of the state
1050*da58b97aSjoerg         // machine to the logical negation of its current value.
1051*da58b97aSjoerg         State.Row.IsStmt = !State.Row.IsStmt;
1052*da58b97aSjoerg         break;
1053*da58b97aSjoerg 
1054*da58b97aSjoerg       case DW_LNS_set_basic_block:
1055*da58b97aSjoerg         // Takes no arguments. Set the basic_block register of the
1056*da58b97aSjoerg         // state machine to true
1057*da58b97aSjoerg         State.Row.BasicBlock = true;
1058*da58b97aSjoerg         break;
1059*da58b97aSjoerg 
1060*da58b97aSjoerg       case DW_LNS_const_add_pc:
1061*da58b97aSjoerg         // Takes no arguments. Add to the address register of the state
1062*da58b97aSjoerg         // machine the address increment value corresponding to special
1063*da58b97aSjoerg         // opcode 255. The motivation for DW_LNS_const_add_pc is this:
1064*da58b97aSjoerg         // when the statement program needs to advance the address by a
1065*da58b97aSjoerg         // small amount, it can use a single special opcode, which occupies
1066*da58b97aSjoerg         // a single byte. When it needs to advance the address by up to
1067*da58b97aSjoerg         // twice the range of the last special opcode, it can use
1068*da58b97aSjoerg         // DW_LNS_const_add_pc followed by a special opcode, for a total
1069*da58b97aSjoerg         // of two bytes. Only if it needs to advance the address by more
1070*da58b97aSjoerg         // than twice that range will it need to use both DW_LNS_advance_pc
1071*da58b97aSjoerg         // and a special opcode, requiring three or more bytes.
1072*da58b97aSjoerg         {
1073*da58b97aSjoerg           uint64_t AddrOffset =
1074*da58b97aSjoerg               State.advanceAddrForOpcode(Opcode, OpcodeOffset).AddrDelta;
1075*da58b97aSjoerg           if (Verbose)
1076*da58b97aSjoerg             *OS << format(" (0x%16.16" PRIx64 ")", AddrOffset);
1077*da58b97aSjoerg         }
1078*da58b97aSjoerg         break;
1079*da58b97aSjoerg 
1080*da58b97aSjoerg       case DW_LNS_fixed_advance_pc:
1081*da58b97aSjoerg         // Takes a single uhalf operand. Add to the address register of
1082*da58b97aSjoerg         // the state machine the value of the (unencoded) operand. This
1083*da58b97aSjoerg         // is the only extended opcode that takes an argument that is not
1084*da58b97aSjoerg         // a variable length number. The motivation for DW_LNS_fixed_advance_pc
1085*da58b97aSjoerg         // is this: existing assemblers cannot emit DW_LNS_advance_pc or
1086*da58b97aSjoerg         // special opcodes because they cannot encode LEB128 numbers or
1087*da58b97aSjoerg         // judge when the computation of a special opcode overflows and
1088*da58b97aSjoerg         // requires the use of DW_LNS_advance_pc. Such assemblers, however,
1089*da58b97aSjoerg         // can use DW_LNS_fixed_advance_pc instead, sacrificing compression.
1090*da58b97aSjoerg         {
1091*da58b97aSjoerg           uint16_t PCOffset =
1092*da58b97aSjoerg               TableData.getRelocatedValue(Cursor, 2);
1093*da58b97aSjoerg           if (Cursor) {
1094*da58b97aSjoerg             State.Row.Address.Address += PCOffset;
1095*da58b97aSjoerg             if (Verbose)
1096*da58b97aSjoerg               *OS << format(" (0x%4.4" PRIx16 ")", PCOffset);
1097*da58b97aSjoerg           }
1098*da58b97aSjoerg         }
1099*da58b97aSjoerg         break;
1100*da58b97aSjoerg 
1101*da58b97aSjoerg       case DW_LNS_set_prologue_end:
1102*da58b97aSjoerg         // Takes no arguments. Set the prologue_end register of the
1103*da58b97aSjoerg         // state machine to true
1104*da58b97aSjoerg         State.Row.PrologueEnd = true;
1105*da58b97aSjoerg         break;
1106*da58b97aSjoerg 
1107*da58b97aSjoerg       case DW_LNS_set_epilogue_begin:
1108*da58b97aSjoerg         // Takes no arguments. Set the basic_block register of the
1109*da58b97aSjoerg         // state machine to true
1110*da58b97aSjoerg         State.Row.EpilogueBegin = true;
1111*da58b97aSjoerg         break;
1112*da58b97aSjoerg 
1113*da58b97aSjoerg       case DW_LNS_set_isa:
1114*da58b97aSjoerg         // Takes a single unsigned LEB128 operand and stores it in the
1115*da58b97aSjoerg         // ISA register of the state machine.
1116*da58b97aSjoerg         if (Optional<uint8_t> Isa = parseULEB128<uint8_t>(TableData, Cursor)) {
1117*da58b97aSjoerg           State.Row.Isa = *Isa;
1118*da58b97aSjoerg           if (Verbose)
1119*da58b97aSjoerg             *OS << " (" << (uint64_t)State.Row.Isa << ")";
1120*da58b97aSjoerg         }
1121*da58b97aSjoerg         break;
1122*da58b97aSjoerg 
1123*da58b97aSjoerg       default:
1124*da58b97aSjoerg         // Handle any unknown standard opcodes here. We know the lengths
1125*da58b97aSjoerg         // of such opcodes because they are specified in the prologue
1126*da58b97aSjoerg         // as a multiple of LEB128 operands for each opcode.
1127*da58b97aSjoerg         {
1128*da58b97aSjoerg           assert(Opcode - 1U < Prologue.StandardOpcodeLengths.size());
1129*da58b97aSjoerg           if (Verbose)
1130*da58b97aSjoerg             *OS << "Unrecognized standard opcode";
1131*da58b97aSjoerg           uint8_t OpcodeLength = Prologue.StandardOpcodeLengths[Opcode - 1];
1132*da58b97aSjoerg           std::vector<uint64_t> Operands;
1133*da58b97aSjoerg           for (uint8_t I = 0; I < OpcodeLength; ++I) {
1134*da58b97aSjoerg             if (Optional<uint64_t> Value =
1135*da58b97aSjoerg                     parseULEB128<uint64_t>(TableData, Cursor))
1136*da58b97aSjoerg               Operands.push_back(*Value);
1137*da58b97aSjoerg             else
1138*da58b97aSjoerg               break;
1139*da58b97aSjoerg           }
1140*da58b97aSjoerg           if (Verbose && !Operands.empty()) {
1141*da58b97aSjoerg             *OS << " (operands: ";
1142*da58b97aSjoerg             bool First = true;
1143*da58b97aSjoerg             for (uint64_t Value : Operands) {
1144*da58b97aSjoerg               if (!First)
1145*da58b97aSjoerg                 *OS << ", ";
1146*da58b97aSjoerg               First = false;
1147*da58b97aSjoerg               *OS << format("0x%16.16" PRIx64, Value);
1148*da58b97aSjoerg             }
1149*da58b97aSjoerg             if (Verbose)
1150*da58b97aSjoerg               *OS << ')';
1151*da58b97aSjoerg           }
1152*da58b97aSjoerg         }
1153*da58b97aSjoerg         break;
1154*da58b97aSjoerg       }
1155*da58b97aSjoerg 
1156*da58b97aSjoerg       *OffsetPtr = Cursor.tell();
1157*da58b97aSjoerg     } else {
1158*da58b97aSjoerg       // Special Opcodes.
1159*da58b97aSjoerg       ParsingState::AddrAndLineDelta Delta =
1160*da58b97aSjoerg           State.handleSpecialOpcode(Opcode, OpcodeOffset);
1161*da58b97aSjoerg 
1162*da58b97aSjoerg       if (Verbose)
1163*da58b97aSjoerg         *OS << "address += " << Delta.Address << ",  line += " << Delta.Line;
1164*da58b97aSjoerg       EmitRow();
1165*da58b97aSjoerg       *OffsetPtr = Cursor.tell();
1166*da58b97aSjoerg     }
1167*da58b97aSjoerg 
1168*da58b97aSjoerg     // When a row is added to the matrix, it is also dumped, which includes a
1169*da58b97aSjoerg     // new line already, so don't add an extra one.
1170*da58b97aSjoerg     if (Verbose && Rows.size() == RowCount)
1171*da58b97aSjoerg       *OS << "\n";
1172*da58b97aSjoerg 
1173*da58b97aSjoerg     // Most parse failures other than when parsing extended opcodes are due to
1174*da58b97aSjoerg     // failures to read ULEBs. Bail out of parsing, since we don't know where to
1175*da58b97aSjoerg     // continue reading from as there is no stated length for such byte
1176*da58b97aSjoerg     // sequences. Print the final trailing new line if needed before doing so.
1177*da58b97aSjoerg     if (!Cursor && Opcode != 0) {
1178*da58b97aSjoerg       if (Verbose)
1179*da58b97aSjoerg         *OS << "\n";
1180*da58b97aSjoerg       return Cursor.takeError();
1181*da58b97aSjoerg     }
1182*da58b97aSjoerg 
1183*da58b97aSjoerg     if (!Cursor)
1184*da58b97aSjoerg       RecoverableErrorHandler(Cursor.takeError());
118506f32e7eSjoerg   }
118606f32e7eSjoerg 
118706f32e7eSjoerg   if (!State.Sequence.Empty)
1188*da58b97aSjoerg     RecoverableErrorHandler(createStringError(
1189*da58b97aSjoerg         errc::illegal_byte_sequence,
1190*da58b97aSjoerg         "last sequence in debug line table at offset 0x%8.8" PRIx64
1191*da58b97aSjoerg         " is not terminated",
1192*da58b97aSjoerg         DebugLineOffset));
119306f32e7eSjoerg 
119406f32e7eSjoerg   // Sort all sequences so that address lookup will work faster.
119506f32e7eSjoerg   if (!Sequences.empty()) {
119606f32e7eSjoerg     llvm::sort(Sequences, Sequence::orderByHighPC);
119706f32e7eSjoerg     // Note: actually, instruction address ranges of sequences should not
119806f32e7eSjoerg     // overlap (in shared objects and executables). If they do, the address
119906f32e7eSjoerg     // lookup would still work, though, but result would be ambiguous.
120006f32e7eSjoerg     // We don't report warning in this case. For example,
120106f32e7eSjoerg     // sometimes .so compiled from multiple object files contains a few
120206f32e7eSjoerg     // rudimentary sequences for address ranges [0x0, 0xsomething).
120306f32e7eSjoerg   }
120406f32e7eSjoerg 
1205*da58b97aSjoerg   // Terminate the table with a final blank line to clearly delineate it from
1206*da58b97aSjoerg   // later dumps.
1207*da58b97aSjoerg   if (OS)
1208*da58b97aSjoerg     *OS << "\n";
1209*da58b97aSjoerg 
121006f32e7eSjoerg   return Error::success();
121106f32e7eSjoerg }
121206f32e7eSjoerg 
findRowInSeq(const DWARFDebugLine::Sequence & Seq,object::SectionedAddress Address) const121306f32e7eSjoerg uint32_t DWARFDebugLine::LineTable::findRowInSeq(
121406f32e7eSjoerg     const DWARFDebugLine::Sequence &Seq,
121506f32e7eSjoerg     object::SectionedAddress Address) const {
121606f32e7eSjoerg   if (!Seq.containsPC(Address))
121706f32e7eSjoerg     return UnknownRowIndex;
121806f32e7eSjoerg   assert(Seq.SectionIndex == Address.SectionIndex);
121906f32e7eSjoerg   // In some cases, e.g. first instruction in a function, the compiler generates
122006f32e7eSjoerg   // two entries, both with the same address. We want the last one.
122106f32e7eSjoerg   //
122206f32e7eSjoerg   // In general we want a non-empty range: the last row whose address is less
122306f32e7eSjoerg   // than or equal to Address. This can be computed as upper_bound - 1.
122406f32e7eSjoerg   DWARFDebugLine::Row Row;
122506f32e7eSjoerg   Row.Address = Address;
122606f32e7eSjoerg   RowIter FirstRow = Rows.begin() + Seq.FirstRowIndex;
122706f32e7eSjoerg   RowIter LastRow = Rows.begin() + Seq.LastRowIndex;
122806f32e7eSjoerg   assert(FirstRow->Address.Address <= Row.Address.Address &&
122906f32e7eSjoerg          Row.Address.Address < LastRow[-1].Address.Address);
123006f32e7eSjoerg   RowIter RowPos = std::upper_bound(FirstRow + 1, LastRow - 1, Row,
123106f32e7eSjoerg                                     DWARFDebugLine::Row::orderByAddress) -
123206f32e7eSjoerg                    1;
123306f32e7eSjoerg   assert(Seq.SectionIndex == RowPos->Address.SectionIndex);
123406f32e7eSjoerg   return RowPos - Rows.begin();
123506f32e7eSjoerg }
123606f32e7eSjoerg 
lookupAddress(object::SectionedAddress Address) const123706f32e7eSjoerg uint32_t DWARFDebugLine::LineTable::lookupAddress(
123806f32e7eSjoerg     object::SectionedAddress Address) const {
123906f32e7eSjoerg 
124006f32e7eSjoerg   // Search for relocatable addresses
124106f32e7eSjoerg   uint32_t Result = lookupAddressImpl(Address);
124206f32e7eSjoerg 
124306f32e7eSjoerg   if (Result != UnknownRowIndex ||
124406f32e7eSjoerg       Address.SectionIndex == object::SectionedAddress::UndefSection)
124506f32e7eSjoerg     return Result;
124606f32e7eSjoerg 
124706f32e7eSjoerg   // Search for absolute addresses
124806f32e7eSjoerg   Address.SectionIndex = object::SectionedAddress::UndefSection;
124906f32e7eSjoerg   return lookupAddressImpl(Address);
125006f32e7eSjoerg }
125106f32e7eSjoerg 
lookupAddressImpl(object::SectionedAddress Address) const125206f32e7eSjoerg uint32_t DWARFDebugLine::LineTable::lookupAddressImpl(
125306f32e7eSjoerg     object::SectionedAddress Address) const {
125406f32e7eSjoerg   // First, find an instruction sequence containing the given address.
125506f32e7eSjoerg   DWARFDebugLine::Sequence Sequence;
125606f32e7eSjoerg   Sequence.SectionIndex = Address.SectionIndex;
125706f32e7eSjoerg   Sequence.HighPC = Address.Address;
125806f32e7eSjoerg   SequenceIter It = llvm::upper_bound(Sequences, Sequence,
125906f32e7eSjoerg                                       DWARFDebugLine::Sequence::orderByHighPC);
126006f32e7eSjoerg   if (It == Sequences.end() || It->SectionIndex != Address.SectionIndex)
126106f32e7eSjoerg     return UnknownRowIndex;
126206f32e7eSjoerg   return findRowInSeq(*It, Address);
126306f32e7eSjoerg }
126406f32e7eSjoerg 
lookupAddressRange(object::SectionedAddress Address,uint64_t Size,std::vector<uint32_t> & Result) const126506f32e7eSjoerg bool DWARFDebugLine::LineTable::lookupAddressRange(
126606f32e7eSjoerg     object::SectionedAddress Address, uint64_t Size,
126706f32e7eSjoerg     std::vector<uint32_t> &Result) const {
126806f32e7eSjoerg 
126906f32e7eSjoerg   // Search for relocatable addresses
127006f32e7eSjoerg   if (lookupAddressRangeImpl(Address, Size, Result))
127106f32e7eSjoerg     return true;
127206f32e7eSjoerg 
127306f32e7eSjoerg   if (Address.SectionIndex == object::SectionedAddress::UndefSection)
127406f32e7eSjoerg     return false;
127506f32e7eSjoerg 
127606f32e7eSjoerg   // Search for absolute addresses
127706f32e7eSjoerg   Address.SectionIndex = object::SectionedAddress::UndefSection;
127806f32e7eSjoerg   return lookupAddressRangeImpl(Address, Size, Result);
127906f32e7eSjoerg }
128006f32e7eSjoerg 
lookupAddressRangeImpl(object::SectionedAddress Address,uint64_t Size,std::vector<uint32_t> & Result) const128106f32e7eSjoerg bool DWARFDebugLine::LineTable::lookupAddressRangeImpl(
128206f32e7eSjoerg     object::SectionedAddress Address, uint64_t Size,
128306f32e7eSjoerg     std::vector<uint32_t> &Result) const {
128406f32e7eSjoerg   if (Sequences.empty())
128506f32e7eSjoerg     return false;
128606f32e7eSjoerg   uint64_t EndAddr = Address.Address + Size;
128706f32e7eSjoerg   // First, find an instruction sequence containing the given address.
128806f32e7eSjoerg   DWARFDebugLine::Sequence Sequence;
128906f32e7eSjoerg   Sequence.SectionIndex = Address.SectionIndex;
129006f32e7eSjoerg   Sequence.HighPC = Address.Address;
129106f32e7eSjoerg   SequenceIter LastSeq = Sequences.end();
129206f32e7eSjoerg   SequenceIter SeqPos = llvm::upper_bound(
129306f32e7eSjoerg       Sequences, Sequence, DWARFDebugLine::Sequence::orderByHighPC);
129406f32e7eSjoerg   if (SeqPos == LastSeq || !SeqPos->containsPC(Address))
129506f32e7eSjoerg     return false;
129606f32e7eSjoerg 
129706f32e7eSjoerg   SequenceIter StartPos = SeqPos;
129806f32e7eSjoerg 
129906f32e7eSjoerg   // Add the rows from the first sequence to the vector, starting with the
130006f32e7eSjoerg   // index we just calculated
130106f32e7eSjoerg 
130206f32e7eSjoerg   while (SeqPos != LastSeq && SeqPos->LowPC < EndAddr) {
130306f32e7eSjoerg     const DWARFDebugLine::Sequence &CurSeq = *SeqPos;
130406f32e7eSjoerg     // For the first sequence, we need to find which row in the sequence is the
130506f32e7eSjoerg     // first in our range.
130606f32e7eSjoerg     uint32_t FirstRowIndex = CurSeq.FirstRowIndex;
130706f32e7eSjoerg     if (SeqPos == StartPos)
130806f32e7eSjoerg       FirstRowIndex = findRowInSeq(CurSeq, Address);
130906f32e7eSjoerg 
131006f32e7eSjoerg     // Figure out the last row in the range.
131106f32e7eSjoerg     uint32_t LastRowIndex =
131206f32e7eSjoerg         findRowInSeq(CurSeq, {EndAddr - 1, Address.SectionIndex});
131306f32e7eSjoerg     if (LastRowIndex == UnknownRowIndex)
131406f32e7eSjoerg       LastRowIndex = CurSeq.LastRowIndex - 1;
131506f32e7eSjoerg 
131606f32e7eSjoerg     assert(FirstRowIndex != UnknownRowIndex);
131706f32e7eSjoerg     assert(LastRowIndex != UnknownRowIndex);
131806f32e7eSjoerg 
131906f32e7eSjoerg     for (uint32_t I = FirstRowIndex; I <= LastRowIndex; ++I) {
132006f32e7eSjoerg       Result.push_back(I);
132106f32e7eSjoerg     }
132206f32e7eSjoerg 
132306f32e7eSjoerg     ++SeqPos;
132406f32e7eSjoerg   }
132506f32e7eSjoerg 
132606f32e7eSjoerg   return true;
132706f32e7eSjoerg }
132806f32e7eSjoerg 
getSourceByIndex(uint64_t FileIndex,FileLineInfoKind Kind) const132906f32e7eSjoerg Optional<StringRef> DWARFDebugLine::LineTable::getSourceByIndex(uint64_t FileIndex,
133006f32e7eSjoerg                                                                 FileLineInfoKind Kind) const {
133106f32e7eSjoerg   if (Kind == FileLineInfoKind::None || !Prologue.hasFileAtIndex(FileIndex))
133206f32e7eSjoerg     return None;
133306f32e7eSjoerg   const FileNameEntry &Entry = Prologue.getFileNameEntry(FileIndex);
133406f32e7eSjoerg   if (Optional<const char *> source = Entry.Source.getAsCString())
133506f32e7eSjoerg     return StringRef(*source);
133606f32e7eSjoerg   return None;
133706f32e7eSjoerg }
133806f32e7eSjoerg 
isPathAbsoluteOnWindowsOrPosix(const Twine & Path)133906f32e7eSjoerg static bool isPathAbsoluteOnWindowsOrPosix(const Twine &Path) {
134006f32e7eSjoerg   // Debug info can contain paths from any OS, not necessarily
134106f32e7eSjoerg   // an OS we're currently running on. Moreover different compilation units can
134206f32e7eSjoerg   // be compiled on different operating systems and linked together later.
134306f32e7eSjoerg   return sys::path::is_absolute(Path, sys::path::Style::posix) ||
134406f32e7eSjoerg          sys::path::is_absolute(Path, sys::path::Style::windows);
134506f32e7eSjoerg }
134606f32e7eSjoerg 
getFileNameByIndex(uint64_t FileIndex,StringRef CompDir,FileLineInfoKind Kind,std::string & Result,sys::path::Style Style) const134706f32e7eSjoerg bool DWARFDebugLine::Prologue::getFileNameByIndex(
134806f32e7eSjoerg     uint64_t FileIndex, StringRef CompDir, FileLineInfoKind Kind,
134906f32e7eSjoerg     std::string &Result, sys::path::Style Style) const {
135006f32e7eSjoerg   if (Kind == FileLineInfoKind::None || !hasFileAtIndex(FileIndex))
135106f32e7eSjoerg     return false;
135206f32e7eSjoerg   const FileNameEntry &Entry = getFileNameEntry(FileIndex);
1353*da58b97aSjoerg   Optional<const char *> Name = Entry.Name.getAsCString();
1354*da58b97aSjoerg   if (!Name)
1355*da58b97aSjoerg     return false;
1356*da58b97aSjoerg   StringRef FileName = *Name;
1357*da58b97aSjoerg   if (Kind == FileLineInfoKind::RawValue ||
135806f32e7eSjoerg       isPathAbsoluteOnWindowsOrPosix(FileName)) {
1359*da58b97aSjoerg     Result = std::string(FileName);
1360*da58b97aSjoerg     return true;
1361*da58b97aSjoerg   }
1362*da58b97aSjoerg   if (Kind == FileLineInfoKind::BaseNameOnly) {
1363*da58b97aSjoerg     Result = std::string(llvm::sys::path::filename(FileName));
136406f32e7eSjoerg     return true;
136506f32e7eSjoerg   }
136606f32e7eSjoerg 
136706f32e7eSjoerg   SmallString<16> FilePath;
136806f32e7eSjoerg   StringRef IncludeDir;
136906f32e7eSjoerg   // Be defensive about the contents of Entry.
137006f32e7eSjoerg   if (getVersion() >= 5) {
1371*da58b97aSjoerg     // DirIdx 0 is the compilation directory, so don't include it for
1372*da58b97aSjoerg     // relative names.
1373*da58b97aSjoerg     if ((Entry.DirIdx != 0 || Kind != FileLineInfoKind::RelativeFilePath) &&
1374*da58b97aSjoerg         Entry.DirIdx < IncludeDirectories.size())
137506f32e7eSjoerg       IncludeDir = IncludeDirectories[Entry.DirIdx].getAsCString().getValue();
137606f32e7eSjoerg   } else {
137706f32e7eSjoerg     if (0 < Entry.DirIdx && Entry.DirIdx <= IncludeDirectories.size())
137806f32e7eSjoerg       IncludeDir =
137906f32e7eSjoerg           IncludeDirectories[Entry.DirIdx - 1].getAsCString().getValue();
138006f32e7eSjoerg   }
138106f32e7eSjoerg 
1382*da58b97aSjoerg   // For absolute paths only, include the compilation directory of compile unit.
1383*da58b97aSjoerg   // We know that FileName is not absolute, the only way to have an absolute
1384*da58b97aSjoerg   // path at this point would be if IncludeDir is absolute.
1385*da58b97aSjoerg   if (Kind == FileLineInfoKind::AbsoluteFilePath && !CompDir.empty() &&
1386*da58b97aSjoerg       !isPathAbsoluteOnWindowsOrPosix(IncludeDir))
1387*da58b97aSjoerg     sys::path::append(FilePath, Style, CompDir);
1388*da58b97aSjoerg 
1389*da58b97aSjoerg   assert((Kind == FileLineInfoKind::AbsoluteFilePath ||
1390*da58b97aSjoerg           Kind == FileLineInfoKind::RelativeFilePath) &&
1391*da58b97aSjoerg          "invalid FileLineInfo Kind");
1392*da58b97aSjoerg 
139306f32e7eSjoerg   // sys::path::append skips empty strings.
139406f32e7eSjoerg   sys::path::append(FilePath, Style, IncludeDir, FileName);
1395*da58b97aSjoerg   Result = std::string(FilePath.str());
139606f32e7eSjoerg   return true;
139706f32e7eSjoerg }
139806f32e7eSjoerg 
getFileLineInfoForAddress(object::SectionedAddress Address,const char * CompDir,FileLineInfoKind Kind,DILineInfo & Result) const139906f32e7eSjoerg bool DWARFDebugLine::LineTable::getFileLineInfoForAddress(
140006f32e7eSjoerg     object::SectionedAddress Address, const char *CompDir,
140106f32e7eSjoerg     FileLineInfoKind Kind, DILineInfo &Result) const {
140206f32e7eSjoerg   // Get the index of row we're looking for in the line table.
140306f32e7eSjoerg   uint32_t RowIndex = lookupAddress(Address);
140406f32e7eSjoerg   if (RowIndex == -1U)
140506f32e7eSjoerg     return false;
140606f32e7eSjoerg   // Take file number and line/column from the row.
140706f32e7eSjoerg   const auto &Row = Rows[RowIndex];
140806f32e7eSjoerg   if (!getFileNameByIndex(Row.File, CompDir, Kind, Result.FileName))
140906f32e7eSjoerg     return false;
141006f32e7eSjoerg   Result.Line = Row.Line;
141106f32e7eSjoerg   Result.Column = Row.Column;
141206f32e7eSjoerg   Result.Discriminator = Row.Discriminator;
141306f32e7eSjoerg   Result.Source = getSourceByIndex(Row.File, Kind);
141406f32e7eSjoerg   return true;
141506f32e7eSjoerg }
141606f32e7eSjoerg 
141706f32e7eSjoerg // We want to supply the Unit associated with a .debug_line[.dwo] table when
141806f32e7eSjoerg // we dump it, if possible, but still dump the table even if there isn't a Unit.
141906f32e7eSjoerg // Therefore, collect up handles on all the Units that point into the
142006f32e7eSjoerg // line-table section.
142106f32e7eSjoerg static DWARFDebugLine::SectionParser::LineToUnitMap
buildLineToUnitMap(DWARFUnitVector::iterator_range Units)1422*da58b97aSjoerg buildLineToUnitMap(DWARFUnitVector::iterator_range Units) {
142306f32e7eSjoerg   DWARFDebugLine::SectionParser::LineToUnitMap LineToUnit;
1424*da58b97aSjoerg   for (const auto &U : Units)
1425*da58b97aSjoerg     if (auto CUDIE = U->getUnitDIE())
142606f32e7eSjoerg       if (auto StmtOffset = toSectionOffset(CUDIE.find(DW_AT_stmt_list)))
1427*da58b97aSjoerg         LineToUnit.insert(std::make_pair(*StmtOffset, &*U));
142806f32e7eSjoerg   return LineToUnit;
142906f32e7eSjoerg }
143006f32e7eSjoerg 
SectionParser(DWARFDataExtractor & Data,const DWARFContext & C,DWARFUnitVector::iterator_range Units)1431*da58b97aSjoerg DWARFDebugLine::SectionParser::SectionParser(
1432*da58b97aSjoerg     DWARFDataExtractor &Data, const DWARFContext &C,
1433*da58b97aSjoerg     DWARFUnitVector::iterator_range Units)
143406f32e7eSjoerg     : DebugLineData(Data), Context(C) {
1435*da58b97aSjoerg   LineToUnit = buildLineToUnitMap(Units);
143606f32e7eSjoerg   if (!DebugLineData.isValidOffset(Offset))
143706f32e7eSjoerg     Done = true;
143806f32e7eSjoerg }
143906f32e7eSjoerg 
totalLengthIsValid() const144006f32e7eSjoerg bool DWARFDebugLine::Prologue::totalLengthIsValid() const {
1441*da58b97aSjoerg   return TotalLength != 0u;
144206f32e7eSjoerg }
144306f32e7eSjoerg 
parseNext(function_ref<void (Error)> RecoverableErrorHandler,function_ref<void (Error)> UnrecoverableErrorHandler,raw_ostream * OS,bool Verbose)144406f32e7eSjoerg DWARFDebugLine::LineTable DWARFDebugLine::SectionParser::parseNext(
1445*da58b97aSjoerg     function_ref<void(Error)> RecoverableErrorHandler,
1446*da58b97aSjoerg     function_ref<void(Error)> UnrecoverableErrorHandler, raw_ostream *OS,
1447*da58b97aSjoerg     bool Verbose) {
144806f32e7eSjoerg   assert(DebugLineData.isValidOffset(Offset) &&
144906f32e7eSjoerg          "parsing should have terminated");
145006f32e7eSjoerg   DWARFUnit *U = prepareToParse(Offset);
145106f32e7eSjoerg   uint64_t OldOffset = Offset;
145206f32e7eSjoerg   LineTable LT;
145306f32e7eSjoerg   if (Error Err = LT.parse(DebugLineData, &Offset, Context, U,
1454*da58b97aSjoerg                            RecoverableErrorHandler, OS, Verbose))
1455*da58b97aSjoerg     UnrecoverableErrorHandler(std::move(Err));
145606f32e7eSjoerg   moveToNextTable(OldOffset, LT.Prologue);
145706f32e7eSjoerg   return LT;
145806f32e7eSjoerg }
145906f32e7eSjoerg 
skip(function_ref<void (Error)> RecoverableErrorHandler,function_ref<void (Error)> UnrecoverableErrorHandler)146006f32e7eSjoerg void DWARFDebugLine::SectionParser::skip(
1461*da58b97aSjoerg     function_ref<void(Error)> RecoverableErrorHandler,
1462*da58b97aSjoerg     function_ref<void(Error)> UnrecoverableErrorHandler) {
146306f32e7eSjoerg   assert(DebugLineData.isValidOffset(Offset) &&
146406f32e7eSjoerg          "parsing should have terminated");
146506f32e7eSjoerg   DWARFUnit *U = prepareToParse(Offset);
146606f32e7eSjoerg   uint64_t OldOffset = Offset;
146706f32e7eSjoerg   LineTable LT;
1468*da58b97aSjoerg   if (Error Err = LT.Prologue.parse(DebugLineData, &Offset,
1469*da58b97aSjoerg                                     RecoverableErrorHandler, Context, U))
1470*da58b97aSjoerg     UnrecoverableErrorHandler(std::move(Err));
147106f32e7eSjoerg   moveToNextTable(OldOffset, LT.Prologue);
147206f32e7eSjoerg }
147306f32e7eSjoerg 
prepareToParse(uint64_t Offset)147406f32e7eSjoerg DWARFUnit *DWARFDebugLine::SectionParser::prepareToParse(uint64_t Offset) {
147506f32e7eSjoerg   DWARFUnit *U = nullptr;
147606f32e7eSjoerg   auto It = LineToUnit.find(Offset);
147706f32e7eSjoerg   if (It != LineToUnit.end())
147806f32e7eSjoerg     U = It->second;
147906f32e7eSjoerg   DebugLineData.setAddressSize(U ? U->getAddressByteSize() : 0);
148006f32e7eSjoerg   return U;
148106f32e7eSjoerg }
148206f32e7eSjoerg 
moveToNextTable(uint64_t OldOffset,const Prologue & P)148306f32e7eSjoerg void DWARFDebugLine::SectionParser::moveToNextTable(uint64_t OldOffset,
148406f32e7eSjoerg                                                     const Prologue &P) {
148506f32e7eSjoerg   // If the length field is not valid, we don't know where the next table is, so
148606f32e7eSjoerg   // cannot continue to parse. Mark the parser as done, and leave the Offset
148706f32e7eSjoerg   // value as it currently is. This will be the end of the bad length field.
148806f32e7eSjoerg   if (!P.totalLengthIsValid()) {
148906f32e7eSjoerg     Done = true;
149006f32e7eSjoerg     return;
149106f32e7eSjoerg   }
149206f32e7eSjoerg 
149306f32e7eSjoerg   Offset = OldOffset + P.TotalLength + P.sizeofTotalLength();
149406f32e7eSjoerg   if (!DebugLineData.isValidOffset(Offset)) {
149506f32e7eSjoerg     Done = true;
149606f32e7eSjoerg   }
149706f32e7eSjoerg }
1498