DWARFDebugLoc.cpp 14 KB

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