1 //===-- AArch66.h ---------------------------------------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 #include "lldb/lldb-types.h"
11 #include "ABIAArch64.h"
12 #include "ABIMacOSX_arm64.h"
13 #include "ABISysV_arm64.h"
14 #include "Utility/ARM64_DWARF_Registers.h"
15 #include "lldb/Core/PluginManager.h"
16 #include "lldb/Target/Process.h"
23 LLDB_PLUGIN_DEFINE(ABIAArch64
)
25 void ABIAArch64::Initialize() {
26 ABISysV_arm64::Initialize();
27 ABIMacOSX_arm64::Initialize();
30 void ABIAArch64::Terminate() {
31 ABISysV_arm64::Terminate();
32 ABIMacOSX_arm64::Terminate();
35 lldb::addr_t
ABIAArch64::FixCodeAddress(lldb::addr_t pc
) {
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();
46 if (mask
!= LLDB_INVALID_ADDRESS_MASK
)
47 return FixAddress(pc
, mask
);
52 lldb::addr_t
ABIAArch64::FixDataAddress(lldb::addr_t pc
) {
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
);
68 std::pair
<uint32_t, uint32_t>
69 ABIAArch64::GetEHAndDWARFNums(llvm::StringRef name
) {
71 return {LLDB_INVALID_REGNUM
, arm64_dwarf::pc
};
73 return {LLDB_INVALID_REGNUM
, arm64_dwarf::cpsr
};
74 return MCBasedABI::GetEHAndDWARFNums(name
);
77 std::string
ABIAArch64::GetMCName(std::string reg
) {
78 MapRegisterName(reg
, "v", "q");
79 MapRegisterName(reg
, "x29", "fp");
80 MapRegisterName(reg
, "x30", "lr");
84 uint32_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
);
102 static void addPartialRegisters(
103 std::vector
<lldb_private::DynamicRegisterInfo::Register
> ®s
,
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
)
112 lldb_private::DynamicRegisterInfo::Register partial_reg
{
113 lldb_private::ConstString(
114 llvm::formatv(partial_reg_format
, it
.index()).str()),
115 lldb_private::ConstString(),
116 lldb_private::ConstString("supplementary registers"),
118 LLDB_INVALID_INDEX32
,
127 addSupplementaryRegister(regs
, partial_reg
);
131 void ABIAArch64::AugmentRegisterInfo(
132 std::vector
<lldb_private::DynamicRegisterInfo::Register
> ®s
) {
133 lldb_private::MCBasedABI::AugmentRegisterInfo(regs
);
135 lldb_private::ConstString sp_string
{"sp"};
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
;
142 for (auto it
: llvm::enumerate(regs
)) {
143 lldb_private::DynamicRegisterInfo::Register
&info
= it
.value();
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");
148 unsigned int reg_num
;
149 auto get_reg
= [&info
, ®_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);
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();
165 z_byte_size
= info
.byte_size
;
167 // if we have at least one subregister, abort
168 else if (get_reg("w") || get_reg("s") || get_reg("d"))
172 // Create aliases for partial registers.
175 addPartialRegisters(regs
, x_regs
, 8, "w{0}", 4, lldb::eEncodingUint
,
178 auto bool_predicate
= [](const auto ®_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
);
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
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,
196 lldb::eEncodingVector
, lldb::eFormatVectorOfUInt8
);
197 addPartialRegisters(regs
, z_regs
, *z_byte_size
, "s{0}", 4,
198 lldb::eEncodingIEEE754
, lldb::eFormatFloat
);
199 addPartialRegisters(regs
, z_regs
, *z_byte_size
, "d{0}", 8,
200 lldb::eEncodingIEEE754
, lldb::eFormatFloat
);