1 //===-- RegisterContextPOSIX_powerpc.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_powerpc.h"
24 #include "Plugins/Process/elf-core/ProcessElfCore.h"
25 
26 using namespace lldb_private;
27 using namespace lldb;
28 
29 static const
30 uint32_t g_gpr_regnums[] =
31 {
32     gpr_r0_powerpc,
33     gpr_r1_powerpc,
34     gpr_r2_powerpc,
35     gpr_r3_powerpc,
36     gpr_r4_powerpc,
37     gpr_r5_powerpc,
38     gpr_r6_powerpc,
39     gpr_r7_powerpc,
40     gpr_r8_powerpc,
41     gpr_r9_powerpc,
42     gpr_r10_powerpc,
43     gpr_r11_powerpc,
44     gpr_r12_powerpc,
45     gpr_r13_powerpc,
46     gpr_r14_powerpc,
47     gpr_r15_powerpc,
48     gpr_r16_powerpc,
49     gpr_r17_powerpc,
50     gpr_r18_powerpc,
51     gpr_r19_powerpc,
52     gpr_r20_powerpc,
53     gpr_r21_powerpc,
54     gpr_r22_powerpc,
55     gpr_r23_powerpc,
56     gpr_r24_powerpc,
57     gpr_r25_powerpc,
58     gpr_r26_powerpc,
59     gpr_r27_powerpc,
60     gpr_r28_powerpc,
61     gpr_r29_powerpc,
62     gpr_r30_powerpc,
63     gpr_r31_powerpc,
64     gpr_lr_powerpc,
65     gpr_cr_powerpc,
66     gpr_xer_powerpc,
67     gpr_ctr_powerpc,
68     gpr_pc_powerpc,
69 };
70 
71 static const
72 uint32_t g_fpr_regnums[] =
73 {
74     fpr_f0_powerpc,
75     fpr_f1_powerpc,
76     fpr_f2_powerpc,
77     fpr_f3_powerpc,
78     fpr_f4_powerpc,
79     fpr_f5_powerpc,
80     fpr_f6_powerpc,
81     fpr_f7_powerpc,
82     fpr_f8_powerpc,
83     fpr_f9_powerpc,
84     fpr_f10_powerpc,
85     fpr_f11_powerpc,
86     fpr_f12_powerpc,
87     fpr_f13_powerpc,
88     fpr_f14_powerpc,
89     fpr_f15_powerpc,
90     fpr_f16_powerpc,
91     fpr_f17_powerpc,
92     fpr_f18_powerpc,
93     fpr_f19_powerpc,
94     fpr_f20_powerpc,
95     fpr_f21_powerpc,
96     fpr_f22_powerpc,
97     fpr_f23_powerpc,
98     fpr_f24_powerpc,
99     fpr_f25_powerpc,
100     fpr_f26_powerpc,
101     fpr_f27_powerpc,
102     fpr_f28_powerpc,
103     fpr_f29_powerpc,
104     fpr_f30_powerpc,
105     fpr_f31_powerpc,
106     fpr_fpscr_powerpc,
107 };
108 
109 static const
110 uint32_t g_vmx_regnums[] =
111 {
112     vmx_v0_powerpc,
113     vmx_v1_powerpc,
114     vmx_v2_powerpc,
115     vmx_v3_powerpc,
116     vmx_v4_powerpc,
117     vmx_v5_powerpc,
118     vmx_v6_powerpc,
119     vmx_v7_powerpc,
120     vmx_v8_powerpc,
121     vmx_v9_powerpc,
122     vmx_v10_powerpc,
123     vmx_v11_powerpc,
124     vmx_v12_powerpc,
125     vmx_v13_powerpc,
126     vmx_v14_powerpc,
127     vmx_v15_powerpc,
128     vmx_v16_powerpc,
129     vmx_v17_powerpc,
130     vmx_v18_powerpc,
131     vmx_v19_powerpc,
132     vmx_v20_powerpc,
133     vmx_v21_powerpc,
134     vmx_v22_powerpc,
135     vmx_v23_powerpc,
136     vmx_v24_powerpc,
137     vmx_v25_powerpc,
138     vmx_v26_powerpc,
139     vmx_v27_powerpc,
140     vmx_v28_powerpc,
141     vmx_v29_powerpc,
142     vmx_v30_powerpc,
143     vmx_v31_powerpc,
144     vmx_vrsave_powerpc,
145     vmx_vscr_powerpc,
146 };
147 
148 // Number of register sets provided by this context.
149 enum
150 {
151     k_num_register_sets = 3
152 };
153 
154 static const RegisterSet
155 g_reg_sets_powerpc[k_num_register_sets] =
156 {
157     { "General Purpose Registers",  "gpr", k_num_gpr_registers_powerpc, g_gpr_regnums },
158     { "Floating Point Registers",  "fpr", k_num_fpr_registers_powerpc, g_fpr_regnums },
159     { "Altivec/VMX Registers",  "vmx", k_num_vmx_registers_powerpc, g_vmx_regnums },
160 };
161 
162 bool RegisterContextPOSIX_powerpc::IsGPR(unsigned reg)
163 {
164     return reg <= k_num_gpr_registers_powerpc;   // GPR's come first.
165 }
166 
167 bool
168 RegisterContextPOSIX_powerpc::IsFPR(unsigned reg)
169 {
170     return (reg >= k_first_fpr) && (reg <= k_last_fpr);
171 }
172 
173 bool
174 RegisterContextPOSIX_powerpc::IsVMX(unsigned reg)
175 {
176     return (reg >= k_first_vmx) && (reg <= k_last_vmx);
177 }
178 
179 RegisterContextPOSIX_powerpc::RegisterContextPOSIX_powerpc(Thread &thread,
180                                                uint32_t concrete_frame_idx,
181                                                RegisterInfoInterface *register_info)
182     : RegisterContext(thread, concrete_frame_idx)
183 {
184     m_register_info_ap.reset(register_info);
185 
186     // elf-core yet to support ReadFPR()
187     ProcessSP base = CalculateProcess();
188     if (base.get()->GetPluginName() ==  ProcessElfCore::GetPluginNameStatic())
189         return;
190 }
191 
192 RegisterContextPOSIX_powerpc::~RegisterContextPOSIX_powerpc()
193 {
194 }
195 
196 void
197 RegisterContextPOSIX_powerpc::Invalidate()
198 {
199 }
200 
201 void
202 RegisterContextPOSIX_powerpc::InvalidateAllRegisters()
203 {
204 }
205 
206 unsigned
207 RegisterContextPOSIX_powerpc::GetRegisterOffset(unsigned reg)
208 {
209     assert(reg < k_num_registers_powerpc && "Invalid register number.");
210     return GetRegisterInfo()[reg].byte_offset;
211 }
212 
213 unsigned
214 RegisterContextPOSIX_powerpc::GetRegisterSize(unsigned reg)
215 {
216     assert(reg < k_num_registers_powerpc && "Invalid register number.");
217     return GetRegisterInfo()[reg].byte_size;
218 }
219 
220 size_t
221 RegisterContextPOSIX_powerpc::GetRegisterCount()
222 {
223     size_t num_registers = k_num_registers_powerpc;
224     return num_registers;
225 }
226 
227 size_t
228 RegisterContextPOSIX_powerpc::GetGPRSize()
229 {
230     return m_register_info_ap->GetGPRSize();
231 }
232 
233 const RegisterInfo *
234 RegisterContextPOSIX_powerpc::GetRegisterInfo()
235 {
236     // Commonly, this method is overridden and g_register_infos is copied and specialized.
237     // So, use GetRegisterInfo() rather than g_register_infos in this scope.
238     return m_register_info_ap->GetRegisterInfo ();
239 }
240 
241 const RegisterInfo *
242 RegisterContextPOSIX_powerpc::GetRegisterInfoAtIndex(size_t reg)
243 {
244     if (reg < k_num_registers_powerpc)
245         return &GetRegisterInfo()[reg];
246     else
247         return NULL;
248 }
249 
250 size_t
251 RegisterContextPOSIX_powerpc::GetRegisterSetCount()
252 {
253     size_t sets = 0;
254     for (size_t set = 0; set < k_num_register_sets; ++set)
255     {
256         if (IsRegisterSetAvailable(set))
257             ++sets;
258     }
259 
260     return sets;
261 }
262 
263 const RegisterSet *
264 RegisterContextPOSIX_powerpc::GetRegisterSet(size_t set)
265 {
266     if (IsRegisterSetAvailable(set))
267         return &g_reg_sets_powerpc[set];
268     else
269         return NULL;
270 }
271 
272 const char *
273 RegisterContextPOSIX_powerpc::GetRegisterName(unsigned reg)
274 {
275     assert(reg < k_num_registers_powerpc && "Invalid register offset.");
276     return GetRegisterInfo()[reg].name;
277 }
278 
279 lldb::ByteOrder
280 RegisterContextPOSIX_powerpc::GetByteOrder()
281 {
282     // Get the target process whose privileged thread was used for the register read.
283     lldb::ByteOrder byte_order = eByteOrderInvalid;
284     Process *process = CalculateProcess().get();
285 
286     if (process)
287         byte_order = process->GetByteOrder();
288     return byte_order;
289 }
290 
291 bool
292 RegisterContextPOSIX_powerpc::IsRegisterSetAvailable(size_t set_index)
293 {
294     size_t num_sets = k_num_register_sets;
295 
296     return (set_index < num_sets);
297 }
298 
299 // Used when parsing DWARF and EH frame information and any other
300 // object file sections that contain register numbers in them.
301 uint32_t
302 RegisterContextPOSIX_powerpc::ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
303                                                                  uint32_t num)
304 {
305     const uint32_t num_regs = GetRegisterCount();
306 
307     assert (kind < kNumRegisterKinds);
308     for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
309     {
310         const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg_idx);
311 
312         if (reg_info->kinds[kind] == num)
313             return reg_idx;
314     }
315 
316     return LLDB_INVALID_REGNUM;
317 }
318 
319