LLDB mainline
ABIAArch64.cpp
Go to the documentation of this file.
1//===-- AArch66.h ---------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "lldb/lldb-types.h"
10
11#include "ABIAArch64.h"
12#include "ABIMacOSX_arm64.h"
13#include "ABISysV_arm64.h"
16#include "lldb/Target/Process.h"
17
18#include <bitset>
19#include <optional>
20
21using namespace lldb;
22
24
25void ABIAArch64::Initialize() {
28}
29
33}
34
36 if (lldb::ProcessSP process_sp = GetProcessSP()) {
37 // b55 is the highest bit outside TBI (if it's enabled), use
38 // it to determine if the high bits are set to 0 or 1.
39 const addr_t pac_sign_extension = 0x0080000000000000ULL;
40 addr_t mask = process_sp->GetCodeAddressMask();
41 // Test if the high memory mask has been overriden separately
42 if (pc & pac_sign_extension &&
43 process_sp->GetHighmemCodeAddressMask() != LLDB_INVALID_ADDRESS_MASK)
44 mask = process_sp->GetHighmemCodeAddressMask();
45
46 if (mask != LLDB_INVALID_ADDRESS_MASK)
47 return FixAddress(pc, mask);
48 }
49 return pc;
50}
51
53 if (lldb::ProcessSP process_sp = GetProcessSP()) {
54 // b55 is the highest bit outside TBI (if it's enabled), use
55 // it to determine if the high bits are set to 0 or 1.
56 const addr_t pac_sign_extension = 0x0080000000000000ULL;
57 addr_t mask = process_sp->GetDataAddressMask();
58 // Test if the high memory mask has been overriden separately
59 if (pc & pac_sign_extension &&
60 process_sp->GetHighmemDataAddressMask() != LLDB_INVALID_ADDRESS_MASK)
61 mask = process_sp->GetHighmemDataAddressMask();
62 if (mask != LLDB_INVALID_ADDRESS_MASK)
63 return FixAddress(pc, mask);
64 }
65 return pc;
66}
67
68std::pair<uint32_t, uint32_t>
69ABIAArch64::GetEHAndDWARFNums(llvm::StringRef name) {
70 if (name == "pc")
72 if (name == "cpsr")
74 return MCBasedABI::GetEHAndDWARFNums(name);
75}
76
77std::string ABIAArch64::GetMCName(std::string reg) {
78 MapRegisterName(reg, "v", "q");
79 MapRegisterName(reg, "x29", "fp");
80 MapRegisterName(reg, "x30", "lr");
81 return reg;
82}
83
84uint32_t ABIAArch64::GetGenericNum(llvm::StringRef name) {
85 return llvm::StringSwitch<uint32_t>(name)
86 .Case("pc", LLDB_REGNUM_GENERIC_PC)
87 .Cases("lr", "x30", LLDB_REGNUM_GENERIC_RA)
88 .Cases("sp", "x31", LLDB_REGNUM_GENERIC_SP)
89 .Cases("fp", "x29", LLDB_REGNUM_GENERIC_FP)
90 .Case("cpsr", LLDB_REGNUM_GENERIC_FLAGS)
91 .Case("x0", LLDB_REGNUM_GENERIC_ARG1)
92 .Case("x1", LLDB_REGNUM_GENERIC_ARG2)
93 .Case("x2", LLDB_REGNUM_GENERIC_ARG3)
94 .Case("x3", LLDB_REGNUM_GENERIC_ARG4)
95 .Case("x4", LLDB_REGNUM_GENERIC_ARG5)
96 .Case("x5", LLDB_REGNUM_GENERIC_ARG6)
97 .Case("x6", LLDB_REGNUM_GENERIC_ARG7)
98 .Case("x7", LLDB_REGNUM_GENERIC_ARG8)
99 .Default(LLDB_INVALID_REGNUM);
100}
101
103 std::vector<lldb_private::DynamicRegisterInfo::Register> &regs,
104 llvm::ArrayRef<std::optional<uint32_t>> full_reg_indices,
105 uint32_t full_reg_size, const char *partial_reg_format,
106 uint32_t partial_reg_size, lldb::Encoding encoding, lldb::Format format) {
107 for (auto it : llvm::enumerate(full_reg_indices)) {
108 std::optional<uint32_t> full_reg_index = it.value();
109 if (!full_reg_index || regs[*full_reg_index].byte_size != full_reg_size)
110 return;
111
114 llvm::formatv(partial_reg_format, it.index()).str()),
116 lldb_private::ConstString("supplementary registers"),
117 partial_reg_size,
119 encoding,
120 format,
125 {*full_reg_index},
126 {}};
127 addSupplementaryRegister(regs, partial_reg);
128 }
129}
130
132 std::vector<lldb_private::DynamicRegisterInfo::Register> &regs) {
134
135 lldb_private::ConstString sp_string{"sp"};
136
137 std::array<std::optional<uint32_t>, 32> x_regs;
138 std::array<std::optional<uint32_t>, 32> v_regs;
139 std::array<std::optional<uint32_t>, 32> z_regs;
140 std::optional<uint32_t> z_byte_size;
141
142 for (auto it : llvm::enumerate(regs)) {
144 // GDB sends x31 as "sp". Add the "x31" alt_name for convenience.
145 if (info.name == sp_string && !info.alt_name)
146 info.alt_name.SetCString("x31");
147
148 unsigned int reg_num;
149 auto get_reg = [&info, &reg_num](const char *prefix) {
150 llvm::StringRef reg_name = info.name.GetStringRef();
151 llvm::StringRef alt_name = info.alt_name.GetStringRef();
152 return (reg_name.consume_front(prefix) &&
153 llvm::to_integer(reg_name, reg_num, 10) && reg_num < 32) ||
154 (alt_name.consume_front(prefix) &&
155 llvm::to_integer(alt_name, reg_num, 10) && reg_num < 32);
156 };
157
158 if (get_reg("x"))
159 x_regs[reg_num] = it.index();
160 else if (get_reg("v"))
161 v_regs[reg_num] = it.index();
162 else if (get_reg("z")) {
163 z_regs[reg_num] = it.index();
164 if (!z_byte_size)
165 z_byte_size = info.byte_size;
166 }
167 // if we have at least one subregister, abort
168 else if (get_reg("w") || get_reg("s") || get_reg("d"))
169 return;
170 }
171
172 // Create aliases for partial registers.
173
174 // Wn for Xn.
175 addPartialRegisters(regs, x_regs, 8, "w{0}", 4, lldb::eEncodingUint,
177
178 auto bool_predicate = [](const auto &reg_num) { return bool(reg_num); };
179 bool saw_v_regs = std::any_of(v_regs.begin(), v_regs.end(), bool_predicate);
180 bool saw_z_regs = std::any_of(z_regs.begin(), z_regs.end(), bool_predicate);
181
182 // Sn/Dn for Vn.
183 if (saw_v_regs) {
184 addPartialRegisters(regs, v_regs, 16, "s{0}", 4, lldb::eEncodingIEEE754,
186 addPartialRegisters(regs, v_regs, 16, "d{0}", 8, lldb::eEncodingIEEE754,
188 } else if (saw_z_regs && z_byte_size) {
189 // When SVE is enabled, some debug stubs will not describe the Neon V
190 // registers because they can be read from the bottom 128 bits of the SVE
191 // registers.
192
193 // The size used here is the one sent by the debug server. This only needs
194 // to be correct right now. Later we will rely on the value of vg instead.
195 addPartialRegisters(regs, z_regs, *z_byte_size, "v{0}", 16,
197 addPartialRegisters(regs, z_regs, *z_byte_size, "s{0}", 4,
199 addPartialRegisters(regs, z_regs, *z_byte_size, "d{0}", 8,
201 }
202}
static void addPartialRegisters(std::vector< lldb_private::DynamicRegisterInfo::Register > &regs, llvm::ArrayRef< std::optional< uint32_t > > full_reg_indices, uint32_t full_reg_size, const char *partial_reg_format, uint32_t partial_reg_size, lldb::Encoding encoding, lldb::Format format)
Definition: ABIAArch64.cpp:102
#define LLDB_PLUGIN_DEFINE(PluginName)
Definition: PluginManager.h:32
static void Terminate()
Definition: ABIAArch64.cpp:30
lldb::addr_t FixDataAddress(lldb::addr_t pc) override
Definition: ABIAArch64.cpp:52
lldb::addr_t FixCodeAddress(lldb::addr_t pc) override
Some targets might use bits in a code address to indicate a mode switch.
Definition: ABIAArch64.cpp:35
uint32_t GetGenericNum(llvm::StringRef name) override
Return the generic number of the given register.
Definition: ABIAArch64.cpp:84
virtual lldb::addr_t FixAddress(lldb::addr_t pc, lldb::addr_t mask)
Definition: ABIAArch64.h:23
void AugmentRegisterInfo(std::vector< lldb_private::DynamicRegisterInfo::Register > &regs) override
Definition: ABIAArch64.cpp:131
std::pair< uint32_t, uint32_t > GetEHAndDWARFNums(llvm::StringRef name) override
Return eh_frame and dwarf numbers for the given register.
Definition: ABIAArch64.cpp:69
std::string GetMCName(std::string reg) override
For the given (capitalized) lldb register name, return the name of this register in the MCRegisterInf...
Definition: ABIAArch64.cpp:77
static void Terminate()
static void Initialize()
static void Initialize()
static void Terminate()
lldb::ProcessSP GetProcessSP() const
Request to get a Process shared pointer.
Definition: ABI.h:96
A uniqued constant string class.
Definition: ConstString.h:40
void SetCString(const char *cstr)
Set the C string value.
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
Definition: ConstString.h:197
void AugmentRegisterInfo(std::vector< DynamicRegisterInfo::Register > &regs) override
Definition: ABI.cpp:271
static void MapRegisterName(std::string &reg, llvm::StringRef from_prefix, llvm::StringRef to_prefix)
If the register name is of the form "<from_prefix>[<number>]" then change the name to "<to_prefix>[<n...
Definition: ABI.cpp:305
#define LLDB_REGNUM_GENERIC_RA
Definition: lldb-defines.h:59
#define LLDB_REGNUM_GENERIC_ARG8
Definition: lldb-defines.h:75
#define LLDB_INVALID_ADDRESS_MASK
Address Mask Bits not used for addressing are set to 1 in the mask; all mask bits set is an invalid v...
Definition: lldb-defines.h:133
#define LLDB_REGNUM_GENERIC_ARG6
Definition: lldb-defines.h:71
#define LLDB_INVALID_INDEX32
Definition: lldb-defines.h:83
#define LLDB_REGNUM_GENERIC_SP
Definition: lldb-defines.h:57
#define LLDB_REGNUM_GENERIC_ARG4
Definition: lldb-defines.h:67
#define LLDB_REGNUM_GENERIC_ARG3
Definition: lldb-defines.h:65
#define LLDB_REGNUM_GENERIC_ARG1
Definition: lldb-defines.h:61
#define LLDB_REGNUM_GENERIC_ARG7
Definition: lldb-defines.h:73
#define LLDB_REGNUM_GENERIC_FLAGS
Definition: lldb-defines.h:60
#define LLDB_INVALID_REGNUM
Definition: lldb-defines.h:87
#define LLDB_REGNUM_GENERIC_ARG2
Definition: lldb-defines.h:63
#define LLDB_REGNUM_GENERIC_PC
Definition: lldb-defines.h:56
#define LLDB_REGNUM_GENERIC_FP
Definition: lldb-defines.h:58
#define LLDB_REGNUM_GENERIC_ARG5
Definition: lldb-defines.h:69
Definition: SBAddress.h:15
Format
Display format definitions.
@ eFormatVectorOfUInt8
std::shared_ptr< lldb_private::Process > ProcessSP
Definition: lldb-forward.h:389
Encoding
Register encoding definitions.
@ eEncodingIEEE754
float
@ eEncodingVector
vector registers
@ eEncodingUint
unsigned integer
uint64_t addr_t
Definition: lldb-types.h:80