]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm64.cpp
Update ELF Tool Chain to upstream rev 3400
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / Process / Utility / RegisterContextPOSIX_arm64.cpp
1 //===-- RegisterContextPOSIX_arm64.cpp --------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include <cstring>
11 #include <errno.h>
12 #include <stdint.h>
13
14 #include "lldb/Core/DataBufferHeap.h"
15 #include "lldb/Core/DataExtractor.h"
16 #include "lldb/Core/RegisterValue.h"
17 #include "lldb/Core/Scalar.h"
18 #include "lldb/Target/Target.h"
19 #include "lldb/Target/Thread.h"
20 #include "lldb/Host/Endian.h"
21 #include "llvm/Support/Compiler.h"
22
23 #include "RegisterContextPOSIX_arm64.h"
24 #include "Plugins/Process/elf-core/ProcessElfCore.h"
25
26 using namespace lldb;
27 using namespace lldb_private;
28
29 // ARM64 general purpose registers.
30 const uint32_t g_gpr_regnums_arm64[] =
31 {
32     gpr_x0_arm64,
33     gpr_x1_arm64,
34     gpr_x2_arm64,
35     gpr_x3_arm64,
36     gpr_x4_arm64,
37     gpr_x5_arm64,
38     gpr_x6_arm64,
39     gpr_x7_arm64,
40     gpr_x8_arm64,
41     gpr_x9_arm64,
42     gpr_x10_arm64,
43     gpr_x11_arm64,
44     gpr_x12_arm64,
45     gpr_x13_arm64,
46     gpr_x14_arm64,
47     gpr_x15_arm64,
48     gpr_x16_arm64,
49     gpr_x17_arm64,
50     gpr_x18_arm64,
51     gpr_x19_arm64,
52     gpr_x20_arm64,
53     gpr_x21_arm64,
54     gpr_x22_arm64,
55     gpr_x23_arm64,
56     gpr_x24_arm64,
57     gpr_x25_arm64,
58     gpr_x26_arm64,
59     gpr_x27_arm64,
60     gpr_x28_arm64,
61     gpr_fp_arm64,
62     gpr_lr_arm64,
63     gpr_sp_arm64,
64     gpr_pc_arm64,
65     gpr_cpsr_arm64,
66     LLDB_INVALID_REGNUM // register sets need to end with this flag
67 };
68 static_assert(((sizeof g_gpr_regnums_arm64 / sizeof g_gpr_regnums_arm64[0]) - 1) == k_num_gpr_registers_arm64, \
69               "g_gpr_regnums_arm64 has wrong number of register infos");
70
71 // ARM64 floating point registers.
72 static const uint32_t g_fpu_regnums_arm64[] =
73 {
74     fpu_v0_arm64,
75     fpu_v1_arm64,
76     fpu_v2_arm64,
77     fpu_v3_arm64,
78     fpu_v4_arm64,
79     fpu_v5_arm64,
80     fpu_v6_arm64,
81     fpu_v7_arm64,
82     fpu_v8_arm64,
83     fpu_v9_arm64,
84     fpu_v10_arm64,
85     fpu_v11_arm64,
86     fpu_v12_arm64,
87     fpu_v13_arm64,
88     fpu_v14_arm64,
89     fpu_v15_arm64,
90     fpu_v16_arm64,
91     fpu_v17_arm64,
92     fpu_v18_arm64,
93     fpu_v19_arm64,
94     fpu_v20_arm64,
95     fpu_v21_arm64,
96     fpu_v22_arm64,
97     fpu_v23_arm64,
98     fpu_v24_arm64,
99     fpu_v25_arm64,
100     fpu_v26_arm64,
101     fpu_v27_arm64,
102     fpu_v28_arm64,
103     fpu_v29_arm64,
104     fpu_v30_arm64,
105     fpu_v31_arm64,
106     fpu_fpsr_arm64,
107     fpu_fpcr_arm64,
108     LLDB_INVALID_REGNUM // register sets need to end with this flag
109 };
110 static_assert(((sizeof g_fpu_regnums_arm64 / sizeof g_fpu_regnums_arm64[0]) - 1) == k_num_fpr_registers_arm64, \
111               "g_fpu_regnums_arm64 has wrong number of register infos");
112
113 // Number of register sets provided by this context.
114 enum
115 {
116     k_num_register_sets = 2
117 };
118
119 // Register sets for ARM64.
120 static const lldb_private::RegisterSet
121 g_reg_sets_arm64[k_num_register_sets] =
122 {
123     { "General Purpose Registers",  "gpr", k_num_gpr_registers_arm64, g_gpr_regnums_arm64 },
124     { "Floating Point Registers",   "fpu", k_num_fpr_registers_arm64, g_fpu_regnums_arm64 }
125 };
126
127 bool RegisterContextPOSIX_arm64::IsGPR(unsigned reg)
128 {
129     return reg <= m_reg_info.last_gpr;   // GPR's come first.
130 }
131
132 bool RegisterContextPOSIX_arm64::IsFPR(unsigned reg)
133 {
134     return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
135 }
136
137 RegisterContextPOSIX_arm64::RegisterContextPOSIX_arm64(lldb_private::Thread &thread,
138                                                        uint32_t concrete_frame_idx,
139                                                        lldb_private::RegisterInfoInterface *register_info)
140     : lldb_private::RegisterContext(thread, concrete_frame_idx)
141 {
142     m_register_info_ap.reset(register_info);
143
144     switch (register_info->m_target_arch.GetMachine())
145     {
146         case llvm::Triple::aarch64:
147             m_reg_info.num_registers     = k_num_registers_arm64;
148             m_reg_info.num_gpr_registers = k_num_gpr_registers_arm64;
149             m_reg_info.num_fpr_registers = k_num_fpr_registers_arm64;
150             m_reg_info.last_gpr          = k_last_gpr_arm64;
151             m_reg_info.first_fpr         = k_first_fpr_arm64;
152             m_reg_info.last_fpr          = k_last_fpr_arm64;
153             m_reg_info.first_fpr_v       = fpu_v0_arm64;
154             m_reg_info.last_fpr_v        = fpu_v31_arm64;
155             m_reg_info.gpr_flags         = gpr_cpsr_arm64;
156             break;
157         default:
158             assert(false && "Unhandled target architecture.");
159             break;
160     }
161
162     ::memset(&m_fpr, 0, sizeof m_fpr);
163
164     // elf-core yet to support ReadFPR()
165     lldb::ProcessSP base = CalculateProcess();
166     if (base.get()->GetPluginName() ==  ProcessElfCore::GetPluginNameStatic())
167         return;
168 }
169
170 RegisterContextPOSIX_arm64::~RegisterContextPOSIX_arm64()
171 {
172 }
173
174 void
175 RegisterContextPOSIX_arm64::Invalidate()
176 {
177 }
178
179 void
180 RegisterContextPOSIX_arm64::InvalidateAllRegisters()
181 {
182 }
183
184 unsigned
185 RegisterContextPOSIX_arm64::GetRegisterOffset(unsigned reg)
186 {
187     assert(reg < m_reg_info.num_registers && "Invalid register number.");
188     return GetRegisterInfo()[reg].byte_offset;
189 }
190
191 unsigned
192 RegisterContextPOSIX_arm64::GetRegisterSize(unsigned reg)
193 {
194     assert(reg < m_reg_info.num_registers && "Invalid register number.");
195     return GetRegisterInfo()[reg].byte_size;
196 }
197
198 size_t
199 RegisterContextPOSIX_arm64::GetRegisterCount()
200 {
201     size_t num_registers = m_reg_info.num_gpr_registers + m_reg_info.num_fpr_registers;
202     return num_registers;
203 }
204
205 size_t
206 RegisterContextPOSIX_arm64::GetGPRSize()
207 {
208     return m_register_info_ap->GetGPRSize ();
209 }
210
211 const lldb_private::RegisterInfo *
212 RegisterContextPOSIX_arm64::GetRegisterInfo()
213 {
214     // Commonly, this method is overridden and g_register_infos is copied and specialized.
215     // So, use GetRegisterInfo() rather than g_register_infos in this scope.
216     return m_register_info_ap->GetRegisterInfo ();
217 }
218
219 const lldb_private::RegisterInfo *
220 RegisterContextPOSIX_arm64::GetRegisterInfoAtIndex(size_t reg)
221 {
222     if (reg < m_reg_info.num_registers)
223         return &GetRegisterInfo()[reg];
224     else
225         return NULL;
226 }
227
228 size_t
229 RegisterContextPOSIX_arm64::GetRegisterSetCount()
230 {
231     size_t sets = 0;
232     for (size_t set = 0; set < k_num_register_sets; ++set)
233     {
234         if (IsRegisterSetAvailable(set))
235             ++sets;
236     }
237
238     return sets;
239 }
240
241 const lldb_private::RegisterSet *
242 RegisterContextPOSIX_arm64::GetRegisterSet(size_t set)
243 {
244     if (IsRegisterSetAvailable(set))
245     {
246         switch (m_register_info_ap->m_target_arch.GetMachine())
247         {
248             case llvm::Triple::aarch64:
249                 return &g_reg_sets_arm64[set];
250             default:
251                 assert(false && "Unhandled target architecture.");
252                 return NULL;
253         }
254     }
255     return NULL;
256 }
257
258 const char *
259 RegisterContextPOSIX_arm64::GetRegisterName(unsigned reg)
260 {
261     assert(reg < m_reg_info.num_registers && "Invalid register offset.");
262     return GetRegisterInfo()[reg].name;
263 }
264
265 lldb::ByteOrder
266 RegisterContextPOSIX_arm64::GetByteOrder()
267 {
268     // Get the target process whose privileged thread was used for the register read.
269     lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;
270     lldb_private::Process *process = CalculateProcess().get();
271
272     if (process)
273         byte_order = process->GetByteOrder();
274     return byte_order;
275 }
276
277 bool
278 RegisterContextPOSIX_arm64::IsRegisterSetAvailable(size_t set_index)
279 {
280     return set_index < k_num_register_sets;
281 }
282
283
284 // Used when parsing DWARF and EH frame information and any other
285 // object file sections that contain register numbers in them. 
286 uint32_t
287 RegisterContextPOSIX_arm64::ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
288                                                                 uint32_t num)
289 {
290     const uint32_t num_regs = GetRegisterCount();
291
292     assert (kind < lldb::kNumRegisterKinds);
293     for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
294     {
295         const lldb_private::RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg_idx);
296
297         if (reg_info->kinds[kind] == num)
298             return reg_idx;
299     }
300
301     return LLDB_INVALID_REGNUM;
302 }