LLDB  mainline
EmulateInstructionARM64.cpp
Go to the documentation of this file.
1 //===-- EmulateInstructionARM64.cpp ---------------------------------------===//
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 
10 
11 #include "lldb/Core/Address.h"
13 #include "lldb/Symbol/UnwindPlan.h"
14 #include "lldb/Utility/ArchSpec.h"
17 #include "lldb/Utility/Stream.h"
18 
19 #include "llvm/Support/CheckedArithmetic.h"
20 
24 
25 #include <cstdlib>
26 
27 #define GPR_OFFSET(idx) ((idx)*8)
28 #define GPR_OFFSET_NAME(reg) 0
29 #define FPU_OFFSET(idx) ((idx)*16)
30 #define FPU_OFFSET_NAME(reg) 0
31 #define EXC_OFFSET_NAME(reg) 0
32 #define DBG_OFFSET_NAME(reg) 0
33 #define DBG_OFFSET_NAME(reg) 0
34 #define DEFINE_DBG(re, y) \
35  "na", nullptr, 8, 0, lldb::eEncodingUint, lldb::eFormatHex, \
36  {LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM, \
37  LLDB_INVALID_REGNUM, LLDB_INVALID_REGNUM}, \
38  nullptr, nullptr
39 
40 #define DECLARE_REGISTER_INFOS_ARM64_STRUCT
41 
43 
44 #include "llvm/ADT/STLExtras.h"
45 #include "llvm/Support/MathExtras.h"
46 
48 
49 using namespace lldb;
50 using namespace lldb_private;
51 
53 
54 static bool LLDBTableGetRegisterInfo(uint32_t reg_num, RegisterInfo &reg_info) {
55  if (reg_num >= llvm::array_lengthof(g_register_infos_arm64_le))
56  return false;
57  reg_info = g_register_infos_arm64_le[reg_num];
58  return true;
59 }
60 
61 #define No_VFP 0
62 #define VFPv1 (1u << 1)
63 #define VFPv2 (1u << 2)
64 #define VFPv3 (1u << 3)
65 #define AdvancedSIMD (1u << 4)
66 
67 #define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD)
68 #define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD)
69 #define VFPv2v3 (VFPv2 | VFPv3)
70 
71 #define UInt(x) ((uint64_t)x)
72 #define SInt(x) ((int64_t)x)
73 #define bit bool
74 #define boolean bool
75 #define integer int64_t
76 
77 static inline bool IsZero(uint64_t x) { return x == 0; }
78 
79 static inline uint64_t NOT(uint64_t x) { return ~x; }
80 
81 // LSL()
82 // =====
83 
84 static inline uint64_t LSL(uint64_t x, integer shift) {
85  if (shift == 0)
86  return x;
87  return x << shift;
88 }
89 
90 // ConstrainUnpredictable()
91 // ========================
92 
97  switch (which) {
100  // TODO: don't know what to really do here? Pseudo code says:
101  // set result to one of above Constraint behaviours or UNDEFINED
102  break;
103  }
104  return result;
105 }
106 
107 //
108 // EmulateInstructionARM implementation
109 //
110 
112  PluginManager::RegisterPlugin(GetPluginNameStatic(),
113  GetPluginDescriptionStatic(), CreateInstance);
114 }
115 
117  PluginManager::UnregisterPlugin(CreateInstance);
118 }
119 
121  return "Emulate instructions for the ARM64 architecture.";
122 }
123 
126  InstructionType inst_type) {
128  inst_type)) {
129  if (arch.GetTriple().getArch() == llvm::Triple::aarch64 ||
130  arch.GetTriple().getArch() == llvm::Triple::aarch64_32) {
131  return new EmulateInstructionARM64(arch);
132  }
133  }
134 
135  return nullptr;
136 }
137 
139  if (arch.GetTriple().getArch() == llvm::Triple::arm)
140  return true;
141  else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
142  return true;
143 
144  return false;
145 }
146 
148  uint32_t reg_num,
149  RegisterInfo &reg_info) {
150  if (reg_kind == eRegisterKindGeneric) {
151  switch (reg_num) {
153  reg_kind = eRegisterKindLLDB;
154  reg_num = gpr_pc_arm64;
155  break;
157  reg_kind = eRegisterKindLLDB;
158  reg_num = gpr_sp_arm64;
159  break;
161  reg_kind = eRegisterKindLLDB;
162  reg_num = gpr_fp_arm64;
163  break;
165  reg_kind = eRegisterKindLLDB;
166  reg_num = gpr_lr_arm64;
167  break;
169  reg_kind = eRegisterKindLLDB;
170  reg_num = gpr_cpsr_arm64;
171  break;
172 
173  default:
174  return false;
175  }
176  }
177 
178  if (reg_kind == eRegisterKindLLDB)
179  return LLDBTableGetRegisterInfo(reg_num, reg_info);
180  return false;
181 }
182 
185  static EmulateInstructionARM64::Opcode g_opcodes[] = {
186  // Prologue instructions
187 
188  // push register(s)
189  {0xff000000, 0xd1000000, No_VFP,
191  "SUB <Xd|SP>, <Xn|SP>, #<imm> {, <shift>}"},
192  {0xff000000, 0xf1000000, No_VFP,
194  "SUBS <Xd>, <Xn|SP>, #<imm> {, <shift>}"},
195  {0xff000000, 0x91000000, No_VFP,
197  "ADD <Xd|SP>, <Xn|SP>, #<imm> {, <shift>}"},
198  {0xff000000, 0xb1000000, No_VFP,
200  "ADDS <Xd>, <Xn|SP>, #<imm> {, <shift>}"},
201 
202  {0xff000000, 0x51000000, No_VFP,
204  "SUB <Wd|WSP>, <Wn|WSP>, #<imm> {, <shift>}"},
205  {0xff000000, 0x71000000, No_VFP,
207  "SUBS <Wd>, <Wn|WSP>, #<imm> {, <shift>}"},
208  {0xff000000, 0x11000000, No_VFP,
210  "ADD <Wd|WSP>, <Wn|WSP>, #<imm> {, <shift>}"},
211  {0xff000000, 0x31000000, No_VFP,
213  "ADDS <Wd>, <Wn|WSP>, #<imm> {, <shift>}"},
214 
215  {0xffc00000, 0x29000000, No_VFP,
216  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
217  "STP <Wt>, <Wt2>, [<Xn|SP>{, #<imm>}]"},
218  {0xffc00000, 0xa9000000, No_VFP,
219  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
220  "STP <Xt>, <Xt2>, [<Xn|SP>{, #<imm>}]"},
221  {0xffc00000, 0x2d000000, No_VFP,
222  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
223  "STP <St>, <St2>, [<Xn|SP>{, #<imm>}]"},
224  {0xffc00000, 0x6d000000, No_VFP,
225  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
226  "STP <Dt>, <Dt2>, [<Xn|SP>{, #<imm>}]"},
227  {0xffc00000, 0xad000000, No_VFP,
228  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
229  "STP <Qt>, <Qt2>, [<Xn|SP>{, #<imm>}]"},
230 
231  {0xffc00000, 0x29800000, No_VFP,
232  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
233  "STP <Wt>, <Wt2>, [<Xn|SP>, #<imm>]!"},
234  {0xffc00000, 0xa9800000, No_VFP,
235  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
236  "STP <Xt>, <Xt2>, [<Xn|SP>, #<imm>]!"},
237  {0xffc00000, 0x2d800000, No_VFP,
238  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
239  "STP <St>, <St2>, [<Xn|SP>, #<imm>]!"},
240  {0xffc00000, 0x6d800000, No_VFP,
241  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
242  "STP <Dt>, <Dt2>, [<Xn|SP>, #<imm>]!"},
243  {0xffc00000, 0xad800000, No_VFP,
244  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
245  "STP <Qt>, <Qt2>, [<Xn|SP>, #<imm>]!"},
246 
247  {0xffc00000, 0x28800000, No_VFP,
248  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
249  "STP <Wt>, <Wt2>, [<Xn|SP>, #<imm>]!"},
250  {0xffc00000, 0xa8800000, No_VFP,
251  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
252  "STP <Xt>, <Xt2>, [<Xn|SP>, #<imm>]!"},
253  {0xffc00000, 0x2c800000, No_VFP,
254  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
255  "STP <St>, <St2>, [<Xn|SP>, #<imm>]!"},
256  {0xffc00000, 0x6c800000, No_VFP,
257  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
258  "STP <Dt>, <Dt2>, [<Xn|SP>, #<imm>]!"},
259  {0xffc00000, 0xac800000, No_VFP,
260  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
261  "STP <Qt>, <Qt2>, [<Xn|SP>, #<imm>]!"},
262 
263  {0xffc00000, 0x29400000, No_VFP,
264  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
265  "LDP <Wt>, <Wt2>, [<Xn|SP>{, #<imm>}]"},
266  {0xffc00000, 0xa9400000, No_VFP,
267  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
268  "LDP <Xt>, <Xt2>, [<Xn|SP>{, #<imm>}]"},
269  {0xffc00000, 0x2d400000, No_VFP,
270  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
271  "LDP <St>, <St2>, [<Xn|SP>{, #<imm>}]"},
272  {0xffc00000, 0x6d400000, No_VFP,
273  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
274  "LDP <Dt>, <Dt2>, [<Xn|SP>{, #<imm>}]"},
275  {0xffc00000, 0xad400000, No_VFP,
276  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
277  "LDP <Qt>, <Qt2>, [<Xn|SP>{, #<imm>}]"},
278 
279  {0xffc00000, 0x29c00000, No_VFP,
280  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
281  "LDP <Wt>, <Wt2>, [<Xn|SP>, #<imm>]!"},
282  {0xffc00000, 0xa9c00000, No_VFP,
283  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
284  "LDP <Xt>, <Xt2>, [<Xn|SP>, #<imm>]!"},
285  {0xffc00000, 0x2dc00000, No_VFP,
286  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
287  "LDP <St>, <St2>, [<Xn|SP>, #<imm>]!"},
288  {0xffc00000, 0x6dc00000, No_VFP,
289  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
290  "LDP <Dt>, <Dt2>, [<Xn|SP>, #<imm>]!"},
291  {0xffc00000, 0xadc00000, No_VFP,
292  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
293  "LDP <Qt>, <Qt2>, [<Xn|SP>, #<imm>]!"},
294 
295  {0xffc00000, 0x28c00000, No_VFP,
296  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
297  "LDP <Wt>, <Wt2>, [<Xn|SP>, #<imm>]!"},
298  {0xffc00000, 0xa8c00000, No_VFP,
299  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
300  "LDP <Xt>, <Xt2>, [<Xn|SP>, #<imm>]!"},
301  {0xffc00000, 0x2cc00000, No_VFP,
302  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
303  "LDP <St>, <St2>, [<Xn|SP>, #<imm>]!"},
304  {0xffc00000, 0x6cc00000, No_VFP,
305  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
306  "LDP <Dt>, <Dt2>, [<Xn|SP>, #<imm>]!"},
307  {0xffc00000, 0xacc00000, No_VFP,
308  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
309  "LDP <Qt>, <Qt2>, [<Xn|SP>, #<imm>]!"},
310 
311  {0xffe00c00, 0xb8000400, No_VFP,
312  &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_POST>,
313  "STR <Wt>, [<Xn|SP>], #<simm>"},
314  {0xffe00c00, 0xf8000400, No_VFP,
315  &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_POST>,
316  "STR <Xt>, [<Xn|SP>], #<simm>"},
317  {0xffe00c00, 0xb8000c00, No_VFP,
318  &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_PRE>,
319  "STR <Wt>, [<Xn|SP>, #<simm>]!"},
320  {0xffe00c00, 0xf8000c00, No_VFP,
321  &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_PRE>,
322  "STR <Xt>, [<Xn|SP>, #<simm>]!"},
323  {0xffc00000, 0xb9000000, No_VFP,
324  &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_OFF>,
325  "STR <Wt>, [<Xn|SP>{, #<pimm>}]"},
326  {0xffc00000, 0xf9000000, No_VFP,
327  &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_OFF>,
328  "STR <Xt>, [<Xn|SP>{, #<pimm>}]"},
329 
330  {0xffe00c00, 0xb8400400, No_VFP,
331  &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_POST>,
332  "LDR <Wt>, [<Xn|SP>], #<simm>"},
333  {0xffe00c00, 0xf8400400, No_VFP,
334  &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_POST>,
335  "LDR <Xt>, [<Xn|SP>], #<simm>"},
336  {0xffe00c00, 0xb8400c00, No_VFP,
337  &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_PRE>,
338  "LDR <Wt>, [<Xn|SP>, #<simm>]!"},
339  {0xffe00c00, 0xf8400c00, No_VFP,
340  &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_PRE>,
341  "LDR <Xt>, [<Xn|SP>, #<simm>]!"},
342  {0xffc00000, 0xb9400000, No_VFP,
343  &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_OFF>,
344  "LDR <Wt>, [<Xn|SP>{, #<pimm>}]"},
345  {0xffc00000, 0xf9400000, No_VFP,
346  &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_OFF>,
347  "LDR <Xt>, [<Xn|SP>{, #<pimm>}]"},
348 
349  {0xfc000000, 0x14000000, No_VFP, &EmulateInstructionARM64::EmulateB,
350  "B <label>"},
351  {0xff000010, 0x54000000, No_VFP, &EmulateInstructionARM64::EmulateBcond,
352  "B.<cond> <label>"},
353  {0x7f000000, 0x34000000, No_VFP, &EmulateInstructionARM64::EmulateCBZ,
354  "CBZ <Wt>, <label>"},
355  {0x7f000000, 0x35000000, No_VFP, &EmulateInstructionARM64::EmulateCBZ,
356  "CBNZ <Wt>, <label>"},
357  {0x7f000000, 0x36000000, No_VFP, &EmulateInstructionARM64::EmulateTBZ,
358  "TBZ <R><t>, #<imm>, <label>"},
359  {0x7f000000, 0x37000000, No_VFP, &EmulateInstructionARM64::EmulateTBZ,
360  "TBNZ <R><t>, #<imm>, <label>"},
361 
362  };
363  static const size_t k_num_arm_opcodes = llvm::array_lengthof(g_opcodes);
364 
365  for (size_t i = 0; i < k_num_arm_opcodes; ++i) {
366  if ((g_opcodes[i].mask & opcode) == g_opcodes[i].value)
367  return &g_opcodes[i];
368  }
369  return nullptr;
370 }
371 
373  bool success = false;
374  m_addr = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
375  LLDB_INVALID_ADDRESS, &success);
376  if (success) {
377  Context read_inst_context;
378  read_inst_context.type = eContextReadOpcode;
379  read_inst_context.SetNoArgs();
380  m_opcode.SetOpcode32(
381  ReadMemoryUnsigned(read_inst_context, m_addr, 4, 0, &success),
382  GetByteOrder());
383  }
384  if (!success)
385  m_addr = LLDB_INVALID_ADDRESS;
386  return success;
387 }
388 
390  const uint32_t opcode = m_opcode.GetOpcode32();
391  Opcode *opcode_data = GetOpcodeForInstruction(opcode);
392  if (opcode_data == nullptr)
393  return false;
394 
395  const bool auto_advance_pc =
396  evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
397  m_ignore_conditions =
398  evaluate_options & eEmulateInstructionOptionIgnoreConditions;
399 
400  bool success = false;
401 
402  // Only return false if we are unable to read the CPSR if we care about
403  // conditions
404  if (!success && !m_ignore_conditions)
405  return false;
406 
407  uint32_t orig_pc_value = 0;
408  if (auto_advance_pc) {
409  orig_pc_value =
410  ReadRegisterUnsigned(eRegisterKindLLDB, gpr_pc_arm64, 0, &success);
411  if (!success)
412  return false;
413  }
414 
415  // Call the Emulate... function.
416  success = (this->*opcode_data->callback)(opcode);
417  if (!success)
418  return false;
419 
420  if (auto_advance_pc) {
421  uint32_t new_pc_value =
422  ReadRegisterUnsigned(eRegisterKindLLDB, gpr_pc_arm64, 0, &success);
423  if (!success)
424  return false;
425 
426  if (new_pc_value == orig_pc_value) {
428  context.type = eContextAdvancePC;
429  context.SetNoArgs();
430  if (!WriteRegisterUnsigned(context, eRegisterKindLLDB, gpr_pc_arm64,
431  orig_pc_value + 4))
432  return false;
433  }
434  }
435  return true;
436 }
437 
439  UnwindPlan &unwind_plan) {
440  unwind_plan.Clear();
441  unwind_plan.SetRegisterKind(eRegisterKindLLDB);
442 
444 
445  // Our previous Call Frame Address is the stack pointer
446  row->GetCFAValue().SetIsRegisterPlusOffset(gpr_sp_arm64, 0);
447 
448  unwind_plan.AppendRow(row);
449  unwind_plan.SetSourceName("EmulateInstructionARM64");
450  unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
454  return true;
455 }
456 
458  if (m_arch.GetTriple().isAndroid())
459  return LLDB_INVALID_REGNUM; // Don't use frame pointer on android
460 
461  return gpr_fp_arm64;
462 }
463 
465  bool aarch32 = m_opcode_pstate.RW == 1;
466  // if !HaveAnyAArch32() then assert !aarch32;
467  // if HighestELUsingAArch32() then assert aarch32;
468  return aarch32;
469 }
470 
472  addr_t target) {
473 #if 0
474  // Set program counter to a new address, with a branch reason hint for
475  // possible use by hardware fetching the next instruction.
476  BranchTo(bits(N) target, BranchType branch_type)
477  Hint_Branch(branch_type);
478  if N == 32 then
479  assert UsingAArch32();
480  _PC = ZeroExtend(target);
481  else
482  assert N == 64 && !UsingAArch32();
483  // Remove the tag bits from a tagged target
484  case PSTATE.EL of
485  when EL0, EL1
486  if target<55> == '1' && TCR_EL1.TBI1 == '1' then
487  target<63:56> = '11111111';
488  if target<55> == '0' && TCR_EL1.TBI0 == '1' then
489  target<63:56> = '00000000';
490  when EL2
491  if TCR_EL2.TBI == '1' then
492  target<63:56> = '00000000';
493  when EL3
494  if TCR_EL3.TBI == '1' then
495  target<63:56> = '00000000';
496  _PC = target<63:0>;
497  return;
498 #endif
499 
500  addr_t addr;
501 
502  // Hint_Branch(branch_type);
503  if (N == 32) {
504  if (!UsingAArch32())
505  return false;
506  addr = target;
507  } else if (N == 64) {
508  if (UsingAArch32())
509  return false;
510  // TODO: Remove the tag bits from a tagged target
511  addr = target;
512  } else
513  return false;
514 
515  return WriteRegisterUnsigned(context, eRegisterKindGeneric,
516  LLDB_REGNUM_GENERIC_PC, addr);
517 }
518 
520  // If we are ignoring conditions, then always return true. this allows us to
521  // iterate over disassembly code and still emulate an instruction even if we
522  // don't have all the right bits set in the CPSR register...
523  if (m_ignore_conditions)
524  return true;
525 
526  bool result = false;
527  switch (UnsignedBits(cond, 3, 1)) {
528  case 0:
529  result = (m_opcode_pstate.Z == 1);
530  break;
531  case 1:
532  result = (m_opcode_pstate.C == 1);
533  break;
534  case 2:
535  result = (m_opcode_pstate.N == 1);
536  break;
537  case 3:
538  result = (m_opcode_pstate.V == 1);
539  break;
540  case 4:
541  result = (m_opcode_pstate.C == 1 && m_opcode_pstate.Z == 0);
542  break;
543  case 5:
544  result = (m_opcode_pstate.N == m_opcode_pstate.V);
545  break;
546  case 6:
547  result = (m_opcode_pstate.N == m_opcode_pstate.V && m_opcode_pstate.Z == 0);
548  break;
549  case 7:
550  // Always execute (cond == 0b1110, or the special 0b1111 which gives
551  // opcodes different meanings, but always means execution happens.
552  return true;
553  }
554 
555  if (cond & 1)
556  result = !result;
557  return result;
558 }
559 
561 AddWithCarry(uint32_t N, uint64_t x, uint64_t y, bit carry_in,
563  uint64_t unsigned_sum = UInt(x) + UInt(y) + UInt(carry_in);
564  llvm::Optional<int64_t> signed_sum = llvm::checkedAdd(SInt(x), SInt(y));
565  bool overflow = !signed_sum;
566  if (!overflow)
567  overflow |= !llvm::checkedAdd(*signed_sum, SInt(carry_in));
568  uint64_t result = unsigned_sum;
569  if (N < 64)
570  result = Bits64(result, N - 1, 0);
571  proc_state.N = Bit64(result, N - 1);
572  proc_state.Z = IsZero(result);
573  proc_state.C = UInt(result) != unsigned_sum;
574  proc_state.V = overflow;
575  return result;
576 }
577 
579  // integer d = UInt(Rd);
580  // integer n = UInt(Rn);
581  // integer datasize = if sf == 1 then 64 else 32;
582  // boolean sub_op = (op == 1);
583  // boolean setflags = (S == 1);
584  // bits(datasize) imm;
585  //
586  // case shift of
587  // when '00' imm = ZeroExtend(imm12, datasize);
588  // when '01' imm = ZeroExtend(imm12 : Zeros(12), datasize);
589  // when '1x' UNDEFINED;
590  //
591  //
592  // bits(datasize) result;
593  // bits(datasize) operand1 = if n == 31 then SP[] else X[n];
594  // bits(datasize) operand2 = imm;
595  // bits(4) nzcv;
596  // bit carry_in;
597  //
598  // if sub_op then
599  // operand2 = NOT(operand2);
600  // carry_in = 1;
601  // else
602  // carry_in = 0;
603  //
604  // (result, nzcv) = AddWithCarry(operand1, operand2, carry_in);
605  //
606  // if setflags then
607  // PSTATE.NZCV = nzcv;
608  //
609  // if d == 31 && !setflags then
610  // SP[] = result;
611  // else
612  // X[d] = result;
613 
614  const uint32_t sf = Bit32(opcode, 31);
615  const uint32_t op = Bit32(opcode, 30);
616  const uint32_t S = Bit32(opcode, 29);
617  const uint32_t shift = Bits32(opcode, 23, 22);
618  const uint32_t imm12 = Bits32(opcode, 21, 10);
619  const uint32_t Rn = Bits32(opcode, 9, 5);
620  const uint32_t Rd = Bits32(opcode, 4, 0);
621 
622  bool success = false;
623 
624  const uint32_t d = UInt(Rd);
625  const uint32_t n = UInt(Rn);
626  const uint32_t datasize = (sf == 1) ? 64 : 32;
627  boolean sub_op = op == 1;
628  boolean setflags = S == 1;
629  uint64_t imm;
630 
631  switch (shift) {
632  case 0:
633  imm = imm12;
634  break;
635  case 1:
636  imm = imm12 << 12;
637  break;
638  default:
639  return false; // UNDEFINED;
640  }
641  uint64_t result;
642  uint64_t operand1 =
643  ReadRegisterUnsigned(eRegisterKindLLDB, gpr_x0_arm64 + n, 0, &success);
644  uint64_t operand2 = imm;
645  bit carry_in;
646 
647  if (sub_op) {
648  operand2 = NOT(operand2);
649  carry_in = true;
650  imm = -imm; // For the Register plug offset context below
651  } else {
652  carry_in = false;
653  }
654 
655  ProcState proc_state;
656 
657  result = AddWithCarry(datasize, operand1, operand2, carry_in, proc_state);
658 
659  if (setflags) {
660  m_emulated_pstate.N = proc_state.N;
661  m_emulated_pstate.Z = proc_state.Z;
662  m_emulated_pstate.C = proc_state.C;
663  m_emulated_pstate.V = proc_state.V;
664  }
665 
666  Context context;
667  RegisterInfo reg_info_Rn;
668  if (GetRegisterInfo(eRegisterKindLLDB, n, reg_info_Rn))
669  context.SetRegisterPlusOffset(reg_info_Rn, imm);
670 
671  if (n == GetFramePointerRegisterNumber() && d == gpr_sp_arm64 && !setflags) {
672  // 'mov sp, fp' - common epilogue instruction, CFA is now in terms of the
673  // stack pointer, instead of frame pointer.
674  context.type = EmulateInstruction::eContextRestoreStackPointer;
675  } else if ((n == gpr_sp_arm64 || n == GetFramePointerRegisterNumber()) &&
676  d == gpr_sp_arm64 && !setflags) {
677  context.type = EmulateInstruction::eContextAdjustStackPointer;
678  } else if (d == GetFramePointerRegisterNumber() && n == gpr_sp_arm64 &&
679  !setflags) {
680  context.type = EmulateInstruction::eContextSetFramePointer;
681  } else {
682  context.type = EmulateInstruction::eContextImmediate;
683  }
684 
685  // If setflags && d == gpr_sp_arm64 then d = WZR/XZR. See CMN, CMP
686  if (!setflags || d != gpr_sp_arm64)
687  WriteRegisterUnsigned(context, eRegisterKindLLDB, gpr_x0_arm64 + d, result);
688 
689  return false;
690 }
691 
692 template <EmulateInstructionARM64::AddrMode a_mode>
694  uint32_t opc = Bits32(opcode, 31, 30);
695  uint32_t V = Bit32(opcode, 26);
696  uint32_t L = Bit32(opcode, 22);
697  uint32_t imm7 = Bits32(opcode, 21, 15);
698  uint32_t Rt2 = Bits32(opcode, 14, 10);
699  uint32_t Rn = Bits32(opcode, 9, 5);
700  uint32_t Rt = Bits32(opcode, 4, 0);
701 
702  integer n = UInt(Rn);
703  integer t = UInt(Rt);
704  integer t2 = UInt(Rt2);
705  uint64_t idx;
706 
707  MemOp memop = L == 1 ? MemOp_LOAD : MemOp_STORE;
708  boolean vector = (V == 1);
709  // AccType acctype = AccType_NORMAL;
710  boolean is_signed = false;
711  boolean wback = a_mode != AddrMode_OFF;
712  boolean wb_unknown = false;
713  boolean rt_unknown = false;
714  integer scale;
715  integer size;
716 
717  if (opc == 3)
718  return false; // UNDEFINED
719 
720  if (vector) {
721  scale = 2 + UInt(opc);
722  } else {
723  scale = (opc & 2) ? 3 : 2;
724  is_signed = (opc & 1) != 0;
725  if (is_signed && memop == MemOp_STORE)
726  return false; // UNDEFINED
727  }
728 
729  if (!vector && wback && ((t == n) || (t2 == n))) {
730  switch (ConstrainUnpredictable(Unpredictable_WBOVERLAP)) {
731  case Constraint_UNKNOWN:
732  wb_unknown = true; // writeback is UNKNOWN
733  break;
734 
735  case Constraint_SUPPRESSWB:
736  wback = false; // writeback is suppressed
737  break;
738 
739  case Constraint_NOP:
740  memop = MemOp_NOP; // do nothing
741  wback = false;
742  break;
743 
744  case Constraint_NONE:
745  break;
746  }
747  }
748 
749  if (memop == MemOp_LOAD && t == t2) {
750  switch (ConstrainUnpredictable(Unpredictable_LDPOVERLAP)) {
751  case Constraint_UNKNOWN:
752  rt_unknown = true; // result is UNKNOWN
753  break;
754 
755  case Constraint_NOP:
756  memop = MemOp_NOP; // do nothing
757  wback = false;
758  break;
759 
760  default:
761  break;
762  }
763  }
764 
765  idx = LSL(llvm::SignExtend64<7>(imm7), scale);
766  size = (integer)1 << scale;
767  uint64_t datasize = size * 8;
768  uint64_t address;
769  uint64_t wb_address;
770 
771  RegisterValue data_Rt;
772  RegisterValue data_Rt2;
773  RegisterInfo reg_info_base;
774  RegisterInfo reg_info_Rt;
775  RegisterInfo reg_info_Rt2;
776  if (!GetRegisterInfo(eRegisterKindLLDB, gpr_x0_arm64 + n, reg_info_base))
777  return false;
778 
779  if (vector) {
780  if (!GetRegisterInfo(eRegisterKindLLDB, fpu_d0_arm64 + t, reg_info_Rt))
781  return false;
782  if (!GetRegisterInfo(eRegisterKindLLDB, fpu_d0_arm64 + t2, reg_info_Rt2))
783  return false;
784  } else {
785  if (!GetRegisterInfo(eRegisterKindLLDB, gpr_x0_arm64 + t, reg_info_Rt))
786  return false;
787  if (!GetRegisterInfo(eRegisterKindLLDB, gpr_x0_arm64 + t2, reg_info_Rt2))
788  return false;
789  }
790 
791  bool success = false;
792  if (n == 31) {
793  // CheckSPAlignment();
794  address =
795  ReadRegisterUnsigned(eRegisterKindLLDB, gpr_sp_arm64, 0, &success);
796  } else
797  address =
798  ReadRegisterUnsigned(eRegisterKindLLDB, gpr_x0_arm64 + n, 0, &success);
799 
800  wb_address = address + idx;
801  if (a_mode != AddrMode_POST)
802  address = wb_address;
803 
804  Context context_t;
805  Context context_t2;
806 
807  uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
808  Status error;
809 
810  switch (memop) {
811  case MemOp_STORE: {
812  if (n == 31 || n == GetFramePointerRegisterNumber()) // if this store is
813  // based off of the sp
814  // or fp register
815  {
816  context_t.type = eContextPushRegisterOnStack;
817  context_t2.type = eContextPushRegisterOnStack;
818  } else {
819  context_t.type = eContextRegisterStore;
820  context_t2.type = eContextRegisterStore;
821  }
822  context_t.SetRegisterToRegisterPlusOffset(reg_info_Rt, reg_info_base, 0);
823  context_t2.SetRegisterToRegisterPlusOffset(reg_info_Rt2, reg_info_base,
824  size);
825 
826  if (!ReadRegister(&reg_info_Rt, data_Rt))
827  return false;
828 
829  if (data_Rt.GetAsMemoryData(&reg_info_Rt, buffer, reg_info_Rt.byte_size,
830  eByteOrderLittle, error) == 0)
831  return false;
832 
833  if (!WriteMemory(context_t, address + 0, buffer, reg_info_Rt.byte_size))
834  return false;
835 
836  if (!ReadRegister(&reg_info_Rt2, data_Rt2))
837  return false;
838 
839  if (data_Rt2.GetAsMemoryData(&reg_info_Rt2, buffer, reg_info_Rt2.byte_size,
840  eByteOrderLittle, error) == 0)
841  return false;
842 
843  if (!WriteMemory(context_t2, address + size, buffer,
844  reg_info_Rt2.byte_size))
845  return false;
846  } break;
847 
848  case MemOp_LOAD: {
849  if (n == 31 || n == GetFramePointerRegisterNumber()) // if this load is
850  // based off of the sp
851  // or fp register
852  {
853  context_t.type = eContextPopRegisterOffStack;
854  context_t2.type = eContextPopRegisterOffStack;
855  } else {
856  context_t.type = eContextRegisterLoad;
857  context_t2.type = eContextRegisterLoad;
858  }
859  context_t.SetAddress(address);
860  context_t2.SetAddress(address + size);
861 
862  if (rt_unknown)
863  memset(buffer, 'U', reg_info_Rt.byte_size);
864  else {
865  if (!ReadMemory(context_t, address, buffer, reg_info_Rt.byte_size))
866  return false;
867  }
868 
869  if (data_Rt.SetFromMemoryData(&reg_info_Rt, buffer, reg_info_Rt.byte_size,
870  eByteOrderLittle, error) == 0)
871  return false;
872 
873  if (!vector && is_signed && !data_Rt.SignExtend(datasize))
874  return false;
875 
876  if (!WriteRegister(context_t, &reg_info_Rt, data_Rt))
877  return false;
878 
879  if (!rt_unknown) {
880  if (!ReadMemory(context_t2, address + size, buffer,
881  reg_info_Rt2.byte_size))
882  return false;
883  }
884 
885  if (data_Rt2.SetFromMemoryData(&reg_info_Rt2, buffer,
886  reg_info_Rt2.byte_size, eByteOrderLittle,
887  error) == 0)
888  return false;
889 
890  if (!vector && is_signed && !data_Rt2.SignExtend(datasize))
891  return false;
892 
893  if (!WriteRegister(context_t2, &reg_info_Rt2, data_Rt2))
894  return false;
895  } break;
896 
897  default:
898  break;
899  }
900 
901  if (wback) {
902  if (wb_unknown)
903  wb_address = LLDB_INVALID_ADDRESS;
904  Context context;
905  context.SetImmediateSigned(idx);
906  if (n == 31)
907  context.type = eContextAdjustStackPointer;
908  else
909  context.type = eContextAdjustBaseRegister;
910  WriteRegisterUnsigned(context, &reg_info_base, wb_address);
911  }
912  return true;
913 }
914 
915 template <EmulateInstructionARM64::AddrMode a_mode>
917  uint32_t size = Bits32(opcode, 31, 30);
918  uint32_t opc = Bits32(opcode, 23, 22);
919  uint32_t n = Bits32(opcode, 9, 5);
920  uint32_t t = Bits32(opcode, 4, 0);
921 
922  bool wback;
923  bool postindex;
924  uint64_t offset;
925 
926  switch (a_mode) {
927  case AddrMode_POST:
928  wback = true;
929  postindex = true;
930  offset = llvm::SignExtend64<9>(Bits32(opcode, 20, 12));
931  break;
932  case AddrMode_PRE:
933  wback = true;
934  postindex = false;
935  offset = llvm::SignExtend64<9>(Bits32(opcode, 20, 12));
936  break;
937  case AddrMode_OFF:
938  wback = false;
939  postindex = false;
940  offset = LSL(Bits32(opcode, 21, 10), size);
941  break;
942  }
943 
944  MemOp memop;
945 
946  if (Bit32(opc, 1) == 0) {
947  memop = Bit32(opc, 0) == 1 ? MemOp_LOAD : MemOp_STORE;
948  } else {
949  memop = MemOp_LOAD;
950  if (size == 2 && Bit32(opc, 0) == 1)
951  return false;
952  }
953 
954  Status error;
955  bool success = false;
956  uint64_t address;
957  uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
958  RegisterValue data_Rt;
959 
960  if (n == 31)
961  address =
962  ReadRegisterUnsigned(eRegisterKindLLDB, gpr_sp_arm64, 0, &success);
963  else
964  address =
965  ReadRegisterUnsigned(eRegisterKindLLDB, gpr_x0_arm64 + n, 0, &success);
966 
967  if (!success)
968  return false;
969 
970  if (!postindex)
971  address += offset;
972 
973  RegisterInfo reg_info_base;
974  if (!GetRegisterInfo(eRegisterKindLLDB, gpr_x0_arm64 + n, reg_info_base))
975  return false;
976 
977  RegisterInfo reg_info_Rt;
978  if (!GetRegisterInfo(eRegisterKindLLDB, gpr_x0_arm64 + t, reg_info_Rt))
979  return false;
980 
981  Context context;
982  switch (memop) {
983  case MemOp_STORE:
984  if (n == 31 || n == GetFramePointerRegisterNumber()) // if this store is
985  // based off of the sp
986  // or fp register
987  context.type = eContextPushRegisterOnStack;
988  else
989  context.type = eContextRegisterStore;
990  context.SetRegisterToRegisterPlusOffset(reg_info_Rt, reg_info_base,
991  postindex ? 0 : offset);
992 
993  if (!ReadRegister(&reg_info_Rt, data_Rt))
994  return false;
995 
996  if (data_Rt.GetAsMemoryData(&reg_info_Rt, buffer, reg_info_Rt.byte_size,
997  eByteOrderLittle, error) == 0)
998  return false;
999 
1000  if (!WriteMemory(context, address, buffer, reg_info_Rt.byte_size))
1001  return false;
1002  break;
1003 
1004  case MemOp_LOAD:
1005  if (n == 31 || n == GetFramePointerRegisterNumber()) // if this store is
1006  // based off of the sp
1007  // or fp register
1008  context.type = eContextPopRegisterOffStack;
1009  else
1010  context.type = eContextRegisterLoad;
1011  context.SetAddress(address);
1012 
1013  if (!ReadMemory(context, address, buffer, reg_info_Rt.byte_size))
1014  return false;
1015 
1016  if (data_Rt.SetFromMemoryData(&reg_info_Rt, buffer, reg_info_Rt.byte_size,
1017  eByteOrderLittle, error) == 0)
1018  return false;
1019 
1020  if (!WriteRegister(context, &reg_info_Rt, data_Rt))
1021  return false;
1022  break;
1023  default:
1024  return false;
1025  }
1026 
1027  if (wback) {
1028  if (postindex)
1029  address += offset;
1030 
1031  if (n == 31)
1032  context.type = eContextAdjustStackPointer;
1033  else
1034  context.type = eContextAdjustBaseRegister;
1035  context.SetImmediateSigned(offset);
1036 
1037  if (!WriteRegisterUnsigned(context, &reg_info_base, address))
1038  return false;
1039  }
1040  return true;
1041 }
1042 
1044 #if 0
1045  // ARM64 pseudo code...
1046  if branch_type == BranchType_CALL then X[30] = PC[] + 4;
1047  BranchTo(PC[] + offset, branch_type);
1048 #endif
1049 
1050  bool success = false;
1051 
1053  context.type = EmulateInstruction::eContextRelativeBranchImmediate;
1054  const uint64_t pc = ReadRegisterUnsigned(eRegisterKindGeneric,
1055  LLDB_REGNUM_GENERIC_PC, 0, &success);
1056  if (!success)
1057  return false;
1058 
1059  int64_t offset = llvm::SignExtend64<28>(Bits32(opcode, 25, 0) << 2);
1060  BranchType branch_type = Bit32(opcode, 31) ? BranchType_CALL : BranchType_JMP;
1061  addr_t target = pc + offset;
1062  context.SetImmediateSigned(offset);
1063 
1064  switch (branch_type) {
1065  case BranchType_CALL: {
1066  addr_t x30 = pc + 4;
1067  if (!WriteRegisterUnsigned(context, eRegisterKindLLDB, gpr_lr_arm64, x30))
1068  return false;
1069  } break;
1070  case BranchType_JMP:
1071  break;
1072  default:
1073  return false;
1074  }
1075 
1076  return BranchTo(context, 64, target);
1077 }
1078 
1080 #if 0
1081  // ARM64 pseudo code...
1082  bits(64) offset = SignExtend(imm19:'00', 64);
1083  bits(4) condition = cond;
1084  if ConditionHolds(condition) then
1085  BranchTo(PC[] + offset, BranchType_JMP);
1086 #endif
1087 
1088  if (ConditionHolds(Bits32(opcode, 3, 0))) {
1089  bool success = false;
1090 
1091  const uint64_t pc = ReadRegisterUnsigned(
1093  if (!success)
1094  return false;
1095 
1096  int64_t offset = llvm::SignExtend64<21>(Bits32(opcode, 23, 5) << 2);
1097  addr_t target = pc + offset;
1098 
1100  context.type = EmulateInstruction::eContextRelativeBranchImmediate;
1101  context.SetImmediateSigned(offset);
1102  if (!BranchTo(context, 64, target))
1103  return false;
1104  }
1105  return true;
1106 }
1107 
1109 #if 0
1110  integer t = UInt(Rt);
1111  integer datasize = if sf == '1' then 64 else 32;
1112  boolean iszero = (op == '0');
1113  bits(64) offset = SignExtend(imm19:'00', 64);
1114 
1115  bits(datasize) operand1 = X[t];
1116  if IsZero(operand1) == iszero then
1117  BranchTo(PC[] + offset, BranchType_JMP);
1118 #endif
1119 
1120  bool success = false;
1121 
1122  uint32_t t = Bits32(opcode, 4, 0);
1123  bool is_zero = Bit32(opcode, 24) == 0;
1124  int32_t offset = llvm::SignExtend64<21>(Bits32(opcode, 23, 5) << 2);
1125 
1126  const uint64_t operand =
1127  ReadRegisterUnsigned(eRegisterKindLLDB, gpr_x0_arm64 + t, 0, &success);
1128  if (!success)
1129  return false;
1130 
1131  if (m_ignore_conditions || ((operand == 0) == is_zero)) {
1132  const uint64_t pc = ReadRegisterUnsigned(
1134  if (!success)
1135  return false;
1136 
1138  context.type = EmulateInstruction::eContextRelativeBranchImmediate;
1139  context.SetImmediateSigned(offset);
1140  if (!BranchTo(context, 64, pc + offset))
1141  return false;
1142  }
1143  return true;
1144 }
1145 
1147 #if 0
1148  integer t = UInt(Rt);
1149  integer datasize = if b5 == '1' then 64 else 32;
1150  integer bit_pos = UInt(b5:b40);
1151  bit bit_val = op;
1152  bits(64) offset = SignExtend(imm14:'00', 64);
1153 #endif
1154 
1155  bool success = false;
1156 
1157  uint32_t t = Bits32(opcode, 4, 0);
1158  uint32_t bit_pos = (Bit32(opcode, 31) << 6) | (Bits32(opcode, 23, 19));
1159  uint32_t bit_val = Bit32(opcode, 24);
1160  int64_t offset = llvm::SignExtend64<16>(Bits32(opcode, 18, 5) << 2);
1161 
1162  const uint64_t operand =
1163  ReadRegisterUnsigned(eRegisterKindLLDB, gpr_x0_arm64 + t, 0, &success);
1164  if (!success)
1165  return false;
1166 
1167  if (m_ignore_conditions || Bit32(operand, bit_pos) == bit_val) {
1168  const uint64_t pc = ReadRegisterUnsigned(
1170  if (!success)
1171  return false;
1172 
1174  context.type = EmulateInstruction::eContextRelativeBranchImmediate;
1175  context.SetImmediateSigned(offset);
1176  if (!BranchTo(context, 64, pc + offset))
1177  return false;
1178  }
1179  return true;
1180 }
LLDBTableGetRegisterInfo
static bool LLDBTableGetRegisterInfo(uint32_t reg_num, RegisterInfo &reg_info)
Definition: EmulateInstructionARM64.cpp:54
EmulateInstructionARM64::Opcode::callback
bool(EmulateInstructionARM64::* callback)(const uint32_t opcode)
Definition: EmulateInstructionARM64.h:160
EmulateInstructionARM64::ProcState::Z
uint32_t Z
Definition: EmulateInstructionARM64.h:134
EmulateInstructionARM64::BranchType
BranchType
Definition: EmulateInstructionARM64.h:76
lldb_private::UnwindPlan::AppendRow
void AppendRow(const RowSP &row_sp)
Definition: UnwindPlan.cpp:360
lldb_private::ArchSpec
Definition: ArchSpec.h:33
EmulateInstructionARM64::ProcState
Definition: EmulateInstructionARM64.h:132
EmulateInstructionARM64::Unpredictable_WBOVERLAP
@ Unpredictable_WBOVERLAP
Definition: EmulateInstructionARM64.h:115
EmulateInstructionARM64::AddWithCarry
static uint64_t AddWithCarry(uint32_t N, uint64_t x, uint64_t y, bool carry_in, EmulateInstructionARM64::ProcState &proc_state)
Definition: EmulateInstructionARM64.cpp:561
lldb_private::UnsignedBits
static uint64_t UnsignedBits(const uint64_t value, const uint64_t msbit, const uint64_t lsbit)
Definition: InstructionUtils.h:97
LSL
static uint64_t LSL(uint64_t x, integer shift)
Definition: EmulateInstructionARM64.cpp:84
LLDB_INVALID_REGNUM
#define LLDB_INVALID_REGNUM
Definition: lldb-defines.h:79
EmulateInstructionARM64::Opcode
Definition: EmulateInstructionARM64.h:156
lldb_private::RegisterValue
Definition: RegisterValue.h:28
lldb_private::UnwindPlan::SetRegisterKind
void SetRegisterKind(lldb::RegisterKind kind)
Definition: UnwindPlan.h:437
EmulateInstructionARM64::SupportsEmulatingInstructionsOfTypeStatic
static bool SupportsEmulatingInstructionsOfTypeStatic(lldb_private::InstructionType inst_type)
Definition: EmulateInstructionARM64.h:35
lldb_private::gpr_lr_arm64
@ gpr_lr_arm64
Definition: lldb-arm64-register-enums.h:48
lldb::eRegisterKindGeneric
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target
Definition: lldb-enumerations.h:230
EmulateInstructionARM64::Terminate
static void Terminate()
Definition: EmulateInstructionARM64.cpp:116
lldb_private::UnwindPlan::SetUnwindPlanValidAtAllInstructions
void SetUnwindPlanValidAtAllInstructions(lldb_private::LazyBool valid_at_all_insn)
Definition: UnwindPlan.h:490
EmulateInstructionARM64::EmulateLDRSTRImm
bool EmulateLDRSTRImm(const uint32_t opcode)
Definition: EmulateInstructionARM64.cpp:916
lldb_private::eLazyBoolYes
@ eLazyBoolYes
Definition: lldb-private-enumerations.h:115
lldb_private::gpr_pc_arm64
@ gpr_pc_arm64
Definition: lldb-arm64-register-enums.h:50
lldb_private::EmulateInstruction::Context
Definition: EmulateInstruction.h:184
EmulateInstructionARM64::GetOpcodeForInstruction
static Opcode * GetOpcodeForInstruction(const uint32_t opcode)
Definition: EmulateInstructionARM64.cpp:184
lldb_private::gpr_x0_arm64
@ gpr_x0_arm64
Definition: lldb-arm64-register-enums.h:18
NOT
static uint64_t NOT(uint64_t x)
Definition: EmulateInstructionARM64.cpp:79
EmulateInstructionARM64::GetPluginDescriptionStatic
static llvm::StringRef GetPluginDescriptionStatic()
Definition: EmulateInstructionARM64.cpp:120
EmulateInstructionARM64
Definition: EmulateInstructionARM64.h:17
lldb_private::UnwindPlan::SetUnwindPlanForSignalTrap
void SetUnwindPlanForSignalTrap(lldb_private::LazyBool is_for_signal_trap)
Definition: UnwindPlan.h:502
RegisterValue.h
EmulateInstructionARM64::GetFramePointerRegisterNumber
uint32_t GetFramePointerRegisterNumber() const
Definition: EmulateInstructionARM64.cpp:457
EmulateInstructionARM64::Unpredictable_LDPOVERLAP
@ Unpredictable_LDPOVERLAP
Definition: EmulateInstructionARM64.h:115
lldb_private::ArchSpec::GetTriple
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition: ArchSpec.h:444
lldb::addr_t
uint64_t addr_t
Definition: lldb-types.h:83
pc
@ pc
Definition: CompactUnwindInfo.cpp:1250
lldb_private::UnwindPlan::SetSourceName
void SetSourceName(const char *)
Definition: UnwindPlan.cpp:562
LLDB_PLUGIN_DEFINE_ADV
LLDB_PLUGIN_DEFINE_ADV(ObjectContainerUniversalMachO, ObjectContainerMachOArchive) void ObjectContainerUniversalMachO
Definition: ObjectContainerUniversalMachO.cpp:23
EmulateInstructionARM64::CreateFunctionEntryUnwind
bool CreateFunctionEntryUnwind(lldb_private::UnwindPlan &unwind_plan) override
Definition: EmulateInstructionARM64.cpp:438
ARMUtils.h
UInt
#define UInt(x)
Definition: EmulateInstructionARM64.cpp:71
LLDB_REGNUM_GENERIC_FLAGS
#define LLDB_REGNUM_GENERIC_FLAGS
Definition: lldb-defines.h:55
error
static llvm::raw_ostream & error(Stream &strm)
Definition: CommandReturnObject.cpp:17
EmulateInstructionARM64::EmulateADDSUBImm
bool EmulateADDSUBImm(const uint32_t opcode)
Definition: EmulateInstructionARM64.cpp:578
arm64_dwarf::x30
@ x30
Definition: ARM64_DWARF_Registers.h:48
lldb_private::Bit32
static uint32_t Bit32(const uint32_t bits, const uint32_t bit)
Definition: InstructionUtils.h:36
lldb::eRegisterKindLLDB
@ eRegisterKindLLDB
lldb's internal register numbers
Definition: lldb-enumerations.h:234
EmulateInstructionARM64::ConditionHolds
bool ConditionHolds(const uint32_t cond)
Definition: EmulateInstructionARM64.cpp:519
lldb_private::UnwindPlan::SetReturnAddressRegister
void SetReturnAddressRegister(uint32_t regnum)
Definition: UnwindPlan.h:439
lldb_private::EmulateInstruction::Context::type
ContextType type
Definition: EmulateInstruction.h:185
lldb_private::UnwindPlan::SetSourcedFromCompiler
void SetSourcedFromCompiler(lldb_private::LazyBool from_compiler)
Definition: UnwindPlan.h:478
EmulateInstructionARM64::ConstraintType
ConstraintType
Definition: EmulateInstructionARM64.h:117
lldb_private::EmulateInstruction::Context::SetRegisterPlusOffset
void SetRegisterPlusOffset(RegisterInfo base_reg, int64_t signed_offset)
Definition: EmulateInstruction.h:242
bit
#define bit
Definition: EmulateInstructionARM64.cpp:73
lldb_private::EmulateInstruction::Context::SetRegisterToRegisterPlusOffset
void SetRegisterToRegisterPlusOffset(RegisterInfo data_reg, RegisterInfo base_reg, int64_t offset)
Definition: EmulateInstruction.h:255
No_VFP
#define No_VFP
Definition: EmulateInstructionARM64.cpp:61
ARMDefines.h
RegisterInfos_arm64.h
EmulateInstructionARM64::MemOp
MemOp
Definition: EmulateInstructionARM64.h:107
EmulateInstructionARM64::EmulateLDPSTP
bool EmulateLDPSTP(const uint32_t opcode)
Definition: EmulateInstructionARM64.cpp:693
EmulateInstructionARM64::CreateInstance
static lldb_private::EmulateInstruction * CreateInstance(const lldb_private::ArchSpec &arch, lldb_private::InstructionType inst_type)
Definition: EmulateInstructionARM64.cpp:125
EmulateInstructionARM64::ReadInstruction
bool ReadInstruction() override
Definition: EmulateInstructionARM64.cpp:372
Address.h
UnwindPlan.h
InstructionUtils.h
lldb::RegisterKind
RegisterKind
Register numbering types.
Definition: lldb-enumerations.h:227
lldb_private::UnwindPlan::RowSP
std::shared_ptr< Row > RowSP
Definition: UnwindPlan.h:395
IsZero
static bool IsZero(uint64_t x)
Definition: EmulateInstructionARM64.cpp:77
EmulateInstructionARM64.h
lldb_private::RegisterValue::SetFromMemoryData
uint32_t SetFromMemoryData(const RegisterInfo *reg_info, const void *src, uint32_t src_len, lldb::ByteOrder src_byte_order, Status &error)
Definition: RegisterValue.cpp:84
lldb_private::fpu_d0_arm64
@ fpu_d0_arm64
Definition: lldb-arm64-register-enums.h:152
lldb_private::UnwindPlan::Clear
void Clear()
Definition: UnwindPlan.h:508
lldb_private::Status
Definition: Status.h:44
SInt
#define SInt(x)
Definition: EmulateInstructionARM64.cpp:72
lldb_private::EmulateInstruction::Context::SetNoArgs
void SetNoArgs()
Definition: EmulateInstruction.h:321
EmulateInstructionARM64::EmulateBcond
bool EmulateBcond(const uint32_t opcode)
Definition: EmulateInstructionARM64.cpp:1079
lldb_private::gpr_fp_arm64
@ gpr_fp_arm64
Definition: lldb-arm64-register-enums.h:47
lldb_private::UnwindPlan::Row
Definition: UnwindPlan.h:55
uint32_t
lldb_private::eLazyBoolNo
@ eLazyBoolNo
Definition: lldb-private-enumerations.h:115
lldb_private::EmulateInstruction
Definition: EmulateInstruction.h:93
EmulateInstructionARM64::ProcState::N
uint32_t N
Definition: EmulateInstructionARM64.h:133
LLDB_REGNUM_GENERIC_SP
#define LLDB_REGNUM_GENERIC_SP
Definition: lldb-defines.h:52
EmulateInstructionARM64::ProcState::V
uint32_t V
Definition: EmulateInstructionARM64.h:133
lldb_private::RegisterValue::GetAsMemoryData
uint32_t GetAsMemoryData(const RegisterInfo *reg_info, void *dst, uint32_t dst_len, lldb::ByteOrder dst_byte_order, Status &error) const
Definition: RegisterValue.cpp:38
lldb_private::gpr_sp_arm64
@ gpr_sp_arm64
Definition: lldb-arm64-register-enums.h:49
ArchSpec.h
lldb_private::gpr_cpsr_arm64
@ gpr_cpsr_arm64
Definition: lldb-arm64-register-enums.h:51
EmulateInstructionARM64::EmulateCBZ
bool EmulateCBZ(const uint32_t opcode)
Definition: EmulateInstructionARM64.cpp:1108
EmulateInstructionARM64::Initialize
static void Initialize()
Definition: EmulateInstructionARM64.cpp:111
PluginManager.h
LLDB_INVALID_ADDRESS
#define LLDB_INVALID_ADDRESS
Definition: lldb-defines.h:74
EmulateInstructionARM64::EvaluateInstruction
bool EvaluateInstruction(uint32_t evaluate_options) override
Definition: EmulateInstructionARM64.cpp:389
lldb_private::InstructionType
InstructionType
Instruction types.
Definition: lldb-private-enumerations.h:118
EmulateInstructionARM64::GetRegisterInfo
bool GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num, lldb_private::RegisterInfo &reg_info) override
Definition: EmulateInstructionARM64.cpp:147
EmulateInstructionARM64::Unpredictable
Unpredictable
Definition: EmulateInstructionARM64.h:115
EmulateInstructionARM64::Constraint_UNKNOWN
@ Constraint_UNKNOWN
Definition: EmulateInstructionARM64.h:119
EmulateInstructionARM64::BranchTo
bool BranchTo(const Context &context, uint32_t N, lldb::addr_t target)
Definition: EmulateInstructionARM64.cpp:471
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
LLDB_REGNUM_GENERIC_FP
#define LLDB_REGNUM_GENERIC_FP
Definition: lldb-defines.h:53
lldb_private::EmulateInstruction::Context::SetAddress
void SetAddress(lldb::addr_t address)
Definition: EmulateInstruction.h:300
LLDB_REGNUM_GENERIC_PC
#define LLDB_REGNUM_GENERIC_PC
Definition: lldb-defines.h:51
ConstString.h
lldb_private::RegisterValue::SignExtend
bool SignExtend(uint32_t sign_bitpos)
Definition: RegisterValue.cpp:459
EmulateInstructionARM64::UsingAArch32
bool UsingAArch32()
Definition: EmulateInstructionARM64.cpp:464
Stream.h
EmulateInstructionARM64::SetTargetTriple
bool SetTargetTriple(const lldb_private::ArchSpec &arch) override
Definition: EmulateInstructionARM64.cpp:138
EmulateInstructionARM64::EmulateB
bool EmulateB(const uint32_t opcode)
Definition: EmulateInstructionARM64.cpp:1043
lldb_private::bits
static uint32_t bits(const uint32_t val, const uint32_t msbit, const uint32_t lsbit)
Definition: ARMUtils.h:264
EmulateInstructionARM64::ProcState::C
uint32_t C
Definition: EmulateInstructionARM64.h:133
integer
#define integer
Definition: EmulateInstructionARM64.cpp:75
lldb::eByteOrderLittle
@ eByteOrderLittle
Definition: lldb-enumerations.h:142
lldb_private::EmulateInstruction::Context::SetImmediateSigned
void SetImmediateSigned(int64_t signed_immediate)
Definition: EmulateInstruction.h:295
ConstrainUnpredictable
EmulateInstructionARM64::ConstraintType ConstrainUnpredictable(EmulateInstructionARM64::Unpredictable which)
Definition: EmulateInstructionARM64.cpp:94
lldb_private::Bits64
static uint64_t Bits64(const uint64_t bits, const uint32_t msbit, const uint32_t lsbit)
Definition: InstructionUtils.h:21
lldb_private::UnwindPlan
Definition: UnwindPlan.h:53
lldb
Definition: SBAddress.h:15
lldb_private::Bit64
static uint64_t Bit64(const uint64_t bits, const uint32_t bit)
Definition: InstructionUtils.h:40
EmulateInstructionARM64::EmulateTBZ
bool EmulateTBZ(const uint32_t opcode)
Definition: EmulateInstructionARM64.cpp:1146
lldb_private::Bits32
static uint32_t Bits32(const uint32_t bits, const uint32_t msbit, const uint32_t lsbit)
Definition: InstructionUtils.h:29
LLDB_REGNUM_GENERIC_RA
#define LLDB_REGNUM_GENERIC_RA
Definition: lldb-defines.h:54
lldb-arm64-register-enums.h