DwarfParser.hpp 31 KB

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