LCOV - code coverage report
Current view: top level - lib/DebugInfo - DWARFDebugLine.cpp (source / functions) Hit Total Coverage
Test: llvm-toolchain.info Lines: 307 329 93.3 %
Date: 2015-01-30 11:55:44 Functions: 23 23 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/DWARFDebugLine.h"
      11             : #include "llvm/Support/Dwarf.h"
      12             : #include "llvm/Support/Format.h"
      13             : #include "llvm/Support/Path.h"
      14             : #include "llvm/Support/raw_ostream.h"
      15             : #include <algorithm>
      16             : using namespace llvm;
      17             : using namespace dwarf;
      18             : typedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind;
      19             : 
      20        1539 : DWARFDebugLine::Prologue::Prologue() {
      21         513 :   clear();
      22         513 : }
      23             : 
      24        1976 : void DWARFDebugLine::Prologue::clear() {
      25        1976 :   TotalLength = Version = PrologueLength = 0;
      26        1976 :   MinInstLength = MaxOpsPerInst = DefaultIsStmt = LineBase = LineRange = 0;
      27        1976 :   OpcodeBase = 0;
      28        1976 :   StandardOpcodeLengths.clear();
      29        1976 :   IncludeDirectories.clear();
      30        1976 :   FileNames.clear();
      31        1976 : }
      32             : 
      33         105 : void DWARFDebugLine::Prologue::dump(raw_ostream &OS) const {
      34         105 :   OS << "Line table prologue:\n"
      35         315 :      << format("    total_length: 0x%8.8x\n", TotalLength)
      36         315 :      << format("         version: %u\n", Version)
      37         315 :      << format(" prologue_length: 0x%8.8x\n", PrologueLength)
      38         315 :      << format(" min_inst_length: %u\n", MinInstLength)
      39         315 :      << format(Version >= 4 ? "max_ops_per_inst: %u\n" : "", MaxOpsPerInst)
      40         315 :      << format(" default_is_stmt: %u\n", DefaultIsStmt)
      41         315 :      << format("       line_base: %i\n", LineBase)
      42         315 :      << format("      line_range: %u\n", LineRange)
      43         315 :      << format("     opcode_base: %u\n", OpcodeBase);
      44             : 
      45        2538 :   for (uint32_t i = 0; i < StandardOpcodeLengths.size(); ++i)
      46        1164 :     OS << format("standard_opcode_lengths[%s] = %u\n", LNStandardString(i+1),
      47        4656 :                  StandardOpcodeLengths[i]);
      48             : 
      49         210 :   if (!IncludeDirectories.empty())
      50          26 :     for (uint32_t i = 0; i < IncludeDirectories.size(); ++i)
      51          27 :       OS << format("include_directories[%3u] = '", i+1)
      52          27 :          << IncludeDirectories[i] << "'\n";
      53             : 
      54         210 :   if (!FileNames.empty()) {
      55          91 :     OS << "                Dir  Mod Time   File Len   File Name\n"
      56             :        << "                ---- ---------- ---------- -----------"
      57          91 :           "----------------\n";
      58         398 :     for (uint32_t i = 0; i < FileNames.size(); ++i) {
      59         216 :       const FileNameEntry& fileEntry = FileNames[i];
      60         324 :       OS << format("file_names[%3u] %4" PRIu64 " ", i+1, fileEntry.DirIdx)
      61             :          << format("0x%8.8" PRIx64 " 0x%8.8" PRIx64 " ",
      62         324 :                    fileEntry.ModTime, fileEntry.Length)
      63         216 :          << fileEntry.Name << '\n';
      64             :     }
      65             :   }
      66         105 : }
      67             : 
      68         522 : bool DWARFDebugLine::Prologue::parse(DataExtractor debug_line_data,
      69             :                                      uint32_t *offset_ptr) {
      70         522 :   const uint32_t prologue_offset = *offset_ptr;
      71             : 
      72         522 :   clear();
      73         522 :   TotalLength = debug_line_data.getU32(offset_ptr);
      74         522 :   Version = debug_line_data.getU16(offset_ptr);
      75         522 :   if (Version < 2)
      76             :     return false;
      77             : 
      78         427 :   PrologueLength = debug_line_data.getU32(offset_ptr);
      79         427 :   const uint32_t end_prologue_offset = PrologueLength + *offset_ptr;
      80         427 :   MinInstLength = debug_line_data.getU8(offset_ptr);
      81         427 :   if (Version >= 4)
      82           1 :     MaxOpsPerInst = debug_line_data.getU8(offset_ptr);
      83         427 :   DefaultIsStmt = debug_line_data.getU8(offset_ptr);
      84         427 :   LineBase = debug_line_data.getU8(offset_ptr);
      85         427 :   LineRange = debug_line_data.getU8(offset_ptr);
      86         427 :   OpcodeBase = debug_line_data.getU8(offset_ptr);
      87             : 
      88         427 :   StandardOpcodeLengths.reserve(OpcodeBase - 1);
      89        5455 :   for (uint32_t i = 1; i < OpcodeBase; ++i) {
      90        5028 :     uint8_t op_len = debug_line_data.getU8(offset_ptr);
      91        5028 :     StandardOpcodeLengths.push_back(op_len);
      92             :   }
      93             : 
      94        2718 :   while (*offset_ptr < end_prologue_offset) {
      95        2718 :     const char *s = debug_line_data.getCStr(offset_ptr);
      96        2718 :     if (s && s[0])
      97        2291 :       IncludeDirectories.push_back(s);
      98             :     else
      99             :       break;
     100             :   }
     101             : 
     102       22131 :   while (*offset_ptr < end_prologue_offset) {
     103       22131 :     const char *name = debug_line_data.getCStr(offset_ptr);
     104       22131 :     if (name && name[0]) {
     105             :       FileNameEntry fileEntry;
     106       21704 :       fileEntry.Name = name;
     107       21704 :       fileEntry.DirIdx = debug_line_data.getULEB128(offset_ptr);
     108       21704 :       fileEntry.ModTime = debug_line_data.getULEB128(offset_ptr);
     109       21704 :       fileEntry.Length = debug_line_data.getULEB128(offset_ptr);
     110       21704 :       FileNames.push_back(fileEntry);
     111             :     } else {
     112             :       break;
     113             :     }
     114             :   }
     115             : 
     116         427 :   if (*offset_ptr != end_prologue_offset) {
     117             :     fprintf(stderr, "warning: parsing line table prologue at 0x%8.8x should"
     118             :                     " have ended at 0x%8.8x but it ended at 0x%8.8x\n",
     119           0 :             prologue_offset, end_prologue_offset, *offset_ptr);
     120           0 :     return false;
     121             :   }
     122             :   return true;
     123             : }
     124             : 
     125         646 : DWARFDebugLine::Row::Row(bool default_is_stmt) {
     126         646 :   reset(default_is_stmt);
     127         646 : }
     128             : 
     129      330286 : void DWARFDebugLine::Row::postAppend() {
     130      330286 :   BasicBlock = false;
     131      330286 :   PrologueEnd = false;
     132      330286 :   EpilogueBegin = false;
     133      330286 : }
     134             : 
     135       13716 : void DWARFDebugLine::Row::reset(bool default_is_stmt) {
     136       13716 :   Address = 0;
     137       13716 :   Line = 1;
     138       13716 :   Column = 0;
     139       13716 :   File = 1;
     140       13716 :   Isa = 0;
     141       13716 :   Discriminator = 0;
     142       13716 :   IsStmt = default_is_stmt;
     143       13716 :   BasicBlock = false;
     144       13716 :   EndSequence = false;
     145       13716 :   PrologueEnd = false;
     146       13716 :   EpilogueBegin = false;
     147       13716 : }
     148             : 
     149         524 : void DWARFDebugLine::Row::dump(raw_ostream &OS) const {
     150        1572 :   OS << format("0x%16.16" PRIx64 " %6u %6u", Address, Line, Column)
     151        1572 :      << format(" %6u %3u %13u ", File, Isa, Discriminator)
     152        1048 :      << (IsStmt ? " is_stmt" : "")
     153        1048 :      << (BasicBlock ? " basic_block" : "")
     154        1048 :      << (PrologueEnd ? " prologue_end" : "")
     155        1048 :      << (EpilogueBegin ? " epilogue_begin" : "")
     156        1048 :      << (EndSequence ? " end_sequence" : "")
     157         524 :      << '\n';
     158         524 : }
     159             : 
     160         862 : DWARFDebugLine::Sequence::Sequence() {
     161         862 :   reset();
     162         862 : }
     163             : 
     164       26584 : void DWARFDebugLine::Sequence::reset() {
     165       26584 :   LowPC = 0;
     166       26584 :   HighPC = 0;
     167       26584 :   FirstRowIndex = 0;
     168       26584 :   LastRowIndex = 0;
     169       26584 :   Empty = true;
     170       26584 : }
     171             : 
     172        1026 : DWARFDebugLine::LineTable::LineTable() {
     173         513 :   clear();
     174         513 : }
     175             : 
     176         105 : void DWARFDebugLine::LineTable::dump(raw_ostream &OS) const {
     177         105 :   Prologue.dump(OS);
     178         105 :   OS << '\n';
     179             : 
     180         210 :   if (!Rows.empty()) {
     181          78 :     OS << "Address            Line   Column File   ISA Discriminator Flags\n"
     182             :        << "------------------ ------ ------ ------ --- ------------- "
     183          78 :           "-------------\n";
     184         836 :     for (const Row &R : Rows) {
     185         524 :       R.dump(OS);
     186             :     }
     187             :   }
     188         105 : }
     189             : 
     190         941 : void DWARFDebugLine::LineTable::clear() {
     191         941 :   Prologue.clear();
     192         941 :   Rows.clear();
     193         941 :   Sequences.clear();
     194         941 : }
     195             : 
     196         418 : DWARFDebugLine::ParsingState::ParsingState(struct LineTable *LT)
     197         418 :     : LineTable(LT), RowNumber(0) {
     198         418 :   resetRowAndSequence();
     199         418 : }
     200             : 
     201       13070 : void DWARFDebugLine::ParsingState::resetRowAndSequence() {
     202       13070 :   Row.reset(LineTable->Prologue.DefaultIsStmt);
     203       13070 :   Sequence.reset();
     204       13070 : }
     205             : 
     206      330286 : void DWARFDebugLine::ParsingState::appendRowToMatrix(uint32_t offset) {
     207      330286 :   if (Sequence.Empty) {
     208             :     // Record the beginning of instruction sequence.
     209       12653 :     Sequence.Empty = false;
     210       12653 :     Sequence.LowPC = Row.Address;
     211       12653 :     Sequence.FirstRowIndex = RowNumber;
     212             :   }
     213      330286 :   ++RowNumber;
     214      330286 :   LineTable->appendRow(Row);
     215      330286 :   if (Row.EndSequence) {
     216             :     // Record the end of instruction sequence.
     217       12652 :     Sequence.HighPC = Row.Address;
     218       12652 :     Sequence.LastRowIndex = RowNumber;
     219       25304 :     if (Sequence.isValid())
     220       12652 :       LineTable->appendSequence(Sequence);
     221       12652 :     Sequence.reset();
     222             :   }
     223      330286 :   Row.postAppend();
     224      330286 : }
     225             : 
     226             : const DWARFDebugLine::LineTable *
     227        1304 : DWARFDebugLine::getLineTable(uint32_t offset) const {
     228        2608 :   LineTableConstIter pos = LineTableMap.find(offset);
     229        2608 :   if (pos != LineTableMap.end())
     230         981 :     return &pos->second;
     231             :   return nullptr;
     232             : }
     233             : 
     234             : const DWARFDebugLine::LineTable *
     235         323 : DWARFDebugLine::getOrParseLineTable(DataExtractor debug_line_data,
     236             :                                     uint32_t offset) {
     237             :   std::pair<LineTableIter, bool> pos =
     238        1292 :     LineTableMap.insert(LineTableMapTy::value_type(offset, LineTable()));
     239         323 :   LineTable *LT = &pos.first->second;
     240         323 :   if (pos.second) {
     241         323 :     if (!LT->parse(debug_line_data, RelocMap, &offset))
     242             :       return nullptr;
     243             :   }
     244         322 :   return LT;
     245             : }
     246             : 
     247         419 : bool DWARFDebugLine::LineTable::parse(DataExtractor debug_line_data,
     248             :                                       const RelocAddrMap *RMap,
     249             :                                       uint32_t *offset_ptr) {
     250         419 :   const uint32_t debug_line_offset = *offset_ptr;
     251             : 
     252         419 :   clear();
     253             : 
     254         419 :   if (!Prologue.parse(debug_line_data, offset_ptr)) {
     255             :     // Restore our offset and return false to indicate failure!
     256           1 :     *offset_ptr = debug_line_offset;
     257           1 :     return false;
     258             :   }
     259             : 
     260         418 :   const uint32_t end_offset = debug_line_offset + Prologue.TotalLength +
     261         418 :                               sizeof(Prologue.TotalLength);
     262             : 
     263         418 :   ParsingState State(this);
     264             : 
     265      833465 :   while (*offset_ptr < end_offset) {
     266      832629 :     uint8_t opcode = debug_line_data.getU8(offset_ptr);
     267             : 
     268      832629 :     if (opcode == 0) {
     269             :       // Extended Opcodes always start with a zero opcode followed by
     270             :       // a uleb128 length so you can skip ones you don't know about
     271       36263 :       uint32_t ext_offset = *offset_ptr;
     272       36263 :       uint64_t len = debug_line_data.getULEB128(offset_ptr);
     273       36263 :       uint32_t arg_size = len - (*offset_ptr - ext_offset);
     274             : 
     275       36263 :       uint8_t sub_opcode = debug_line_data.getU8(offset_ptr);
     276       36263 :       switch (sub_opcode) {
     277             :       case DW_LNE_end_sequence:
     278             :         // Set the end_sequence register of the state machine to true and
     279             :         // append a row to the matrix using the current values of the
     280             :         // state-machine registers. Then reset the registers to the initial
     281             :         // values specified above. Every statement program sequence must end
     282             :         // with a DW_LNE_end_sequence instruction which creates a row whose
     283             :         // address is that of the byte after the last target machine instruction
     284             :         // of the sequence.
     285       12652 :         State.Row.EndSequence = true;
     286       12652 :         State.appendRowToMatrix(*offset_ptr);
     287       12652 :         State.resetRowAndSequence();
     288       12652 :         break;
     289             : 
     290             :       case DW_LNE_set_address:
     291             :         // Takes a single relocatable address as an operand. The size of the
     292             :         // operand is the size appropriate to hold an address on the target
     293             :         // machine. Set the address register to the value given by the
     294             :         // relocatable address. All of the other statement program opcodes
     295             :         // that affect the address register add a delta to it. This instruction
     296             :         // stores a relocatable value into it instead.
     297             :         {
     298             :           // If this address is in our relocation map, apply the relocation.
     299       12653 :           RelocAddrMap::const_iterator AI = RMap->find(*offset_ptr);
     300       25306 :           if (AI != RMap->end()) {
     301         179 :              const std::pair<uint8_t, int64_t> &R = AI->second;
     302             :              State.Row.Address =
     303         179 :                  debug_line_data.getAddress(offset_ptr) + R.second;
     304             :           } else
     305       12474 :             State.Row.Address = debug_line_data.getAddress(offset_ptr);
     306             :         }
     307       12653 :         break;
     308             : 
     309             :       case DW_LNE_define_file:
     310             :         // Takes 4 arguments. The first is a null terminated string containing
     311             :         // a source file name. The second is an unsigned LEB128 number
     312             :         // representing the directory index of the directory in which the file
     313             :         // was found. The third is an unsigned LEB128 number representing the
     314             :         // time of last modification of the file. The fourth is an unsigned
     315             :         // LEB128 number representing the length in bytes of the file. The time
     316             :         // and length fields may contain LEB128(0) if the information is not
     317             :         // available.
     318             :         //
     319             :         // The directory index represents an entry in the include_directories
     320             :         // section of the statement program prologue. The index is LEB128(0)
     321             :         // if the file was found in the current directory of the compilation,
     322             :         // LEB128(1) if it was found in the first directory in the
     323             :         // include_directories section, and so on. The directory index is
     324             :         // ignored for file names that represent full path names.
     325             :         //
     326             :         // The files are numbered, starting at 1, in the order in which they
     327             :         // appear; the names in the prologue come before names defined by
     328             :         // the DW_LNE_define_file instruction. These numbers are used in the
     329             :         // the file register of the state machine.
     330             :         {
     331             :           FileNameEntry fileEntry;
     332           0 :           fileEntry.Name = debug_line_data.getCStr(offset_ptr);
     333           0 :           fileEntry.DirIdx = debug_line_data.getULEB128(offset_ptr);
     334           0 :           fileEntry.ModTime = debug_line_data.getULEB128(offset_ptr);
     335           0 :           fileEntry.Length = debug_line_data.getULEB128(offset_ptr);
     336           0 :           Prologue.FileNames.push_back(fileEntry);
     337             :         }
     338           0 :         break;
     339             : 
     340             :       case DW_LNE_set_discriminator:
     341       10958 :         State.Row.Discriminator = debug_line_data.getULEB128(offset_ptr);
     342       10958 :         break;
     343             : 
     344             :       default:
     345             :         // Length doesn't include the zero opcode byte or the length itself, but
     346             :         // it does include the sub_opcode, so we have to adjust for that below
     347           0 :         (*offset_ptr) += arg_size;
     348           0 :         break;
     349             :       }
     350      796366 :     } else if (opcode < Prologue.OpcodeBase) {
     351      514116 :       switch (opcode) {
     352             :       // Standard Opcodes
     353             :       case DW_LNS_copy:
     354             :         // Takes no arguments. Append a row to the matrix using the
     355             :         // current values of the state-machine registers. Then set
     356             :         // the basic_block register to false.
     357       35384 :         State.appendRowToMatrix(*offset_ptr);
     358       35384 :         break;
     359             : 
     360             :       case DW_LNS_advance_pc:
     361             :         // Takes a single unsigned LEB128 operand, multiplies it by the
     362             :         // min_inst_length field of the prologue, and adds the
     363             :         // result to the address register of the state machine.
     364             :         State.Row.Address +=
     365       41124 :             debug_line_data.getULEB128(offset_ptr) * Prologue.MinInstLength;
     366       41124 :         break;
     367             : 
     368             :       case DW_LNS_advance_line:
     369             :         // Takes a single signed LEB128 operand and adds that value to
     370             :         // the line register of the state machine.
     371      226208 :         State.Row.Line += debug_line_data.getSLEB128(offset_ptr);
     372      226208 :         break;
     373             : 
     374             :       case DW_LNS_set_file:
     375             :         // Takes a single unsigned LEB128 operand and stores it in the file
     376             :         // register of the state machine.
     377      138317 :         State.Row.File = debug_line_data.getULEB128(offset_ptr);
     378      138317 :         break;
     379             : 
     380             :       case DW_LNS_set_column:
     381             :         // Takes a single unsigned LEB128 operand and stores it in the
     382             :         // column register of the state machine.
     383         358 :         State.Row.Column = debug_line_data.getULEB128(offset_ptr);
     384         358 :         break;
     385             : 
     386             :       case DW_LNS_negate_stmt:
     387             :         // Takes no arguments. Set the is_stmt register of the state
     388             :         // machine to the logical negation of its current value.
     389        4249 :         State.Row.IsStmt = !State.Row.IsStmt;
     390        4249 :         break;
     391             : 
     392             :       case DW_LNS_set_basic_block:
     393             :         // Takes no arguments. Set the basic_block register of the
     394             :         // state machine to true
     395           0 :         State.Row.BasicBlock = true;
     396           0 :         break;
     397             : 
     398             :       case DW_LNS_const_add_pc:
     399             :         // Takes no arguments. Add to the address register of the state
     400             :         // machine the address increment value corresponding to special
     401             :         // opcode 255. The motivation for DW_LNS_const_add_pc is this:
     402             :         // when the statement program needs to advance the address by a
     403             :         // small amount, it can use a single special opcode, which occupies
     404             :         // a single byte. When it needs to advance the address by up to
     405             :         // twice the range of the last special opcode, it can use
     406             :         // DW_LNS_const_add_pc followed by a special opcode, for a total
     407             :         // of two bytes. Only if it needs to advance the address by more
     408             :         // than twice that range will it need to use both DW_LNS_advance_pc
     409             :         // and a special opcode, requiring three or more bytes.
     410             :         {
     411       68026 :           uint8_t adjust_opcode = 255 - Prologue.OpcodeBase;
     412             :           uint64_t addr_offset =
     413       68026 :               (adjust_opcode / Prologue.LineRange) * Prologue.MinInstLength;
     414       68026 :           State.Row.Address += addr_offset;
     415             :         }
     416       68026 :         break;
     417             : 
     418             :       case DW_LNS_fixed_advance_pc:
     419             :         // Takes a single uhalf operand. Add to the address register of
     420             :         // the state machine the value of the (unencoded) operand. This
     421             :         // is the only extended opcode that takes an argument that is not
     422             :         // a variable length number. The motivation for DW_LNS_fixed_advance_pc
     423             :         // is this: existing assemblers cannot emit DW_LNS_advance_pc or
     424             :         // special opcodes because they cannot encode LEB128 numbers or
     425             :         // judge when the computation of a special opcode overflows and
     426             :         // requires the use of DW_LNS_advance_pc. Such assemblers, however,
     427             :         // can use DW_LNS_fixed_advance_pc instead, sacrificing compression.
     428           0 :         State.Row.Address += debug_line_data.getU16(offset_ptr);
     429           0 :         break;
     430             : 
     431             :       case DW_LNS_set_prologue_end:
     432             :         // Takes no arguments. Set the prologue_end register of the
     433             :         // state machine to true
     434         450 :         State.Row.PrologueEnd = true;
     435         450 :         break;
     436             : 
     437             :       case DW_LNS_set_epilogue_begin:
     438             :         // Takes no arguments. Set the basic_block register of the
     439             :         // state machine to true
     440           0 :         State.Row.EpilogueBegin = true;
     441           0 :         break;
     442             : 
     443             :       case DW_LNS_set_isa:
     444             :         // Takes a single unsigned LEB128 operand and stores it in the
     445             :         // column register of the state machine.
     446           0 :         State.Row.Isa = debug_line_data.getULEB128(offset_ptr);
     447           0 :         break;
     448             : 
     449             :       default:
     450             :         // Handle any unknown standard opcodes here. We know the lengths
     451             :         // of such opcodes because they are specified in the prologue
     452             :         // as a multiple of LEB128 operands for each opcode.
     453             :         {
     454             :           assert(opcode - 1U < Prologue.StandardOpcodeLengths.size());
     455           0 :           uint8_t opcode_length = Prologue.StandardOpcodeLengths[opcode - 1];
     456           0 :           for (uint8_t i = 0; i < opcode_length; ++i)
     457           0 :             debug_line_data.getULEB128(offset_ptr);
     458             :         }
     459             :         break;
     460             :       }
     461             :     } else {
     462             :       // Special Opcodes
     463             : 
     464             :       // A special opcode value is chosen based on the amount that needs
     465             :       // to be added to the line and address registers. The maximum line
     466             :       // increment for a special opcode is the value of the line_base
     467             :       // field in the header, plus the value of the line_range field,
     468             :       // minus 1 (line base + line range - 1). If the desired line
     469             :       // increment is greater than the maximum line increment, a standard
     470             :       // opcode must be used instead of a special opcode. The "address
     471             :       // advance" is calculated by dividing the desired address increment
     472             :       // by the minimum_instruction_length field from the header. The
     473             :       // special opcode is then calculated using the following formula:
     474             :       //
     475             :       //  opcode = (desired line increment - line_base) +
     476             :       //           (line_range * address advance) + opcode_base
     477             :       //
     478             :       // If the resulting opcode is greater than 255, a standard opcode
     479             :       // must be used instead.
     480             :       //
     481             :       // To decode a special opcode, subtract the opcode_base from the
     482             :       // opcode itself to give the adjusted opcode. The amount to
     483             :       // increment the address register is the result of the adjusted
     484             :       // opcode divided by the line_range multiplied by the
     485             :       // minimum_instruction_length field from the header. That is:
     486             :       //
     487             :       //  address increment = (adjusted opcode / line_range) *
     488             :       //                      minimum_instruction_length
     489             :       //
     490             :       // The amount to increment the line register is the line_base plus
     491             :       // the result of the adjusted opcode modulo the line_range. That is:
     492             :       //
     493             :       // line increment = line_base + (adjusted opcode % line_range)
     494             : 
     495      282250 :       uint8_t adjust_opcode = opcode - Prologue.OpcodeBase;
     496             :       uint64_t addr_offset =
     497      282250 :           (adjust_opcode / Prologue.LineRange) * Prologue.MinInstLength;
     498             :       int32_t line_offset =
     499      282250 :           Prologue.LineBase + (adjust_opcode % Prologue.LineRange);
     500      282250 :       State.Row.Line += line_offset;
     501      282250 :       State.Row.Address += addr_offset;
     502      282250 :       State.appendRowToMatrix(*offset_ptr);
     503             :     }
     504             :   }
     505             : 
     506         418 :   if (!State.Sequence.Empty) {
     507             :     fprintf(stderr, "warning: last sequence in debug line table is not"
     508           1 :                     "terminated!\n");
     509             :   }
     510             : 
     511             :   // Sort all sequences so that address lookup will work faster.
     512         836 :   if (!Sequences.empty()) {
     513         748 :     std::sort(Sequences.begin(), Sequences.end(), Sequence::orderByLowPC);
     514             :     // Note: actually, instruction address ranges of sequences should not
     515             :     // overlap (in shared objects and executables). If they do, the address
     516             :     // lookup would still work, though, but result would be ambiguous.
     517             :     // We don't report warning in this case. For example,
     518             :     // sometimes .so compiled from multiple object files contains a few
     519             :     // rudimentary sequences for address ranges [0x0, 0xsomething).
     520             :   }
     521             : 
     522         418 :   return end_offset;
     523             : }
     524             : 
     525         219 : uint32_t DWARFDebugLine::LineTable::lookupAddress(uint64_t address) const {
     526         219 :   uint32_t unknown_index = UINT32_MAX;
     527         438 :   if (Sequences.empty())
     528             :     return unknown_index;
     529             :   // First, find an instruction sequence containing the given address.
     530         219 :   DWARFDebugLine::Sequence sequence;
     531         219 :   sequence.LowPC = address;
     532         438 :   SequenceIter first_seq = Sequences.begin();
     533         438 :   SequenceIter last_seq = Sequences.end();
     534             :   SequenceIter seq_pos = std::lower_bound(first_seq, last_seq, sequence,
     535         219 :       DWARFDebugLine::Sequence::orderByLowPC);
     536         219 :   DWARFDebugLine::Sequence found_seq;
     537         219 :   if (seq_pos == last_seq) {
     538          86 :     found_seq = Sequences.back();
     539         176 :   } else if (seq_pos->LowPC == address) {
     540           8 :     found_seq = *seq_pos;
     541             :   } else {
     542         168 :     if (seq_pos == first_seq)
     543             :       return unknown_index;
     544         168 :     found_seq = *(seq_pos - 1);
     545             :   }
     546         438 :   if (!found_seq.containsPC(address))
     547             :     return unknown_index;
     548             :   // Search for instruction address in the rows describing the sequence.
     549             :   // Rows are stored in a vector, so we may use arithmetical operations with
     550             :   // iterators.
     551         219 :   DWARFDebugLine::Row row;
     552         219 :   row.Address = address;
     553         657 :   RowIter first_row = Rows.begin() + found_seq.FirstRowIndex;
     554         657 :   RowIter last_row = Rows.begin() + found_seq.LastRowIndex;
     555             :   RowIter row_pos = std::lower_bound(first_row, last_row, row,
     556         219 :       DWARFDebugLine::Row::orderByAddress);
     557         219 :   if (row_pos == last_row) {
     558           0 :     return found_seq.LastRowIndex - 1;
     559             :   }
     560         438 :   uint32_t index = found_seq.FirstRowIndex + (row_pos - first_row);
     561         219 :   if (row_pos->Address > address) {
     562         153 :     if (row_pos == first_row)
     563             :       return unknown_index;
     564             :     else
     565         153 :       index--;
     566             :   }
     567         219 :   return index;
     568             : }
     569             : 
     570           6 : bool DWARFDebugLine::LineTable::lookupAddressRange(
     571             :     uint64_t address, uint64_t size, std::vector<uint32_t> &result) const {
     572          12 :   if (Sequences.empty())
     573             :     return false;
     574           6 :   uint64_t end_addr = address + size;
     575             :   // First, find an instruction sequence containing the given address.
     576           6 :   DWARFDebugLine::Sequence sequence;
     577           6 :   sequence.LowPC = address;
     578          12 :   SequenceIter first_seq = Sequences.begin();
     579          12 :   SequenceIter last_seq = Sequences.end();
     580             :   SequenceIter seq_pos = std::lower_bound(first_seq, last_seq, sequence,
     581           6 :       DWARFDebugLine::Sequence::orderByLowPC);
     582           6 :   if (seq_pos == last_seq || seq_pos->LowPC != address) {
     583           3 :     if (seq_pos == first_seq)
     584             :       return false;
     585           3 :     seq_pos--;
     586             :   }
     587          12 :   if (!seq_pos->containsPC(address))
     588             :     return false;
     589             : 
     590             :   SequenceIter start_pos = seq_pos;
     591             : 
     592             :   // Add the rows from the first sequence to the vector, starting with the
     593             :   // index we just calculated
     594             : 
     595          12 :   while (seq_pos != last_seq && seq_pos->LowPC < end_addr) {
     596           6 :     DWARFDebugLine::Sequence cur_seq = *seq_pos;
     597             :     uint32_t first_row_index;
     598             :     uint32_t last_row_index;
     599           6 :     if (seq_pos == start_pos) {
     600             :       // For the first sequence, we need to find which row in the sequence is the
     601             :       // first in our range. Rows are stored in a vector, so we may use
     602             :       // arithmetical operations with iterators.
     603           6 :       DWARFDebugLine::Row row;
     604           6 :       row.Address = address;
     605          18 :       RowIter first_row = Rows.begin() + cur_seq.FirstRowIndex;
     606          18 :       RowIter last_row = Rows.begin() + cur_seq.LastRowIndex;
     607             :       RowIter row_pos = std::upper_bound(first_row, last_row, row,
     608           6 :                                          DWARFDebugLine::Row::orderByAddress);
     609             :       // The 'row_pos' iterator references the first row that is greater than
     610             :       // our start address. Unless that's the first row, we want to start at
     611             :       // the row before that.
     612          12 :       first_row_index = cur_seq.FirstRowIndex + (row_pos - first_row);
     613           6 :       if (row_pos != first_row)
     614           6 :         --first_row_index;
     615             :     } else
     616             :       first_row_index = cur_seq.FirstRowIndex;
     617             : 
     618             :     // For the last sequence in our range, we need to figure out the last row in
     619             :     // range.  For all other sequences we can go to the end of the sequence.
     620           6 :     if (cur_seq.HighPC > end_addr) {
     621           3 :       DWARFDebugLine::Row row;
     622           3 :       row.Address = end_addr;
     623           9 :       RowIter first_row = Rows.begin() + cur_seq.FirstRowIndex;
     624           9 :       RowIter last_row = Rows.begin() + cur_seq.LastRowIndex;
     625             :       RowIter row_pos = std::upper_bound(first_row, last_row, row,
     626           3 :                                          DWARFDebugLine::Row::orderByAddress);
     627             :       // The 'row_pos' iterator references the first row that is greater than
     628             :       // our end address.  The row before that is the last row we want.
     629           6 :       last_row_index = cur_seq.FirstRowIndex + (row_pos - first_row) - 1;
     630             :     } else
     631             :       // Contrary to what you might expect, DWARFDebugLine::SequenceLastRowIndex
     632             :       // isn't a valid index within the current sequence.  It's that plus one.
     633           3 :       last_row_index = cur_seq.LastRowIndex - 1;
     634             : 
     635          37 :     for (uint32_t i = first_row_index; i <= last_row_index; ++i) {
     636          31 :       result.push_back(i);
     637             :     }
     638             : 
     639             :     ++seq_pos;
     640             :   }
     641             : 
     642             :   return true;
     643             : }
     644             : 
     645             : bool
     646        1392 : DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex,
     647             :                                               const char *CompDir,
     648             :                                               FileLineInfoKind Kind,
     649             :                                               std::string &Result) const {
     650        2784 :   if (FileIndex == 0 || FileIndex > Prologue.FileNames.size() ||
     651             :       Kind == FileLineInfoKind::None)
     652             :     return false;
     653        2762 :   const FileNameEntry &Entry = Prologue.FileNames[FileIndex - 1];
     654        1381 :   const char *FileName = Entry.Name;
     655        4143 :   if (Kind != FileLineInfoKind::AbsoluteFilePath ||
     656        4081 :       sys::path::is_absolute(FileName)) {
     657             :     Result = FileName;
     658          31 :     return true;
     659             :   }
     660             : 
     661             :   SmallString<16> FilePath;
     662        1350 :   uint64_t IncludeDirIndex = Entry.DirIdx;
     663        1350 :   const char *IncludeDir = "";
     664             :   // Be defensive about the contents of Entry.
     665        1739 :   if (IncludeDirIndex > 0 &&
     666         389 :       IncludeDirIndex <= Prologue.IncludeDirectories.size())
     667         778 :     IncludeDir = Prologue.IncludeDirectories[IncludeDirIndex - 1];
     668             : 
     669             :   // We may still need to append compilation directory of compile unit.
     670             :   // We know that FileName is not absolute, the only way to have an
     671             :   // absolute path at this point would be if IncludeDir is absolute.
     672        4050 :   if (CompDir && Kind == FileLineInfoKind::AbsoluteFilePath &&
     673        3678 :       sys::path::is_relative(IncludeDir))
     674         848 :     sys::path::append(FilePath, CompDir);
     675             : 
     676             :   // sys::path::append skips empty strings.
     677        1350 :   sys::path::append(FilePath, IncludeDir, FileName);
     678        2700 :   Result = FilePath.str();
     679        1350 :   return true;
     680             : }
     681             : 
     682             : bool
     683         219 : DWARFDebugLine::LineTable::getFileLineInfoForAddress(uint64_t Address,
     684             :                                                      const char *CompDir,
     685             :                                                      FileLineInfoKind Kind,
     686             :                                                      DILineInfo &Result) const {
     687             :   // Get the index of row we're looking for in the line table.
     688         219 :   uint32_t RowIndex = lookupAddress(Address);
     689         219 :   if (RowIndex == -1U)
     690             :     return false;
     691             :   // Take file number and line/column from the row.
     692         438 :   const auto &Row = Rows[RowIndex];
     693         219 :   if (!getFileNameByIndex(Row.File, CompDir, Kind, Result.FileName))
     694             :     return false;
     695         219 :   Result.Line = Row.Line;
     696         219 :   Result.Column = Row.Column;
     697         219 :   return true;
     698             : }

Generated by: LCOV version 1.11