DwarfCfa.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738
  1. /*
  2. * Copyright (C) 2016 The Android Open Source Project
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. #include <inttypes.h>
  17. #include <stdint.h>
  18. #include <string>
  19. #include <type_traits>
  20. #include <vector>
  21. #include <android-base/macros.h>
  22. #include <android-base/stringprintf.h>
  23. #include <unwindstack/DwarfError.h>
  24. #include <unwindstack/DwarfLocation.h>
  25. #include <unwindstack/Log.h>
  26. #include "DwarfCfa.h"
  27. #include "DwarfEncoding.h"
  28. #include "DwarfOp.h"
  29. namespace unwindstack {
  30. template <typename AddressType>
  31. constexpr typename DwarfCfa<AddressType>::process_func DwarfCfa<AddressType>::kCallbackTable[64];
  32. template <typename AddressType>
  33. bool DwarfCfa<AddressType>::GetLocationInfo(uint64_t pc, uint64_t start_offset, uint64_t end_offset,
  34. dwarf_loc_regs_t* loc_regs) {
  35. if (cie_loc_regs_ != nullptr) {
  36. for (const auto& entry : *cie_loc_regs_) {
  37. (*loc_regs)[entry.first] = entry.second;
  38. }
  39. }
  40. last_error_.code = DWARF_ERROR_NONE;
  41. last_error_.address = 0;
  42. memory_->set_cur_offset(start_offset);
  43. uint64_t cfa_offset;
  44. cur_pc_ = fde_->pc_start;
  45. loc_regs->pc_start = cur_pc_;
  46. while (true) {
  47. if (cur_pc_ > pc) {
  48. loc_regs->pc_end = cur_pc_;
  49. return true;
  50. }
  51. if ((cfa_offset = memory_->cur_offset()) >= end_offset) {
  52. loc_regs->pc_end = fde_->pc_end;
  53. return true;
  54. }
  55. loc_regs->pc_start = cur_pc_;
  56. operands_.clear();
  57. // Read the cfa information.
  58. uint8_t cfa_value;
  59. if (!memory_->ReadBytes(&cfa_value, 1)) {
  60. last_error_.code = DWARF_ERROR_MEMORY_INVALID;
  61. last_error_.address = memory_->cur_offset();
  62. return false;
  63. }
  64. uint8_t cfa_low = cfa_value & 0x3f;
  65. // Check the 2 high bits.
  66. switch (cfa_value >> 6) {
  67. case 1:
  68. cur_pc_ += cfa_low * fde_->cie->code_alignment_factor;
  69. break;
  70. case 2: {
  71. uint64_t offset;
  72. if (!memory_->ReadULEB128(&offset)) {
  73. last_error_.code = DWARF_ERROR_MEMORY_INVALID;
  74. last_error_.address = memory_->cur_offset();
  75. return false;
  76. }
  77. SignedType signed_offset =
  78. static_cast<SignedType>(offset) * fde_->cie->data_alignment_factor;
  79. (*loc_regs)[cfa_low] = {.type = DWARF_LOCATION_OFFSET,
  80. .values = {static_cast<uint64_t>(signed_offset)}};
  81. break;
  82. }
  83. case 3: {
  84. if (cie_loc_regs_ == nullptr) {
  85. log(0, "restore while processing cie");
  86. last_error_.code = DWARF_ERROR_ILLEGAL_STATE;
  87. return false;
  88. }
  89. auto reg_entry = cie_loc_regs_->find(cfa_low);
  90. if (reg_entry == cie_loc_regs_->end()) {
  91. loc_regs->erase(cfa_low);
  92. } else {
  93. (*loc_regs)[cfa_low] = reg_entry->second;
  94. }
  95. break;
  96. }
  97. case 0: {
  98. const auto handle_func = DwarfCfa<AddressType>::kCallbackTable[cfa_low];
  99. if (handle_func == nullptr) {
  100. last_error_.code = DWARF_ERROR_ILLEGAL_VALUE;
  101. return false;
  102. }
  103. const auto cfa = &DwarfCfaInfo::kTable[cfa_low];
  104. for (size_t i = 0; i < cfa->num_operands; i++) {
  105. if (cfa->operands[i] == DW_EH_PE_block) {
  106. uint64_t block_length;
  107. if (!memory_->ReadULEB128(&block_length)) {
  108. last_error_.code = DWARF_ERROR_MEMORY_INVALID;
  109. last_error_.address = memory_->cur_offset();
  110. return false;
  111. }
  112. operands_.push_back(block_length);
  113. memory_->set_cur_offset(memory_->cur_offset() + block_length);
  114. continue;
  115. }
  116. uint64_t value;
  117. if (!memory_->ReadEncodedValue<AddressType>(cfa->operands[i], &value)) {
  118. last_error_.code = DWARF_ERROR_MEMORY_INVALID;
  119. last_error_.address = memory_->cur_offset();
  120. return false;
  121. }
  122. operands_.push_back(value);
  123. }
  124. if (!(this->*handle_func)(loc_regs)) {
  125. return false;
  126. }
  127. break;
  128. }
  129. }
  130. }
  131. }
  132. template <typename AddressType>
  133. std::string DwarfCfa<AddressType>::GetOperandString(uint8_t operand, uint64_t value,
  134. uint64_t* cur_pc) {
  135. std::string string;
  136. switch (operand) {
  137. case DwarfCfaInfo::DWARF_DISPLAY_REGISTER:
  138. string = " register(" + std::to_string(value) + ")";
  139. break;
  140. case DwarfCfaInfo::DWARF_DISPLAY_SIGNED_NUMBER:
  141. string += " " + std::to_string(static_cast<SignedType>(value));
  142. break;
  143. case DwarfCfaInfo::DWARF_DISPLAY_ADVANCE_LOC:
  144. *cur_pc += value;
  145. FALLTHROUGH_INTENDED;
  146. // Fall through to log the value.
  147. case DwarfCfaInfo::DWARF_DISPLAY_NUMBER:
  148. string += " " + std::to_string(value);
  149. break;
  150. case DwarfCfaInfo::DWARF_DISPLAY_SET_LOC:
  151. *cur_pc = value;
  152. FALLTHROUGH_INTENDED;
  153. // Fall through to log the value.
  154. case DwarfCfaInfo::DWARF_DISPLAY_ADDRESS:
  155. if (std::is_same<AddressType, uint32_t>::value) {
  156. string += android::base::StringPrintf(" 0x%" PRIx32, static_cast<uint32_t>(value));
  157. } else {
  158. string += android::base::StringPrintf(" 0x%" PRIx64, static_cast<uint64_t>(value));
  159. }
  160. break;
  161. default:
  162. string = " unknown";
  163. }
  164. return string;
  165. }
  166. template <typename AddressType>
  167. bool DwarfCfa<AddressType>::LogOffsetRegisterString(uint32_t indent, uint64_t cfa_offset,
  168. uint8_t reg) {
  169. uint64_t offset;
  170. if (!memory_->ReadULEB128(&offset)) {
  171. return false;
  172. }
  173. uint64_t end_offset = memory_->cur_offset();
  174. memory_->set_cur_offset(cfa_offset);
  175. std::string raw_data = "Raw Data:";
  176. for (uint64_t i = cfa_offset; i < end_offset; i++) {
  177. uint8_t value;
  178. if (!memory_->ReadBytes(&value, 1)) {
  179. return false;
  180. }
  181. raw_data += android::base::StringPrintf(" 0x%02x", value);
  182. }
  183. log(indent, "DW_CFA_offset register(%d) %" PRId64, reg, offset);
  184. log(indent, "%s", raw_data.c_str());
  185. return true;
  186. }
  187. template <typename AddressType>
  188. bool DwarfCfa<AddressType>::LogInstruction(uint32_t indent, uint64_t cfa_offset, uint8_t op,
  189. uint64_t* cur_pc) {
  190. const auto* cfa = &DwarfCfaInfo::kTable[op];
  191. if (cfa->name[0] == '\0') {
  192. log(indent, "Illegal");
  193. log(indent, "Raw Data: 0x%02x", op);
  194. return true;
  195. }
  196. std::string log_string(cfa->name);
  197. std::vector<std::string> expression_lines;
  198. for (size_t i = 0; i < cfa->num_operands; i++) {
  199. if (cfa->operands[i] == DW_EH_PE_block) {
  200. // This is a Dwarf Expression.
  201. uint64_t end_offset;
  202. if (!memory_->ReadULEB128(&end_offset)) {
  203. return false;
  204. }
  205. log_string += " " + std::to_string(end_offset);
  206. end_offset += memory_->cur_offset();
  207. DwarfOp<AddressType> op(memory_, nullptr);
  208. op.GetLogInfo(memory_->cur_offset(), end_offset, &expression_lines);
  209. memory_->set_cur_offset(end_offset);
  210. } else {
  211. uint64_t value;
  212. if (!memory_->ReadEncodedValue<AddressType>(cfa->operands[i], &value)) {
  213. return false;
  214. }
  215. log_string += GetOperandString(cfa->display_operands[i], value, cur_pc);
  216. }
  217. }
  218. log(indent, "%s", log_string.c_str());
  219. // Get the raw bytes of the data.
  220. uint64_t end_offset = memory_->cur_offset();
  221. memory_->set_cur_offset(cfa_offset);
  222. std::string raw_data("Raw Data:");
  223. for (uint64_t i = 0; i < end_offset - cfa_offset; i++) {
  224. uint8_t value;
  225. if (!memory_->ReadBytes(&value, 1)) {
  226. return false;
  227. }
  228. // Only show 10 raw bytes per line.
  229. if ((i % 10) == 0 && i != 0) {
  230. log(indent, "%s", raw_data.c_str());
  231. raw_data.clear();
  232. }
  233. if (raw_data.empty()) {
  234. raw_data = "Raw Data:";
  235. }
  236. raw_data += android::base::StringPrintf(" 0x%02x", value);
  237. }
  238. if (!raw_data.empty()) {
  239. log(indent, "%s", raw_data.c_str());
  240. }
  241. // Log any of the expression data.
  242. for (const auto& line : expression_lines) {
  243. log(indent + 1, "%s", line.c_str());
  244. }
  245. return true;
  246. }
  247. template <typename AddressType>
  248. bool DwarfCfa<AddressType>::Log(uint32_t indent, uint64_t pc, uint64_t start_offset,
  249. uint64_t end_offset) {
  250. memory_->set_cur_offset(start_offset);
  251. uint64_t cfa_offset;
  252. uint64_t cur_pc = fde_->pc_start;
  253. uint64_t old_pc = cur_pc;
  254. while ((cfa_offset = memory_->cur_offset()) < end_offset && cur_pc <= pc) {
  255. // Read the cfa information.
  256. uint8_t cfa_value;
  257. if (!memory_->ReadBytes(&cfa_value, 1)) {
  258. return false;
  259. }
  260. // Check the 2 high bits.
  261. uint8_t cfa_low = cfa_value & 0x3f;
  262. switch (cfa_value >> 6) {
  263. case 0:
  264. if (!LogInstruction(indent, cfa_offset, cfa_low, &cur_pc)) {
  265. return false;
  266. }
  267. break;
  268. case 1:
  269. log(indent, "DW_CFA_advance_loc %d", cfa_low);
  270. log(indent, "Raw Data: 0x%02x", cfa_value);
  271. cur_pc += cfa_low * fde_->cie->code_alignment_factor;
  272. break;
  273. case 2:
  274. if (!LogOffsetRegisterString(indent, cfa_offset, cfa_low)) {
  275. return false;
  276. }
  277. break;
  278. case 3:
  279. log(indent, "DW_CFA_restore register(%d)", cfa_low);
  280. log(indent, "Raw Data: 0x%02x", cfa_value);
  281. break;
  282. }
  283. if (cur_pc != old_pc) {
  284. log(0, "");
  285. log(indent, "PC 0x%" PRIx64, cur_pc);
  286. }
  287. old_pc = cur_pc;
  288. }
  289. return true;
  290. }
  291. // Static data.
  292. template <typename AddressType>
  293. bool DwarfCfa<AddressType>::cfa_nop(dwarf_loc_regs_t*) {
  294. return true;
  295. }
  296. template <typename AddressType>
  297. bool DwarfCfa<AddressType>::cfa_set_loc(dwarf_loc_regs_t*) {
  298. AddressType cur_pc = cur_pc_;
  299. AddressType new_pc = operands_[0];
  300. if (new_pc < cur_pc) {
  301. if (std::is_same<AddressType, uint32_t>::value) {
  302. log(0, "Warning: PC is moving backwards: old 0x%" PRIx32 " new 0x%" PRIx32, cur_pc, new_pc);
  303. } else {
  304. log(0, "Warning: PC is moving backwards: old 0x%" PRIx64 " new 0x%" PRIx64, cur_pc, new_pc);
  305. }
  306. }
  307. cur_pc_ = new_pc;
  308. return true;
  309. }
  310. template <typename AddressType>
  311. bool DwarfCfa<AddressType>::cfa_advance_loc(dwarf_loc_regs_t*) {
  312. cur_pc_ += operands_[0] * fde_->cie->code_alignment_factor;
  313. return true;
  314. }
  315. template <typename AddressType>
  316. bool DwarfCfa<AddressType>::cfa_offset(dwarf_loc_regs_t* loc_regs) {
  317. AddressType reg = operands_[0];
  318. (*loc_regs)[reg] = {.type = DWARF_LOCATION_OFFSET, .values = {operands_[1]}};
  319. return true;
  320. }
  321. template <typename AddressType>
  322. bool DwarfCfa<AddressType>::cfa_restore(dwarf_loc_regs_t* loc_regs) {
  323. AddressType reg = operands_[0];
  324. if (cie_loc_regs_ == nullptr) {
  325. log(0, "restore while processing cie");
  326. last_error_.code = DWARF_ERROR_ILLEGAL_STATE;
  327. return false;
  328. }
  329. auto reg_entry = cie_loc_regs_->find(reg);
  330. if (reg_entry == cie_loc_regs_->end()) {
  331. loc_regs->erase(reg);
  332. } else {
  333. (*loc_regs)[reg] = reg_entry->second;
  334. }
  335. return true;
  336. }
  337. template <typename AddressType>
  338. bool DwarfCfa<AddressType>::cfa_undefined(dwarf_loc_regs_t* loc_regs) {
  339. AddressType reg = operands_[0];
  340. (*loc_regs)[reg] = {.type = DWARF_LOCATION_UNDEFINED};
  341. return true;
  342. }
  343. template <typename AddressType>
  344. bool DwarfCfa<AddressType>::cfa_same_value(dwarf_loc_regs_t* loc_regs) {
  345. AddressType reg = operands_[0];
  346. loc_regs->erase(reg);
  347. return true;
  348. }
  349. template <typename AddressType>
  350. bool DwarfCfa<AddressType>::cfa_register(dwarf_loc_regs_t* loc_regs) {
  351. AddressType reg = operands_[0];
  352. AddressType reg_dst = operands_[1];
  353. (*loc_regs)[reg] = {.type = DWARF_LOCATION_REGISTER, .values = {reg_dst}};
  354. return true;
  355. }
  356. template <typename AddressType>
  357. bool DwarfCfa<AddressType>::cfa_remember_state(dwarf_loc_regs_t* loc_regs) {
  358. loc_reg_state_.push(*loc_regs);
  359. return true;
  360. }
  361. template <typename AddressType>
  362. bool DwarfCfa<AddressType>::cfa_restore_state(dwarf_loc_regs_t* loc_regs) {
  363. if (loc_reg_state_.size() == 0) {
  364. log(0, "Warning: Attempt to restore without remember.");
  365. return true;
  366. }
  367. *loc_regs = loc_reg_state_.top();
  368. loc_reg_state_.pop();
  369. return true;
  370. }
  371. template <typename AddressType>
  372. bool DwarfCfa<AddressType>::cfa_def_cfa(dwarf_loc_regs_t* loc_regs) {
  373. (*loc_regs)[CFA_REG] = {.type = DWARF_LOCATION_REGISTER, .values = {operands_[0], operands_[1]}};
  374. return true;
  375. }
  376. template <typename AddressType>
  377. bool DwarfCfa<AddressType>::cfa_def_cfa_register(dwarf_loc_regs_t* loc_regs) {
  378. auto cfa_location = loc_regs->find(CFA_REG);
  379. if (cfa_location == loc_regs->end() || cfa_location->second.type != DWARF_LOCATION_REGISTER) {
  380. log(0, "Attempt to set new register, but cfa is not already set to a register.");
  381. last_error_.code = DWARF_ERROR_ILLEGAL_STATE;
  382. return false;
  383. }
  384. cfa_location->second.values[0] = operands_[0];
  385. return true;
  386. }
  387. template <typename AddressType>
  388. bool DwarfCfa<AddressType>::cfa_def_cfa_offset(dwarf_loc_regs_t* loc_regs) {
  389. // Changing the offset if this is not a register is illegal.
  390. auto cfa_location = loc_regs->find(CFA_REG);
  391. if (cfa_location == loc_regs->end() || cfa_location->second.type != DWARF_LOCATION_REGISTER) {
  392. log(0, "Attempt to set offset, but cfa is not set to a register.");
  393. last_error_.code = DWARF_ERROR_ILLEGAL_STATE;
  394. return false;
  395. }
  396. cfa_location->second.values[1] = operands_[0];
  397. return true;
  398. }
  399. template <typename AddressType>
  400. bool DwarfCfa<AddressType>::cfa_def_cfa_expression(dwarf_loc_regs_t* loc_regs) {
  401. // There is only one type of expression for CFA evaluation and the DWARF
  402. // specification is unclear whether it returns the address or the
  403. // dereferenced value. GDB expects the value, so will we.
  404. (*loc_regs)[CFA_REG] = {.type = DWARF_LOCATION_VAL_EXPRESSION,
  405. .values = {operands_[0], memory_->cur_offset()}};
  406. return true;
  407. }
  408. template <typename AddressType>
  409. bool DwarfCfa<AddressType>::cfa_expression(dwarf_loc_regs_t* loc_regs) {
  410. AddressType reg = operands_[0];
  411. (*loc_regs)[reg] = {.type = DWARF_LOCATION_EXPRESSION,
  412. .values = {operands_[1], memory_->cur_offset()}};
  413. return true;
  414. }
  415. template <typename AddressType>
  416. bool DwarfCfa<AddressType>::cfa_offset_extended_sf(dwarf_loc_regs_t* loc_regs) {
  417. AddressType reg = operands_[0];
  418. SignedType value = static_cast<SignedType>(operands_[1]) * fde_->cie->data_alignment_factor;
  419. (*loc_regs)[reg] = {.type = DWARF_LOCATION_OFFSET, .values = {static_cast<uint64_t>(value)}};
  420. return true;
  421. }
  422. template <typename AddressType>
  423. bool DwarfCfa<AddressType>::cfa_def_cfa_sf(dwarf_loc_regs_t* loc_regs) {
  424. SignedType offset = static_cast<SignedType>(operands_[1]) * fde_->cie->data_alignment_factor;
  425. (*loc_regs)[CFA_REG] = {.type = DWARF_LOCATION_REGISTER,
  426. .values = {operands_[0], static_cast<uint64_t>(offset)}};
  427. return true;
  428. }
  429. template <typename AddressType>
  430. bool DwarfCfa<AddressType>::cfa_def_cfa_offset_sf(dwarf_loc_regs_t* loc_regs) {
  431. // Changing the offset if this is not a register is illegal.
  432. auto cfa_location = loc_regs->find(CFA_REG);
  433. if (cfa_location == loc_regs->end() || cfa_location->second.type != DWARF_LOCATION_REGISTER) {
  434. log(0, "Attempt to set offset, but cfa is not set to a register.");
  435. last_error_.code = DWARF_ERROR_ILLEGAL_STATE;
  436. return false;
  437. }
  438. SignedType offset = static_cast<SignedType>(operands_[0]) * fde_->cie->data_alignment_factor;
  439. cfa_location->second.values[1] = static_cast<uint64_t>(offset);
  440. return true;
  441. }
  442. template <typename AddressType>
  443. bool DwarfCfa<AddressType>::cfa_val_offset(dwarf_loc_regs_t* loc_regs) {
  444. AddressType reg = operands_[0];
  445. SignedType offset = static_cast<SignedType>(operands_[1]) * fde_->cie->data_alignment_factor;
  446. (*loc_regs)[reg] = {.type = DWARF_LOCATION_VAL_OFFSET, .values = {static_cast<uint64_t>(offset)}};
  447. return true;
  448. }
  449. template <typename AddressType>
  450. bool DwarfCfa<AddressType>::cfa_val_offset_sf(dwarf_loc_regs_t* loc_regs) {
  451. AddressType reg = operands_[0];
  452. SignedType offset = static_cast<SignedType>(operands_[1]) * fde_->cie->data_alignment_factor;
  453. (*loc_regs)[reg] = {.type = DWARF_LOCATION_VAL_OFFSET, .values = {static_cast<uint64_t>(offset)}};
  454. return true;
  455. }
  456. template <typename AddressType>
  457. bool DwarfCfa<AddressType>::cfa_val_expression(dwarf_loc_regs_t* loc_regs) {
  458. AddressType reg = operands_[0];
  459. (*loc_regs)[reg] = {.type = DWARF_LOCATION_VAL_EXPRESSION,
  460. .values = {operands_[1], memory_->cur_offset()}};
  461. return true;
  462. }
  463. template <typename AddressType>
  464. bool DwarfCfa<AddressType>::cfa_gnu_negative_offset_extended(dwarf_loc_regs_t* loc_regs) {
  465. AddressType reg = operands_[0];
  466. SignedType offset = -static_cast<SignedType>(operands_[1]);
  467. (*loc_regs)[reg] = {.type = DWARF_LOCATION_OFFSET, .values = {static_cast<uint64_t>(offset)}};
  468. return true;
  469. }
  470. const DwarfCfaInfo::Info DwarfCfaInfo::kTable[64] = {
  471. {
  472. // 0x00 DW_CFA_nop
  473. "DW_CFA_nop",
  474. 2,
  475. 0,
  476. {},
  477. {},
  478. },
  479. {
  480. "DW_CFA_set_loc", // 0x01 DW_CFA_set_loc
  481. 2,
  482. 1,
  483. {DW_EH_PE_absptr},
  484. {DWARF_DISPLAY_SET_LOC},
  485. },
  486. {
  487. "DW_CFA_advance_loc1", // 0x02 DW_CFA_advance_loc1
  488. 2,
  489. 1,
  490. {DW_EH_PE_udata1},
  491. {DWARF_DISPLAY_ADVANCE_LOC},
  492. },
  493. {
  494. "DW_CFA_advance_loc2", // 0x03 DW_CFA_advance_loc2
  495. 2,
  496. 1,
  497. {DW_EH_PE_udata2},
  498. {DWARF_DISPLAY_ADVANCE_LOC},
  499. },
  500. {
  501. "DW_CFA_advance_loc4", // 0x04 DW_CFA_advance_loc4
  502. 2,
  503. 1,
  504. {DW_EH_PE_udata4},
  505. {DWARF_DISPLAY_ADVANCE_LOC},
  506. },
  507. {
  508. "DW_CFA_offset_extended", // 0x05 DW_CFA_offset_extended
  509. 2,
  510. 2,
  511. {DW_EH_PE_uleb128, DW_EH_PE_uleb128},
  512. {DWARF_DISPLAY_REGISTER, DWARF_DISPLAY_NUMBER},
  513. },
  514. {
  515. "DW_CFA_restore_extended", // 0x06 DW_CFA_restore_extended
  516. 2,
  517. 1,
  518. {DW_EH_PE_uleb128},
  519. {DWARF_DISPLAY_REGISTER},
  520. },
  521. {
  522. "DW_CFA_undefined", // 0x07 DW_CFA_undefined
  523. 2,
  524. 1,
  525. {DW_EH_PE_uleb128},
  526. {DWARF_DISPLAY_REGISTER},
  527. },
  528. {
  529. "DW_CFA_same_value", // 0x08 DW_CFA_same_value
  530. 2,
  531. 1,
  532. {DW_EH_PE_uleb128},
  533. {DWARF_DISPLAY_REGISTER},
  534. },
  535. {
  536. "DW_CFA_register", // 0x09 DW_CFA_register
  537. 2,
  538. 2,
  539. {DW_EH_PE_uleb128, DW_EH_PE_uleb128},
  540. {DWARF_DISPLAY_REGISTER, DWARF_DISPLAY_REGISTER},
  541. },
  542. {
  543. "DW_CFA_remember_state", // 0x0a DW_CFA_remember_state
  544. 2,
  545. 0,
  546. {},
  547. {},
  548. },
  549. {
  550. "DW_CFA_restore_state", // 0x0b DW_CFA_restore_state
  551. 2,
  552. 0,
  553. {},
  554. {},
  555. },
  556. {
  557. "DW_CFA_def_cfa", // 0x0c DW_CFA_def_cfa
  558. 2,
  559. 2,
  560. {DW_EH_PE_uleb128, DW_EH_PE_uleb128},
  561. {DWARF_DISPLAY_REGISTER, DWARF_DISPLAY_NUMBER},
  562. },
  563. {
  564. "DW_CFA_def_cfa_register", // 0x0d DW_CFA_def_cfa_register
  565. 2,
  566. 1,
  567. {DW_EH_PE_uleb128},
  568. {DWARF_DISPLAY_REGISTER},
  569. },
  570. {
  571. "DW_CFA_def_cfa_offset", // 0x0e DW_CFA_def_cfa_offset
  572. 2,
  573. 1,
  574. {DW_EH_PE_uleb128},
  575. {DWARF_DISPLAY_NUMBER},
  576. },
  577. {
  578. "DW_CFA_def_cfa_expression", // 0x0f DW_CFA_def_cfa_expression
  579. 2,
  580. 1,
  581. {DW_EH_PE_block},
  582. {DWARF_DISPLAY_EVAL_BLOCK},
  583. },
  584. {
  585. "DW_CFA_expression", // 0x10 DW_CFA_expression
  586. 2,
  587. 2,
  588. {DW_EH_PE_uleb128, DW_EH_PE_block},
  589. {DWARF_DISPLAY_REGISTER, DWARF_DISPLAY_EVAL_BLOCK},
  590. },
  591. {
  592. "DW_CFA_offset_extended_sf", // 0x11 DW_CFA_offset_extend_sf
  593. 2,
  594. 2,
  595. {DW_EH_PE_uleb128, DW_EH_PE_sleb128},
  596. {DWARF_DISPLAY_REGISTER, DWARF_DISPLAY_SIGNED_NUMBER},
  597. },
  598. {
  599. "DW_CFA_def_cfa_sf", // 0x12 DW_CFA_def_cfa_sf
  600. 2,
  601. 2,
  602. {DW_EH_PE_uleb128, DW_EH_PE_sleb128},
  603. {DWARF_DISPLAY_REGISTER, DWARF_DISPLAY_SIGNED_NUMBER},
  604. },
  605. {
  606. "DW_CFA_def_cfa_offset_sf", // 0x13 DW_CFA_def_cfa_offset_sf
  607. 2,
  608. 1,
  609. {DW_EH_PE_sleb128},
  610. {DWARF_DISPLAY_SIGNED_NUMBER},
  611. },
  612. {
  613. "DW_CFA_val_offset", // 0x14 DW_CFA_val_offset
  614. 2,
  615. 2,
  616. {DW_EH_PE_uleb128, DW_EH_PE_uleb128},
  617. {DWARF_DISPLAY_REGISTER, DWARF_DISPLAY_NUMBER},
  618. },
  619. {
  620. "DW_CFA_val_offset_sf", // 0x15 DW_CFA_val_offset_sf
  621. 2,
  622. 2,
  623. {DW_EH_PE_uleb128, DW_EH_PE_sleb128},
  624. {DWARF_DISPLAY_REGISTER, DWARF_DISPLAY_SIGNED_NUMBER},
  625. },
  626. {
  627. "DW_CFA_val_expression", // 0x16 DW_CFA_val_expression
  628. 2,
  629. 2,
  630. {DW_EH_PE_uleb128, DW_EH_PE_block},
  631. {DWARF_DISPLAY_REGISTER, DWARF_DISPLAY_EVAL_BLOCK},
  632. },
  633. {"", 0, 0, {}, {}}, // 0x17 illegal cfa
  634. {"", 0, 0, {}, {}}, // 0x18 illegal cfa
  635. {"", 0, 0, {}, {}}, // 0x19 illegal cfa
  636. {"", 0, 0, {}, {}}, // 0x1a illegal cfa
  637. {"", 0, 0, {}, {}}, // 0x1b illegal cfa
  638. {"", 0, 0, {}, {}}, // 0x1c DW_CFA_lo_user (Treat as illegal)
  639. {"", 0, 0, {}, {}}, // 0x1d illegal cfa
  640. {"", 0, 0, {}, {}}, // 0x1e illegal cfa
  641. {"", 0, 0, {}, {}}, // 0x1f illegal cfa
  642. {"", 0, 0, {}, {}}, // 0x20 illegal cfa
  643. {"", 0, 0, {}, {}}, // 0x21 illegal cfa
  644. {"", 0, 0, {}, {}}, // 0x22 illegal cfa
  645. {"", 0, 0, {}, {}}, // 0x23 illegal cfa
  646. {"", 0, 0, {}, {}}, // 0x24 illegal cfa
  647. {"", 0, 0, {}, {}}, // 0x25 illegal cfa
  648. {"", 0, 0, {}, {}}, // 0x26 illegal cfa
  649. {"", 0, 0, {}, {}}, // 0x27 illegal cfa
  650. {"", 0, 0, {}, {}}, // 0x28 illegal cfa
  651. {"", 0, 0, {}, {}}, // 0x29 illegal cfa
  652. {"", 0, 0, {}, {}}, // 0x2a illegal cfa
  653. {"", 0, 0, {}, {}}, // 0x2b illegal cfa
  654. {"", 0, 0, {}, {}}, // 0x2c illegal cfa
  655. {"", 0, 0, {}, {}}, // 0x2d DW_CFA_GNU_window_save (Treat as illegal)
  656. {
  657. "DW_CFA_GNU_args_size", // 0x2e DW_CFA_GNU_args_size
  658. 2,
  659. 1,
  660. {DW_EH_PE_uleb128},
  661. {DWARF_DISPLAY_NUMBER},
  662. },
  663. {
  664. "DW_CFA_GNU_negative_offset_extended", // 0x2f DW_CFA_GNU_negative_offset_extended
  665. 2,
  666. 2,
  667. {DW_EH_PE_uleb128, DW_EH_PE_uleb128},
  668. {DWARF_DISPLAY_REGISTER, DWARF_DISPLAY_NUMBER},
  669. },
  670. {"", 0, 0, {}, {}}, // 0x31 illegal cfa
  671. {"", 0, 0, {}, {}}, // 0x32 illegal cfa
  672. {"", 0, 0, {}, {}}, // 0x33 illegal cfa
  673. {"", 0, 0, {}, {}}, // 0x34 illegal cfa
  674. {"", 0, 0, {}, {}}, // 0x35 illegal cfa
  675. {"", 0, 0, {}, {}}, // 0x36 illegal cfa
  676. {"", 0, 0, {}, {}}, // 0x37 illegal cfa
  677. {"", 0, 0, {}, {}}, // 0x38 illegal cfa
  678. {"", 0, 0, {}, {}}, // 0x39 illegal cfa
  679. {"", 0, 0, {}, {}}, // 0x3a illegal cfa
  680. {"", 0, 0, {}, {}}, // 0x3b illegal cfa
  681. {"", 0, 0, {}, {}}, // 0x3c illegal cfa
  682. {"", 0, 0, {}, {}}, // 0x3d illegal cfa
  683. {"", 0, 0, {}, {}}, // 0x3e illegal cfa
  684. {"", 0, 0, {}, {}}, // 0x3f DW_CFA_hi_user (Treat as illegal)
  685. };
  686. // Explicitly instantiate DwarfCfa.
  687. template class DwarfCfa<uint32_t>;
  688. template class DwarfCfa<uint64_t>;
  689. } // namespace unwindstack