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 static_assert(k_first_gpr_powerpc == 0, "GPRs must index starting at 0, or fix IsGPR()");
163 bool RegisterContextPOSIX_powerpc::IsGPR(unsigned reg)
164 {
165     return (reg <= k_last_gpr_powerpc);   // GPR's come first.
166 }
167 
168 bool
169 RegisterContextPOSIX_powerpc::IsFPR(unsigned reg)
170 {
171     return (reg >= k_first_fpr) && (reg <= k_last_fpr);
172 }
173 
174 bool
175 RegisterContextPOSIX_powerpc::IsVMX(unsigned reg)
176 {
177     return (reg >= k_first_vmx) && (reg <= k_last_vmx);
178 }
179 
180 RegisterContextPOSIX_powerpc::RegisterContextPOSIX_powerpc(Thread &thread,
181                                                uint32_t concrete_frame_idx,
182                                                RegisterInfoInterface *register_info)
183     : RegisterContext(thread, concrete_frame_idx)
184 {
185     m_register_info_ap.reset(register_info);
186 
187     // elf-core yet to support ReadFPR()
188     ProcessSP base = CalculateProcess();
189     if (base.get()->GetPluginName() ==  ProcessElfCore::GetPluginNameStatic())
190         return;
191 }
192 
193 RegisterContextPOSIX_powerpc::~RegisterContextPOSIX_powerpc()
194 {
195 }
196 
197 void
198 RegisterContextPOSIX_powerpc::Invalidate()
199 {
200 }
201 
202 void
203 RegisterContextPOSIX_powerpc::InvalidateAllRegisters()
204 {
205 }
206 
207 unsigned
208 RegisterContextPOSIX_powerpc::GetRegisterOffset(unsigned reg)
209 {
210     assert(reg < k_num_registers_powerpc && "Invalid register number.");
211     return GetRegisterInfo()[reg].byte_offset;
212 }
213 
214 unsigned
215 RegisterContextPOSIX_powerpc::GetRegisterSize(unsigned reg)
216 {
217     assert(reg < k_num_registers_powerpc && "Invalid register number.");
218     return GetRegisterInfo()[reg].byte_size;
219 }
220 
221 size_t
222 RegisterContextPOSIX_powerpc::GetRegisterCount()
223 {
224     size_t num_registers = k_num_registers_powerpc;
225     return num_registers;
226 }
227 
228 size_t
229 RegisterContextPOSIX_powerpc::GetGPRSize()
230 {
231     return m_register_info_ap->GetGPRSize();
232 }
233 
234 const RegisterInfo *
235 RegisterContextPOSIX_powerpc::GetRegisterInfo()
236 {
237     // Commonly, this method is overridden and g_register_infos is copied and specialized.
238     // So, use GetRegisterInfo() rather than g_register_infos in this scope.
239     return m_register_info_ap->GetRegisterInfo ();
240 }
241 
242 const RegisterInfo *
243 RegisterContextPOSIX_powerpc::GetRegisterInfoAtIndex(size_t reg)
244 {
245     if (reg < k_num_registers_powerpc)
246         return &GetRegisterInfo()[reg];
247     else
248         return NULL;
249 }
250 
251 size_t
252 RegisterContextPOSIX_powerpc::GetRegisterSetCount()
253 {
254     size_t sets = 0;
255     for (size_t set = 0; set < k_num_register_sets; ++set)
256     {
257         if (IsRegisterSetAvailable(set))
258             ++sets;
259     }
260 
261     return sets;
262 }
263 
264 const RegisterSet *
265 RegisterContextPOSIX_powerpc::GetRegisterSet(size_t set)
266 {
267     if (IsRegisterSetAvailable(set))
268         return &g_reg_sets_powerpc[set];
269     else
270         return NULL;
271 }
272 
273 const char *
274 RegisterContextPOSIX_powerpc::GetRegisterName(unsigned reg)
275 {
276     assert(reg < k_num_registers_powerpc && "Invalid register offset.");
277     return GetRegisterInfo()[reg].name;
278 }
279 
280 lldb::ByteOrder
281 RegisterContextPOSIX_powerpc::GetByteOrder()
282 {
283     // Get the target process whose privileged thread was used for the register read.
284     lldb::ByteOrder byte_order = eByteOrderInvalid;
285     Process *process = CalculateProcess().get();
286 
287     if (process)
288         byte_order = process->GetByteOrder();
289     return byte_order;
290 }
291 
292 bool
293 RegisterContextPOSIX_powerpc::IsRegisterSetAvailable(size_t set_index)
294 {
295     size_t num_sets = k_num_register_sets;
296 
297     return (set_index < num_sets);
298 }
299 
300 // Used when parsing DWARF and EH frame information and any other
301 // object file sections that contain register numbers in them.
302 uint32_t
303 RegisterContextPOSIX_powerpc::ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
304                                                                  uint32_t num)
305 {
306     const uint32_t num_regs = GetRegisterCount();
307 
308     assert (kind < kNumRegisterKinds);
309     for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
310     {
311         const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg_idx);
312 
313         if (reg_info->kinds[kind] == num)
314             return reg_idx;
315     }
316 
317     return LLDB_INVALID_REGNUM;
318 }
319 
320