DWARFFormValue.cpp 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787
  1. //===- DWARFFormValue.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/DWARFFormValue.h"
  9. #include "llvm/ADT/ArrayRef.h"
  10. #include "llvm/ADT/StringRef.h"
  11. #include "llvm/BinaryFormat/Dwarf.h"
  12. #include "llvm/DebugInfo/DWARF/DWARFContext.h"
  13. #include "llvm/DebugInfo/DWARF/DWARFDataExtractor.h"
  14. #include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
  15. #include "llvm/DebugInfo/DWARF/DWARFObject.h"
  16. #include "llvm/DebugInfo/DWARF/DWARFSection.h"
  17. #include "llvm/DebugInfo/DWARF/DWARFUnit.h"
  18. #include "llvm/Support/ErrorHandling.h"
  19. #include "llvm/Support/Format.h"
  20. #include "llvm/Support/WithColor.h"
  21. #include "llvm/Support/raw_ostream.h"
  22. #include <cinttypes>
  23. #include <cstdint>
  24. #include <limits>
  25. #include <optional>
  26. using namespace llvm;
  27. using namespace dwarf;
  28. static const DWARFFormValue::FormClass DWARF5FormClasses[] = {
  29. DWARFFormValue::FC_Unknown, // 0x0
  30. DWARFFormValue::FC_Address, // 0x01 DW_FORM_addr
  31. DWARFFormValue::FC_Unknown, // 0x02 unused
  32. DWARFFormValue::FC_Block, // 0x03 DW_FORM_block2
  33. DWARFFormValue::FC_Block, // 0x04 DW_FORM_block4
  34. DWARFFormValue::FC_Constant, // 0x05 DW_FORM_data2
  35. // --- These can be FC_SectionOffset in DWARF3 and below:
  36. DWARFFormValue::FC_Constant, // 0x06 DW_FORM_data4
  37. DWARFFormValue::FC_Constant, // 0x07 DW_FORM_data8
  38. // ---
  39. DWARFFormValue::FC_String, // 0x08 DW_FORM_string
  40. DWARFFormValue::FC_Block, // 0x09 DW_FORM_block
  41. DWARFFormValue::FC_Block, // 0x0a DW_FORM_block1
  42. DWARFFormValue::FC_Constant, // 0x0b DW_FORM_data1
  43. DWARFFormValue::FC_Flag, // 0x0c DW_FORM_flag
  44. DWARFFormValue::FC_Constant, // 0x0d DW_FORM_sdata
  45. DWARFFormValue::FC_String, // 0x0e DW_FORM_strp
  46. DWARFFormValue::FC_Constant, // 0x0f DW_FORM_udata
  47. DWARFFormValue::FC_Reference, // 0x10 DW_FORM_ref_addr
  48. DWARFFormValue::FC_Reference, // 0x11 DW_FORM_ref1
  49. DWARFFormValue::FC_Reference, // 0x12 DW_FORM_ref2
  50. DWARFFormValue::FC_Reference, // 0x13 DW_FORM_ref4
  51. DWARFFormValue::FC_Reference, // 0x14 DW_FORM_ref8
  52. DWARFFormValue::FC_Reference, // 0x15 DW_FORM_ref_udata
  53. DWARFFormValue::FC_Indirect, // 0x16 DW_FORM_indirect
  54. DWARFFormValue::FC_SectionOffset, // 0x17 DW_FORM_sec_offset
  55. DWARFFormValue::FC_Exprloc, // 0x18 DW_FORM_exprloc
  56. DWARFFormValue::FC_Flag, // 0x19 DW_FORM_flag_present
  57. DWARFFormValue::FC_String, // 0x1a DW_FORM_strx
  58. DWARFFormValue::FC_Address, // 0x1b DW_FORM_addrx
  59. DWARFFormValue::FC_Reference, // 0x1c DW_FORM_ref_sup4
  60. DWARFFormValue::FC_String, // 0x1d DW_FORM_strp_sup
  61. DWARFFormValue::FC_Constant, // 0x1e DW_FORM_data16
  62. DWARFFormValue::FC_String, // 0x1f DW_FORM_line_strp
  63. DWARFFormValue::FC_Reference, // 0x20 DW_FORM_ref_sig8
  64. DWARFFormValue::FC_Constant, // 0x21 DW_FORM_implicit_const
  65. DWARFFormValue::FC_SectionOffset, // 0x22 DW_FORM_loclistx
  66. DWARFFormValue::FC_SectionOffset, // 0x23 DW_FORM_rnglistx
  67. DWARFFormValue::FC_Reference, // 0x24 DW_FORM_ref_sup8
  68. DWARFFormValue::FC_String, // 0x25 DW_FORM_strx1
  69. DWARFFormValue::FC_String, // 0x26 DW_FORM_strx2
  70. DWARFFormValue::FC_String, // 0x27 DW_FORM_strx3
  71. DWARFFormValue::FC_String, // 0x28 DW_FORM_strx4
  72. DWARFFormValue::FC_Address, // 0x29 DW_FORM_addrx1
  73. DWARFFormValue::FC_Address, // 0x2a DW_FORM_addrx2
  74. DWARFFormValue::FC_Address, // 0x2b DW_FORM_addrx3
  75. DWARFFormValue::FC_Address, // 0x2c DW_FORM_addrx4
  76. DWARFFormValue::FC_Address, // 0x2001 DW_FORM_addrx_offset
  77. };
  78. DWARFFormValue DWARFFormValue::createFromSValue(dwarf::Form F, int64_t V) {
  79. return DWARFFormValue(F, ValueType(V));
  80. }
  81. DWARFFormValue DWARFFormValue::createFromUValue(dwarf::Form F, uint64_t V) {
  82. return DWARFFormValue(F, ValueType(V));
  83. }
  84. DWARFFormValue DWARFFormValue::createFromPValue(dwarf::Form F, const char *V) {
  85. return DWARFFormValue(F, ValueType(V));
  86. }
  87. DWARFFormValue DWARFFormValue::createFromBlockValue(dwarf::Form F,
  88. ArrayRef<uint8_t> D) {
  89. ValueType V;
  90. V.uval = D.size();
  91. V.data = D.data();
  92. return DWARFFormValue(F, V);
  93. }
  94. DWARFFormValue DWARFFormValue::createFromUnit(dwarf::Form F, const DWARFUnit *U,
  95. uint64_t *OffsetPtr) {
  96. DWARFFormValue FormValue(F);
  97. FormValue.extractValue(U->getDebugInfoExtractor(), OffsetPtr,
  98. U->getFormParams(), U);
  99. return FormValue;
  100. }
  101. bool DWARFFormValue::skipValue(dwarf::Form Form, DataExtractor DebugInfoData,
  102. uint64_t *OffsetPtr,
  103. const dwarf::FormParams Params) {
  104. bool Indirect = false;
  105. do {
  106. switch (Form) {
  107. // Blocks of inlined data that have a length field and the data bytes
  108. // inlined in the .debug_info.
  109. case DW_FORM_exprloc:
  110. case DW_FORM_block: {
  111. uint64_t size = DebugInfoData.getULEB128(OffsetPtr);
  112. *OffsetPtr += size;
  113. return true;
  114. }
  115. case DW_FORM_block1: {
  116. uint8_t size = DebugInfoData.getU8(OffsetPtr);
  117. *OffsetPtr += size;
  118. return true;
  119. }
  120. case DW_FORM_block2: {
  121. uint16_t size = DebugInfoData.getU16(OffsetPtr);
  122. *OffsetPtr += size;
  123. return true;
  124. }
  125. case DW_FORM_block4: {
  126. uint32_t size = DebugInfoData.getU32(OffsetPtr);
  127. *OffsetPtr += size;
  128. return true;
  129. }
  130. // Inlined NULL terminated C-strings.
  131. case DW_FORM_string:
  132. DebugInfoData.getCStr(OffsetPtr);
  133. return true;
  134. case DW_FORM_addr:
  135. case DW_FORM_ref_addr:
  136. case DW_FORM_flag_present:
  137. case DW_FORM_data1:
  138. case DW_FORM_data2:
  139. case DW_FORM_data4:
  140. case DW_FORM_data8:
  141. case DW_FORM_data16:
  142. case DW_FORM_flag:
  143. case DW_FORM_ref1:
  144. case DW_FORM_ref2:
  145. case DW_FORM_ref4:
  146. case DW_FORM_ref8:
  147. case DW_FORM_ref_sig8:
  148. case DW_FORM_ref_sup4:
  149. case DW_FORM_ref_sup8:
  150. case DW_FORM_strx1:
  151. case DW_FORM_strx2:
  152. case DW_FORM_strx4:
  153. case DW_FORM_addrx1:
  154. case DW_FORM_addrx2:
  155. case DW_FORM_addrx4:
  156. case DW_FORM_sec_offset:
  157. case DW_FORM_strp:
  158. case DW_FORM_strp_sup:
  159. case DW_FORM_line_strp:
  160. case DW_FORM_GNU_ref_alt:
  161. case DW_FORM_GNU_strp_alt:
  162. case DW_FORM_implicit_const:
  163. if (std::optional<uint8_t> FixedSize =
  164. dwarf::getFixedFormByteSize(Form, Params)) {
  165. *OffsetPtr += *FixedSize;
  166. return true;
  167. }
  168. return false;
  169. // signed or unsigned LEB 128 values.
  170. case DW_FORM_sdata:
  171. DebugInfoData.getSLEB128(OffsetPtr);
  172. return true;
  173. case DW_FORM_udata:
  174. case DW_FORM_ref_udata:
  175. case DW_FORM_strx:
  176. case DW_FORM_addrx:
  177. case DW_FORM_loclistx:
  178. case DW_FORM_rnglistx:
  179. case DW_FORM_GNU_addr_index:
  180. case DW_FORM_GNU_str_index:
  181. DebugInfoData.getULEB128(OffsetPtr);
  182. return true;
  183. case DW_FORM_LLVM_addrx_offset:
  184. DebugInfoData.getULEB128(OffsetPtr);
  185. *OffsetPtr += 4;
  186. return true;
  187. case DW_FORM_indirect:
  188. Indirect = true;
  189. Form = static_cast<dwarf::Form>(DebugInfoData.getULEB128(OffsetPtr));
  190. break;
  191. default:
  192. return false;
  193. }
  194. } while (Indirect);
  195. return true;
  196. }
  197. bool DWARFFormValue::isFormClass(DWARFFormValue::FormClass FC) const {
  198. // First, check DWARF5 form classes.
  199. if (Form < ArrayRef(DWARF5FormClasses).size() &&
  200. DWARF5FormClasses[Form] == FC)
  201. return true;
  202. // Check more forms from extensions and proposals.
  203. switch (Form) {
  204. case DW_FORM_GNU_ref_alt:
  205. return (FC == FC_Reference);
  206. case DW_FORM_GNU_addr_index:
  207. return (FC == FC_Address);
  208. case DW_FORM_GNU_str_index:
  209. case DW_FORM_GNU_strp_alt:
  210. return (FC == FC_String);
  211. case DW_FORM_LLVM_addrx_offset:
  212. return (FC == FC_Address);
  213. default:
  214. break;
  215. }
  216. if (FC == FC_SectionOffset) {
  217. if (Form == DW_FORM_strp || Form == DW_FORM_line_strp)
  218. return true;
  219. // In DWARF3 DW_FORM_data4 and DW_FORM_data8 served also as a section
  220. // offset. If we don't have a DWARFUnit, default to the old behavior.
  221. if (Form == DW_FORM_data4 || Form == DW_FORM_data8)
  222. return !U || U->getVersion() <= 3;
  223. }
  224. return false;
  225. }
  226. bool DWARFFormValue::extractValue(const DWARFDataExtractor &Data,
  227. uint64_t *OffsetPtr, dwarf::FormParams FP,
  228. const DWARFContext *Ctx,
  229. const DWARFUnit *CU) {
  230. if (!Ctx && CU)
  231. Ctx = &CU->getContext();
  232. C = Ctx;
  233. U = CU;
  234. Format = FP.Format;
  235. bool Indirect = false;
  236. bool IsBlock = false;
  237. Value.data = nullptr;
  238. // Read the value for the form into value and follow and DW_FORM_indirect
  239. // instances we run into
  240. Error Err = Error::success();
  241. do {
  242. Indirect = false;
  243. switch (Form) {
  244. case DW_FORM_addr:
  245. case DW_FORM_ref_addr: {
  246. uint16_t Size =
  247. (Form == DW_FORM_addr) ? FP.AddrSize : FP.getRefAddrByteSize();
  248. Value.uval =
  249. Data.getRelocatedValue(Size, OffsetPtr, &Value.SectionIndex, &Err);
  250. break;
  251. }
  252. case DW_FORM_exprloc:
  253. case DW_FORM_block:
  254. Value.uval = Data.getULEB128(OffsetPtr, &Err);
  255. IsBlock = true;
  256. break;
  257. case DW_FORM_block1:
  258. Value.uval = Data.getU8(OffsetPtr, &Err);
  259. IsBlock = true;
  260. break;
  261. case DW_FORM_block2:
  262. Value.uval = Data.getU16(OffsetPtr, &Err);
  263. IsBlock = true;
  264. break;
  265. case DW_FORM_block4:
  266. Value.uval = Data.getU32(OffsetPtr, &Err);
  267. IsBlock = true;
  268. break;
  269. case DW_FORM_data1:
  270. case DW_FORM_ref1:
  271. case DW_FORM_flag:
  272. case DW_FORM_strx1:
  273. case DW_FORM_addrx1:
  274. Value.uval = Data.getU8(OffsetPtr, &Err);
  275. break;
  276. case DW_FORM_data2:
  277. case DW_FORM_ref2:
  278. case DW_FORM_strx2:
  279. case DW_FORM_addrx2:
  280. Value.uval = Data.getU16(OffsetPtr, &Err);
  281. break;
  282. case DW_FORM_strx3:
  283. Value.uval = Data.getU24(OffsetPtr, &Err);
  284. break;
  285. case DW_FORM_data4:
  286. case DW_FORM_ref4:
  287. case DW_FORM_ref_sup4:
  288. case DW_FORM_strx4:
  289. case DW_FORM_addrx4:
  290. Value.uval = Data.getRelocatedValue(4, OffsetPtr, nullptr, &Err);
  291. break;
  292. case DW_FORM_data8:
  293. case DW_FORM_ref8:
  294. case DW_FORM_ref_sup8:
  295. Value.uval = Data.getRelocatedValue(8, OffsetPtr, nullptr, &Err);
  296. break;
  297. case DW_FORM_data16:
  298. // Treat this like a 16-byte block.
  299. Value.uval = 16;
  300. IsBlock = true;
  301. break;
  302. case DW_FORM_sdata:
  303. Value.sval = Data.getSLEB128(OffsetPtr, &Err);
  304. break;
  305. case DW_FORM_udata:
  306. case DW_FORM_ref_udata:
  307. case DW_FORM_rnglistx:
  308. case DW_FORM_loclistx:
  309. case DW_FORM_GNU_addr_index:
  310. case DW_FORM_GNU_str_index:
  311. case DW_FORM_addrx:
  312. case DW_FORM_strx:
  313. Value.uval = Data.getULEB128(OffsetPtr, &Err);
  314. break;
  315. case DW_FORM_LLVM_addrx_offset:
  316. Value.uval = Data.getULEB128(OffsetPtr, &Err) << 32;
  317. Value.uval |= Data.getU32(OffsetPtr, &Err);
  318. break;
  319. case DW_FORM_string:
  320. Value.cstr = Data.getCStr(OffsetPtr, &Err);
  321. break;
  322. case DW_FORM_indirect:
  323. Form = static_cast<dwarf::Form>(Data.getULEB128(OffsetPtr, &Err));
  324. Indirect = true;
  325. break;
  326. case DW_FORM_strp:
  327. case DW_FORM_sec_offset:
  328. case DW_FORM_GNU_ref_alt:
  329. case DW_FORM_GNU_strp_alt:
  330. case DW_FORM_line_strp:
  331. case DW_FORM_strp_sup: {
  332. Value.uval = Data.getRelocatedValue(FP.getDwarfOffsetByteSize(),
  333. OffsetPtr, nullptr, &Err);
  334. break;
  335. }
  336. case DW_FORM_flag_present:
  337. Value.uval = 1;
  338. break;
  339. case DW_FORM_ref_sig8:
  340. Value.uval = Data.getU64(OffsetPtr, &Err);
  341. break;
  342. case DW_FORM_implicit_const:
  343. // Value has been already set by DWARFFormValue::createFromSValue.
  344. break;
  345. default:
  346. // DWARFFormValue::skipValue() will have caught this and caused all
  347. // DWARF DIEs to fail to be parsed, so this code is not be reachable.
  348. llvm_unreachable("unsupported form");
  349. }
  350. } while (Indirect && !Err);
  351. if (IsBlock)
  352. Value.data = Data.getBytes(OffsetPtr, Value.uval, &Err).bytes_begin();
  353. return !errorToBool(std::move(Err));
  354. }
  355. void DWARFFormValue::dumpAddress(raw_ostream &OS, uint8_t AddressSize,
  356. uint64_t Address) {
  357. uint8_t HexDigits = AddressSize * 2;
  358. OS << format("0x%*.*" PRIx64, HexDigits, HexDigits, Address);
  359. }
  360. void DWARFFormValue::dumpSectionedAddress(raw_ostream &OS,
  361. DIDumpOptions DumpOpts,
  362. object::SectionedAddress SA) const {
  363. dumpAddress(OS, U->getAddressByteSize(), SA.Address);
  364. dumpAddressSection(U->getContext().getDWARFObj(), OS, DumpOpts,
  365. SA.SectionIndex);
  366. }
  367. void DWARFFormValue::dumpAddressSection(const DWARFObject &Obj, raw_ostream &OS,
  368. DIDumpOptions DumpOpts,
  369. uint64_t SectionIndex) {
  370. if (!DumpOpts.Verbose || SectionIndex == -1ULL)
  371. return;
  372. ArrayRef<SectionName> SectionNames = Obj.getSectionNames();
  373. const auto &SecRef = SectionNames[SectionIndex];
  374. OS << " \"" << SecRef.Name << '\"';
  375. // Print section index if name is not unique.
  376. if (!SecRef.IsNameUnique)
  377. OS << format(" [%" PRIu64 "]", SectionIndex);
  378. }
  379. void DWARFFormValue::dump(raw_ostream &OS, DIDumpOptions DumpOpts) const {
  380. uint64_t UValue = Value.uval;
  381. bool CURelativeOffset = false;
  382. raw_ostream &AddrOS = DumpOpts.ShowAddresses
  383. ? WithColor(OS, HighlightColor::Address).get()
  384. : nulls();
  385. int OffsetDumpWidth = 2 * dwarf::getDwarfOffsetByteSize(Format);
  386. switch (Form) {
  387. case DW_FORM_addr:
  388. dumpSectionedAddress(AddrOS, DumpOpts, {Value.uval, Value.SectionIndex});
  389. break;
  390. case DW_FORM_addrx:
  391. case DW_FORM_addrx1:
  392. case DW_FORM_addrx2:
  393. case DW_FORM_addrx3:
  394. case DW_FORM_addrx4:
  395. case DW_FORM_GNU_addr_index: {
  396. if (U == nullptr) {
  397. OS << "<invalid dwarf unit>";
  398. break;
  399. }
  400. std::optional<object::SectionedAddress> A =
  401. U->getAddrOffsetSectionItem(UValue);
  402. if (!A || DumpOpts.Verbose)
  403. AddrOS << format("indexed (%8.8x) address = ", (uint32_t)UValue);
  404. if (A)
  405. dumpSectionedAddress(AddrOS, DumpOpts, *A);
  406. else
  407. OS << "<unresolved>";
  408. break;
  409. }
  410. case DW_FORM_LLVM_addrx_offset: {
  411. if (U == nullptr) {
  412. OS << "<invalid dwarf unit>";
  413. break;
  414. }
  415. uint32_t Index = UValue >> 32;
  416. uint32_t Offset = UValue & 0xffffffff;
  417. std::optional<object::SectionedAddress> A =
  418. U->getAddrOffsetSectionItem(Index);
  419. if (!A || DumpOpts.Verbose)
  420. AddrOS << format("indexed (%8.8x) + 0x%x address = ", Index, Offset);
  421. if (A) {
  422. A->Address += Offset;
  423. dumpSectionedAddress(AddrOS, DumpOpts, *A);
  424. } else
  425. OS << "<unresolved>";
  426. break;
  427. }
  428. case DW_FORM_flag_present:
  429. OS << "true";
  430. break;
  431. case DW_FORM_flag:
  432. case DW_FORM_data1:
  433. OS << format("0x%02x", (uint8_t)UValue);
  434. break;
  435. case DW_FORM_data2:
  436. OS << format("0x%04x", (uint16_t)UValue);
  437. break;
  438. case DW_FORM_data4:
  439. OS << format("0x%08x", (uint32_t)UValue);
  440. break;
  441. case DW_FORM_ref_sig8:
  442. AddrOS << format("0x%016" PRIx64, UValue);
  443. break;
  444. case DW_FORM_data8:
  445. OS << format("0x%016" PRIx64, UValue);
  446. break;
  447. case DW_FORM_data16:
  448. OS << format_bytes(ArrayRef<uint8_t>(Value.data, 16), std::nullopt, 16, 16);
  449. break;
  450. case DW_FORM_string:
  451. OS << '"';
  452. OS.write_escaped(Value.cstr);
  453. OS << '"';
  454. break;
  455. case DW_FORM_exprloc:
  456. case DW_FORM_block:
  457. case DW_FORM_block1:
  458. case DW_FORM_block2:
  459. case DW_FORM_block4:
  460. if (UValue > 0) {
  461. switch (Form) {
  462. case DW_FORM_exprloc:
  463. case DW_FORM_block:
  464. AddrOS << format("<0x%" PRIx64 "> ", UValue);
  465. break;
  466. case DW_FORM_block1:
  467. AddrOS << format("<0x%2.2x> ", (uint8_t)UValue);
  468. break;
  469. case DW_FORM_block2:
  470. AddrOS << format("<0x%4.4x> ", (uint16_t)UValue);
  471. break;
  472. case DW_FORM_block4:
  473. AddrOS << format("<0x%8.8x> ", (uint32_t)UValue);
  474. break;
  475. default:
  476. break;
  477. }
  478. const uint8_t *DataPtr = Value.data;
  479. if (DataPtr) {
  480. // UValue contains size of block
  481. const uint8_t *EndDataPtr = DataPtr + UValue;
  482. while (DataPtr < EndDataPtr) {
  483. AddrOS << format("%2.2x ", *DataPtr);
  484. ++DataPtr;
  485. }
  486. } else
  487. OS << "NULL";
  488. }
  489. break;
  490. case DW_FORM_sdata:
  491. case DW_FORM_implicit_const:
  492. OS << Value.sval;
  493. break;
  494. case DW_FORM_udata:
  495. OS << Value.uval;
  496. break;
  497. case DW_FORM_strp:
  498. if (DumpOpts.Verbose)
  499. OS << format(" .debug_str[0x%0*" PRIx64 "] = ", OffsetDumpWidth, UValue);
  500. dumpString(OS);
  501. break;
  502. case DW_FORM_line_strp:
  503. if (DumpOpts.Verbose)
  504. OS << format(" .debug_line_str[0x%0*" PRIx64 "] = ", OffsetDumpWidth,
  505. UValue);
  506. dumpString(OS);
  507. break;
  508. case DW_FORM_strx:
  509. case DW_FORM_strx1:
  510. case DW_FORM_strx2:
  511. case DW_FORM_strx3:
  512. case DW_FORM_strx4:
  513. case DW_FORM_GNU_str_index:
  514. if (DumpOpts.Verbose)
  515. OS << format("indexed (%8.8x) string = ", (uint32_t)UValue);
  516. dumpString(OS);
  517. break;
  518. case DW_FORM_GNU_strp_alt:
  519. if (DumpOpts.Verbose)
  520. OS << format("alt indirect string, offset: 0x%" PRIx64 "", UValue);
  521. dumpString(OS);
  522. break;
  523. case DW_FORM_ref_addr:
  524. AddrOS << format("0x%016" PRIx64, UValue);
  525. break;
  526. case DW_FORM_ref1:
  527. CURelativeOffset = true;
  528. if (DumpOpts.Verbose)
  529. AddrOS << format("cu + 0x%2.2x", (uint8_t)UValue);
  530. break;
  531. case DW_FORM_ref2:
  532. CURelativeOffset = true;
  533. if (DumpOpts.Verbose)
  534. AddrOS << format("cu + 0x%4.4x", (uint16_t)UValue);
  535. break;
  536. case DW_FORM_ref4:
  537. CURelativeOffset = true;
  538. if (DumpOpts.Verbose)
  539. AddrOS << format("cu + 0x%4.4x", (uint32_t)UValue);
  540. break;
  541. case DW_FORM_ref8:
  542. CURelativeOffset = true;
  543. if (DumpOpts.Verbose)
  544. AddrOS << format("cu + 0x%8.8" PRIx64, UValue);
  545. break;
  546. case DW_FORM_ref_udata:
  547. CURelativeOffset = true;
  548. if (DumpOpts.Verbose)
  549. AddrOS << format("cu + 0x%" PRIx64, UValue);
  550. break;
  551. case DW_FORM_GNU_ref_alt:
  552. AddrOS << format("<alt 0x%" PRIx64 ">", UValue);
  553. break;
  554. // All DW_FORM_indirect attributes should be resolved prior to calling
  555. // this function
  556. case DW_FORM_indirect:
  557. OS << "DW_FORM_indirect";
  558. break;
  559. case DW_FORM_rnglistx:
  560. OS << format("indexed (0x%x) rangelist = ", (uint32_t)UValue);
  561. break;
  562. case DW_FORM_loclistx:
  563. OS << format("indexed (0x%x) loclist = ", (uint32_t)UValue);
  564. break;
  565. case DW_FORM_sec_offset:
  566. AddrOS << format("0x%0*" PRIx64, OffsetDumpWidth, UValue);
  567. break;
  568. default:
  569. OS << format("DW_FORM(0x%4.4x)", Form);
  570. break;
  571. }
  572. if (CURelativeOffset) {
  573. if (DumpOpts.Verbose)
  574. OS << " => {";
  575. if (DumpOpts.ShowAddresses)
  576. WithColor(OS, HighlightColor::Address).get()
  577. << format("0x%8.8" PRIx64, UValue + (U ? U->getOffset() : 0));
  578. if (DumpOpts.Verbose)
  579. OS << "}";
  580. }
  581. }
  582. void DWARFFormValue::dumpString(raw_ostream &OS) const {
  583. if (auto DbgStr = dwarf::toString(*this)) {
  584. auto COS = WithColor(OS, HighlightColor::String);
  585. COS.get() << '"';
  586. COS.get().write_escaped(*DbgStr);
  587. COS.get() << '"';
  588. }
  589. }
  590. Expected<const char *> DWARFFormValue::getAsCString() const {
  591. if (!isFormClass(FC_String))
  592. return make_error<StringError>("Invalid form for string attribute",
  593. inconvertibleErrorCode());
  594. if (Form == DW_FORM_string)
  595. return Value.cstr;
  596. // FIXME: Add support for DW_FORM_GNU_strp_alt
  597. if (Form == DW_FORM_GNU_strp_alt || C == nullptr)
  598. return make_error<StringError>("Unsupported form for string attribute",
  599. inconvertibleErrorCode());
  600. uint64_t Offset = Value.uval;
  601. std::optional<uint32_t> Index;
  602. if (Form == DW_FORM_GNU_str_index || Form == DW_FORM_strx ||
  603. Form == DW_FORM_strx1 || Form == DW_FORM_strx2 || Form == DW_FORM_strx3 ||
  604. Form == DW_FORM_strx4) {
  605. if (!U)
  606. return make_error<StringError>("API limitation - string extraction not "
  607. "available without a DWARFUnit",
  608. inconvertibleErrorCode());
  609. Expected<uint64_t> StrOffset = U->getStringOffsetSectionItem(Offset);
  610. Index = Offset;
  611. if (!StrOffset)
  612. return StrOffset.takeError();
  613. Offset = *StrOffset;
  614. }
  615. // Prefer the Unit's string extractor, because for .dwo it will point to
  616. // .debug_str.dwo, while the Context's extractor always uses .debug_str.
  617. DataExtractor StrData = Form == DW_FORM_line_strp
  618. ? C->getLineStringExtractor()
  619. : U ? U->getStringExtractor()
  620. : C->getStringExtractor();
  621. if (const char *Str = StrData.getCStr(&Offset))
  622. return Str;
  623. std::string Msg = FormEncodingString(Form).str();
  624. if (Index)
  625. Msg += (" uses index " + Twine(*Index) + ", but the referenced string").str();
  626. Msg += (" offset " + Twine(Offset) + " is beyond .debug_str bounds").str();
  627. return make_error<StringError>(Msg,
  628. inconvertibleErrorCode());
  629. }
  630. std::optional<uint64_t> DWARFFormValue::getAsAddress() const {
  631. if (auto SA = getAsSectionedAddress())
  632. return SA->Address;
  633. return std::nullopt;
  634. }
  635. std::optional<object::SectionedAddress>
  636. DWARFFormValue::getAsSectionedAddress() const {
  637. if (!isFormClass(FC_Address))
  638. return std::nullopt;
  639. bool AddrOffset = Form == dwarf::DW_FORM_LLVM_addrx_offset;
  640. if (Form == DW_FORM_GNU_addr_index || Form == DW_FORM_addrx || AddrOffset) {
  641. uint32_t Index = AddrOffset ? (Value.uval >> 32) : Value.uval;
  642. if (!U)
  643. return std::nullopt;
  644. std::optional<object::SectionedAddress> SA =
  645. U->getAddrOffsetSectionItem(Index);
  646. if (!SA)
  647. return std::nullopt;
  648. if (AddrOffset)
  649. SA->Address += (Value.uval & 0xffffffff);
  650. return SA;
  651. }
  652. return {{Value.uval, Value.SectionIndex}};
  653. }
  654. std::optional<uint64_t> DWARFFormValue::getAsReference() const {
  655. if (auto R = getAsRelativeReference())
  656. return R->Unit ? R->Unit->getOffset() + R->Offset : R->Offset;
  657. return std::nullopt;
  658. }
  659. std::optional<DWARFFormValue::UnitOffset>
  660. DWARFFormValue::getAsRelativeReference() const {
  661. if (!isFormClass(FC_Reference))
  662. return std::nullopt;
  663. switch (Form) {
  664. case DW_FORM_ref1:
  665. case DW_FORM_ref2:
  666. case DW_FORM_ref4:
  667. case DW_FORM_ref8:
  668. case DW_FORM_ref_udata:
  669. if (!U)
  670. return std::nullopt;
  671. return UnitOffset{const_cast<DWARFUnit*>(U), Value.uval};
  672. case DW_FORM_ref_addr:
  673. case DW_FORM_ref_sig8:
  674. case DW_FORM_GNU_ref_alt:
  675. return UnitOffset{nullptr, Value.uval};
  676. default:
  677. return std::nullopt;
  678. }
  679. }
  680. std::optional<uint64_t> DWARFFormValue::getAsSectionOffset() const {
  681. if (!isFormClass(FC_SectionOffset))
  682. return std::nullopt;
  683. return Value.uval;
  684. }
  685. std::optional<uint64_t> DWARFFormValue::getAsUnsignedConstant() const {
  686. if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) ||
  687. Form == DW_FORM_sdata)
  688. return std::nullopt;
  689. return Value.uval;
  690. }
  691. std::optional<int64_t> DWARFFormValue::getAsSignedConstant() const {
  692. if ((!isFormClass(FC_Constant) && !isFormClass(FC_Flag)) ||
  693. (Form == DW_FORM_udata &&
  694. uint64_t(std::numeric_limits<int64_t>::max()) < Value.uval))
  695. return std::nullopt;
  696. switch (Form) {
  697. case DW_FORM_data4:
  698. return int32_t(Value.uval);
  699. case DW_FORM_data2:
  700. return int16_t(Value.uval);
  701. case DW_FORM_data1:
  702. return int8_t(Value.uval);
  703. case DW_FORM_sdata:
  704. case DW_FORM_data8:
  705. default:
  706. return Value.sval;
  707. }
  708. }
  709. std::optional<ArrayRef<uint8_t>> DWARFFormValue::getAsBlock() const {
  710. if (!isFormClass(FC_Block) && !isFormClass(FC_Exprloc) &&
  711. Form != DW_FORM_data16)
  712. return std::nullopt;
  713. return ArrayRef(Value.data, Value.uval);
  714. }
  715. std::optional<uint64_t> DWARFFormValue::getAsCStringOffset() const {
  716. if (!isFormClass(FC_String) && Form == DW_FORM_string)
  717. return std::nullopt;
  718. return Value.uval;
  719. }
  720. std::optional<uint64_t> DWARFFormValue::getAsReferenceUVal() const {
  721. if (!isFormClass(FC_Reference))
  722. return std::nullopt;
  723. return Value.uval;
  724. }
  725. std::optional<std::string>
  726. DWARFFormValue::getAsFile(DILineInfoSpecifier::FileLineInfoKind Kind) const {
  727. if (U == nullptr || !isFormClass(FC_Constant))
  728. return std::nullopt;
  729. DWARFUnit *DLU = const_cast<DWARFUnit *>(U)->getLinkedUnit();
  730. if (auto *LT = DLU->getContext().getLineTableForUnit(DLU)) {
  731. std::string FileName;
  732. if (LT->getFileNameByIndex(Value.uval, DLU->getCompilationDir(), Kind,
  733. FileName))
  734. return FileName;
  735. }
  736. return std::nullopt;
  737. }