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 17 #ifndef _LIBUNWINDSTACK_ARM_EXIDX_H 18 #define _LIBUNWINDSTACK_ARM_EXIDX_H 19 20 #include <stdint.h> 21 22 #include <deque> 23 #include <map> 24 25 namespace unwindstack { 26 27 // Forward declarations. 28 class Memory; 29 class RegsArm; 30 31 enum ArmStatus : size_t { 32 ARM_STATUS_NONE = 0, 33 ARM_STATUS_NO_UNWIND, 34 ARM_STATUS_FINISH, 35 ARM_STATUS_RESERVED, 36 ARM_STATUS_SPARE, 37 ARM_STATUS_TRUNCATED, 38 ARM_STATUS_READ_FAILED, 39 ARM_STATUS_MALFORMED, 40 ARM_STATUS_INVALID_ALIGNMENT, 41 ARM_STATUS_INVALID_PERSONALITY, 42 }; 43 44 enum ArmOp : uint8_t { 45 ARM_OP_FINISH = 0xb0, 46 }; 47 48 enum ArmLogType : uint8_t { 49 ARM_LOG_NONE, 50 ARM_LOG_FULL, 51 ARM_LOG_BY_REG, 52 }; 53 54 class ArmExidx { 55 public: ArmExidx(RegsArm * regs,Memory * elf_memory,Memory * process_memory)56 ArmExidx(RegsArm* regs, Memory* elf_memory, Memory* process_memory) 57 : regs_(regs), elf_memory_(elf_memory), process_memory_(process_memory) {} ~ArmExidx()58 virtual ~ArmExidx() {} 59 60 void LogRawData(); 61 62 void LogByReg(); 63 64 bool ExtractEntryData(uint32_t entry_offset); 65 66 bool Eval(); 67 68 bool Decode(); 69 data()70 std::deque<uint8_t>* data() { return &data_; } 71 status()72 ArmStatus status() { return status_; } status_address()73 uint64_t status_address() { return status_address_; } 74 regs()75 RegsArm* regs() { return regs_; } 76 cfa()77 uint32_t cfa() { return cfa_; } set_cfa(uint32_t cfa)78 void set_cfa(uint32_t cfa) { cfa_ = cfa; } 79 pc_set()80 bool pc_set() { return pc_set_; } set_pc_set(bool pc_set)81 void set_pc_set(bool pc_set) { pc_set_ = pc_set; } 82 set_log(ArmLogType log_type)83 void set_log(ArmLogType log_type) { log_type_ = log_type; } set_log_skip_execution(bool skip_execution)84 void set_log_skip_execution(bool skip_execution) { log_skip_execution_ = skip_execution; } set_log_indent(uint8_t indent)85 void set_log_indent(uint8_t indent) { log_indent_ = indent; } 86 87 private: 88 bool GetByte(uint8_t* byte); 89 void AdjustRegisters(int32_t offset); 90 91 bool DecodePrefix_10_00(uint8_t byte); 92 bool DecodePrefix_10_01(uint8_t byte); 93 bool DecodePrefix_10_10(uint8_t byte); 94 bool DecodePrefix_10_11_0000(); 95 bool DecodePrefix_10_11_0001(); 96 bool DecodePrefix_10_11_0010(); 97 bool DecodePrefix_10_11_0011(); 98 bool DecodePrefix_10_11_01nn(); 99 bool DecodePrefix_10_11_1nnn(uint8_t byte); 100 bool DecodePrefix_10(uint8_t byte); 101 102 bool DecodePrefix_11_000(uint8_t byte); 103 bool DecodePrefix_11_001(uint8_t byte); 104 bool DecodePrefix_11_010(uint8_t byte); 105 bool DecodePrefix_11(uint8_t byte); 106 107 RegsArm* regs_ = nullptr; 108 uint32_t cfa_ = 0; 109 std::deque<uint8_t> data_; 110 ArmStatus status_ = ARM_STATUS_NONE; 111 uint64_t status_address_ = 0; 112 113 Memory* elf_memory_; 114 Memory* process_memory_; 115 116 ArmLogType log_type_ = ARM_LOG_NONE; 117 uint8_t log_indent_ = 0; 118 bool log_skip_execution_ = false; 119 bool pc_set_ = false; 120 int32_t log_cfa_offset_ = 0; 121 std::map<uint8_t, int32_t> log_regs_; 122 }; 123 124 } // namespace unwindstack 125 126 #endif // _LIBUNWINDSTACK_ARM_EXIDX_H 127