1b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer//===-- DWARFDebugLine.cpp ------------------------------------------------===//
2b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer//
3b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer//                     The LLVM Compiler Infrastructure
4b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer//
5b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer// This file is distributed under the University of Illinois Open Source
6b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer// License. See LICENSE.TXT for details.
7b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer//
8b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer//===----------------------------------------------------------------------===//
9b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
10ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
11b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer#include "llvm/Support/Dwarf.h"
12b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer#include "llvm/Support/Format.h"
1338a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov#include "llvm/Support/Path.h"
14b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer#include "llvm/Support/raw_ostream.h"
157393c7f748acb10b143cab296ae98551b4c430f4Benjamin Kramer#include <algorithm>
16b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramerusing namespace llvm;
17b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramerusing namespace dwarf;
18dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinestypedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind;
19dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
20de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarDWARFDebugLine::Prologue::Prologue() { clear(); }
21dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
22dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid DWARFDebugLine::Prologue::clear() {
23dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  TotalLength = Version = PrologueLength = 0;
24dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MinInstLength = MaxOpsPerInst = DefaultIsStmt = LineBase = LineRange = 0;
25dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  OpcodeBase = 0;
266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  IsDWARF64 = false;
27dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  StandardOpcodeLengths.clear();
28dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  IncludeDirectories.clear();
29dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  FileNames.clear();
30dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
31b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
32b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramervoid DWARFDebugLine::Prologue::dump(raw_ostream &OS) const {
33b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer  OS << "Line table prologue:\n"
346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar     << format("    total_length: 0x%8.8" PRIx64 "\n", TotalLength)
3536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     << format("         version: %u\n", Version)
366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar     << format(" prologue_length: 0x%8.8" PRIx64 "\n", PrologueLength)
3736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     << format(" min_inst_length: %u\n", MinInstLength)
3836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     << format(Version >= 4 ? "max_ops_per_inst: %u\n" : "", MaxOpsPerInst)
3936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     << format(" default_is_stmt: %u\n", DefaultIsStmt)
4036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     << format("       line_base: %i\n", LineBase)
4136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     << format("      line_range: %u\n", LineRange)
4236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     << format("     opcode_base: %u\n", OpcodeBase);
43b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
44b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer  for (uint32_t i = 0; i < StandardOpcodeLengths.size(); ++i)
45de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    OS << format("standard_opcode_lengths[%s] = %u\n", LNStandardString(i + 1),
46b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer                 StandardOpcodeLengths[i]);
47b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
48b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer  if (!IncludeDirectories.empty())
49b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer    for (uint32_t i = 0; i < IncludeDirectories.size(); ++i)
50de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      OS << format("include_directories[%3u] = '", i + 1)
51b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer         << IncludeDirectories[i] << "'\n";
52b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
53b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer  if (!FileNames.empty()) {
54b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer    OS << "                Dir  Mod Time   File Len   File Name\n"
55b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer       << "                ---- ---------- ---------- -----------"
56b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer          "----------------\n";
57b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer    for (uint32_t i = 0; i < FileNames.size(); ++i) {
58de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      const FileNameEntry &fileEntry = FileNames[i];
59de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      OS << format("file_names[%3u] %4" PRIu64 " ", i + 1, fileEntry.DirIdx)
60de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar         << format("0x%8.8" PRIx64 " 0x%8.8" PRIx64 " ", fileEntry.ModTime,
61de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                   fileEntry.Length)
62b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer         << fileEntry.Name << '\n';
63b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer    }
64b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer  }
65b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer}
66b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
67dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool DWARFDebugLine::Prologue::parse(DataExtractor debug_line_data,
68dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                     uint32_t *offset_ptr) {
696948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  const uint64_t prologue_offset = *offset_ptr;
70dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
71dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  clear();
72dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  TotalLength = debug_line_data.getU32(offset_ptr);
736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (TotalLength == UINT32_MAX) {
746948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    IsDWARF64 = true;
756948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    TotalLength = debug_line_data.getU64(offset_ptr);
766948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  } else if (TotalLength > 0xffffff00) {
776948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return false;
786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
79dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Version = debug_line_data.getU16(offset_ptr);
80dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Version < 2)
81dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
82dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
83de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  PrologueLength =
84de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      debug_line_data.getUnsigned(offset_ptr, sizeofPrologueLength());
856948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  const uint64_t end_prologue_offset = PrologueLength + *offset_ptr;
86dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  MinInstLength = debug_line_data.getU8(offset_ptr);
87dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Version >= 4)
88dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    MaxOpsPerInst = debug_line_data.getU8(offset_ptr);
89dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  DefaultIsStmt = debug_line_data.getU8(offset_ptr);
90dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LineBase = debug_line_data.getU8(offset_ptr);
91dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LineRange = debug_line_data.getU8(offset_ptr);
92dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  OpcodeBase = debug_line_data.getU8(offset_ptr);
93dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
94dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  StandardOpcodeLengths.reserve(OpcodeBase - 1);
95dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (uint32_t i = 1; i < OpcodeBase; ++i) {
96dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    uint8_t op_len = debug_line_data.getU8(offset_ptr);
97dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    StandardOpcodeLengths.push_back(op_len);
98dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
99dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
100dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  while (*offset_ptr < end_prologue_offset) {
101dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const char *s = debug_line_data.getCStr(offset_ptr);
102dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (s && s[0])
103dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      IncludeDirectories.push_back(s);
104dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    else
105dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
106dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
107dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
108dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  while (*offset_ptr < end_prologue_offset) {
109dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    const char *name = debug_line_data.getCStr(offset_ptr);
110dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (name && name[0]) {
111dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      FileNameEntry fileEntry;
112dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      fileEntry.Name = name;
113dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      fileEntry.DirIdx = debug_line_data.getULEB128(offset_ptr);
114dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      fileEntry.ModTime = debug_line_data.getULEB128(offset_ptr);
115dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      fileEntry.Length = debug_line_data.getULEB128(offset_ptr);
116dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      FileNames.push_back(fileEntry);
117dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else {
118dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      break;
119dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    }
120dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
121dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
122dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (*offset_ptr != end_prologue_offset) {
1236948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    fprintf(stderr, "warning: parsing line table prologue at 0x%8.8" PRIx64
1246948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                    " should have ended at 0x%8.8" PRIx64
1256948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                    " but it ended at 0x%8.8" PRIx64 "\n",
1266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar            prologue_offset, end_prologue_offset, (uint64_t)*offset_ptr);
127dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    return false;
128dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
129dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return true;
130dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
131dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
132de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarDWARFDebugLine::Row::Row(bool default_is_stmt) { reset(default_is_stmt); }
133dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
134b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramervoid DWARFDebugLine::Row::postAppend() {
135b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer  BasicBlock = false;
136b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer  PrologueEnd = false;
137b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer  EpilogueBegin = false;
138b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer}
139b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
140b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramervoid DWARFDebugLine::Row::reset(bool default_is_stmt) {
141b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer  Address = 0;
142b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer  Line = 1;
143b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer  Column = 0;
144b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer  File = 1;
145b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer  Isa = 0;
14636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  Discriminator = 0;
147b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer  IsStmt = default_is_stmt;
148b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer  BasicBlock = false;
149b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer  EndSequence = false;
150b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer  PrologueEnd = false;
151b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer  EpilogueBegin = false;
152b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer}
153b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
154b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramervoid DWARFDebugLine::Row::dump(raw_ostream &OS) const {
15541a964931a0e0943ceef28b0c691843bf8ca87b7Benjamin Kramer  OS << format("0x%16.16" PRIx64 " %6u %6u", Address, Line, Column)
15636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines     << format(" %6u %3u %13u ", File, Isa, Discriminator)
157de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar     << (IsStmt ? " is_stmt" : "") << (BasicBlock ? " basic_block" : "")
158b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer     << (PrologueEnd ? " prologue_end" : "")
159b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer     << (EpilogueBegin ? " epilogue_begin" : "")
160de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar     << (EndSequence ? " end_sequence" : "") << '\n';
161b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer}
162b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
163de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarDWARFDebugLine::Sequence::Sequence() { reset(); }
164dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
165dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid DWARFDebugLine::Sequence::reset() {
166dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LowPC = 0;
167dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  HighPC = 0;
168dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  FirstRowIndex = 0;
169dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LastRowIndex = 0;
170dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Empty = true;
171dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
172dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
173de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga NainarDWARFDebugLine::LineTable::LineTable() { clear(); }
174dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
175b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramervoid DWARFDebugLine::LineTable::dump(raw_ostream &OS) const {
176b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer  Prologue.dump(OS);
177b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer  OS << '\n';
178b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
179b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer  if (!Rows.empty()) {
18036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    OS << "Address            Line   Column File   ISA Discriminator Flags\n"
18136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines       << "------------------ ------ ------ ------ --- ------------- "
18236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines          "-------------\n";
18336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    for (const Row &R : Rows) {
18436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      R.dump(OS);
18536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
186b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer  }
187b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer}
188b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
189dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid DWARFDebugLine::LineTable::clear() {
190dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Prologue.clear();
191dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Rows.clear();
192dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Sequences.clear();
193b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer}
194b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
195dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesDWARFDebugLine::ParsingState::ParsingState(struct LineTable *LT)
196dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    : LineTable(LT), RowNumber(0) {
197dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  resetRowAndSequence();
198351f83be64057380877615153fe5dc50308ab017Alexey Samsonov}
199351f83be64057380877615153fe5dc50308ab017Alexey Samsonov
200dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid DWARFDebugLine::ParsingState::resetRowAndSequence() {
201dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Row.reset(LineTable->Prologue.DefaultIsStmt);
202dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Sequence.reset();
203dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines}
2046bc4e712dc35db68a621f54c176f6e0b14f40f97Nick Lewycky
205dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid DWARFDebugLine::ParsingState::appendRowToMatrix(uint32_t offset) {
206dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Sequence.Empty) {
207dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Record the beginning of instruction sequence.
208dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Sequence.Empty = false;
209dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Sequence.LowPC = Row.Address;
210dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Sequence.FirstRowIndex = RowNumber;
211dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
212dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  ++RowNumber;
213dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LineTable->appendRow(Row);
214dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Row.EndSequence) {
215dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Record the end of instruction sequence.
216dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Sequence.HighPC = Row.Address;
217dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Sequence.LastRowIndex = RowNumber;
218dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Sequence.isValid())
219dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      LineTable->appendSequence(Sequence);
220dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    Sequence.reset();
221dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
222dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  Row.postAppend();
223b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer}
224b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
225b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramerconst DWARFDebugLine::LineTable *
226b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin KramerDWARFDebugLine::getLineTable(uint32_t offset) const {
227b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer  LineTableConstIter pos = LineTableMap.find(offset);
228b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer  if (pos != LineTableMap.end())
229b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer    return &pos->second;
230dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return nullptr;
231b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer}
232b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
233c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin Kramerconst DWARFDebugLine::LineTable *
234c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin KramerDWARFDebugLine::getOrParseLineTable(DataExtractor debug_line_data,
235c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin Kramer                                    uint32_t offset) {
2361d13d9ed969259d3be267cf0e2c6fe92c1baed49Benjamin Kramer  std::pair<LineTableIter, bool> pos =
237de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      LineTableMap.insert(LineTableMapTy::value_type(offset, LineTable()));
238dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  LineTable *LT = &pos.first->second;
2391d13d9ed969259d3be267cf0e2c6fe92c1baed49Benjamin Kramer  if (pos.second) {
240dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (!LT->parse(debug_line_data, RelocMap, &offset))
241dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      return nullptr;
242c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin Kramer  }
243dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return LT;
244c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin Kramer}
245c26ed9b47ff77ca6244feda9e3837b49624605dbBenjamin Kramer
246dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool DWARFDebugLine::LineTable::parse(DataExtractor debug_line_data,
247dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                      const RelocAddrMap *RMap,
248dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                      uint32_t *offset_ptr) {
249b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer  const uint32_t debug_line_offset = *offset_ptr;
250b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
251dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  clear();
252b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
253dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!Prologue.parse(debug_line_data, offset_ptr)) {
254b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer    // Restore our offset and return false to indicate failure!
255b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer    *offset_ptr = debug_line_offset;
256b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer    return false;
257b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer  }
258b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
259de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  const uint32_t end_offset =
260de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      debug_line_offset + Prologue.TotalLength + Prologue.sizeofTotalLength();
261b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
262dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  ParsingState State(this);
2639013db3399d2847899ba32daf58844bba1aef6ddBenjamin Kramer
264b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer  while (*offset_ptr < end_offset) {
265b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer    uint8_t opcode = debug_line_data.getU8(offset_ptr);
266b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
267b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer    if (opcode == 0) {
268b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      // Extended Opcodes always start with a zero opcode followed by
269b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      // a uleb128 length so you can skip ones you don't know about
270b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      uint32_t ext_offset = *offset_ptr;
271b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      uint64_t len = debug_line_data.getULEB128(offset_ptr);
272b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      uint32_t arg_size = len - (*offset_ptr - ext_offset);
273b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
274b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      uint8_t sub_opcode = debug_line_data.getU8(offset_ptr);
275b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      switch (sub_opcode) {
276b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      case DW_LNE_end_sequence:
277b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // Set the end_sequence register of the state machine to true and
278b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // append a row to the matrix using the current values of the
279b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // state-machine registers. Then reset the registers to the initial
280b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // values specified above. Every statement program sequence must end
281b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // with a DW_LNE_end_sequence instruction which creates a row whose
282b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // address is that of the byte after the last target machine instruction
283b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // of the sequence.
284dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        State.Row.EndSequence = true;
285dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        State.appendRowToMatrix(*offset_ptr);
286dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        State.resetRowAndSequence();
287b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        break;
288b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
289b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      case DW_LNE_set_address:
290b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // Takes a single relocatable address as an operand. The size of the
291b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // operand is the size appropriate to hold an address on the target
292b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // machine. Set the address register to the value given by the
293b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // relocatable address. All of the other statement program opcodes
294b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // that affect the address register add a delta to it. This instruction
295b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // stores a relocatable value into it instead.
296ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor        {
297ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor          // If this address is in our relocation map, apply the relocation.
298ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor          RelocAddrMap::const_iterator AI = RMap->find(*offset_ptr);
299ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor          if (AI != RMap->end()) {
300de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            const std::pair<uint8_t, int64_t> &R = AI->second;
301de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar            State.Row.Address =
302de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                debug_line_data.getAddress(offset_ptr) + R.second;
303ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor          } else
304dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            State.Row.Address = debug_line_data.getAddress(offset_ptr);
305ee7c0d2f931590ccdc53a14b1839e11bb29fc96eAndrew Kaylor        }
306b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        break;
307b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
308b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      case DW_LNE_define_file:
309b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // Takes 4 arguments. The first is a null terminated string containing
310b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // a source file name. The second is an unsigned LEB128 number
311b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // representing the directory index of the directory in which the file
312b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // was found. The third is an unsigned LEB128 number representing the
313b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // time of last modification of the file. The fourth is an unsigned
314b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // LEB128 number representing the length in bytes of the file. The time
315b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // and length fields may contain LEB128(0) if the information is not
316b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // available.
317b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        //
318b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // The directory index represents an entry in the include_directories
319b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // section of the statement program prologue. The index is LEB128(0)
320b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // if the file was found in the current directory of the compilation,
321b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // LEB128(1) if it was found in the first directory in the
322b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // include_directories section, and so on. The directory index is
323b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // ignored for file names that represent full path names.
324b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        //
325b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // The files are numbered, starting at 1, in the order in which they
326b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // appear; the names in the prologue come before names defined by
327b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // the DW_LNE_define_file instruction. These numbers are used in the
328b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // the file register of the state machine.
329b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        {
330b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer          FileNameEntry fileEntry;
331b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer          fileEntry.Name = debug_line_data.getCStr(offset_ptr);
332b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer          fileEntry.DirIdx = debug_line_data.getULEB128(offset_ptr);
333b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer          fileEntry.ModTime = debug_line_data.getULEB128(offset_ptr);
334b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer          fileEntry.Length = debug_line_data.getULEB128(offset_ptr);
335dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          Prologue.FileNames.push_back(fileEntry);
336b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        }
337b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        break;
338b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
33936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      case DW_LNE_set_discriminator:
340dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        State.Row.Discriminator = debug_line_data.getULEB128(offset_ptr);
34136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines        break;
34236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
343b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      default:
344b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // Length doesn't include the zero opcode byte or the length itself, but
345b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // it does include the sub_opcode, so we have to adjust for that below
346b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        (*offset_ptr) += arg_size;
347b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        break;
348b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      }
349dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    } else if (opcode < Prologue.OpcodeBase) {
350b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      switch (opcode) {
351b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      // Standard Opcodes
352b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      case DW_LNS_copy:
353b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // Takes no arguments. Append a row to the matrix using the
354b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // current values of the state-machine registers. Then set
355b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // the basic_block register to false.
356dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        State.appendRowToMatrix(*offset_ptr);
357b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        break;
358b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
359b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      case DW_LNS_advance_pc:
360b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // Takes a single unsigned LEB128 operand, multiplies it by the
361b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // min_inst_length field of the prologue, and adds the
362b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // result to the address register of the state machine.
363dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        State.Row.Address +=
364dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            debug_line_data.getULEB128(offset_ptr) * Prologue.MinInstLength;
365b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        break;
366b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
367b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      case DW_LNS_advance_line:
368b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // Takes a single signed LEB128 operand and adds that value to
369b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // the line register of the state machine.
370dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        State.Row.Line += debug_line_data.getSLEB128(offset_ptr);
371b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        break;
372b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
373b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      case DW_LNS_set_file:
374b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // Takes a single unsigned LEB128 operand and stores it in the file
375b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // register of the state machine.
376dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        State.Row.File = debug_line_data.getULEB128(offset_ptr);
377b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        break;
378b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
379b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      case DW_LNS_set_column:
380b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // Takes a single unsigned LEB128 operand and stores it in the
381b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // column register of the state machine.
382dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        State.Row.Column = debug_line_data.getULEB128(offset_ptr);
383b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        break;
384b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
385b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      case DW_LNS_negate_stmt:
386b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // Takes no arguments. Set the is_stmt register of the state
387b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // machine to the logical negation of its current value.
388dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        State.Row.IsStmt = !State.Row.IsStmt;
389b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        break;
390b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
391b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      case DW_LNS_set_basic_block:
392b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // Takes no arguments. Set the basic_block register of the
393b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // state machine to true
394dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        State.Row.BasicBlock = true;
395b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        break;
396b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
397b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      case DW_LNS_const_add_pc:
398b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // Takes no arguments. Add to the address register of the state
399b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // machine the address increment value corresponding to special
400b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // opcode 255. The motivation for DW_LNS_const_add_pc is this:
401b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // when the statement program needs to advance the address by a
402b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // small amount, it can use a single special opcode, which occupies
403b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // a single byte. When it needs to advance the address by up to
404b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // twice the range of the last special opcode, it can use
405b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // DW_LNS_const_add_pc followed by a special opcode, for a total
406b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // of two bytes. Only if it needs to advance the address by more
407b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // than twice that range will it need to use both DW_LNS_advance_pc
408b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // and a special opcode, requiring three or more bytes.
409b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        {
410dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          uint8_t adjust_opcode = 255 - Prologue.OpcodeBase;
411dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          uint64_t addr_offset =
412dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines              (adjust_opcode / Prologue.LineRange) * Prologue.MinInstLength;
413dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          State.Row.Address += addr_offset;
414b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        }
415b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        break;
416b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
417b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      case DW_LNS_fixed_advance_pc:
418b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // Takes a single uhalf operand. Add to the address register of
419b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // the state machine the value of the (unencoded) operand. This
420b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // is the only extended opcode that takes an argument that is not
421b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // a variable length number. The motivation for DW_LNS_fixed_advance_pc
422b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // is this: existing assemblers cannot emit DW_LNS_advance_pc or
423b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // special opcodes because they cannot encode LEB128 numbers or
424b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // judge when the computation of a special opcode overflows and
425b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // requires the use of DW_LNS_advance_pc. Such assemblers, however,
426b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // can use DW_LNS_fixed_advance_pc instead, sacrificing compression.
427dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        State.Row.Address += debug_line_data.getU16(offset_ptr);
428b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        break;
429b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
430b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      case DW_LNS_set_prologue_end:
431b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // Takes no arguments. Set the prologue_end register of the
432b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // state machine to true
433dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        State.Row.PrologueEnd = true;
434b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        break;
435b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
436b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      case DW_LNS_set_epilogue_begin:
437b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // Takes no arguments. Set the basic_block register of the
438b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // state machine to true
439dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        State.Row.EpilogueBegin = true;
440b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        break;
441b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
442b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      case DW_LNS_set_isa:
443b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // Takes a single unsigned LEB128 operand and stores it in the
444b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // column register of the state machine.
445dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        State.Row.Isa = debug_line_data.getULEB128(offset_ptr);
446b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        break;
447b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
448b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      default:
449b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // Handle any unknown standard opcodes here. We know the lengths
450b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // of such opcodes because they are specified in the prologue
451b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        // as a multiple of LEB128 operands for each opcode.
452b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        {
453dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          assert(opcode - 1U < Prologue.StandardOpcodeLengths.size());
454dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          uint8_t opcode_length = Prologue.StandardOpcodeLengths[opcode - 1];
455dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          for (uint8_t i = 0; i < opcode_length; ++i)
456b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer            debug_line_data.getULEB128(offset_ptr);
457b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        }
458b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer        break;
459b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      }
460b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer    } else {
461b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      // Special Opcodes
462b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
463b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      // A special opcode value is chosen based on the amount that needs
464b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      // to be added to the line and address registers. The maximum line
465b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      // increment for a special opcode is the value of the line_base
466b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      // field in the header, plus the value of the line_range field,
467b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      // minus 1 (line base + line range - 1). If the desired line
468b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      // increment is greater than the maximum line increment, a standard
469017449d64b8920eb926e9e752e22d2f5921a6237NAKAMURA Takumi      // opcode must be used instead of a special opcode. The "address
470017449d64b8920eb926e9e752e22d2f5921a6237NAKAMURA Takumi      // advance" is calculated by dividing the desired address increment
471b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      // by the minimum_instruction_length field from the header. The
472b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      // special opcode is then calculated using the following formula:
473b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      //
474b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      //  opcode = (desired line increment - line_base) +
475b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      //           (line_range * address advance) + opcode_base
476b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      //
477b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      // If the resulting opcode is greater than 255, a standard opcode
478b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      // must be used instead.
479b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      //
480b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      // To decode a special opcode, subtract the opcode_base from the
481b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      // opcode itself to give the adjusted opcode. The amount to
482b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      // increment the address register is the result of the adjusted
483b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      // opcode divided by the line_range multiplied by the
484b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      // minimum_instruction_length field from the header. That is:
485b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      //
486b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      //  address increment = (adjusted opcode / line_range) *
487b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      //                      minimum_instruction_length
488b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      //
489b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      // The amount to increment the line register is the line_base plus
490b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      // the result of the adjusted opcode modulo the line_range. That is:
491b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      //
492b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer      // line increment = line_base + (adjusted opcode % line_range)
493b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
494dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      uint8_t adjust_opcode = opcode - Prologue.OpcodeBase;
495dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      uint64_t addr_offset =
496dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          (adjust_opcode / Prologue.LineRange) * Prologue.MinInstLength;
497dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      int32_t line_offset =
498dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          Prologue.LineBase + (adjust_opcode % Prologue.LineRange);
499dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      State.Row.Line += line_offset;
500dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      State.Row.Address += addr_offset;
501dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      State.appendRowToMatrix(*offset_ptr);
502de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      // Reset discriminator to 0.
503de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      State.Row.Discriminator = 0;
504b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer    }
505b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer  }
506b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
507dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!State.Sequence.Empty) {
508dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    fprintf(stderr, "warning: last sequence in debug line table is not"
509dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                    "terminated!\n");
510dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
511dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
512dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  // Sort all sequences so that address lookup will work faster.
513dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (!Sequences.empty()) {
514dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    std::sort(Sequences.begin(), Sequences.end(), Sequence::orderByLowPC);
515dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // Note: actually, instruction address ranges of sequences should not
516dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // overlap (in shared objects and executables). If they do, the address
517dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // lookup would still work, though, but result would be ambiguous.
518dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // We don't report warning in this case. For example,
519dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // sometimes .so compiled from multiple object files contains a few
520dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // rudimentary sequences for address ranges [0x0, 0xsomething).
521dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  }
522b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
523b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer  return end_offset;
524b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer}
525b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer
5266948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainaruint32_t
5276948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga NainarDWARFDebugLine::LineTable::findRowInSeq(const DWARFDebugLine::Sequence &seq,
5286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar                                        uint64_t address) const {
5296948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (!seq.containsPC(address))
5306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return UnknownRowIndex;
5316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // Search for instruction address in the rows describing the sequence.
5326948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // Rows are stored in a vector, so we may use arithmetical operations with
5336948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  // iterators.
5346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  DWARFDebugLine::Row row;
5356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  row.Address = address;
5366948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  RowIter first_row = Rows.begin() + seq.FirstRowIndex;
5376948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  RowIter last_row = Rows.begin() + seq.LastRowIndex;
5386948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  LineTable::RowIter row_pos = std::lower_bound(
5396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      first_row, last_row, row, DWARFDebugLine::Row::orderByAddress);
5406948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (row_pos == last_row) {
5416948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return seq.LastRowIndex - 1;
5426948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
5436948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  uint32_t index = seq.FirstRowIndex + (row_pos - first_row);
5446948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  if (row_pos->Address > address) {
5456948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (row_pos == first_row)
5466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      return UnknownRowIndex;
5476948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    else
5486948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      index--;
5496948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  }
5506948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return index;
5516948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar}
5526948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
553dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesuint32_t DWARFDebugLine::LineTable::lookupAddress(uint64_t address) const {
554351f83be64057380877615153fe5dc50308ab017Alexey Samsonov  if (Sequences.empty())
5556948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    return UnknownRowIndex;
556351f83be64057380877615153fe5dc50308ab017Alexey Samsonov  // First, find an instruction sequence containing the given address.
557351f83be64057380877615153fe5dc50308ab017Alexey Samsonov  DWARFDebugLine::Sequence sequence;
558351f83be64057380877615153fe5dc50308ab017Alexey Samsonov  sequence.LowPC = address;
559351f83be64057380877615153fe5dc50308ab017Alexey Samsonov  SequenceIter first_seq = Sequences.begin();
560351f83be64057380877615153fe5dc50308ab017Alexey Samsonov  SequenceIter last_seq = Sequences.end();
561de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SequenceIter seq_pos = std::lower_bound(
562de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      first_seq, last_seq, sequence, DWARFDebugLine::Sequence::orderByLowPC);
563351f83be64057380877615153fe5dc50308ab017Alexey Samsonov  DWARFDebugLine::Sequence found_seq;
564351f83be64057380877615153fe5dc50308ab017Alexey Samsonov  if (seq_pos == last_seq) {
565351f83be64057380877615153fe5dc50308ab017Alexey Samsonov    found_seq = Sequences.back();
566351f83be64057380877615153fe5dc50308ab017Alexey Samsonov  } else if (seq_pos->LowPC == address) {
567351f83be64057380877615153fe5dc50308ab017Alexey Samsonov    found_seq = *seq_pos;
568351f83be64057380877615153fe5dc50308ab017Alexey Samsonov  } else {
569351f83be64057380877615153fe5dc50308ab017Alexey Samsonov    if (seq_pos == first_seq)
5706948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      return UnknownRowIndex;
571351f83be64057380877615153fe5dc50308ab017Alexey Samsonov    found_seq = *(seq_pos - 1);
572351f83be64057380877615153fe5dc50308ab017Alexey Samsonov  }
5736948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar  return findRowInSeq(found_seq, address);
574b848e976110a2c4f0a6a9e252115ba291c844fbeBenjamin Kramer}
57538a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov
576dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesbool DWARFDebugLine::LineTable::lookupAddressRange(
577dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    uint64_t address, uint64_t size, std::vector<uint32_t> &result) const {
578e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  if (Sequences.empty())
579e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor    return false;
580e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  uint64_t end_addr = address + size;
581e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  // First, find an instruction sequence containing the given address.
582e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  DWARFDebugLine::Sequence sequence;
583e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  sequence.LowPC = address;
584e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  SequenceIter first_seq = Sequences.begin();
585e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  SequenceIter last_seq = Sequences.end();
586de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar  SequenceIter seq_pos = std::lower_bound(
587de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar      first_seq, last_seq, sequence, DWARFDebugLine::Sequence::orderByLowPC);
588e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  if (seq_pos == last_seq || seq_pos->LowPC != address) {
589e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor    if (seq_pos == first_seq)
590e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor      return false;
591e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor    seq_pos--;
592e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  }
593e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  if (!seq_pos->containsPC(address))
594e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor    return false;
595e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor
596e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  SequenceIter start_pos = seq_pos;
597e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor
598e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  // Add the rows from the first sequence to the vector, starting with the
599e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  // index we just calculated
600e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor
601e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  while (seq_pos != last_seq && seq_pos->LowPC < end_addr) {
6026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    const DWARFDebugLine::Sequence &cur_seq = *seq_pos;
6036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    // For the first sequence, we need to find which row in the sequence is the
6046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    // first in our range.
6056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    uint32_t first_row_index = cur_seq.FirstRowIndex;
6066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (seq_pos == start_pos)
6076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar      first_row_index = findRowInSeq(cur_seq, address);
6086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
6096948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    // Figure out the last row in the range.
6106948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    uint32_t last_row_index = findRowInSeq(cur_seq, end_addr - 1);
6116948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    if (last_row_index == UnknownRowIndex)
612e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor      last_row_index = cur_seq.LastRowIndex - 1;
613e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor
6146948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    assert(first_row_index != UnknownRowIndex);
6156948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar    assert(last_row_index != UnknownRowIndex);
6166948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar
617e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor    for (uint32_t i = first_row_index; i <= last_row_index; ++i) {
618e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor      result.push_back(i);
619e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor    }
620e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor
621e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor    ++seq_pos;
622e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor  }
6238090a24bd6369662dfcd9d9df21b9c122238ed10NAKAMURA Takumi
6248090a24bd6369662dfcd9d9df21b9c122238ed10NAKAMURA Takumi  return true;
625e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor}
626e27a787760ea7c2899da3287002fe8ba316df0d0Andrew Kaylor
627de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarbool DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex,
628de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                                   const char *CompDir,
629de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                                   FileLineInfoKind Kind,
630de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar                                                   std::string &Result) const {
631dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (FileIndex == 0 || FileIndex > Prologue.FileNames.size() ||
632dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Kind == FileLineInfoKind::None)
63338a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov    return false;
63438a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  const FileNameEntry &Entry = Prologue.FileNames[FileIndex - 1];
63538a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  const char *FileName = Entry.Name;
636dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (Kind != FileLineInfoKind::AbsoluteFilePath ||
63738a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov      sys::path::is_absolute(FileName)) {
63838a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov    Result = FileName;
63938a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov    return true;
64038a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  }
64137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
64238a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  SmallString<16> FilePath;
64338a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  uint64_t IncludeDirIndex = Entry.DirIdx;
64437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const char *IncludeDir = "";
64538a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  // Be defensive about the contents of Entry.
64638a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  if (IncludeDirIndex > 0 &&
64737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      IncludeDirIndex <= Prologue.IncludeDirectories.size())
64837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    IncludeDir = Prologue.IncludeDirectories[IncludeDirIndex - 1];
64937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
65037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // We may still need to append compilation directory of compile unit.
65137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // We know that FileName is not absolute, the only way to have an
65237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // absolute path at this point would be if IncludeDir is absolute.
65337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (CompDir && Kind == FileLineInfoKind::AbsoluteFilePath &&
65437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines      sys::path::is_relative(IncludeDir))
65537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    sys::path::append(FilePath, CompDir);
65637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
65737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // sys::path::append skips empty strings.
65837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  sys::path::append(FilePath, IncludeDir, FileName);
65938a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  Result = FilePath.str();
66038a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov  return true;
66138a6381c0a58e013577b1957199128af9573fc20Alexey Samsonov}
66237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines
663de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainarbool DWARFDebugLine::LineTable::getFileLineInfoForAddress(
664de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    uint64_t Address, const char *CompDir, FileLineInfoKind Kind,
665de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar    DILineInfo &Result) const {
66637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Get the index of row we're looking for in the line table.
66737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  uint32_t RowIndex = lookupAddress(Address);
66837ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (RowIndex == -1U)
66937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return false;
67037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  // Take file number and line/column from the row.
67137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  const auto &Row = Rows[RowIndex];
67237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  if (!getFileNameByIndex(Row.File, CompDir, Kind, Result.FileName))
67337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines    return false;
67437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Result.Line = Row.Line;
67537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  Result.Column = Row.Column;
67637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines  return true;
67737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines}
678