]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/Process/Utility/RegisterContextPOSIX_arm.cpp
Update to ELF Tool Chain r3490
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / Process / Utility / RegisterContextPOSIX_arm.cpp
1 //===-- RegisterContextPOSIX_arm.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_arm.h"
24 #include "Plugins/Process/elf-core/ProcessElfCore.h"
25
26 using namespace lldb;
27 using namespace lldb_private;
28
29 // arm general purpose registers.
30 const uint32_t g_gpr_regnums_arm[] =
31 {
32     gpr_r0_arm,
33     gpr_r1_arm,
34     gpr_r2_arm,
35     gpr_r3_arm,
36     gpr_r4_arm,
37     gpr_r5_arm,
38     gpr_r6_arm,
39     gpr_r7_arm,
40     gpr_r8_arm,
41     gpr_r9_arm,
42     gpr_r10_arm,
43     gpr_r11_arm,
44     gpr_r12_arm,
45     gpr_sp_arm,
46     gpr_lr_arm,
47     gpr_pc_arm,
48     gpr_cpsr_arm,
49     LLDB_INVALID_REGNUM // register sets need to end with this flag
50
51 };
52 static_assert(((sizeof g_gpr_regnums_arm / sizeof g_gpr_regnums_arm[0]) - 1) == k_num_gpr_registers_arm, \
53               "g_gpr_regnums_arm has wrong number of register infos");
54
55 // arm floating point registers.
56 static const uint32_t g_fpu_regnums_arm[] =
57 {
58     fpu_s0_arm,
59     fpu_s1_arm,
60     fpu_s2_arm,
61     fpu_s3_arm,
62     fpu_s4_arm,
63     fpu_s5_arm,
64     fpu_s6_arm,
65     fpu_s7_arm,
66     fpu_s8_arm,
67     fpu_s9_arm,
68     fpu_s10_arm,
69     fpu_s11_arm,
70     fpu_s12_arm,
71     fpu_s13_arm,
72     fpu_s14_arm,
73     fpu_s15_arm,
74     fpu_s16_arm,
75     fpu_s17_arm,
76     fpu_s18_arm,
77     fpu_s19_arm,
78     fpu_s20_arm,
79     fpu_s21_arm,
80     fpu_s22_arm,
81     fpu_s23_arm,
82     fpu_s24_arm,
83     fpu_s25_arm,
84     fpu_s26_arm,
85     fpu_s27_arm,
86     fpu_s28_arm,
87     fpu_s29_arm,
88     fpu_s30_arm,
89     fpu_s31_arm,
90     fpu_fpscr_arm,
91     fpu_d0_arm,
92     fpu_d1_arm,
93     fpu_d2_arm,
94     fpu_d3_arm,
95     fpu_d4_arm,
96     fpu_d5_arm,
97     fpu_d6_arm,
98     fpu_d7_arm,
99     fpu_d8_arm,
100     fpu_d9_arm,
101     fpu_d10_arm,
102     fpu_d11_arm,
103     fpu_d12_arm,
104     fpu_d13_arm,
105     fpu_d14_arm,
106     fpu_d15_arm,
107     fpu_d16_arm,
108     fpu_d17_arm,
109     fpu_d18_arm,
110     fpu_d19_arm,
111     fpu_d20_arm,
112     fpu_d21_arm,
113     fpu_d22_arm,
114     fpu_d23_arm,
115     fpu_d24_arm,
116     fpu_d25_arm,
117     fpu_d26_arm,
118     fpu_d27_arm,
119     fpu_d28_arm,
120     fpu_d29_arm,
121     fpu_d30_arm,
122     fpu_d31_arm,
123     fpu_q0_arm,
124     fpu_q1_arm,
125     fpu_q2_arm,
126     fpu_q3_arm,
127     fpu_q4_arm,
128     fpu_q5_arm,
129     fpu_q6_arm,
130     fpu_q7_arm,
131     fpu_q8_arm,
132     fpu_q9_arm,
133     fpu_q10_arm,
134     fpu_q11_arm,
135     fpu_q12_arm,
136     fpu_q13_arm,
137     fpu_q14_arm,
138     fpu_q15_arm,
139     LLDB_INVALID_REGNUM // register sets need to end with this flag
140
141 };
142 static_assert(((sizeof g_fpu_regnums_arm / sizeof g_fpu_regnums_arm[0]) - 1) == k_num_fpr_registers_arm, \
143               "g_fpu_regnums_arm has wrong number of register infos");
144
145 // Number of register sets provided by this context.
146 enum
147 {
148     k_num_register_sets = 2
149 };
150
151 // Register sets for arm.
152 static const lldb_private::RegisterSet
153 g_reg_sets_arm[k_num_register_sets] =
154 {
155     { "General Purpose Registers",  "gpr", k_num_gpr_registers_arm, g_gpr_regnums_arm },
156     { "Floating Point Registers",   "fpu", k_num_fpr_registers_arm, g_fpu_regnums_arm }
157 };
158
159 bool RegisterContextPOSIX_arm::IsGPR(unsigned reg)
160 {
161     return reg <= m_reg_info.last_gpr;   // GPR's come first.
162 }
163
164 bool RegisterContextPOSIX_arm::IsFPR(unsigned reg)
165 {
166     return (m_reg_info.first_fpr <= reg && reg <= m_reg_info.last_fpr);
167 }
168
169 RegisterContextPOSIX_arm::RegisterContextPOSIX_arm(lldb_private::Thread &thread,
170                                                        uint32_t concrete_frame_idx,
171                                                        lldb_private::RegisterInfoInterface *register_info)
172     : lldb_private::RegisterContext(thread, concrete_frame_idx)
173 {
174     m_register_info_ap.reset(register_info);
175
176     switch (register_info->m_target_arch.GetMachine())
177     {
178         case llvm::Triple::arm:
179             m_reg_info.num_registers     = k_num_registers_arm;
180             m_reg_info.num_gpr_registers = k_num_gpr_registers_arm;
181             m_reg_info.num_fpr_registers = k_num_fpr_registers_arm;
182             m_reg_info.last_gpr          = k_last_gpr_arm;
183             m_reg_info.first_fpr         = k_first_fpr_arm;
184             m_reg_info.last_fpr          = k_last_fpr_arm;
185             m_reg_info.first_fpr_v       = fpu_s0_arm;
186             m_reg_info.last_fpr_v        = fpu_s31_arm;
187             m_reg_info.gpr_flags         = gpr_cpsr_arm;
188             break;
189         default:
190             assert(false && "Unhandled target architecture.");
191             break;
192     }
193
194     ::memset(&m_fpr, 0, sizeof m_fpr);
195
196     // elf-core yet to support ReadFPR()
197     lldb::ProcessSP base = CalculateProcess();
198     if (base.get()->GetPluginName() ==  ProcessElfCore::GetPluginNameStatic())
199         return;
200 }
201
202 RegisterContextPOSIX_arm::~RegisterContextPOSIX_arm()
203 {
204 }
205
206 void
207 RegisterContextPOSIX_arm::Invalidate()
208 {
209 }
210
211 void
212 RegisterContextPOSIX_arm::InvalidateAllRegisters()
213 {
214 }
215
216 unsigned
217 RegisterContextPOSIX_arm::GetRegisterOffset(unsigned reg)
218 {
219     assert(reg < m_reg_info.num_registers && "Invalid register number.");
220     return GetRegisterInfo()[reg].byte_offset;
221 }
222
223 unsigned
224 RegisterContextPOSIX_arm::GetRegisterSize(unsigned reg)
225 {
226     assert(reg < m_reg_info.num_registers && "Invalid register number.");
227     return GetRegisterInfo()[reg].byte_size;
228 }
229
230 size_t
231 RegisterContextPOSIX_arm::GetRegisterCount()
232 {
233     size_t num_registers = m_reg_info.num_gpr_registers + m_reg_info.num_fpr_registers;
234     return num_registers;
235 }
236
237 size_t
238 RegisterContextPOSIX_arm::GetGPRSize()
239 {
240     return m_register_info_ap->GetGPRSize ();
241 }
242
243 const lldb_private::RegisterInfo *
244 RegisterContextPOSIX_arm::GetRegisterInfo()
245 {
246     // Commonly, this method is overridden and g_register_infos is copied and specialized.
247     // So, use GetRegisterInfo() rather than g_register_infos in this scope.
248     return m_register_info_ap->GetRegisterInfo ();
249 }
250
251 const lldb_private::RegisterInfo *
252 RegisterContextPOSIX_arm::GetRegisterInfoAtIndex(size_t reg)
253 {
254     if (reg < m_reg_info.num_registers)
255         return &GetRegisterInfo()[reg];
256     else
257         return NULL;
258 }
259
260 size_t
261 RegisterContextPOSIX_arm::GetRegisterSetCount()
262 {
263     size_t sets = 0;
264     for (size_t set = 0; set < k_num_register_sets; ++set)
265     {
266         if (IsRegisterSetAvailable(set))
267             ++sets;
268     }
269
270     return sets;
271 }
272
273 const lldb_private::RegisterSet *
274 RegisterContextPOSIX_arm::GetRegisterSet(size_t set)
275 {
276     if (IsRegisterSetAvailable(set))
277     {
278         switch (m_register_info_ap->m_target_arch.GetMachine())
279         {
280             case llvm::Triple::arm:
281                 return &g_reg_sets_arm[set];
282             default:
283                 assert(false && "Unhandled target architecture.");
284                 return NULL;
285         }
286     }
287     return NULL;
288 }
289
290 const char *
291 RegisterContextPOSIX_arm::GetRegisterName(unsigned reg)
292 {
293     assert(reg < m_reg_info.num_registers && "Invalid register offset.");
294     return GetRegisterInfo()[reg].name;
295 }
296
297 lldb::ByteOrder
298 RegisterContextPOSIX_arm::GetByteOrder()
299 {
300     // Get the target process whose privileged thread was used for the register read.
301     lldb::ByteOrder byte_order = lldb::eByteOrderInvalid;
302     lldb_private::Process *process = CalculateProcess().get();
303
304     if (process)
305         byte_order = process->GetByteOrder();
306     return byte_order;
307 }
308
309 bool
310 RegisterContextPOSIX_arm::IsRegisterSetAvailable(size_t set_index)
311 {
312     return set_index < k_num_register_sets;
313 }
314
315
316 // Used when parsing DWARF and EH frame information and any other
317 // object file sections that contain register numbers in them. 
318 uint32_t
319 RegisterContextPOSIX_arm::ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
320                                                                 uint32_t num)
321 {
322     const uint32_t num_regs = GetRegisterCount();
323
324     assert (kind < lldb::kNumRegisterKinds);
325     for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
326     {
327         const lldb_private::RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg_idx);
328
329         if (reg_info->kinds[kind] == num)
330             return reg_idx;
331     }
332
333     return LLDB_INVALID_REGNUM;
334 }
335