1 //===-- DNBArchImpl.cpp -----------------------------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Created by Greg Clayton on 6/25/07.
10 //
11 //===----------------------------------------------------------------------===//
12
13 #if defined(__powerpc__) || defined(__ppc__) || defined(__ppc64__)
14
15 #if __DARWIN_UNIX03
16 #define PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(reg) __##reg
17 #else
18 #define PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(reg) reg
19 #endif
20
21 #include "MacOSX/ppc/DNBArchImpl.h"
22 #include "DNBBreakpoint.h"
23 #include "DNBLog.h"
24 #include "DNBRegisterInfo.h"
25 #include "MacOSX/MachThread.h"
26
27 static const uint8_t g_breakpoint_opcode[] = {0x7F, 0xC0, 0x00, 0x08};
28
SoftwareBreakpointOpcode(nub_size_t size)29 const uint8_t *DNBArchMachPPC::SoftwareBreakpointOpcode(nub_size_t size) {
30 if (size == 4)
31 return g_breakpoint_opcode;
32 return NULL;
33 }
34
GetCPUType()35 uint32_t DNBArchMachPPC::GetCPUType() { return CPU_TYPE_POWERPC; }
36
GetPC(uint64_t failValue)37 uint64_t DNBArchMachPPC::GetPC(uint64_t failValue) {
38 // Get program counter
39 if (GetGPRState(false) == KERN_SUCCESS)
40 return m_state.gpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(srr0);
41 return failValue;
42 }
43
SetPC(uint64_t value)44 kern_return_t DNBArchMachPPC::SetPC(uint64_t value) {
45 // Get program counter
46 kern_return_t err = GetGPRState(false);
47 if (err == KERN_SUCCESS) {
48 m_state.gpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(srr0) = value;
49 err = SetGPRState();
50 }
51 return err == KERN_SUCCESS;
52 }
53
GetSP(uint64_t failValue)54 uint64_t DNBArchMachPPC::GetSP(uint64_t failValue) {
55 // Get stack pointer
56 if (GetGPRState(false) == KERN_SUCCESS)
57 return m_state.gpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(r1);
58 return failValue;
59 }
60
GetGPRState(bool force)61 kern_return_t DNBArchMachPPC::GetGPRState(bool force) {
62 if (force || m_state.GetError(e_regSetGPR, Read)) {
63 mach_msg_type_number_t count = e_regSetWordSizeGPR;
64 m_state.SetError(e_regSetGPR, Read,
65 ::thread_get_state(m_thread->MachPortNumber(), e_regSetGPR,
66 (thread_state_t)&m_state.gpr, &count));
67 }
68 return m_state.GetError(e_regSetGPR, Read);
69 }
70
GetFPRState(bool force)71 kern_return_t DNBArchMachPPC::GetFPRState(bool force) {
72 if (force || m_state.GetError(e_regSetFPR, Read)) {
73 mach_msg_type_number_t count = e_regSetWordSizeFPR;
74 m_state.SetError(e_regSetFPR, Read,
75 ::thread_get_state(m_thread->MachPortNumber(), e_regSetFPR,
76 (thread_state_t)&m_state.fpr, &count));
77 }
78 return m_state.GetError(e_regSetFPR, Read);
79 }
80
GetEXCState(bool force)81 kern_return_t DNBArchMachPPC::GetEXCState(bool force) {
82 if (force || m_state.GetError(e_regSetEXC, Read)) {
83 mach_msg_type_number_t count = e_regSetWordSizeEXC;
84 m_state.SetError(e_regSetEXC, Read,
85 ::thread_get_state(m_thread->MachPortNumber(), e_regSetEXC,
86 (thread_state_t)&m_state.exc, &count));
87 }
88 return m_state.GetError(e_regSetEXC, Read);
89 }
90
GetVECState(bool force)91 kern_return_t DNBArchMachPPC::GetVECState(bool force) {
92 if (force || m_state.GetError(e_regSetVEC, Read)) {
93 mach_msg_type_number_t count = e_regSetWordSizeVEC;
94 m_state.SetError(e_regSetVEC, Read,
95 ::thread_get_state(m_thread->MachPortNumber(), e_regSetVEC,
96 (thread_state_t)&m_state.vec, &count));
97 }
98 return m_state.GetError(e_regSetVEC, Read);
99 }
100
SetGPRState()101 kern_return_t DNBArchMachPPC::SetGPRState() {
102 m_state.SetError(e_regSetGPR, Write,
103 ::thread_set_state(m_thread->MachPortNumber(), e_regSetGPR,
104 (thread_state_t)&m_state.gpr,
105 e_regSetWordSizeGPR));
106 return m_state.GetError(e_regSetGPR, Write);
107 }
108
SetFPRState()109 kern_return_t DNBArchMachPPC::SetFPRState() {
110 m_state.SetError(e_regSetFPR, Write,
111 ::thread_set_state(m_thread->MachPortNumber(), e_regSetFPR,
112 (thread_state_t)&m_state.fpr,
113 e_regSetWordSizeFPR));
114 return m_state.GetError(e_regSetFPR, Write);
115 }
116
SetEXCState()117 kern_return_t DNBArchMachPPC::SetEXCState() {
118 m_state.SetError(e_regSetEXC, Write,
119 ::thread_set_state(m_thread->MachPortNumber(), e_regSetEXC,
120 (thread_state_t)&m_state.exc,
121 e_regSetWordSizeEXC));
122 return m_state.GetError(e_regSetEXC, Write);
123 }
124
SetVECState()125 kern_return_t DNBArchMachPPC::SetVECState() {
126 m_state.SetError(e_regSetVEC, Write,
127 ::thread_set_state(m_thread->MachPortNumber(), e_regSetVEC,
128 (thread_state_t)&m_state.vec,
129 e_regSetWordSizeVEC));
130 return m_state.GetError(e_regSetVEC, Write);
131 }
132
ThreadWillResume()133 bool DNBArchMachPPC::ThreadWillResume() {
134 bool success = true;
135
136 // Do we need to step this thread? If so, let the mach thread tell us so.
137 if (m_thread->IsStepping()) {
138 // This is the primary thread, let the arch do anything it needs
139 success = EnableHardwareSingleStep(true) == KERN_SUCCESS;
140 }
141 return success;
142 }
143
ThreadDidStop()144 bool DNBArchMachPPC::ThreadDidStop() {
145 bool success = true;
146
147 m_state.InvalidateAllRegisterStates();
148
149 // Are we stepping a single instruction?
150 if (GetGPRState(true) == KERN_SUCCESS) {
151 // We are single stepping, was this the primary thread?
152 if (m_thread->IsStepping()) {
153 // This was the primary thread, we need to clear the trace
154 // bit if so.
155 success = EnableHardwareSingleStep(false) == KERN_SUCCESS;
156 } else {
157 // The MachThread will automatically restore the suspend count
158 // in ThreadDidStop(), so we don't need to do anything here if
159 // we weren't the primary thread the last time
160 }
161 }
162 return success;
163 }
164
165 // Set the single step bit in the processor status register.
EnableHardwareSingleStep(bool enable)166 kern_return_t DNBArchMachPPC::EnableHardwareSingleStep(bool enable) {
167 DNBLogThreadedIf(LOG_STEP,
168 "DNBArchMachPPC::EnableHardwareSingleStep( enable = %d )",
169 enable);
170 if (GetGPRState(false) == KERN_SUCCESS) {
171 const uint32_t trace_bit = 0x400;
172 if (enable)
173 m_state.gpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(srr1) |= trace_bit;
174 else
175 m_state.gpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(srr1) &= ~trace_bit;
176 return SetGPRState();
177 }
178 return m_state.GetError(e_regSetGPR, Read);
179 }
180
181 // Register information definitions for 32 bit PowerPC.
182
183 enum gpr_regnums {
184 e_regNumGPR_srr0,
185 e_regNumGPR_srr1,
186 e_regNumGPR_r0,
187 e_regNumGPR_r1,
188 e_regNumGPR_r2,
189 e_regNumGPR_r3,
190 e_regNumGPR_r4,
191 e_regNumGPR_r5,
192 e_regNumGPR_r6,
193 e_regNumGPR_r7,
194 e_regNumGPR_r8,
195 e_regNumGPR_r9,
196 e_regNumGPR_r10,
197 e_regNumGPR_r11,
198 e_regNumGPR_r12,
199 e_regNumGPR_r13,
200 e_regNumGPR_r14,
201 e_regNumGPR_r15,
202 e_regNumGPR_r16,
203 e_regNumGPR_r17,
204 e_regNumGPR_r18,
205 e_regNumGPR_r19,
206 e_regNumGPR_r20,
207 e_regNumGPR_r21,
208 e_regNumGPR_r22,
209 e_regNumGPR_r23,
210 e_regNumGPR_r24,
211 e_regNumGPR_r25,
212 e_regNumGPR_r26,
213 e_regNumGPR_r27,
214 e_regNumGPR_r28,
215 e_regNumGPR_r29,
216 e_regNumGPR_r30,
217 e_regNumGPR_r31,
218 e_regNumGPR_cr,
219 e_regNumGPR_xer,
220 e_regNumGPR_lr,
221 e_regNumGPR_ctr,
222 e_regNumGPR_mq,
223 e_regNumGPR_vrsave
224 };
225
226 // General purpose registers
227 static DNBRegisterInfo g_gpr_registers[] = {
228 {"srr0", Uint, 4, Hex}, {"srr1", Uint, 4, Hex}, {"r0", Uint, 4, Hex},
229 {"r1", Uint, 4, Hex}, {"r2", Uint, 4, Hex}, {"r3", Uint, 4, Hex},
230 {"r4", Uint, 4, Hex}, {"r5", Uint, 4, Hex}, {"r6", Uint, 4, Hex},
231 {"r7", Uint, 4, Hex}, {"r8", Uint, 4, Hex}, {"r9", Uint, 4, Hex},
232 {"r10", Uint, 4, Hex}, {"r11", Uint, 4, Hex}, {"r12", Uint, 4, Hex},
233 {"r13", Uint, 4, Hex}, {"r14", Uint, 4, Hex}, {"r15", Uint, 4, Hex},
234 {"r16", Uint, 4, Hex}, {"r17", Uint, 4, Hex}, {"r18", Uint, 4, Hex},
235 {"r19", Uint, 4, Hex}, {"r20", Uint, 4, Hex}, {"r21", Uint, 4, Hex},
236 {"r22", Uint, 4, Hex}, {"r23", Uint, 4, Hex}, {"r24", Uint, 4, Hex},
237 {"r25", Uint, 4, Hex}, {"r26", Uint, 4, Hex}, {"r27", Uint, 4, Hex},
238 {"r28", Uint, 4, Hex}, {"r29", Uint, 4, Hex}, {"r30", Uint, 4, Hex},
239 {"r31", Uint, 4, Hex}, {"cr", Uint, 4, Hex}, {"xer", Uint, 4, Hex},
240 {"lr", Uint, 4, Hex}, {"ctr", Uint, 4, Hex}, {"mq", Uint, 4, Hex},
241 {"vrsave", Uint, 4, Hex},
242 };
243
244 // Floating point registers
245 static DNBRegisterInfo g_fpr_registers[] = {
246 {"fp0", IEEE754, 8, Float}, {"fp1", IEEE754, 8, Float},
247 {"fp2", IEEE754, 8, Float}, {"fp3", IEEE754, 8, Float},
248 {"fp4", IEEE754, 8, Float}, {"fp5", IEEE754, 8, Float},
249 {"fp6", IEEE754, 8, Float}, {"fp7", IEEE754, 8, Float},
250 {"fp8", IEEE754, 8, Float}, {"fp9", IEEE754, 8, Float},
251 {"fp10", IEEE754, 8, Float}, {"fp11", IEEE754, 8, Float},
252 {"fp12", IEEE754, 8, Float}, {"fp13", IEEE754, 8, Float},
253 {"fp14", IEEE754, 8, Float}, {"fp15", IEEE754, 8, Float},
254 {"fp16", IEEE754, 8, Float}, {"fp17", IEEE754, 8, Float},
255 {"fp18", IEEE754, 8, Float}, {"fp19", IEEE754, 8, Float},
256 {"fp20", IEEE754, 8, Float}, {"fp21", IEEE754, 8, Float},
257 {"fp22", IEEE754, 8, Float}, {"fp23", IEEE754, 8, Float},
258 {"fp24", IEEE754, 8, Float}, {"fp25", IEEE754, 8, Float},
259 {"fp26", IEEE754, 8, Float}, {"fp27", IEEE754, 8, Float},
260 {"fp28", IEEE754, 8, Float}, {"fp29", IEEE754, 8, Float},
261 {"fp30", IEEE754, 8, Float}, {"fp31", IEEE754, 8, Float},
262 {"fpscr", Uint, 4, Hex}};
263
264 // Exception registers
265
266 static DNBRegisterInfo g_exc_registers[] = {{"dar", Uint, 4, Hex},
267 {"dsisr", Uint, 4, Hex},
268 {"exception", Uint, 4, Hex}};
269
270 // Altivec registers
271 static DNBRegisterInfo g_vec_registers[] = {
272 {"vr0", Vector, 16, VectorOfFloat32},
273 {"vr1", Vector, 16, VectorOfFloat32},
274 {"vr2", Vector, 16, VectorOfFloat32},
275 {"vr3", Vector, 16, VectorOfFloat32},
276 {"vr4", Vector, 16, VectorOfFloat32},
277 {"vr5", Vector, 16, VectorOfFloat32},
278 {"vr6", Vector, 16, VectorOfFloat32},
279 {"vr7", Vector, 16, VectorOfFloat32},
280 {"vr8", Vector, 16, VectorOfFloat32},
281 {"vr9", Vector, 16, VectorOfFloat32},
282 {"vr10", Vector, 16, VectorOfFloat32},
283 {"vr11", Vector, 16, VectorOfFloat32},
284 {"vr12", Vector, 16, VectorOfFloat32},
285 {"vr13", Vector, 16, VectorOfFloat32},
286 {"vr14", Vector, 16, VectorOfFloat32},
287 {"vr15", Vector, 16, VectorOfFloat32},
288 {"vr16", Vector, 16, VectorOfFloat32},
289 {"vr17", Vector, 16, VectorOfFloat32},
290 {"vr18", Vector, 16, VectorOfFloat32},
291 {"vr19", Vector, 16, VectorOfFloat32},
292 {"vr20", Vector, 16, VectorOfFloat32},
293 {"vr21", Vector, 16, VectorOfFloat32},
294 {"vr22", Vector, 16, VectorOfFloat32},
295 {"vr23", Vector, 16, VectorOfFloat32},
296 {"vr24", Vector, 16, VectorOfFloat32},
297 {"vr25", Vector, 16, VectorOfFloat32},
298 {"vr26", Vector, 16, VectorOfFloat32},
299 {"vr27", Vector, 16, VectorOfFloat32},
300 {"vr28", Vector, 16, VectorOfFloat32},
301 {"vr29", Vector, 16, VectorOfFloat32},
302 {"vr30", Vector, 16, VectorOfFloat32},
303 {"vr31", Vector, 16, VectorOfFloat32},
304 {"vscr", Uint, 16, Hex},
305 {"vrvalid", Uint, 4, Hex}};
306
307 // Number of registers in each register set
308 const size_t k_num_gpr_registers =
309 sizeof(g_gpr_registers) / sizeof(DNBRegisterInfo);
310 const size_t k_num_fpr_registers =
311 sizeof(g_fpr_registers) / sizeof(DNBRegisterInfo);
312 const size_t k_num_exc_registers =
313 sizeof(g_exc_registers) / sizeof(DNBRegisterInfo);
314 const size_t k_num_vec_registers =
315 sizeof(g_vec_registers) / sizeof(DNBRegisterInfo);
316 // Total number of registers for this architecture
317 const size_t k_num_ppc_registers = k_num_gpr_registers + k_num_fpr_registers +
318 k_num_exc_registers + k_num_vec_registers;
319
320 // Register set definitions. The first definitions at register set index
321 // of zero is for all registers, followed by other registers sets. The
322 // register information for the all register set need not be filled in.
323 static const DNBRegisterSetInfo g_reg_sets[] = {
324 {"PowerPC Registers", NULL, k_num_ppc_registers},
325 {"General Purpose Registers", g_gpr_registers, k_num_gpr_registers},
326 {"Floating Point Registers", g_fpr_registers, k_num_fpr_registers},
327 {"Exception State Registers", g_exc_registers, k_num_exc_registers},
328 {"Altivec Registers", g_vec_registers, k_num_vec_registers}};
329 // Total number of register sets for this architecture
330 const size_t k_num_register_sets =
331 sizeof(g_reg_sets) / sizeof(DNBRegisterSetInfo);
332
333 const DNBRegisterSetInfo *
GetRegisterSetInfo(nub_size_t * num_reg_sets) const334 DNBArchMachPPC::GetRegisterSetInfo(nub_size_t *num_reg_sets) const {
335 *num_reg_sets = k_num_register_sets;
336 return g_reg_sets;
337 }
338
GetRegisterValue(uint32_t set,uint32_t reg,DNBRegisterValue * value) const339 bool DNBArchMachPPC::GetRegisterValue(uint32_t set, uint32_t reg,
340 DNBRegisterValue *value) const {
341 if (set == REGISTER_SET_GENERIC) {
342 switch (reg) {
343 case GENERIC_REGNUM_PC: // Program Counter
344 set = e_regSetGPR;
345 reg = e_regNumGPR_srr0;
346 break;
347
348 case GENERIC_REGNUM_SP: // Stack Pointer
349 set = e_regSetGPR;
350 reg = e_regNumGPR_r1;
351 break;
352
353 case GENERIC_REGNUM_FP: // Frame Pointer
354 // Return false for now instead of returning r30 as gcc 3.x would
355 // use a variety of registers for the FP and it takes inspecting
356 // the stack to make sure there is a frame pointer before we can
357 // determine the FP.
358 return false;
359
360 case GENERIC_REGNUM_RA: // Return Address
361 set = e_regSetGPR;
362 reg = e_regNumGPR_lr;
363 break;
364
365 case GENERIC_REGNUM_FLAGS: // Processor flags register
366 set = e_regSetGPR;
367 reg = e_regNumGPR_srr1;
368 break;
369
370 default:
371 return false;
372 }
373 }
374
375 if (!m_state.RegsAreValid(set))
376 return false;
377
378 const DNBRegisterInfo *regInfo = m_thread->GetRegisterInfo(set, reg);
379 if (regInfo) {
380 value->info = *regInfo;
381 switch (set) {
382 case e_regSetGPR:
383 if (reg < k_num_gpr_registers) {
384 value->value.uint32 =
385 (&m_state.gpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(srr0))[reg];
386 return true;
387 }
388 break;
389
390 case e_regSetFPR:
391 if (reg < 32) {
392 value->value.float64 =
393 m_state.fpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(fpregs)[reg];
394 return true;
395 } else if (reg == 32) {
396 value->value.uint32 =
397 m_state.fpr.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(fpscr);
398 return true;
399 }
400 break;
401
402 case e_regSetEXC:
403 if (reg < k_num_exc_registers) {
404 value->value.uint32 =
405 (&m_state.exc.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(dar))[reg];
406 return true;
407 }
408 break;
409
410 case e_regSetVEC:
411 if (reg < k_num_vec_registers) {
412 if (reg < 33) // FP0 - FP31 and VSCR
413 {
414 // Copy all 4 uint32 values for this vector register
415 value->value.v_uint32[0] =
416 m_state.vec.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(save_vr)[reg]
417 [0];
418 value->value.v_uint32[1] =
419 m_state.vec.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(save_vr)[reg]
420 [1];
421 value->value.v_uint32[2] =
422 m_state.vec.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(save_vr)[reg]
423 [2];
424 value->value.v_uint32[3] =
425 m_state.vec.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(save_vr)[reg]
426 [3];
427 return true;
428 } else if (reg == 34) // VRVALID
429 {
430 value->value.uint32 =
431 m_state.vec.PREFIX_DOUBLE_UNDERSCORE_DARWIN_UNIX03(save_vrvalid);
432 return true;
433 }
434 }
435 break;
436 }
437 }
438 return false;
439 }
440
GetRegisterState(int set,bool force)441 kern_return_t DNBArchMachPPC::GetRegisterState(int set, bool force) {
442 switch (set) {
443 case e_regSetALL:
444 return GetGPRState(force) | GetFPRState(force) | GetEXCState(force) |
445 GetVECState(force);
446 case e_regSetGPR:
447 return GetGPRState(force);
448 case e_regSetFPR:
449 return GetFPRState(force);
450 case e_regSetEXC:
451 return GetEXCState(force);
452 case e_regSetVEC:
453 return GetVECState(force);
454 default:
455 break;
456 }
457 return KERN_INVALID_ARGUMENT;
458 }
459
SetRegisterState(int set)460 kern_return_t DNBArchMachPPC::SetRegisterState(int set) {
461 // Make sure we have a valid context to set.
462 kern_return_t err = GetRegisterState(set, false);
463 if (err != KERN_SUCCESS)
464 return err;
465
466 switch (set) {
467 case e_regSetALL:
468 return SetGPRState() | SetFPRState() | SetEXCState() | SetVECState();
469 case e_regSetGPR:
470 return SetGPRState();
471 case e_regSetFPR:
472 return SetFPRState();
473 case e_regSetEXC:
474 return SetEXCState();
475 case e_regSetVEC:
476 return SetVECState();
477 default:
478 break;
479 }
480 return KERN_INVALID_ARGUMENT;
481 }
482
RegisterSetStateIsValid(int set) const483 bool DNBArchMachPPC::RegisterSetStateIsValid(int set) const {
484 return m_state.RegsAreValid(set);
485 }
486
487 #endif // #if defined (__powerpc__) || defined (__ppc__) || defined (__ppc64__)
488