LCOV - code coverage report
Current view: top level - lib/DebugInfo/DWARF - DWARFDebugLine.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 512 551 92.9 %
Date: 2018-05-20 00:06:23 Functions: 54 54 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : //===- DWARFDebugLine.cpp -------------------------------------------------===//
       2             : //
       3             : //                     The LLVM Compiler Infrastructure
       4             : //
       5             : // This file is distributed under the University of Illinois Open Source
       6             : // License. See LICENSE.TXT for details.
       7             : //
       8             : //===----------------------------------------------------------------------===//
       9             : 
      10             : #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
      11             : #include "llvm/ADT/Optional.h"
      12             : #include "llvm/ADT/SmallString.h"
      13             : #include "llvm/ADT/SmallVector.h"
      14             : #include "llvm/ADT/StringRef.h"
      15             : #include "llvm/BinaryFormat/Dwarf.h"
      16             : #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
      17             : #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
      18             : #include "llvm/Support/Format.h"
      19             : #include "llvm/Support/Path.h"
      20             : #include "llvm/Support/WithColor.h"
      21             : #include "llvm/Support/raw_ostream.h"
      22             : #include <algorithm>
      23             : #include <cassert>
      24             : #include <cinttypes>
      25             : #include <cstdint>
      26             : #include <cstdio>
      27             : #include <utility>
      28             : 
      29             : using namespace llvm;
      30             : using namespace dwarf;
      31             : 
      32             : using FileLineInfoKind = DILineInfoSpecifier::FileLineInfoKind;
      33             : 
      34             : namespace {
      35             : 
      36             : struct ContentDescriptor {
      37             :   dwarf::LineNumberEntryFormat Type;
      38             :   dwarf::Form Form;
      39             : };
      40             : 
      41             : using ContentDescriptors = SmallVector<ContentDescriptor, 4>;
      42             : 
      43             : } // end anonmyous namespace
      44             : 
      45         138 : void DWARFDebugLine::ContentTypeTracker::trackContentType(
      46             :     dwarf::LineNumberEntryFormat ContentType) {
      47         138 :   switch (ContentType) {
      48           4 :   case dwarf::DW_LNCT_timestamp:
      49           4 :     HasModTime = true;
      50           4 :     break;
      51           4 :   case dwarf::DW_LNCT_size:
      52           4 :     HasLength = true;
      53           4 :     break;
      54          23 :   case dwarf::DW_LNCT_MD5:
      55          23 :     HasMD5 = true;
      56          23 :     break;
      57           5 :   case dwarf::DW_LNCT_LLVM_source:
      58           5 :     HasSource = true;
      59           5 :     break;
      60             :   default:
      61             :     // We only care about values we consider optional, and new values may be
      62             :     // added in the vendor extension range, so we do not match exhaustively.
      63             :     break;
      64             :   }
      65         138 : }
      66             : 
      67        2794 : DWARFDebugLine::Prologue::Prologue() { clear(); }
      68             : 
      69        5442 : void DWARFDebugLine::Prologue::clear() {
      70        5442 :   TotalLength = PrologueLength = 0;
      71        5442 :   SegSelectorSize = 0;
      72        5442 :   MinInstLength = MaxOpsPerInst = DefaultIsStmt = LineBase = LineRange = 0;
      73        5442 :   OpcodeBase = 0;
      74        5442 :   FormParams = dwarf::FormParams({0, 0, DWARF32});
      75        5442 :   ContentTypes = ContentTypeTracker();
      76             :   StandardOpcodeLengths.clear();
      77             :   IncludeDirectories.clear();
      78             :   FileNames.clear();
      79        5442 : }
      80             : 
      81         333 : void DWARFDebugLine::Prologue::dump(raw_ostream &OS,
      82             :                                     DIDumpOptions DumpOptions) const {
      83         333 :   OS << "Line table prologue:\n"
      84         999 :      << format("    total_length: 0x%8.8" PRIx64 "\n", TotalLength)
      85         666 :      << format("         version: %u\n", getVersion());
      86         333 :   if (getVersion() >= 5)
      87          99 :     OS << format("    address_size: %u\n", getAddressSize())
      88          33 :        << format(" seg_select_size: %u\n", SegSelectorSize);
      89         999 :   OS << format(" prologue_length: 0x%8.8" PRIx64 "\n", PrologueLength)
      90         666 :      << format(" min_inst_length: %u\n", MinInstLength)
      91         999 :      << format(getVersion() >= 4 ? "max_ops_per_inst: %u\n" : "", MaxOpsPerInst)
      92         666 :      << format(" default_is_stmt: %u\n", DefaultIsStmt)
      93         666 :      << format("       line_base: %i\n", LineBase)
      94         666 :      << format("      line_range: %u\n", LineRange)
      95         333 :      << format("     opcode_base: %u\n", OpcodeBase);
      96             : 
      97       12177 :   for (uint32_t I = 0; I != StandardOpcodeLengths.size(); ++I)
      98        3837 :     OS << format("standard_opcode_lengths[%s] = %u\n",
      99        7674 :                  LNStandardString(I + 1).data(), StandardOpcodeLengths[I]);
     100             : 
     101         333 :   if (!IncludeDirectories.empty()) {
     102             :     // DWARF v5 starts directory indexes at 0.
     103          69 :     uint32_t DirBase = getVersion() >= 5 ? 0 : 1;
     104         450 :     for (uint32_t I = 0; I != IncludeDirectories.size(); ++I) {
     105         208 :       OS << format("include_directories[%3u] = ", I + DirBase);
     106         208 :       IncludeDirectories[I].dump(OS, DumpOptions);
     107             :       OS << '\n';
     108             :     }
     109             :   }
     110             : 
     111         333 :   if (!FileNames.empty()) {
     112             :     // DWARF v5 starts file indexes at 0.
     113         300 :     uint32_t FileBase = getVersion() >= 5 ? 0 : 1;
     114        1782 :     for (uint32_t I = 0; I != FileNames.size(); ++I) {
     115             :       const FileNameEntry &FileEntry = FileNames[I];
     116         788 :       OS <<   format("file_names[%3u]:\n", I + FileBase);
     117         394 :       OS <<          "           name: ";
     118         394 :       FileEntry.Name.dump(OS, DumpOptions);
     119             :       OS << '\n'
     120         788 :          <<   format("      dir_index: %" PRIu64 "\n", FileEntry.DirIdx);
     121         394 :       if (ContentTypes.HasMD5)
     122          58 :         OS <<        "   md5_checksum: " << FileEntry.Checksum.digest() << '\n';
     123         394 :       if (ContentTypes.HasModTime)
     124         674 :         OS << format("       mod_time: 0x%8.8" PRIx64 "\n", FileEntry.ModTime);
     125         394 :       if (ContentTypes.HasLength)
     126         337 :         OS << format("         length: 0x%8.8" PRIx64 "\n", FileEntry.Length);
     127         394 :       if (ContentTypes.HasSource) {
     128           9 :         OS <<        "         source: ";
     129           9 :         FileEntry.Source.dump(OS, DumpOptions);
     130             :         OS << '\n';
     131             :       }
     132             :     }
     133             :   }
     134         333 : }
     135             : 
     136             : // Parse v2-v4 directory and file tables.
     137             : static void
     138        1273 : parseV2DirFileTables(const DWARFDataExtractor &DebugLineData,
     139             :                      uint32_t *OffsetPtr, uint64_t EndPrologueOffset,
     140             :                      DWARFDebugLine::ContentTypeTracker &ContentTypes,
     141             :                      std::vector<DWARFFormValue> &IncludeDirectories,
     142             :                      std::vector<DWARFDebugLine::FileNameEntry> &FileNames) {
     143        2175 :   while (*OffsetPtr < EndPrologueOffset) {
     144        1724 :     StringRef S = DebugLineData.getCStrRef(OffsetPtr);
     145        1724 :     if (S.empty())
     146             :       break;
     147             :     DWARFFormValue Dir(dwarf::DW_FORM_string);
     148             :     Dir.setPValue(S.data());
     149         451 :     IncludeDirectories.push_back(Dir);
     150             :   }
     151             : 
     152        4903 :   while (*OffsetPtr < EndPrologueOffset) {
     153        3081 :     StringRef Name = DebugLineData.getCStrRef(OffsetPtr);
     154        3081 :     if (Name.empty())
     155             :       break;
     156             :     DWARFDebugLine::FileNameEntry FileEntry;
     157             :     FileEntry.Name.setForm(dwarf::DW_FORM_string);
     158             :     FileEntry.Name.setPValue(Name.data());
     159        1815 :     FileEntry.DirIdx = DebugLineData.getULEB128(OffsetPtr);
     160        1815 :     FileEntry.ModTime = DebugLineData.getULEB128(OffsetPtr);
     161        1815 :     FileEntry.Length = DebugLineData.getULEB128(OffsetPtr);
     162        1815 :     FileNames.push_back(FileEntry);
     163             :   }
     164             : 
     165        1273 :   ContentTypes.HasModTime = true;
     166        1273 :   ContentTypes.HasLength = true;
     167        1273 : }
     168             : 
     169             : // Parse v5 directory/file entry content descriptions.
     170             : // Returns the descriptors, or an empty vector if we did not find a path or
     171             : // ran off the end of the prologue.
     172             : static ContentDescriptors
     173         116 : parseV5EntryFormat(const DWARFDataExtractor &DebugLineData, uint32_t
     174             :     *OffsetPtr, uint64_t EndPrologueOffset, DWARFDebugLine::ContentTypeTracker
     175             :     *ContentTypes) {
     176             :   ContentDescriptors Descriptors;
     177         116 :   int FormatCount = DebugLineData.getU8(OffsetPtr);
     178             :   bool HasPath = false;
     179         510 :   for (int I = 0; I != FormatCount; ++I) {
     180         197 :     if (*OffsetPtr >= EndPrologueOffset)
     181           0 :       return ContentDescriptors();
     182             :     ContentDescriptor Descriptor;
     183         197 :     Descriptor.Type =
     184         197 :       dwarf::LineNumberEntryFormat(DebugLineData.getULEB128(OffsetPtr));
     185         197 :     Descriptor.Form = dwarf::Form(DebugLineData.getULEB128(OffsetPtr));
     186         197 :     if (Descriptor.Type == dwarf::DW_LNCT_path)
     187             :       HasPath = true;
     188         197 :     if (ContentTypes)
     189         138 :       ContentTypes->trackContentType(Descriptor.Type);
     190         197 :     Descriptors.push_back(Descriptor);
     191             :   }
     192         116 :   return HasPath ? Descriptors : ContentDescriptors();
     193             : }
     194             : 
     195             : static bool
     196          61 : parseV5DirFileTables(const DWARFDataExtractor &DebugLineData,
     197             :                      uint32_t *OffsetPtr, uint64_t EndPrologueOffset,
     198             :                      const dwarf::FormParams &FormParams,
     199             :                      const DWARFContext &Ctx, const DWARFUnit *U,
     200             :                      DWARFDebugLine::ContentTypeTracker &ContentTypes,
     201             :                      std::vector<DWARFFormValue> &IncludeDirectories,
     202             :                      std::vector<DWARFDebugLine::FileNameEntry> &FileNames) {
     203             :   // Get the directory entry description.
     204             :   ContentDescriptors DirDescriptors =
     205          61 :       parseV5EntryFormat(DebugLineData, OffsetPtr, EndPrologueOffset, nullptr);
     206          61 :   if (DirDescriptors.empty())
     207             :     return false;
     208             : 
     209             :   // Get the directory entries, according to the format described above.
     210          56 :   int DirEntryCount = DebugLineData.getU8(OffsetPtr);
     211         188 :   for (int I = 0; I != DirEntryCount; ++I) {
     212          67 :     if (*OffsetPtr >= EndPrologueOffset)
     213             :       return false;
     214         199 :     for (auto Descriptor : DirDescriptors) {
     215          67 :       DWARFFormValue Value(Descriptor.Form);
     216          67 :       switch (Descriptor.Type) {
     217          66 :       case DW_LNCT_path:
     218          66 :         if (!Value.extractValue(DebugLineData, OffsetPtr, FormParams, &Ctx, U))
     219           1 :           return false;
     220          66 :         IncludeDirectories.push_back(Value);
     221          66 :         break;
     222           1 :       default:
     223           1 :         if (!Value.skipValue(DebugLineData, OffsetPtr, FormParams))
     224             :           return false;
     225             :       }
     226             :     }
     227             :   }
     228             : 
     229             :   // Get the file entry description.
     230             :   ContentDescriptors FileDescriptors =
     231             :       parseV5EntryFormat(DebugLineData, OffsetPtr, EndPrologueOffset,
     232          55 :           &ContentTypes);
     233          55 :   if (FileDescriptors.empty())
     234             :     return false;
     235             : 
     236             :   // Get the file entries, according to the format described above.
     237          55 :   int FileEntryCount = DebugLineData.getU8(OffsetPtr);
     238         263 :   for (int I = 0; I != FileEntryCount; ++I) {
     239         104 :     if (*OffsetPtr >= EndPrologueOffset)
     240           0 :       return false;
     241             :     DWARFDebugLine::FileNameEntry FileEntry;
     242         652 :     for (auto Descriptor : FileDescriptors) {
     243             :       DWARFFormValue Value(Descriptor.Form);
     244         274 :       if (!Value.extractValue(DebugLineData, OffsetPtr, FormParams, &Ctx, U))
     245           0 :         return false;
     246         274 :       switch (Descriptor.Type) {
     247         104 :       case DW_LNCT_path:
     248         104 :         FileEntry.Name = Value;
     249         104 :         break;
     250          11 :       case DW_LNCT_LLVM_source:
     251          11 :         FileEntry.Source = Value;
     252          11 :         break;
     253          96 :       case DW_LNCT_directory_index:
     254          96 :         FileEntry.DirIdx = Value.getAsUnsignedConstant().getValue();
     255          96 :         break;
     256           8 :       case DW_LNCT_timestamp:
     257           8 :         FileEntry.ModTime = Value.getAsUnsignedConstant().getValue();
     258           8 :         break;
     259           8 :       case DW_LNCT_size:
     260           8 :         FileEntry.Length = Value.getAsUnsignedConstant().getValue();
     261           8 :         break;
     262             :       case DW_LNCT_MD5:
     263             :         assert(Value.getAsBlock().getValue().size() == 16);
     264          94 :         std::uninitialized_copy_n(Value.getAsBlock().getValue().begin(), 16,
     265             :                                   FileEntry.Checksum.Bytes.begin());
     266          47 :         break;
     267             :       default:
     268             :         break;
     269             :       }
     270             :     }
     271         104 :     FileNames.push_back(FileEntry);
     272             :   }
     273             :   return true;
     274             : }
     275             : 
     276             : template <typename... Ts>
     277          59 : static std::string formatErrorString(char const *Fmt, const Ts &... Vals) {
     278             :   std::string Buffer;
     279          59 :   raw_string_ostream Stream(Buffer);
     280         118 :   Stream << format(Fmt, Vals...);
     281          59 :   return Stream.str();
     282             : }
     283             : 
     284             : template <typename... Ts>
     285          59 : static Error createError(char const *Fmt, const Ts &... Vals) {
     286             :   return make_error<StringError>(formatErrorString(Fmt, Vals...),
     287         118 :                                  inconvertibleErrorCode());
     288             : }
     289             : 
     290        1355 : Error DWARFDebugLine::Prologue::parse(const DWARFDataExtractor &DebugLineData,
     291             :                                       uint32_t *OffsetPtr,
     292             :                                       const DWARFContext &Ctx,
     293             :                                       const DWARFUnit *U) {
     294        1355 :   const uint64_t PrologueOffset = *OffsetPtr;
     295             : 
     296        1355 :   clear();
     297        1355 :   TotalLength = DebugLineData.getU32(OffsetPtr);
     298        1355 :   if (TotalLength == UINT32_MAX) {
     299          16 :     FormParams.Format = dwarf::DWARF64;
     300          16 :     TotalLength = DebugLineData.getU64(OffsetPtr);
     301        1339 :   } else if (TotalLength >= 0xffffff00) {
     302             :     return createError(
     303             :         "parsing line table prologue at offset 0x%8.8" PRIx64
     304             :         " unsupported reserved unit length found of value 0x%8.8" PRIx64,
     305           7 :         PrologueOffset, TotalLength);
     306             :   }
     307        1348 :   FormParams.Version = DebugLineData.getU16(OffsetPtr);
     308        1348 :   if (getVersion() < 2)
     309             :     return createError("parsing line table prologue at offset 0x%8.8" PRIx64
     310             :                        " found unsupported version 0x%2.2" PRIx16,
     311          14 :                        PrologueOffset, getVersion());
     312             : 
     313        1334 :   if (getVersion() >= 5) {
     314          61 :     FormParams.AddrSize = DebugLineData.getU8(OffsetPtr);
     315             :     assert((DebugLineData.getAddressSize() == 0 ||
     316             :             DebugLineData.getAddressSize() == getAddressSize()) &&
     317             :            "Line table header and data extractor disagree");
     318          61 :     SegSelectorSize = DebugLineData.getU8(OffsetPtr);
     319             :   }
     320             : 
     321        1334 :   PrologueLength = DebugLineData.getUnsigned(OffsetPtr, sizeofPrologueLength());
     322        1334 :   const uint64_t EndPrologueOffset = PrologueLength + *OffsetPtr;
     323        1334 :   MinInstLength = DebugLineData.getU8(OffsetPtr);
     324        1334 :   if (getVersion() >= 4)
     325         413 :     MaxOpsPerInst = DebugLineData.getU8(OffsetPtr);
     326        1334 :   DefaultIsStmt = DebugLineData.getU8(OffsetPtr);
     327        1334 :   LineBase = DebugLineData.getU8(OffsetPtr);
     328        1334 :   LineRange = DebugLineData.getU8(OffsetPtr);
     329        1334 :   OpcodeBase = DebugLineData.getU8(OffsetPtr);
     330             : 
     331        1334 :   StandardOpcodeLengths.reserve(OpcodeBase - 1);
     332       32896 :   for (uint32_t I = 1; I < OpcodeBase; ++I) {
     333       15781 :     uint8_t OpLen = DebugLineData.getU8(OffsetPtr);
     334       15781 :     StandardOpcodeLengths.push_back(OpLen);
     335             :   }
     336             : 
     337        1334 :   if (getVersion() >= 5) {
     338          61 :     if (!parseV5DirFileTables(DebugLineData, OffsetPtr, EndPrologueOffset,
     339             :                               FormParams, Ctx, U, ContentTypes,
     340             :                               IncludeDirectories, FileNames)) {
     341             :       return createError(
     342             :           "parsing line table prologue at 0x%8.8" PRIx64
     343             :           " found an invalid directory or file table description at"
     344             :           " 0x%8.8" PRIx64,
     345           6 :           PrologueOffset, (uint64_t)*OffsetPtr);
     346             :     }
     347             :   } else
     348        1273 :     parseV2DirFileTables(DebugLineData, OffsetPtr, EndPrologueOffset,
     349             :                          ContentTypes, IncludeDirectories, FileNames);
     350             : 
     351        1328 :   if (*OffsetPtr != EndPrologueOffset)
     352             :     return createError("parsing line table prologue at 0x%8.8" PRIx64
     353             :                        " should have ended at 0x%8.8" PRIx64
     354             :                        " but it ended at 0x%8.8" PRIx64,
     355          20 :                        PrologueOffset, EndPrologueOffset, (uint64_t)*OffsetPtr);
     356             :   return Error::success();
     357             : }
     358             : 
     359        2053 : DWARFDebugLine::Row::Row(bool DefaultIsStmt) { reset(DefaultIsStmt); }
     360             : 
     361        7559 : void DWARFDebugLine::Row::postAppend() {
     362        7559 :   BasicBlock = false;
     363        7559 :   PrologueEnd = false;
     364        7559 :   EpilogueBegin = false;
     365        7559 : }
     366             : 
     367        4614 : void DWARFDebugLine::Row::reset(bool DefaultIsStmt) {
     368        4614 :   Address = 0;
     369        4614 :   Line = 1;
     370        4614 :   Column = 0;
     371        4614 :   File = 1;
     372        4614 :   Isa = 0;
     373        4614 :   Discriminator = 0;
     374        4614 :   IsStmt = DefaultIsStmt;
     375        4614 :   BasicBlock = false;
     376        4614 :   EndSequence = false;
     377        4614 :   PrologueEnd = false;
     378        4614 :   EpilogueBegin = false;
     379        4614 : }
     380             : 
     381         132 : void DWARFDebugLine::Row::dumpTableHeader(raw_ostream &OS) {
     382         132 :   OS << "Address            Line   Column File   ISA Discriminator Flags\n"
     383         132 :      << "------------------ ------ ------ ------ --- ------------- "
     384             :         "-------------\n";
     385         132 : }
     386             : 
     387        1605 : void DWARFDebugLine::Row::dump(raw_ostream &OS) const {
     388        4815 :   OS << format("0x%16.16" PRIx64 " %6u %6u", Address, Line, Column)
     389        4815 :      << format(" %6u %3u %13u ", File, Isa, Discriminator)
     390        1605 :      << (IsStmt ? " is_stmt" : "") << (BasicBlock ? " basic_block" : "")
     391        1605 :      << (PrologueEnd ? " prologue_end" : "")
     392        1605 :      << (EpilogueBegin ? " epilogue_begin" : "")
     393        1605 :      << (EndSequence ? " end_sequence" : "") << '\n';
     394        1605 : }
     395             : 
     396        2747 : DWARFDebugLine::Sequence::Sequence() { reset(); }
     397             : 
     398        6576 : void DWARFDebugLine::Sequence::reset() {
     399        6576 :   LowPC = 0;
     400        6576 :   HighPC = 0;
     401        6576 :   FirstRowIndex = 0;
     402        6576 :   LastRowIndex = 0;
     403        6576 :   Empty = true;
     404        6576 : }
     405             : 
     406        2730 : DWARFDebugLine::LineTable::LineTable() { clear(); }
     407             : 
     408         148 : void DWARFDebugLine::LineTable::dump(raw_ostream &OS,
     409             :                                      DIDumpOptions DumpOptions) const {
     410         148 :   Prologue.dump(OS, DumpOptions);
     411             :   OS << '\n';
     412             : 
     413         148 :   if (!Rows.empty()) {
     414         130 :     Row::dumpTableHeader(OS);
     415         130 :     for (const Row &R : Rows) {
     416         791 :       R.dump(OS);
     417             :     }
     418             :   }
     419         148 : }
     420             : 
     421        2690 : void DWARFDebugLine::LineTable::clear() {
     422        2690 :   Prologue.clear();
     423             :   Rows.clear();
     424             :   Sequences.clear();
     425        2690 : }
     426             : 
     427        1293 : DWARFDebugLine::ParsingState::ParsingState(struct LineTable *LT)
     428        1293 :     : LineTable(LT) {
     429        1293 :   resetRowAndSequence();
     430        1293 : }
     431             : 
     432        2561 : void DWARFDebugLine::ParsingState::resetRowAndSequence() {
     433        2561 :   Row.reset(LineTable->Prologue.DefaultIsStmt);
     434        2561 :   Sequence.reset();
     435        2561 : }
     436             : 
     437        7559 : void DWARFDebugLine::ParsingState::appendRowToMatrix(uint32_t Offset) {
     438        7559 :   if (Sequence.Empty) {
     439             :     // Record the beginning of instruction sequence.
     440        1274 :     Sequence.Empty = false;
     441        1274 :     Sequence.LowPC = Row.Address;
     442        1274 :     Sequence.FirstRowIndex = RowNumber;
     443             :   }
     444        7559 :   ++RowNumber;
     445        7559 :   LineTable->appendRow(Row);
     446        7559 :   if (Row.EndSequence) {
     447             :     // Record the end of instruction sequence.
     448        1268 :     Sequence.HighPC = Row.Address;
     449        1268 :     Sequence.LastRowIndex = RowNumber;
     450             :     if (Sequence.isValid())
     451        1234 :       LineTable->appendSequence(Sequence);
     452        1268 :     Sequence.reset();
     453             :   }
     454        7559 :   Row.postAppend();
     455        7559 : }
     456             : 
     457             : const DWARFDebugLine::LineTable *
     458        3487 : DWARFDebugLine::getLineTable(uint32_t Offset) const {
     459             :   LineTableConstIter Pos = LineTableMap.find(Offset);
     460        3487 :   if (Pos != LineTableMap.end())
     461        2692 :     return &Pos->second;
     462             :   return nullptr;
     463             : }
     464             : 
     465         833 : Expected<const DWARFDebugLine::LineTable *> DWARFDebugLine::getOrParseLineTable(
     466             :     DWARFDataExtractor &DebugLineData, uint32_t Offset, const DWARFContext &Ctx,
     467             :     const DWARFUnit *U, std::function<void(StringRef)> WarnCallback) {
     468        1666 :   if (!DebugLineData.isValidOffset(Offset))
     469           8 :     return createError("offset 0x%8.8" PRIx32
     470             :                        " is not a valid debug line section offset",
     471             :                        Offset);
     472             : 
     473             :   std::pair<LineTableIter, bool> Pos =
     474        1658 :       LineTableMap.insert(LineTableMapTy::value_type(Offset, LineTable()));
     475         829 :   LineTable *LT = &Pos.first->second;
     476         829 :   if (Pos.second) {
     477        2457 :     if (Error Err = LT->parse(DebugLineData, &Offset, Ctx, U, WarnCallback))
     478             :       return std::move(Err);
     479             :     return LT;
     480             :   }
     481             :   return LT;
     482             : }
     483             : 
     484        1325 : Error DWARFDebugLine::LineTable::parse(
     485             :     DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr,
     486             :     const DWARFContext &Ctx, const DWARFUnit *U,
     487             :     std::function<void(StringRef)> WarnCallback, raw_ostream *OS) {
     488        1325 :   const uint32_t DebugLineOffset = *OffsetPtr;
     489             : 
     490        1325 :   clear();
     491             : 
     492        1325 :   Error PrologueErr = Prologue.parse(DebugLineData, OffsetPtr, Ctx, U);
     493             : 
     494        1325 :   if (OS) {
     495             :     // The presence of OS signals verbose dumping.
     496         185 :     DIDumpOptions DumpOptions;
     497         185 :     DumpOptions.Verbose = true;
     498         185 :     Prologue.dump(*OS, DumpOptions);
     499             :   }
     500             : 
     501        1325 :   if (PrologueErr)
     502             :     return PrologueErr;
     503             : 
     504             :   const uint32_t EndOffset =
     505        2586 :       DebugLineOffset + Prologue.TotalLength + Prologue.sizeofTotalLength();
     506             : 
     507             :   // See if we should tell the data extractor the address size.
     508        1293 :   if (DebugLineData.getAddressSize() == 0)
     509          46 :     DebugLineData.setAddressSize(Prologue.getAddressSize());
     510             :   else
     511             :     assert(Prologue.getAddressSize() == 0 ||
     512             :            Prologue.getAddressSize() == DebugLineData.getAddressSize());
     513             : 
     514        1293 :   ParsingState State(this);
     515             : 
     516       19058 :   while (*OffsetPtr < EndOffset) {
     517       17773 :     if (OS)
     518        1898 :       *OS << format("0x%08.08" PRIx32 ": ", *OffsetPtr);
     519             : 
     520       17773 :     uint8_t Opcode = DebugLineData.getU8(OffsetPtr);
     521             : 
     522       17773 :     if (OS)
     523        1898 :       *OS << format("%02.02" PRIx8 " ", Opcode);
     524             : 
     525       17773 :     if (Opcode == 0) {
     526             :       // Extended Opcodes always start with a zero opcode followed by
     527             :       // a uleb128 length so you can skip ones you don't know about
     528        2921 :       uint64_t Len = DebugLineData.getULEB128(OffsetPtr);
     529        2921 :       uint32_t ExtOffset = *OffsetPtr;
     530             : 
     531             :       // Tolerate zero-length; assume length is correct and soldier on.
     532        2923 :       if (Len == 0) {
     533           2 :         if (OS)
     534           2 :           *OS << "Badly formed extended line op (length 0)\n";
     535           2 :         continue;
     536             :       }
     537             : 
     538        2919 :       uint8_t SubOpcode = DebugLineData.getU8(OffsetPtr);
     539        2919 :       if (OS)
     540         238 :         *OS << LNExtendedString(SubOpcode);
     541        2919 :       switch (SubOpcode) {
     542        1268 :       case DW_LNE_end_sequence:
     543             :         // Set the end_sequence register of the state machine to true and
     544             :         // append a row to the matrix using the current values of the
     545             :         // state-machine registers. Then reset the registers to the initial
     546             :         // values specified above. Every statement program sequence must end
     547             :         // with a DW_LNE_end_sequence instruction which creates a row whose
     548             :         // address is that of the byte after the last target machine instruction
     549             :         // of the sequence.
     550        1268 :         State.Row.EndSequence = true;
     551        1268 :         State.appendRowToMatrix(*OffsetPtr);
     552        1268 :         if (OS) {
     553         118 :           *OS << "\n";
     554         118 :           OS->indent(12);
     555         118 :           State.Row.dump(*OS);
     556             :         }
     557        1268 :         State.resetRowAndSequence();
     558        1268 :         break;
     559             : 
     560        1261 :       case DW_LNE_set_address:
     561             :         // Takes a single relocatable address as an operand. The size of the
     562             :         // operand is the size appropriate to hold an address on the target
     563             :         // machine. Set the address register to the value given by the
     564             :         // relocatable address. All of the other statement program opcodes
     565             :         // that affect the address register add a delta to it. This instruction
     566             :         // stores a relocatable value into it instead.
     567             :         //
     568             :         // Make sure the extractor knows the address size.  If not, infer it
     569             :         // from the size of the operand.
     570        1261 :         if (DebugLineData.getAddressSize() == 0)
     571          19 :           DebugLineData.setAddressSize(Len - 1);
     572        1242 :         else if (DebugLineData.getAddressSize() != Len - 1) {
     573             :           return createError("mismatching address size at offset 0x%8.8" PRIx32
     574             :                              " expected 0x%2.2" PRIx8 " found 0x%2.2" PRIx64,
     575           4 :                              ExtOffset, DebugLineData.getAddressSize(),
     576           6 :                              Len - 1);
     577             :         }
     578        1259 :         State.Row.Address = DebugLineData.getRelocatedAddress(OffsetPtr);
     579        1259 :         if (OS)
     580         118 :           *OS << format(" (0x%16.16" PRIx64 ")", State.Row.Address);
     581             :         break;
     582             : 
     583             :       case DW_LNE_define_file:
     584             :         // Takes 4 arguments. The first is a null terminated string containing
     585             :         // a source file name. The second is an unsigned LEB128 number
     586             :         // representing the directory index of the directory in which the file
     587             :         // was found. The third is an unsigned LEB128 number representing the
     588             :         // time of last modification of the file. The fourth is an unsigned
     589             :         // LEB128 number representing the length in bytes of the file. The time
     590             :         // and length fields may contain LEB128(0) if the information is not
     591             :         // available.
     592             :         //
     593             :         // The directory index represents an entry in the include_directories
     594             :         // section of the statement program prologue. The index is LEB128(0)
     595             :         // if the file was found in the current directory of the compilation,
     596             :         // LEB128(1) if it was found in the first directory in the
     597             :         // include_directories section, and so on. The directory index is
     598             :         // ignored for file names that represent full path names.
     599             :         //
     600             :         // The files are numbered, starting at 1, in the order in which they
     601             :         // appear; the names in the prologue come before names defined by
     602             :         // the DW_LNE_define_file instruction. These numbers are used in the
     603             :         // the file register of the state machine.
     604             :         {
     605             :           FileNameEntry FileEntry;
     606           0 :           const char *Name = DebugLineData.getCStr(OffsetPtr);
     607             :           FileEntry.Name.setForm(dwarf::DW_FORM_string);
     608             :           FileEntry.Name.setPValue(Name);
     609           0 :           FileEntry.DirIdx = DebugLineData.getULEB128(OffsetPtr);
     610           0 :           FileEntry.ModTime = DebugLineData.getULEB128(OffsetPtr);
     611           0 :           FileEntry.Length = DebugLineData.getULEB128(OffsetPtr);
     612           0 :           Prologue.FileNames.push_back(FileEntry);
     613           0 :           if (OS)
     614           0 :             *OS << " (" << Name << ", dir=" << FileEntry.DirIdx << ", mod_time="
     615           0 :                 << format("(0x%16.16" PRIx64 ")", FileEntry.ModTime)
     616           0 :                 << ", length=" << FileEntry.Length << ")";
     617             :         }
     618           0 :         break;
     619             : 
     620         388 :       case DW_LNE_set_discriminator:
     621         388 :         State.Row.Discriminator = DebugLineData.getULEB128(OffsetPtr);
     622         388 :         if (OS)
     623           0 :           *OS << " (" << State.Row.Discriminator << ")";
     624             :         break;
     625             : 
     626           2 :       default:
     627           2 :         if (OS)
     628           4 :           *OS << format("Unrecognized extended op 0x%02.02" PRIx8, SubOpcode)
     629           4 :               << format(" length %" PRIx64, Len);
     630             :         // Len doesn't include the zero opcode byte or the length itself, but
     631             :         // it does include the sub_opcode, so we have to adjust for that.
     632           2 :         (*OffsetPtr) += Len - 1;
     633           2 :         break;
     634             :       }
     635             :       // Make sure the stated and parsed lengths are the same.
     636             :       // Otherwise we have an unparseable line-number program.
     637        2917 :       if (*OffsetPtr - ExtOffset != Len)
     638             :         return createError("unexpected line op length at offset 0x%8.8" PRIx32
     639             :                            " expected 0x%2.2" PRIx64 " found 0x%2.2" PRIx32,
     640           6 :                            ExtOffset, Len, *OffsetPtr - ExtOffset);
     641       14852 :     } else if (Opcode < Prologue.OpcodeBase) {
     642        9464 :       if (OS)
     643        1038 :         *OS << LNStandardString(Opcode);
     644        9464 :       switch (Opcode) {
     645             :       // Standard Opcodes
     646         903 :       case DW_LNS_copy:
     647             :         // Takes no arguments. Append a row to the matrix using the
     648             :         // current values of the state-machine registers. Then set
     649             :         // the basic_block register to false.
     650         903 :         State.appendRowToMatrix(*OffsetPtr);
     651         903 :         if (OS) {
     652          73 :           *OS << "\n";
     653          73 :           OS->indent(12);
     654          73 :           State.Row.dump(*OS);
     655          73 :           *OS << "\n";
     656             :         }
     657             :         break;
     658             : 
     659        1615 :       case DW_LNS_advance_pc:
     660             :         // Takes a single unsigned LEB128 operand, multiplies it by the
     661             :         // min_inst_length field of the prologue, and adds the
     662             :         // result to the address register of the state machine.
     663             :         {
     664             :           uint64_t AddrOffset =
     665        1615 :               DebugLineData.getULEB128(OffsetPtr) * Prologue.MinInstLength;
     666        1615 :           State.Row.Address += AddrOffset;
     667        1615 :           if (OS)
     668         151 :             *OS << " (" << AddrOffset << ")";
     669             :         }
     670             :         break;
     671             : 
     672        1013 :       case DW_LNS_advance_line:
     673             :         // Takes a single signed LEB128 operand and adds that value to
     674             :         // the line register of the state machine.
     675        1013 :         State.Row.Line += DebugLineData.getSLEB128(OffsetPtr);
     676        1013 :         if (OS)
     677         194 :           *OS << " (" << State.Row.Line << ")";
     678             :         break;
     679             : 
     680         141 :       case DW_LNS_set_file:
     681             :         // Takes a single unsigned LEB128 operand and stores it in the file
     682             :         // register of the state machine.
     683         141 :         State.Row.File = DebugLineData.getULEB128(OffsetPtr);
     684         141 :         if (OS)
     685          24 :           *OS << " (" << State.Row.File << ")";
     686             :         break;
     687             : 
     688        2292 :       case DW_LNS_set_column:
     689             :         // Takes a single unsigned LEB128 operand and stores it in the
     690             :         // column register of the state machine.
     691        2292 :         State.Row.Column = DebugLineData.getULEB128(OffsetPtr);
     692        2292 :         if (OS)
     693         568 :           *OS << " (" << State.Row.Column << ")";
     694             :         break;
     695             : 
     696        1025 :       case DW_LNS_negate_stmt:
     697             :         // Takes no arguments. Set the is_stmt register of the state
     698             :         // machine to the logical negation of its current value.
     699        1025 :         State.Row.IsStmt = !State.Row.IsStmt;
     700        1025 :         break;
     701             : 
     702           0 :       case DW_LNS_set_basic_block:
     703             :         // Takes no arguments. Set the basic_block register of the
     704             :         // state machine to true
     705           0 :         State.Row.BasicBlock = true;
     706           0 :         break;
     707             : 
     708         848 :       case DW_LNS_const_add_pc:
     709             :         // Takes no arguments. Add to the address register of the state
     710             :         // machine the address increment value corresponding to special
     711             :         // opcode 255. The motivation for DW_LNS_const_add_pc is this:
     712             :         // when the statement program needs to advance the address by a
     713             :         // small amount, it can use a single special opcode, which occupies
     714             :         // a single byte. When it needs to advance the address by up to
     715             :         // twice the range of the last special opcode, it can use
     716             :         // DW_LNS_const_add_pc followed by a special opcode, for a total
     717             :         // of two bytes. Only if it needs to advance the address by more
     718             :         // than twice that range will it need to use both DW_LNS_advance_pc
     719             :         // and a special opcode, requiring three or more bytes.
     720             :         {
     721         848 :           uint8_t AdjustOpcode = 255 - Prologue.OpcodeBase;
     722             :           uint64_t AddrOffset =
     723         848 :               (AdjustOpcode / Prologue.LineRange) * Prologue.MinInstLength;
     724         848 :           State.Row.Address += AddrOffset;
     725         848 :           if (OS)
     726             :             *OS
     727         105 :                 << format(" (0x%16.16" PRIx64 ")", AddrOffset);
     728             :         }
     729             :         break;
     730             : 
     731           0 :       case DW_LNS_fixed_advance_pc:
     732             :         // Takes a single uhalf operand. Add to the address register of
     733             :         // the state machine the value of the (unencoded) operand. This
     734             :         // is the only extended opcode that takes an argument that is not
     735             :         // a variable length number. The motivation for DW_LNS_fixed_advance_pc
     736             :         // is this: existing assemblers cannot emit DW_LNS_advance_pc or
     737             :         // special opcodes because they cannot encode LEB128 numbers or
     738             :         // judge when the computation of a special opcode overflows and
     739             :         // requires the use of DW_LNS_advance_pc. Such assemblers, however,
     740             :         // can use DW_LNS_fixed_advance_pc instead, sacrificing compression.
     741             :         {
     742           0 :           uint16_t PCOffset = DebugLineData.getU16(OffsetPtr);
     743           0 :           State.Row.Address += PCOffset;
     744           0 :           if (OS)
     745             :             *OS
     746           0 :                 << format(" (0x%16.16" PRIx64 ")", PCOffset);
     747             :         }
     748             :         break;
     749             : 
     750        1627 :       case DW_LNS_set_prologue_end:
     751             :         // Takes no arguments. Set the prologue_end register of the
     752             :         // state machine to true
     753        1627 :         State.Row.PrologueEnd = true;
     754        1627 :         break;
     755             : 
     756           0 :       case DW_LNS_set_epilogue_begin:
     757             :         // Takes no arguments. Set the basic_block register of the
     758             :         // state machine to true
     759           0 :         State.Row.EpilogueBegin = true;
     760           0 :         break;
     761             : 
     762           0 :       case DW_LNS_set_isa:
     763             :         // Takes a single unsigned LEB128 operand and stores it in the
     764             :         // column register of the state machine.
     765           0 :         State.Row.Isa = DebugLineData.getULEB128(OffsetPtr);
     766           0 :         if (OS)
     767           0 :           *OS << " (" << State.Row.Isa << ")";
     768             :         break;
     769             : 
     770           0 :       default:
     771             :         // Handle any unknown standard opcodes here. We know the lengths
     772             :         // of such opcodes because they are specified in the prologue
     773             :         // as a multiple of LEB128 operands for each opcode.
     774             :         {
     775             :           assert(Opcode - 1U < Prologue.StandardOpcodeLengths.size());
     776           0 :           uint8_t OpcodeLength = Prologue.StandardOpcodeLengths[Opcode - 1];
     777           0 :           for (uint8_t I = 0; I < OpcodeLength; ++I) {
     778           0 :             uint64_t Value = DebugLineData.getULEB128(OffsetPtr);
     779           0 :             if (OS)
     780           0 :               *OS << format("Skipping ULEB128 value: 0x%16.16" PRIx64 ")\n",
     781             :                             Value);
     782           0 :           }
     783             :         }
     784             :         break;
     785             :       }
     786             :     } else {
     787             :       // Special Opcodes
     788             : 
     789             :       // A special opcode value is chosen based on the amount that needs
     790             :       // to be added to the line and address registers. The maximum line
     791             :       // increment for a special opcode is the value of the line_base
     792             :       // field in the header, plus the value of the line_range field,
     793             :       // minus 1 (line base + line range - 1). If the desired line
     794             :       // increment is greater than the maximum line increment, a standard
     795             :       // opcode must be used instead of a special opcode. The "address
     796             :       // advance" is calculated by dividing the desired address increment
     797             :       // by the minimum_instruction_length field from the header. The
     798             :       // special opcode is then calculated using the following formula:
     799             :       //
     800             :       //  opcode = (desired line increment - line_base) +
     801             :       //           (line_range * address advance) + opcode_base
     802             :       //
     803             :       // If the resulting opcode is greater than 255, a standard opcode
     804             :       // must be used instead.
     805             :       //
     806             :       // To decode a special opcode, subtract the opcode_base from the
     807             :       // opcode itself to give the adjusted opcode. The amount to
     808             :       // increment the address register is the result of the adjusted
     809             :       // opcode divided by the line_range multiplied by the
     810             :       // minimum_instruction_length field from the header. That is:
     811             :       //
     812             :       //  address increment = (adjusted opcode / line_range) *
     813             :       //                      minimum_instruction_length
     814             :       //
     815             :       // The amount to increment the line register is the line_base plus
     816             :       // the result of the adjusted opcode modulo the line_range. That is:
     817             :       //
     818             :       // line increment = line_base + (adjusted opcode % line_range)
     819             : 
     820        5388 :       uint8_t AdjustOpcode = Opcode - Prologue.OpcodeBase;
     821        5388 :       uint64_t AddrOffset =
     822        5388 :           (AdjustOpcode / Prologue.LineRange) * Prologue.MinInstLength;
     823        5388 :       int32_t LineOffset =
     824        5388 :           Prologue.LineBase + (AdjustOpcode % Prologue.LineRange);
     825        5388 :       State.Row.Line += LineOffset;
     826        5388 :       State.Row.Address += AddrOffset;
     827             : 
     828        5388 :       if (OS) {
     829         620 :         *OS << "address += " << ((uint32_t)AdjustOpcode)
     830        1240 :             << ",  line += " << LineOffset << "\n";
     831         620 :         OS->indent(12);
     832         620 :         State.Row.dump(*OS);
     833             :       }
     834             : 
     835        5388 :       State.appendRowToMatrix(*OffsetPtr);
     836             :       // Reset discriminator to 0.
     837        5388 :       State.Row.Discriminator = 0;
     838             :     }
     839       17763 :     if(OS)
     840        1893 :       *OS << "\n";
     841             :   }
     842             : 
     843        1285 :   if (!State.Sequence.Empty)
     844             :     WarnCallback("last sequence in debug line table is not terminated!");
     845             : 
     846             :   // Sort all sequences so that address lookup will work faster.
     847        1285 :   if (!Sequences.empty()) {
     848             :     llvm::sort(Sequences.begin(), Sequences.end(), Sequence::orderByLowPC);
     849             :     // Note: actually, instruction address ranges of sequences should not
     850             :     // overlap (in shared objects and executables). If they do, the address
     851             :     // lookup would still work, though, but result would be ambiguous.
     852             :     // We don't report warning in this case. For example,
     853             :     // sometimes .so compiled from multiple object files contains a few
     854             :     // rudimentary sequences for address ranges [0x0, 0xsomething).
     855             :   }
     856             : 
     857             :   return Error::success();
     858             : }
     859             : 
     860             : uint32_t
     861         762 : DWARFDebugLine::LineTable::findRowInSeq(const DWARFDebugLine::Sequence &Seq,
     862             :                                         uint64_t Address) const {
     863         762 :   if (!Seq.containsPC(Address))
     864           2 :     return UnknownRowIndex;
     865             :   // Search for instruction address in the rows describing the sequence.
     866             :   // Rows are stored in a vector, so we may use arithmetical operations with
     867             :   // iterators.
     868         760 :   DWARFDebugLine::Row Row;
     869         760 :   Row.Address = Address;
     870         760 :   RowIter FirstRow = Rows.begin() + Seq.FirstRowIndex;
     871         760 :   RowIter LastRow = Rows.begin() + Seq.LastRowIndex;
     872             :   LineTable::RowIter RowPos = std::lower_bound(
     873             :       FirstRow, LastRow, Row, DWARFDebugLine::Row::orderByAddress);
     874         760 :   if (RowPos == LastRow) {
     875           0 :     return Seq.LastRowIndex - 1;
     876             :   }
     877         760 :   uint32_t Index = Seq.FirstRowIndex + (RowPos - FirstRow);
     878         760 :   if (RowPos->Address > Address) {
     879         557 :     if (RowPos == FirstRow)
     880           0 :       return UnknownRowIndex;
     881             :     else
     882         557 :       Index--;
     883             :   }
     884             :   return Index;
     885             : }
     886             : 
     887         726 : uint32_t DWARFDebugLine::LineTable::lookupAddress(uint64_t Address) const {
     888         726 :   if (Sequences.empty())
     889          12 :     return UnknownRowIndex;
     890             :   // First, find an instruction sequence containing the given address.
     891         714 :   DWARFDebugLine::Sequence Sequence;
     892         714 :   Sequence.LowPC = Address;
     893         714 :   SequenceIter FirstSeq = Sequences.begin();
     894         714 :   SequenceIter LastSeq = Sequences.end();
     895             :   SequenceIter SeqPos = std::lower_bound(
     896             :       FirstSeq, LastSeq, Sequence, DWARFDebugLine::Sequence::orderByLowPC);
     897         714 :   DWARFDebugLine::Sequence FoundSeq;
     898         714 :   if (SeqPos == LastSeq) {
     899         651 :     FoundSeq = Sequences.back();
     900          63 :   } else if (SeqPos->LowPC == Address) {
     901          44 :     FoundSeq = *SeqPos;
     902             :   } else {
     903          19 :     if (SeqPos == FirstSeq)
     904           4 :       return UnknownRowIndex;
     905          15 :     FoundSeq = *(SeqPos - 1);
     906             :   }
     907         710 :   return findRowInSeq(FoundSeq, Address);
     908             : }
     909             : 
     910          26 : bool DWARFDebugLine::LineTable::lookupAddressRange(
     911             :     uint64_t Address, uint64_t Size, std::vector<uint32_t> &Result) const {
     912          26 :   if (Sequences.empty())
     913             :     return false;
     914          26 :   uint64_t EndAddr = Address + Size;
     915             :   // First, find an instruction sequence containing the given address.
     916          26 :   DWARFDebugLine::Sequence Sequence;
     917          26 :   Sequence.LowPC = Address;
     918          26 :   SequenceIter FirstSeq = Sequences.begin();
     919          26 :   SequenceIter LastSeq = Sequences.end();
     920             :   SequenceIter SeqPos = std::lower_bound(
     921             :       FirstSeq, LastSeq, Sequence, DWARFDebugLine::Sequence::orderByLowPC);
     922          26 :   if (SeqPos == LastSeq || SeqPos->LowPC != Address) {
     923          14 :     if (SeqPos == FirstSeq)
     924             :       return false;
     925             :     SeqPos--;
     926             :   }
     927          26 :   if (!SeqPos->containsPC(Address))
     928             :     return false;
     929             : 
     930             :   SequenceIter StartPos = SeqPos;
     931             : 
     932             :   // Add the rows from the first sequence to the vector, starting with the
     933             :   // index we just calculated
     934             : 
     935          52 :   while (SeqPos != LastSeq && SeqPos->LowPC < EndAddr) {
     936             :     const DWARFDebugLine::Sequence &CurSeq = *SeqPos;
     937             :     // For the first sequence, we need to find which row in the sequence is the
     938             :     // first in our range.
     939          26 :     uint32_t FirstRowIndex = CurSeq.FirstRowIndex;
     940          26 :     if (SeqPos == StartPos)
     941          26 :       FirstRowIndex = findRowInSeq(CurSeq, Address);
     942             : 
     943             :     // Figure out the last row in the range.
     944          26 :     uint32_t LastRowIndex = findRowInSeq(CurSeq, EndAddr - 1);
     945          26 :     if (LastRowIndex == UnknownRowIndex)
     946           0 :       LastRowIndex = CurSeq.LastRowIndex - 1;
     947             : 
     948             :     assert(FirstRowIndex != UnknownRowIndex);
     949             :     assert(LastRowIndex != UnknownRowIndex);
     950             : 
     951         142 :     for (uint32_t I = FirstRowIndex; I <= LastRowIndex; ++I) {
     952         116 :       Result.push_back(I);
     953             :     }
     954             : 
     955             :     ++SeqPos;
     956             :   }
     957             : 
     958             :   return true;
     959             : }
     960             : 
     961        4340 : bool DWARFDebugLine::LineTable::hasFileAtIndex(uint64_t FileIndex) const {
     962        8680 :   return FileIndex != 0 && FileIndex <= Prologue.FileNames.size();
     963             : }
     964             : 
     965         708 : Optional<StringRef> DWARFDebugLine::LineTable::getSourceByIndex(uint64_t FileIndex,
     966             :                                                                 FileLineInfoKind Kind) const {
     967         708 :   if (Kind == FileLineInfoKind::None || !hasFileAtIndex(FileIndex))
     968             :     return None;
     969         708 :   const FileNameEntry &Entry = Prologue.FileNames[FileIndex - 1];
     970         708 :   if (Optional<const char *> source = Entry.Source.getAsCString())
     971          24 :     return StringRef(*source);
     972             :   return None;
     973             : }
     974             : 
     975        6517 : static bool isPathAbsoluteOnWindowsOrPosix(const Twine &Path) {
     976             :   // Debug info can contain paths from any OS, not necessarily
     977             :   // an OS we're currently running on. Moreover different compilation units can
     978             :   // be compiled on different operating systems and linked together later.
     979       12821 :   return sys::path::is_absolute(Path, sys::path::Style::posix) ||
     980       12821 :          sys::path::is_absolute(Path, sys::path::Style::windows);
     981             : }
     982             : 
     983        3535 : bool DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex,
     984             :                                                    const char *CompDir,
     985             :                                                    FileLineInfoKind Kind,
     986             :                                                    std::string &Result) const {
     987        3535 :   if (Kind == FileLineInfoKind::None || !hasFileAtIndex(FileIndex))
     988             :     return false;
     989        3535 :   const FileNameEntry &Entry = Prologue.FileNames[FileIndex - 1];
     990        7070 :   StringRef FileName = Entry.Name.getAsCString().getValue();
     991        6951 :   if (Kind != FileLineInfoKind::AbsoluteFilePath ||
     992        6951 :       isPathAbsoluteOnWindowsOrPosix(FileName)) {
     993         238 :     Result = FileName;
     994         119 :     return true;
     995             :   }
     996             : 
     997             :   SmallString<16> FilePath;
     998        3416 :   uint64_t IncludeDirIndex = Entry.DirIdx;
     999        3416 :   StringRef IncludeDir;
    1000             :   // Be defensive about the contents of Entry.
    1001        3836 :   if (IncludeDirIndex > 0 &&
    1002         420 :       IncludeDirIndex <= Prologue.IncludeDirectories.size())
    1003        1257 :     IncludeDir = Prologue.IncludeDirectories[IncludeDirIndex - 1]
    1004         838 :                      .getAsCString()
    1005             :                      .getValue();
    1006             : 
    1007             :   // We may still need to append compilation directory of compile unit.
    1008             :   // We know that FileName is not absolute, the only way to have an
    1009             :   // absolute path at this point would be if IncludeDir is absolute.
    1010        6517 :   if (CompDir && Kind == FileLineInfoKind::AbsoluteFilePath &&
    1011        3636 :       !isPathAbsoluteOnWindowsOrPosix(IncludeDir))
    1012        2881 :     sys::path::append(FilePath, CompDir);
    1013             : 
    1014             :   // sys::path::append skips empty strings.
    1015        3416 :   sys::path::append(FilePath, IncludeDir, FileName);
    1016        6832 :   Result = FilePath.str();
    1017             :   return true;
    1018             : }
    1019             : 
    1020         726 : bool DWARFDebugLine::LineTable::getFileLineInfoForAddress(
    1021             :     uint64_t Address, const char *CompDir, FileLineInfoKind Kind,
    1022             :     DILineInfo &Result) const {
    1023             :   // Get the index of row we're looking for in the line table.
    1024         726 :   uint32_t RowIndex = lookupAddress(Address);
    1025         726 :   if (RowIndex == -1U)
    1026             :     return false;
    1027             :   // Take file number and line/column from the row.
    1028         708 :   const auto &Row = Rows[RowIndex];
    1029         708 :   if (!getFileNameByIndex(Row.File, CompDir, Kind, Result.FileName))
    1030             :     return false;
    1031         708 :   Result.Line = Row.Line;
    1032         708 :   Result.Column = Row.Column;
    1033         708 :   Result.Discriminator = Row.Discriminator;
    1034        1416 :   Result.Source = getSourceByIndex(Row.File, Kind);
    1035         708 :   return true;
    1036             : }
    1037             : 
    1038             : // We want to supply the Unit associated with a .debug_line[.dwo] table when
    1039             : // we dump it, if possible, but still dump the table even if there isn't a Unit.
    1040             : // Therefore, collect up handles on all the Units that point into the
    1041             : // line-table section.
    1042             : static DWARFDebugLine::SectionParser::LineToUnitMap
    1043         237 : buildLineToUnitMap(DWARFDebugLine::SectionParser::cu_range CUs,
    1044             :                    DWARFDebugLine::SectionParser::tu_range TUSections) {
    1045             :   DWARFDebugLine::SectionParser::LineToUnitMap LineToUnit;
    1046         533 :   for (const auto &CU : CUs)
    1047         592 :     if (auto CUDIE = CU->getUnitDIE())
    1048         590 :       if (auto StmtOffset = toSectionOffset(CUDIE.find(DW_AT_stmt_list)))
    1049         544 :         LineToUnit.insert(std::make_pair(*StmtOffset, &*CU));
    1050         272 :   for (const auto &TUS : TUSections)
    1051         127 :     for (const auto &TU : TUS)
    1052          92 :       if (auto TUDIE = TU->getUnitDIE())
    1053          92 :         if (auto StmtOffset = toSectionOffset(TUDIE.find(DW_AT_stmt_list)))
    1054          86 :           LineToUnit.insert(std::make_pair(*StmtOffset, &*TU));
    1055         237 :   return LineToUnit;
    1056             : }
    1057             : 
    1058         237 : DWARFDebugLine::SectionParser::SectionParser(DWARFDataExtractor &Data,
    1059             :                                              const DWARFContext &C,
    1060         237 :                                              cu_range CUs, tu_range TUs)
    1061         237 :     : DebugLineData(Data), Context(C) {
    1062         474 :   LineToUnit = buildLineToUnitMap(CUs, TUs);
    1063         474 :   if (!DebugLineData.isValidOffset(Offset))
    1064           3 :     Done = true;
    1065         237 : }
    1066             : 
    1067         370 : bool DWARFDebugLine::Prologue::totalLengthIsValid() const {
    1068         370 :   return TotalLength == 0xffffffff || TotalLength < 0xffffff00;
    1069             : }
    1070             : 
    1071         340 : DWARFDebugLine::LineTable DWARFDebugLine::SectionParser::parseNext(
    1072             :     function_ref<void(StringRef)> StringCallback,
    1073             :     function_ref<void(Error)> ErrorCallback, raw_ostream *OS) {
    1074             :   assert(DebugLineData.isValidOffset(Offset) &&
    1075             :          "parsing should have terminated");
    1076         340 :   DWARFUnit *U = prepareToParse(Offset);
    1077         340 :   uint32_t OldOffset = Offset;
    1078         340 :   LineTable LT;
    1079         680 :   Error Err = LT.parse(DebugLineData, &Offset, Context, U, StringCallback, OS);
    1080         680 :   ErrorCallback(std::move(Err));
    1081         340 :   moveToNextTable(OldOffset, LT.Prologue);
    1082         340 :   return LT;
    1083             : }
    1084             : 
    1085          30 : void DWARFDebugLine::SectionParser::skip(
    1086             :     function_ref<void(Error)> ErrorCallback) {
    1087             :   assert(DebugLineData.isValidOffset(Offset) &&
    1088             :          "parsing should have terminated");
    1089          30 :   DWARFUnit *U = prepareToParse(Offset);
    1090          30 :   uint32_t OldOffset = Offset;
    1091          60 :   LineTable LT;
    1092          30 :   Error Err = LT.Prologue.parse(DebugLineData, &Offset, Context, U);
    1093          60 :   ErrorCallback(std::move(Err));
    1094          30 :   moveToNextTable(OldOffset, LT.Prologue);
    1095          30 : }
    1096             : 
    1097         370 : DWARFUnit *DWARFDebugLine::SectionParser::prepareToParse(uint32_t Offset) {
    1098             :   DWARFUnit *U = nullptr;
    1099         370 :   auto It = LineToUnit.find(Offset);
    1100         370 :   if (It != LineToUnit.end())
    1101         281 :     U = It->second;
    1102         651 :   DebugLineData.setAddressSize(U ? U->getAddressByteSize() : 0);
    1103         370 :   return U;
    1104             : }
    1105             : 
    1106         370 : void DWARFDebugLine::SectionParser::moveToNextTable(uint32_t OldOffset,
    1107             :                                                     const Prologue &P) {
    1108             :   // If the length field is not valid, we don't know where the next table is, so
    1109             :   // cannot continue to parse. Mark the parser as done, and leave the Offset
    1110             :   // value as it currently is. This will be the end of the bad length field.
    1111         370 :   if (!P.totalLengthIsValid()) {
    1112           6 :     Done = true;
    1113           6 :     return;
    1114             :   }
    1115             : 
    1116         728 :   Offset = OldOffset + P.TotalLength + P.sizeofTotalLength();
    1117         728 :   if (!DebugLineData.isValidOffset(Offset)) {
    1118         228 :     Done = true;
    1119             :   }
    1120             : }
    1121             : 
    1122          33 : void DWARFDebugLine::warn(StringRef Message) {
    1123          33 :   WithColor::warning() << Message << '\n';
    1124          33 : }
    1125             : 
    1126         523 : void DWARFDebugLine::warnForError(Error Err) {
    1127        1046 :   handleAllErrors(std::move(Err),
    1128          93 :                   [](ErrorInfoBase &Info) { warn(Info.message()); });
    1129         523 : }

Generated by: LCOV version 1.13