Coverage Report

Created: 2025-06-13 06:34

/src/perfetto/buildtools/android-unwinding/libunwindstack/ArmExidx.h
Line
Count
Source (jump to first uncovered line)
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:
55
  ArmExidx(RegsArm* regs, Memory* elf_memory, Memory* process_memory)
56
0
      : regs_(regs), elf_memory_(elf_memory), process_memory_(process_memory) {}
57
0
  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
69
0
  std::deque<uint8_t>* data() { return &data_; }
70
71
0
  ArmStatus status() { return status_; }
72
0
  uint64_t status_address() { return status_address_; }
73
74
0
  RegsArm* regs() { return regs_; }
75
76
0
  uint32_t cfa() { return cfa_; }
77
0
  void set_cfa(uint32_t cfa) { cfa_ = cfa; }
78
79
0
  bool pc_set() { return pc_set_; }
80
0
  void set_pc_set(bool pc_set) { pc_set_ = pc_set; }
81
82
0
  void set_log(ArmLogType log_type) { log_type_ = log_type; }
83
0
  void set_log_skip_execution(bool skip_execution) { log_skip_execution_ = skip_execution; }
84
0
  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