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