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 #pragma once 18 19 #include <stdint.h> 20 21 #include <deque> 22 #include <map> 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 enum ArmLogType : uint8_t { 48 ARM_LOG_NONE, 49 ARM_LOG_FULL, 50 ARM_LOG_BY_REG, 51 }; 52 53 class ArmExidx { 54 public: ArmExidx(RegsArm * regs,Memory * elf_memory,Memory * process_memory)55 ArmExidx(RegsArm* regs, Memory* elf_memory, Memory* process_memory) 56 : regs_(regs), elf_memory_(elf_memory), process_memory_(process_memory) {} ~ArmExidx()57 virtual ~ArmExidx() {} 58 59 void LogRawData(); 60 61 void LogByReg(); 62 63 bool ExtractEntryData(uint32_t entry_offset); 64 65 bool Eval(); 66 67 bool Decode(); 68 data()69 std::deque<uint8_t>* data() { return &data_; } 70 status()71 ArmStatus status() { return status_; } status_address()72 uint64_t status_address() { return status_address_; } 73 regs()74 RegsArm* regs() { return regs_; } 75 cfa()76 uint32_t cfa() { return cfa_; } set_cfa(uint32_t cfa)77 void set_cfa(uint32_t cfa) { cfa_ = cfa; } 78 pc_set()79 bool pc_set() { return pc_set_; } set_pc_set(bool pc_set)80 void set_pc_set(bool pc_set) { pc_set_ = pc_set; } 81 set_log(ArmLogType log_type)82 void set_log(ArmLogType log_type) { log_type_ = log_type; } set_log_skip_execution(bool skip_execution)83 void set_log_skip_execution(bool skip_execution) { log_skip_execution_ = skip_execution; } set_log_indent(uint8_t indent)84 void set_log_indent(uint8_t indent) { log_indent_ = indent; } 85 86 private: 87 bool GetByte(uint8_t* byte); 88 void AdjustRegisters(int32_t offset); 89 90 bool DecodePrefix_10_00(uint8_t byte); 91 bool DecodePrefix_10_01(uint8_t byte); 92 bool DecodePrefix_10_10(uint8_t byte); 93 bool DecodePrefix_10_11_0000(); 94 bool DecodePrefix_10_11_0001(); 95 bool DecodePrefix_10_11_0010(); 96 bool DecodePrefix_10_11_0011(); 97 bool DecodePrefix_10_11_01nn(); 98 bool DecodePrefix_10_11_1nnn(uint8_t byte); 99 bool DecodePrefix_10(uint8_t byte); 100 101 bool DecodePrefix_11_000(uint8_t byte); 102 bool DecodePrefix_11_001(uint8_t byte); 103 bool DecodePrefix_11_010(uint8_t byte); 104 bool DecodePrefix_11(uint8_t byte); 105 106 RegsArm* regs_ = nullptr; 107 uint32_t cfa_ = 0; 108 std::deque<uint8_t> data_; 109 ArmStatus status_ = ARM_STATUS_NONE; 110 uint64_t status_address_ = 0; 111 112 Memory* elf_memory_; 113 Memory* process_memory_; 114 115 ArmLogType log_type_ = ARM_LOG_NONE; 116 uint8_t log_indent_ = 0; 117 bool log_skip_execution_ = false; 118 bool pc_set_ = false; 119 int32_t log_cfa_offset_ = 0; 120 std::map<uint8_t, int32_t> log_regs_; 121 }; 122 123 } // namespace unwindstack 124