DwarfParser.hpp 32 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848
  1. //===----------------------------------------------------------------------===//
  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. // Parses DWARF CFIs (FDEs and CIEs).
  9. //
  10. //===----------------------------------------------------------------------===//
  11. #ifndef __DWARF_PARSER_HPP__
  12. #define __DWARF_PARSER_HPP__
  13. #include <inttypes.h>
  14. #include <stdint.h>
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include "libunwind.h"
  18. #include "dwarf2.h"
  19. #include "Registers.hpp"
  20. #include "config.h"
  21. namespace libunwind {
  22. /// CFI_Parser does basic parsing of a CFI (Call Frame Information) records.
  23. /// See DWARF Spec for details:
  24. /// http://refspecs.linuxbase.org/LSB_3.1.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html
  25. ///
  26. template <typename A>
  27. class CFI_Parser {
  28. public:
  29. typedef typename A::pint_t pint_t;
  30. /// Information encoded in a CIE (Common Information Entry)
  31. struct CIE_Info {
  32. pint_t cieStart;
  33. pint_t cieLength;
  34. pint_t cieInstructions;
  35. uint8_t pointerEncoding;
  36. uint8_t lsdaEncoding;
  37. uint8_t personalityEncoding;
  38. uint8_t personalityOffsetInCIE;
  39. pint_t personality;
  40. uint32_t codeAlignFactor;
  41. int dataAlignFactor;
  42. bool isSignalFrame;
  43. bool fdesHaveAugmentationData;
  44. uint8_t returnAddressRegister;
  45. #if defined(_LIBUNWIND_TARGET_AARCH64)
  46. bool addressesSignedWithBKey;
  47. #endif
  48. };
  49. /// Information about an FDE (Frame Description Entry)
  50. struct FDE_Info {
  51. pint_t fdeStart;
  52. pint_t fdeLength;
  53. pint_t fdeInstructions;
  54. pint_t pcStart;
  55. pint_t pcEnd;
  56. pint_t lsda;
  57. };
  58. enum {
  59. kMaxRegisterNumber = _LIBUNWIND_HIGHEST_DWARF_REGISTER
  60. };
  61. enum RegisterSavedWhere {
  62. kRegisterUnused,
  63. kRegisterUndefined,
  64. kRegisterInCFA,
  65. kRegisterInCFADecrypt, // sparc64 specific
  66. kRegisterOffsetFromCFA,
  67. kRegisterInRegister,
  68. kRegisterAtExpression,
  69. kRegisterIsExpression
  70. };
  71. struct RegisterLocation {
  72. RegisterSavedWhere location;
  73. bool initialStateSaved;
  74. int64_t value;
  75. };
  76. /// Information about a frame layout and registers saved determined
  77. /// by "running" the DWARF FDE "instructions"
  78. struct PrologInfo {
  79. uint32_t cfaRegister;
  80. int32_t cfaRegisterOffset; // CFA = (cfaRegister)+cfaRegisterOffset
  81. int64_t cfaExpression; // CFA = expression
  82. uint32_t spExtraArgSize;
  83. RegisterLocation savedRegisters[kMaxRegisterNumber + 1];
  84. enum class InitializeTime { kLazy, kNormal };
  85. // When saving registers, this data structure is lazily initialized.
  86. PrologInfo(InitializeTime IT = InitializeTime::kNormal) {
  87. if (IT == InitializeTime::kNormal)
  88. memset(this, 0, sizeof(*this));
  89. }
  90. void checkSaveRegister(uint64_t reg, PrologInfo &initialState) {
  91. if (!savedRegisters[reg].initialStateSaved) {
  92. initialState.savedRegisters[reg] = savedRegisters[reg];
  93. savedRegisters[reg].initialStateSaved = true;
  94. }
  95. }
  96. void setRegister(uint64_t reg, RegisterSavedWhere newLocation,
  97. int64_t newValue, PrologInfo &initialState) {
  98. checkSaveRegister(reg, initialState);
  99. savedRegisters[reg].location = newLocation;
  100. savedRegisters[reg].value = newValue;
  101. }
  102. void setRegisterLocation(uint64_t reg, RegisterSavedWhere newLocation,
  103. PrologInfo &initialState) {
  104. checkSaveRegister(reg, initialState);
  105. savedRegisters[reg].location = newLocation;
  106. }
  107. void setRegisterValue(uint64_t reg, int64_t newValue,
  108. PrologInfo &initialState) {
  109. checkSaveRegister(reg, initialState);
  110. savedRegisters[reg].value = newValue;
  111. }
  112. void restoreRegisterToInitialState(uint64_t reg, PrologInfo &initialState) {
  113. if (savedRegisters[reg].initialStateSaved)
  114. savedRegisters[reg] = initialState.savedRegisters[reg];
  115. // else the register still holds its initial state
  116. }
  117. };
  118. struct PrologInfoStackEntry {
  119. PrologInfoStackEntry(PrologInfoStackEntry *n, const PrologInfo &i)
  120. : next(n), info(i) {}
  121. PrologInfoStackEntry *next;
  122. PrologInfo info;
  123. };
  124. struct RememberStack {
  125. PrologInfoStackEntry *entry;
  126. RememberStack() : entry(nullptr) {}
  127. ~RememberStack() {
  128. #if defined(_LIBUNWIND_REMEMBER_CLEANUP_NEEDED)
  129. // Clean up rememberStack. Even in the case where every
  130. // DW_CFA_remember_state is paired with a DW_CFA_restore_state,
  131. // parseInstructions can skip restore opcodes if it reaches the target PC
  132. // and stops interpreting, so we have to make sure we don't leak memory.
  133. while (entry) {
  134. PrologInfoStackEntry *next = entry->next;
  135. _LIBUNWIND_REMEMBER_FREE(entry);
  136. entry = next;
  137. }
  138. #endif
  139. }
  140. };
  141. static bool findFDE(A &addressSpace, pint_t pc, pint_t ehSectionStart,
  142. size_t sectionLength, pint_t fdeHint, FDE_Info *fdeInfo,
  143. CIE_Info *cieInfo);
  144. static const char *decodeFDE(A &addressSpace, pint_t fdeStart,
  145. FDE_Info *fdeInfo, CIE_Info *cieInfo,
  146. bool useCIEInfo = false);
  147. static bool parseFDEInstructions(A &addressSpace, const FDE_Info &fdeInfo,
  148. const CIE_Info &cieInfo, pint_t upToPC,
  149. int arch, PrologInfo *results);
  150. static const char *parseCIE(A &addressSpace, pint_t cie, CIE_Info *cieInfo);
  151. };
  152. /// Parse a FDE into a CIE_Info and an FDE_Info. If useCIEInfo is
  153. /// true, treat cieInfo as already-parsed CIE_Info (whose start offset
  154. /// must match the one specified by the FDE) rather than parsing the
  155. /// one indicated within the FDE.
  156. template <typename A>
  157. const char *CFI_Parser<A>::decodeFDE(A &addressSpace, pint_t fdeStart,
  158. FDE_Info *fdeInfo, CIE_Info *cieInfo,
  159. bool useCIEInfo) {
  160. pint_t p = fdeStart;
  161. pint_t cfiLength = (pint_t)addressSpace.get32(p);
  162. p += 4;
  163. if (cfiLength == 0xffffffff) {
  164. // 0xffffffff means length is really next 8 bytes
  165. cfiLength = (pint_t)addressSpace.get64(p);
  166. p += 8;
  167. }
  168. if (cfiLength == 0)
  169. return "FDE has zero length"; // zero terminator
  170. uint32_t ciePointer = addressSpace.get32(p);
  171. if (ciePointer == 0)
  172. return "FDE is really a CIE"; // this is a CIE not an FDE
  173. pint_t nextCFI = p + cfiLength;
  174. pint_t cieStart = p - ciePointer;
  175. if (useCIEInfo) {
  176. if (cieInfo->cieStart != cieStart)
  177. return "CIE start does not match";
  178. } else {
  179. const char *err = parseCIE(addressSpace, cieStart, cieInfo);
  180. if (err != NULL)
  181. return err;
  182. }
  183. p += 4;
  184. // Parse pc begin and range.
  185. pint_t pcStart =
  186. addressSpace.getEncodedP(p, nextCFI, cieInfo->pointerEncoding);
  187. pint_t pcRange =
  188. addressSpace.getEncodedP(p, nextCFI, cieInfo->pointerEncoding & 0x0F);
  189. // Parse rest of info.
  190. fdeInfo->lsda = 0;
  191. // Check for augmentation length.
  192. if (cieInfo->fdesHaveAugmentationData) {
  193. pint_t augLen = (pint_t)addressSpace.getULEB128(p, nextCFI);
  194. pint_t endOfAug = p + augLen;
  195. if (cieInfo->lsdaEncoding != DW_EH_PE_omit) {
  196. // Peek at value (without indirection). Zero means no LSDA.
  197. pint_t lsdaStart = p;
  198. if (addressSpace.getEncodedP(p, nextCFI, cieInfo->lsdaEncoding & 0x0F) !=
  199. 0) {
  200. // Reset pointer and re-parse LSDA address.
  201. p = lsdaStart;
  202. fdeInfo->lsda =
  203. addressSpace.getEncodedP(p, nextCFI, cieInfo->lsdaEncoding);
  204. }
  205. }
  206. p = endOfAug;
  207. }
  208. fdeInfo->fdeStart = fdeStart;
  209. fdeInfo->fdeLength = nextCFI - fdeStart;
  210. fdeInfo->fdeInstructions = p;
  211. fdeInfo->pcStart = pcStart;
  212. fdeInfo->pcEnd = pcStart + pcRange;
  213. return NULL; // success
  214. }
  215. /// Scan an eh_frame section to find an FDE for a pc
  216. template <typename A>
  217. bool CFI_Parser<A>::findFDE(A &addressSpace, pint_t pc, pint_t ehSectionStart,
  218. size_t sectionLength, pint_t fdeHint,
  219. FDE_Info *fdeInfo, CIE_Info *cieInfo) {
  220. //fprintf(stderr, "findFDE(0x%llX)\n", (long long)pc);
  221. pint_t p = (fdeHint != 0) ? fdeHint : ehSectionStart;
  222. const pint_t ehSectionEnd = (sectionLength == SIZE_MAX)
  223. ? static_cast<pint_t>(-1)
  224. : (ehSectionStart + sectionLength);
  225. while (p < ehSectionEnd) {
  226. pint_t currentCFI = p;
  227. //fprintf(stderr, "findFDE() CFI at 0x%llX\n", (long long)p);
  228. pint_t cfiLength = addressSpace.get32(p);
  229. p += 4;
  230. if (cfiLength == 0xffffffff) {
  231. // 0xffffffff means length is really next 8 bytes
  232. cfiLength = (pint_t)addressSpace.get64(p);
  233. p += 8;
  234. }
  235. if (cfiLength == 0)
  236. return false; // zero terminator
  237. uint32_t id = addressSpace.get32(p);
  238. if (id == 0) {
  239. // Skip over CIEs.
  240. p += cfiLength;
  241. } else {
  242. // Process FDE to see if it covers pc.
  243. pint_t nextCFI = p + cfiLength;
  244. uint32_t ciePointer = addressSpace.get32(p);
  245. pint_t cieStart = p - ciePointer;
  246. // Validate pointer to CIE is within section.
  247. if ((ehSectionStart <= cieStart) && (cieStart < ehSectionEnd)) {
  248. if (parseCIE(addressSpace, cieStart, cieInfo) == NULL) {
  249. p += 4;
  250. // Parse pc begin and range.
  251. pint_t pcStart =
  252. addressSpace.getEncodedP(p, nextCFI, cieInfo->pointerEncoding);
  253. pint_t pcRange = addressSpace.getEncodedP(
  254. p, nextCFI, cieInfo->pointerEncoding & 0x0F);
  255. // Test if pc is within the function this FDE covers.
  256. if ((pcStart < pc) && (pc <= pcStart + pcRange)) {
  257. // parse rest of info
  258. fdeInfo->lsda = 0;
  259. // check for augmentation length
  260. if (cieInfo->fdesHaveAugmentationData) {
  261. pint_t augLen = (pint_t)addressSpace.getULEB128(p, nextCFI);
  262. pint_t endOfAug = p + augLen;
  263. if (cieInfo->lsdaEncoding != DW_EH_PE_omit) {
  264. // Peek at value (without indirection). Zero means no LSDA.
  265. pint_t lsdaStart = p;
  266. if (addressSpace.getEncodedP(
  267. p, nextCFI, cieInfo->lsdaEncoding & 0x0F) != 0) {
  268. // Reset pointer and re-parse LSDA address.
  269. p = lsdaStart;
  270. fdeInfo->lsda = addressSpace
  271. .getEncodedP(p, nextCFI, cieInfo->lsdaEncoding);
  272. }
  273. }
  274. p = endOfAug;
  275. }
  276. fdeInfo->fdeStart = currentCFI;
  277. fdeInfo->fdeLength = nextCFI - currentCFI;
  278. fdeInfo->fdeInstructions = p;
  279. fdeInfo->pcStart = pcStart;
  280. fdeInfo->pcEnd = pcStart + pcRange;
  281. return true;
  282. } else {
  283. // pc is not in begin/range, skip this FDE
  284. }
  285. } else {
  286. // Malformed CIE, now augmentation describing pc range encoding.
  287. }
  288. } else {
  289. // malformed FDE. CIE is bad
  290. }
  291. p = nextCFI;
  292. }
  293. }
  294. return false;
  295. }
  296. /// Extract info from a CIE
  297. template <typename A>
  298. const char *CFI_Parser<A>::parseCIE(A &addressSpace, pint_t cie,
  299. CIE_Info *cieInfo) {
  300. cieInfo->pointerEncoding = 0;
  301. cieInfo->lsdaEncoding = DW_EH_PE_omit;
  302. cieInfo->personalityEncoding = 0;
  303. cieInfo->personalityOffsetInCIE = 0;
  304. cieInfo->personality = 0;
  305. cieInfo->codeAlignFactor = 0;
  306. cieInfo->dataAlignFactor = 0;
  307. cieInfo->isSignalFrame = false;
  308. cieInfo->fdesHaveAugmentationData = false;
  309. #if defined(_LIBUNWIND_TARGET_AARCH64)
  310. cieInfo->addressesSignedWithBKey = false;
  311. #endif
  312. cieInfo->cieStart = cie;
  313. pint_t p = cie;
  314. pint_t cieLength = (pint_t)addressSpace.get32(p);
  315. p += 4;
  316. pint_t cieContentEnd = p + cieLength;
  317. if (cieLength == 0xffffffff) {
  318. // 0xffffffff means length is really next 8 bytes
  319. cieLength = (pint_t)addressSpace.get64(p);
  320. p += 8;
  321. cieContentEnd = p + cieLength;
  322. }
  323. if (cieLength == 0)
  324. return NULL;
  325. // CIE ID is always 0
  326. if (addressSpace.get32(p) != 0)
  327. return "CIE ID is not zero";
  328. p += 4;
  329. // Version is always 1 or 3
  330. uint8_t version = addressSpace.get8(p);
  331. if ((version != 1) && (version != 3))
  332. return "CIE version is not 1 or 3";
  333. ++p;
  334. // save start of augmentation string and find end
  335. pint_t strStart = p;
  336. while (addressSpace.get8(p) != 0)
  337. ++p;
  338. ++p;
  339. // parse code aligment factor
  340. cieInfo->codeAlignFactor = (uint32_t)addressSpace.getULEB128(p, cieContentEnd);
  341. // parse data alignment factor
  342. cieInfo->dataAlignFactor = (int)addressSpace.getSLEB128(p, cieContentEnd);
  343. // parse return address register
  344. uint64_t raReg = (version == 1) ? addressSpace.get8(p++)
  345. : addressSpace.getULEB128(p, cieContentEnd);
  346. assert(raReg < 255 && "return address register too large");
  347. cieInfo->returnAddressRegister = (uint8_t)raReg;
  348. // parse augmentation data based on augmentation string
  349. const char *result = NULL;
  350. if (addressSpace.get8(strStart) == 'z') {
  351. // parse augmentation data length
  352. addressSpace.getULEB128(p, cieContentEnd);
  353. for (pint_t s = strStart; addressSpace.get8(s) != '\0'; ++s) {
  354. switch (addressSpace.get8(s)) {
  355. case 'z':
  356. cieInfo->fdesHaveAugmentationData = true;
  357. break;
  358. case 'P':
  359. cieInfo->personalityEncoding = addressSpace.get8(p);
  360. ++p;
  361. cieInfo->personalityOffsetInCIE = (uint8_t)(p - cie);
  362. cieInfo->personality = addressSpace
  363. .getEncodedP(p, cieContentEnd, cieInfo->personalityEncoding);
  364. break;
  365. case 'L':
  366. cieInfo->lsdaEncoding = addressSpace.get8(p);
  367. ++p;
  368. break;
  369. case 'R':
  370. cieInfo->pointerEncoding = addressSpace.get8(p);
  371. ++p;
  372. break;
  373. case 'S':
  374. cieInfo->isSignalFrame = true;
  375. break;
  376. #if defined(_LIBUNWIND_TARGET_AARCH64)
  377. case 'B':
  378. cieInfo->addressesSignedWithBKey = true;
  379. break;
  380. #endif
  381. default:
  382. // ignore unknown letters
  383. break;
  384. }
  385. }
  386. }
  387. cieInfo->cieLength = cieContentEnd - cieInfo->cieStart;
  388. cieInfo->cieInstructions = p;
  389. return result;
  390. }
  391. /// "run" the DWARF instructions and create the abstact PrologInfo for an FDE
  392. template <typename A>
  393. bool CFI_Parser<A>::parseFDEInstructions(A &addressSpace,
  394. const FDE_Info &fdeInfo,
  395. const CIE_Info &cieInfo, pint_t upToPC,
  396. int arch, PrologInfo *results) {
  397. // Alloca is used for the allocation of the rememberStack entries. It removes
  398. // the dependency on new/malloc but the below for loop can not be refactored
  399. // into functions. Entry could be saved during the processing of a CIE and
  400. // restored by an FDE.
  401. RememberStack rememberStack;
  402. struct ParseInfo {
  403. pint_t instructions;
  404. pint_t instructionsEnd;
  405. pint_t pcoffset;
  406. };
  407. ParseInfo parseInfoArray[] = {
  408. {cieInfo.cieInstructions, cieInfo.cieStart + cieInfo.cieLength,
  409. (pint_t)(-1)},
  410. {fdeInfo.fdeInstructions, fdeInfo.fdeStart + fdeInfo.fdeLength,
  411. upToPC - fdeInfo.pcStart}};
  412. for (const auto &info : parseInfoArray) {
  413. pint_t p = info.instructions;
  414. pint_t instructionsEnd = info.instructionsEnd;
  415. pint_t pcoffset = info.pcoffset;
  416. pint_t codeOffset = 0;
  417. // initialState initialized as registers in results are modified. Use
  418. // PrologInfo accessor functions to avoid reading uninitialized data.
  419. PrologInfo initialState(PrologInfo::InitializeTime::kLazy);
  420. _LIBUNWIND_TRACE_DWARF("parseFDEInstructions(instructions=0x%0" PRIx64
  421. ")\n",
  422. static_cast<uint64_t>(instructionsEnd));
  423. // see DWARF Spec, section 6.4.2 for details on unwind opcodes
  424. while ((p < instructionsEnd) && (codeOffset < pcoffset)) {
  425. uint64_t reg;
  426. uint64_t reg2;
  427. int64_t offset;
  428. uint64_t length;
  429. uint8_t opcode = addressSpace.get8(p);
  430. uint8_t operand;
  431. ++p;
  432. switch (opcode) {
  433. case DW_CFA_nop:
  434. _LIBUNWIND_TRACE_DWARF("DW_CFA_nop\n");
  435. break;
  436. case DW_CFA_set_loc:
  437. codeOffset = addressSpace.getEncodedP(p, instructionsEnd,
  438. cieInfo.pointerEncoding);
  439. _LIBUNWIND_TRACE_DWARF("DW_CFA_set_loc\n");
  440. break;
  441. case DW_CFA_advance_loc1:
  442. codeOffset += (addressSpace.get8(p) * cieInfo.codeAlignFactor);
  443. p += 1;
  444. _LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc1: new offset=%" PRIu64 "\n",
  445. static_cast<uint64_t>(codeOffset));
  446. break;
  447. case DW_CFA_advance_loc2:
  448. codeOffset += (addressSpace.get16(p) * cieInfo.codeAlignFactor);
  449. p += 2;
  450. _LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc2: new offset=%" PRIu64 "\n",
  451. static_cast<uint64_t>(codeOffset));
  452. break;
  453. case DW_CFA_advance_loc4:
  454. codeOffset += (addressSpace.get32(p) * cieInfo.codeAlignFactor);
  455. p += 4;
  456. _LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc4: new offset=%" PRIu64 "\n",
  457. static_cast<uint64_t>(codeOffset));
  458. break;
  459. case DW_CFA_offset_extended:
  460. reg = addressSpace.getULEB128(p, instructionsEnd);
  461. offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd) *
  462. cieInfo.dataAlignFactor;
  463. if (reg > kMaxRegisterNumber) {
  464. _LIBUNWIND_LOG0(
  465. "malformed DW_CFA_offset_extended DWARF unwind, reg too big");
  466. return false;
  467. }
  468. results->setRegister(reg, kRegisterInCFA, offset, initialState);
  469. _LIBUNWIND_TRACE_DWARF("DW_CFA_offset_extended(reg=%" PRIu64 ", "
  470. "offset=%" PRId64 ")\n",
  471. reg, offset);
  472. break;
  473. case DW_CFA_restore_extended:
  474. reg = addressSpace.getULEB128(p, instructionsEnd);
  475. if (reg > kMaxRegisterNumber) {
  476. _LIBUNWIND_LOG0(
  477. "malformed DW_CFA_restore_extended DWARF unwind, reg too big");
  478. return false;
  479. }
  480. results->restoreRegisterToInitialState(reg, initialState);
  481. _LIBUNWIND_TRACE_DWARF("DW_CFA_restore_extended(reg=%" PRIu64 ")\n",
  482. reg);
  483. break;
  484. case DW_CFA_undefined:
  485. reg = addressSpace.getULEB128(p, instructionsEnd);
  486. if (reg > kMaxRegisterNumber) {
  487. _LIBUNWIND_LOG0(
  488. "malformed DW_CFA_undefined DWARF unwind, reg too big");
  489. return false;
  490. }
  491. results->setRegisterLocation(reg, kRegisterUndefined, initialState);
  492. _LIBUNWIND_TRACE_DWARF("DW_CFA_undefined(reg=%" PRIu64 ")\n", reg);
  493. break;
  494. case DW_CFA_same_value:
  495. reg = addressSpace.getULEB128(p, instructionsEnd);
  496. if (reg > kMaxRegisterNumber) {
  497. _LIBUNWIND_LOG0(
  498. "malformed DW_CFA_same_value DWARF unwind, reg too big");
  499. return false;
  500. }
  501. // <rdar://problem/8456377> DW_CFA_same_value unsupported
  502. // "same value" means register was stored in frame, but its current
  503. // value has not changed, so no need to restore from frame.
  504. // We model this as if the register was never saved.
  505. results->setRegisterLocation(reg, kRegisterUnused, initialState);
  506. _LIBUNWIND_TRACE_DWARF("DW_CFA_same_value(reg=%" PRIu64 ")\n", reg);
  507. break;
  508. case DW_CFA_register:
  509. reg = addressSpace.getULEB128(p, instructionsEnd);
  510. reg2 = addressSpace.getULEB128(p, instructionsEnd);
  511. if (reg > kMaxRegisterNumber) {
  512. _LIBUNWIND_LOG0(
  513. "malformed DW_CFA_register DWARF unwind, reg too big");
  514. return false;
  515. }
  516. if (reg2 > kMaxRegisterNumber) {
  517. _LIBUNWIND_LOG0(
  518. "malformed DW_CFA_register DWARF unwind, reg2 too big");
  519. return false;
  520. }
  521. results->setRegister(reg, kRegisterInRegister, (int64_t)reg2,
  522. initialState);
  523. _LIBUNWIND_TRACE_DWARF(
  524. "DW_CFA_register(reg=%" PRIu64 ", reg2=%" PRIu64 ")\n", reg, reg2);
  525. break;
  526. case DW_CFA_remember_state: {
  527. // Avoid operator new because that would be an upward dependency.
  528. // Avoid malloc because it needs heap allocation.
  529. PrologInfoStackEntry *entry =
  530. (PrologInfoStackEntry *)_LIBUNWIND_REMEMBER_ALLOC(
  531. sizeof(PrologInfoStackEntry));
  532. if (entry != NULL) {
  533. entry->next = rememberStack.entry;
  534. entry->info = *results;
  535. rememberStack.entry = entry;
  536. } else {
  537. return false;
  538. }
  539. _LIBUNWIND_TRACE_DWARF("DW_CFA_remember_state\n");
  540. break;
  541. }
  542. case DW_CFA_restore_state:
  543. if (rememberStack.entry != NULL) {
  544. PrologInfoStackEntry *top = rememberStack.entry;
  545. *results = top->info;
  546. rememberStack.entry = top->next;
  547. _LIBUNWIND_REMEMBER_FREE(top);
  548. } else {
  549. return false;
  550. }
  551. _LIBUNWIND_TRACE_DWARF("DW_CFA_restore_state\n");
  552. break;
  553. case DW_CFA_def_cfa:
  554. reg = addressSpace.getULEB128(p, instructionsEnd);
  555. offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd);
  556. if (reg > kMaxRegisterNumber) {
  557. _LIBUNWIND_LOG0("malformed DW_CFA_def_cfa DWARF unwind, reg too big");
  558. return false;
  559. }
  560. results->cfaRegister = (uint32_t)reg;
  561. results->cfaRegisterOffset = (int32_t)offset;
  562. _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa(reg=%" PRIu64 ", offset=%" PRIu64
  563. ")\n",
  564. reg, offset);
  565. break;
  566. case DW_CFA_def_cfa_register:
  567. reg = addressSpace.getULEB128(p, instructionsEnd);
  568. if (reg > kMaxRegisterNumber) {
  569. _LIBUNWIND_LOG0(
  570. "malformed DW_CFA_def_cfa_register DWARF unwind, reg too big");
  571. return false;
  572. }
  573. results->cfaRegister = (uint32_t)reg;
  574. _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_register(%" PRIu64 ")\n", reg);
  575. break;
  576. case DW_CFA_def_cfa_offset:
  577. results->cfaRegisterOffset =
  578. (int32_t)addressSpace.getULEB128(p, instructionsEnd);
  579. _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_offset(%d)\n",
  580. results->cfaRegisterOffset);
  581. break;
  582. case DW_CFA_def_cfa_expression:
  583. results->cfaRegister = 0;
  584. results->cfaExpression = (int64_t)p;
  585. length = addressSpace.getULEB128(p, instructionsEnd);
  586. assert(length < static_cast<pint_t>(~0) && "pointer overflow");
  587. p += static_cast<pint_t>(length);
  588. _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_expression(expression=0x%" PRIx64
  589. ", length=%" PRIu64 ")\n",
  590. results->cfaExpression, length);
  591. break;
  592. case DW_CFA_expression:
  593. reg = addressSpace.getULEB128(p, instructionsEnd);
  594. if (reg > kMaxRegisterNumber) {
  595. _LIBUNWIND_LOG0(
  596. "malformed DW_CFA_expression DWARF unwind, reg too big");
  597. return false;
  598. }
  599. results->setRegister(reg, kRegisterAtExpression, (int64_t)p,
  600. initialState);
  601. length = addressSpace.getULEB128(p, instructionsEnd);
  602. assert(length < static_cast<pint_t>(~0) && "pointer overflow");
  603. p += static_cast<pint_t>(length);
  604. _LIBUNWIND_TRACE_DWARF("DW_CFA_expression(reg=%" PRIu64 ", "
  605. "expression=0x%" PRIx64 ", "
  606. "length=%" PRIu64 ")\n",
  607. reg, results->savedRegisters[reg].value, length);
  608. break;
  609. case DW_CFA_offset_extended_sf:
  610. reg = addressSpace.getULEB128(p, instructionsEnd);
  611. if (reg > kMaxRegisterNumber) {
  612. _LIBUNWIND_LOG0(
  613. "malformed DW_CFA_offset_extended_sf DWARF unwind, reg too big");
  614. return false;
  615. }
  616. offset = addressSpace.getSLEB128(p, instructionsEnd) *
  617. cieInfo.dataAlignFactor;
  618. results->setRegister(reg, kRegisterInCFA, offset, initialState);
  619. _LIBUNWIND_TRACE_DWARF("DW_CFA_offset_extended_sf(reg=%" PRIu64 ", "
  620. "offset=%" PRId64 ")\n",
  621. reg, offset);
  622. break;
  623. case DW_CFA_def_cfa_sf:
  624. reg = addressSpace.getULEB128(p, instructionsEnd);
  625. offset = addressSpace.getSLEB128(p, instructionsEnd) *
  626. cieInfo.dataAlignFactor;
  627. if (reg > kMaxRegisterNumber) {
  628. _LIBUNWIND_LOG0(
  629. "malformed DW_CFA_def_cfa_sf DWARF unwind, reg too big");
  630. return false;
  631. }
  632. results->cfaRegister = (uint32_t)reg;
  633. results->cfaRegisterOffset = (int32_t)offset;
  634. _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_sf(reg=%" PRIu64 ", "
  635. "offset=%" PRId64 ")\n",
  636. reg, offset);
  637. break;
  638. case DW_CFA_def_cfa_offset_sf:
  639. results->cfaRegisterOffset =
  640. (int32_t)(addressSpace.getSLEB128(p, instructionsEnd) *
  641. cieInfo.dataAlignFactor);
  642. _LIBUNWIND_TRACE_DWARF("DW_CFA_def_cfa_offset_sf(%d)\n",
  643. results->cfaRegisterOffset);
  644. break;
  645. case DW_CFA_val_offset:
  646. reg = addressSpace.getULEB128(p, instructionsEnd);
  647. if (reg > kMaxRegisterNumber) {
  648. _LIBUNWIND_LOG(
  649. "malformed DW_CFA_val_offset DWARF unwind, reg (%" PRIu64
  650. ") out of range\n",
  651. reg);
  652. return false;
  653. }
  654. offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd) *
  655. cieInfo.dataAlignFactor;
  656. results->setRegister(reg, kRegisterOffsetFromCFA, offset, initialState);
  657. _LIBUNWIND_TRACE_DWARF("DW_CFA_val_offset(reg=%" PRIu64 ", "
  658. "offset=%" PRId64 "\n",
  659. reg, offset);
  660. break;
  661. case DW_CFA_val_offset_sf:
  662. reg = addressSpace.getULEB128(p, instructionsEnd);
  663. if (reg > kMaxRegisterNumber) {
  664. _LIBUNWIND_LOG0(
  665. "malformed DW_CFA_val_offset_sf DWARF unwind, reg too big");
  666. return false;
  667. }
  668. offset = addressSpace.getSLEB128(p, instructionsEnd) *
  669. cieInfo.dataAlignFactor;
  670. results->setRegister(reg, kRegisterOffsetFromCFA, offset, initialState);
  671. _LIBUNWIND_TRACE_DWARF("DW_CFA_val_offset_sf(reg=%" PRIu64 ", "
  672. "offset=%" PRId64 "\n",
  673. reg, offset);
  674. break;
  675. case DW_CFA_val_expression:
  676. reg = addressSpace.getULEB128(p, instructionsEnd);
  677. if (reg > kMaxRegisterNumber) {
  678. _LIBUNWIND_LOG0(
  679. "malformed DW_CFA_val_expression DWARF unwind, reg too big");
  680. return false;
  681. }
  682. results->setRegister(reg, kRegisterIsExpression, (int64_t)p,
  683. initialState);
  684. length = addressSpace.getULEB128(p, instructionsEnd);
  685. assert(length < static_cast<pint_t>(~0) && "pointer overflow");
  686. p += static_cast<pint_t>(length);
  687. _LIBUNWIND_TRACE_DWARF("DW_CFA_val_expression(reg=%" PRIu64 ", "
  688. "expression=0x%" PRIx64 ", length=%" PRIu64
  689. ")\n",
  690. reg, results->savedRegisters[reg].value, length);
  691. break;
  692. case DW_CFA_GNU_args_size:
  693. length = addressSpace.getULEB128(p, instructionsEnd);
  694. results->spExtraArgSize = (uint32_t)length;
  695. _LIBUNWIND_TRACE_DWARF("DW_CFA_GNU_args_size(%" PRIu64 ")\n", length);
  696. break;
  697. case DW_CFA_GNU_negative_offset_extended:
  698. reg = addressSpace.getULEB128(p, instructionsEnd);
  699. if (reg > kMaxRegisterNumber) {
  700. _LIBUNWIND_LOG0("malformed DW_CFA_GNU_negative_offset_extended DWARF "
  701. "unwind, reg too big");
  702. return false;
  703. }
  704. offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd) *
  705. cieInfo.dataAlignFactor;
  706. results->setRegister(reg, kRegisterInCFA, -offset, initialState);
  707. _LIBUNWIND_TRACE_DWARF(
  708. "DW_CFA_GNU_negative_offset_extended(%" PRId64 ")\n", offset);
  709. break;
  710. #if defined(_LIBUNWIND_TARGET_AARCH64) || defined(_LIBUNWIND_TARGET_SPARC) || \
  711. defined(_LIBUNWIND_TARGET_SPARC64)
  712. // The same constant is used to represent different instructions on
  713. // AArch64 (negate_ra_state) and SPARC (window_save).
  714. static_assert(DW_CFA_AARCH64_negate_ra_state == DW_CFA_GNU_window_save,
  715. "uses the same constant");
  716. case DW_CFA_AARCH64_negate_ra_state:
  717. switch (arch) {
  718. #if defined(_LIBUNWIND_TARGET_AARCH64)
  719. case REGISTERS_ARM64: {
  720. int64_t value =
  721. results->savedRegisters[UNW_AARCH64_RA_SIGN_STATE].value ^ 0x1;
  722. results->setRegisterValue(UNW_AARCH64_RA_SIGN_STATE, value,
  723. initialState);
  724. _LIBUNWIND_TRACE_DWARF("DW_CFA_AARCH64_negate_ra_state\n");
  725. } break;
  726. #endif
  727. #if defined(_LIBUNWIND_TARGET_SPARC)
  728. // case DW_CFA_GNU_window_save:
  729. case REGISTERS_SPARC:
  730. _LIBUNWIND_TRACE_DWARF("DW_CFA_GNU_window_save()\n");
  731. for (reg = UNW_SPARC_O0; reg <= UNW_SPARC_O7; reg++) {
  732. results->setRegister(reg, kRegisterInRegister,
  733. ((int64_t)reg - UNW_SPARC_O0) + UNW_SPARC_I0,
  734. initialState);
  735. }
  736. for (reg = UNW_SPARC_L0; reg <= UNW_SPARC_I7; reg++) {
  737. results->setRegister(reg, kRegisterInCFA,
  738. ((int64_t)reg - UNW_SPARC_L0) * 4,
  739. initialState);
  740. }
  741. break;
  742. #endif
  743. #if defined(_LIBUNWIND_TARGET_SPARC64)
  744. // case DW_CFA_GNU_window_save:
  745. case REGISTERS_SPARC64:
  746. // Don't save %o0-%o7 on sparc64.
  747. // https://reviews.llvm.org/D32450#736405
  748. for (reg = UNW_SPARC_L0; reg <= UNW_SPARC_I7; reg++) {
  749. if (reg == UNW_SPARC_I7)
  750. results->setRegister(
  751. reg, kRegisterInCFADecrypt,
  752. static_cast<int64_t>((reg - UNW_SPARC_L0) * sizeof(pint_t)),
  753. initialState);
  754. else
  755. results->setRegister(
  756. reg, kRegisterInCFA,
  757. static_cast<int64_t>((reg - UNW_SPARC_L0) * sizeof(pint_t)),
  758. initialState);
  759. }
  760. _LIBUNWIND_TRACE_DWARF("DW_CFA_GNU_window_save\n");
  761. break;
  762. #endif
  763. }
  764. break;
  765. #else
  766. (void)arch;
  767. #endif
  768. default:
  769. operand = opcode & 0x3F;
  770. switch (opcode & 0xC0) {
  771. case DW_CFA_offset:
  772. reg = operand;
  773. if (reg > kMaxRegisterNumber) {
  774. _LIBUNWIND_LOG("malformed DW_CFA_offset DWARF unwind, reg (%" PRIu64
  775. ") out of range",
  776. reg);
  777. return false;
  778. }
  779. offset = (int64_t)addressSpace.getULEB128(p, instructionsEnd) *
  780. cieInfo.dataAlignFactor;
  781. results->setRegister(reg, kRegisterInCFA, offset, initialState);
  782. _LIBUNWIND_TRACE_DWARF("DW_CFA_offset(reg=%d, offset=%" PRId64 ")\n",
  783. operand, offset);
  784. break;
  785. case DW_CFA_advance_loc:
  786. codeOffset += operand * cieInfo.codeAlignFactor;
  787. _LIBUNWIND_TRACE_DWARF("DW_CFA_advance_loc: new offset=%" PRIu64 "\n",
  788. static_cast<uint64_t>(codeOffset));
  789. break;
  790. case DW_CFA_restore:
  791. reg = operand;
  792. if (reg > kMaxRegisterNumber) {
  793. _LIBUNWIND_LOG(
  794. "malformed DW_CFA_restore DWARF unwind, reg (%" PRIu64
  795. ") out of range",
  796. reg);
  797. return false;
  798. }
  799. results->restoreRegisterToInitialState(reg, initialState);
  800. _LIBUNWIND_TRACE_DWARF("DW_CFA_restore(reg=%" PRIu64 ")\n",
  801. static_cast<uint64_t>(operand));
  802. break;
  803. default:
  804. _LIBUNWIND_TRACE_DWARF("unknown CFA opcode 0x%02X\n", opcode);
  805. return false;
  806. }
  807. }
  808. }
  809. }
  810. return true;
  811. }
  812. } // namespace libunwind
  813. #endif // __DWARF_PARSER_HPP__