123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738 |
- /*
- * Copyright (C) 2016 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- #include <inttypes.h>
- #include <stdint.h>
- #include <string>
- #include <type_traits>
- #include <vector>
- #include <android-base/macros.h>
- #include <android-base/stringprintf.h>
- #include <unwindstack/DwarfError.h>
- #include <unwindstack/DwarfLocation.h>
- #include <unwindstack/Log.h>
- #include "DwarfCfa.h"
- #include "DwarfEncoding.h"
- #include "DwarfOp.h"
- namespace unwindstack {
- template <typename AddressType>
- constexpr typename DwarfCfa<AddressType>::process_func DwarfCfa<AddressType>::kCallbackTable[64];
- template <typename AddressType>
- bool DwarfCfa<AddressType>::GetLocationInfo(uint64_t pc, uint64_t start_offset, uint64_t end_offset,
- dwarf_loc_regs_t* loc_regs) {
- if (cie_loc_regs_ != nullptr) {
- for (const auto& entry : *cie_loc_regs_) {
- (*loc_regs)[entry.first] = entry.second;
- }
- }
- last_error_.code = DWARF_ERROR_NONE;
- last_error_.address = 0;
- memory_->set_cur_offset(start_offset);
- uint64_t cfa_offset;
- cur_pc_ = fde_->pc_start;
- loc_regs->pc_start = cur_pc_;
- while (true) {
- if (cur_pc_ > pc) {
- loc_regs->pc_end = cur_pc_;
- return true;
- }
- if ((cfa_offset = memory_->cur_offset()) >= end_offset) {
- loc_regs->pc_end = fde_->pc_end;
- return true;
- }
- loc_regs->pc_start = cur_pc_;
- operands_.clear();
- // Read the cfa information.
- uint8_t cfa_value;
- if (!memory_->ReadBytes(&cfa_value, 1)) {
- last_error_.code = DWARF_ERROR_MEMORY_INVALID;
- last_error_.address = memory_->cur_offset();
- return false;
- }
- uint8_t cfa_low = cfa_value & 0x3f;
- // Check the 2 high bits.
- switch (cfa_value >> 6) {
- case 1:
- cur_pc_ += cfa_low * fde_->cie->code_alignment_factor;
- break;
- case 2: {
- uint64_t offset;
- if (!memory_->ReadULEB128(&offset)) {
- last_error_.code = DWARF_ERROR_MEMORY_INVALID;
- last_error_.address = memory_->cur_offset();
- return false;
- }
- SignedType signed_offset =
- static_cast<SignedType>(offset) * fde_->cie->data_alignment_factor;
- (*loc_regs)[cfa_low] = {.type = DWARF_LOCATION_OFFSET,
- .values = {static_cast<uint64_t>(signed_offset)}};
- break;
- }
- case 3: {
- if (cie_loc_regs_ == nullptr) {
- log(0, "restore while processing cie");
- last_error_.code = DWARF_ERROR_ILLEGAL_STATE;
- return false;
- }
- auto reg_entry = cie_loc_regs_->find(cfa_low);
- if (reg_entry == cie_loc_regs_->end()) {
- loc_regs->erase(cfa_low);
- } else {
- (*loc_regs)[cfa_low] = reg_entry->second;
- }
- break;
- }
- case 0: {
- const auto handle_func = DwarfCfa<AddressType>::kCallbackTable[cfa_low];
- if (handle_func == nullptr) {
- last_error_.code = DWARF_ERROR_ILLEGAL_VALUE;
- return false;
- }
- const auto cfa = &DwarfCfaInfo::kTable[cfa_low];
- for (size_t i = 0; i < cfa->num_operands; i++) {
- if (cfa->operands[i] == DW_EH_PE_block) {
- uint64_t block_length;
- if (!memory_->ReadULEB128(&block_length)) {
- last_error_.code = DWARF_ERROR_MEMORY_INVALID;
- last_error_.address = memory_->cur_offset();
- return false;
- }
- operands_.push_back(block_length);
- memory_->set_cur_offset(memory_->cur_offset() + block_length);
- continue;
- }
- uint64_t value;
- if (!memory_->ReadEncodedValue<AddressType>(cfa->operands[i], &value)) {
- last_error_.code = DWARF_ERROR_MEMORY_INVALID;
- last_error_.address = memory_->cur_offset();
- return false;
- }
- operands_.push_back(value);
- }
- if (!(this->*handle_func)(loc_regs)) {
- return false;
- }
- break;
- }
- }
- }
- }
- template <typename AddressType>
- std::string DwarfCfa<AddressType>::GetOperandString(uint8_t operand, uint64_t value,
- uint64_t* cur_pc) {
- std::string string;
- switch (operand) {
- case DwarfCfaInfo::DWARF_DISPLAY_REGISTER:
- string = " register(" + std::to_string(value) + ")";
- break;
- case DwarfCfaInfo::DWARF_DISPLAY_SIGNED_NUMBER:
- string += " " + std::to_string(static_cast<SignedType>(value));
- break;
- case DwarfCfaInfo::DWARF_DISPLAY_ADVANCE_LOC:
- *cur_pc += value;
- FALLTHROUGH_INTENDED;
- // Fall through to log the value.
- case DwarfCfaInfo::DWARF_DISPLAY_NUMBER:
- string += " " + std::to_string(value);
- break;
- case DwarfCfaInfo::DWARF_DISPLAY_SET_LOC:
- *cur_pc = value;
- FALLTHROUGH_INTENDED;
- // Fall through to log the value.
- case DwarfCfaInfo::DWARF_DISPLAY_ADDRESS:
- if (std::is_same<AddressType, uint32_t>::value) {
- string += android::base::StringPrintf(" 0x%" PRIx32, static_cast<uint32_t>(value));
- } else {
- string += android::base::StringPrintf(" 0x%" PRIx64, static_cast<uint64_t>(value));
- }
- break;
- default:
- string = " unknown";
- }
- return string;
- }
- template <typename AddressType>
- bool DwarfCfa<AddressType>::LogOffsetRegisterString(uint32_t indent, uint64_t cfa_offset,
- uint8_t reg) {
- uint64_t offset;
- if (!memory_->ReadULEB128(&offset)) {
- return false;
- }
- uint64_t end_offset = memory_->cur_offset();
- memory_->set_cur_offset(cfa_offset);
- std::string raw_data = "Raw Data:";
- for (uint64_t i = cfa_offset; i < end_offset; i++) {
- uint8_t value;
- if (!memory_->ReadBytes(&value, 1)) {
- return false;
- }
- raw_data += android::base::StringPrintf(" 0x%02x", value);
- }
- log(indent, "DW_CFA_offset register(%d) %" PRId64, reg, offset);
- log(indent, "%s", raw_data.c_str());
- return true;
- }
- template <typename AddressType>
- bool DwarfCfa<AddressType>::LogInstruction(uint32_t indent, uint64_t cfa_offset, uint8_t op,
- uint64_t* cur_pc) {
- const auto* cfa = &DwarfCfaInfo::kTable[op];
- if (cfa->name[0] == '\0') {
- log(indent, "Illegal");
- log(indent, "Raw Data: 0x%02x", op);
- return true;
- }
- std::string log_string(cfa->name);
- std::vector<std::string> expression_lines;
- for (size_t i = 0; i < cfa->num_operands; i++) {
- if (cfa->operands[i] == DW_EH_PE_block) {
- // This is a Dwarf Expression.
- uint64_t end_offset;
- if (!memory_->ReadULEB128(&end_offset)) {
- return false;
- }
- log_string += " " + std::to_string(end_offset);
- end_offset += memory_->cur_offset();
- DwarfOp<AddressType> op(memory_, nullptr);
- op.GetLogInfo(memory_->cur_offset(), end_offset, &expression_lines);
- memory_->set_cur_offset(end_offset);
- } else {
- uint64_t value;
- if (!memory_->ReadEncodedValue<AddressType>(cfa->operands[i], &value)) {
- return false;
- }
- log_string += GetOperandString(cfa->display_operands[i], value, cur_pc);
- }
- }
- log(indent, "%s", log_string.c_str());
- // Get the raw bytes of the data.
- uint64_t end_offset = memory_->cur_offset();
- memory_->set_cur_offset(cfa_offset);
- std::string raw_data("Raw Data:");
- for (uint64_t i = 0; i < end_offset - cfa_offset; i++) {
- uint8_t value;
- if (!memory_->ReadBytes(&value, 1)) {
- return false;
- }
- // Only show 10 raw bytes per line.
- if ((i % 10) == 0 && i != 0) {
- log(indent, "%s", raw_data.c_str());
- raw_data.clear();
- }
- if (raw_data.empty()) {
- raw_data = "Raw Data:";
- }
- raw_data += android::base::StringPrintf(" 0x%02x", value);
- }
- if (!raw_data.empty()) {
- log(indent, "%s", raw_data.c_str());
- }
- // Log any of the expression data.
- for (const auto& line : expression_lines) {
- log(indent + 1, "%s", line.c_str());
- }
- return true;
- }
- template <typename AddressType>
- bool DwarfCfa<AddressType>::Log(uint32_t indent, uint64_t pc, uint64_t start_offset,
- uint64_t end_offset) {
- memory_->set_cur_offset(start_offset);
- uint64_t cfa_offset;
- uint64_t cur_pc = fde_->pc_start;
- uint64_t old_pc = cur_pc;
- while ((cfa_offset = memory_->cur_offset()) < end_offset && cur_pc <= pc) {
- // Read the cfa information.
- uint8_t cfa_value;
- if (!memory_->ReadBytes(&cfa_value, 1)) {
- return false;
- }
- // Check the 2 high bits.
- uint8_t cfa_low = cfa_value & 0x3f;
- switch (cfa_value >> 6) {
- case 0:
- if (!LogInstruction(indent, cfa_offset, cfa_low, &cur_pc)) {
- return false;
- }
- break;
- case 1:
- log(indent, "DW_CFA_advance_loc %d", cfa_low);
- log(indent, "Raw Data: 0x%02x", cfa_value);
- cur_pc += cfa_low * fde_->cie->code_alignment_factor;
- break;
- case 2:
- if (!LogOffsetRegisterString(indent, cfa_offset, cfa_low)) {
- return false;
- }
- break;
- case 3:
- log(indent, "DW_CFA_restore register(%d)", cfa_low);
- log(indent, "Raw Data: 0x%02x", cfa_value);
- break;
- }
- if (cur_pc != old_pc) {
- log(0, "");
- log(indent, "PC 0x%" PRIx64, cur_pc);
- }
- old_pc = cur_pc;
- }
- return true;
- }
- // Static data.
- template <typename AddressType>
- bool DwarfCfa<AddressType>::cfa_nop(dwarf_loc_regs_t*) {
- return true;
- }
- template <typename AddressType>
- bool DwarfCfa<AddressType>::cfa_set_loc(dwarf_loc_regs_t*) {
- AddressType cur_pc = cur_pc_;
- AddressType new_pc = operands_[0];
- if (new_pc < cur_pc) {
- if (std::is_same<AddressType, uint32_t>::value) {
- log(0, "Warning: PC is moving backwards: old 0x%" PRIx32 " new 0x%" PRIx32, cur_pc, new_pc);
- } else {
- log(0, "Warning: PC is moving backwards: old 0x%" PRIx64 " new 0x%" PRIx64, cur_pc, new_pc);
- }
- }
- cur_pc_ = new_pc;
- return true;
- }
- template <typename AddressType>
- bool DwarfCfa<AddressType>::cfa_advance_loc(dwarf_loc_regs_t*) {
- cur_pc_ += operands_[0] * fde_->cie->code_alignment_factor;
- return true;
- }
- template <typename AddressType>
- bool DwarfCfa<AddressType>::cfa_offset(dwarf_loc_regs_t* loc_regs) {
- AddressType reg = operands_[0];
- (*loc_regs)[reg] = {.type = DWARF_LOCATION_OFFSET, .values = {operands_[1]}};
- return true;
- }
- template <typename AddressType>
- bool DwarfCfa<AddressType>::cfa_restore(dwarf_loc_regs_t* loc_regs) {
- AddressType reg = operands_[0];
- if (cie_loc_regs_ == nullptr) {
- log(0, "restore while processing cie");
- last_error_.code = DWARF_ERROR_ILLEGAL_STATE;
- return false;
- }
- auto reg_entry = cie_loc_regs_->find(reg);
- if (reg_entry == cie_loc_regs_->end()) {
- loc_regs->erase(reg);
- } else {
- (*loc_regs)[reg] = reg_entry->second;
- }
- return true;
- }
- template <typename AddressType>
- bool DwarfCfa<AddressType>::cfa_undefined(dwarf_loc_regs_t* loc_regs) {
- AddressType reg = operands_[0];
- (*loc_regs)[reg] = {.type = DWARF_LOCATION_UNDEFINED};
- return true;
- }
- template <typename AddressType>
- bool DwarfCfa<AddressType>::cfa_same_value(dwarf_loc_regs_t* loc_regs) {
- AddressType reg = operands_[0];
- loc_regs->erase(reg);
- return true;
- }
- template <typename AddressType>
- bool DwarfCfa<AddressType>::cfa_register(dwarf_loc_regs_t* loc_regs) {
- AddressType reg = operands_[0];
- AddressType reg_dst = operands_[1];
- (*loc_regs)[reg] = {.type = DWARF_LOCATION_REGISTER, .values = {reg_dst}};
- return true;
- }
- template <typename AddressType>
- bool DwarfCfa<AddressType>::cfa_remember_state(dwarf_loc_regs_t* loc_regs) {
- loc_reg_state_.push(*loc_regs);
- return true;
- }
- template <typename AddressType>
- bool DwarfCfa<AddressType>::cfa_restore_state(dwarf_loc_regs_t* loc_regs) {
- if (loc_reg_state_.size() == 0) {
- log(0, "Warning: Attempt to restore without remember.");
- return true;
- }
- *loc_regs = loc_reg_state_.top();
- loc_reg_state_.pop();
- return true;
- }
- template <typename AddressType>
- bool DwarfCfa<AddressType>::cfa_def_cfa(dwarf_loc_regs_t* loc_regs) {
- (*loc_regs)[CFA_REG] = {.type = DWARF_LOCATION_REGISTER, .values = {operands_[0], operands_[1]}};
- return true;
- }
- template <typename AddressType>
- bool DwarfCfa<AddressType>::cfa_def_cfa_register(dwarf_loc_regs_t* loc_regs) {
- auto cfa_location = loc_regs->find(CFA_REG);
- if (cfa_location == loc_regs->end() || cfa_location->second.type != DWARF_LOCATION_REGISTER) {
- log(0, "Attempt to set new register, but cfa is not already set to a register.");
- last_error_.code = DWARF_ERROR_ILLEGAL_STATE;
- return false;
- }
- cfa_location->second.values[0] = operands_[0];
- return true;
- }
- template <typename AddressType>
- bool DwarfCfa<AddressType>::cfa_def_cfa_offset(dwarf_loc_regs_t* loc_regs) {
- // Changing the offset if this is not a register is illegal.
- auto cfa_location = loc_regs->find(CFA_REG);
- if (cfa_location == loc_regs->end() || cfa_location->second.type != DWARF_LOCATION_REGISTER) {
- log(0, "Attempt to set offset, but cfa is not set to a register.");
- last_error_.code = DWARF_ERROR_ILLEGAL_STATE;
- return false;
- }
- cfa_location->second.values[1] = operands_[0];
- return true;
- }
- template <typename AddressType>
- bool DwarfCfa<AddressType>::cfa_def_cfa_expression(dwarf_loc_regs_t* loc_regs) {
- // There is only one type of expression for CFA evaluation and the DWARF
- // specification is unclear whether it returns the address or the
- // dereferenced value. GDB expects the value, so will we.
- (*loc_regs)[CFA_REG] = {.type = DWARF_LOCATION_VAL_EXPRESSION,
- .values = {operands_[0], memory_->cur_offset()}};
- return true;
- }
- template <typename AddressType>
- bool DwarfCfa<AddressType>::cfa_expression(dwarf_loc_regs_t* loc_regs) {
- AddressType reg = operands_[0];
- (*loc_regs)[reg] = {.type = DWARF_LOCATION_EXPRESSION,
- .values = {operands_[1], memory_->cur_offset()}};
- return true;
- }
- template <typename AddressType>
- bool DwarfCfa<AddressType>::cfa_offset_extended_sf(dwarf_loc_regs_t* loc_regs) {
- AddressType reg = operands_[0];
- SignedType value = static_cast<SignedType>(operands_[1]) * fde_->cie->data_alignment_factor;
- (*loc_regs)[reg] = {.type = DWARF_LOCATION_OFFSET, .values = {static_cast<uint64_t>(value)}};
- return true;
- }
- template <typename AddressType>
- bool DwarfCfa<AddressType>::cfa_def_cfa_sf(dwarf_loc_regs_t* loc_regs) {
- SignedType offset = static_cast<SignedType>(operands_[1]) * fde_->cie->data_alignment_factor;
- (*loc_regs)[CFA_REG] = {.type = DWARF_LOCATION_REGISTER,
- .values = {operands_[0], static_cast<uint64_t>(offset)}};
- return true;
- }
- template <typename AddressType>
- bool DwarfCfa<AddressType>::cfa_def_cfa_offset_sf(dwarf_loc_regs_t* loc_regs) {
- // Changing the offset if this is not a register is illegal.
- auto cfa_location = loc_regs->find(CFA_REG);
- if (cfa_location == loc_regs->end() || cfa_location->second.type != DWARF_LOCATION_REGISTER) {
- log(0, "Attempt to set offset, but cfa is not set to a register.");
- last_error_.code = DWARF_ERROR_ILLEGAL_STATE;
- return false;
- }
- SignedType offset = static_cast<SignedType>(operands_[0]) * fde_->cie->data_alignment_factor;
- cfa_location->second.values[1] = static_cast<uint64_t>(offset);
- return true;
- }
- template <typename AddressType>
- bool DwarfCfa<AddressType>::cfa_val_offset(dwarf_loc_regs_t* loc_regs) {
- AddressType reg = operands_[0];
- SignedType offset = static_cast<SignedType>(operands_[1]) * fde_->cie->data_alignment_factor;
- (*loc_regs)[reg] = {.type = DWARF_LOCATION_VAL_OFFSET, .values = {static_cast<uint64_t>(offset)}};
- return true;
- }
- template <typename AddressType>
- bool DwarfCfa<AddressType>::cfa_val_offset_sf(dwarf_loc_regs_t* loc_regs) {
- AddressType reg = operands_[0];
- SignedType offset = static_cast<SignedType>(operands_[1]) * fde_->cie->data_alignment_factor;
- (*loc_regs)[reg] = {.type = DWARF_LOCATION_VAL_OFFSET, .values = {static_cast<uint64_t>(offset)}};
- return true;
- }
- template <typename AddressType>
- bool DwarfCfa<AddressType>::cfa_val_expression(dwarf_loc_regs_t* loc_regs) {
- AddressType reg = operands_[0];
- (*loc_regs)[reg] = {.type = DWARF_LOCATION_VAL_EXPRESSION,
- .values = {operands_[1], memory_->cur_offset()}};
- return true;
- }
- template <typename AddressType>
- bool DwarfCfa<AddressType>::cfa_gnu_negative_offset_extended(dwarf_loc_regs_t* loc_regs) {
- AddressType reg = operands_[0];
- SignedType offset = -static_cast<SignedType>(operands_[1]);
- (*loc_regs)[reg] = {.type = DWARF_LOCATION_OFFSET, .values = {static_cast<uint64_t>(offset)}};
- return true;
- }
- const DwarfCfaInfo::Info DwarfCfaInfo::kTable[64] = {
- {
- // 0x00 DW_CFA_nop
- "DW_CFA_nop",
- 2,
- 0,
- {},
- {},
- },
- {
- "DW_CFA_set_loc", // 0x01 DW_CFA_set_loc
- 2,
- 1,
- {DW_EH_PE_absptr},
- {DWARF_DISPLAY_SET_LOC},
- },
- {
- "DW_CFA_advance_loc1", // 0x02 DW_CFA_advance_loc1
- 2,
- 1,
- {DW_EH_PE_udata1},
- {DWARF_DISPLAY_ADVANCE_LOC},
- },
- {
- "DW_CFA_advance_loc2", // 0x03 DW_CFA_advance_loc2
- 2,
- 1,
- {DW_EH_PE_udata2},
- {DWARF_DISPLAY_ADVANCE_LOC},
- },
- {
- "DW_CFA_advance_loc4", // 0x04 DW_CFA_advance_loc4
- 2,
- 1,
- {DW_EH_PE_udata4},
- {DWARF_DISPLAY_ADVANCE_LOC},
- },
- {
- "DW_CFA_offset_extended", // 0x05 DW_CFA_offset_extended
- 2,
- 2,
- {DW_EH_PE_uleb128, DW_EH_PE_uleb128},
- {DWARF_DISPLAY_REGISTER, DWARF_DISPLAY_NUMBER},
- },
- {
- "DW_CFA_restore_extended", // 0x06 DW_CFA_restore_extended
- 2,
- 1,
- {DW_EH_PE_uleb128},
- {DWARF_DISPLAY_REGISTER},
- },
- {
- "DW_CFA_undefined", // 0x07 DW_CFA_undefined
- 2,
- 1,
- {DW_EH_PE_uleb128},
- {DWARF_DISPLAY_REGISTER},
- },
- {
- "DW_CFA_same_value", // 0x08 DW_CFA_same_value
- 2,
- 1,
- {DW_EH_PE_uleb128},
- {DWARF_DISPLAY_REGISTER},
- },
- {
- "DW_CFA_register", // 0x09 DW_CFA_register
- 2,
- 2,
- {DW_EH_PE_uleb128, DW_EH_PE_uleb128},
- {DWARF_DISPLAY_REGISTER, DWARF_DISPLAY_REGISTER},
- },
- {
- "DW_CFA_remember_state", // 0x0a DW_CFA_remember_state
- 2,
- 0,
- {},
- {},
- },
- {
- "DW_CFA_restore_state", // 0x0b DW_CFA_restore_state
- 2,
- 0,
- {},
- {},
- },
- {
- "DW_CFA_def_cfa", // 0x0c DW_CFA_def_cfa
- 2,
- 2,
- {DW_EH_PE_uleb128, DW_EH_PE_uleb128},
- {DWARF_DISPLAY_REGISTER, DWARF_DISPLAY_NUMBER},
- },
- {
- "DW_CFA_def_cfa_register", // 0x0d DW_CFA_def_cfa_register
- 2,
- 1,
- {DW_EH_PE_uleb128},
- {DWARF_DISPLAY_REGISTER},
- },
- {
- "DW_CFA_def_cfa_offset", // 0x0e DW_CFA_def_cfa_offset
- 2,
- 1,
- {DW_EH_PE_uleb128},
- {DWARF_DISPLAY_NUMBER},
- },
- {
- "DW_CFA_def_cfa_expression", // 0x0f DW_CFA_def_cfa_expression
- 2,
- 1,
- {DW_EH_PE_block},
- {DWARF_DISPLAY_EVAL_BLOCK},
- },
- {
- "DW_CFA_expression", // 0x10 DW_CFA_expression
- 2,
- 2,
- {DW_EH_PE_uleb128, DW_EH_PE_block},
- {DWARF_DISPLAY_REGISTER, DWARF_DISPLAY_EVAL_BLOCK},
- },
- {
- "DW_CFA_offset_extended_sf", // 0x11 DW_CFA_offset_extend_sf
- 2,
- 2,
- {DW_EH_PE_uleb128, DW_EH_PE_sleb128},
- {DWARF_DISPLAY_REGISTER, DWARF_DISPLAY_SIGNED_NUMBER},
- },
- {
- "DW_CFA_def_cfa_sf", // 0x12 DW_CFA_def_cfa_sf
- 2,
- 2,
- {DW_EH_PE_uleb128, DW_EH_PE_sleb128},
- {DWARF_DISPLAY_REGISTER, DWARF_DISPLAY_SIGNED_NUMBER},
- },
- {
- "DW_CFA_def_cfa_offset_sf", // 0x13 DW_CFA_def_cfa_offset_sf
- 2,
- 1,
- {DW_EH_PE_sleb128},
- {DWARF_DISPLAY_SIGNED_NUMBER},
- },
- {
- "DW_CFA_val_offset", // 0x14 DW_CFA_val_offset
- 2,
- 2,
- {DW_EH_PE_uleb128, DW_EH_PE_uleb128},
- {DWARF_DISPLAY_REGISTER, DWARF_DISPLAY_NUMBER},
- },
- {
- "DW_CFA_val_offset_sf", // 0x15 DW_CFA_val_offset_sf
- 2,
- 2,
- {DW_EH_PE_uleb128, DW_EH_PE_sleb128},
- {DWARF_DISPLAY_REGISTER, DWARF_DISPLAY_SIGNED_NUMBER},
- },
- {
- "DW_CFA_val_expression", // 0x16 DW_CFA_val_expression
- 2,
- 2,
- {DW_EH_PE_uleb128, DW_EH_PE_block},
- {DWARF_DISPLAY_REGISTER, DWARF_DISPLAY_EVAL_BLOCK},
- },
- {"", 0, 0, {}, {}}, // 0x17 illegal cfa
- {"", 0, 0, {}, {}}, // 0x18 illegal cfa
- {"", 0, 0, {}, {}}, // 0x19 illegal cfa
- {"", 0, 0, {}, {}}, // 0x1a illegal cfa
- {"", 0, 0, {}, {}}, // 0x1b illegal cfa
- {"", 0, 0, {}, {}}, // 0x1c DW_CFA_lo_user (Treat as illegal)
- {"", 0, 0, {}, {}}, // 0x1d illegal cfa
- {"", 0, 0, {}, {}}, // 0x1e illegal cfa
- {"", 0, 0, {}, {}}, // 0x1f illegal cfa
- {"", 0, 0, {}, {}}, // 0x20 illegal cfa
- {"", 0, 0, {}, {}}, // 0x21 illegal cfa
- {"", 0, 0, {}, {}}, // 0x22 illegal cfa
- {"", 0, 0, {}, {}}, // 0x23 illegal cfa
- {"", 0, 0, {}, {}}, // 0x24 illegal cfa
- {"", 0, 0, {}, {}}, // 0x25 illegal cfa
- {"", 0, 0, {}, {}}, // 0x26 illegal cfa
- {"", 0, 0, {}, {}}, // 0x27 illegal cfa
- {"", 0, 0, {}, {}}, // 0x28 illegal cfa
- {"", 0, 0, {}, {}}, // 0x29 illegal cfa
- {"", 0, 0, {}, {}}, // 0x2a illegal cfa
- {"", 0, 0, {}, {}}, // 0x2b illegal cfa
- {"", 0, 0, {}, {}}, // 0x2c illegal cfa
- {"", 0, 0, {}, {}}, // 0x2d DW_CFA_GNU_window_save (Treat as illegal)
- {
- "DW_CFA_GNU_args_size", // 0x2e DW_CFA_GNU_args_size
- 2,
- 1,
- {DW_EH_PE_uleb128},
- {DWARF_DISPLAY_NUMBER},
- },
- {
- "DW_CFA_GNU_negative_offset_extended", // 0x2f DW_CFA_GNU_negative_offset_extended
- 2,
- 2,
- {DW_EH_PE_uleb128, DW_EH_PE_uleb128},
- {DWARF_DISPLAY_REGISTER, DWARF_DISPLAY_NUMBER},
- },
- {"", 0, 0, {}, {}}, // 0x31 illegal cfa
- {"", 0, 0, {}, {}}, // 0x32 illegal cfa
- {"", 0, 0, {}, {}}, // 0x33 illegal cfa
- {"", 0, 0, {}, {}}, // 0x34 illegal cfa
- {"", 0, 0, {}, {}}, // 0x35 illegal cfa
- {"", 0, 0, {}, {}}, // 0x36 illegal cfa
- {"", 0, 0, {}, {}}, // 0x37 illegal cfa
- {"", 0, 0, {}, {}}, // 0x38 illegal cfa
- {"", 0, 0, {}, {}}, // 0x39 illegal cfa
- {"", 0, 0, {}, {}}, // 0x3a illegal cfa
- {"", 0, 0, {}, {}}, // 0x3b illegal cfa
- {"", 0, 0, {}, {}}, // 0x3c illegal cfa
- {"", 0, 0, {}, {}}, // 0x3d illegal cfa
- {"", 0, 0, {}, {}}, // 0x3e illegal cfa
- {"", 0, 0, {}, {}}, // 0x3f DW_CFA_hi_user (Treat as illegal)
- };
- // Explicitly instantiate DwarfCfa.
- template class DwarfCfa<uint32_t>;
- template class DwarfCfa<uint64_t>;
- } // namespace unwindstack
|