1*eb293b8fSAndroid Build Coastguard Worker /* 2*eb293b8fSAndroid Build Coastguard Worker * Copyright (C) 2016 The Android Open Source Project 3*eb293b8fSAndroid Build Coastguard Worker * 4*eb293b8fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*eb293b8fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*eb293b8fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*eb293b8fSAndroid Build Coastguard Worker * 8*eb293b8fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*eb293b8fSAndroid Build Coastguard Worker * 10*eb293b8fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*eb293b8fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*eb293b8fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*eb293b8fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*eb293b8fSAndroid Build Coastguard Worker * limitations under the License. 15*eb293b8fSAndroid Build Coastguard Worker */ 16*eb293b8fSAndroid Build Coastguard Worker 17*eb293b8fSAndroid Build Coastguard Worker #pragma once 18*eb293b8fSAndroid Build Coastguard Worker 19*eb293b8fSAndroid Build Coastguard Worker #include <stdint.h> 20*eb293b8fSAndroid Build Coastguard Worker 21*eb293b8fSAndroid Build Coastguard Worker #include <deque> 22*eb293b8fSAndroid Build Coastguard Worker #include <map> 23*eb293b8fSAndroid Build Coastguard Worker 24*eb293b8fSAndroid Build Coastguard Worker namespace unwindstack { 25*eb293b8fSAndroid Build Coastguard Worker 26*eb293b8fSAndroid Build Coastguard Worker // Forward declarations. 27*eb293b8fSAndroid Build Coastguard Worker class Memory; 28*eb293b8fSAndroid Build Coastguard Worker class RegsArm; 29*eb293b8fSAndroid Build Coastguard Worker 30*eb293b8fSAndroid Build Coastguard Worker enum ArmStatus : size_t { 31*eb293b8fSAndroid Build Coastguard Worker ARM_STATUS_NONE = 0, 32*eb293b8fSAndroid Build Coastguard Worker ARM_STATUS_NO_UNWIND, 33*eb293b8fSAndroid Build Coastguard Worker ARM_STATUS_FINISH, 34*eb293b8fSAndroid Build Coastguard Worker ARM_STATUS_RESERVED, 35*eb293b8fSAndroid Build Coastguard Worker ARM_STATUS_SPARE, 36*eb293b8fSAndroid Build Coastguard Worker ARM_STATUS_TRUNCATED, 37*eb293b8fSAndroid Build Coastguard Worker ARM_STATUS_READ_FAILED, 38*eb293b8fSAndroid Build Coastguard Worker ARM_STATUS_MALFORMED, 39*eb293b8fSAndroid Build Coastguard Worker ARM_STATUS_INVALID_ALIGNMENT, 40*eb293b8fSAndroid Build Coastguard Worker ARM_STATUS_INVALID_PERSONALITY, 41*eb293b8fSAndroid Build Coastguard Worker }; 42*eb293b8fSAndroid Build Coastguard Worker 43*eb293b8fSAndroid Build Coastguard Worker enum ArmOp : uint8_t { 44*eb293b8fSAndroid Build Coastguard Worker ARM_OP_FINISH = 0xb0, 45*eb293b8fSAndroid Build Coastguard Worker }; 46*eb293b8fSAndroid Build Coastguard Worker 47*eb293b8fSAndroid Build Coastguard Worker enum ArmLogType : uint8_t { 48*eb293b8fSAndroid Build Coastguard Worker ARM_LOG_NONE, 49*eb293b8fSAndroid Build Coastguard Worker ARM_LOG_FULL, 50*eb293b8fSAndroid Build Coastguard Worker ARM_LOG_BY_REG, 51*eb293b8fSAndroid Build Coastguard Worker }; 52*eb293b8fSAndroid Build Coastguard Worker 53*eb293b8fSAndroid Build Coastguard Worker class ArmExidx { 54*eb293b8fSAndroid Build Coastguard Worker public: ArmExidx(RegsArm * regs,Memory * elf_memory,Memory * process_memory)55*eb293b8fSAndroid Build Coastguard Worker ArmExidx(RegsArm* regs, Memory* elf_memory, Memory* process_memory) 56*eb293b8fSAndroid Build Coastguard Worker : regs_(regs), elf_memory_(elf_memory), process_memory_(process_memory) {} ~ArmExidx()57*eb293b8fSAndroid Build Coastguard Worker virtual ~ArmExidx() {} 58*eb293b8fSAndroid Build Coastguard Worker 59*eb293b8fSAndroid Build Coastguard Worker void LogRawData(); 60*eb293b8fSAndroid Build Coastguard Worker 61*eb293b8fSAndroid Build Coastguard Worker void LogByReg(); 62*eb293b8fSAndroid Build Coastguard Worker 63*eb293b8fSAndroid Build Coastguard Worker bool ExtractEntryData(uint32_t entry_offset); 64*eb293b8fSAndroid Build Coastguard Worker 65*eb293b8fSAndroid Build Coastguard Worker bool Eval(); 66*eb293b8fSAndroid Build Coastguard Worker 67*eb293b8fSAndroid Build Coastguard Worker bool Decode(); 68*eb293b8fSAndroid Build Coastguard Worker data()69*eb293b8fSAndroid Build Coastguard Worker std::deque<uint8_t>* data() { return &data_; } 70*eb293b8fSAndroid Build Coastguard Worker status()71*eb293b8fSAndroid Build Coastguard Worker ArmStatus status() { return status_; } status_address()72*eb293b8fSAndroid Build Coastguard Worker uint64_t status_address() { return status_address_; } 73*eb293b8fSAndroid Build Coastguard Worker regs()74*eb293b8fSAndroid Build Coastguard Worker RegsArm* regs() { return regs_; } 75*eb293b8fSAndroid Build Coastguard Worker cfa()76*eb293b8fSAndroid Build Coastguard Worker uint32_t cfa() { return cfa_; } set_cfa(uint32_t cfa)77*eb293b8fSAndroid Build Coastguard Worker void set_cfa(uint32_t cfa) { cfa_ = cfa; } 78*eb293b8fSAndroid Build Coastguard Worker pc_set()79*eb293b8fSAndroid Build Coastguard Worker bool pc_set() { return pc_set_; } set_pc_set(bool pc_set)80*eb293b8fSAndroid Build Coastguard Worker void set_pc_set(bool pc_set) { pc_set_ = pc_set; } 81*eb293b8fSAndroid Build Coastguard Worker set_log(ArmLogType log_type)82*eb293b8fSAndroid Build Coastguard Worker void set_log(ArmLogType log_type) { log_type_ = log_type; } set_log_skip_execution(bool skip_execution)83*eb293b8fSAndroid Build Coastguard Worker void set_log_skip_execution(bool skip_execution) { log_skip_execution_ = skip_execution; } set_log_indent(uint8_t indent)84*eb293b8fSAndroid Build Coastguard Worker void set_log_indent(uint8_t indent) { log_indent_ = indent; } 85*eb293b8fSAndroid Build Coastguard Worker 86*eb293b8fSAndroid Build Coastguard Worker private: 87*eb293b8fSAndroid Build Coastguard Worker bool GetByte(uint8_t* byte); 88*eb293b8fSAndroid Build Coastguard Worker void AdjustRegisters(int32_t offset); 89*eb293b8fSAndroid Build Coastguard Worker 90*eb293b8fSAndroid Build Coastguard Worker bool DecodePrefix_10_00(uint8_t byte); 91*eb293b8fSAndroid Build Coastguard Worker bool DecodePrefix_10_01(uint8_t byte); 92*eb293b8fSAndroid Build Coastguard Worker bool DecodePrefix_10_10(uint8_t byte); 93*eb293b8fSAndroid Build Coastguard Worker bool DecodePrefix_10_11_0000(); 94*eb293b8fSAndroid Build Coastguard Worker bool DecodePrefix_10_11_0001(); 95*eb293b8fSAndroid Build Coastguard Worker bool DecodePrefix_10_11_0010(); 96*eb293b8fSAndroid Build Coastguard Worker bool DecodePrefix_10_11_0011(); 97*eb293b8fSAndroid Build Coastguard Worker bool DecodePrefix_10_11_01nn(); 98*eb293b8fSAndroid Build Coastguard Worker bool DecodePrefix_10_11_1nnn(uint8_t byte); 99*eb293b8fSAndroid Build Coastguard Worker bool DecodePrefix_10(uint8_t byte); 100*eb293b8fSAndroid Build Coastguard Worker 101*eb293b8fSAndroid Build Coastguard Worker bool DecodePrefix_11_000(uint8_t byte); 102*eb293b8fSAndroid Build Coastguard Worker bool DecodePrefix_11_001(uint8_t byte); 103*eb293b8fSAndroid Build Coastguard Worker bool DecodePrefix_11_010(uint8_t byte); 104*eb293b8fSAndroid Build Coastguard Worker bool DecodePrefix_11(uint8_t byte); 105*eb293b8fSAndroid Build Coastguard Worker 106*eb293b8fSAndroid Build Coastguard Worker RegsArm* regs_ = nullptr; 107*eb293b8fSAndroid Build Coastguard Worker uint32_t cfa_ = 0; 108*eb293b8fSAndroid Build Coastguard Worker std::deque<uint8_t> data_; 109*eb293b8fSAndroid Build Coastguard Worker ArmStatus status_ = ARM_STATUS_NONE; 110*eb293b8fSAndroid Build Coastguard Worker uint64_t status_address_ = 0; 111*eb293b8fSAndroid Build Coastguard Worker 112*eb293b8fSAndroid Build Coastguard Worker Memory* elf_memory_; 113*eb293b8fSAndroid Build Coastguard Worker Memory* process_memory_; 114*eb293b8fSAndroid Build Coastguard Worker 115*eb293b8fSAndroid Build Coastguard Worker ArmLogType log_type_ = ARM_LOG_NONE; 116*eb293b8fSAndroid Build Coastguard Worker uint8_t log_indent_ = 0; 117*eb293b8fSAndroid Build Coastguard Worker bool log_skip_execution_ = false; 118*eb293b8fSAndroid Build Coastguard Worker bool pc_set_ = false; 119*eb293b8fSAndroid Build Coastguard Worker int32_t log_cfa_offset_ = 0; 120*eb293b8fSAndroid Build Coastguard Worker std::map<uint8_t, int32_t> log_regs_; 121*eb293b8fSAndroid Build Coastguard Worker }; 122*eb293b8fSAndroid Build Coastguard Worker 123*eb293b8fSAndroid Build Coastguard Worker } // namespace unwindstack 124