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 // Number of register sets provided by this context.
110 enum
111 {
112     k_num_register_sets = 2
113 };
114 
115 static const RegisterSet
116 g_reg_sets_powerpc[k_num_register_sets] =
117 {
118     { "General Purpose Registers",  "gpr", k_num_gpr_registers_powerpc, g_gpr_regnums },
119     { "Floating Point Registers",  "fpr", k_num_fpr_registers_powerpc, g_fpr_regnums },
120 };
121 
122 bool RegisterContextPOSIX_powerpc::IsGPR(unsigned reg)
123 {
124     return reg <= k_num_gpr_registers_powerpc;   // GPR's come first.
125 }
126 
127 bool
128 RegisterContextPOSIX_powerpc::IsFPR(unsigned reg)
129 {
130     // XXX
131     return (reg >= k_first_fpr) && (reg <= k_last_fpr);
132 }
133 
134 RegisterContextPOSIX_powerpc::RegisterContextPOSIX_powerpc(Thread &thread,
135                                                uint32_t concrete_frame_idx,
136                                                RegisterInfoInterface *register_info)
137     : RegisterContext(thread, concrete_frame_idx)
138 {
139     m_register_info_ap.reset(register_info);
140 
141     // elf-core yet to support ReadFPR()
142     ProcessSP base = CalculateProcess();
143     if (base.get()->GetPluginName() ==  ProcessElfCore::GetPluginNameStatic())
144         return;
145 }
146 
147 RegisterContextPOSIX_powerpc::~RegisterContextPOSIX_powerpc()
148 {
149 }
150 
151 void
152 RegisterContextPOSIX_powerpc::Invalidate()
153 {
154 }
155 
156 void
157 RegisterContextPOSIX_powerpc::InvalidateAllRegisters()
158 {
159 }
160 
161 unsigned
162 RegisterContextPOSIX_powerpc::GetRegisterOffset(unsigned reg)
163 {
164     assert(reg < k_num_registers_powerpc && "Invalid register number.");
165     return GetRegisterInfo()[reg].byte_offset;
166 }
167 
168 unsigned
169 RegisterContextPOSIX_powerpc::GetRegisterSize(unsigned reg)
170 {
171     assert(reg < k_num_registers_powerpc && "Invalid register number.");
172     return GetRegisterInfo()[reg].byte_size;
173 }
174 
175 size_t
176 RegisterContextPOSIX_powerpc::GetRegisterCount()
177 {
178     size_t num_registers = k_num_registers_powerpc;
179     return num_registers;
180 }
181 
182 size_t
183 RegisterContextPOSIX_powerpc::GetGPRSize()
184 {
185     return m_register_info_ap->GetGPRSize();
186 }
187 
188 const RegisterInfo *
189 RegisterContextPOSIX_powerpc::GetRegisterInfo()
190 {
191     // Commonly, this method is overridden and g_register_infos is copied and specialized.
192     // So, use GetRegisterInfo() rather than g_register_infos in this scope.
193     return m_register_info_ap->GetRegisterInfo ();
194 }
195 
196 const RegisterInfo *
197 RegisterContextPOSIX_powerpc::GetRegisterInfoAtIndex(size_t reg)
198 {
199     if (reg < k_num_registers_powerpc)
200         return &GetRegisterInfo()[reg];
201     else
202         return NULL;
203 }
204 
205 size_t
206 RegisterContextPOSIX_powerpc::GetRegisterSetCount()
207 {
208     size_t sets = 0;
209     for (size_t set = 0; set < k_num_register_sets; ++set)
210     {
211         if (IsRegisterSetAvailable(set))
212             ++sets;
213     }
214 
215     return sets;
216 }
217 
218 const RegisterSet *
219 RegisterContextPOSIX_powerpc::GetRegisterSet(size_t set)
220 {
221     if (IsRegisterSetAvailable(set))
222         return &g_reg_sets_powerpc[set];
223     else
224         return NULL;
225 }
226 
227 const char *
228 RegisterContextPOSIX_powerpc::GetRegisterName(unsigned reg)
229 {
230     assert(reg < k_num_registers_powerpc && "Invalid register offset.");
231     return GetRegisterInfo()[reg].name;
232 }
233 
234 lldb::ByteOrder
235 RegisterContextPOSIX_powerpc::GetByteOrder()
236 {
237     // Get the target process whose privileged thread was used for the register read.
238     lldb::ByteOrder byte_order = eByteOrderInvalid;
239     Process *process = CalculateProcess().get();
240 
241     if (process)
242         byte_order = process->GetByteOrder();
243     return byte_order;
244 }
245 
246 bool
247 RegisterContextPOSIX_powerpc::IsRegisterSetAvailable(size_t set_index)
248 {
249     size_t num_sets = k_num_register_sets;
250 
251     return (set_index < num_sets);
252 }
253 
254 // Used when parsing DWARF and EH frame information and any other
255 // object file sections that contain register numbers in them.
256 uint32_t
257 RegisterContextPOSIX_powerpc::ConvertRegisterKindToRegisterNumber(lldb::RegisterKind kind,
258                                                                  uint32_t num)
259 {
260     const uint32_t num_regs = GetRegisterCount();
261 
262     assert (kind < kNumRegisterKinds);
263     for (uint32_t reg_idx = 0; reg_idx < num_regs; ++reg_idx)
264     {
265         const RegisterInfo *reg_info = GetRegisterInfoAtIndex (reg_idx);
266 
267         if (reg_info->kinds[kind] == num)
268             return reg_idx;
269     }
270 
271     return LLDB_INVALID_REGNUM;
272 }
273 
274