xref: /aosp_15_r20/system/unwinding/libunwindstack/ArmExidx.h (revision eb293b8f56ee8303637c5595cfcdeef8039e85c6)
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