DwarfInstructions.hpp 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829
  1. //===-------------------------- DwarfInstructions.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. // Processor specific interpretation of DWARF unwind info.
  9. //
  10. //===----------------------------------------------------------------------===//
  11. #ifndef __DWARF_INSTRUCTIONS_HPP__
  12. #define __DWARF_INSTRUCTIONS_HPP__
  13. #include <stdint.h>
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include "dwarf2.h"
  17. #include "Registers.hpp"
  18. #include "DwarfParser.hpp"
  19. #include "config.h"
  20. namespace libunwind {
  21. /// DwarfInstructions maps abtract DWARF unwind instructions to a particular
  22. /// architecture
  23. template <typename A, typename R>
  24. class DwarfInstructions {
  25. public:
  26. typedef typename A::pint_t pint_t;
  27. typedef typename A::sint_t sint_t;
  28. static int stepWithDwarf(A &addressSpace, pint_t pc, pint_t fdeStart,
  29. R &registers, bool &isSignalFrame);
  30. private:
  31. enum {
  32. DW_X86_64_RET_ADDR = 16
  33. };
  34. enum {
  35. DW_X86_RET_ADDR = 8
  36. };
  37. typedef typename CFI_Parser<A>::RegisterLocation RegisterLocation;
  38. typedef typename CFI_Parser<A>::PrologInfo PrologInfo;
  39. typedef typename CFI_Parser<A>::FDE_Info FDE_Info;
  40. typedef typename CFI_Parser<A>::CIE_Info CIE_Info;
  41. static pint_t evaluateExpression(pint_t expression, A &addressSpace,
  42. const R &registers,
  43. pint_t initialStackValue);
  44. static pint_t getSavedRegister(A &addressSpace, const R &registers,
  45. pint_t cfa, const RegisterLocation &savedReg);
  46. static double getSavedFloatRegister(A &addressSpace, const R &registers,
  47. pint_t cfa, const RegisterLocation &savedReg);
  48. static v128 getSavedVectorRegister(A &addressSpace, const R &registers,
  49. pint_t cfa, const RegisterLocation &savedReg);
  50. static pint_t getCFA(A &addressSpace, const PrologInfo &prolog,
  51. const R &registers) {
  52. if (prolog.cfaRegister != 0)
  53. return (pint_t)((sint_t)registers.getRegister((int)prolog.cfaRegister) +
  54. prolog.cfaRegisterOffset);
  55. if (prolog.cfaExpression != 0)
  56. return evaluateExpression((pint_t)prolog.cfaExpression, addressSpace,
  57. registers, 0);
  58. assert(0 && "getCFA(): unknown location");
  59. __builtin_unreachable();
  60. }
  61. };
  62. template <typename A, typename R>
  63. typename A::pint_t DwarfInstructions<A, R>::getSavedRegister(
  64. A &addressSpace, const R &registers, pint_t cfa,
  65. const RegisterLocation &savedReg) {
  66. switch (savedReg.location) {
  67. case CFI_Parser<A>::kRegisterInCFA:
  68. return (pint_t)addressSpace.getRegister(cfa + (pint_t)savedReg.value);
  69. case CFI_Parser<A>::kRegisterAtExpression:
  70. return (pint_t)addressSpace.getRegister(evaluateExpression(
  71. (pint_t)savedReg.value, addressSpace, registers, cfa));
  72. case CFI_Parser<A>::kRegisterIsExpression:
  73. return evaluateExpression((pint_t)savedReg.value, addressSpace,
  74. registers, cfa);
  75. case CFI_Parser<A>::kRegisterInRegister:
  76. return registers.getRegister((int)savedReg.value);
  77. case CFI_Parser<A>::kRegisterUndefined:
  78. return 0;
  79. case CFI_Parser<A>::kRegisterUnused:
  80. case CFI_Parser<A>::kRegisterOffsetFromCFA:
  81. // FIX ME
  82. break;
  83. }
  84. _LIBUNWIND_ABORT("unsupported restore location for register");
  85. }
  86. template <typename A, typename R>
  87. double DwarfInstructions<A, R>::getSavedFloatRegister(
  88. A &addressSpace, const R &registers, pint_t cfa,
  89. const RegisterLocation &savedReg) {
  90. switch (savedReg.location) {
  91. case CFI_Parser<A>::kRegisterInCFA:
  92. return addressSpace.getDouble(cfa + (pint_t)savedReg.value);
  93. case CFI_Parser<A>::kRegisterAtExpression:
  94. return addressSpace.getDouble(
  95. evaluateExpression((pint_t)savedReg.value, addressSpace,
  96. registers, cfa));
  97. case CFI_Parser<A>::kRegisterIsExpression:
  98. case CFI_Parser<A>::kRegisterUnused:
  99. case CFI_Parser<A>::kRegisterUndefined:
  100. case CFI_Parser<A>::kRegisterOffsetFromCFA:
  101. case CFI_Parser<A>::kRegisterInRegister:
  102. // FIX ME
  103. break;
  104. }
  105. _LIBUNWIND_ABORT("unsupported restore location for float register");
  106. }
  107. template <typename A, typename R>
  108. v128 DwarfInstructions<A, R>::getSavedVectorRegister(
  109. A &addressSpace, const R &registers, pint_t cfa,
  110. const RegisterLocation &savedReg) {
  111. switch (savedReg.location) {
  112. case CFI_Parser<A>::kRegisterInCFA:
  113. return addressSpace.getVector(cfa + (pint_t)savedReg.value);
  114. case CFI_Parser<A>::kRegisterAtExpression:
  115. return addressSpace.getVector(
  116. evaluateExpression((pint_t)savedReg.value, addressSpace,
  117. registers, cfa));
  118. case CFI_Parser<A>::kRegisterIsExpression:
  119. case CFI_Parser<A>::kRegisterUnused:
  120. case CFI_Parser<A>::kRegisterUndefined:
  121. case CFI_Parser<A>::kRegisterOffsetFromCFA:
  122. case CFI_Parser<A>::kRegisterInRegister:
  123. // FIX ME
  124. break;
  125. }
  126. _LIBUNWIND_ABORT("unsupported restore location for vector register");
  127. }
  128. template <typename A, typename R>
  129. int DwarfInstructions<A, R>::stepWithDwarf(A &addressSpace, pint_t pc,
  130. pint_t fdeStart, R &registers,
  131. bool &isSignalFrame) {
  132. FDE_Info fdeInfo;
  133. CIE_Info cieInfo;
  134. if (CFI_Parser<A>::decodeFDE(addressSpace, fdeStart, &fdeInfo,
  135. &cieInfo) == NULL) {
  136. PrologInfo prolog;
  137. if (CFI_Parser<A>::parseFDEInstructions(addressSpace, fdeInfo, cieInfo, pc,
  138. R::getArch(), &prolog)) {
  139. // get pointer to cfa (architecture specific)
  140. pint_t cfa = getCFA(addressSpace, prolog, registers);
  141. // restore registers that DWARF says were saved
  142. R newRegisters = registers;
  143. pint_t returnAddress = 0;
  144. const int lastReg = R::lastDwarfRegNum();
  145. assert(static_cast<int>(CFI_Parser<A>::kMaxRegisterNumber) >= lastReg &&
  146. "register range too large");
  147. assert(lastReg >= (int)cieInfo.returnAddressRegister &&
  148. "register range does not contain return address register");
  149. for (int i = 0; i <= lastReg; ++i) {
  150. if (prolog.savedRegisters[i].location !=
  151. CFI_Parser<A>::kRegisterUnused) {
  152. if (registers.validFloatRegister(i))
  153. newRegisters.setFloatRegister(
  154. i, getSavedFloatRegister(addressSpace, registers, cfa,
  155. prolog.savedRegisters[i]));
  156. else if (registers.validVectorRegister(i))
  157. newRegisters.setVectorRegister(
  158. i, getSavedVectorRegister(addressSpace, registers, cfa,
  159. prolog.savedRegisters[i]));
  160. else if (i == (int)cieInfo.returnAddressRegister)
  161. returnAddress = getSavedRegister(addressSpace, registers, cfa,
  162. prolog.savedRegisters[i]);
  163. else if (registers.validRegister(i))
  164. newRegisters.setRegister(
  165. i, getSavedRegister(addressSpace, registers, cfa,
  166. prolog.savedRegisters[i]));
  167. else
  168. return UNW_EBADREG;
  169. } else if (i == (int)cieInfo.returnAddressRegister) {
  170. // Leaf function keeps the return address in register and there is no
  171. // explicit intructions how to restore it.
  172. returnAddress = registers.getRegister(cieInfo.returnAddressRegister);
  173. }
  174. }
  175. // By definition, the CFA is the stack pointer at the call site, so
  176. // restoring SP means setting it to CFA.
  177. newRegisters.setSP(cfa);
  178. isSignalFrame = cieInfo.isSignalFrame;
  179. #if defined(_LIBUNWIND_TARGET_AARCH64)
  180. // If the target is aarch64 then the return address may have been signed
  181. // using the v8.3 pointer authentication extensions. The original
  182. // return address needs to be authenticated before the return address is
  183. // restored. autia1716 is used instead of autia as autia1716 assembles
  184. // to a NOP on pre-v8.3a architectures.
  185. if ((R::getArch() == REGISTERS_ARM64) &&
  186. prolog.savedRegisters[UNW_ARM64_RA_SIGN_STATE].value &&
  187. returnAddress != 0) {
  188. #if !defined(_LIBUNWIND_IS_NATIVE_ONLY)
  189. return UNW_ECROSSRASIGNING;
  190. #else
  191. register unsigned long long x17 __asm("x17") = returnAddress;
  192. register unsigned long long x16 __asm("x16") = cfa;
  193. // These are the autia1716/autib1716 instructions. The hint instructions
  194. // are used here as gcc does not assemble autia1716/autib1716 for pre
  195. // armv8.3a targets.
  196. if (cieInfo.addressesSignedWithBKey)
  197. asm("hint 0xe" : "+r"(x17) : "r"(x16)); // autib1716
  198. else
  199. asm("hint 0xc" : "+r"(x17) : "r"(x16)); // autia1716
  200. returnAddress = x17;
  201. #endif
  202. }
  203. #endif
  204. #if defined(_LIBUNWIND_TARGET_SPARC)
  205. if (R::getArch() == REGISTERS_SPARC) {
  206. // Skip call site instruction and delay slot
  207. returnAddress += 8;
  208. // Skip unimp instruction if function returns a struct
  209. if ((addressSpace.get32(returnAddress) & 0xC1C00000) == 0)
  210. returnAddress += 4;
  211. }
  212. #endif
  213. #if defined(_LIBUNWIND_TARGET_PPC64)
  214. #define PPC64_ELFV1_R2_LOAD_INST_ENCODING 0xe8410028u // ld r2,40(r1)
  215. #define PPC64_ELFV1_R2_OFFSET 40
  216. #define PPC64_ELFV2_R2_LOAD_INST_ENCODING 0xe8410018u // ld r2,24(r1)
  217. #define PPC64_ELFV2_R2_OFFSET 24
  218. // If the instruction at return address is a TOC (r2) restore,
  219. // then r2 was saved and needs to be restored.
  220. // ELFv2 ABI specifies that the TOC Pointer must be saved at SP + 24,
  221. // while in ELFv1 ABI it is saved at SP + 40.
  222. if (R::getArch() == REGISTERS_PPC64 && returnAddress != 0) {
  223. pint_t sp = newRegisters.getRegister(UNW_REG_SP);
  224. pint_t r2 = 0;
  225. switch (addressSpace.get32(returnAddress)) {
  226. case PPC64_ELFV1_R2_LOAD_INST_ENCODING:
  227. r2 = addressSpace.get64(sp + PPC64_ELFV1_R2_OFFSET);
  228. break;
  229. case PPC64_ELFV2_R2_LOAD_INST_ENCODING:
  230. r2 = addressSpace.get64(sp + PPC64_ELFV2_R2_OFFSET);
  231. break;
  232. }
  233. if (r2)
  234. newRegisters.setRegister(UNW_PPC64_R2, r2);
  235. }
  236. #endif
  237. // Return address is address after call site instruction, so setting IP to
  238. // that does simualates a return.
  239. newRegisters.setIP(returnAddress);
  240. // Simulate the step by replacing the register set with the new ones.
  241. registers = newRegisters;
  242. return UNW_STEP_SUCCESS;
  243. }
  244. }
  245. return UNW_EBADFRAME;
  246. }
  247. template <typename A, typename R>
  248. typename A::pint_t
  249. DwarfInstructions<A, R>::evaluateExpression(pint_t expression, A &addressSpace,
  250. const R &registers,
  251. pint_t initialStackValue) {
  252. const bool log = false;
  253. pint_t p = expression;
  254. pint_t expressionEnd = expression + 20; // temp, until len read
  255. pint_t length = (pint_t)addressSpace.getULEB128(p, expressionEnd);
  256. expressionEnd = p + length;
  257. if (log)
  258. fprintf(stderr, "evaluateExpression(): length=%" PRIu64 "\n",
  259. (uint64_t)length);
  260. pint_t stack[100];
  261. pint_t *sp = stack;
  262. *(++sp) = initialStackValue;
  263. while (p < expressionEnd) {
  264. if (log) {
  265. for (pint_t *t = sp; t > stack; --t) {
  266. fprintf(stderr, "sp[] = 0x%" PRIx64 "\n", (uint64_t)(*t));
  267. }
  268. }
  269. uint8_t opcode = addressSpace.get8(p++);
  270. sint_t svalue, svalue2;
  271. pint_t value;
  272. uint32_t reg;
  273. switch (opcode) {
  274. case DW_OP_addr:
  275. // push immediate address sized value
  276. value = addressSpace.getP(p);
  277. p += sizeof(pint_t);
  278. *(++sp) = value;
  279. if (log)
  280. fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value);
  281. break;
  282. case DW_OP_deref:
  283. // pop stack, dereference, push result
  284. value = *sp--;
  285. *(++sp) = addressSpace.getP(value);
  286. if (log)
  287. fprintf(stderr, "dereference 0x%" PRIx64 "\n", (uint64_t)value);
  288. break;
  289. case DW_OP_const1u:
  290. // push immediate 1 byte value
  291. value = addressSpace.get8(p);
  292. p += 1;
  293. *(++sp) = value;
  294. if (log)
  295. fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value);
  296. break;
  297. case DW_OP_const1s:
  298. // push immediate 1 byte signed value
  299. svalue = (int8_t) addressSpace.get8(p);
  300. p += 1;
  301. *(++sp) = (pint_t)svalue;
  302. if (log)
  303. fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)svalue);
  304. break;
  305. case DW_OP_const2u:
  306. // push immediate 2 byte value
  307. value = addressSpace.get16(p);
  308. p += 2;
  309. *(++sp) = value;
  310. if (log)
  311. fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value);
  312. break;
  313. case DW_OP_const2s:
  314. // push immediate 2 byte signed value
  315. svalue = (int16_t) addressSpace.get16(p);
  316. p += 2;
  317. *(++sp) = (pint_t)svalue;
  318. if (log)
  319. fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)svalue);
  320. break;
  321. case DW_OP_const4u:
  322. // push immediate 4 byte value
  323. value = addressSpace.get32(p);
  324. p += 4;
  325. *(++sp) = value;
  326. if (log)
  327. fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value);
  328. break;
  329. case DW_OP_const4s:
  330. // push immediate 4 byte signed value
  331. svalue = (int32_t)addressSpace.get32(p);
  332. p += 4;
  333. *(++sp) = (pint_t)svalue;
  334. if (log)
  335. fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)svalue);
  336. break;
  337. case DW_OP_const8u:
  338. // push immediate 8 byte value
  339. value = (pint_t)addressSpace.get64(p);
  340. p += 8;
  341. *(++sp) = value;
  342. if (log)
  343. fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value);
  344. break;
  345. case DW_OP_const8s:
  346. // push immediate 8 byte signed value
  347. value = (pint_t)addressSpace.get64(p);
  348. p += 8;
  349. *(++sp) = value;
  350. if (log)
  351. fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value);
  352. break;
  353. case DW_OP_constu:
  354. // push immediate ULEB128 value
  355. value = (pint_t)addressSpace.getULEB128(p, expressionEnd);
  356. *(++sp) = value;
  357. if (log)
  358. fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)value);
  359. break;
  360. case DW_OP_consts:
  361. // push immediate SLEB128 value
  362. svalue = (sint_t)addressSpace.getSLEB128(p, expressionEnd);
  363. *(++sp) = (pint_t)svalue;
  364. if (log)
  365. fprintf(stderr, "push 0x%" PRIx64 "\n", (uint64_t)svalue);
  366. break;
  367. case DW_OP_dup:
  368. // push top of stack
  369. value = *sp;
  370. *(++sp) = value;
  371. if (log)
  372. fprintf(stderr, "duplicate top of stack\n");
  373. break;
  374. case DW_OP_drop:
  375. // pop
  376. --sp;
  377. if (log)
  378. fprintf(stderr, "pop top of stack\n");
  379. break;
  380. case DW_OP_over:
  381. // dup second
  382. value = sp[-1];
  383. *(++sp) = value;
  384. if (log)
  385. fprintf(stderr, "duplicate second in stack\n");
  386. break;
  387. case DW_OP_pick:
  388. // pick from
  389. reg = addressSpace.get8(p);
  390. p += 1;
  391. value = sp[-(int)reg];
  392. *(++sp) = value;
  393. if (log)
  394. fprintf(stderr, "duplicate %d in stack\n", reg);
  395. break;
  396. case DW_OP_swap:
  397. // swap top two
  398. value = sp[0];
  399. sp[0] = sp[-1];
  400. sp[-1] = value;
  401. if (log)
  402. fprintf(stderr, "swap top of stack\n");
  403. break;
  404. case DW_OP_rot:
  405. // rotate top three
  406. value = sp[0];
  407. sp[0] = sp[-1];
  408. sp[-1] = sp[-2];
  409. sp[-2] = value;
  410. if (log)
  411. fprintf(stderr, "rotate top three of stack\n");
  412. break;
  413. case DW_OP_xderef:
  414. // pop stack, dereference, push result
  415. value = *sp--;
  416. *sp = *((pint_t*)value);
  417. if (log)
  418. fprintf(stderr, "x-dereference 0x%" PRIx64 "\n", (uint64_t)value);
  419. break;
  420. case DW_OP_abs:
  421. svalue = (sint_t)*sp;
  422. if (svalue < 0)
  423. *sp = (pint_t)(-svalue);
  424. if (log)
  425. fprintf(stderr, "abs\n");
  426. break;
  427. case DW_OP_and:
  428. value = *sp--;
  429. *sp &= value;
  430. if (log)
  431. fprintf(stderr, "and\n");
  432. break;
  433. case DW_OP_div:
  434. svalue = (sint_t)(*sp--);
  435. svalue2 = (sint_t)*sp;
  436. *sp = (pint_t)(svalue2 / svalue);
  437. if (log)
  438. fprintf(stderr, "div\n");
  439. break;
  440. case DW_OP_minus:
  441. value = *sp--;
  442. *sp = *sp - value;
  443. if (log)
  444. fprintf(stderr, "minus\n");
  445. break;
  446. case DW_OP_mod:
  447. svalue = (sint_t)(*sp--);
  448. svalue2 = (sint_t)*sp;
  449. *sp = (pint_t)(svalue2 % svalue);
  450. if (log)
  451. fprintf(stderr, "module\n");
  452. break;
  453. case DW_OP_mul:
  454. svalue = (sint_t)(*sp--);
  455. svalue2 = (sint_t)*sp;
  456. *sp = (pint_t)(svalue2 * svalue);
  457. if (log)
  458. fprintf(stderr, "mul\n");
  459. break;
  460. case DW_OP_neg:
  461. *sp = 0 - *sp;
  462. if (log)
  463. fprintf(stderr, "neg\n");
  464. break;
  465. case DW_OP_not:
  466. svalue = (sint_t)(*sp);
  467. *sp = (pint_t)(~svalue);
  468. if (log)
  469. fprintf(stderr, "not\n");
  470. break;
  471. case DW_OP_or:
  472. value = *sp--;
  473. *sp |= value;
  474. if (log)
  475. fprintf(stderr, "or\n");
  476. break;
  477. case DW_OP_plus:
  478. value = *sp--;
  479. *sp += value;
  480. if (log)
  481. fprintf(stderr, "plus\n");
  482. break;
  483. case DW_OP_plus_uconst:
  484. // pop stack, add uelb128 constant, push result
  485. *sp += static_cast<pint_t>(addressSpace.getULEB128(p, expressionEnd));
  486. if (log)
  487. fprintf(stderr, "add constant\n");
  488. break;
  489. case DW_OP_shl:
  490. value = *sp--;
  491. *sp = *sp << value;
  492. if (log)
  493. fprintf(stderr, "shift left\n");
  494. break;
  495. case DW_OP_shr:
  496. value = *sp--;
  497. *sp = *sp >> value;
  498. if (log)
  499. fprintf(stderr, "shift left\n");
  500. break;
  501. case DW_OP_shra:
  502. value = *sp--;
  503. svalue = (sint_t)*sp;
  504. *sp = (pint_t)(svalue >> value);
  505. if (log)
  506. fprintf(stderr, "shift left arithmetric\n");
  507. break;
  508. case DW_OP_xor:
  509. value = *sp--;
  510. *sp ^= value;
  511. if (log)
  512. fprintf(stderr, "xor\n");
  513. break;
  514. case DW_OP_skip:
  515. svalue = (int16_t) addressSpace.get16(p);
  516. p += 2;
  517. p = (pint_t)((sint_t)p + svalue);
  518. if (log)
  519. fprintf(stderr, "skip %" PRIu64 "\n", (uint64_t)svalue);
  520. break;
  521. case DW_OP_bra:
  522. svalue = (int16_t) addressSpace.get16(p);
  523. p += 2;
  524. if (*sp--)
  525. p = (pint_t)((sint_t)p + svalue);
  526. if (log)
  527. fprintf(stderr, "bra %" PRIu64 "\n", (uint64_t)svalue);
  528. break;
  529. case DW_OP_eq:
  530. value = *sp--;
  531. *sp = (*sp == value);
  532. if (log)
  533. fprintf(stderr, "eq\n");
  534. break;
  535. case DW_OP_ge:
  536. value = *sp--;
  537. *sp = (*sp >= value);
  538. if (log)
  539. fprintf(stderr, "ge\n");
  540. break;
  541. case DW_OP_gt:
  542. value = *sp--;
  543. *sp = (*sp > value);
  544. if (log)
  545. fprintf(stderr, "gt\n");
  546. break;
  547. case DW_OP_le:
  548. value = *sp--;
  549. *sp = (*sp <= value);
  550. if (log)
  551. fprintf(stderr, "le\n");
  552. break;
  553. case DW_OP_lt:
  554. value = *sp--;
  555. *sp = (*sp < value);
  556. if (log)
  557. fprintf(stderr, "lt\n");
  558. break;
  559. case DW_OP_ne:
  560. value = *sp--;
  561. *sp = (*sp != value);
  562. if (log)
  563. fprintf(stderr, "ne\n");
  564. break;
  565. case DW_OP_lit0:
  566. case DW_OP_lit1:
  567. case DW_OP_lit2:
  568. case DW_OP_lit3:
  569. case DW_OP_lit4:
  570. case DW_OP_lit5:
  571. case DW_OP_lit6:
  572. case DW_OP_lit7:
  573. case DW_OP_lit8:
  574. case DW_OP_lit9:
  575. case DW_OP_lit10:
  576. case DW_OP_lit11:
  577. case DW_OP_lit12:
  578. case DW_OP_lit13:
  579. case DW_OP_lit14:
  580. case DW_OP_lit15:
  581. case DW_OP_lit16:
  582. case DW_OP_lit17:
  583. case DW_OP_lit18:
  584. case DW_OP_lit19:
  585. case DW_OP_lit20:
  586. case DW_OP_lit21:
  587. case DW_OP_lit22:
  588. case DW_OP_lit23:
  589. case DW_OP_lit24:
  590. case DW_OP_lit25:
  591. case DW_OP_lit26:
  592. case DW_OP_lit27:
  593. case DW_OP_lit28:
  594. case DW_OP_lit29:
  595. case DW_OP_lit30:
  596. case DW_OP_lit31:
  597. value = static_cast<pint_t>(opcode - DW_OP_lit0);
  598. *(++sp) = value;
  599. if (log)
  600. fprintf(stderr, "push literal 0x%" PRIx64 "\n", (uint64_t)value);
  601. break;
  602. case DW_OP_reg0:
  603. case DW_OP_reg1:
  604. case DW_OP_reg2:
  605. case DW_OP_reg3:
  606. case DW_OP_reg4:
  607. case DW_OP_reg5:
  608. case DW_OP_reg6:
  609. case DW_OP_reg7:
  610. case DW_OP_reg8:
  611. case DW_OP_reg9:
  612. case DW_OP_reg10:
  613. case DW_OP_reg11:
  614. case DW_OP_reg12:
  615. case DW_OP_reg13:
  616. case DW_OP_reg14:
  617. case DW_OP_reg15:
  618. case DW_OP_reg16:
  619. case DW_OP_reg17:
  620. case DW_OP_reg18:
  621. case DW_OP_reg19:
  622. case DW_OP_reg20:
  623. case DW_OP_reg21:
  624. case DW_OP_reg22:
  625. case DW_OP_reg23:
  626. case DW_OP_reg24:
  627. case DW_OP_reg25:
  628. case DW_OP_reg26:
  629. case DW_OP_reg27:
  630. case DW_OP_reg28:
  631. case DW_OP_reg29:
  632. case DW_OP_reg30:
  633. case DW_OP_reg31:
  634. reg = static_cast<uint32_t>(opcode - DW_OP_reg0);
  635. *(++sp) = registers.getRegister((int)reg);
  636. if (log)
  637. fprintf(stderr, "push reg %d\n", reg);
  638. break;
  639. case DW_OP_regx:
  640. reg = static_cast<uint32_t>(addressSpace.getULEB128(p, expressionEnd));
  641. *(++sp) = registers.getRegister((int)reg);
  642. if (log)
  643. fprintf(stderr, "push reg %d + 0x%" PRIx64 "\n", reg, (uint64_t)svalue);
  644. break;
  645. case DW_OP_breg0:
  646. case DW_OP_breg1:
  647. case DW_OP_breg2:
  648. case DW_OP_breg3:
  649. case DW_OP_breg4:
  650. case DW_OP_breg5:
  651. case DW_OP_breg6:
  652. case DW_OP_breg7:
  653. case DW_OP_breg8:
  654. case DW_OP_breg9:
  655. case DW_OP_breg10:
  656. case DW_OP_breg11:
  657. case DW_OP_breg12:
  658. case DW_OP_breg13:
  659. case DW_OP_breg14:
  660. case DW_OP_breg15:
  661. case DW_OP_breg16:
  662. case DW_OP_breg17:
  663. case DW_OP_breg18:
  664. case DW_OP_breg19:
  665. case DW_OP_breg20:
  666. case DW_OP_breg21:
  667. case DW_OP_breg22:
  668. case DW_OP_breg23:
  669. case DW_OP_breg24:
  670. case DW_OP_breg25:
  671. case DW_OP_breg26:
  672. case DW_OP_breg27:
  673. case DW_OP_breg28:
  674. case DW_OP_breg29:
  675. case DW_OP_breg30:
  676. case DW_OP_breg31:
  677. reg = static_cast<uint32_t>(opcode - DW_OP_breg0);
  678. svalue = (sint_t)addressSpace.getSLEB128(p, expressionEnd);
  679. svalue += static_cast<sint_t>(registers.getRegister((int)reg));
  680. *(++sp) = (pint_t)(svalue);
  681. if (log)
  682. fprintf(stderr, "push reg %d + 0x%" PRIx64 "\n", reg, (uint64_t)svalue);
  683. break;
  684. case DW_OP_bregx:
  685. reg = static_cast<uint32_t>(addressSpace.getULEB128(p, expressionEnd));
  686. svalue = (sint_t)addressSpace.getSLEB128(p, expressionEnd);
  687. svalue += static_cast<sint_t>(registers.getRegister((int)reg));
  688. *(++sp) = (pint_t)(svalue);
  689. if (log)
  690. fprintf(stderr, "push reg %d + 0x%" PRIx64 "\n", reg, (uint64_t)svalue);
  691. break;
  692. case DW_OP_fbreg:
  693. _LIBUNWIND_ABORT("DW_OP_fbreg not implemented");
  694. break;
  695. case DW_OP_piece:
  696. _LIBUNWIND_ABORT("DW_OP_piece not implemented");
  697. break;
  698. case DW_OP_deref_size:
  699. // pop stack, dereference, push result
  700. value = *sp--;
  701. switch (addressSpace.get8(p++)) {
  702. case 1:
  703. value = addressSpace.get8(value);
  704. break;
  705. case 2:
  706. value = addressSpace.get16(value);
  707. break;
  708. case 4:
  709. value = addressSpace.get32(value);
  710. break;
  711. case 8:
  712. value = (pint_t)addressSpace.get64(value);
  713. break;
  714. default:
  715. _LIBUNWIND_ABORT("DW_OP_deref_size with bad size");
  716. }
  717. *(++sp) = value;
  718. if (log)
  719. fprintf(stderr, "sized dereference 0x%" PRIx64 "\n", (uint64_t)value);
  720. break;
  721. case DW_OP_xderef_size:
  722. case DW_OP_nop:
  723. case DW_OP_push_object_addres:
  724. case DW_OP_call2:
  725. case DW_OP_call4:
  726. case DW_OP_call_ref:
  727. default:
  728. _LIBUNWIND_ABORT("DWARF opcode not implemented");
  729. }
  730. }
  731. if (log)
  732. fprintf(stderr, "expression evaluates to 0x%" PRIx64 "\n", (uint64_t)*sp);
  733. return *sp;
  734. }
  735. } // namespace libunwind
  736. #endif // __DWARF_INSTRUCTIONS_HPP__