]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Plugins/Instruction/PPC64/EmulateInstructionPPC64.cpp
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Plugins / Instruction / PPC64 / EmulateInstructionPPC64.cpp
1 //===-- EmulateInstructionPPC64.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 "EmulateInstructionPPC64.h"
11
12 #include <stdlib.h>
13
14 #include "lldb/Core/PluginManager.h"
15 #include "lldb/Symbol/UnwindPlan.h"
16 #include "lldb/Utility/ArchSpec.h"
17 #include "lldb/Utility/ConstString.h"
18
19 #include "Plugins/Process/Utility/lldb-ppc64le-register-enums.h"
20
21 #define DECLARE_REGISTER_INFOS_PPC64LE_STRUCT
22 #include "Plugins/Process/Utility/RegisterInfos_ppc64le.h"
23
24 #include "Plugins/Process/Utility/InstructionUtils.h"
25
26 using namespace lldb;
27 using namespace lldb_private;
28
29 EmulateInstructionPPC64::EmulateInstructionPPC64(const ArchSpec &arch)
30     : EmulateInstruction(arch) {}
31
32 void EmulateInstructionPPC64::Initialize() {
33   PluginManager::RegisterPlugin(GetPluginNameStatic(),
34                                 GetPluginDescriptionStatic(), CreateInstance);
35 }
36
37 void EmulateInstructionPPC64::Terminate() {
38   PluginManager::UnregisterPlugin(CreateInstance);
39 }
40
41 ConstString EmulateInstructionPPC64::GetPluginNameStatic() {
42   ConstString g_plugin_name("lldb.emulate-instruction.ppc64");
43   return g_plugin_name;
44 }
45
46 ConstString EmulateInstructionPPC64::GetPluginName() {
47   static ConstString g_plugin_name("EmulateInstructionPPC64");
48   return g_plugin_name;
49 }
50
51 const char *EmulateInstructionPPC64::GetPluginDescriptionStatic() {
52   return "Emulate instructions for the PPC64 architecture.";
53 }
54
55 EmulateInstruction *
56 EmulateInstructionPPC64::CreateInstance(const ArchSpec &arch,
57                                         InstructionType inst_type) {
58   if (EmulateInstructionPPC64::SupportsEmulatingInstructionsOfTypeStatic(
59           inst_type)) {
60     if (arch.GetTriple().getArch() == llvm::Triple::ppc64 ||
61         arch.GetTriple().getArch() == llvm::Triple::ppc64le) {
62       return new EmulateInstructionPPC64(arch);
63     }
64   }
65
66   return nullptr;
67 }
68
69 bool EmulateInstructionPPC64::SetTargetTriple(const ArchSpec &arch) {
70   if (arch.GetTriple().getArch() == llvm::Triple::ppc64)
71     return true;
72   else if (arch.GetTriple().getArch() == llvm::Triple::ppc64le)
73     return true;
74
75   return false;
76 }
77
78 static bool LLDBTableGetRegisterInfo(uint32_t reg_num, RegisterInfo &reg_info) {
79   if (reg_num >= llvm::array_lengthof(g_register_infos_ppc64le))
80     return false;
81   reg_info = g_register_infos_ppc64le[reg_num];
82   return true;
83 }
84
85 bool EmulateInstructionPPC64::GetRegisterInfo(RegisterKind reg_kind,
86                                               uint32_t reg_num,
87                                               RegisterInfo &reg_info) {
88   if (reg_kind == eRegisterKindGeneric) {
89     switch (reg_num) {
90     case LLDB_REGNUM_GENERIC_PC:
91       reg_kind = eRegisterKindLLDB;
92       reg_num = gpr_pc_ppc64le;
93       break;
94     case LLDB_REGNUM_GENERIC_SP:
95       reg_kind = eRegisterKindLLDB;
96       reg_num = gpr_r1_ppc64le;
97       break;
98     case LLDB_REGNUM_GENERIC_RA:
99       reg_kind = eRegisterKindLLDB;
100       reg_num = gpr_lr_ppc64le;
101       break;
102     case LLDB_REGNUM_GENERIC_FLAGS:
103       reg_kind = eRegisterKindLLDB;
104       reg_num = gpr_cr_ppc64le;
105       break;
106
107     default:
108       return false;
109     }
110   }
111
112   if (reg_kind == eRegisterKindLLDB)
113     return LLDBTableGetRegisterInfo(reg_num, reg_info);
114   return false;
115 }
116
117 bool EmulateInstructionPPC64::ReadInstruction() {
118   bool success = false;
119   m_addr = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
120                                 LLDB_INVALID_ADDRESS, &success);
121   if (success) {
122     Context ctx;
123     ctx.type = eContextReadOpcode;
124     ctx.SetNoArgs();
125     m_opcode.SetOpcode32(ReadMemoryUnsigned(ctx, m_addr, 4, 0, &success),
126                          GetByteOrder());
127   }
128   if (!success)
129     m_addr = LLDB_INVALID_ADDRESS;
130   return success;
131 }
132
133 bool EmulateInstructionPPC64::CreateFunctionEntryUnwind(
134     UnwindPlan &unwind_plan) {
135   unwind_plan.Clear();
136   unwind_plan.SetRegisterKind(eRegisterKindLLDB);
137
138   UnwindPlan::RowSP row(new UnwindPlan::Row);
139
140   // Our previous Call Frame Address is the stack pointer
141   row->GetCFAValue().SetIsRegisterPlusOffset(gpr_r1_ppc64le, 0);
142
143   unwind_plan.AppendRow(row);
144   unwind_plan.SetSourceName("EmulateInstructionPPC64");
145   unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
146   unwind_plan.SetUnwindPlanValidAtAllInstructions(eLazyBoolYes);
147   unwind_plan.SetReturnAddressRegister(gpr_lr_ppc64le);
148   return true;
149 }
150
151 EmulateInstructionPPC64::Opcode *
152 EmulateInstructionPPC64::GetOpcodeForInstruction(uint32_t opcode) {
153   static EmulateInstructionPPC64::Opcode g_opcodes[] = {
154       {0xfc0007ff, 0x7c0002a6, &EmulateInstructionPPC64::EmulateMFSPR,
155        "mfspr RT, SPR"},
156       {0xfc000003, 0xf8000000, &EmulateInstructionPPC64::EmulateSTD,
157        "std RS, DS(RA)"},
158       {0xfc000003, 0xf8000001, &EmulateInstructionPPC64::EmulateSTD,
159        "stdu RS, DS(RA)"},
160       {0xfc0007fe, 0x7c000378, &EmulateInstructionPPC64::EmulateOR,
161        "or RA, RS, RB"},
162       {0xfc000000, 0x38000000, &EmulateInstructionPPC64::EmulateADDI,
163        "addi RT, RA, SI"},
164       {0xfc000003, 0xe8000000, &EmulateInstructionPPC64::EmulateLD,
165        "ld RT, DS(RA)"}};
166   static const size_t k_num_ppc_opcodes = llvm::array_lengthof(g_opcodes);
167
168   for (size_t i = 0; i < k_num_ppc_opcodes; ++i) {
169     if ((g_opcodes[i].mask & opcode) == g_opcodes[i].value)
170       return &g_opcodes[i];
171   }
172   return nullptr;
173 }
174
175 bool EmulateInstructionPPC64::EvaluateInstruction(uint32_t evaluate_options) {
176   const uint32_t opcode = m_opcode.GetOpcode32();
177   // LLDB_LOG(log, "PPC64::EvaluateInstruction: opcode={0:X+8}", opcode);
178   Opcode *opcode_data = GetOpcodeForInstruction(opcode);
179   if (!opcode_data)
180     return false;
181
182   // LLDB_LOG(log, "PPC64::EvaluateInstruction: {0}", opcode_data->name);
183   const bool auto_advance_pc =
184       evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
185
186   bool success = false;
187
188   uint32_t orig_pc_value = 0;
189   if (auto_advance_pc) {
190     orig_pc_value =
191         ReadRegisterUnsigned(eRegisterKindLLDB, gpr_pc_ppc64le, 0, &success);
192     if (!success)
193       return false;
194   }
195
196   // Call the Emulate... function.
197   success = (this->*opcode_data->callback)(opcode);
198   if (!success)
199     return false;
200
201   if (auto_advance_pc) {
202     uint32_t new_pc_value =
203         ReadRegisterUnsigned(eRegisterKindLLDB, gpr_pc_ppc64le, 0, &success);
204     if (!success)
205       return false;
206
207     if (auto_advance_pc && (new_pc_value == orig_pc_value)) {
208       EmulateInstruction::Context context;
209       context.type = eContextAdvancePC;
210       context.SetNoArgs();
211       if (!WriteRegisterUnsigned(context, eRegisterKindLLDB, gpr_pc_ppc64le,
212                                  orig_pc_value + 4))
213         return false;
214     }
215   }
216   return true;
217 }
218
219 bool EmulateInstructionPPC64::EmulateMFSPR(uint32_t opcode) {
220   uint32_t rt = Bits32(opcode, 25, 21);
221   uint32_t spr = Bits32(opcode, 20, 11);
222
223   enum { SPR_LR = 0x100 };
224
225   // For now, we're only insterested in 'mfspr r0, lr'
226   if (rt != gpr_r0_ppc64le || spr != SPR_LR)
227     return false;
228
229   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
230   LLDB_LOG(log, "EmulateMFSPR: {0:X+8}: mfspr r0, lr", m_addr);
231
232   bool success;
233   uint64_t lr =
234       ReadRegisterUnsigned(eRegisterKindLLDB, gpr_lr_ppc64le, 0, &success);
235   if (!success)
236     return false;
237   Context context;
238   context.type = eContextWriteRegisterRandomBits;
239   WriteRegisterUnsigned(context, eRegisterKindLLDB, gpr_r0_ppc64le, lr);
240   LLDB_LOG(log, "EmulateMFSPR: success!");
241   return true;
242 }
243
244 bool EmulateInstructionPPC64::EmulateLD(uint32_t opcode) {
245   uint32_t rt = Bits32(opcode, 25, 21);
246   uint32_t ra = Bits32(opcode, 20, 16);
247   uint32_t ds = Bits32(opcode, 15, 2);
248
249   int32_t ids = llvm::SignExtend32<16>(ds << 2);
250
251   // For now, tracking only loads from 0(r1) to r1 (0(r1) is the ABI defined
252   // location to save previous SP)
253   if (ra != gpr_r1_ppc64le || rt != gpr_r1_ppc64le || ids != 0)
254     return false;
255
256   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
257   LLDB_LOG(log, "EmulateLD: {0:X+8}: ld r{1}, {2}(r{3})", m_addr, rt, ids, ra);
258
259   RegisterInfo r1_info;
260   if (!GetRegisterInfo(eRegisterKindLLDB, gpr_r1_ppc64le, r1_info))
261     return false;
262
263   // restore SP
264   Context ctx;
265   ctx.type = eContextRestoreStackPointer;
266   ctx.SetRegisterToRegisterPlusOffset(r1_info, r1_info, 0);
267
268   WriteRegisterUnsigned(ctx, eRegisterKindLLDB, gpr_r1_ppc64le, 0);
269   LLDB_LOG(log, "EmulateLD: success!");
270   return true;
271 }
272
273 bool EmulateInstructionPPC64::EmulateSTD(uint32_t opcode) {
274   uint32_t rs = Bits32(opcode, 25, 21);
275   uint32_t ra = Bits32(opcode, 20, 16);
276   uint32_t ds = Bits32(opcode, 15, 2);
277   uint32_t u = Bits32(opcode, 1, 0);
278
279   // For now, tracking only stores to r1
280   if (ra != gpr_r1_ppc64le)
281     return false;
282   // ... and only stores of SP, FP and LR (moved into r0 by a previous mfspr)
283   if (rs != gpr_r1_ppc64le && rs != gpr_r31_ppc64le && rs != gpr_r30_ppc64le &&
284       rs != gpr_r0_ppc64le)
285     return false;
286
287   bool success;
288   uint64_t rs_val = ReadRegisterUnsigned(eRegisterKindLLDB, rs, 0, &success);
289   if (!success)
290     return false;
291
292   int32_t ids = llvm::SignExtend32<16>(ds << 2);
293   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
294   LLDB_LOG(log, "EmulateSTD: {0:X+8}: std{1} r{2}, {3}(r{4})", m_addr,
295            u ? "u" : "", rs, ids, ra);
296
297   // Make sure that r0 is really holding LR value (this won't catch unlikely
298   // cases, such as r0 being overwritten after mfspr)
299   uint32_t rs_num = rs;
300   if (rs == gpr_r0_ppc64le) {
301     uint64_t lr =
302         ReadRegisterUnsigned(eRegisterKindLLDB, gpr_lr_ppc64le, 0, &success);
303     if (!success || lr != rs_val)
304       return false;
305     rs_num = gpr_lr_ppc64le;
306   }
307
308   // set context
309   RegisterInfo rs_info;
310   if (!GetRegisterInfo(eRegisterKindLLDB, rs_num, rs_info))
311     return false;
312   RegisterInfo ra_info;
313   if (!GetRegisterInfo(eRegisterKindLLDB, ra, ra_info))
314     return false;
315
316   Context ctx;
317   ctx.type = eContextPushRegisterOnStack;
318   ctx.SetRegisterToRegisterPlusOffset(rs_info, ra_info, ids);
319
320   // store
321   uint64_t ra_val = ReadRegisterUnsigned(eRegisterKindLLDB, ra, 0, &success);
322   if (!success)
323     return false;
324
325   lldb::addr_t addr = ra_val + ids;
326   WriteMemory(ctx, addr, &rs_val, sizeof(rs_val));
327
328   // update RA?
329   if (u) {
330     Context ctx;
331     // NOTE Currently, RA will always be equal to SP(r1)
332     ctx.type = eContextAdjustStackPointer;
333     WriteRegisterUnsigned(ctx, eRegisterKindLLDB, ra, addr);
334   }
335
336   LLDB_LOG(log, "EmulateSTD: success!");
337   return true;
338 }
339
340 bool EmulateInstructionPPC64::EmulateOR(uint32_t opcode) {
341   uint32_t rs = Bits32(opcode, 25, 21);
342   uint32_t ra = Bits32(opcode, 20, 16);
343   uint32_t rb = Bits32(opcode, 15, 11);
344
345   // to be safe, process only the known 'mr r31/r30, r1' prologue instructions
346   if (m_fp != LLDB_INVALID_REGNUM || rs != rb ||
347       (ra != gpr_r30_ppc64le && ra != gpr_r31_ppc64le) || rb != gpr_r1_ppc64le)
348     return false;
349
350   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
351   LLDB_LOG(log, "EmulateOR: {0:X+8}: mr r{1}, r{2}", m_addr, ra, rb);
352
353   // set context
354   RegisterInfo ra_info;
355   if (!GetRegisterInfo(eRegisterKindLLDB, ra, ra_info))
356     return false;
357
358   Context ctx;
359   ctx.type = eContextSetFramePointer;
360   ctx.SetRegister(ra_info);
361
362   // move
363   bool success;
364   uint64_t rb_val = ReadRegisterUnsigned(eRegisterKindLLDB, rb, 0, &success);
365   if (!success)
366     return false;
367   WriteRegisterUnsigned(ctx, eRegisterKindLLDB, ra, rb_val);
368   m_fp = ra;
369   LLDB_LOG(log, "EmulateOR: success!");
370   return true;
371 }
372
373 bool EmulateInstructionPPC64::EmulateADDI(uint32_t opcode) {
374   uint32_t rt = Bits32(opcode, 25, 21);
375   uint32_t ra = Bits32(opcode, 20, 16);
376   uint32_t si = Bits32(opcode, 15, 0);
377
378   // handle stack adjustments only
379   // (this is a typical epilogue operation, with ra == r1. If it's
380   //  something else, then we won't know the correct value of ra)
381   if (rt != gpr_r1_ppc64le || ra != gpr_r1_ppc64le)
382     return false;
383
384   int32_t si_val = llvm::SignExtend32<16>(si);
385   Log *log(GetLogIfAllCategoriesSet(LIBLLDB_LOG_UNWIND));
386   LLDB_LOG(log, "EmulateADDI: {0:X+8}: addi r1, r1, {1}", m_addr, si_val);
387
388   // set context
389   RegisterInfo r1_info;
390   if (!GetRegisterInfo(eRegisterKindLLDB, gpr_r1_ppc64le, r1_info))
391     return false;
392
393   Context ctx;
394   ctx.type = eContextRestoreStackPointer;
395   ctx.SetRegisterToRegisterPlusOffset(r1_info, r1_info, 0);
396
397   // adjust SP
398   bool success;
399   uint64_t r1 =
400       ReadRegisterUnsigned(eRegisterKindLLDB, gpr_r1_ppc64le, 0, &success);
401   if (!success)
402     return false;
403   WriteRegisterUnsigned(ctx, eRegisterKindLLDB, gpr_r1_ppc64le, r1 + si_val);
404   LLDB_LOG(log, "EmulateADDI: success!");
405   return true;
406 }