blob: 77f3c00cc03fdde839493690e6b1cebdf73f79fe [file] [log] [blame]
Eugene Zelenkoe94042c2017-02-27 23:43:14 +00001//===- DWARFDebugLine.cpp -------------------------------------------------===//
Benjamin Kramer5acab502011-09-15 02:12:05 +00002//
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
Paul Robinson9d4eb692017-05-01 23:27:55 +000010#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
Eugene Zelenkoe94042c2017-02-27 23:43:14 +000011#include "llvm/ADT/SmallString.h"
George Rimarf8a96422017-04-21 09:12:18 +000012#include "llvm/DebugInfo/DWARF/DWARFContext.h"
Eugene Zelenkoe94042c2017-02-27 23:43:14 +000013#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
Benjamin Kramer5acab502011-09-15 02:12:05 +000014#include "llvm/Support/Dwarf.h"
15#include "llvm/Support/Format.h"
Alexey Samsonov45be7932012-08-30 07:49:50 +000016#include "llvm/Support/Path.h"
Benjamin Kramer5acab502011-09-15 02:12:05 +000017#include "llvm/Support/raw_ostream.h"
Benjamin Kramera57c46a2011-09-15 02:19:33 +000018#include <algorithm>
Eugene Zelenkoe94042c2017-02-27 23:43:14 +000019#include <cassert>
20#include <cinttypes>
21#include <cstdint>
22#include <cstdio>
23#include <utility>
24
Benjamin Kramer5acab502011-09-15 02:12:05 +000025using namespace llvm;
26using namespace dwarf;
Eugene Zelenkoe94042c2017-02-27 23:43:14 +000027
Alexey Samsonovdce67342014-05-15 21:24:32 +000028typedef DILineInfoSpecifier::FileLineInfoKind FileLineInfoKind;
Benjamin Kramer5acab502011-09-15 02:12:05 +000029
Dehao Chen1b54fce2016-04-28 22:09:37 +000030DWARFDebugLine::Prologue::Prologue() { clear(); }
Alexey Samsonov836b1ae2014-04-29 21:28:13 +000031
32void DWARFDebugLine::Prologue::clear() {
33 TotalLength = Version = PrologueLength = 0;
34 MinInstLength = MaxOpsPerInst = DefaultIsStmt = LineBase = LineRange = 0;
35 OpcodeBase = 0;
Ed Maste6d0bee52015-05-28 15:38:17 +000036 IsDWARF64 = false;
Alexey Samsonov836b1ae2014-04-29 21:28:13 +000037 StandardOpcodeLengths.clear();
38 IncludeDirectories.clear();
39 FileNames.clear();
40}
41
Benjamin Kramer5acab502011-09-15 02:12:05 +000042void DWARFDebugLine::Prologue::dump(raw_ostream &OS) const {
43 OS << "Line table prologue:\n"
Ed Maste6d0bee52015-05-28 15:38:17 +000044 << format(" total_length: 0x%8.8" PRIx64 "\n", TotalLength)
David Blaikie1d4736e2014-02-24 23:58:54 +000045 << format(" version: %u\n", Version)
Ed Maste6d0bee52015-05-28 15:38:17 +000046 << format(" prologue_length: 0x%8.8" PRIx64 "\n", PrologueLength)
David Blaikie1d4736e2014-02-24 23:58:54 +000047 << format(" min_inst_length: %u\n", MinInstLength)
48 << format(Version >= 4 ? "max_ops_per_inst: %u\n" : "", MaxOpsPerInst)
49 << format(" default_is_stmt: %u\n", DefaultIsStmt)
50 << format(" line_base: %i\n", LineBase)
51 << format(" line_range: %u\n", LineRange)
52 << format(" opcode_base: %u\n", OpcodeBase);
Benjamin Kramer5acab502011-09-15 02:12:05 +000053
Paul Robinson9d4eb692017-05-01 23:27:55 +000054 for (uint32_t I = 0; I != StandardOpcodeLengths.size(); ++I)
Mehdi Amini149f6ea2016-10-05 05:59:29 +000055 OS << format("standard_opcode_lengths[%s] = %u\n",
Paul Robinson9d4eb692017-05-01 23:27:55 +000056 LNStandardString(I + 1).data(), StandardOpcodeLengths[I]);
Benjamin Kramer5acab502011-09-15 02:12:05 +000057
58 if (!IncludeDirectories.empty())
Paul Robinson9d4eb692017-05-01 23:27:55 +000059 for (uint32_t I = 0; I != IncludeDirectories.size(); ++I)
60 OS << format("include_directories[%3u] = '", I + 1)
61 << IncludeDirectories[I] << "'\n";
Benjamin Kramer5acab502011-09-15 02:12:05 +000062
63 if (!FileNames.empty()) {
64 OS << " Dir Mod Time File Len File Name\n"
65 << " ---- ---------- ---------- -----------"
66 "----------------\n";
Paul Robinson9d4eb692017-05-01 23:27:55 +000067 for (uint32_t I = 0; I != FileNames.size(); ++I) {
68 const FileNameEntry &FileEntry = FileNames[I];
69 OS << format("file_names[%3u] %4" PRIu64 " ", I + 1, FileEntry.DirIdx)
70 << format("0x%8.8" PRIx64 " 0x%8.8" PRIx64 " ", FileEntry.ModTime,
71 FileEntry.Length)
72 << FileEntry.Name << '\n';
Benjamin Kramer5acab502011-09-15 02:12:05 +000073 }
74 }
75}
76
Paul Robinson9d4eb692017-05-01 23:27:55 +000077bool DWARFDebugLine::Prologue::parse(DataExtractor DebugLineData,
78 uint32_t *OffsetPtr) {
79 const uint64_t PrologueOffset = *OffsetPtr;
Alexey Samsonov836b1ae2014-04-29 21:28:13 +000080
81 clear();
Paul Robinson9d4eb692017-05-01 23:27:55 +000082 TotalLength = DebugLineData.getU32(OffsetPtr);
Ed Maste6d0bee52015-05-28 15:38:17 +000083 if (TotalLength == UINT32_MAX) {
84 IsDWARF64 = true;
Paul Robinson9d4eb692017-05-01 23:27:55 +000085 TotalLength = DebugLineData.getU64(OffsetPtr);
Ed Maste6d0bee52015-05-28 15:38:17 +000086 } else if (TotalLength > 0xffffff00) {
87 return false;
88 }
Paul Robinson9d4eb692017-05-01 23:27:55 +000089 Version = DebugLineData.getU16(OffsetPtr);
Alexey Samsonov836b1ae2014-04-29 21:28:13 +000090 if (Version < 2)
91 return false;
92
Paul Robinson9d4eb692017-05-01 23:27:55 +000093 PrologueLength = DebugLineData.getUnsigned(OffsetPtr, sizeofPrologueLength());
94 const uint64_t EndPrologueOffset = PrologueLength + *OffsetPtr;
95 MinInstLength = DebugLineData.getU8(OffsetPtr);
Alexey Samsonov836b1ae2014-04-29 21:28:13 +000096 if (Version >= 4)
Paul Robinson9d4eb692017-05-01 23:27:55 +000097 MaxOpsPerInst = DebugLineData.getU8(OffsetPtr);
98 DefaultIsStmt = DebugLineData.getU8(OffsetPtr);
99 LineBase = DebugLineData.getU8(OffsetPtr);
100 LineRange = DebugLineData.getU8(OffsetPtr);
101 OpcodeBase = DebugLineData.getU8(OffsetPtr);
Alexey Samsonov836b1ae2014-04-29 21:28:13 +0000102
103 StandardOpcodeLengths.reserve(OpcodeBase - 1);
Paul Robinson9d4eb692017-05-01 23:27:55 +0000104 for (uint32_t I = 1; I < OpcodeBase; ++I) {
105 uint8_t OpLen = DebugLineData.getU8(OffsetPtr);
106 StandardOpcodeLengths.push_back(OpLen);
Alexey Samsonov836b1ae2014-04-29 21:28:13 +0000107 }
108
Paul Robinson9d4eb692017-05-01 23:27:55 +0000109 while (*OffsetPtr < EndPrologueOffset) {
110 const char *S = DebugLineData.getCStr(OffsetPtr);
111 if (S && S[0])
112 IncludeDirectories.push_back(S);
Alexey Samsonov836b1ae2014-04-29 21:28:13 +0000113 else
114 break;
115 }
116
Paul Robinson9d4eb692017-05-01 23:27:55 +0000117 while (*OffsetPtr < EndPrologueOffset) {
118 const char *Name = DebugLineData.getCStr(OffsetPtr);
119 if (Name && Name[0]) {
120 FileNameEntry FileEntry;
121 FileEntry.Name = Name;
122 FileEntry.DirIdx = DebugLineData.getULEB128(OffsetPtr);
123 FileEntry.ModTime = DebugLineData.getULEB128(OffsetPtr);
124 FileEntry.Length = DebugLineData.getULEB128(OffsetPtr);
125 FileNames.push_back(FileEntry);
Alexey Samsonov836b1ae2014-04-29 21:28:13 +0000126 } else {
127 break;
128 }
129 }
130
Paul Robinson9d4eb692017-05-01 23:27:55 +0000131 if (*OffsetPtr != EndPrologueOffset) {
132 fprintf(stderr,
133 "warning: parsing line table prologue at 0x%8.8" PRIx64
134 " should have ended at 0x%8.8" PRIx64
135 " but it ended at 0x%8.8" PRIx64 "\n",
136 PrologueOffset, EndPrologueOffset, (uint64_t)*OffsetPtr);
Alexey Samsonov836b1ae2014-04-29 21:28:13 +0000137 return false;
138 }
139 return true;
140}
141
Paul Robinson9d4eb692017-05-01 23:27:55 +0000142DWARFDebugLine::Row::Row(bool DefaultIsStmt) { reset(DefaultIsStmt); }
Alexey Samsonov836b1ae2014-04-29 21:28:13 +0000143
Benjamin Kramer5acab502011-09-15 02:12:05 +0000144void DWARFDebugLine::Row::postAppend() {
145 BasicBlock = false;
146 PrologueEnd = false;
147 EpilogueBegin = false;
148}
149
Paul Robinson9d4eb692017-05-01 23:27:55 +0000150void DWARFDebugLine::Row::reset(bool DefaultIsStmt) {
Benjamin Kramer5acab502011-09-15 02:12:05 +0000151 Address = 0;
152 Line = 1;
153 Column = 0;
154 File = 1;
155 Isa = 0;
Diego Novillo5b5cf502014-02-14 19:27:53 +0000156 Discriminator = 0;
Paul Robinson9d4eb692017-05-01 23:27:55 +0000157 IsStmt = DefaultIsStmt;
Benjamin Kramer5acab502011-09-15 02:12:05 +0000158 BasicBlock = false;
159 EndSequence = false;
160 PrologueEnd = false;
161 EpilogueBegin = false;
162}
163
164void DWARFDebugLine::Row::dump(raw_ostream &OS) const {
Benjamin Kramerf3da5292011-11-05 08:57:40 +0000165 OS << format("0x%16.16" PRIx64 " %6u %6u", Address, Line, Column)
Diego Novillo5b5cf502014-02-14 19:27:53 +0000166 << format(" %6u %3u %13u ", File, Isa, Discriminator)
Dehao Chen1b54fce2016-04-28 22:09:37 +0000167 << (IsStmt ? " is_stmt" : "") << (BasicBlock ? " basic_block" : "")
Benjamin Kramer5acab502011-09-15 02:12:05 +0000168 << (PrologueEnd ? " prologue_end" : "")
169 << (EpilogueBegin ? " epilogue_begin" : "")
Dehao Chen1b54fce2016-04-28 22:09:37 +0000170 << (EndSequence ? " end_sequence" : "") << '\n';
Benjamin Kramer5acab502011-09-15 02:12:05 +0000171}
172
Dehao Chen1b54fce2016-04-28 22:09:37 +0000173DWARFDebugLine::Sequence::Sequence() { reset(); }
Alexey Samsonov836b1ae2014-04-29 21:28:13 +0000174
175void DWARFDebugLine::Sequence::reset() {
176 LowPC = 0;
177 HighPC = 0;
178 FirstRowIndex = 0;
179 LastRowIndex = 0;
180 Empty = true;
181}
182
Dehao Chen1b54fce2016-04-28 22:09:37 +0000183DWARFDebugLine::LineTable::LineTable() { clear(); }
Alexey Samsonov836b1ae2014-04-29 21:28:13 +0000184
Benjamin Kramer5acab502011-09-15 02:12:05 +0000185void DWARFDebugLine::LineTable::dump(raw_ostream &OS) const {
186 Prologue.dump(OS);
187 OS << '\n';
188
189 if (!Rows.empty()) {
Diego Novillo5b5cf502014-02-14 19:27:53 +0000190 OS << "Address Line Column File ISA Discriminator Flags\n"
191 << "------------------ ------ ------ ------ --- ------------- "
192 "-------------\n";
Alexey Samsonov1eabf982014-03-13 07:52:54 +0000193 for (const Row &R : Rows) {
194 R.dump(OS);
195 }
Benjamin Kramer5acab502011-09-15 02:12:05 +0000196 }
197}
198
Alexey Samsonov836b1ae2014-04-29 21:28:13 +0000199void DWARFDebugLine::LineTable::clear() {
200 Prologue.clear();
201 Rows.clear();
202 Sequences.clear();
203}
204
Alexey Samsonov110d5952014-04-30 00:09:19 +0000205DWARFDebugLine::ParsingState::ParsingState(struct LineTable *LT)
206 : LineTable(LT), RowNumber(0) {
207 resetRowAndSequence();
208}
Nick Lewycky4d044922011-09-15 03:41:51 +0000209
Alexey Samsonov110d5952014-04-30 00:09:19 +0000210void DWARFDebugLine::ParsingState::resetRowAndSequence() {
211 Row.reset(LineTable->Prologue.DefaultIsStmt);
212 Sequence.reset();
213}
214
Paul Robinson9d4eb692017-05-01 23:27:55 +0000215void DWARFDebugLine::ParsingState::appendRowToMatrix(uint32_t Offset) {
Alexey Samsonov110d5952014-04-30 00:09:19 +0000216 if (Sequence.Empty) {
Alexey Samsonov947228c2012-08-07 11:46:57 +0000217 // Record the beginning of instruction sequence.
Alexey Samsonov110d5952014-04-30 00:09:19 +0000218 Sequence.Empty = false;
219 Sequence.LowPC = Row.Address;
220 Sequence.FirstRowIndex = RowNumber;
Alexey Samsonov947228c2012-08-07 11:46:57 +0000221 }
Alexey Samsonov110d5952014-04-30 00:09:19 +0000222 ++RowNumber;
223 LineTable->appendRow(Row);
224 if (Row.EndSequence) {
Alexey Samsonov947228c2012-08-07 11:46:57 +0000225 // Record the end of instruction sequence.
Alexey Samsonov110d5952014-04-30 00:09:19 +0000226 Sequence.HighPC = Row.Address;
227 Sequence.LastRowIndex = RowNumber;
228 if (Sequence.isValid())
229 LineTable->appendSequence(Sequence);
230 Sequence.reset();
Alexey Samsonov947228c2012-08-07 11:46:57 +0000231 }
Alexey Samsonov110d5952014-04-30 00:09:19 +0000232 Row.postAppend();
Benjamin Kramer5acab502011-09-15 02:12:05 +0000233}
234
Benjamin Kramer5acab502011-09-15 02:12:05 +0000235const DWARFDebugLine::LineTable *
Paul Robinson9d4eb692017-05-01 23:27:55 +0000236DWARFDebugLine::getLineTable(uint32_t Offset) const {
237 LineTableConstIter Pos = LineTableMap.find(Offset);
238 if (Pos != LineTableMap.end())
239 return &Pos->second;
Craig Topper2617dcc2014-04-15 06:32:26 +0000240 return nullptr;
Benjamin Kramer5acab502011-09-15 02:12:05 +0000241}
242
Benjamin Kramer679e1752011-09-15 20:43:18 +0000243const DWARFDebugLine::LineTable *
Paul Robinson9d4eb692017-05-01 23:27:55 +0000244DWARFDebugLine::getOrParseLineTable(DataExtractor DebugLineData,
245 uint32_t Offset) {
246 std::pair<LineTableIter, bool> Pos =
247 LineTableMap.insert(LineTableMapTy::value_type(Offset, LineTable()));
248 LineTable *LT = &Pos.first->second;
249 if (Pos.second) {
250 if (!LT->parse(DebugLineData, RelocMap, &Offset))
Craig Topper2617dcc2014-04-15 06:32:26 +0000251 return nullptr;
Benjamin Kramer679e1752011-09-15 20:43:18 +0000252 }
Alexey Samsonov110d5952014-04-30 00:09:19 +0000253 return LT;
Benjamin Kramer679e1752011-09-15 20:43:18 +0000254}
255
Paul Robinson9d4eb692017-05-01 23:27:55 +0000256bool DWARFDebugLine::LineTable::parse(DataExtractor DebugLineData,
Alexey Samsonov110d5952014-04-30 00:09:19 +0000257 const RelocAddrMap *RMap,
Paul Robinson9d4eb692017-05-01 23:27:55 +0000258 uint32_t *OffsetPtr) {
259 const uint32_t DebugLineOffset = *OffsetPtr;
Benjamin Kramer5acab502011-09-15 02:12:05 +0000260
Alexey Samsonov110d5952014-04-30 00:09:19 +0000261 clear();
Benjamin Kramer5acab502011-09-15 02:12:05 +0000262
Paul Robinson9d4eb692017-05-01 23:27:55 +0000263 if (!Prologue.parse(DebugLineData, OffsetPtr)) {
Benjamin Kramer5acab502011-09-15 02:12:05 +0000264 // Restore our offset and return false to indicate failure!
Paul Robinson9d4eb692017-05-01 23:27:55 +0000265 *OffsetPtr = DebugLineOffset;
Benjamin Kramer5acab502011-09-15 02:12:05 +0000266 return false;
267 }
268
Paul Robinson9d4eb692017-05-01 23:27:55 +0000269 const uint32_t EndOffset =
270 DebugLineOffset + Prologue.TotalLength + Prologue.sizeofTotalLength();
Benjamin Kramer5acab502011-09-15 02:12:05 +0000271
Alexey Samsonov110d5952014-04-30 00:09:19 +0000272 ParsingState State(this);
Benjamin Kramer112ec172011-09-15 21:59:13 +0000273
Paul Robinson9d4eb692017-05-01 23:27:55 +0000274 while (*OffsetPtr < EndOffset) {
275 uint8_t Opcode = DebugLineData.getU8(OffsetPtr);
Benjamin Kramer5acab502011-09-15 02:12:05 +0000276
Paul Robinson9d4eb692017-05-01 23:27:55 +0000277 if (Opcode == 0) {
Benjamin Kramer5acab502011-09-15 02:12:05 +0000278 // Extended Opcodes always start with a zero opcode followed by
279 // a uleb128 length so you can skip ones you don't know about
Paul Robinson9d4eb692017-05-01 23:27:55 +0000280 uint32_t ExtOffset = *OffsetPtr;
281 uint64_t Len = DebugLineData.getULEB128(OffsetPtr);
282 uint32_t ArgSize = Len - (*OffsetPtr - ExtOffset);
Benjamin Kramer5acab502011-09-15 02:12:05 +0000283
Paul Robinson9d4eb692017-05-01 23:27:55 +0000284 uint8_t SubOpcode = DebugLineData.getU8(OffsetPtr);
285 switch (SubOpcode) {
Benjamin Kramer5acab502011-09-15 02:12:05 +0000286 case DW_LNE_end_sequence:
287 // Set the end_sequence register of the state machine to true and
288 // append a row to the matrix using the current values of the
289 // state-machine registers. Then reset the registers to the initial
290 // values specified above. Every statement program sequence must end
291 // with a DW_LNE_end_sequence instruction which creates a row whose
292 // address is that of the byte after the last target machine instruction
293 // of the sequence.
Alexey Samsonov110d5952014-04-30 00:09:19 +0000294 State.Row.EndSequence = true;
Paul Robinson9d4eb692017-05-01 23:27:55 +0000295 State.appendRowToMatrix(*OffsetPtr);
Alexey Samsonov110d5952014-04-30 00:09:19 +0000296 State.resetRowAndSequence();
Benjamin Kramer5acab502011-09-15 02:12:05 +0000297 break;
298
299 case DW_LNE_set_address:
300 // Takes a single relocatable address as an operand. The size of the
301 // operand is the size appropriate to hold an address on the target
302 // machine. Set the address register to the value given by the
303 // relocatable address. All of the other statement program opcodes
304 // that affect the address register add a delta to it. This instruction
305 // stores a relocatable value into it instead.
Paul Robinson9d4eb692017-05-01 23:27:55 +0000306 State.Row.Address = getRelocatedValue(
307 DebugLineData, DebugLineData.getAddressSize(), OffsetPtr, RMap);
Benjamin Kramer5acab502011-09-15 02:12:05 +0000308 break;
309
310 case DW_LNE_define_file:
311 // Takes 4 arguments. The first is a null terminated string containing
312 // a source file name. The second is an unsigned LEB128 number
313 // representing the directory index of the directory in which the file
314 // was found. The third is an unsigned LEB128 number representing the
315 // time of last modification of the file. The fourth is an unsigned
316 // LEB128 number representing the length in bytes of the file. The time
317 // and length fields may contain LEB128(0) if the information is not
318 // available.
319 //
320 // The directory index represents an entry in the include_directories
321 // section of the statement program prologue. The index is LEB128(0)
322 // if the file was found in the current directory of the compilation,
323 // LEB128(1) if it was found in the first directory in the
324 // include_directories section, and so on. The directory index is
325 // ignored for file names that represent full path names.
326 //
327 // The files are numbered, starting at 1, in the order in which they
328 // appear; the names in the prologue come before names defined by
329 // the DW_LNE_define_file instruction. These numbers are used in the
330 // the file register of the state machine.
331 {
Paul Robinson9d4eb692017-05-01 23:27:55 +0000332 FileNameEntry FileEntry;
333 FileEntry.Name = DebugLineData.getCStr(OffsetPtr);
334 FileEntry.DirIdx = DebugLineData.getULEB128(OffsetPtr);
335 FileEntry.ModTime = DebugLineData.getULEB128(OffsetPtr);
336 FileEntry.Length = DebugLineData.getULEB128(OffsetPtr);
337 Prologue.FileNames.push_back(FileEntry);
Benjamin Kramer5acab502011-09-15 02:12:05 +0000338 }
339 break;
340
Diego Novillo5b5cf502014-02-14 19:27:53 +0000341 case DW_LNE_set_discriminator:
Paul Robinson9d4eb692017-05-01 23:27:55 +0000342 State.Row.Discriminator = DebugLineData.getULEB128(OffsetPtr);
Diego Novillo5b5cf502014-02-14 19:27:53 +0000343 break;
344
Benjamin Kramer5acab502011-09-15 02:12:05 +0000345 default:
346 // Length doesn't include the zero opcode byte or the length itself, but
347 // it does include the sub_opcode, so we have to adjust for that below
Paul Robinson9d4eb692017-05-01 23:27:55 +0000348 (*OffsetPtr) += ArgSize;
Benjamin Kramer5acab502011-09-15 02:12:05 +0000349 break;
350 }
Paul Robinson9d4eb692017-05-01 23:27:55 +0000351 } else if (Opcode < Prologue.OpcodeBase) {
352 switch (Opcode) {
Benjamin Kramer5acab502011-09-15 02:12:05 +0000353 // Standard Opcodes
354 case DW_LNS_copy:
355 // Takes no arguments. Append a row to the matrix using the
356 // current values of the state-machine registers. Then set
357 // the basic_block register to false.
Paul Robinson9d4eb692017-05-01 23:27:55 +0000358 State.appendRowToMatrix(*OffsetPtr);
Benjamin Kramer5acab502011-09-15 02:12:05 +0000359 break;
360
361 case DW_LNS_advance_pc:
362 // Takes a single unsigned LEB128 operand, multiplies it by the
363 // min_inst_length field of the prologue, and adds the
364 // result to the address register of the state machine.
Alexey Samsonov110d5952014-04-30 00:09:19 +0000365 State.Row.Address +=
Paul Robinson9d4eb692017-05-01 23:27:55 +0000366 DebugLineData.getULEB128(OffsetPtr) * Prologue.MinInstLength;
Benjamin Kramer5acab502011-09-15 02:12:05 +0000367 break;
368
369 case DW_LNS_advance_line:
370 // Takes a single signed LEB128 operand and adds that value to
371 // the line register of the state machine.
Paul Robinson9d4eb692017-05-01 23:27:55 +0000372 State.Row.Line += DebugLineData.getSLEB128(OffsetPtr);
Benjamin Kramer5acab502011-09-15 02:12:05 +0000373 break;
374
375 case DW_LNS_set_file:
376 // Takes a single unsigned LEB128 operand and stores it in the file
377 // register of the state machine.
Paul Robinson9d4eb692017-05-01 23:27:55 +0000378 State.Row.File = DebugLineData.getULEB128(OffsetPtr);
Benjamin Kramer5acab502011-09-15 02:12:05 +0000379 break;
380
381 case DW_LNS_set_column:
382 // Takes a single unsigned LEB128 operand and stores it in the
383 // column register of the state machine.
Paul Robinson9d4eb692017-05-01 23:27:55 +0000384 State.Row.Column = DebugLineData.getULEB128(OffsetPtr);
Benjamin Kramer5acab502011-09-15 02:12:05 +0000385 break;
386
387 case DW_LNS_negate_stmt:
388 // Takes no arguments. Set the is_stmt register of the state
389 // machine to the logical negation of its current value.
Alexey Samsonov110d5952014-04-30 00:09:19 +0000390 State.Row.IsStmt = !State.Row.IsStmt;
Benjamin Kramer5acab502011-09-15 02:12:05 +0000391 break;
392
393 case DW_LNS_set_basic_block:
394 // Takes no arguments. Set the basic_block register of the
395 // state machine to true
Alexey Samsonov110d5952014-04-30 00:09:19 +0000396 State.Row.BasicBlock = true;
Benjamin Kramer5acab502011-09-15 02:12:05 +0000397 break;
398
399 case DW_LNS_const_add_pc:
400 // Takes no arguments. Add to the address register of the state
401 // machine the address increment value corresponding to special
402 // opcode 255. The motivation for DW_LNS_const_add_pc is this:
403 // when the statement program needs to advance the address by a
404 // small amount, it can use a single special opcode, which occupies
405 // a single byte. When it needs to advance the address by up to
406 // twice the range of the last special opcode, it can use
407 // DW_LNS_const_add_pc followed by a special opcode, for a total
408 // of two bytes. Only if it needs to advance the address by more
409 // than twice that range will it need to use both DW_LNS_advance_pc
410 // and a special opcode, requiring three or more bytes.
411 {
Paul Robinson9d4eb692017-05-01 23:27:55 +0000412 uint8_t AdjustOpcode = 255 - Prologue.OpcodeBase;
413 uint64_t AddrOffset =
414 (AdjustOpcode / Prologue.LineRange) * Prologue.MinInstLength;
415 State.Row.Address += AddrOffset;
Benjamin Kramer5acab502011-09-15 02:12:05 +0000416 }
417 break;
418
419 case DW_LNS_fixed_advance_pc:
420 // Takes a single uhalf operand. Add to the address register of
421 // the state machine the value of the (unencoded) operand. This
422 // is the only extended opcode that takes an argument that is not
423 // a variable length number. The motivation for DW_LNS_fixed_advance_pc
424 // is this: existing assemblers cannot emit DW_LNS_advance_pc or
425 // special opcodes because they cannot encode LEB128 numbers or
426 // judge when the computation of a special opcode overflows and
427 // requires the use of DW_LNS_advance_pc. Such assemblers, however,
428 // can use DW_LNS_fixed_advance_pc instead, sacrificing compression.
Paul Robinson9d4eb692017-05-01 23:27:55 +0000429 State.Row.Address += DebugLineData.getU16(OffsetPtr);
Benjamin Kramer5acab502011-09-15 02:12:05 +0000430 break;
431
432 case DW_LNS_set_prologue_end:
433 // Takes no arguments. Set the prologue_end register of the
434 // state machine to true
Alexey Samsonov110d5952014-04-30 00:09:19 +0000435 State.Row.PrologueEnd = true;
Benjamin Kramer5acab502011-09-15 02:12:05 +0000436 break;
437
438 case DW_LNS_set_epilogue_begin:
439 // Takes no arguments. Set the basic_block register of the
440 // state machine to true
Alexey Samsonov110d5952014-04-30 00:09:19 +0000441 State.Row.EpilogueBegin = true;
Benjamin Kramer5acab502011-09-15 02:12:05 +0000442 break;
443
444 case DW_LNS_set_isa:
445 // Takes a single unsigned LEB128 operand and stores it in the
446 // column register of the state machine.
Paul Robinson9d4eb692017-05-01 23:27:55 +0000447 State.Row.Isa = DebugLineData.getULEB128(OffsetPtr);
Benjamin Kramer5acab502011-09-15 02:12:05 +0000448 break;
449
450 default:
451 // Handle any unknown standard opcodes here. We know the lengths
452 // of such opcodes because they are specified in the prologue
453 // as a multiple of LEB128 operands for each opcode.
454 {
Paul Robinson9d4eb692017-05-01 23:27:55 +0000455 assert(Opcode - 1U < Prologue.StandardOpcodeLengths.size());
456 uint8_t OpcodeLength = Prologue.StandardOpcodeLengths[Opcode - 1];
457 for (uint8_t I = 0; I < OpcodeLength; ++I)
458 DebugLineData.getULEB128(OffsetPtr);
Benjamin Kramer5acab502011-09-15 02:12:05 +0000459 }
460 break;
461 }
462 } else {
463 // Special Opcodes
464
465 // A special opcode value is chosen based on the amount that needs
466 // to be added to the line and address registers. The maximum line
467 // increment for a special opcode is the value of the line_base
468 // field in the header, plus the value of the line_range field,
469 // minus 1 (line base + line range - 1). If the desired line
470 // increment is greater than the maximum line increment, a standard
NAKAMURA Takumif9959852011-10-08 11:22:47 +0000471 // opcode must be used instead of a special opcode. The "address
472 // advance" is calculated by dividing the desired address increment
Benjamin Kramer5acab502011-09-15 02:12:05 +0000473 // by the minimum_instruction_length field from the header. The
474 // special opcode is then calculated using the following formula:
475 //
476 // opcode = (desired line increment - line_base) +
477 // (line_range * address advance) + opcode_base
478 //
479 // If the resulting opcode is greater than 255, a standard opcode
480 // must be used instead.
481 //
482 // To decode a special opcode, subtract the opcode_base from the
483 // opcode itself to give the adjusted opcode. The amount to
484 // increment the address register is the result of the adjusted
485 // opcode divided by the line_range multiplied by the
486 // minimum_instruction_length field from the header. That is:
487 //
488 // address increment = (adjusted opcode / line_range) *
489 // minimum_instruction_length
490 //
491 // The amount to increment the line register is the line_base plus
492 // the result of the adjusted opcode modulo the line_range. That is:
493 //
494 // line increment = line_base + (adjusted opcode % line_range)
495
Paul Robinson9d4eb692017-05-01 23:27:55 +0000496 uint8_t AdjustOpcode = Opcode - Prologue.OpcodeBase;
497 uint64_t AddrOffset =
498 (AdjustOpcode / Prologue.LineRange) * Prologue.MinInstLength;
499 int32_t LineOffset =
500 Prologue.LineBase + (AdjustOpcode % Prologue.LineRange);
501 State.Row.Line += LineOffset;
502 State.Row.Address += AddrOffset;
503 State.appendRowToMatrix(*OffsetPtr);
Dehao Chen1b54fce2016-04-28 22:09:37 +0000504 // Reset discriminator to 0.
505 State.Row.Discriminator = 0;
Benjamin Kramer5acab502011-09-15 02:12:05 +0000506 }
507 }
508
Alexey Samsonov110d5952014-04-30 00:09:19 +0000509 if (!State.Sequence.Empty) {
510 fprintf(stderr, "warning: last sequence in debug line table is not"
511 "terminated!\n");
512 }
513
514 // Sort all sequences so that address lookup will work faster.
515 if (!Sequences.empty()) {
516 std::sort(Sequences.begin(), Sequences.end(), Sequence::orderByLowPC);
517 // Note: actually, instruction address ranges of sequences should not
518 // overlap (in shared objects and executables). If they do, the address
519 // lookup would still work, though, but result would be ambiguous.
520 // We don't report warning in this case. For example,
521 // sometimes .so compiled from multiple object files contains a few
522 // rudimentary sequences for address ranges [0x0, 0xsomething).
523 }
Benjamin Kramer5acab502011-09-15 02:12:05 +0000524
Paul Robinson9d4eb692017-05-01 23:27:55 +0000525 return EndOffset;
Benjamin Kramer5acab502011-09-15 02:12:05 +0000526}
527
Keno Fischerc2c60182015-05-31 23:37:04 +0000528uint32_t
Paul Robinson9d4eb692017-05-01 23:27:55 +0000529DWARFDebugLine::LineTable::findRowInSeq(const DWARFDebugLine::Sequence &Seq,
530 uint64_t Address) const {
531 if (!Seq.containsPC(Address))
Keno Fischerc2c60182015-05-31 23:37:04 +0000532 return UnknownRowIndex;
533 // Search for instruction address in the rows describing the sequence.
534 // Rows are stored in a vector, so we may use arithmetical operations with
535 // iterators.
Paul Robinson9d4eb692017-05-01 23:27:55 +0000536 DWARFDebugLine::Row Row;
537 Row.Address = Address;
538 RowIter FirstRow = Rows.begin() + Seq.FirstRowIndex;
539 RowIter LastRow = Rows.begin() + Seq.LastRowIndex;
540 LineTable::RowIter RowPos = std::lower_bound(
541 FirstRow, LastRow, Row, DWARFDebugLine::Row::orderByAddress);
542 if (RowPos == LastRow) {
543 return Seq.LastRowIndex - 1;
Keno Fischerc2c60182015-05-31 23:37:04 +0000544 }
Paul Robinson9d4eb692017-05-01 23:27:55 +0000545 uint32_t Index = Seq.FirstRowIndex + (RowPos - FirstRow);
546 if (RowPos->Address > Address) {
547 if (RowPos == FirstRow)
Keno Fischerc2c60182015-05-31 23:37:04 +0000548 return UnknownRowIndex;
549 else
Paul Robinson9d4eb692017-05-01 23:27:55 +0000550 Index--;
Keno Fischerc2c60182015-05-31 23:37:04 +0000551 }
Paul Robinson9d4eb692017-05-01 23:27:55 +0000552 return Index;
Keno Fischerc2c60182015-05-31 23:37:04 +0000553}
554
Paul Robinson9d4eb692017-05-01 23:27:55 +0000555uint32_t DWARFDebugLine::LineTable::lookupAddress(uint64_t Address) const {
Alexey Samsonov947228c2012-08-07 11:46:57 +0000556 if (Sequences.empty())
Keno Fischerc2c60182015-05-31 23:37:04 +0000557 return UnknownRowIndex;
Alexey Samsonov947228c2012-08-07 11:46:57 +0000558 // First, find an instruction sequence containing the given address.
Paul Robinson9d4eb692017-05-01 23:27:55 +0000559 DWARFDebugLine::Sequence Sequence;
560 Sequence.LowPC = Address;
561 SequenceIter FirstSeq = Sequences.begin();
562 SequenceIter LastSeq = Sequences.end();
563 SequenceIter SeqPos = std::lower_bound(
564 FirstSeq, LastSeq, Sequence, DWARFDebugLine::Sequence::orderByLowPC);
565 DWARFDebugLine::Sequence FoundSeq;
566 if (SeqPos == LastSeq) {
567 FoundSeq = Sequences.back();
568 } else if (SeqPos->LowPC == Address) {
569 FoundSeq = *SeqPos;
Alexey Samsonov947228c2012-08-07 11:46:57 +0000570 } else {
Paul Robinson9d4eb692017-05-01 23:27:55 +0000571 if (SeqPos == FirstSeq)
Keno Fischerc2c60182015-05-31 23:37:04 +0000572 return UnknownRowIndex;
Paul Robinson9d4eb692017-05-01 23:27:55 +0000573 FoundSeq = *(SeqPos - 1);
Benjamin Kramer5acab502011-09-15 02:12:05 +0000574 }
Paul Robinson9d4eb692017-05-01 23:27:55 +0000575 return findRowInSeq(FoundSeq, Address);
Benjamin Kramer5acab502011-09-15 02:12:05 +0000576}
Alexey Samsonov45be7932012-08-30 07:49:50 +0000577
Alexey Samsonov836b1ae2014-04-29 21:28:13 +0000578bool DWARFDebugLine::LineTable::lookupAddressRange(
Paul Robinson9d4eb692017-05-01 23:27:55 +0000579 uint64_t Address, uint64_t Size, std::vector<uint32_t> &Result) const {
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000580 if (Sequences.empty())
581 return false;
Paul Robinson9d4eb692017-05-01 23:27:55 +0000582 uint64_t EndAddr = Address + Size;
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000583 // First, find an instruction sequence containing the given address.
Paul Robinson9d4eb692017-05-01 23:27:55 +0000584 DWARFDebugLine::Sequence Sequence;
585 Sequence.LowPC = Address;
586 SequenceIter FirstSeq = Sequences.begin();
587 SequenceIter LastSeq = Sequences.end();
588 SequenceIter SeqPos = std::lower_bound(
589 FirstSeq, LastSeq, Sequence, DWARFDebugLine::Sequence::orderByLowPC);
590 if (SeqPos == LastSeq || SeqPos->LowPC != Address) {
591 if (SeqPos == FirstSeq)
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000592 return false;
Paul Robinson9d4eb692017-05-01 23:27:55 +0000593 SeqPos--;
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000594 }
Paul Robinson9d4eb692017-05-01 23:27:55 +0000595 if (!SeqPos->containsPC(Address))
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000596 return false;
597
Paul Robinson9d4eb692017-05-01 23:27:55 +0000598 SequenceIter StartPos = SeqPos;
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000599
600 // Add the rows from the first sequence to the vector, starting with the
601 // index we just calculated
602
Paul Robinson9d4eb692017-05-01 23:27:55 +0000603 while (SeqPos != LastSeq && SeqPos->LowPC < EndAddr) {
604 const DWARFDebugLine::Sequence &CurSeq = *SeqPos;
Keno Fischerc2c60182015-05-31 23:37:04 +0000605 // For the first sequence, we need to find which row in the sequence is the
606 // first in our range.
Paul Robinson9d4eb692017-05-01 23:27:55 +0000607 uint32_t FirstRowIndex = CurSeq.FirstRowIndex;
608 if (SeqPos == StartPos)
609 FirstRowIndex = findRowInSeq(CurSeq, Address);
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000610
Keno Fischerc2c60182015-05-31 23:37:04 +0000611 // Figure out the last row in the range.
Paul Robinson9d4eb692017-05-01 23:27:55 +0000612 uint32_t LastRowIndex = findRowInSeq(CurSeq, EndAddr - 1);
613 if (LastRowIndex == UnknownRowIndex)
614 LastRowIndex = CurSeq.LastRowIndex - 1;
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000615
Paul Robinson9d4eb692017-05-01 23:27:55 +0000616 assert(FirstRowIndex != UnknownRowIndex);
617 assert(LastRowIndex != UnknownRowIndex);
Keno Fischerc2c60182015-05-31 23:37:04 +0000618
Paul Robinson9d4eb692017-05-01 23:27:55 +0000619 for (uint32_t I = FirstRowIndex; I <= LastRowIndex; ++I) {
620 Result.push_back(I);
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000621 }
622
Paul Robinson9d4eb692017-05-01 23:27:55 +0000623 ++SeqPos;
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000624 }
NAKAMURA Takumi4b86cdb2013-01-26 01:45:06 +0000625
626 return true;
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000627}
628
Paul Robinson9d4eb692017-05-01 23:27:55 +0000629bool DWARFDebugLine::LineTable::hasFileAtIndex(uint64_t FileIndex) const {
Pete Cooperb2ba7762016-07-22 01:41:32 +0000630 return FileIndex != 0 && FileIndex <= Prologue.FileNames.size();
631}
632
Paul Robinson9d4eb692017-05-01 23:27:55 +0000633bool DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex,
634 const char *CompDir,
635 FileLineInfoKind Kind,
636 std::string &Result) const {
Pete Cooperb2ba7762016-07-22 01:41:32 +0000637 if (Kind == FileLineInfoKind::None || !hasFileAtIndex(FileIndex))
Alexey Samsonov45be7932012-08-30 07:49:50 +0000638 return false;
639 const FileNameEntry &Entry = Prologue.FileNames[FileIndex - 1];
640 const char *FileName = Entry.Name;
Alexey Samsonovdce67342014-05-15 21:24:32 +0000641 if (Kind != FileLineInfoKind::AbsoluteFilePath ||
Alexey Samsonov45be7932012-08-30 07:49:50 +0000642 sys::path::is_absolute(FileName)) {
643 Result = FileName;
644 return true;
645 }
Frederic Riss101b5e22014-09-19 15:11:51 +0000646
Alexey Samsonov45be7932012-08-30 07:49:50 +0000647 SmallString<16> FilePath;
648 uint64_t IncludeDirIndex = Entry.DirIdx;
Frederic Riss101b5e22014-09-19 15:11:51 +0000649 const char *IncludeDir = "";
Alexey Samsonov45be7932012-08-30 07:49:50 +0000650 // Be defensive about the contents of Entry.
651 if (IncludeDirIndex > 0 &&
Frederic Riss101b5e22014-09-19 15:11:51 +0000652 IncludeDirIndex <= Prologue.IncludeDirectories.size())
653 IncludeDir = Prologue.IncludeDirectories[IncludeDirIndex - 1];
654
655 // We may still need to append compilation directory of compile unit.
656 // We know that FileName is not absolute, the only way to have an
657 // absolute path at this point would be if IncludeDir is absolute.
658 if (CompDir && Kind == FileLineInfoKind::AbsoluteFilePath &&
659 sys::path::is_relative(IncludeDir))
660 sys::path::append(FilePath, CompDir);
661
662 // sys::path::append skips empty strings.
663 sys::path::append(FilePath, IncludeDir, FileName);
Alexey Samsonov45be7932012-08-30 07:49:50 +0000664 Result = FilePath.str();
665 return true;
666}
Frederic Riss101b5e22014-09-19 15:11:51 +0000667
Dehao Chen1b54fce2016-04-28 22:09:37 +0000668bool DWARFDebugLine::LineTable::getFileLineInfoForAddress(
669 uint64_t Address, const char *CompDir, FileLineInfoKind Kind,
670 DILineInfo &Result) const {
Frederic Riss101b5e22014-09-19 15:11:51 +0000671 // Get the index of row we're looking for in the line table.
672 uint32_t RowIndex = lookupAddress(Address);
673 if (RowIndex == -1U)
674 return false;
675 // Take file number and line/column from the row.
676 const auto &Row = Rows[RowIndex];
677 if (!getFileNameByIndex(Row.File, CompDir, Kind, Result.FileName))
678 return false;
679 Result.Line = Row.Line;
680 Result.Column = Row.Column;
Eric Christopherba1024c2016-12-14 18:29:39 +0000681 Result.Discriminator = Row.Discriminator;
Frederic Riss101b5e22014-09-19 15:11:51 +0000682 return true;
683}