DWARFDebugLoc.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  1. //===- DWARFDebugLoc.cpp --------------------------------------------------===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. #include "llvm/DebugInfo/DWARF/DWARFDebugLoc.h"
  9. #include "llvm/ADT/StringRef.h"
  10. #include "llvm/BinaryFormat/Dwarf.h"
  11. #include "llvm/DebugInfo/DWARF/DWARFContext.h"
  12. #include "llvm/DebugInfo/DWARF/DWARFExpression.h"
  13. #include "llvm/DebugInfo/DWARF/DWARFRelocMap.h"
  14. #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
  15. #include "llvm/Support/Compiler.h"
  16. #include "llvm/Support/Format.h"
  17. #include "llvm/Support/WithColor.h"
  18. #include "llvm/Support/raw_ostream.h"
  19. #include <algorithm>
  20. #include <cinttypes>
  21. #include <cstdint>
  22. using namespace llvm;
  23. using object::SectionedAddress;
  24. namespace {
  25. class DWARFLocationInterpreter {
  26. Optional<object::SectionedAddress> Base;
  27. std::function<Optional<object::SectionedAddress>(uint32_t)> LookupAddr;
  28. public:
  29. DWARFLocationInterpreter(
  30. Optional<object::SectionedAddress> Base,
  31. std::function<Optional<object::SectionedAddress>(uint32_t)> LookupAddr)
  32. : Base(Base), LookupAddr(std::move(LookupAddr)) {}
  33. Expected<Optional<DWARFLocationExpression>>
  34. Interpret(const DWARFLocationEntry &E);
  35. };
  36. } // namespace
  37. static Error createResolverError(uint32_t Index, unsigned Kind) {
  38. return make_error<ResolverError>(Index, (dwarf::LoclistEntries)Kind);
  39. }
  40. Expected<Optional<DWARFLocationExpression>>
  41. DWARFLocationInterpreter::Interpret(const DWARFLocationEntry &E) {
  42. switch (E.Kind) {
  43. case dwarf::DW_LLE_end_of_list:
  44. return None;
  45. case dwarf::DW_LLE_base_addressx: {
  46. Base = LookupAddr(E.Value0);
  47. if (!Base)
  48. return createResolverError(E.Value0, E.Kind);
  49. return None;
  50. }
  51. case dwarf::DW_LLE_startx_endx: {
  52. Optional<SectionedAddress> LowPC = LookupAddr(E.Value0);
  53. if (!LowPC)
  54. return createResolverError(E.Value0, E.Kind);
  55. Optional<SectionedAddress> HighPC = LookupAddr(E.Value1);
  56. if (!HighPC)
  57. return createResolverError(E.Value1, E.Kind);
  58. return DWARFLocationExpression{
  59. DWARFAddressRange{LowPC->Address, HighPC->Address, LowPC->SectionIndex},
  60. E.Loc};
  61. }
  62. case dwarf::DW_LLE_startx_length: {
  63. Optional<SectionedAddress> LowPC = LookupAddr(E.Value0);
  64. if (!LowPC)
  65. return createResolverError(E.Value0, E.Kind);
  66. return DWARFLocationExpression{DWARFAddressRange{LowPC->Address,
  67. LowPC->Address + E.Value1,
  68. LowPC->SectionIndex},
  69. E.Loc};
  70. }
  71. case dwarf::DW_LLE_offset_pair: {
  72. if (!Base) {
  73. return createStringError(inconvertibleErrorCode(),
  74. "Unable to resolve location list offset pair: "
  75. "Base address not defined");
  76. }
  77. DWARFAddressRange Range{Base->Address + E.Value0, Base->Address + E.Value1,
  78. Base->SectionIndex};
  79. if (Range.SectionIndex == SectionedAddress::UndefSection)
  80. Range.SectionIndex = E.SectionIndex;
  81. return DWARFLocationExpression{Range, E.Loc};
  82. }
  83. case dwarf::DW_LLE_default_location:
  84. return DWARFLocationExpression{None, E.Loc};
  85. case dwarf::DW_LLE_base_address:
  86. Base = SectionedAddress{E.Value0, E.SectionIndex};
  87. return None;
  88. case dwarf::DW_LLE_start_end:
  89. return DWARFLocationExpression{
  90. DWARFAddressRange{E.Value0, E.Value1, E.SectionIndex}, E.Loc};
  91. case dwarf::DW_LLE_start_length:
  92. return DWARFLocationExpression{
  93. DWARFAddressRange{E.Value0, E.Value0 + E.Value1, E.SectionIndex},
  94. E.Loc};
  95. default:
  96. llvm_unreachable("unreachable locations list kind");
  97. }
  98. }
  99. static void dumpExpression(raw_ostream &OS, DIDumpOptions DumpOpts,
  100. ArrayRef<uint8_t> Data, bool IsLittleEndian,
  101. unsigned AddressSize, const MCRegisterInfo *MRI,
  102. DWARFUnit *U) {
  103. DWARFDataExtractor Extractor(Data, IsLittleEndian, AddressSize);
  104. // Note. We do not pass any format to DWARFExpression, even if the
  105. // corresponding unit is known. For now, there is only one operation,
  106. // DW_OP_call_ref, which depends on the format; it is rarely used, and
  107. // is unexpected in location tables.
  108. DWARFExpression(Extractor, AddressSize).print(OS, DumpOpts, MRI, U);
  109. }
  110. bool DWARFLocationTable::dumpLocationList(uint64_t *Offset, raw_ostream &OS,
  111. Optional<SectionedAddress> BaseAddr,
  112. const MCRegisterInfo *MRI,
  113. const DWARFObject &Obj, DWARFUnit *U,
  114. DIDumpOptions DumpOpts,
  115. unsigned Indent) const {
  116. DWARFLocationInterpreter Interp(
  117. BaseAddr, [U](uint32_t Index) -> Optional<SectionedAddress> {
  118. if (U)
  119. return U->getAddrOffsetSectionItem(Index);
  120. return None;
  121. });
  122. OS << format("0x%8.8" PRIx64 ": ", *Offset);
  123. Error E = visitLocationList(Offset, [&](const DWARFLocationEntry &E) {
  124. Expected<Optional<DWARFLocationExpression>> Loc = Interp.Interpret(E);
  125. if (!Loc || DumpOpts.DisplayRawContents)
  126. dumpRawEntry(E, OS, Indent, DumpOpts, Obj);
  127. if (Loc && *Loc) {
  128. OS << "\n";
  129. OS.indent(Indent);
  130. if (DumpOpts.DisplayRawContents)
  131. OS << " => ";
  132. DIDumpOptions RangeDumpOpts(DumpOpts);
  133. RangeDumpOpts.DisplayRawContents = false;
  134. if (Loc.get()->Range)
  135. Loc.get()->Range->dump(OS, Data.getAddressSize(), RangeDumpOpts, &Obj);
  136. else
  137. OS << "<default>";
  138. }
  139. if (!Loc)
  140. consumeError(Loc.takeError());
  141. if (E.Kind != dwarf::DW_LLE_base_address &&
  142. E.Kind != dwarf::DW_LLE_base_addressx &&
  143. E.Kind != dwarf::DW_LLE_end_of_list) {
  144. OS << ": ";
  145. dumpExpression(OS, DumpOpts, E.Loc, Data.isLittleEndian(),
  146. Data.getAddressSize(), MRI, U);
  147. }
  148. return true;
  149. });
  150. if (E) {
  151. DumpOpts.RecoverableErrorHandler(std::move(E));
  152. return false;
  153. }
  154. return true;
  155. }
  156. Error DWARFLocationTable::visitAbsoluteLocationList(
  157. uint64_t Offset, Optional<SectionedAddress> BaseAddr,
  158. std::function<Optional<SectionedAddress>(uint32_t)> LookupAddr,
  159. function_ref<bool(Expected<DWARFLocationExpression>)> Callback) const {
  160. DWARFLocationInterpreter Interp(BaseAddr, std::move(LookupAddr));
  161. return visitLocationList(&Offset, [&](const DWARFLocationEntry &E) {
  162. Expected<Optional<DWARFLocationExpression>> Loc = Interp.Interpret(E);
  163. if (!Loc)
  164. return Callback(Loc.takeError());
  165. if (*Loc)
  166. return Callback(**Loc);
  167. return true;
  168. });
  169. }
  170. void DWARFDebugLoc::dump(raw_ostream &OS, const MCRegisterInfo *MRI,
  171. const DWARFObject &Obj, DIDumpOptions DumpOpts,
  172. Optional<uint64_t> DumpOffset) const {
  173. auto BaseAddr = None;
  174. unsigned Indent = 12;
  175. if (DumpOffset) {
  176. dumpLocationList(&*DumpOffset, OS, BaseAddr, MRI, Obj, nullptr, DumpOpts,
  177. Indent);
  178. } else {
  179. uint64_t Offset = 0;
  180. StringRef Separator;
  181. bool CanContinue = true;
  182. while (CanContinue && Data.isValidOffset(Offset)) {
  183. OS << Separator;
  184. Separator = "\n";
  185. CanContinue = dumpLocationList(&Offset, OS, BaseAddr, MRI, Obj, nullptr,
  186. DumpOpts, Indent);
  187. OS << '\n';
  188. }
  189. }
  190. }
  191. Error DWARFDebugLoc::visitLocationList(
  192. uint64_t *Offset,
  193. function_ref<bool(const DWARFLocationEntry &)> Callback) const {
  194. DataExtractor::Cursor C(*Offset);
  195. while (true) {
  196. uint64_t SectionIndex;
  197. uint64_t Value0 = Data.getRelocatedAddress(C);
  198. uint64_t Value1 = Data.getRelocatedAddress(C, &SectionIndex);
  199. DWARFLocationEntry E;
  200. // The end of any given location list is marked by an end of list entry,
  201. // which consists of a 0 for the beginning address offset and a 0 for the
  202. // ending address offset. A beginning offset of 0xff...f marks the base
  203. // address selection entry.
  204. if (Value0 == 0 && Value1 == 0) {
  205. E.Kind = dwarf::DW_LLE_end_of_list;
  206. } else if (Value0 == (Data.getAddressSize() == 4 ? -1U : -1ULL)) {
  207. E.Kind = dwarf::DW_LLE_base_address;
  208. E.Value0 = Value1;
  209. E.SectionIndex = SectionIndex;
  210. } else {
  211. E.Kind = dwarf::DW_LLE_offset_pair;
  212. E.Value0 = Value0;
  213. E.Value1 = Value1;
  214. E.SectionIndex = SectionIndex;
  215. unsigned Bytes = Data.getU16(C);
  216. // A single location description describing the location of the object...
  217. Data.getU8(C, E.Loc, Bytes);
  218. }
  219. if (!C)
  220. return C.takeError();
  221. if (!Callback(E) || E.Kind == dwarf::DW_LLE_end_of_list)
  222. break;
  223. }
  224. *Offset = C.tell();
  225. return Error::success();
  226. }
  227. void DWARFDebugLoc::dumpRawEntry(const DWARFLocationEntry &Entry,
  228. raw_ostream &OS, unsigned Indent,
  229. DIDumpOptions DumpOpts,
  230. const DWARFObject &Obj) const {
  231. uint64_t Value0, Value1;
  232. switch (Entry.Kind) {
  233. case dwarf::DW_LLE_base_address:
  234. Value0 = Data.getAddressSize() == 4 ? -1U : -1ULL;
  235. Value1 = Entry.Value0;
  236. break;
  237. case dwarf::DW_LLE_offset_pair:
  238. Value0 = Entry.Value0;
  239. Value1 = Entry.Value1;
  240. break;
  241. case dwarf::DW_LLE_end_of_list:
  242. return;
  243. default:
  244. llvm_unreachable("Not possible in DWARF4!");
  245. }
  246. OS << '\n';
  247. OS.indent(Indent);
  248. OS << '(' << format_hex(Value0, 2 + Data.getAddressSize() * 2) << ", "
  249. << format_hex(Value1, 2 + Data.getAddressSize() * 2) << ')';
  250. DWARFFormValue::dumpAddressSection(Obj, OS, DumpOpts, Entry.SectionIndex);
  251. }
  252. Error DWARFDebugLoclists::visitLocationList(
  253. uint64_t *Offset, function_ref<bool(const DWARFLocationEntry &)> F) const {
  254. DataExtractor::Cursor C(*Offset);
  255. bool Continue = true;
  256. while (Continue) {
  257. DWARFLocationEntry E;
  258. E.Kind = Data.getU8(C);
  259. switch (E.Kind) {
  260. case dwarf::DW_LLE_end_of_list:
  261. break;
  262. case dwarf::DW_LLE_base_addressx:
  263. E.Value0 = Data.getULEB128(C);
  264. break;
  265. case dwarf::DW_LLE_startx_endx:
  266. E.Value0 = Data.getULEB128(C);
  267. E.Value1 = Data.getULEB128(C);
  268. break;
  269. case dwarf::DW_LLE_startx_length:
  270. E.Value0 = Data.getULEB128(C);
  271. // Pre-DWARF 5 has different interpretation of the length field. We have
  272. // to support both pre- and standartized styles for the compatibility.
  273. if (Version < 5)
  274. E.Value1 = Data.getU32(C);
  275. else
  276. E.Value1 = Data.getULEB128(C);
  277. break;
  278. case dwarf::DW_LLE_offset_pair:
  279. E.Value0 = Data.getULEB128(C);
  280. E.Value1 = Data.getULEB128(C);
  281. E.SectionIndex = SectionedAddress::UndefSection;
  282. break;
  283. case dwarf::DW_LLE_default_location:
  284. break;
  285. case dwarf::DW_LLE_base_address:
  286. E.Value0 = Data.getRelocatedAddress(C, &E.SectionIndex);
  287. break;
  288. case dwarf::DW_LLE_start_end:
  289. E.Value0 = Data.getRelocatedAddress(C, &E.SectionIndex);
  290. E.Value1 = Data.getRelocatedAddress(C);
  291. break;
  292. case dwarf::DW_LLE_start_length:
  293. E.Value0 = Data.getRelocatedAddress(C, &E.SectionIndex);
  294. E.Value1 = Data.getULEB128(C);
  295. break;
  296. default:
  297. cantFail(C.takeError());
  298. return createStringError(errc::illegal_byte_sequence,
  299. "LLE of kind %x not supported", (int)E.Kind);
  300. }
  301. if (E.Kind != dwarf::DW_LLE_base_address &&
  302. E.Kind != dwarf::DW_LLE_base_addressx &&
  303. E.Kind != dwarf::DW_LLE_end_of_list) {
  304. unsigned Bytes = Version >= 5 ? Data.getULEB128(C) : Data.getU16(C);
  305. // A single location description describing the location of the object...
  306. Data.getU8(C, E.Loc, Bytes);
  307. }
  308. if (!C)
  309. return C.takeError();
  310. Continue = F(E) && E.Kind != dwarf::DW_LLE_end_of_list;
  311. }
  312. *Offset = C.tell();
  313. return Error::success();
  314. }
  315. void DWARFDebugLoclists::dumpRawEntry(const DWARFLocationEntry &Entry,
  316. raw_ostream &OS, unsigned Indent,
  317. DIDumpOptions DumpOpts,
  318. const DWARFObject &Obj) const {
  319. size_t MaxEncodingStringLength = 0;
  320. #define HANDLE_DW_LLE(ID, NAME) \
  321. MaxEncodingStringLength = std::max(MaxEncodingStringLength, \
  322. dwarf::LocListEncodingString(ID).size());
  323. #include "llvm/BinaryFormat/Dwarf.def"
  324. OS << "\n";
  325. OS.indent(Indent);
  326. StringRef EncodingString = dwarf::LocListEncodingString(Entry.Kind);
  327. // Unsupported encodings should have been reported during parsing.
  328. assert(!EncodingString.empty() && "Unknown loclist entry encoding");
  329. OS << format("%-*s(", MaxEncodingStringLength, EncodingString.data());
  330. unsigned FieldSize = 2 + 2 * Data.getAddressSize();
  331. switch (Entry.Kind) {
  332. case dwarf::DW_LLE_end_of_list:
  333. case dwarf::DW_LLE_default_location:
  334. break;
  335. case dwarf::DW_LLE_startx_endx:
  336. case dwarf::DW_LLE_startx_length:
  337. case dwarf::DW_LLE_offset_pair:
  338. case dwarf::DW_LLE_start_end:
  339. case dwarf::DW_LLE_start_length:
  340. OS << format_hex(Entry.Value0, FieldSize) << ", "
  341. << format_hex(Entry.Value1, FieldSize);
  342. break;
  343. case dwarf::DW_LLE_base_addressx:
  344. case dwarf::DW_LLE_base_address:
  345. OS << format_hex(Entry.Value0, FieldSize);
  346. break;
  347. }
  348. OS << ')';
  349. switch (Entry.Kind) {
  350. case dwarf::DW_LLE_base_address:
  351. case dwarf::DW_LLE_start_end:
  352. case dwarf::DW_LLE_start_length:
  353. DWARFFormValue::dumpAddressSection(Obj, OS, DumpOpts, Entry.SectionIndex);
  354. break;
  355. default:
  356. break;
  357. }
  358. }
  359. void DWARFDebugLoclists::dumpRange(uint64_t StartOffset, uint64_t Size,
  360. raw_ostream &OS, const MCRegisterInfo *MRI,
  361. const DWARFObject &Obj,
  362. DIDumpOptions DumpOpts) {
  363. if (!Data.isValidOffsetForDataOfSize(StartOffset, Size)) {
  364. OS << "Invalid dump range\n";
  365. return;
  366. }
  367. uint64_t Offset = StartOffset;
  368. StringRef Separator;
  369. bool CanContinue = true;
  370. while (CanContinue && Offset < StartOffset + Size) {
  371. OS << Separator;
  372. Separator = "\n";
  373. CanContinue = dumpLocationList(&Offset, OS, /*BaseAddr=*/None, MRI, Obj,
  374. nullptr, DumpOpts, /*Indent=*/12);
  375. OS << '\n';
  376. }
  377. }
  378. void llvm::ResolverError::log(raw_ostream &OS) const {
  379. OS << format("unable to resolve indirect address %u for: %s", Index,
  380. dwarf::LocListEncodingString(Kind).data());
  381. }
  382. char llvm::ResolverError::ID;