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