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