DWARFDebugFrame.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616
  1. //===- DWARFDebugFrame.h - Parsing of .debug_frame ------------------------===//
  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/DWARFDebugFrame.h"
  9. #include "llvm/ADT/DenseMap.h"
  10. #include "llvm/ADT/Optional.h"
  11. #include "llvm/ADT/StringExtras.h"
  12. #include "llvm/ADT/StringRef.h"
  13. #include "llvm/BinaryFormat/Dwarf.h"
  14. #include "llvm/MC/MCRegisterInfo.h"
  15. #include "llvm/Support/Casting.h"
  16. #include "llvm/Support/Compiler.h"
  17. #include "llvm/Support/DataExtractor.h"
  18. #include "llvm/Support/Errc.h"
  19. #include "llvm/Support/ErrorHandling.h"
  20. #include "llvm/Support/Format.h"
  21. #include "llvm/Support/raw_ostream.h"
  22. #include <algorithm>
  23. #include <cassert>
  24. #include <cinttypes>
  25. #include <cstdint>
  26. #include <string>
  27. #include <vector>
  28. using namespace llvm;
  29. using namespace dwarf;
  30. static void printRegister(raw_ostream &OS, const MCRegisterInfo *MRI, bool IsEH,
  31. unsigned RegNum) {
  32. if (MRI) {
  33. if (Optional<unsigned> LLVMRegNum = MRI->getLLVMRegNum(RegNum, IsEH)) {
  34. if (const char *RegName = MRI->getName(*LLVMRegNum)) {
  35. OS << RegName;
  36. return;
  37. }
  38. }
  39. }
  40. OS << "reg" << RegNum;
  41. }
  42. // See DWARF standard v3, section 7.23
  43. const uint8_t DWARF_CFI_PRIMARY_OPCODE_MASK = 0xc0;
  44. const uint8_t DWARF_CFI_PRIMARY_OPERAND_MASK = 0x3f;
  45. Error CFIProgram::parse(DWARFDataExtractor Data, uint64_t *Offset,
  46. uint64_t EndOffset) {
  47. DataExtractor::Cursor C(*Offset);
  48. while (C && C.tell() < EndOffset) {
  49. uint8_t Opcode = Data.getRelocatedValue(C, 1);
  50. if (!C)
  51. break;
  52. // Some instructions have a primary opcode encoded in the top bits.
  53. if (uint8_t Primary = Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK) {
  54. // If it's a primary opcode, the first operand is encoded in the bottom
  55. // bits of the opcode itself.
  56. uint64_t Op1 = Opcode & DWARF_CFI_PRIMARY_OPERAND_MASK;
  57. switch (Primary) {
  58. case DW_CFA_advance_loc:
  59. case DW_CFA_restore:
  60. addInstruction(Primary, Op1);
  61. break;
  62. case DW_CFA_offset:
  63. addInstruction(Primary, Op1, Data.getULEB128(C));
  64. break;
  65. default:
  66. llvm_unreachable("invalid primary CFI opcode");
  67. }
  68. continue;
  69. }
  70. // Extended opcode - its value is Opcode itself.
  71. switch (Opcode) {
  72. default:
  73. return createStringError(errc::illegal_byte_sequence,
  74. "invalid extended CFI opcode 0x%" PRIx8, Opcode);
  75. case DW_CFA_nop:
  76. case DW_CFA_remember_state:
  77. case DW_CFA_restore_state:
  78. case DW_CFA_GNU_window_save:
  79. // No operands
  80. addInstruction(Opcode);
  81. break;
  82. case DW_CFA_set_loc:
  83. // Operands: Address
  84. addInstruction(Opcode, Data.getRelocatedAddress(C));
  85. break;
  86. case DW_CFA_advance_loc1:
  87. // Operands: 1-byte delta
  88. addInstruction(Opcode, Data.getRelocatedValue(C, 1));
  89. break;
  90. case DW_CFA_advance_loc2:
  91. // Operands: 2-byte delta
  92. addInstruction(Opcode, Data.getRelocatedValue(C, 2));
  93. break;
  94. case DW_CFA_advance_loc4:
  95. // Operands: 4-byte delta
  96. addInstruction(Opcode, Data.getRelocatedValue(C, 4));
  97. break;
  98. case DW_CFA_restore_extended:
  99. case DW_CFA_undefined:
  100. case DW_CFA_same_value:
  101. case DW_CFA_def_cfa_register:
  102. case DW_CFA_def_cfa_offset:
  103. case DW_CFA_GNU_args_size:
  104. // Operands: ULEB128
  105. addInstruction(Opcode, Data.getULEB128(C));
  106. break;
  107. case DW_CFA_def_cfa_offset_sf:
  108. // Operands: SLEB128
  109. addInstruction(Opcode, Data.getSLEB128(C));
  110. break;
  111. case DW_CFA_offset_extended:
  112. case DW_CFA_register:
  113. case DW_CFA_def_cfa:
  114. case DW_CFA_val_offset: {
  115. // Operands: ULEB128, ULEB128
  116. // Note: We can not embed getULEB128 directly into function
  117. // argument list. getULEB128 changes Offset and order of evaluation
  118. // for arguments is unspecified.
  119. uint64_t op1 = Data.getULEB128(C);
  120. uint64_t op2 = Data.getULEB128(C);
  121. addInstruction(Opcode, op1, op2);
  122. break;
  123. }
  124. case DW_CFA_offset_extended_sf:
  125. case DW_CFA_def_cfa_sf:
  126. case DW_CFA_val_offset_sf: {
  127. // Operands: ULEB128, SLEB128
  128. // Note: see comment for the previous case
  129. uint64_t op1 = Data.getULEB128(C);
  130. uint64_t op2 = (uint64_t)Data.getSLEB128(C);
  131. addInstruction(Opcode, op1, op2);
  132. break;
  133. }
  134. case DW_CFA_def_cfa_expression: {
  135. uint64_t ExprLength = Data.getULEB128(C);
  136. addInstruction(Opcode, 0);
  137. StringRef Expression = Data.getBytes(C, ExprLength);
  138. DataExtractor Extractor(Expression, Data.isLittleEndian(),
  139. Data.getAddressSize());
  140. // Note. We do not pass the DWARF format to DWARFExpression, because
  141. // DW_OP_call_ref, the only operation which depends on the format, is
  142. // prohibited in call frame instructions, see sec. 6.4.2 in DWARFv5.
  143. Instructions.back().Expression =
  144. DWARFExpression(Extractor, Data.getAddressSize());
  145. break;
  146. }
  147. case DW_CFA_expression:
  148. case DW_CFA_val_expression: {
  149. uint64_t RegNum = Data.getULEB128(C);
  150. addInstruction(Opcode, RegNum, 0);
  151. uint64_t BlockLength = Data.getULEB128(C);
  152. StringRef Expression = Data.getBytes(C, BlockLength);
  153. DataExtractor Extractor(Expression, Data.isLittleEndian(),
  154. Data.getAddressSize());
  155. // Note. We do not pass the DWARF format to DWARFExpression, because
  156. // DW_OP_call_ref, the only operation which depends on the format, is
  157. // prohibited in call frame instructions, see sec. 6.4.2 in DWARFv5.
  158. Instructions.back().Expression =
  159. DWARFExpression(Extractor, Data.getAddressSize());
  160. break;
  161. }
  162. }
  163. }
  164. *Offset = C.tell();
  165. return C.takeError();
  166. }
  167. namespace {
  168. } // end anonymous namespace
  169. ArrayRef<CFIProgram::OperandType[2]> CFIProgram::getOperandTypes() {
  170. static OperandType OpTypes[DW_CFA_restore+1][2];
  171. static bool Initialized = false;
  172. if (Initialized) {
  173. return ArrayRef<OperandType[2]>(&OpTypes[0], DW_CFA_restore+1);
  174. }
  175. Initialized = true;
  176. #define DECLARE_OP2(OP, OPTYPE0, OPTYPE1) \
  177. do { \
  178. OpTypes[OP][0] = OPTYPE0; \
  179. OpTypes[OP][1] = OPTYPE1; \
  180. } while (false)
  181. #define DECLARE_OP1(OP, OPTYPE0) DECLARE_OP2(OP, OPTYPE0, OT_None)
  182. #define DECLARE_OP0(OP) DECLARE_OP1(OP, OT_None)
  183. DECLARE_OP1(DW_CFA_set_loc, OT_Address);
  184. DECLARE_OP1(DW_CFA_advance_loc, OT_FactoredCodeOffset);
  185. DECLARE_OP1(DW_CFA_advance_loc1, OT_FactoredCodeOffset);
  186. DECLARE_OP1(DW_CFA_advance_loc2, OT_FactoredCodeOffset);
  187. DECLARE_OP1(DW_CFA_advance_loc4, OT_FactoredCodeOffset);
  188. DECLARE_OP1(DW_CFA_MIPS_advance_loc8, OT_FactoredCodeOffset);
  189. DECLARE_OP2(DW_CFA_def_cfa, OT_Register, OT_Offset);
  190. DECLARE_OP2(DW_CFA_def_cfa_sf, OT_Register, OT_SignedFactDataOffset);
  191. DECLARE_OP1(DW_CFA_def_cfa_register, OT_Register);
  192. DECLARE_OP1(DW_CFA_def_cfa_offset, OT_Offset);
  193. DECLARE_OP1(DW_CFA_def_cfa_offset_sf, OT_SignedFactDataOffset);
  194. DECLARE_OP1(DW_CFA_def_cfa_expression, OT_Expression);
  195. DECLARE_OP1(DW_CFA_undefined, OT_Register);
  196. DECLARE_OP1(DW_CFA_same_value, OT_Register);
  197. DECLARE_OP2(DW_CFA_offset, OT_Register, OT_UnsignedFactDataOffset);
  198. DECLARE_OP2(DW_CFA_offset_extended, OT_Register, OT_UnsignedFactDataOffset);
  199. DECLARE_OP2(DW_CFA_offset_extended_sf, OT_Register, OT_SignedFactDataOffset);
  200. DECLARE_OP2(DW_CFA_val_offset, OT_Register, OT_UnsignedFactDataOffset);
  201. DECLARE_OP2(DW_CFA_val_offset_sf, OT_Register, OT_SignedFactDataOffset);
  202. DECLARE_OP2(DW_CFA_register, OT_Register, OT_Register);
  203. DECLARE_OP2(DW_CFA_expression, OT_Register, OT_Expression);
  204. DECLARE_OP2(DW_CFA_val_expression, OT_Register, OT_Expression);
  205. DECLARE_OP1(DW_CFA_restore, OT_Register);
  206. DECLARE_OP1(DW_CFA_restore_extended, OT_Register);
  207. DECLARE_OP0(DW_CFA_remember_state);
  208. DECLARE_OP0(DW_CFA_restore_state);
  209. DECLARE_OP0(DW_CFA_GNU_window_save);
  210. DECLARE_OP1(DW_CFA_GNU_args_size, OT_Offset);
  211. DECLARE_OP0(DW_CFA_nop);
  212. #undef DECLARE_OP0
  213. #undef DECLARE_OP1
  214. #undef DECLARE_OP2
  215. return ArrayRef<OperandType[2]>(&OpTypes[0], DW_CFA_restore+1);
  216. }
  217. /// Print \p Opcode's operand number \p OperandIdx which has value \p Operand.
  218. void CFIProgram::printOperand(raw_ostream &OS, DIDumpOptions DumpOpts,
  219. const MCRegisterInfo *MRI, bool IsEH,
  220. const Instruction &Instr, unsigned OperandIdx,
  221. uint64_t Operand) const {
  222. assert(OperandIdx < 2);
  223. uint8_t Opcode = Instr.Opcode;
  224. OperandType Type = getOperandTypes()[Opcode][OperandIdx];
  225. switch (Type) {
  226. case OT_Unset: {
  227. OS << " Unsupported " << (OperandIdx ? "second" : "first") << " operand to";
  228. auto OpcodeName = CallFrameString(Opcode, Arch);
  229. if (!OpcodeName.empty())
  230. OS << " " << OpcodeName;
  231. else
  232. OS << format(" Opcode %x", Opcode);
  233. break;
  234. }
  235. case OT_None:
  236. break;
  237. case OT_Address:
  238. OS << format(" %" PRIx64, Operand);
  239. break;
  240. case OT_Offset:
  241. // The offsets are all encoded in a unsigned form, but in practice
  242. // consumers use them signed. It's most certainly legacy due to
  243. // the lack of signed variants in the first Dwarf standards.
  244. OS << format(" %+" PRId64, int64_t(Operand));
  245. break;
  246. case OT_FactoredCodeOffset: // Always Unsigned
  247. if (CodeAlignmentFactor)
  248. OS << format(" %" PRId64, Operand * CodeAlignmentFactor);
  249. else
  250. OS << format(" %" PRId64 "*code_alignment_factor" , Operand);
  251. break;
  252. case OT_SignedFactDataOffset:
  253. if (DataAlignmentFactor)
  254. OS << format(" %" PRId64, int64_t(Operand) * DataAlignmentFactor);
  255. else
  256. OS << format(" %" PRId64 "*data_alignment_factor" , int64_t(Operand));
  257. break;
  258. case OT_UnsignedFactDataOffset:
  259. if (DataAlignmentFactor)
  260. OS << format(" %" PRId64, Operand * DataAlignmentFactor);
  261. else
  262. OS << format(" %" PRId64 "*data_alignment_factor" , Operand);
  263. break;
  264. case OT_Register:
  265. OS << ' ';
  266. printRegister(OS, MRI, IsEH, Operand);
  267. break;
  268. case OT_Expression:
  269. assert(Instr.Expression && "missing DWARFExpression object");
  270. OS << " ";
  271. Instr.Expression->print(OS, DumpOpts, MRI, nullptr, IsEH);
  272. break;
  273. }
  274. }
  275. void CFIProgram::dump(raw_ostream &OS, DIDumpOptions DumpOpts,
  276. const MCRegisterInfo *MRI, bool IsEH,
  277. unsigned IndentLevel) const {
  278. for (const auto &Instr : Instructions) {
  279. uint8_t Opcode = Instr.Opcode;
  280. if (Opcode & DWARF_CFI_PRIMARY_OPCODE_MASK)
  281. Opcode &= DWARF_CFI_PRIMARY_OPCODE_MASK;
  282. OS.indent(2 * IndentLevel);
  283. OS << CallFrameString(Opcode, Arch) << ":";
  284. for (unsigned i = 0; i < Instr.Ops.size(); ++i)
  285. printOperand(OS, DumpOpts, MRI, IsEH, Instr, i, Instr.Ops[i]);
  286. OS << '\n';
  287. }
  288. }
  289. // Returns the CIE identifier to be used by the requested format.
  290. // CIE ids for .debug_frame sections are defined in Section 7.24 of DWARFv5.
  291. // For CIE ID in .eh_frame sections see
  292. // https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html
  293. constexpr uint64_t getCIEId(bool IsDWARF64, bool IsEH) {
  294. if (IsEH)
  295. return 0;
  296. if (IsDWARF64)
  297. return DW64_CIE_ID;
  298. return DW_CIE_ID;
  299. }
  300. void CIE::dump(raw_ostream &OS, DIDumpOptions DumpOpts,
  301. const MCRegisterInfo *MRI, bool IsEH) const {
  302. // A CIE with a zero length is a terminator entry in the .eh_frame section.
  303. if (IsEH && Length == 0) {
  304. OS << format("%08" PRIx64, Offset) << " ZERO terminator\n";
  305. return;
  306. }
  307. OS << format("%08" PRIx64, Offset)
  308. << format(" %0*" PRIx64, IsDWARF64 ? 16 : 8, Length)
  309. << format(" %0*" PRIx64, IsDWARF64 && !IsEH ? 16 : 8,
  310. getCIEId(IsDWARF64, IsEH))
  311. << " CIE\n"
  312. << " Format: " << FormatString(IsDWARF64) << "\n"
  313. << format(" Version: %d\n", Version)
  314. << " Augmentation: \"" << Augmentation << "\"\n";
  315. if (Version >= 4) {
  316. OS << format(" Address size: %u\n", (uint32_t)AddressSize);
  317. OS << format(" Segment desc size: %u\n",
  318. (uint32_t)SegmentDescriptorSize);
  319. }
  320. OS << format(" Code alignment factor: %u\n", (uint32_t)CodeAlignmentFactor);
  321. OS << format(" Data alignment factor: %d\n", (int32_t)DataAlignmentFactor);
  322. OS << format(" Return address column: %d\n", (int32_t)ReturnAddressRegister);
  323. if (Personality)
  324. OS << format(" Personality Address: %016" PRIx64 "\n", *Personality);
  325. if (!AugmentationData.empty()) {
  326. OS << " Augmentation data: ";
  327. for (uint8_t Byte : AugmentationData)
  328. OS << ' ' << hexdigit(Byte >> 4) << hexdigit(Byte & 0xf);
  329. OS << "\n";
  330. }
  331. OS << "\n";
  332. CFIs.dump(OS, DumpOpts, MRI, IsEH);
  333. OS << "\n";
  334. }
  335. void FDE::dump(raw_ostream &OS, DIDumpOptions DumpOpts,
  336. const MCRegisterInfo *MRI, bool IsEH) const {
  337. OS << format("%08" PRIx64, Offset)
  338. << format(" %0*" PRIx64, IsDWARF64 ? 16 : 8, Length)
  339. << format(" %0*" PRIx64, IsDWARF64 && !IsEH ? 16 : 8, CIEPointer)
  340. << " FDE cie=";
  341. if (LinkedCIE)
  342. OS << format("%08" PRIx64, LinkedCIE->getOffset());
  343. else
  344. OS << "<invalid offset>";
  345. OS << format(" pc=%08" PRIx64 "...%08" PRIx64 "\n", InitialLocation,
  346. InitialLocation + AddressRange);
  347. OS << " Format: " << FormatString(IsDWARF64) << "\n";
  348. if (LSDAAddress)
  349. OS << format(" LSDA Address: %016" PRIx64 "\n", *LSDAAddress);
  350. CFIs.dump(OS, DumpOpts, MRI, IsEH);
  351. OS << "\n";
  352. }
  353. DWARFDebugFrame::DWARFDebugFrame(Triple::ArchType Arch,
  354. bool IsEH, uint64_t EHFrameAddress)
  355. : Arch(Arch), IsEH(IsEH), EHFrameAddress(EHFrameAddress) {}
  356. DWARFDebugFrame::~DWARFDebugFrame() = default;
  357. static void LLVM_ATTRIBUTE_UNUSED dumpDataAux(DataExtractor Data,
  358. uint64_t Offset, int Length) {
  359. errs() << "DUMP: ";
  360. for (int i = 0; i < Length; ++i) {
  361. uint8_t c = Data.getU8(&Offset);
  362. errs().write_hex(c); errs() << " ";
  363. }
  364. errs() << "\n";
  365. }
  366. Error DWARFDebugFrame::parse(DWARFDataExtractor Data) {
  367. uint64_t Offset = 0;
  368. DenseMap<uint64_t, CIE *> CIEs;
  369. while (Data.isValidOffset(Offset)) {
  370. uint64_t StartOffset = Offset;
  371. uint64_t Length;
  372. DwarfFormat Format;
  373. std::tie(Length, Format) = Data.getInitialLength(&Offset);
  374. bool IsDWARF64 = Format == DWARF64;
  375. // If the Length is 0, then this CIE is a terminator. We add it because some
  376. // dumper tools might need it to print something special for such entries
  377. // (e.g. llvm-objdump --dwarf=frames prints "ZERO terminator").
  378. if (Length == 0) {
  379. auto Cie = std::make_unique<CIE>(
  380. IsDWARF64, StartOffset, 0, 0, SmallString<8>(), 0, 0, 0, 0, 0,
  381. SmallString<8>(), 0, 0, None, None, Arch);
  382. CIEs[StartOffset] = Cie.get();
  383. Entries.push_back(std::move(Cie));
  384. break;
  385. }
  386. // At this point, Offset points to the next field after Length.
  387. // Length is the structure size excluding itself. Compute an offset one
  388. // past the end of the structure (needed to know how many instructions to
  389. // read).
  390. uint64_t StartStructureOffset = Offset;
  391. uint64_t EndStructureOffset = Offset + Length;
  392. // The Id field's size depends on the DWARF format
  393. Error Err = Error::success();
  394. uint64_t Id = Data.getRelocatedValue((IsDWARF64 && !IsEH) ? 8 : 4, &Offset,
  395. /*SectionIndex=*/nullptr, &Err);
  396. if (Err)
  397. return Err;
  398. if (Id == getCIEId(IsDWARF64, IsEH)) {
  399. uint8_t Version = Data.getU8(&Offset);
  400. const char *Augmentation = Data.getCStr(&Offset);
  401. StringRef AugmentationString(Augmentation ? Augmentation : "");
  402. // TODO: we should provide a way to report a warning and continue dumping.
  403. if (IsEH && Version != 1)
  404. return createStringError(errc::not_supported,
  405. "unsupported CIE version: %" PRIu8, Version);
  406. uint8_t AddressSize = Version < 4 ? Data.getAddressSize() :
  407. Data.getU8(&Offset);
  408. Data.setAddressSize(AddressSize);
  409. uint8_t SegmentDescriptorSize = Version < 4 ? 0 : Data.getU8(&Offset);
  410. uint64_t CodeAlignmentFactor = Data.getULEB128(&Offset);
  411. int64_t DataAlignmentFactor = Data.getSLEB128(&Offset);
  412. uint64_t ReturnAddressRegister =
  413. Version == 1 ? Data.getU8(&Offset) : Data.getULEB128(&Offset);
  414. // Parse the augmentation data for EH CIEs
  415. StringRef AugmentationData("");
  416. uint32_t FDEPointerEncoding = DW_EH_PE_absptr;
  417. uint32_t LSDAPointerEncoding = DW_EH_PE_omit;
  418. Optional<uint64_t> Personality;
  419. Optional<uint32_t> PersonalityEncoding;
  420. if (IsEH) {
  421. Optional<uint64_t> AugmentationLength;
  422. uint64_t StartAugmentationOffset;
  423. uint64_t EndAugmentationOffset;
  424. // Walk the augmentation string to get all the augmentation data.
  425. for (unsigned i = 0, e = AugmentationString.size(); i != e; ++i) {
  426. switch (AugmentationString[i]) {
  427. default:
  428. return createStringError(
  429. errc::invalid_argument,
  430. "unknown augmentation character in entry at 0x%" PRIx64,
  431. StartOffset);
  432. case 'L':
  433. LSDAPointerEncoding = Data.getU8(&Offset);
  434. break;
  435. case 'P': {
  436. if (Personality)
  437. return createStringError(
  438. errc::invalid_argument,
  439. "duplicate personality in entry at 0x%" PRIx64, StartOffset);
  440. PersonalityEncoding = Data.getU8(&Offset);
  441. Personality = Data.getEncodedPointer(
  442. &Offset, *PersonalityEncoding,
  443. EHFrameAddress ? EHFrameAddress + Offset : 0);
  444. break;
  445. }
  446. case 'R':
  447. FDEPointerEncoding = Data.getU8(&Offset);
  448. break;
  449. case 'S':
  450. // Current frame is a signal trampoline.
  451. break;
  452. case 'z':
  453. if (i)
  454. return createStringError(
  455. errc::invalid_argument,
  456. "'z' must be the first character at 0x%" PRIx64, StartOffset);
  457. // Parse the augmentation length first. We only parse it if
  458. // the string contains a 'z'.
  459. AugmentationLength = Data.getULEB128(&Offset);
  460. StartAugmentationOffset = Offset;
  461. EndAugmentationOffset = Offset + *AugmentationLength;
  462. break;
  463. case 'B':
  464. // B-Key is used for signing functions associated with this
  465. // augmentation string
  466. break;
  467. }
  468. }
  469. if (AugmentationLength.hasValue()) {
  470. if (Offset != EndAugmentationOffset)
  471. return createStringError(errc::invalid_argument,
  472. "parsing augmentation data at 0x%" PRIx64
  473. " failed",
  474. StartOffset);
  475. AugmentationData = Data.getData().slice(StartAugmentationOffset,
  476. EndAugmentationOffset);
  477. }
  478. }
  479. auto Cie = std::make_unique<CIE>(
  480. IsDWARF64, StartOffset, Length, Version, AugmentationString,
  481. AddressSize, SegmentDescriptorSize, CodeAlignmentFactor,
  482. DataAlignmentFactor, ReturnAddressRegister, AugmentationData,
  483. FDEPointerEncoding, LSDAPointerEncoding, Personality,
  484. PersonalityEncoding, Arch);
  485. CIEs[StartOffset] = Cie.get();
  486. Entries.emplace_back(std::move(Cie));
  487. } else {
  488. // FDE
  489. uint64_t CIEPointer = Id;
  490. uint64_t InitialLocation = 0;
  491. uint64_t AddressRange = 0;
  492. Optional<uint64_t> LSDAAddress;
  493. CIE *Cie = CIEs[IsEH ? (StartStructureOffset - CIEPointer) : CIEPointer];
  494. if (IsEH) {
  495. // The address size is encoded in the CIE we reference.
  496. if (!Cie)
  497. return createStringError(errc::invalid_argument,
  498. "parsing FDE data at 0x%" PRIx64
  499. " failed due to missing CIE",
  500. StartOffset);
  501. if (auto Val =
  502. Data.getEncodedPointer(&Offset, Cie->getFDEPointerEncoding(),
  503. EHFrameAddress + Offset)) {
  504. InitialLocation = *Val;
  505. }
  506. if (auto Val = Data.getEncodedPointer(
  507. &Offset, Cie->getFDEPointerEncoding(), 0)) {
  508. AddressRange = *Val;
  509. }
  510. StringRef AugmentationString = Cie->getAugmentationString();
  511. if (!AugmentationString.empty()) {
  512. // Parse the augmentation length and data for this FDE.
  513. uint64_t AugmentationLength = Data.getULEB128(&Offset);
  514. uint64_t EndAugmentationOffset = Offset + AugmentationLength;
  515. // Decode the LSDA if the CIE augmentation string said we should.
  516. if (Cie->getLSDAPointerEncoding() != DW_EH_PE_omit) {
  517. LSDAAddress = Data.getEncodedPointer(
  518. &Offset, Cie->getLSDAPointerEncoding(),
  519. EHFrameAddress ? Offset + EHFrameAddress : 0);
  520. }
  521. if (Offset != EndAugmentationOffset)
  522. return createStringError(errc::invalid_argument,
  523. "parsing augmentation data at 0x%" PRIx64
  524. " failed",
  525. StartOffset);
  526. }
  527. } else {
  528. InitialLocation = Data.getRelocatedAddress(&Offset);
  529. AddressRange = Data.getRelocatedAddress(&Offset);
  530. }
  531. Entries.emplace_back(new FDE(IsDWARF64, StartOffset, Length, CIEPointer,
  532. InitialLocation, AddressRange, Cie,
  533. LSDAAddress, Arch));
  534. }
  535. if (Error E =
  536. Entries.back()->cfis().parse(Data, &Offset, EndStructureOffset))
  537. return E;
  538. if (Offset != EndStructureOffset)
  539. return createStringError(
  540. errc::invalid_argument,
  541. "parsing entry instructions at 0x%" PRIx64 " failed", StartOffset);
  542. }
  543. return Error::success();
  544. }
  545. FrameEntry *DWARFDebugFrame::getEntryAtOffset(uint64_t Offset) const {
  546. auto It = partition_point(Entries, [=](const std::unique_ptr<FrameEntry> &E) {
  547. return E->getOffset() < Offset;
  548. });
  549. if (It != Entries.end() && (*It)->getOffset() == Offset)
  550. return It->get();
  551. return nullptr;
  552. }
  553. void DWARFDebugFrame::dump(raw_ostream &OS, DIDumpOptions DumpOpts,
  554. const MCRegisterInfo *MRI,
  555. Optional<uint64_t> Offset) const {
  556. if (Offset) {
  557. if (auto *Entry = getEntryAtOffset(*Offset))
  558. Entry->dump(OS, DumpOpts, MRI, IsEH);
  559. return;
  560. }
  561. OS << "\n";
  562. for (const auto &Entry : Entries)
  563. Entry->dump(OS, DumpOpts, MRI, IsEH);
  564. }