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