blob: 1ed632b5e0b82082ce80c5a9e2548c370bd9301b [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"
Scott Linder16c7bda2018-02-23 23:01:06 +000011#include "llvm/ADT/Optional.h"
Eugene Zelenkoe94042c2017-02-27 23:43:14 +000012#include "llvm/ADT/SmallString.h"
Eugene Zelenko2db0cfa2017-06-23 21:57:40 +000013#include "llvm/ADT/SmallVector.h"
14#include "llvm/ADT/StringRef.h"
Zachary Turner264b5d92017-06-07 03:48:56 +000015#include "llvm/BinaryFormat/Dwarf.h"
Paul Robinson2bc38732017-05-02 21:40:47 +000016#include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
Eugene Zelenkoe94042c2017-02-27 23:43:14 +000017#include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
Benjamin Kramer5acab502011-09-15 02:12:05 +000018#include "llvm/Support/Format.h"
Alexey Samsonov45be7932012-08-30 07:49:50 +000019#include "llvm/Support/Path.h"
Jonas Devlieghere84e99262018-04-14 22:07:23 +000020#include "llvm/Support/WithColor.h"
Benjamin Kramer5acab502011-09-15 02:12:05 +000021#include "llvm/Support/raw_ostream.h"
Benjamin Kramera57c46a2011-09-15 02:19:33 +000022#include <algorithm>
Eugene Zelenkoe94042c2017-02-27 23:43:14 +000023#include <cassert>
24#include <cinttypes>
25#include <cstdint>
26#include <cstdio>
27#include <utility>
28
Benjamin Kramer5acab502011-09-15 02:12:05 +000029using namespace llvm;
30using namespace dwarf;
Eugene Zelenkoe94042c2017-02-27 23:43:14 +000031
Eugene Zelenko2db0cfa2017-06-23 21:57:40 +000032using FileLineInfoKind = DILineInfoSpecifier::FileLineInfoKind;
33
Paul Robinson2bc38732017-05-02 21:40:47 +000034namespace {
Eugene Zelenko2db0cfa2017-06-23 21:57:40 +000035
Paul Robinson2bc38732017-05-02 21:40:47 +000036struct ContentDescriptor {
37 dwarf::LineNumberEntryFormat Type;
38 dwarf::Form Form;
39};
Eugene Zelenko2db0cfa2017-06-23 21:57:40 +000040
41using ContentDescriptors = SmallVector<ContentDescriptor, 4>;
42
Paul Robinson2bc38732017-05-02 21:40:47 +000043} // end anonmyous namespace
Benjamin Kramer5acab502011-09-15 02:12:05 +000044
Scott Linder16c7bda2018-02-23 23:01:06 +000045void DWARFDebugLine::ContentTypeTracker::trackContentType(
46 dwarf::LineNumberEntryFormat ContentType) {
47 switch (ContentType) {
48 case dwarf::DW_LNCT_timestamp:
49 HasModTime = true;
50 break;
51 case dwarf::DW_LNCT_size:
52 HasLength = true;
53 break;
54 case dwarf::DW_LNCT_MD5:
55 HasMD5 = true;
56 break;
57 case dwarf::DW_LNCT_LLVM_source:
58 HasSource = true;
59 break;
60 default:
61 // We only care about values we consider optional, and new values may be
62 // added in the vendor extension range, so we do not match exhaustively.
63 break;
64 }
65}
66
Dehao Chen1b54fce2016-04-28 22:09:37 +000067DWARFDebugLine::Prologue::Prologue() { clear(); }
Alexey Samsonov836b1ae2014-04-29 21:28:13 +000068
69void DWARFDebugLine::Prologue::clear() {
Paul Robinson75c068c2017-06-26 18:43:01 +000070 TotalLength = PrologueLength = 0;
71 SegSelectorSize = 0;
Alexey Samsonov836b1ae2014-04-29 21:28:13 +000072 MinInstLength = MaxOpsPerInst = DefaultIsStmt = LineBase = LineRange = 0;
73 OpcodeBase = 0;
Pavel Labath322711f2018-03-14 09:39:54 +000074 FormParams = dwarf::FormParams({0, 0, DWARF32});
Scott Linder16c7bda2018-02-23 23:01:06 +000075 ContentTypes = ContentTypeTracker();
Alexey Samsonov836b1ae2014-04-29 21:28:13 +000076 StandardOpcodeLengths.clear();
77 IncludeDirectories.clear();
78 FileNames.clear();
79}
80
Paul Robinson0a227092018-02-05 20:43:15 +000081void DWARFDebugLine::Prologue::dump(raw_ostream &OS,
82 DIDumpOptions DumpOptions) const {
Benjamin Kramer5acab502011-09-15 02:12:05 +000083 OS << "Line table prologue:\n"
Ed Maste6d0bee52015-05-28 15:38:17 +000084 << format(" total_length: 0x%8.8" PRIx64 "\n", TotalLength)
Paul Robinson75c068c2017-06-26 18:43:01 +000085 << format(" version: %u\n", getVersion());
86 if (getVersion() >= 5)
87 OS << format(" address_size: %u\n", getAddressSize())
88 << format(" seg_select_size: %u\n", SegSelectorSize);
89 OS << format(" prologue_length: 0x%8.8" PRIx64 "\n", PrologueLength)
David Blaikie1d4736e2014-02-24 23:58:54 +000090 << format(" min_inst_length: %u\n", MinInstLength)
Paul Robinson75c068c2017-06-26 18:43:01 +000091 << format(getVersion() >= 4 ? "max_ops_per_inst: %u\n" : "", MaxOpsPerInst)
David Blaikie1d4736e2014-02-24 23:58:54 +000092 << format(" default_is_stmt: %u\n", DefaultIsStmt)
93 << format(" line_base: %i\n", LineBase)
94 << format(" line_range: %u\n", LineRange)
95 << format(" opcode_base: %u\n", OpcodeBase);
Benjamin Kramer5acab502011-09-15 02:12:05 +000096
Paul Robinson9d4eb692017-05-01 23:27:55 +000097 for (uint32_t I = 0; I != StandardOpcodeLengths.size(); ++I)
Mehdi Amini149f6ea2016-10-05 05:59:29 +000098 OS << format("standard_opcode_lengths[%s] = %u\n",
Paul Robinson9d4eb692017-05-01 23:27:55 +000099 LNStandardString(I + 1).data(), StandardOpcodeLengths[I]);
Benjamin Kramer5acab502011-09-15 02:12:05 +0000100
Paul Robinson8181d232018-01-18 20:33:35 +0000101 if (!IncludeDirectories.empty()) {
102 // DWARF v5 starts directory indexes at 0.
103 uint32_t DirBase = getVersion() >= 5 ? 0 : 1;
Paul Robinson0a227092018-02-05 20:43:15 +0000104 for (uint32_t I = 0; I != IncludeDirectories.size(); ++I) {
105 OS << format("include_directories[%3u] = ", I + DirBase);
106 IncludeDirectories[I].dump(OS, DumpOptions);
107 OS << '\n';
108 }
Paul Robinson8181d232018-01-18 20:33:35 +0000109 }
Benjamin Kramer5acab502011-09-15 02:12:05 +0000110
111 if (!FileNames.empty()) {
Paul Robinsonceafcd42018-02-08 23:08:02 +0000112 // DWARF v5 starts file indexes at 0.
113 uint32_t FileBase = getVersion() >= 5 ? 0 : 1;
Paul Robinson9d4eb692017-05-01 23:27:55 +0000114 for (uint32_t I = 0; I != FileNames.size(); ++I) {
115 const FileNameEntry &FileEntry = FileNames[I];
Scott Linder16c7bda2018-02-23 23:01:06 +0000116 OS << format("file_names[%3u]:\n", I + FileBase);
117 OS << " name: ";
Paul Robinson0a227092018-02-05 20:43:15 +0000118 FileEntry.Name.dump(OS, DumpOptions);
Scott Linder16c7bda2018-02-23 23:01:06 +0000119 OS << '\n'
120 << format(" dir_index: %" PRIu64 "\n", FileEntry.DirIdx);
121 if (ContentTypes.HasMD5)
122 OS << " md5_checksum: " << FileEntry.Checksum.digest() << '\n';
123 if (ContentTypes.HasModTime)
124 OS << format(" mod_time: 0x%8.8" PRIx64 "\n", FileEntry.ModTime);
125 if (ContentTypes.HasLength)
126 OS << format(" length: 0x%8.8" PRIx64 "\n", FileEntry.Length);
127 if (ContentTypes.HasSource) {
128 OS << " source: ";
129 FileEntry.Source.dump(OS, DumpOptions);
130 OS << '\n';
131 }
Benjamin Kramer5acab502011-09-15 02:12:05 +0000132 }
133 }
134}
135
Paul Robinson2bc38732017-05-02 21:40:47 +0000136// Parse v2-v4 directory and file tables.
137static void
Paul Robinson17536b92017-06-29 16:52:08 +0000138parseV2DirFileTables(const DWARFDataExtractor &DebugLineData,
139 uint32_t *OffsetPtr, uint64_t EndPrologueOffset,
Scott Linder16c7bda2018-02-23 23:01:06 +0000140 DWARFDebugLine::ContentTypeTracker &ContentTypes,
Paul Robinson0a227092018-02-05 20:43:15 +0000141 std::vector<DWARFFormValue> &IncludeDirectories,
Paul Robinson2bc38732017-05-02 21:40:47 +0000142 std::vector<DWARFDebugLine::FileNameEntry> &FileNames) {
143 while (*OffsetPtr < EndPrologueOffset) {
144 StringRef S = DebugLineData.getCStrRef(OffsetPtr);
145 if (S.empty())
146 break;
Paul Robinson0a227092018-02-05 20:43:15 +0000147 DWARFFormValue Dir(dwarf::DW_FORM_string);
148 Dir.setPValue(S.data());
149 IncludeDirectories.push_back(Dir);
Paul Robinson2bc38732017-05-02 21:40:47 +0000150 }
151
152 while (*OffsetPtr < EndPrologueOffset) {
153 StringRef Name = DebugLineData.getCStrRef(OffsetPtr);
154 if (Name.empty())
155 break;
156 DWARFDebugLine::FileNameEntry FileEntry;
Paul Robinson0a227092018-02-05 20:43:15 +0000157 FileEntry.Name.setForm(dwarf::DW_FORM_string);
158 FileEntry.Name.setPValue(Name.data());
Paul Robinson2bc38732017-05-02 21:40:47 +0000159 FileEntry.DirIdx = DebugLineData.getULEB128(OffsetPtr);
160 FileEntry.ModTime = DebugLineData.getULEB128(OffsetPtr);
161 FileEntry.Length = DebugLineData.getULEB128(OffsetPtr);
162 FileNames.push_back(FileEntry);
163 }
Scott Linder16c7bda2018-02-23 23:01:06 +0000164
165 ContentTypes.HasModTime = true;
166 ContentTypes.HasLength = true;
Paul Robinson2bc38732017-05-02 21:40:47 +0000167}
168
169// Parse v5 directory/file entry content descriptions.
170// Returns the descriptors, or an empty vector if we did not find a path or
171// ran off the end of the prologue.
172static ContentDescriptors
Scott Linder16c7bda2018-02-23 23:01:06 +0000173parseV5EntryFormat(const DWARFDataExtractor &DebugLineData, uint32_t
174 *OffsetPtr, uint64_t EndPrologueOffset, DWARFDebugLine::ContentTypeTracker
175 *ContentTypes) {
Paul Robinson2bc38732017-05-02 21:40:47 +0000176 ContentDescriptors Descriptors;
177 int FormatCount = DebugLineData.getU8(OffsetPtr);
178 bool HasPath = false;
179 for (int I = 0; I != FormatCount; ++I) {
180 if (*OffsetPtr >= EndPrologueOffset)
181 return ContentDescriptors();
182 ContentDescriptor Descriptor;
183 Descriptor.Type =
184 dwarf::LineNumberEntryFormat(DebugLineData.getULEB128(OffsetPtr));
185 Descriptor.Form = dwarf::Form(DebugLineData.getULEB128(OffsetPtr));
186 if (Descriptor.Type == dwarf::DW_LNCT_path)
187 HasPath = true;
Scott Linder16c7bda2018-02-23 23:01:06 +0000188 if (ContentTypes)
189 ContentTypes->trackContentType(Descriptor.Type);
Paul Robinson2bc38732017-05-02 21:40:47 +0000190 Descriptors.push_back(Descriptor);
191 }
192 return HasPath ? Descriptors : ContentDescriptors();
193}
194
195static bool
Paul Robinson17536b92017-06-29 16:52:08 +0000196parseV5DirFileTables(const DWARFDataExtractor &DebugLineData,
197 uint32_t *OffsetPtr, uint64_t EndPrologueOffset,
Pavel Labath322711f2018-03-14 09:39:54 +0000198 const dwarf::FormParams &FormParams,
199 const DWARFContext &Ctx, const DWARFUnit *U,
Scott Linder16c7bda2018-02-23 23:01:06 +0000200 DWARFDebugLine::ContentTypeTracker &ContentTypes,
Paul Robinson0a227092018-02-05 20:43:15 +0000201 std::vector<DWARFFormValue> &IncludeDirectories,
Paul Robinson2bc38732017-05-02 21:40:47 +0000202 std::vector<DWARFDebugLine::FileNameEntry> &FileNames) {
203 // Get the directory entry description.
204 ContentDescriptors DirDescriptors =
Paul Robinsona06f8dc2017-12-18 19:08:35 +0000205 parseV5EntryFormat(DebugLineData, OffsetPtr, EndPrologueOffset, nullptr);
Paul Robinson2bc38732017-05-02 21:40:47 +0000206 if (DirDescriptors.empty())
207 return false;
208
209 // Get the directory entries, according to the format described above.
210 int DirEntryCount = DebugLineData.getU8(OffsetPtr);
211 for (int I = 0; I != DirEntryCount; ++I) {
212 if (*OffsetPtr >= EndPrologueOffset)
213 return false;
214 for (auto Descriptor : DirDescriptors) {
215 DWARFFormValue Value(Descriptor.Form);
216 switch (Descriptor.Type) {
217 case DW_LNCT_path:
Paul Robinsonbf750c82018-01-29 20:57:43 +0000218 if (!Value.extractValue(DebugLineData, OffsetPtr, FormParams, &Ctx, U))
Paul Robinson2bc38732017-05-02 21:40:47 +0000219 return false;
Paul Robinson0a227092018-02-05 20:43:15 +0000220 IncludeDirectories.push_back(Value);
Paul Robinson2bc38732017-05-02 21:40:47 +0000221 break;
222 default:
Paul Robinson75c068c2017-06-26 18:43:01 +0000223 if (!Value.skipValue(DebugLineData, OffsetPtr, FormParams))
Paul Robinson2bc38732017-05-02 21:40:47 +0000224 return false;
225 }
226 }
227 }
228
229 // Get the file entry description.
230 ContentDescriptors FileDescriptors =
Scott Linder16c7bda2018-02-23 23:01:06 +0000231 parseV5EntryFormat(DebugLineData, OffsetPtr, EndPrologueOffset,
232 &ContentTypes);
Paul Robinson2bc38732017-05-02 21:40:47 +0000233 if (FileDescriptors.empty())
234 return false;
235
236 // Get the file entries, according to the format described above.
237 int FileEntryCount = DebugLineData.getU8(OffsetPtr);
238 for (int I = 0; I != FileEntryCount; ++I) {
239 if (*OffsetPtr >= EndPrologueOffset)
240 return false;
241 DWARFDebugLine::FileNameEntry FileEntry;
242 for (auto Descriptor : FileDescriptors) {
243 DWARFFormValue Value(Descriptor.Form);
Paul Robinsonbf750c82018-01-29 20:57:43 +0000244 if (!Value.extractValue(DebugLineData, OffsetPtr, FormParams, &Ctx, U))
Paul Robinson2bc38732017-05-02 21:40:47 +0000245 return false;
246 switch (Descriptor.Type) {
247 case DW_LNCT_path:
Paul Robinson0a227092018-02-05 20:43:15 +0000248 FileEntry.Name = Value;
Paul Robinson2bc38732017-05-02 21:40:47 +0000249 break;
Scott Linder16c7bda2018-02-23 23:01:06 +0000250 case DW_LNCT_LLVM_source:
251 FileEntry.Source = Value;
252 break;
Paul Robinson2bc38732017-05-02 21:40:47 +0000253 case DW_LNCT_directory_index:
254 FileEntry.DirIdx = Value.getAsUnsignedConstant().getValue();
255 break;
256 case DW_LNCT_timestamp:
257 FileEntry.ModTime = Value.getAsUnsignedConstant().getValue();
258 break;
259 case DW_LNCT_size:
260 FileEntry.Length = Value.getAsUnsignedConstant().getValue();
261 break;
Paul Robinsona06f8dc2017-12-18 19:08:35 +0000262 case DW_LNCT_MD5:
263 assert(Value.getAsBlock().getValue().size() == 16);
264 std::uninitialized_copy_n(Value.getAsBlock().getValue().begin(), 16,
265 FileEntry.Checksum.Bytes.begin());
266 break;
Paul Robinson2bc38732017-05-02 21:40:47 +0000267 default:
268 break;
269 }
270 }
271 FileNames.push_back(FileEntry);
272 }
273 return true;
274}
275
James Hendersona3acf992018-05-10 10:51:33 +0000276template <typename... Ts>
277static std::string formatErrorString(char const *Fmt, const Ts &... Vals) {
278 std::string Buffer;
279 raw_string_ostream Stream(Buffer);
280 Stream << format(Fmt, Vals...);
281 return Stream.str();
282}
283
284template <typename... Ts>
285static Error createError(char const *Fmt, const Ts &... Vals) {
286 return make_error<StringError>(formatErrorString(Fmt, Vals...),
287 inconvertibleErrorCode());
288}
289
290Error DWARFDebugLine::Prologue::parse(const DWARFDataExtractor &DebugLineData,
291 uint32_t *OffsetPtr,
292 const DWARFContext &Ctx,
293 const DWARFUnit *U) {
Paul Robinson9d4eb692017-05-01 23:27:55 +0000294 const uint64_t PrologueOffset = *OffsetPtr;
Alexey Samsonov836b1ae2014-04-29 21:28:13 +0000295
296 clear();
Paul Robinson9d4eb692017-05-01 23:27:55 +0000297 TotalLength = DebugLineData.getU32(OffsetPtr);
Ed Maste6d0bee52015-05-28 15:38:17 +0000298 if (TotalLength == UINT32_MAX) {
Paul Robinson75c068c2017-06-26 18:43:01 +0000299 FormParams.Format = dwarf::DWARF64;
Paul Robinson9d4eb692017-05-01 23:27:55 +0000300 TotalLength = DebugLineData.getU64(OffsetPtr);
Paul Robinson75c068c2017-06-26 18:43:01 +0000301 } else if (TotalLength >= 0xffffff00) {
James Hendersona3acf992018-05-10 10:51:33 +0000302 return createError(
303 "parsing line table prologue at offset 0x%8.8" PRIx64
304 " unsupported reserved unit length found of value 0x%8.8" PRIx64,
305 PrologueOffset, TotalLength);
Ed Maste6d0bee52015-05-28 15:38:17 +0000306 }
Paul Robinson75c068c2017-06-26 18:43:01 +0000307 FormParams.Version = DebugLineData.getU16(OffsetPtr);
308 if (getVersion() < 2)
James Hendersona3acf992018-05-10 10:51:33 +0000309 return createError("parsing line table prologue at offset 0x%8.8" PRIx64
310 " found unsupported version 0x%2.2" PRIx16,
311 PrologueOffset, getVersion());
Alexey Samsonov836b1ae2014-04-29 21:28:13 +0000312
Paul Robinson75c068c2017-06-26 18:43:01 +0000313 if (getVersion() >= 5) {
314 FormParams.AddrSize = DebugLineData.getU8(OffsetPtr);
Paul Robinson63811a42017-11-22 15:33:17 +0000315 assert((DebugLineData.getAddressSize() == 0 ||
316 DebugLineData.getAddressSize() == getAddressSize()) &&
Paul Robinson75c068c2017-06-26 18:43:01 +0000317 "Line table header and data extractor disagree");
Paul Robinson2bc38732017-05-02 21:40:47 +0000318 SegSelectorSize = DebugLineData.getU8(OffsetPtr);
319 }
320
Paul Robinson9d4eb692017-05-01 23:27:55 +0000321 PrologueLength = DebugLineData.getUnsigned(OffsetPtr, sizeofPrologueLength());
322 const uint64_t EndPrologueOffset = PrologueLength + *OffsetPtr;
323 MinInstLength = DebugLineData.getU8(OffsetPtr);
Paul Robinson75c068c2017-06-26 18:43:01 +0000324 if (getVersion() >= 4)
Paul Robinson9d4eb692017-05-01 23:27:55 +0000325 MaxOpsPerInst = DebugLineData.getU8(OffsetPtr);
326 DefaultIsStmt = DebugLineData.getU8(OffsetPtr);
327 LineBase = DebugLineData.getU8(OffsetPtr);
328 LineRange = DebugLineData.getU8(OffsetPtr);
329 OpcodeBase = DebugLineData.getU8(OffsetPtr);
Alexey Samsonov836b1ae2014-04-29 21:28:13 +0000330
331 StandardOpcodeLengths.reserve(OpcodeBase - 1);
Paul Robinson9d4eb692017-05-01 23:27:55 +0000332 for (uint32_t I = 1; I < OpcodeBase; ++I) {
333 uint8_t OpLen = DebugLineData.getU8(OffsetPtr);
334 StandardOpcodeLengths.push_back(OpLen);
Alexey Samsonov836b1ae2014-04-29 21:28:13 +0000335 }
336
Paul Robinson75c068c2017-06-26 18:43:01 +0000337 if (getVersion() >= 5) {
Paul Robinson2bc38732017-05-02 21:40:47 +0000338 if (!parseV5DirFileTables(DebugLineData, OffsetPtr, EndPrologueOffset,
Scott Linder16c7bda2018-02-23 23:01:06 +0000339 FormParams, Ctx, U, ContentTypes,
340 IncludeDirectories, FileNames)) {
James Hendersona3acf992018-05-10 10:51:33 +0000341 return createError(
Jonas Devlieghere84e99262018-04-14 22:07:23 +0000342 "parsing line table prologue at 0x%8.8" PRIx64
343 " found an invalid directory or file table description at"
James Hendersona3acf992018-05-10 10:51:33 +0000344 " 0x%8.8" PRIx64,
Jonas Devlieghere84e99262018-04-14 22:07:23 +0000345 PrologueOffset, (uint64_t)*OffsetPtr);
Paul Robinson2bc38732017-05-02 21:40:47 +0000346 }
347 } else
348 parseV2DirFileTables(DebugLineData, OffsetPtr, EndPrologueOffset,
Scott Linder16c7bda2018-02-23 23:01:06 +0000349 ContentTypes, IncludeDirectories, FileNames);
Alexey Samsonov836b1ae2014-04-29 21:28:13 +0000350
James Hendersona3acf992018-05-10 10:51:33 +0000351 if (*OffsetPtr != EndPrologueOffset)
352 return createError("parsing line table prologue at 0x%8.8" PRIx64
353 " should have ended at 0x%8.8" PRIx64
354 " but it ended at 0x%8.8" PRIx64,
355 PrologueOffset, EndPrologueOffset, (uint64_t)*OffsetPtr);
356 return Error::success();
Alexey Samsonov836b1ae2014-04-29 21:28:13 +0000357}
358
Paul Robinson9d4eb692017-05-01 23:27:55 +0000359DWARFDebugLine::Row::Row(bool DefaultIsStmt) { reset(DefaultIsStmt); }
Alexey Samsonov836b1ae2014-04-29 21:28:13 +0000360
Benjamin Kramer5acab502011-09-15 02:12:05 +0000361void DWARFDebugLine::Row::postAppend() {
362 BasicBlock = false;
363 PrologueEnd = false;
364 EpilogueBegin = false;
365}
366
Paul Robinson9d4eb692017-05-01 23:27:55 +0000367void DWARFDebugLine::Row::reset(bool DefaultIsStmt) {
Benjamin Kramer5acab502011-09-15 02:12:05 +0000368 Address = 0;
369 Line = 1;
370 Column = 0;
371 File = 1;
372 Isa = 0;
Diego Novillo5b5cf502014-02-14 19:27:53 +0000373 Discriminator = 0;
Paul Robinson9d4eb692017-05-01 23:27:55 +0000374 IsStmt = DefaultIsStmt;
Benjamin Kramer5acab502011-09-15 02:12:05 +0000375 BasicBlock = false;
376 EndSequence = false;
377 PrologueEnd = false;
378 EpilogueBegin = false;
379}
380
Greg Clayton67070462017-05-02 22:48:52 +0000381void DWARFDebugLine::Row::dumpTableHeader(raw_ostream &OS) {
382 OS << "Address Line Column File ISA Discriminator Flags\n"
383 << "------------------ ------ ------ ------ --- ------------- "
384 "-------------\n";
385}
386
Benjamin Kramer5acab502011-09-15 02:12:05 +0000387void DWARFDebugLine::Row::dump(raw_ostream &OS) const {
Benjamin Kramerf3da5292011-11-05 08:57:40 +0000388 OS << format("0x%16.16" PRIx64 " %6u %6u", Address, Line, Column)
Diego Novillo5b5cf502014-02-14 19:27:53 +0000389 << format(" %6u %3u %13u ", File, Isa, Discriminator)
Dehao Chen1b54fce2016-04-28 22:09:37 +0000390 << (IsStmt ? " is_stmt" : "") << (BasicBlock ? " basic_block" : "")
Benjamin Kramer5acab502011-09-15 02:12:05 +0000391 << (PrologueEnd ? " prologue_end" : "")
392 << (EpilogueBegin ? " epilogue_begin" : "")
Dehao Chen1b54fce2016-04-28 22:09:37 +0000393 << (EndSequence ? " end_sequence" : "") << '\n';
Benjamin Kramer5acab502011-09-15 02:12:05 +0000394}
395
Dehao Chen1b54fce2016-04-28 22:09:37 +0000396DWARFDebugLine::Sequence::Sequence() { reset(); }
Alexey Samsonov836b1ae2014-04-29 21:28:13 +0000397
398void DWARFDebugLine::Sequence::reset() {
399 LowPC = 0;
400 HighPC = 0;
401 FirstRowIndex = 0;
402 LastRowIndex = 0;
403 Empty = true;
404}
405
Dehao Chen1b54fce2016-04-28 22:09:37 +0000406DWARFDebugLine::LineTable::LineTable() { clear(); }
Alexey Samsonov836b1ae2014-04-29 21:28:13 +0000407
Paul Robinson0a227092018-02-05 20:43:15 +0000408void DWARFDebugLine::LineTable::dump(raw_ostream &OS,
409 DIDumpOptions DumpOptions) const {
410 Prologue.dump(OS, DumpOptions);
Benjamin Kramer5acab502011-09-15 02:12:05 +0000411 OS << '\n';
412
413 if (!Rows.empty()) {
Greg Clayton67070462017-05-02 22:48:52 +0000414 Row::dumpTableHeader(OS);
Alexey Samsonov1eabf982014-03-13 07:52:54 +0000415 for (const Row &R : Rows) {
416 R.dump(OS);
417 }
Benjamin Kramer5acab502011-09-15 02:12:05 +0000418 }
419}
420
Alexey Samsonov836b1ae2014-04-29 21:28:13 +0000421void DWARFDebugLine::LineTable::clear() {
422 Prologue.clear();
423 Rows.clear();
424 Sequences.clear();
425}
426
Alexey Samsonov110d5952014-04-30 00:09:19 +0000427DWARFDebugLine::ParsingState::ParsingState(struct LineTable *LT)
Eugene Zelenko2db0cfa2017-06-23 21:57:40 +0000428 : LineTable(LT) {
Alexey Samsonov110d5952014-04-30 00:09:19 +0000429 resetRowAndSequence();
430}
Nick Lewycky4d044922011-09-15 03:41:51 +0000431
Alexey Samsonov110d5952014-04-30 00:09:19 +0000432void DWARFDebugLine::ParsingState::resetRowAndSequence() {
433 Row.reset(LineTable->Prologue.DefaultIsStmt);
434 Sequence.reset();
435}
436
Paul Robinson9d4eb692017-05-01 23:27:55 +0000437void DWARFDebugLine::ParsingState::appendRowToMatrix(uint32_t Offset) {
Alexey Samsonov110d5952014-04-30 00:09:19 +0000438 if (Sequence.Empty) {
Alexey Samsonov947228c2012-08-07 11:46:57 +0000439 // Record the beginning of instruction sequence.
Alexey Samsonov110d5952014-04-30 00:09:19 +0000440 Sequence.Empty = false;
441 Sequence.LowPC = Row.Address;
442 Sequence.FirstRowIndex = RowNumber;
Alexey Samsonov947228c2012-08-07 11:46:57 +0000443 }
Alexey Samsonov110d5952014-04-30 00:09:19 +0000444 ++RowNumber;
445 LineTable->appendRow(Row);
446 if (Row.EndSequence) {
Alexey Samsonov947228c2012-08-07 11:46:57 +0000447 // Record the end of instruction sequence.
Alexey Samsonov110d5952014-04-30 00:09:19 +0000448 Sequence.HighPC = Row.Address;
449 Sequence.LastRowIndex = RowNumber;
450 if (Sequence.isValid())
451 LineTable->appendSequence(Sequence);
452 Sequence.reset();
Alexey Samsonov947228c2012-08-07 11:46:57 +0000453 }
Alexey Samsonov110d5952014-04-30 00:09:19 +0000454 Row.postAppend();
Benjamin Kramer5acab502011-09-15 02:12:05 +0000455}
456
Benjamin Kramer5acab502011-09-15 02:12:05 +0000457const DWARFDebugLine::LineTable *
Paul Robinson9d4eb692017-05-01 23:27:55 +0000458DWARFDebugLine::getLineTable(uint32_t Offset) const {
459 LineTableConstIter Pos = LineTableMap.find(Offset);
460 if (Pos != LineTableMap.end())
461 return &Pos->second;
Craig Topper2617dcc2014-04-15 06:32:26 +0000462 return nullptr;
Benjamin Kramer5acab502011-09-15 02:12:05 +0000463}
464
James Hendersona3acf992018-05-10 10:51:33 +0000465Expected<const DWARFDebugLine::LineTable *> DWARFDebugLine::getOrParseLineTable(
466 DWARFDataExtractor &DebugLineData, uint32_t Offset, const DWARFContext &Ctx,
467 const DWARFUnit *U, std::function<void(StringRef)> WarnCallback) {
James Henderson66702622018-03-08 10:53:34 +0000468 if (!DebugLineData.isValidOffset(Offset))
James Henderson11a9de72018-05-10 12:15:43 +0000469 return createError("offset 0x%8.8" PRIx32
James Hendersona3acf992018-05-10 10:51:33 +0000470 " is not a valid debug line section offset",
471 Offset);
James Henderson66702622018-03-08 10:53:34 +0000472
Paul Robinson9d4eb692017-05-01 23:27:55 +0000473 std::pair<LineTableIter, bool> Pos =
474 LineTableMap.insert(LineTableMapTy::value_type(Offset, LineTable()));
475 LineTable *LT = &Pos.first->second;
476 if (Pos.second) {
James Hendersona3acf992018-05-10 10:51:33 +0000477 if (Error Err = LT->parse(DebugLineData, &Offset, Ctx, U, WarnCallback))
478 return std::move(Err);
479 return LT;
Benjamin Kramer679e1752011-09-15 20:43:18 +0000480 }
Alexey Samsonov110d5952014-04-30 00:09:19 +0000481 return LT;
Benjamin Kramer679e1752011-09-15 20:43:18 +0000482}
483
James Hendersona3acf992018-05-10 10:51:33 +0000484Error DWARFDebugLine::LineTable::parse(
485 DWARFDataExtractor &DebugLineData, uint32_t *OffsetPtr,
486 const DWARFContext &Ctx, const DWARFUnit *U,
487 std::function<void(StringRef)> WarnCallback, raw_ostream *OS) {
Paul Robinson9d4eb692017-05-01 23:27:55 +0000488 const uint32_t DebugLineOffset = *OffsetPtr;
Benjamin Kramer5acab502011-09-15 02:12:05 +0000489
Alexey Samsonov110d5952014-04-30 00:09:19 +0000490 clear();
Benjamin Kramer5acab502011-09-15 02:12:05 +0000491
James Hendersona3acf992018-05-10 10:51:33 +0000492 Error PrologueErr = Prologue.parse(DebugLineData, OffsetPtr, Ctx, U);
Benjamin Kramer5acab502011-09-15 02:12:05 +0000493
Paul Robinson0a227092018-02-05 20:43:15 +0000494 if (OS) {
495 // The presence of OS signals verbose dumping.
496 DIDumpOptions DumpOptions;
497 DumpOptions.Verbose = true;
498 Prologue.dump(*OS, DumpOptions);
499 }
Jonas Devlieghere26f9a0c2017-09-21 20:15:30 +0000500
James Hendersona3acf992018-05-10 10:51:33 +0000501 if (PrologueErr)
502 return PrologueErr;
503
Paul Robinson9d4eb692017-05-01 23:27:55 +0000504 const uint32_t EndOffset =
505 DebugLineOffset + Prologue.TotalLength + Prologue.sizeofTotalLength();
Benjamin Kramer5acab502011-09-15 02:12:05 +0000506
Paul Robinson511b54c2017-11-22 15:48:30 +0000507 // See if we should tell the data extractor the address size.
508 if (DebugLineData.getAddressSize() == 0)
509 DebugLineData.setAddressSize(Prologue.getAddressSize());
510 else
511 assert(Prologue.getAddressSize() == 0 ||
512 Prologue.getAddressSize() == DebugLineData.getAddressSize());
513
Alexey Samsonov110d5952014-04-30 00:09:19 +0000514 ParsingState State(this);
Benjamin Kramer112ec172011-09-15 21:59:13 +0000515
Paul Robinson9d4eb692017-05-01 23:27:55 +0000516 while (*OffsetPtr < EndOffset) {
Jonas Devlieghere26f9a0c2017-09-21 20:15:30 +0000517 if (OS)
518 *OS << format("0x%08.08" PRIx32 ": ", *OffsetPtr);
519
Paul Robinson9d4eb692017-05-01 23:27:55 +0000520 uint8_t Opcode = DebugLineData.getU8(OffsetPtr);
Benjamin Kramer5acab502011-09-15 02:12:05 +0000521
Jonas Devlieghere26f9a0c2017-09-21 20:15:30 +0000522 if (OS)
523 *OS << format("%02.02" PRIx8 " ", Opcode);
524
Paul Robinson9d4eb692017-05-01 23:27:55 +0000525 if (Opcode == 0) {
Benjamin Kramer5acab502011-09-15 02:12:05 +0000526 // Extended Opcodes always start with a zero opcode followed by
527 // a uleb128 length so you can skip ones you don't know about
Paul Robinson9d4eb692017-05-01 23:27:55 +0000528 uint64_t Len = DebugLineData.getULEB128(OffsetPtr);
Paul Robinsone0833342017-11-22 15:14:49 +0000529 uint32_t ExtOffset = *OffsetPtr;
530
531 // Tolerate zero-length; assume length is correct and soldier on.
532 if (Len == 0) {
533 if (OS)
534 *OS << "Badly formed extended line op (length 0)\n";
535 continue;
536 }
Benjamin Kramer5acab502011-09-15 02:12:05 +0000537
Paul Robinson9d4eb692017-05-01 23:27:55 +0000538 uint8_t SubOpcode = DebugLineData.getU8(OffsetPtr);
Jonas Devlieghere26f9a0c2017-09-21 20:15:30 +0000539 if (OS)
540 *OS << LNExtendedString(SubOpcode);
Paul Robinson9d4eb692017-05-01 23:27:55 +0000541 switch (SubOpcode) {
Benjamin Kramer5acab502011-09-15 02:12:05 +0000542 case DW_LNE_end_sequence:
543 // Set the end_sequence register of the state machine to true and
544 // append a row to the matrix using the current values of the
545 // state-machine registers. Then reset the registers to the initial
546 // values specified above. Every statement program sequence must end
547 // with a DW_LNE_end_sequence instruction which creates a row whose
548 // address is that of the byte after the last target machine instruction
549 // of the sequence.
Alexey Samsonov110d5952014-04-30 00:09:19 +0000550 State.Row.EndSequence = true;
Paul Robinson9d4eb692017-05-01 23:27:55 +0000551 State.appendRowToMatrix(*OffsetPtr);
Jonas Devlieghere26f9a0c2017-09-21 20:15:30 +0000552 if (OS) {
553 *OS << "\n";
554 OS->indent(12);
555 State.Row.dump(*OS);
556 }
Alexey Samsonov110d5952014-04-30 00:09:19 +0000557 State.resetRowAndSequence();
Benjamin Kramer5acab502011-09-15 02:12:05 +0000558 break;
559
560 case DW_LNE_set_address:
561 // Takes a single relocatable address as an operand. The size of the
562 // operand is the size appropriate to hold an address on the target
563 // machine. Set the address register to the value given by the
564 // relocatable address. All of the other statement program opcodes
565 // that affect the address register add a delta to it. This instruction
566 // stores a relocatable value into it instead.
Paul Robinson511b54c2017-11-22 15:48:30 +0000567 //
568 // Make sure the extractor knows the address size. If not, infer it
569 // from the size of the operand.
570 if (DebugLineData.getAddressSize() == 0)
571 DebugLineData.setAddressSize(Len - 1);
Paul Robinson79474682018-03-22 19:37:56 +0000572 else if (DebugLineData.getAddressSize() != Len - 1) {
James Hendersona3acf992018-05-10 10:51:33 +0000573 return createError("mismatching address size at offset 0x%8.8" PRIx32
574 " expected 0x%2.2" PRIx8 " found 0x%2.2" PRIx64,
575 ExtOffset, DebugLineData.getAddressSize(),
576 Len - 1);
Paul Robinson79474682018-03-22 19:37:56 +0000577 }
Paul Robinson17536b92017-06-29 16:52:08 +0000578 State.Row.Address = DebugLineData.getRelocatedAddress(OffsetPtr);
Jonas Devlieghere26f9a0c2017-09-21 20:15:30 +0000579 if (OS)
580 *OS << format(" (0x%16.16" PRIx64 ")", State.Row.Address);
Benjamin Kramer5acab502011-09-15 02:12:05 +0000581 break;
582
583 case DW_LNE_define_file:
584 // Takes 4 arguments. The first is a null terminated string containing
585 // a source file name. The second is an unsigned LEB128 number
586 // representing the directory index of the directory in which the file
587 // was found. The third is an unsigned LEB128 number representing the
588 // time of last modification of the file. The fourth is an unsigned
589 // LEB128 number representing the length in bytes of the file. The time
590 // and length fields may contain LEB128(0) if the information is not
591 // available.
592 //
593 // The directory index represents an entry in the include_directories
594 // section of the statement program prologue. The index is LEB128(0)
595 // if the file was found in the current directory of the compilation,
596 // LEB128(1) if it was found in the first directory in the
597 // include_directories section, and so on. The directory index is
598 // ignored for file names that represent full path names.
599 //
600 // The files are numbered, starting at 1, in the order in which they
601 // appear; the names in the prologue come before names defined by
602 // the DW_LNE_define_file instruction. These numbers are used in the
603 // the file register of the state machine.
604 {
Paul Robinson9d4eb692017-05-01 23:27:55 +0000605 FileNameEntry FileEntry;
Paul Robinson0a227092018-02-05 20:43:15 +0000606 const char *Name = DebugLineData.getCStr(OffsetPtr);
607 FileEntry.Name.setForm(dwarf::DW_FORM_string);
608 FileEntry.Name.setPValue(Name);
Paul Robinson9d4eb692017-05-01 23:27:55 +0000609 FileEntry.DirIdx = DebugLineData.getULEB128(OffsetPtr);
610 FileEntry.ModTime = DebugLineData.getULEB128(OffsetPtr);
611 FileEntry.Length = DebugLineData.getULEB128(OffsetPtr);
612 Prologue.FileNames.push_back(FileEntry);
Jonas Devlieghere26f9a0c2017-09-21 20:15:30 +0000613 if (OS)
Paul Robinson0a227092018-02-05 20:43:15 +0000614 *OS << " (" << Name << ", dir=" << FileEntry.DirIdx << ", mod_time="
Jonas Devlieghere26f9a0c2017-09-21 20:15:30 +0000615 << format("(0x%16.16" PRIx64 ")", FileEntry.ModTime)
616 << ", length=" << FileEntry.Length << ")";
Benjamin Kramer5acab502011-09-15 02:12:05 +0000617 }
618 break;
619
Diego Novillo5b5cf502014-02-14 19:27:53 +0000620 case DW_LNE_set_discriminator:
Paul Robinson9d4eb692017-05-01 23:27:55 +0000621 State.Row.Discriminator = DebugLineData.getULEB128(OffsetPtr);
Jonas Devlieghere26f9a0c2017-09-21 20:15:30 +0000622 if (OS)
623 *OS << " (" << State.Row.Discriminator << ")";
Diego Novillo5b5cf502014-02-14 19:27:53 +0000624 break;
625
Benjamin Kramer5acab502011-09-15 02:12:05 +0000626 default:
Paul Robinsone0833342017-11-22 15:14:49 +0000627 if (OS)
628 *OS << format("Unrecognized extended op 0x%02.02" PRIx8, SubOpcode)
629 << format(" length %" PRIx64, Len);
630 // Len doesn't include the zero opcode byte or the length itself, but
631 // it does include the sub_opcode, so we have to adjust for that.
632 (*OffsetPtr) += Len - 1;
Benjamin Kramer5acab502011-09-15 02:12:05 +0000633 break;
634 }
Paul Robinsone0833342017-11-22 15:14:49 +0000635 // Make sure the stated and parsed lengths are the same.
636 // Otherwise we have an unparseable line-number program.
James Hendersona3acf992018-05-10 10:51:33 +0000637 if (*OffsetPtr - ExtOffset != Len)
638 return createError("unexpected line op length at offset 0x%8.8" PRIx32
639 " expected 0x%2.2" PRIx64 " found 0x%2.2" PRIx32,
640 ExtOffset, Len, *OffsetPtr - ExtOffset);
Paul Robinson9d4eb692017-05-01 23:27:55 +0000641 } else if (Opcode < Prologue.OpcodeBase) {
Jonas Devlieghere26f9a0c2017-09-21 20:15:30 +0000642 if (OS)
643 *OS << LNStandardString(Opcode);
Paul Robinson9d4eb692017-05-01 23:27:55 +0000644 switch (Opcode) {
Benjamin Kramer5acab502011-09-15 02:12:05 +0000645 // Standard Opcodes
646 case DW_LNS_copy:
647 // Takes no arguments. Append a row to the matrix using the
648 // current values of the state-machine registers. Then set
649 // the basic_block register to false.
Paul Robinson9d4eb692017-05-01 23:27:55 +0000650 State.appendRowToMatrix(*OffsetPtr);
Jonas Devlieghere26f9a0c2017-09-21 20:15:30 +0000651 if (OS) {
652 *OS << "\n";
653 OS->indent(12);
654 State.Row.dump(*OS);
655 *OS << "\n";
656 }
Benjamin Kramer5acab502011-09-15 02:12:05 +0000657 break;
658
659 case DW_LNS_advance_pc:
660 // Takes a single unsigned LEB128 operand, multiplies it by the
661 // min_inst_length field of the prologue, and adds the
662 // result to the address register of the state machine.
Jonas Devlieghere26f9a0c2017-09-21 20:15:30 +0000663 {
664 uint64_t AddrOffset =
665 DebugLineData.getULEB128(OffsetPtr) * Prologue.MinInstLength;
666 State.Row.Address += AddrOffset;
667 if (OS)
668 *OS << " (" << AddrOffset << ")";
669 }
Benjamin Kramer5acab502011-09-15 02:12:05 +0000670 break;
671
672 case DW_LNS_advance_line:
673 // Takes a single signed LEB128 operand and adds that value to
674 // the line register of the state machine.
Paul Robinson9d4eb692017-05-01 23:27:55 +0000675 State.Row.Line += DebugLineData.getSLEB128(OffsetPtr);
Jonas Devlieghere26f9a0c2017-09-21 20:15:30 +0000676 if (OS)
677 *OS << " (" << State.Row.Line << ")";
Benjamin Kramer5acab502011-09-15 02:12:05 +0000678 break;
679
680 case DW_LNS_set_file:
681 // Takes a single unsigned LEB128 operand and stores it in the file
682 // register of the state machine.
Paul Robinson9d4eb692017-05-01 23:27:55 +0000683 State.Row.File = DebugLineData.getULEB128(OffsetPtr);
Jonas Devlieghere26f9a0c2017-09-21 20:15:30 +0000684 if (OS)
685 *OS << " (" << State.Row.File << ")";
Benjamin Kramer5acab502011-09-15 02:12:05 +0000686 break;
687
688 case DW_LNS_set_column:
689 // Takes a single unsigned LEB128 operand and stores it in the
690 // column register of the state machine.
Paul Robinson9d4eb692017-05-01 23:27:55 +0000691 State.Row.Column = DebugLineData.getULEB128(OffsetPtr);
Jonas Devlieghere26f9a0c2017-09-21 20:15:30 +0000692 if (OS)
693 *OS << " (" << State.Row.Column << ")";
Benjamin Kramer5acab502011-09-15 02:12:05 +0000694 break;
695
696 case DW_LNS_negate_stmt:
697 // Takes no arguments. Set the is_stmt register of the state
698 // machine to the logical negation of its current value.
Alexey Samsonov110d5952014-04-30 00:09:19 +0000699 State.Row.IsStmt = !State.Row.IsStmt;
Benjamin Kramer5acab502011-09-15 02:12:05 +0000700 break;
701
702 case DW_LNS_set_basic_block:
703 // Takes no arguments. Set the basic_block register of the
704 // state machine to true
Alexey Samsonov110d5952014-04-30 00:09:19 +0000705 State.Row.BasicBlock = true;
Benjamin Kramer5acab502011-09-15 02:12:05 +0000706 break;
707
708 case DW_LNS_const_add_pc:
709 // Takes no arguments. Add to the address register of the state
710 // machine the address increment value corresponding to special
711 // opcode 255. The motivation for DW_LNS_const_add_pc is this:
712 // when the statement program needs to advance the address by a
713 // small amount, it can use a single special opcode, which occupies
714 // a single byte. When it needs to advance the address by up to
715 // twice the range of the last special opcode, it can use
716 // DW_LNS_const_add_pc followed by a special opcode, for a total
717 // of two bytes. Only if it needs to advance the address by more
718 // than twice that range will it need to use both DW_LNS_advance_pc
719 // and a special opcode, requiring three or more bytes.
720 {
Paul Robinson9d4eb692017-05-01 23:27:55 +0000721 uint8_t AdjustOpcode = 255 - Prologue.OpcodeBase;
722 uint64_t AddrOffset =
723 (AdjustOpcode / Prologue.LineRange) * Prologue.MinInstLength;
724 State.Row.Address += AddrOffset;
Jonas Devlieghere26f9a0c2017-09-21 20:15:30 +0000725 if (OS)
726 *OS
727 << format(" (0x%16.16" PRIx64 ")", AddrOffset);
Benjamin Kramer5acab502011-09-15 02:12:05 +0000728 }
729 break;
730
731 case DW_LNS_fixed_advance_pc:
732 // Takes a single uhalf operand. Add to the address register of
733 // the state machine the value of the (unencoded) operand. This
734 // is the only extended opcode that takes an argument that is not
735 // a variable length number. The motivation for DW_LNS_fixed_advance_pc
736 // is this: existing assemblers cannot emit DW_LNS_advance_pc or
737 // special opcodes because they cannot encode LEB128 numbers or
738 // judge when the computation of a special opcode overflows and
739 // requires the use of DW_LNS_advance_pc. Such assemblers, however,
740 // can use DW_LNS_fixed_advance_pc instead, sacrificing compression.
Jonas Devlieghere26f9a0c2017-09-21 20:15:30 +0000741 {
742 uint16_t PCOffset = DebugLineData.getU16(OffsetPtr);
743 State.Row.Address += PCOffset;
744 if (OS)
745 *OS
746 << format(" (0x%16.16" PRIx64 ")", PCOffset);
747 }
Benjamin Kramer5acab502011-09-15 02:12:05 +0000748 break;
749
750 case DW_LNS_set_prologue_end:
751 // Takes no arguments. Set the prologue_end register of the
752 // state machine to true
Alexey Samsonov110d5952014-04-30 00:09:19 +0000753 State.Row.PrologueEnd = true;
Benjamin Kramer5acab502011-09-15 02:12:05 +0000754 break;
755
756 case DW_LNS_set_epilogue_begin:
757 // Takes no arguments. Set the basic_block register of the
758 // state machine to true
Alexey Samsonov110d5952014-04-30 00:09:19 +0000759 State.Row.EpilogueBegin = true;
Benjamin Kramer5acab502011-09-15 02:12:05 +0000760 break;
761
762 case DW_LNS_set_isa:
763 // Takes a single unsigned LEB128 operand and stores it in the
764 // column register of the state machine.
Paul Robinson9d4eb692017-05-01 23:27:55 +0000765 State.Row.Isa = DebugLineData.getULEB128(OffsetPtr);
Jonas Devlieghere26f9a0c2017-09-21 20:15:30 +0000766 if (OS)
767 *OS << " (" << State.Row.Isa << ")";
Benjamin Kramer5acab502011-09-15 02:12:05 +0000768 break;
769
770 default:
771 // Handle any unknown standard opcodes here. We know the lengths
772 // of such opcodes because they are specified in the prologue
773 // as a multiple of LEB128 operands for each opcode.
774 {
Paul Robinson9d4eb692017-05-01 23:27:55 +0000775 assert(Opcode - 1U < Prologue.StandardOpcodeLengths.size());
776 uint8_t OpcodeLength = Prologue.StandardOpcodeLengths[Opcode - 1];
Jonas Devlieghere26f9a0c2017-09-21 20:15:30 +0000777 for (uint8_t I = 0; I < OpcodeLength; ++I) {
778 uint64_t Value = DebugLineData.getULEB128(OffsetPtr);
779 if (OS)
780 *OS << format("Skipping ULEB128 value: 0x%16.16" PRIx64 ")\n",
781 Value);
782 }
Benjamin Kramer5acab502011-09-15 02:12:05 +0000783 }
784 break;
785 }
786 } else {
787 // Special Opcodes
788
789 // A special opcode value is chosen based on the amount that needs
790 // to be added to the line and address registers. The maximum line
791 // increment for a special opcode is the value of the line_base
792 // field in the header, plus the value of the line_range field,
793 // minus 1 (line base + line range - 1). If the desired line
794 // increment is greater than the maximum line increment, a standard
NAKAMURA Takumif9959852011-10-08 11:22:47 +0000795 // opcode must be used instead of a special opcode. The "address
796 // advance" is calculated by dividing the desired address increment
Benjamin Kramer5acab502011-09-15 02:12:05 +0000797 // by the minimum_instruction_length field from the header. The
798 // special opcode is then calculated using the following formula:
799 //
800 // opcode = (desired line increment - line_base) +
801 // (line_range * address advance) + opcode_base
802 //
803 // If the resulting opcode is greater than 255, a standard opcode
804 // must be used instead.
805 //
806 // To decode a special opcode, subtract the opcode_base from the
807 // opcode itself to give the adjusted opcode. The amount to
808 // increment the address register is the result of the adjusted
809 // opcode divided by the line_range multiplied by the
810 // minimum_instruction_length field from the header. That is:
811 //
812 // address increment = (adjusted opcode / line_range) *
813 // minimum_instruction_length
814 //
815 // The amount to increment the line register is the line_base plus
816 // the result of the adjusted opcode modulo the line_range. That is:
817 //
818 // line increment = line_base + (adjusted opcode % line_range)
819
Paul Robinson9d4eb692017-05-01 23:27:55 +0000820 uint8_t AdjustOpcode = Opcode - Prologue.OpcodeBase;
821 uint64_t AddrOffset =
822 (AdjustOpcode / Prologue.LineRange) * Prologue.MinInstLength;
823 int32_t LineOffset =
824 Prologue.LineBase + (AdjustOpcode % Prologue.LineRange);
825 State.Row.Line += LineOffset;
826 State.Row.Address += AddrOffset;
Jonas Devlieghere26f9a0c2017-09-21 20:15:30 +0000827
828 if (OS) {
829 *OS << "address += " << ((uint32_t)AdjustOpcode)
830 << ", line += " << LineOffset << "\n";
831 OS->indent(12);
832 State.Row.dump(*OS);
833 }
834
Paul Robinson9d4eb692017-05-01 23:27:55 +0000835 State.appendRowToMatrix(*OffsetPtr);
Dehao Chen1b54fce2016-04-28 22:09:37 +0000836 // Reset discriminator to 0.
837 State.Row.Discriminator = 0;
Benjamin Kramer5acab502011-09-15 02:12:05 +0000838 }
Jonas Devlieghere26f9a0c2017-09-21 20:15:30 +0000839 if(OS)
840 *OS << "\n";
Benjamin Kramer5acab502011-09-15 02:12:05 +0000841 }
842
Jonas Devlieghere84e99262018-04-14 22:07:23 +0000843 if (!State.Sequence.Empty)
James Hendersona3acf992018-05-10 10:51:33 +0000844 WarnCallback("last sequence in debug line table is not terminated!");
Alexey Samsonov110d5952014-04-30 00:09:19 +0000845
846 // Sort all sequences so that address lookup will work faster.
847 if (!Sequences.empty()) {
Mandeep Singh Grangfe1d28e2018-04-01 16:18:49 +0000848 llvm::sort(Sequences.begin(), Sequences.end(), Sequence::orderByLowPC);
Alexey Samsonov110d5952014-04-30 00:09:19 +0000849 // Note: actually, instruction address ranges of sequences should not
850 // overlap (in shared objects and executables). If they do, the address
851 // lookup would still work, though, but result would be ambiguous.
852 // We don't report warning in this case. For example,
853 // sometimes .so compiled from multiple object files contains a few
854 // rudimentary sequences for address ranges [0x0, 0xsomething).
855 }
Benjamin Kramer5acab502011-09-15 02:12:05 +0000856
James Hendersona3acf992018-05-10 10:51:33 +0000857 return Error::success();
Benjamin Kramer5acab502011-09-15 02:12:05 +0000858}
859
Keno Fischerc2c60182015-05-31 23:37:04 +0000860uint32_t
Paul Robinson9d4eb692017-05-01 23:27:55 +0000861DWARFDebugLine::LineTable::findRowInSeq(const DWARFDebugLine::Sequence &Seq,
862 uint64_t Address) const {
863 if (!Seq.containsPC(Address))
Keno Fischerc2c60182015-05-31 23:37:04 +0000864 return UnknownRowIndex;
865 // Search for instruction address in the rows describing the sequence.
866 // Rows are stored in a vector, so we may use arithmetical operations with
867 // iterators.
Paul Robinson9d4eb692017-05-01 23:27:55 +0000868 DWARFDebugLine::Row Row;
869 Row.Address = Address;
870 RowIter FirstRow = Rows.begin() + Seq.FirstRowIndex;
871 RowIter LastRow = Rows.begin() + Seq.LastRowIndex;
872 LineTable::RowIter RowPos = std::lower_bound(
873 FirstRow, LastRow, Row, DWARFDebugLine::Row::orderByAddress);
874 if (RowPos == LastRow) {
875 return Seq.LastRowIndex - 1;
Keno Fischerc2c60182015-05-31 23:37:04 +0000876 }
Paul Robinson9d4eb692017-05-01 23:27:55 +0000877 uint32_t Index = Seq.FirstRowIndex + (RowPos - FirstRow);
878 if (RowPos->Address > Address) {
879 if (RowPos == FirstRow)
Keno Fischerc2c60182015-05-31 23:37:04 +0000880 return UnknownRowIndex;
881 else
Paul Robinson9d4eb692017-05-01 23:27:55 +0000882 Index--;
Keno Fischerc2c60182015-05-31 23:37:04 +0000883 }
Paul Robinson9d4eb692017-05-01 23:27:55 +0000884 return Index;
Keno Fischerc2c60182015-05-31 23:37:04 +0000885}
886
Paul Robinson9d4eb692017-05-01 23:27:55 +0000887uint32_t DWARFDebugLine::LineTable::lookupAddress(uint64_t Address) const {
Alexey Samsonov947228c2012-08-07 11:46:57 +0000888 if (Sequences.empty())
Keno Fischerc2c60182015-05-31 23:37:04 +0000889 return UnknownRowIndex;
Alexey Samsonov947228c2012-08-07 11:46:57 +0000890 // First, find an instruction sequence containing the given address.
Paul Robinson9d4eb692017-05-01 23:27:55 +0000891 DWARFDebugLine::Sequence Sequence;
892 Sequence.LowPC = Address;
893 SequenceIter FirstSeq = Sequences.begin();
894 SequenceIter LastSeq = Sequences.end();
895 SequenceIter SeqPos = std::lower_bound(
896 FirstSeq, LastSeq, Sequence, DWARFDebugLine::Sequence::orderByLowPC);
897 DWARFDebugLine::Sequence FoundSeq;
898 if (SeqPos == LastSeq) {
899 FoundSeq = Sequences.back();
900 } else if (SeqPos->LowPC == Address) {
901 FoundSeq = *SeqPos;
Alexey Samsonov947228c2012-08-07 11:46:57 +0000902 } else {
Paul Robinson9d4eb692017-05-01 23:27:55 +0000903 if (SeqPos == FirstSeq)
Keno Fischerc2c60182015-05-31 23:37:04 +0000904 return UnknownRowIndex;
Paul Robinson9d4eb692017-05-01 23:27:55 +0000905 FoundSeq = *(SeqPos - 1);
Benjamin Kramer5acab502011-09-15 02:12:05 +0000906 }
Paul Robinson9d4eb692017-05-01 23:27:55 +0000907 return findRowInSeq(FoundSeq, Address);
Benjamin Kramer5acab502011-09-15 02:12:05 +0000908}
Alexey Samsonov45be7932012-08-30 07:49:50 +0000909
Alexey Samsonov836b1ae2014-04-29 21:28:13 +0000910bool DWARFDebugLine::LineTable::lookupAddressRange(
Paul Robinson9d4eb692017-05-01 23:27:55 +0000911 uint64_t Address, uint64_t Size, std::vector<uint32_t> &Result) const {
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000912 if (Sequences.empty())
913 return false;
Paul Robinson9d4eb692017-05-01 23:27:55 +0000914 uint64_t EndAddr = Address + Size;
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000915 // First, find an instruction sequence containing the given address.
Paul Robinson9d4eb692017-05-01 23:27:55 +0000916 DWARFDebugLine::Sequence Sequence;
917 Sequence.LowPC = Address;
918 SequenceIter FirstSeq = Sequences.begin();
919 SequenceIter LastSeq = Sequences.end();
920 SequenceIter SeqPos = std::lower_bound(
921 FirstSeq, LastSeq, Sequence, DWARFDebugLine::Sequence::orderByLowPC);
922 if (SeqPos == LastSeq || SeqPos->LowPC != Address) {
923 if (SeqPos == FirstSeq)
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000924 return false;
Paul Robinson9d4eb692017-05-01 23:27:55 +0000925 SeqPos--;
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000926 }
Paul Robinson9d4eb692017-05-01 23:27:55 +0000927 if (!SeqPos->containsPC(Address))
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000928 return false;
929
Paul Robinson9d4eb692017-05-01 23:27:55 +0000930 SequenceIter StartPos = SeqPos;
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000931
932 // Add the rows from the first sequence to the vector, starting with the
933 // index we just calculated
934
Paul Robinson9d4eb692017-05-01 23:27:55 +0000935 while (SeqPos != LastSeq && SeqPos->LowPC < EndAddr) {
936 const DWARFDebugLine::Sequence &CurSeq = *SeqPos;
Keno Fischerc2c60182015-05-31 23:37:04 +0000937 // For the first sequence, we need to find which row in the sequence is the
938 // first in our range.
Paul Robinson9d4eb692017-05-01 23:27:55 +0000939 uint32_t FirstRowIndex = CurSeq.FirstRowIndex;
940 if (SeqPos == StartPos)
941 FirstRowIndex = findRowInSeq(CurSeq, Address);
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000942
Keno Fischerc2c60182015-05-31 23:37:04 +0000943 // Figure out the last row in the range.
Paul Robinson9d4eb692017-05-01 23:27:55 +0000944 uint32_t LastRowIndex = findRowInSeq(CurSeq, EndAddr - 1);
945 if (LastRowIndex == UnknownRowIndex)
946 LastRowIndex = CurSeq.LastRowIndex - 1;
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000947
Paul Robinson9d4eb692017-05-01 23:27:55 +0000948 assert(FirstRowIndex != UnknownRowIndex);
949 assert(LastRowIndex != UnknownRowIndex);
Keno Fischerc2c60182015-05-31 23:37:04 +0000950
Paul Robinson9d4eb692017-05-01 23:27:55 +0000951 for (uint32_t I = FirstRowIndex; I <= LastRowIndex; ++I) {
952 Result.push_back(I);
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000953 }
954
Paul Robinson9d4eb692017-05-01 23:27:55 +0000955 ++SeqPos;
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000956 }
NAKAMURA Takumi4b86cdb2013-01-26 01:45:06 +0000957
958 return true;
Andrew Kaylor9a8ff812013-01-26 00:28:05 +0000959}
960
Paul Robinson9d4eb692017-05-01 23:27:55 +0000961bool DWARFDebugLine::LineTable::hasFileAtIndex(uint64_t FileIndex) const {
Pete Cooperb2ba7762016-07-22 01:41:32 +0000962 return FileIndex != 0 && FileIndex <= Prologue.FileNames.size();
963}
964
Scott Linder16c7bda2018-02-23 23:01:06 +0000965Optional<StringRef> DWARFDebugLine::LineTable::getSourceByIndex(uint64_t FileIndex,
966 FileLineInfoKind Kind) const {
967 if (Kind == FileLineInfoKind::None || !hasFileAtIndex(FileIndex))
968 return None;
969 const FileNameEntry &Entry = Prologue.FileNames[FileIndex - 1];
970 if (Optional<const char *> source = Entry.Source.getAsCString())
971 return StringRef(*source);
972 return None;
973}
974
Eugene Zemtsov82d60d62018-03-13 17:54:29 +0000975static bool isPathAbsoluteOnWindowsOrPosix(const Twine &Path) {
976 // Debug info can contain paths from any OS, not necessarily
977 // an OS we're currently running on. Moreover different compilation units can
978 // be compiled on different operating systems and linked together later.
979 return sys::path::is_absolute(Path, sys::path::Style::posix) ||
980 sys::path::is_absolute(Path, sys::path::Style::windows);
981}
982
Paul Robinson9d4eb692017-05-01 23:27:55 +0000983bool DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex,
984 const char *CompDir,
985 FileLineInfoKind Kind,
986 std::string &Result) const {
Pete Cooperb2ba7762016-07-22 01:41:32 +0000987 if (Kind == FileLineInfoKind::None || !hasFileAtIndex(FileIndex))
Alexey Samsonov45be7932012-08-30 07:49:50 +0000988 return false;
989 const FileNameEntry &Entry = Prologue.FileNames[FileIndex - 1];
Paul Robinson0a227092018-02-05 20:43:15 +0000990 StringRef FileName = Entry.Name.getAsCString().getValue();
Alexey Samsonovdce67342014-05-15 21:24:32 +0000991 if (Kind != FileLineInfoKind::AbsoluteFilePath ||
Eugene Zemtsov82d60d62018-03-13 17:54:29 +0000992 isPathAbsoluteOnWindowsOrPosix(FileName)) {
Alexey Samsonov45be7932012-08-30 07:49:50 +0000993 Result = FileName;
994 return true;
995 }
Frederic Riss101b5e22014-09-19 15:11:51 +0000996
Alexey Samsonov45be7932012-08-30 07:49:50 +0000997 SmallString<16> FilePath;
998 uint64_t IncludeDirIndex = Entry.DirIdx;
Paul Robinsonba1c9152017-05-02 17:37:32 +0000999 StringRef IncludeDir;
Alexey Samsonov45be7932012-08-30 07:49:50 +00001000 // Be defensive about the contents of Entry.
1001 if (IncludeDirIndex > 0 &&
Frederic Riss101b5e22014-09-19 15:11:51 +00001002 IncludeDirIndex <= Prologue.IncludeDirectories.size())
Paul Robinson0a227092018-02-05 20:43:15 +00001003 IncludeDir = Prologue.IncludeDirectories[IncludeDirIndex - 1]
1004 .getAsCString()
1005 .getValue();
Frederic Riss101b5e22014-09-19 15:11:51 +00001006
1007 // We may still need to append compilation directory of compile unit.
1008 // We know that FileName is not absolute, the only way to have an
1009 // absolute path at this point would be if IncludeDir is absolute.
1010 if (CompDir && Kind == FileLineInfoKind::AbsoluteFilePath &&
Eugene Zemtsov82d60d62018-03-13 17:54:29 +00001011 !isPathAbsoluteOnWindowsOrPosix(IncludeDir))
Frederic Riss101b5e22014-09-19 15:11:51 +00001012 sys::path::append(FilePath, CompDir);
1013
1014 // sys::path::append skips empty strings.
1015 sys::path::append(FilePath, IncludeDir, FileName);
Alexey Samsonov45be7932012-08-30 07:49:50 +00001016 Result = FilePath.str();
1017 return true;
1018}
Frederic Riss101b5e22014-09-19 15:11:51 +00001019
Dehao Chen1b54fce2016-04-28 22:09:37 +00001020bool DWARFDebugLine::LineTable::getFileLineInfoForAddress(
1021 uint64_t Address, const char *CompDir, FileLineInfoKind Kind,
1022 DILineInfo &Result) const {
Frederic Riss101b5e22014-09-19 15:11:51 +00001023 // Get the index of row we're looking for in the line table.
1024 uint32_t RowIndex = lookupAddress(Address);
1025 if (RowIndex == -1U)
1026 return false;
1027 // Take file number and line/column from the row.
1028 const auto &Row = Rows[RowIndex];
1029 if (!getFileNameByIndex(Row.File, CompDir, Kind, Result.FileName))
1030 return false;
1031 Result.Line = Row.Line;
1032 Result.Column = Row.Column;
Eric Christopherba1024c2016-12-14 18:29:39 +00001033 Result.Discriminator = Row.Discriminator;
Scott Linder16c7bda2018-02-23 23:01:06 +00001034 Result.Source = getSourceByIndex(Row.File, Kind);
Frederic Riss101b5e22014-09-19 15:11:51 +00001035 return true;
1036}
James Hendersona3acf992018-05-10 10:51:33 +00001037
1038// We want to supply the Unit associated with a .debug_line[.dwo] table when
1039// we dump it, if possible, but still dump the table even if there isn't a Unit.
1040// Therefore, collect up handles on all the Units that point into the
1041// line-table section.
1042static DWARFDebugLine::SectionParser::LineToUnitMap
1043buildLineToUnitMap(DWARFDebugLine::SectionParser::cu_range CUs,
1044 DWARFDebugLine::SectionParser::tu_range TUSections) {
1045 DWARFDebugLine::SectionParser::LineToUnitMap LineToUnit;
1046 for (const auto &CU : CUs)
1047 if (auto CUDIE = CU->getUnitDIE())
1048 if (auto StmtOffset = toSectionOffset(CUDIE.find(DW_AT_stmt_list)))
1049 LineToUnit.insert(std::make_pair(*StmtOffset, &*CU));
1050 for (const auto &TUS : TUSections)
1051 for (const auto &TU : TUS)
1052 if (auto TUDIE = TU->getUnitDIE())
1053 if (auto StmtOffset = toSectionOffset(TUDIE.find(DW_AT_stmt_list)))
1054 LineToUnit.insert(std::make_pair(*StmtOffset, &*TU));
1055 return LineToUnit;
1056}
1057
1058DWARFDebugLine::SectionParser::SectionParser(DWARFDataExtractor &Data,
1059 const DWARFContext &C,
1060 cu_range CUs, tu_range TUs)
1061 : DebugLineData(Data), Context(C) {
1062 LineToUnit = buildLineToUnitMap(CUs, TUs);
1063 if (!DebugLineData.isValidOffset(Offset))
1064 Done = true;
1065}
1066
1067bool DWARFDebugLine::Prologue::totalLengthIsValid() const {
1068 return TotalLength == 0xffffffff || TotalLength < 0xffffff00;
1069}
1070
1071DWARFDebugLine::LineTable DWARFDebugLine::SectionParser::parseNext(
1072 function_ref<void(StringRef)> StringCallback,
1073 function_ref<void(Error)> ErrorCallback, raw_ostream *OS) {
1074 assert(DebugLineData.isValidOffset(Offset) &&
1075 "parsing should have terminated");
1076 DWARFUnit *U = prepareToParse(Offset);
1077 uint32_t OldOffset = Offset;
1078 LineTable LT;
1079 Error Err = LT.parse(DebugLineData, &Offset, Context, U, StringCallback, OS);
1080 ErrorCallback(std::move(Err));
1081 moveToNextTable(OldOffset, LT.Prologue);
1082 return LT;
1083}
1084
1085void DWARFDebugLine::SectionParser::skip(
1086 function_ref<void(Error)> ErrorCallback) {
1087 assert(DebugLineData.isValidOffset(Offset) &&
1088 "parsing should have terminated");
1089 DWARFUnit *U = prepareToParse(Offset);
1090 uint32_t OldOffset = Offset;
1091 LineTable LT;
1092 Error Err = LT.Prologue.parse(DebugLineData, &Offset, Context, U);
1093 ErrorCallback(std::move(Err));
1094 moveToNextTable(OldOffset, LT.Prologue);
1095}
1096
1097DWARFUnit *DWARFDebugLine::SectionParser::prepareToParse(uint32_t Offset) {
1098 DWARFUnit *U = nullptr;
1099 auto It = LineToUnit.find(Offset);
1100 if (It != LineToUnit.end())
1101 U = It->second;
1102 DebugLineData.setAddressSize(U ? U->getAddressByteSize() : 0);
1103 return U;
1104}
1105
1106void DWARFDebugLine::SectionParser::moveToNextTable(uint32_t OldOffset,
1107 const Prologue &P) {
1108 // If the length field is not valid, we don't know where the next table is, so
1109 // cannot continue to parse. Mark the parser as done, and leave the Offset
1110 // value as it currently is. This will be the end of the bad length field.
1111 if (!P.totalLengthIsValid()) {
1112 Done = true;
1113 return;
1114 }
1115
1116 Offset = OldOffset + P.TotalLength + P.sizeofTotalLength();
1117 if (!DebugLineData.isValidOffset(Offset)) {
1118 Done = true;
1119 }
1120}
1121
1122void DWARFDebugLine::warn(StringRef Message) {
1123 WithColor::warning() << Message << '\n';
1124}
1125
1126void DWARFDebugLine::warnForError(Error Err) {
1127 handleAllErrors(std::move(Err),
1128 [](ErrorInfoBase &Info) { warn(Info.message()); });
1129}