DWARFDebugLine.cpp 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823
  1. //===- DWARFDebugLine.cpp -------------------------------------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
  10. #include "llvm/ADT/SmallString.h"
  11. #include "llvm/ADT/SmallVector.h"
  12. #include "llvm/ADT/StringRef.h"
  13. #include "llvm/BinaryFormat/Dwarf.h"
  14. #include "llvm/DebugInfo/DWARF/DWARFContext.h"
  15. #include "llvm/DebugInfo/DWARF/DWARFFormValue.h"
  16. #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
  17. #include "llvm/Support/Format.h"
  18. #include "llvm/Support/Path.h"
  19. #include "llvm/Support/raw_ostream.h"
  20. #include <algorithm>
  21. #include <cassert>
  22. #include <cinttypes>
  23. #include <cstdint>
  24. #include <cstdio>
  25. #include <utility>
  26. using namespace llvm;
  27. using namespace dwarf;
  28. using FileLineInfoKind = DILineInfoSpecifier::FileLineInfoKind;
  29. namespace {
  30. struct ContentDescriptor {
  31. dwarf::LineNumberEntryFormat Type;
  32. dwarf::Form Form;
  33. };
  34. using ContentDescriptors = SmallVector<ContentDescriptor, 4>;
  35. } // end anonmyous namespace
  36. DWARFDebugLine::Prologue::Prologue() { clear(); }
  37. void DWARFDebugLine::Prologue::clear() {
  38. TotalLength = PrologueLength = 0;
  39. SegSelectorSize = 0;
  40. MinInstLength = MaxOpsPerInst = DefaultIsStmt = LineBase = LineRange = 0;
  41. OpcodeBase = 0;
  42. FormParams = DWARFFormParams({0, 0, DWARF32});
  43. StandardOpcodeLengths.clear();
  44. IncludeDirectories.clear();
  45. FileNames.clear();
  46. }
  47. void DWARFDebugLine::Prologue::dump(raw_ostream &OS) const {
  48. OS << "Line table prologue:\n"
  49. << format(" total_length: 0x%8.8" PRIx64 "\n", TotalLength)
  50. << format(" version: %u\n", getVersion());
  51. if (getVersion() >= 5)
  52. OS << format(" address_size: %u\n", getAddressSize())
  53. << format(" seg_select_size: %u\n", SegSelectorSize);
  54. OS << format(" prologue_length: 0x%8.8" PRIx64 "\n", PrologueLength)
  55. << format(" min_inst_length: %u\n", MinInstLength)
  56. << format(getVersion() >= 4 ? "max_ops_per_inst: %u\n" : "", MaxOpsPerInst)
  57. << format(" default_is_stmt: %u\n", DefaultIsStmt)
  58. << format(" line_base: %i\n", LineBase)
  59. << format(" line_range: %u\n", LineRange)
  60. << format(" opcode_base: %u\n", OpcodeBase);
  61. for (uint32_t I = 0; I != StandardOpcodeLengths.size(); ++I)
  62. OS << format("standard_opcode_lengths[%s] = %u\n",
  63. LNStandardString(I + 1).data(), StandardOpcodeLengths[I]);
  64. if (!IncludeDirectories.empty())
  65. for (uint32_t I = 0; I != IncludeDirectories.size(); ++I)
  66. OS << format("include_directories[%3u] = '", I + 1)
  67. << IncludeDirectories[I] << "'\n";
  68. if (!FileNames.empty()) {
  69. OS << " Dir Mod Time File Len File Name\n"
  70. << " ---- ---------- ---------- -----------"
  71. "----------------\n";
  72. for (uint32_t I = 0; I != FileNames.size(); ++I) {
  73. const FileNameEntry &FileEntry = FileNames[I];
  74. OS << format("file_names[%3u] %4" PRIu64 " ", I + 1, FileEntry.DirIdx)
  75. << format("0x%8.8" PRIx64 " 0x%8.8" PRIx64 " ", FileEntry.ModTime,
  76. FileEntry.Length)
  77. << FileEntry.Name << '\n';
  78. }
  79. }
  80. }
  81. // Parse v2-v4 directory and file tables.
  82. static void
  83. parseV2DirFileTables(DataExtractor DebugLineData, uint32_t *OffsetPtr,
  84. uint64_t EndPrologueOffset,
  85. std::vector<StringRef> &IncludeDirectories,
  86. std::vector<DWARFDebugLine::FileNameEntry> &FileNames) {
  87. while (*OffsetPtr < EndPrologueOffset) {
  88. StringRef S = DebugLineData.getCStrRef(OffsetPtr);
  89. if (S.empty())
  90. break;
  91. IncludeDirectories.push_back(S);
  92. }
  93. while (*OffsetPtr < EndPrologueOffset) {
  94. StringRef Name = DebugLineData.getCStrRef(OffsetPtr);
  95. if (Name.empty())
  96. break;
  97. DWARFDebugLine::FileNameEntry FileEntry;
  98. FileEntry.Name = Name;
  99. FileEntry.DirIdx = DebugLineData.getULEB128(OffsetPtr);
  100. FileEntry.ModTime = DebugLineData.getULEB128(OffsetPtr);
  101. FileEntry.Length = DebugLineData.getULEB128(OffsetPtr);
  102. FileNames.push_back(FileEntry);
  103. }
  104. }
  105. // Parse v5 directory/file entry content descriptions.
  106. // Returns the descriptors, or an empty vector if we did not find a path or
  107. // ran off the end of the prologue.
  108. static ContentDescriptors
  109. parseV5EntryFormat(DataExtractor DebugLineData, uint32_t *OffsetPtr,
  110. uint64_t EndPrologueOffset) {
  111. ContentDescriptors Descriptors;
  112. int FormatCount = DebugLineData.getU8(OffsetPtr);
  113. bool HasPath = false;
  114. for (int I = 0; I != FormatCount; ++I) {
  115. if (*OffsetPtr >= EndPrologueOffset)
  116. return ContentDescriptors();
  117. ContentDescriptor Descriptor;
  118. Descriptor.Type =
  119. dwarf::LineNumberEntryFormat(DebugLineData.getULEB128(OffsetPtr));
  120. Descriptor.Form = dwarf::Form(DebugLineData.getULEB128(OffsetPtr));
  121. if (Descriptor.Type == dwarf::DW_LNCT_path)
  122. HasPath = true;
  123. Descriptors.push_back(Descriptor);
  124. }
  125. return HasPath ? Descriptors : ContentDescriptors();
  126. }
  127. static bool
  128. parseV5DirFileTables(DataExtractor DebugLineData, uint32_t *OffsetPtr,
  129. uint64_t EndPrologueOffset,
  130. const DWARFFormParams &FormParams,
  131. std::vector<StringRef> &IncludeDirectories,
  132. std::vector<DWARFDebugLine::FileNameEntry> &FileNames) {
  133. // Get the directory entry description.
  134. ContentDescriptors DirDescriptors =
  135. parseV5EntryFormat(DebugLineData, OffsetPtr, EndPrologueOffset);
  136. if (DirDescriptors.empty())
  137. return false;
  138. // Get the directory entries, according to the format described above.
  139. int DirEntryCount = DebugLineData.getU8(OffsetPtr);
  140. for (int I = 0; I != DirEntryCount; ++I) {
  141. if (*OffsetPtr >= EndPrologueOffset)
  142. return false;
  143. for (auto Descriptor : DirDescriptors) {
  144. DWARFFormValue Value(Descriptor.Form);
  145. switch (Descriptor.Type) {
  146. case DW_LNCT_path:
  147. if (!Value.extractValue(DebugLineData, OffsetPtr, nullptr))
  148. return false;
  149. IncludeDirectories.push_back(Value.getAsCString().getValue());
  150. break;
  151. default:
  152. if (!Value.skipValue(DebugLineData, OffsetPtr, FormParams))
  153. return false;
  154. }
  155. }
  156. }
  157. // Get the file entry description.
  158. ContentDescriptors FileDescriptors =
  159. parseV5EntryFormat(DebugLineData, OffsetPtr, EndPrologueOffset);
  160. if (FileDescriptors.empty())
  161. return false;
  162. // Get the file entries, according to the format described above.
  163. int FileEntryCount = DebugLineData.getU8(OffsetPtr);
  164. for (int I = 0; I != FileEntryCount; ++I) {
  165. if (*OffsetPtr >= EndPrologueOffset)
  166. return false;
  167. DWARFDebugLine::FileNameEntry FileEntry;
  168. for (auto Descriptor : FileDescriptors) {
  169. DWARFFormValue Value(Descriptor.Form);
  170. if (!Value.extractValue(DebugLineData, OffsetPtr, nullptr))
  171. return false;
  172. switch (Descriptor.Type) {
  173. case DW_LNCT_path:
  174. FileEntry.Name = Value.getAsCString().getValue();
  175. break;
  176. case DW_LNCT_directory_index:
  177. FileEntry.DirIdx = Value.getAsUnsignedConstant().getValue();
  178. break;
  179. case DW_LNCT_timestamp:
  180. FileEntry.ModTime = Value.getAsUnsignedConstant().getValue();
  181. break;
  182. case DW_LNCT_size:
  183. FileEntry.Length = Value.getAsUnsignedConstant().getValue();
  184. break;
  185. // FIXME: Add MD5
  186. default:
  187. break;
  188. }
  189. }
  190. FileNames.push_back(FileEntry);
  191. }
  192. return true;
  193. }
  194. bool DWARFDebugLine::Prologue::parse(DataExtractor DebugLineData,
  195. uint32_t *OffsetPtr) {
  196. const uint64_t PrologueOffset = *OffsetPtr;
  197. clear();
  198. TotalLength = DebugLineData.getU32(OffsetPtr);
  199. if (TotalLength == UINT32_MAX) {
  200. FormParams.Format = dwarf::DWARF64;
  201. TotalLength = DebugLineData.getU64(OffsetPtr);
  202. } else if (TotalLength >= 0xffffff00) {
  203. return false;
  204. }
  205. FormParams.Version = DebugLineData.getU16(OffsetPtr);
  206. if (getVersion() < 2)
  207. return false;
  208. if (getVersion() >= 5) {
  209. FormParams.AddrSize = DebugLineData.getU8(OffsetPtr);
  210. assert(getAddressSize() == DebugLineData.getAddressSize() &&
  211. "Line table header and data extractor disagree");
  212. SegSelectorSize = DebugLineData.getU8(OffsetPtr);
  213. }
  214. PrologueLength = DebugLineData.getUnsigned(OffsetPtr, sizeofPrologueLength());
  215. const uint64_t EndPrologueOffset = PrologueLength + *OffsetPtr;
  216. MinInstLength = DebugLineData.getU8(OffsetPtr);
  217. if (getVersion() >= 4)
  218. MaxOpsPerInst = DebugLineData.getU8(OffsetPtr);
  219. DefaultIsStmt = DebugLineData.getU8(OffsetPtr);
  220. LineBase = DebugLineData.getU8(OffsetPtr);
  221. LineRange = DebugLineData.getU8(OffsetPtr);
  222. OpcodeBase = DebugLineData.getU8(OffsetPtr);
  223. StandardOpcodeLengths.reserve(OpcodeBase - 1);
  224. for (uint32_t I = 1; I < OpcodeBase; ++I) {
  225. uint8_t OpLen = DebugLineData.getU8(OffsetPtr);
  226. StandardOpcodeLengths.push_back(OpLen);
  227. }
  228. if (getVersion() >= 5) {
  229. if (!parseV5DirFileTables(DebugLineData, OffsetPtr, EndPrologueOffset,
  230. getFormParams(), IncludeDirectories, FileNames)) {
  231. fprintf(stderr,
  232. "warning: parsing line table prologue at 0x%8.8" PRIx64
  233. " found an invalid directory or file table description at"
  234. " 0x%8.8" PRIx64 "\n", PrologueOffset, (uint64_t)*OffsetPtr);
  235. return false;
  236. }
  237. } else
  238. parseV2DirFileTables(DebugLineData, OffsetPtr, EndPrologueOffset,
  239. IncludeDirectories, FileNames);
  240. if (*OffsetPtr != EndPrologueOffset) {
  241. fprintf(stderr,
  242. "warning: parsing line table prologue at 0x%8.8" PRIx64
  243. " should have ended at 0x%8.8" PRIx64
  244. " but it ended at 0x%8.8" PRIx64 "\n",
  245. PrologueOffset, EndPrologueOffset, (uint64_t)*OffsetPtr);
  246. return false;
  247. }
  248. return true;
  249. }
  250. DWARFDebugLine::Row::Row(bool DefaultIsStmt) { reset(DefaultIsStmt); }
  251. void DWARFDebugLine::Row::postAppend() {
  252. BasicBlock = false;
  253. PrologueEnd = false;
  254. EpilogueBegin = false;
  255. }
  256. void DWARFDebugLine::Row::reset(bool DefaultIsStmt) {
  257. Address = 0;
  258. Line = 1;
  259. Column = 0;
  260. File = 1;
  261. Isa = 0;
  262. Discriminator = 0;
  263. IsStmt = DefaultIsStmt;
  264. BasicBlock = false;
  265. EndSequence = false;
  266. PrologueEnd = false;
  267. EpilogueBegin = false;
  268. }
  269. void DWARFDebugLine::Row::dumpTableHeader(raw_ostream &OS) {
  270. OS << "Address Line Column File ISA Discriminator Flags\n"
  271. << "------------------ ------ ------ ------ --- ------------- "
  272. "-------------\n";
  273. }
  274. void DWARFDebugLine::Row::dump(raw_ostream &OS) const {
  275. OS << format("0x%16.16" PRIx64 " %6u %6u", Address, Line, Column)
  276. << format(" %6u %3u %13u ", File, Isa, Discriminator)
  277. << (IsStmt ? " is_stmt" : "") << (BasicBlock ? " basic_block" : "")
  278. << (PrologueEnd ? " prologue_end" : "")
  279. << (EpilogueBegin ? " epilogue_begin" : "")
  280. << (EndSequence ? " end_sequence" : "") << '\n';
  281. }
  282. DWARFDebugLine::Sequence::Sequence() { reset(); }
  283. void DWARFDebugLine::Sequence::reset() {
  284. LowPC = 0;
  285. HighPC = 0;
  286. FirstRowIndex = 0;
  287. LastRowIndex = 0;
  288. Empty = true;
  289. }
  290. DWARFDebugLine::LineTable::LineTable() { clear(); }
  291. void DWARFDebugLine::LineTable::dump(raw_ostream &OS) const {
  292. Prologue.dump(OS);
  293. OS << '\n';
  294. if (!Rows.empty()) {
  295. Row::dumpTableHeader(OS);
  296. for (const Row &R : Rows) {
  297. R.dump(OS);
  298. }
  299. }
  300. }
  301. void DWARFDebugLine::LineTable::clear() {
  302. Prologue.clear();
  303. Rows.clear();
  304. Sequences.clear();
  305. }
  306. DWARFDebugLine::ParsingState::ParsingState(struct LineTable *LT)
  307. : LineTable(LT) {
  308. resetRowAndSequence();
  309. }
  310. void DWARFDebugLine::ParsingState::resetRowAndSequence() {
  311. Row.reset(LineTable->Prologue.DefaultIsStmt);
  312. Sequence.reset();
  313. }
  314. void DWARFDebugLine::ParsingState::appendRowToMatrix(uint32_t Offset) {
  315. if (Sequence.Empty) {
  316. // Record the beginning of instruction sequence.
  317. Sequence.Empty = false;
  318. Sequence.LowPC = Row.Address;
  319. Sequence.FirstRowIndex = RowNumber;
  320. }
  321. ++RowNumber;
  322. LineTable->appendRow(Row);
  323. if (Row.EndSequence) {
  324. // Record the end of instruction sequence.
  325. Sequence.HighPC = Row.Address;
  326. Sequence.LastRowIndex = RowNumber;
  327. if (Sequence.isValid())
  328. LineTable->appendSequence(Sequence);
  329. Sequence.reset();
  330. }
  331. Row.postAppend();
  332. }
  333. const DWARFDebugLine::LineTable *
  334. DWARFDebugLine::getLineTable(uint32_t Offset) const {
  335. LineTableConstIter Pos = LineTableMap.find(Offset);
  336. if (Pos != LineTableMap.end())
  337. return &Pos->second;
  338. return nullptr;
  339. }
  340. const DWARFDebugLine::LineTable *
  341. DWARFDebugLine::getOrParseLineTable(DataExtractor DebugLineData,
  342. uint32_t Offset) {
  343. std::pair<LineTableIter, bool> Pos =
  344. LineTableMap.insert(LineTableMapTy::value_type(Offset, LineTable()));
  345. LineTable *LT = &Pos.first->second;
  346. if (Pos.second) {
  347. if (!LT->parse(DebugLineData, RelocMap, &Offset))
  348. return nullptr;
  349. }
  350. return LT;
  351. }
  352. bool DWARFDebugLine::LineTable::parse(DataExtractor DebugLineData,
  353. const RelocAddrMap *RMap,
  354. uint32_t *OffsetPtr) {
  355. const uint32_t DebugLineOffset = *OffsetPtr;
  356. clear();
  357. if (!Prologue.parse(DebugLineData, OffsetPtr)) {
  358. // Restore our offset and return false to indicate failure!
  359. *OffsetPtr = DebugLineOffset;
  360. return false;
  361. }
  362. const uint32_t EndOffset =
  363. DebugLineOffset + Prologue.TotalLength + Prologue.sizeofTotalLength();
  364. ParsingState State(this);
  365. while (*OffsetPtr < EndOffset) {
  366. uint8_t Opcode = DebugLineData.getU8(OffsetPtr);
  367. if (Opcode == 0) {
  368. // Extended Opcodes always start with a zero opcode followed by
  369. // a uleb128 length so you can skip ones you don't know about
  370. uint32_t ExtOffset = *OffsetPtr;
  371. uint64_t Len = DebugLineData.getULEB128(OffsetPtr);
  372. uint32_t ArgSize = Len - (*OffsetPtr - ExtOffset);
  373. uint8_t SubOpcode = DebugLineData.getU8(OffsetPtr);
  374. switch (SubOpcode) {
  375. case DW_LNE_end_sequence:
  376. // Set the end_sequence register of the state machine to true and
  377. // append a row to the matrix using the current values of the
  378. // state-machine registers. Then reset the registers to the initial
  379. // values specified above. Every statement program sequence must end
  380. // with a DW_LNE_end_sequence instruction which creates a row whose
  381. // address is that of the byte after the last target machine instruction
  382. // of the sequence.
  383. State.Row.EndSequence = true;
  384. State.appendRowToMatrix(*OffsetPtr);
  385. State.resetRowAndSequence();
  386. break;
  387. case DW_LNE_set_address:
  388. // Takes a single relocatable address as an operand. The size of the
  389. // operand is the size appropriate to hold an address on the target
  390. // machine. Set the address register to the value given by the
  391. // relocatable address. All of the other statement program opcodes
  392. // that affect the address register add a delta to it. This instruction
  393. // stores a relocatable value into it instead.
  394. State.Row.Address = getRelocatedValue(
  395. DebugLineData, DebugLineData.getAddressSize(), OffsetPtr, RMap);
  396. break;
  397. case DW_LNE_define_file:
  398. // Takes 4 arguments. The first is a null terminated string containing
  399. // a source file name. The second is an unsigned LEB128 number
  400. // representing the directory index of the directory in which the file
  401. // was found. The third is an unsigned LEB128 number representing the
  402. // time of last modification of the file. The fourth is an unsigned
  403. // LEB128 number representing the length in bytes of the file. The time
  404. // and length fields may contain LEB128(0) if the information is not
  405. // available.
  406. //
  407. // The directory index represents an entry in the include_directories
  408. // section of the statement program prologue. The index is LEB128(0)
  409. // if the file was found in the current directory of the compilation,
  410. // LEB128(1) if it was found in the first directory in the
  411. // include_directories section, and so on. The directory index is
  412. // ignored for file names that represent full path names.
  413. //
  414. // The files are numbered, starting at 1, in the order in which they
  415. // appear; the names in the prologue come before names defined by
  416. // the DW_LNE_define_file instruction. These numbers are used in the
  417. // the file register of the state machine.
  418. {
  419. FileNameEntry FileEntry;
  420. FileEntry.Name = DebugLineData.getCStr(OffsetPtr);
  421. FileEntry.DirIdx = DebugLineData.getULEB128(OffsetPtr);
  422. FileEntry.ModTime = DebugLineData.getULEB128(OffsetPtr);
  423. FileEntry.Length = DebugLineData.getULEB128(OffsetPtr);
  424. Prologue.FileNames.push_back(FileEntry);
  425. }
  426. break;
  427. case DW_LNE_set_discriminator:
  428. State.Row.Discriminator = DebugLineData.getULEB128(OffsetPtr);
  429. break;
  430. default:
  431. // Length doesn't include the zero opcode byte or the length itself, but
  432. // it does include the sub_opcode, so we have to adjust for that below
  433. (*OffsetPtr) += ArgSize;
  434. break;
  435. }
  436. } else if (Opcode < Prologue.OpcodeBase) {
  437. switch (Opcode) {
  438. // Standard Opcodes
  439. case DW_LNS_copy:
  440. // Takes no arguments. Append a row to the matrix using the
  441. // current values of the state-machine registers. Then set
  442. // the basic_block register to false.
  443. State.appendRowToMatrix(*OffsetPtr);
  444. break;
  445. case DW_LNS_advance_pc:
  446. // Takes a single unsigned LEB128 operand, multiplies it by the
  447. // min_inst_length field of the prologue, and adds the
  448. // result to the address register of the state machine.
  449. State.Row.Address +=
  450. DebugLineData.getULEB128(OffsetPtr) * Prologue.MinInstLength;
  451. break;
  452. case DW_LNS_advance_line:
  453. // Takes a single signed LEB128 operand and adds that value to
  454. // the line register of the state machine.
  455. State.Row.Line += DebugLineData.getSLEB128(OffsetPtr);
  456. break;
  457. case DW_LNS_set_file:
  458. // Takes a single unsigned LEB128 operand and stores it in the file
  459. // register of the state machine.
  460. State.Row.File = DebugLineData.getULEB128(OffsetPtr);
  461. break;
  462. case DW_LNS_set_column:
  463. // Takes a single unsigned LEB128 operand and stores it in the
  464. // column register of the state machine.
  465. State.Row.Column = DebugLineData.getULEB128(OffsetPtr);
  466. break;
  467. case DW_LNS_negate_stmt:
  468. // Takes no arguments. Set the is_stmt register of the state
  469. // machine to the logical negation of its current value.
  470. State.Row.IsStmt = !State.Row.IsStmt;
  471. break;
  472. case DW_LNS_set_basic_block:
  473. // Takes no arguments. Set the basic_block register of the
  474. // state machine to true
  475. State.Row.BasicBlock = true;
  476. break;
  477. case DW_LNS_const_add_pc:
  478. // Takes no arguments. Add to the address register of the state
  479. // machine the address increment value corresponding to special
  480. // opcode 255. The motivation for DW_LNS_const_add_pc is this:
  481. // when the statement program needs to advance the address by a
  482. // small amount, it can use a single special opcode, which occupies
  483. // a single byte. When it needs to advance the address by up to
  484. // twice the range of the last special opcode, it can use
  485. // DW_LNS_const_add_pc followed by a special opcode, for a total
  486. // of two bytes. Only if it needs to advance the address by more
  487. // than twice that range will it need to use both DW_LNS_advance_pc
  488. // and a special opcode, requiring three or more bytes.
  489. {
  490. uint8_t AdjustOpcode = 255 - Prologue.OpcodeBase;
  491. uint64_t AddrOffset =
  492. (AdjustOpcode / Prologue.LineRange) * Prologue.MinInstLength;
  493. State.Row.Address += AddrOffset;
  494. }
  495. break;
  496. case DW_LNS_fixed_advance_pc:
  497. // Takes a single uhalf operand. Add to the address register of
  498. // the state machine the value of the (unencoded) operand. This
  499. // is the only extended opcode that takes an argument that is not
  500. // a variable length number. The motivation for DW_LNS_fixed_advance_pc
  501. // is this: existing assemblers cannot emit DW_LNS_advance_pc or
  502. // special opcodes because they cannot encode LEB128 numbers or
  503. // judge when the computation of a special opcode overflows and
  504. // requires the use of DW_LNS_advance_pc. Such assemblers, however,
  505. // can use DW_LNS_fixed_advance_pc instead, sacrificing compression.
  506. State.Row.Address += DebugLineData.getU16(OffsetPtr);
  507. break;
  508. case DW_LNS_set_prologue_end:
  509. // Takes no arguments. Set the prologue_end register of the
  510. // state machine to true
  511. State.Row.PrologueEnd = true;
  512. break;
  513. case DW_LNS_set_epilogue_begin:
  514. // Takes no arguments. Set the basic_block register of the
  515. // state machine to true
  516. State.Row.EpilogueBegin = true;
  517. break;
  518. case DW_LNS_set_isa:
  519. // Takes a single unsigned LEB128 operand and stores it in the
  520. // column register of the state machine.
  521. State.Row.Isa = DebugLineData.getULEB128(OffsetPtr);
  522. break;
  523. default:
  524. // Handle any unknown standard opcodes here. We know the lengths
  525. // of such opcodes because they are specified in the prologue
  526. // as a multiple of LEB128 operands for each opcode.
  527. {
  528. assert(Opcode - 1U < Prologue.StandardOpcodeLengths.size());
  529. uint8_t OpcodeLength = Prologue.StandardOpcodeLengths[Opcode - 1];
  530. for (uint8_t I = 0; I < OpcodeLength; ++I)
  531. DebugLineData.getULEB128(OffsetPtr);
  532. }
  533. break;
  534. }
  535. } else {
  536. // Special Opcodes
  537. // A special opcode value is chosen based on the amount that needs
  538. // to be added to the line and address registers. The maximum line
  539. // increment for a special opcode is the value of the line_base
  540. // field in the header, plus the value of the line_range field,
  541. // minus 1 (line base + line range - 1). If the desired line
  542. // increment is greater than the maximum line increment, a standard
  543. // opcode must be used instead of a special opcode. The "address
  544. // advance" is calculated by dividing the desired address increment
  545. // by the minimum_instruction_length field from the header. The
  546. // special opcode is then calculated using the following formula:
  547. //
  548. // opcode = (desired line increment - line_base) +
  549. // (line_range * address advance) + opcode_base
  550. //
  551. // If the resulting opcode is greater than 255, a standard opcode
  552. // must be used instead.
  553. //
  554. // To decode a special opcode, subtract the opcode_base from the
  555. // opcode itself to give the adjusted opcode. The amount to
  556. // increment the address register is the result of the adjusted
  557. // opcode divided by the line_range multiplied by the
  558. // minimum_instruction_length field from the header. That is:
  559. //
  560. // address increment = (adjusted opcode / line_range) *
  561. // minimum_instruction_length
  562. //
  563. // The amount to increment the line register is the line_base plus
  564. // the result of the adjusted opcode modulo the line_range. That is:
  565. //
  566. // line increment = line_base + (adjusted opcode % line_range)
  567. uint8_t AdjustOpcode = Opcode - Prologue.OpcodeBase;
  568. uint64_t AddrOffset =
  569. (AdjustOpcode / Prologue.LineRange) * Prologue.MinInstLength;
  570. int32_t LineOffset =
  571. Prologue.LineBase + (AdjustOpcode % Prologue.LineRange);
  572. State.Row.Line += LineOffset;
  573. State.Row.Address += AddrOffset;
  574. State.appendRowToMatrix(*OffsetPtr);
  575. // Reset discriminator to 0.
  576. State.Row.Discriminator = 0;
  577. }
  578. }
  579. if (!State.Sequence.Empty) {
  580. fprintf(stderr, "warning: last sequence in debug line table is not"
  581. "terminated!\n");
  582. }
  583. // Sort all sequences so that address lookup will work faster.
  584. if (!Sequences.empty()) {
  585. std::sort(Sequences.begin(), Sequences.end(), Sequence::orderByLowPC);
  586. // Note: actually, instruction address ranges of sequences should not
  587. // overlap (in shared objects and executables). If they do, the address
  588. // lookup would still work, though, but result would be ambiguous.
  589. // We don't report warning in this case. For example,
  590. // sometimes .so compiled from multiple object files contains a few
  591. // rudimentary sequences for address ranges [0x0, 0xsomething).
  592. }
  593. return EndOffset;
  594. }
  595. uint32_t
  596. DWARFDebugLine::LineTable::findRowInSeq(const DWARFDebugLine::Sequence &Seq,
  597. uint64_t Address) const {
  598. if (!Seq.containsPC(Address))
  599. return UnknownRowIndex;
  600. // Search for instruction address in the rows describing the sequence.
  601. // Rows are stored in a vector, so we may use arithmetical operations with
  602. // iterators.
  603. DWARFDebugLine::Row Row;
  604. Row.Address = Address;
  605. RowIter FirstRow = Rows.begin() + Seq.FirstRowIndex;
  606. RowIter LastRow = Rows.begin() + Seq.LastRowIndex;
  607. LineTable::RowIter RowPos = std::lower_bound(
  608. FirstRow, LastRow, Row, DWARFDebugLine::Row::orderByAddress);
  609. if (RowPos == LastRow) {
  610. return Seq.LastRowIndex - 1;
  611. }
  612. uint32_t Index = Seq.FirstRowIndex + (RowPos - FirstRow);
  613. if (RowPos->Address > Address) {
  614. if (RowPos == FirstRow)
  615. return UnknownRowIndex;
  616. else
  617. Index--;
  618. }
  619. return Index;
  620. }
  621. uint32_t DWARFDebugLine::LineTable::lookupAddress(uint64_t Address) const {
  622. if (Sequences.empty())
  623. return UnknownRowIndex;
  624. // First, find an instruction sequence containing the given address.
  625. DWARFDebugLine::Sequence Sequence;
  626. Sequence.LowPC = Address;
  627. SequenceIter FirstSeq = Sequences.begin();
  628. SequenceIter LastSeq = Sequences.end();
  629. SequenceIter SeqPos = std::lower_bound(
  630. FirstSeq, LastSeq, Sequence, DWARFDebugLine::Sequence::orderByLowPC);
  631. DWARFDebugLine::Sequence FoundSeq;
  632. if (SeqPos == LastSeq) {
  633. FoundSeq = Sequences.back();
  634. } else if (SeqPos->LowPC == Address) {
  635. FoundSeq = *SeqPos;
  636. } else {
  637. if (SeqPos == FirstSeq)
  638. return UnknownRowIndex;
  639. FoundSeq = *(SeqPos - 1);
  640. }
  641. return findRowInSeq(FoundSeq, Address);
  642. }
  643. bool DWARFDebugLine::LineTable::lookupAddressRange(
  644. uint64_t Address, uint64_t Size, std::vector<uint32_t> &Result) const {
  645. if (Sequences.empty())
  646. return false;
  647. uint64_t EndAddr = Address + Size;
  648. // First, find an instruction sequence containing the given address.
  649. DWARFDebugLine::Sequence Sequence;
  650. Sequence.LowPC = Address;
  651. SequenceIter FirstSeq = Sequences.begin();
  652. SequenceIter LastSeq = Sequences.end();
  653. SequenceIter SeqPos = std::lower_bound(
  654. FirstSeq, LastSeq, Sequence, DWARFDebugLine::Sequence::orderByLowPC);
  655. if (SeqPos == LastSeq || SeqPos->LowPC != Address) {
  656. if (SeqPos == FirstSeq)
  657. return false;
  658. SeqPos--;
  659. }
  660. if (!SeqPos->containsPC(Address))
  661. return false;
  662. SequenceIter StartPos = SeqPos;
  663. // Add the rows from the first sequence to the vector, starting with the
  664. // index we just calculated
  665. while (SeqPos != LastSeq && SeqPos->LowPC < EndAddr) {
  666. const DWARFDebugLine::Sequence &CurSeq = *SeqPos;
  667. // For the first sequence, we need to find which row in the sequence is the
  668. // first in our range.
  669. uint32_t FirstRowIndex = CurSeq.FirstRowIndex;
  670. if (SeqPos == StartPos)
  671. FirstRowIndex = findRowInSeq(CurSeq, Address);
  672. // Figure out the last row in the range.
  673. uint32_t LastRowIndex = findRowInSeq(CurSeq, EndAddr - 1);
  674. if (LastRowIndex == UnknownRowIndex)
  675. LastRowIndex = CurSeq.LastRowIndex - 1;
  676. assert(FirstRowIndex != UnknownRowIndex);
  677. assert(LastRowIndex != UnknownRowIndex);
  678. for (uint32_t I = FirstRowIndex; I <= LastRowIndex; ++I) {
  679. Result.push_back(I);
  680. }
  681. ++SeqPos;
  682. }
  683. return true;
  684. }
  685. bool DWARFDebugLine::LineTable::hasFileAtIndex(uint64_t FileIndex) const {
  686. return FileIndex != 0 && FileIndex <= Prologue.FileNames.size();
  687. }
  688. bool DWARFDebugLine::LineTable::getFileNameByIndex(uint64_t FileIndex,
  689. const char *CompDir,
  690. FileLineInfoKind Kind,
  691. std::string &Result) const {
  692. if (Kind == FileLineInfoKind::None || !hasFileAtIndex(FileIndex))
  693. return false;
  694. const FileNameEntry &Entry = Prologue.FileNames[FileIndex - 1];
  695. StringRef FileName = Entry.Name;
  696. if (Kind != FileLineInfoKind::AbsoluteFilePath ||
  697. sys::path::is_absolute(FileName)) {
  698. Result = FileName;
  699. return true;
  700. }
  701. SmallString<16> FilePath;
  702. uint64_t IncludeDirIndex = Entry.DirIdx;
  703. StringRef IncludeDir;
  704. // Be defensive about the contents of Entry.
  705. if (IncludeDirIndex > 0 &&
  706. IncludeDirIndex <= Prologue.IncludeDirectories.size())
  707. IncludeDir = Prologue.IncludeDirectories[IncludeDirIndex - 1];
  708. // We may still need to append compilation directory of compile unit.
  709. // We know that FileName is not absolute, the only way to have an
  710. // absolute path at this point would be if IncludeDir is absolute.
  711. if (CompDir && Kind == FileLineInfoKind::AbsoluteFilePath &&
  712. sys::path::is_relative(IncludeDir))
  713. sys::path::append(FilePath, CompDir);
  714. // sys::path::append skips empty strings.
  715. sys::path::append(FilePath, IncludeDir, FileName);
  716. Result = FilePath.str();
  717. return true;
  718. }
  719. bool DWARFDebugLine::LineTable::getFileLineInfoForAddress(
  720. uint64_t Address, const char *CompDir, FileLineInfoKind Kind,
  721. DILineInfo &Result) const {
  722. // Get the index of row we're looking for in the line table.
  723. uint32_t RowIndex = lookupAddress(Address);
  724. if (RowIndex == -1U)
  725. return false;
  726. // Take file number and line/column from the row.
  727. const auto &Row = Rows[RowIndex];
  728. if (!getFileNameByIndex(Row.File, CompDir, Kind, Result.FileName))
  729. return false;
  730. Result.Line = Row.Line;
  731. Result.Column = Row.Column;
  732. Result.Discriminator = Row.Discriminator;
  733. return true;
  734. }