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