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 llvm::Optional<RegisterInfo> LLDBTableGetRegisterInfo(uint32_t reg_num) {
55  if (reg_num >= std::size(g_register_infos_arm64_le))
56  return {};
57  return g_register_infos_arm64_le[reg_num];
58 }
59 
60 #define No_VFP 0
61 #define VFPv1 (1u << 1)
62 #define VFPv2 (1u << 2)
63 #define VFPv3 (1u << 3)
64 #define AdvancedSIMD (1u << 4)
65 
66 #define VFPv1_ABOVE (VFPv1 | VFPv2 | VFPv3 | AdvancedSIMD)
67 #define VFPv2_ABOVE (VFPv2 | VFPv3 | AdvancedSIMD)
68 #define VFPv2v3 (VFPv2 | VFPv3)
69 
70 #define UInt(x) ((uint64_t)x)
71 #define SInt(x) ((int64_t)x)
72 #define bit bool
73 #define boolean bool
74 #define integer int64_t
75 
76 static inline bool IsZero(uint64_t x) { return x == 0; }
77 
78 static inline uint64_t NOT(uint64_t x) { return ~x; }
79 
80 // LSL()
81 // =====
82 
83 static inline uint64_t LSL(uint64_t x, integer shift) {
84  if (shift == 0)
85  return x;
86  return x << shift;
87 }
88 
89 // ConstrainUnpredictable()
90 // ========================
91 
96  switch (which) {
99  // TODO: don't know what to really do here? Pseudo code says:
100  // set result to one of above Constraint behaviours or UNDEFINED
101  break;
102  }
103  return result;
104 }
105 
106 //
107 // EmulateInstructionARM implementation
108 //
109 
111  PluginManager::RegisterPlugin(GetPluginNameStatic(),
112  GetPluginDescriptionStatic(), CreateInstance);
113 }
114 
116  PluginManager::UnregisterPlugin(CreateInstance);
117 }
118 
120  return "Emulate instructions for the ARM64 architecture.";
121 }
122 
125  InstructionType inst_type) {
127  inst_type)) {
128  if (arch.GetTriple().getArch() == llvm::Triple::aarch64 ||
129  arch.GetTriple().getArch() == llvm::Triple::aarch64_32) {
130  return new EmulateInstructionARM64(arch);
131  }
132  }
133 
134  return nullptr;
135 }
136 
138  if (arch.GetTriple().getArch() == llvm::Triple::arm)
139  return true;
140  else if (arch.GetTriple().getArch() == llvm::Triple::thumb)
141  return true;
142 
143  return false;
144 }
145 
146 llvm::Optional<RegisterInfo>
148  uint32_t reg_num) {
149  if (reg_kind == eRegisterKindGeneric) {
150  switch (reg_num) {
152  reg_kind = eRegisterKindLLDB;
153  reg_num = gpr_pc_arm64;
154  break;
156  reg_kind = eRegisterKindLLDB;
157  reg_num = gpr_sp_arm64;
158  break;
160  reg_kind = eRegisterKindLLDB;
161  reg_num = gpr_fp_arm64;
162  break;
164  reg_kind = eRegisterKindLLDB;
165  reg_num = gpr_lr_arm64;
166  break;
168  reg_kind = eRegisterKindLLDB;
169  reg_num = gpr_cpsr_arm64;
170  break;
171 
172  default:
173  return {};
174  }
175  }
176 
177  if (reg_kind == eRegisterKindLLDB)
178  return LLDBTableGetRegisterInfo(reg_num);
179  return {};
180 }
181 
184  static EmulateInstructionARM64::Opcode g_opcodes[] = {
185  // Prologue instructions
186 
187  // push register(s)
188  {0xff000000, 0xd1000000, No_VFP,
190  "SUB <Xd|SP>, <Xn|SP>, #<imm> {, <shift>}"},
191  {0xff000000, 0xf1000000, No_VFP,
193  "SUBS <Xd>, <Xn|SP>, #<imm> {, <shift>}"},
194  {0xff000000, 0x91000000, No_VFP,
196  "ADD <Xd|SP>, <Xn|SP>, #<imm> {, <shift>}"},
197  {0xff000000, 0xb1000000, No_VFP,
199  "ADDS <Xd>, <Xn|SP>, #<imm> {, <shift>}"},
200 
201  {0xff000000, 0x51000000, No_VFP,
203  "SUB <Wd|WSP>, <Wn|WSP>, #<imm> {, <shift>}"},
204  {0xff000000, 0x71000000, No_VFP,
206  "SUBS <Wd>, <Wn|WSP>, #<imm> {, <shift>}"},
207  {0xff000000, 0x11000000, No_VFP,
209  "ADD <Wd|WSP>, <Wn|WSP>, #<imm> {, <shift>}"},
210  {0xff000000, 0x31000000, No_VFP,
212  "ADDS <Wd>, <Wn|WSP>, #<imm> {, <shift>}"},
213 
214  {0xffc00000, 0x29000000, No_VFP,
215  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
216  "STP <Wt>, <Wt2>, [<Xn|SP>{, #<imm>}]"},
217  {0xffc00000, 0xa9000000, No_VFP,
218  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
219  "STP <Xt>, <Xt2>, [<Xn|SP>{, #<imm>}]"},
220  {0xffc00000, 0x2d000000, No_VFP,
221  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
222  "STP <St>, <St2>, [<Xn|SP>{, #<imm>}]"},
223  {0xffc00000, 0x6d000000, No_VFP,
224  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
225  "STP <Dt>, <Dt2>, [<Xn|SP>{, #<imm>}]"},
226  {0xffc00000, 0xad000000, No_VFP,
227  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
228  "STP <Qt>, <Qt2>, [<Xn|SP>{, #<imm>}]"},
229 
230  {0xffc00000, 0x29800000, No_VFP,
231  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
232  "STP <Wt>, <Wt2>, [<Xn|SP>, #<imm>]!"},
233  {0xffc00000, 0xa9800000, No_VFP,
234  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
235  "STP <Xt>, <Xt2>, [<Xn|SP>, #<imm>]!"},
236  {0xffc00000, 0x2d800000, No_VFP,
237  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
238  "STP <St>, <St2>, [<Xn|SP>, #<imm>]!"},
239  {0xffc00000, 0x6d800000, No_VFP,
240  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
241  "STP <Dt>, <Dt2>, [<Xn|SP>, #<imm>]!"},
242  {0xffc00000, 0xad800000, No_VFP,
243  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
244  "STP <Qt>, <Qt2>, [<Xn|SP>, #<imm>]!"},
245 
246  {0xffc00000, 0x28800000, No_VFP,
247  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
248  "STP <Wt>, <Wt2>, [<Xn|SP>, #<imm>]!"},
249  {0xffc00000, 0xa8800000, No_VFP,
250  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
251  "STP <Xt>, <Xt2>, [<Xn|SP>, #<imm>]!"},
252  {0xffc00000, 0x2c800000, No_VFP,
253  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
254  "STP <St>, <St2>, [<Xn|SP>, #<imm>]!"},
255  {0xffc00000, 0x6c800000, No_VFP,
256  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
257  "STP <Dt>, <Dt2>, [<Xn|SP>, #<imm>]!"},
258  {0xffc00000, 0xac800000, No_VFP,
259  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
260  "STP <Qt>, <Qt2>, [<Xn|SP>, #<imm>]!"},
261 
262  {0xffc00000, 0x29400000, No_VFP,
263  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
264  "LDP <Wt>, <Wt2>, [<Xn|SP>{, #<imm>}]"},
265  {0xffc00000, 0xa9400000, No_VFP,
266  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
267  "LDP <Xt>, <Xt2>, [<Xn|SP>{, #<imm>}]"},
268  {0xffc00000, 0x2d400000, No_VFP,
269  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
270  "LDP <St>, <St2>, [<Xn|SP>{, #<imm>}]"},
271  {0xffc00000, 0x6d400000, No_VFP,
272  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
273  "LDP <Dt>, <Dt2>, [<Xn|SP>{, #<imm>}]"},
274  {0xffc00000, 0xad400000, No_VFP,
275  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_OFF>,
276  "LDP <Qt>, <Qt2>, [<Xn|SP>{, #<imm>}]"},
277 
278  {0xffc00000, 0x29c00000, No_VFP,
279  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
280  "LDP <Wt>, <Wt2>, [<Xn|SP>, #<imm>]!"},
281  {0xffc00000, 0xa9c00000, No_VFP,
282  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
283  "LDP <Xt>, <Xt2>, [<Xn|SP>, #<imm>]!"},
284  {0xffc00000, 0x2dc00000, No_VFP,
285  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
286  "LDP <St>, <St2>, [<Xn|SP>, #<imm>]!"},
287  {0xffc00000, 0x6dc00000, No_VFP,
288  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
289  "LDP <Dt>, <Dt2>, [<Xn|SP>, #<imm>]!"},
290  {0xffc00000, 0xadc00000, No_VFP,
291  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_PRE>,
292  "LDP <Qt>, <Qt2>, [<Xn|SP>, #<imm>]!"},
293 
294  {0xffc00000, 0x28c00000, No_VFP,
295  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
296  "LDP <Wt>, <Wt2>, [<Xn|SP>, #<imm>]!"},
297  {0xffc00000, 0xa8c00000, No_VFP,
298  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
299  "LDP <Xt>, <Xt2>, [<Xn|SP>, #<imm>]!"},
300  {0xffc00000, 0x2cc00000, No_VFP,
301  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
302  "LDP <St>, <St2>, [<Xn|SP>, #<imm>]!"},
303  {0xffc00000, 0x6cc00000, No_VFP,
304  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
305  "LDP <Dt>, <Dt2>, [<Xn|SP>, #<imm>]!"},
306  {0xffc00000, 0xacc00000, No_VFP,
307  &EmulateInstructionARM64::EmulateLDPSTP<AddrMode_POST>,
308  "LDP <Qt>, <Qt2>, [<Xn|SP>, #<imm>]!"},
309 
310  {0xffe00c00, 0xb8000400, No_VFP,
311  &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_POST>,
312  "STR <Wt>, [<Xn|SP>], #<simm>"},
313  {0xffe00c00, 0xf8000400, No_VFP,
314  &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_POST>,
315  "STR <Xt>, [<Xn|SP>], #<simm>"},
316  {0xffe00c00, 0xb8000c00, No_VFP,
317  &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_PRE>,
318  "STR <Wt>, [<Xn|SP>, #<simm>]!"},
319  {0xffe00c00, 0xf8000c00, No_VFP,
320  &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_PRE>,
321  "STR <Xt>, [<Xn|SP>, #<simm>]!"},
322  {0xffc00000, 0xb9000000, No_VFP,
323  &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_OFF>,
324  "STR <Wt>, [<Xn|SP>{, #<pimm>}]"},
325  {0xffc00000, 0xf9000000, No_VFP,
326  &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_OFF>,
327  "STR <Xt>, [<Xn|SP>{, #<pimm>}]"},
328 
329  {0xffe00c00, 0xb8400400, No_VFP,
330  &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_POST>,
331  "LDR <Wt>, [<Xn|SP>], #<simm>"},
332  {0xffe00c00, 0xf8400400, No_VFP,
333  &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_POST>,
334  "LDR <Xt>, [<Xn|SP>], #<simm>"},
335  {0xffe00c00, 0xb8400c00, No_VFP,
336  &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_PRE>,
337  "LDR <Wt>, [<Xn|SP>, #<simm>]!"},
338  {0xffe00c00, 0xf8400c00, No_VFP,
339  &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_PRE>,
340  "LDR <Xt>, [<Xn|SP>, #<simm>]!"},
341  {0xffc00000, 0xb9400000, No_VFP,
342  &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_OFF>,
343  "LDR <Wt>, [<Xn|SP>{, #<pimm>}]"},
344  {0xffc00000, 0xf9400000, No_VFP,
345  &EmulateInstructionARM64::EmulateLDRSTRImm<AddrMode_OFF>,
346  "LDR <Xt>, [<Xn|SP>{, #<pimm>}]"},
347 
348  {0xfc000000, 0x14000000, No_VFP, &EmulateInstructionARM64::EmulateB,
349  "B <label>"},
350  {0xff000010, 0x54000000, No_VFP, &EmulateInstructionARM64::EmulateBcond,
351  "B.<cond> <label>"},
352  {0x7f000000, 0x34000000, No_VFP, &EmulateInstructionARM64::EmulateCBZ,
353  "CBZ <Wt>, <label>"},
354  {0x7f000000, 0x35000000, No_VFP, &EmulateInstructionARM64::EmulateCBZ,
355  "CBNZ <Wt>, <label>"},
356  {0x7f000000, 0x36000000, No_VFP, &EmulateInstructionARM64::EmulateTBZ,
357  "TBZ <R><t>, #<imm>, <label>"},
358  {0x7f000000, 0x37000000, No_VFP, &EmulateInstructionARM64::EmulateTBZ,
359  "TBNZ <R><t>, #<imm>, <label>"},
360 
361  };
362  static const size_t k_num_arm_opcodes = std::size(g_opcodes);
363 
364  for (size_t i = 0; i < k_num_arm_opcodes; ++i) {
365  if ((g_opcodes[i].mask & opcode) == g_opcodes[i].value)
366  return &g_opcodes[i];
367  }
368  return nullptr;
369 }
370 
372  bool success = false;
373  m_addr = ReadRegisterUnsigned(eRegisterKindGeneric, LLDB_REGNUM_GENERIC_PC,
374  LLDB_INVALID_ADDRESS, &success);
375  if (success) {
376  Context read_inst_context;
377  read_inst_context.type = eContextReadOpcode;
378  read_inst_context.SetNoArgs();
379  m_opcode.SetOpcode32(
380  ReadMemoryUnsigned(read_inst_context, m_addr, 4, 0, &success),
381  GetByteOrder());
382  }
383  if (!success)
384  m_addr = LLDB_INVALID_ADDRESS;
385  return success;
386 }
387 
389  const uint32_t opcode = m_opcode.GetOpcode32();
390  Opcode *opcode_data = GetOpcodeForInstruction(opcode);
391  if (opcode_data == nullptr)
392  return false;
393 
394  const bool auto_advance_pc =
395  evaluate_options & eEmulateInstructionOptionAutoAdvancePC;
396  m_ignore_conditions =
397  evaluate_options & eEmulateInstructionOptionIgnoreConditions;
398 
399  bool success = false;
400 
401  // Only return false if we are unable to read the CPSR if we care about
402  // conditions
403  if (!success && !m_ignore_conditions)
404  return false;
405 
406  uint32_t orig_pc_value = 0;
407  if (auto_advance_pc) {
408  orig_pc_value =
409  ReadRegisterUnsigned(eRegisterKindLLDB, gpr_pc_arm64, 0, &success);
410  if (!success)
411  return false;
412  }
413 
414  // Call the Emulate... function.
415  success = (this->*opcode_data->callback)(opcode);
416  if (!success)
417  return false;
418 
419  if (auto_advance_pc) {
420  uint32_t new_pc_value =
421  ReadRegisterUnsigned(eRegisterKindLLDB, gpr_pc_arm64, 0, &success);
422  if (!success)
423  return false;
424 
425  if (new_pc_value == orig_pc_value) {
427  context.type = eContextAdvancePC;
428  context.SetNoArgs();
429  if (!WriteRegisterUnsigned(context, eRegisterKindLLDB, gpr_pc_arm64,
430  orig_pc_value + 4))
431  return false;
432  }
433  }
434  return true;
435 }
436 
438  UnwindPlan &unwind_plan) {
439  unwind_plan.Clear();
440  unwind_plan.SetRegisterKind(eRegisterKindLLDB);
441 
443 
444  // Our previous Call Frame Address is the stack pointer
445  row->GetCFAValue().SetIsRegisterPlusOffset(gpr_sp_arm64, 0);
446 
447  unwind_plan.AppendRow(row);
448  unwind_plan.SetSourceName("EmulateInstructionARM64");
449  unwind_plan.SetSourcedFromCompiler(eLazyBoolNo);
453  return true;
454 }
455 
457  if (m_arch.GetTriple().isAndroid())
458  return LLDB_INVALID_REGNUM; // Don't use frame pointer on android
459 
460  return gpr_fp_arm64;
461 }
462 
464  bool aarch32 = m_opcode_pstate.RW == 1;
465  // if !HaveAnyAArch32() then assert !aarch32;
466  // if HighestELUsingAArch32() then assert aarch32;
467  return aarch32;
468 }
469 
471  addr_t target) {
472 #if 0
473  // Set program counter to a new address, with a branch reason hint for
474  // possible use by hardware fetching the next instruction.
475  BranchTo(bits(N) target, BranchType branch_type)
476  Hint_Branch(branch_type);
477  if N == 32 then
478  assert UsingAArch32();
479  _PC = ZeroExtend(target);
480  else
481  assert N == 64 && !UsingAArch32();
482  // Remove the tag bits from a tagged target
483  case PSTATE.EL of
484  when EL0, EL1
485  if target<55> == '1' && TCR_EL1.TBI1 == '1' then
486  target<63:56> = '11111111';
487  if target<55> == '0' && TCR_EL1.TBI0 == '1' then
488  target<63:56> = '00000000';
489  when EL2
490  if TCR_EL2.TBI == '1' then
491  target<63:56> = '00000000';
492  when EL3
493  if TCR_EL3.TBI == '1' then
494  target<63:56> = '00000000';
495  _PC = target<63:0>;
496  return;
497 #endif
498 
499  addr_t addr;
500 
501  // Hint_Branch(branch_type);
502  if (N == 32) {
503  if (!UsingAArch32())
504  return false;
505  addr = target;
506  } else if (N == 64) {
507  if (UsingAArch32())
508  return false;
509  // TODO: Remove the tag bits from a tagged target
510  addr = target;
511  } else
512  return false;
513 
514  return WriteRegisterUnsigned(context, eRegisterKindGeneric,
515  LLDB_REGNUM_GENERIC_PC, addr);
516 }
517 
519  // If we are ignoring conditions, then always return true. this allows us to
520  // iterate over disassembly code and still emulate an instruction even if we
521  // don't have all the right bits set in the CPSR register...
522  if (m_ignore_conditions)
523  return true;
524 
525  bool result = false;
526  switch (UnsignedBits(cond, 3, 1)) {
527  case 0:
528  result = (m_opcode_pstate.Z == 1);
529  break;
530  case 1:
531  result = (m_opcode_pstate.C == 1);
532  break;
533  case 2:
534  result = (m_opcode_pstate.N == 1);
535  break;
536  case 3:
537  result = (m_opcode_pstate.V == 1);
538  break;
539  case 4:
540  result = (m_opcode_pstate.C == 1 && m_opcode_pstate.Z == 0);
541  break;
542  case 5:
543  result = (m_opcode_pstate.N == m_opcode_pstate.V);
544  break;
545  case 6:
546  result = (m_opcode_pstate.N == m_opcode_pstate.V && m_opcode_pstate.Z == 0);
547  break;
548  case 7:
549  // Always execute (cond == 0b1110, or the special 0b1111 which gives
550  // opcodes different meanings, but always means execution happens.
551  return true;
552  }
553 
554  if (cond & 1)
555  result = !result;
556  return result;
557 }
558 
560 AddWithCarry(uint32_t N, uint64_t x, uint64_t y, bit carry_in,
562  uint64_t unsigned_sum = UInt(x) + UInt(y) + UInt(carry_in);
563  std::optional<int64_t> signed_sum = llvm::checkedAdd(SInt(x), SInt(y));
564  bool overflow = !signed_sum;
565  if (!overflow)
566  overflow |= !llvm::checkedAdd(*signed_sum, SInt(carry_in));
567  uint64_t result = unsigned_sum;
568  if (N < 64)
569  result = Bits64(result, N - 1, 0);
570  proc_state.N = Bit64(result, N - 1);
571  proc_state.Z = IsZero(result);
572  proc_state.C = UInt(result) != unsigned_sum;
573  proc_state.V = overflow;
574  return result;
575 }
576 
578  // integer d = UInt(Rd);
579  // integer n = UInt(Rn);
580  // integer datasize = if sf == 1 then 64 else 32;
581  // boolean sub_op = (op == 1);
582  // boolean setflags = (S == 1);
583  // bits(datasize) imm;
584  //
585  // case shift of
586  // when '00' imm = ZeroExtend(imm12, datasize);
587  // when '01' imm = ZeroExtend(imm12 : Zeros(12), datasize);
588  // when '1x' UNDEFINED;
589  //
590  //
591  // bits(datasize) result;
592  // bits(datasize) operand1 = if n == 31 then SP[] else X[n];
593  // bits(datasize) operand2 = imm;
594  // bits(4) nzcv;
595  // bit carry_in;
596  //
597  // if sub_op then
598  // operand2 = NOT(operand2);
599  // carry_in = 1;
600  // else
601  // carry_in = 0;
602  //
603  // (result, nzcv) = AddWithCarry(operand1, operand2, carry_in);
604  //
605  // if setflags then
606  // PSTATE.NZCV = nzcv;
607  //
608  // if d == 31 && !setflags then
609  // SP[] = result;
610  // else
611  // X[d] = result;
612 
613  const uint32_t sf = Bit32(opcode, 31);
614  const uint32_t op = Bit32(opcode, 30);
615  const uint32_t S = Bit32(opcode, 29);
616  const uint32_t shift = Bits32(opcode, 23, 22);
617  const uint32_t imm12 = Bits32(opcode, 21, 10);
618  const uint32_t Rn = Bits32(opcode, 9, 5);
619  const uint32_t Rd = Bits32(opcode, 4, 0);
620 
621  bool success = false;
622 
623  const uint32_t d = UInt(Rd);
624  const uint32_t n = UInt(Rn);
625  const uint32_t datasize = (sf == 1) ? 64 : 32;
626  boolean sub_op = op == 1;
627  boolean setflags = S == 1;
628  uint64_t imm;
629 
630  switch (shift) {
631  case 0:
632  imm = imm12;
633  break;
634  case 1:
635  imm = static_cast<uint64_t>(imm12) << 12;
636  break;
637  default:
638  return false; // UNDEFINED;
639  }
640  uint64_t result;
641  uint64_t operand1 =
642  ReadRegisterUnsigned(eRegisterKindLLDB, gpr_x0_arm64 + n, 0, &success);
643  uint64_t operand2 = imm;
644  bit carry_in;
645 
646  if (sub_op) {
647  operand2 = NOT(operand2);
648  carry_in = true;
649  imm = -imm; // For the Register plug offset context below
650  } else {
651  carry_in = false;
652  }
653 
654  ProcState proc_state;
655 
656  result = AddWithCarry(datasize, operand1, operand2, carry_in, proc_state);
657 
658  if (setflags) {
659  m_emulated_pstate.N = proc_state.N;
660  m_emulated_pstate.Z = proc_state.Z;
661  m_emulated_pstate.C = proc_state.C;
662  m_emulated_pstate.V = proc_state.V;
663  }
664 
665  Context context;
666  llvm::Optional<RegisterInfo> reg_info_Rn =
667  GetRegisterInfo(eRegisterKindLLDB, n);
668  if (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  llvm::Optional<RegisterInfo> reg_info_base =
772  GetRegisterInfo(eRegisterKindLLDB, gpr_x0_arm64 + n);
773  if (!reg_info_base)
774  return false;
775 
776  llvm::Optional<RegisterInfo> reg_info_Rt;
777  llvm::Optional<RegisterInfo> reg_info_Rt2;
778 
779  if (vector) {
780  reg_info_Rt = GetRegisterInfo(eRegisterKindLLDB, fpu_d0_arm64 + t);
781  reg_info_Rt2 = GetRegisterInfo(eRegisterKindLLDB, fpu_d0_arm64 + t2);
782  } else {
783  reg_info_Rt = GetRegisterInfo(eRegisterKindLLDB, gpr_x0_arm64 + t);
784  reg_info_Rt2 = GetRegisterInfo(eRegisterKindLLDB, gpr_x0_arm64 + t2);
785  }
786 
787  if (!reg_info_Rt || !reg_info_Rt2)
788  return false;
789 
790  bool success = false;
791  if (n == 31) {
792  // CheckSPAlignment();
793  address =
794  ReadRegisterUnsigned(eRegisterKindLLDB, gpr_sp_arm64, 0, &success);
795  } else
796  address =
797  ReadRegisterUnsigned(eRegisterKindLLDB, gpr_x0_arm64 + n, 0, &success);
798 
799  wb_address = address + idx;
800  if (a_mode != AddrMode_POST)
801  address = wb_address;
802 
803  Context context_t;
804  Context context_t2;
805 
806  uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
807  Status error;
808 
809  switch (memop) {
810  case MemOp_STORE: {
811  if (n == 31 || n == GetFramePointerRegisterNumber()) // if this store is
812  // based off of the sp
813  // or fp register
814  {
815  context_t.type = eContextPushRegisterOnStack;
816  context_t2.type = eContextPushRegisterOnStack;
817  } else {
818  context_t.type = eContextRegisterStore;
819  context_t2.type = eContextRegisterStore;
820  }
821  context_t.SetRegisterToRegisterPlusOffset(*reg_info_Rt, *reg_info_base, 0);
822  context_t2.SetRegisterToRegisterPlusOffset(*reg_info_Rt2, *reg_info_base,
823  size);
824 
825  llvm::Optional<RegisterValue> data_Rt = ReadRegister(*reg_info_Rt);
826  if (!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  llvm::Optional<RegisterValue> data_Rt2 = ReadRegister(*reg_info_Rt2);
837  if (!data_Rt2)
838  return false;
839 
840  if (data_Rt2->GetAsMemoryData(*reg_info_Rt2, buffer,
841  reg_info_Rt2->byte_size, eByteOrderLittle,
842  error) == 0)
843  return false;
844 
845  if (!WriteMemory(context_t2, address + size, buffer,
846  reg_info_Rt2->byte_size))
847  return false;
848  } break;
849 
850  case MemOp_LOAD: {
851  if (n == 31 || n == GetFramePointerRegisterNumber()) // if this load is
852  // based off of the sp
853  // or fp register
854  {
855  context_t.type = eContextPopRegisterOffStack;
856  context_t2.type = eContextPopRegisterOffStack;
857  } else {
858  context_t.type = eContextRegisterLoad;
859  context_t2.type = eContextRegisterLoad;
860  }
861  context_t.SetAddress(address);
862  context_t2.SetAddress(address + size);
863 
864  if (rt_unknown)
865  memset(buffer, 'U', reg_info_Rt->byte_size);
866  else {
867  if (!ReadMemory(context_t, address, buffer, reg_info_Rt->byte_size))
868  return false;
869  }
870 
871  RegisterValue data_Rt;
872  if (data_Rt.SetFromMemoryData(*reg_info_Rt, buffer, reg_info_Rt->byte_size,
873  eByteOrderLittle, error) == 0)
874  return false;
875 
876  if (!vector && is_signed && !data_Rt.SignExtend(datasize))
877  return false;
878 
879  if (!WriteRegister(context_t, *reg_info_Rt, data_Rt))
880  return false;
881 
882  if (!rt_unknown) {
883  if (!ReadMemory(context_t2, address + size, buffer,
884  reg_info_Rt2->byte_size))
885  return false;
886  }
887 
888  RegisterValue data_Rt2;
889  if (data_Rt2.SetFromMemoryData(*reg_info_Rt2, buffer,
890  reg_info_Rt2->byte_size, eByteOrderLittle,
891  error) == 0)
892  return false;
893 
894  if (!vector && is_signed && !data_Rt2.SignExtend(datasize))
895  return false;
896 
897  if (!WriteRegister(context_t2, *reg_info_Rt2, data_Rt2))
898  return false;
899  } break;
900 
901  default:
902  break;
903  }
904 
905  if (wback) {
906  if (wb_unknown)
907  wb_address = LLDB_INVALID_ADDRESS;
908  Context context;
909  context.SetImmediateSigned(idx);
910  if (n == 31)
911  context.type = eContextAdjustStackPointer;
912  else
913  context.type = eContextAdjustBaseRegister;
914  WriteRegisterUnsigned(context, *reg_info_base, wb_address);
915  }
916  return true;
917 }
918 
919 template <EmulateInstructionARM64::AddrMode a_mode>
921  uint32_t size = Bits32(opcode, 31, 30);
922  uint32_t opc = Bits32(opcode, 23, 22);
923  uint32_t n = Bits32(opcode, 9, 5);
924  uint32_t t = Bits32(opcode, 4, 0);
925 
926  bool wback;
927  bool postindex;
928  uint64_t offset;
929 
930  switch (a_mode) {
931  case AddrMode_POST:
932  wback = true;
933  postindex = true;
934  offset = llvm::SignExtend64<9>(Bits32(opcode, 20, 12));
935  break;
936  case AddrMode_PRE:
937  wback = true;
938  postindex = false;
939  offset = llvm::SignExtend64<9>(Bits32(opcode, 20, 12));
940  break;
941  case AddrMode_OFF:
942  wback = false;
943  postindex = false;
944  offset = LSL(Bits32(opcode, 21, 10), size);
945  break;
946  }
947 
948  MemOp memop;
949 
950  if (Bit32(opc, 1) == 0) {
951  memop = Bit32(opc, 0) == 1 ? MemOp_LOAD : MemOp_STORE;
952  } else {
953  memop = MemOp_LOAD;
954  if (size == 2 && Bit32(opc, 0) == 1)
955  return false;
956  }
957 
958  Status error;
959  bool success = false;
960  uint64_t address;
961  uint8_t buffer[RegisterValue::kMaxRegisterByteSize];
962 
963  if (n == 31)
964  address =
965  ReadRegisterUnsigned(eRegisterKindLLDB, gpr_sp_arm64, 0, &success);
966  else
967  address =
968  ReadRegisterUnsigned(eRegisterKindLLDB, gpr_x0_arm64 + n, 0, &success);
969 
970  if (!success)
971  return false;
972 
973  if (!postindex)
974  address += offset;
975 
976  llvm::Optional<RegisterInfo> reg_info_base =
977  GetRegisterInfo(eRegisterKindLLDB, gpr_x0_arm64 + n);
978  if (!reg_info_base)
979  return false;
980 
981  llvm::Optional<RegisterInfo> reg_info_Rt =
982  GetRegisterInfo(eRegisterKindLLDB, gpr_x0_arm64 + t);
983  if (!reg_info_Rt)
984  return false;
985 
986  Context context;
987  switch (memop) {
988  case MemOp_STORE: {
989  if (n == 31 || n == GetFramePointerRegisterNumber()) // if this store is
990  // based off of the sp
991  // or fp register
992  context.type = eContextPushRegisterOnStack;
993  else
994  context.type = eContextRegisterStore;
995  context.SetRegisterToRegisterPlusOffset(*reg_info_Rt, *reg_info_base,
996  postindex ? 0 : offset);
997 
998  llvm::Optional<RegisterValue> data_Rt = ReadRegister(*reg_info_Rt);
999  if (!data_Rt)
1000  return false;
1001 
1002  if (data_Rt->GetAsMemoryData(*reg_info_Rt, buffer, reg_info_Rt->byte_size,
1003  eByteOrderLittle, error) == 0)
1004  return false;
1005 
1006  if (!WriteMemory(context, address, buffer, reg_info_Rt->byte_size))
1007  return false;
1008  } break;
1009 
1010  case MemOp_LOAD: {
1011  if (n == 31 || n == GetFramePointerRegisterNumber()) // if this store is
1012  // based off of the sp
1013  // or fp register
1014  context.type = eContextPopRegisterOffStack;
1015  else
1016  context.type = eContextRegisterLoad;
1017  context.SetAddress(address);
1018 
1019  if (!ReadMemory(context, address, buffer, reg_info_Rt->byte_size))
1020  return false;
1021 
1022  RegisterValue data_Rt;
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 }
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
llvm
Definition: Debugger.h:50
lldb_private::UnwindPlan::AppendRow
void AppendRow(const RowSP &row_sp)
Definition: UnwindPlan.cpp:362
lldb_private::ArchSpec
Definition: ArchSpec.h:32
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:560
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:83
LLDB_INVALID_REGNUM
#define LLDB_INVALID_REGNUM
Definition: lldb-defines.h:79
lldb_private::gpr_cpsr_arm64
@ gpr_cpsr_arm64
Definition: lldb-arm64-register-enums.h:51
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::fpu_d0_arm64
@ fpu_d0_arm64
Definition: lldb-arm64-register-enums.h:152
lldb::eRegisterKindGeneric
@ eRegisterKindGeneric
insn ptr reg, stack ptr reg, etc not specific to any particular target
Definition: lldb-enumerations.h:231
EmulateInstructionARM64::Terminate
static void Terminate()
Definition: EmulateInstructionARM64.cpp:115
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:920
lldb_private::eLazyBoolYes
@ eLazyBoolYes
Definition: lldb-private-enumerations.h:115
lldb_private::EmulateInstruction::Context
Definition: EmulateInstruction.h:184
EmulateInstructionARM64::GetOpcodeForInstruction
static Opcode * GetOpcodeForInstruction(const uint32_t opcode)
Definition: EmulateInstructionARM64.cpp:183
NOT
static uint64_t NOT(uint64_t x)
Definition: EmulateInstructionARM64.cpp:78
EmulateInstructionARM64::GetPluginDescriptionStatic
static llvm::StringRef GetPluginDescriptionStatic()
Definition: EmulateInstructionARM64.cpp:119
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:456
EmulateInstructionARM64::Unpredictable_LDPOVERLAP
@ Unpredictable_LDPOVERLAP
Definition: EmulateInstructionARM64.h:115
lldb_private::ArchSpec::GetTriple
llvm::Triple & GetTriple()
Architecture triple accessor.
Definition: ArchSpec.h:463
lldb::addr_t
uint64_t addr_t
Definition: lldb-types.h:83
lldb_private::gpr_sp_arm64
@ gpr_sp_arm64
Definition: lldb-arm64-register-enums.h:49
pc
@ pc
Definition: CompactUnwindInfo.cpp:1251
lldb_private::UnwindPlan::SetSourceName
void SetSourceName(const char *)
Definition: UnwindPlan.cpp:564
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:437
ARMUtils.h
UInt
#define UInt(x)
Definition: EmulateInstructionARM64.cpp:70
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:577
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:235
EmulateInstructionARM64::ConditionHolds
bool ConditionHolds(const uint32_t cond)
Definition: EmulateInstructionARM64.cpp:518
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:249
bit
#define bit
Definition: EmulateInstructionARM64.cpp:72
lldb_private::EmulateInstruction::Context::SetRegisterToRegisterPlusOffset
void SetRegisterToRegisterPlusOffset(RegisterInfo data_reg, RegisterInfo base_reg, int64_t offset)
Definition: EmulateInstruction.h:262
No_VFP
#define No_VFP
Definition: EmulateInstructionARM64.cpp:60
lldb_private::gpr_lr_arm64
@ gpr_lr_arm64
Definition: lldb-arm64-register-enums.h:48
ARMDefines.h
RegisterInfos_arm64.h
EmulateInstructionARM64::MemOp
MemOp
Definition: EmulateInstructionARM64.h:107
arm64_dwarf::x30
@ x30
Definition: ARM64_DWARF_Registers.h:48
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:124
EmulateInstructionARM64::ReadInstruction
bool ReadInstruction() override
Definition: EmulateInstructionARM64.cpp:371
Address.h
UnwindPlan.h
InstructionUtils.h
lldb::RegisterKind
RegisterKind
Register numbering types.
Definition: lldb-enumerations.h:228
lldb_private::UnwindPlan::RowSP
std::shared_ptr< Row > RowSP
Definition: UnwindPlan.h:395
IsZero
static bool IsZero(uint64_t x)
Definition: EmulateInstructionARM64.cpp:76
EmulateInstructionARM64.h
LLDBTableGetRegisterInfo
static llvm::Optional< RegisterInfo > LLDBTableGetRegisterInfo(uint32_t reg_num)
Definition: EmulateInstructionARM64.cpp:54
lldb_private::UnwindPlan::Clear
void Clear()
Definition: UnwindPlan.h:508
lldb_private::Status
Definition: Status.h:44
SInt
#define SInt(x)
Definition: EmulateInstructionARM64.cpp:71
lldb_private::EmulateInstruction::Context::SetNoArgs
void SetNoArgs()
Definition: EmulateInstruction.h:328
EmulateInstructionARM64::EmulateBcond
bool EmulateBcond(const uint32_t opcode)
Definition: EmulateInstructionARM64.cpp:1086
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::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:79
lldb_private::gpr_x0_arm64
@ gpr_x0_arm64
Definition: lldb-arm64-register-enums.h:18
lldb_private::Rd
Definition: RISCVInstructions.h:22
ArchSpec.h
EmulateInstructionARM64::EmulateCBZ
bool EmulateCBZ(const uint32_t opcode)
Definition: EmulateInstructionARM64.cpp:1115
EmulateInstructionARM64::Initialize
static void Initialize()
Definition: EmulateInstructionARM64.cpp:110
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:388
lldb_private::InstructionType
InstructionType
Instruction types.
Definition: lldb-private-enumerations.h:118
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:470
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:307
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:452
lldb_private::gpr_pc_arm64
@ gpr_pc_arm64
Definition: lldb-arm64-register-enums.h:50
EmulateInstructionARM64::UsingAArch32
bool UsingAArch32()
Definition: EmulateInstructionARM64.cpp:463
Stream.h
EmulateInstructionARM64::SetTargetTriple
bool SetTargetTriple(const lldb_private::ArchSpec &arch) override
Definition: EmulateInstructionARM64.cpp:137
EmulateInstructionARM64::EmulateB
bool EmulateB(const uint32_t opcode)
Definition: EmulateInstructionARM64.cpp:1050
lldb_private::bits
static uint32_t bits(const uint32_t val, const uint32_t msbit, const uint32_t lsbit)
Definition: ARMUtils.h:265
EmulateInstructionARM64::ProcState::C
uint32_t C
Definition: EmulateInstructionARM64.h:133
integer
#define integer
Definition: EmulateInstructionARM64.cpp:74
lldb::eByteOrderLittle
@ eByteOrderLittle
Definition: lldb-enumerations.h:143
lldb_private::EmulateInstruction::Context::SetImmediateSigned
void SetImmediateSigned(int64_t signed_immediate)
Definition: EmulateInstruction.h:302
ConstrainUnpredictable
EmulateInstructionARM64::ConstraintType ConstrainUnpredictable(EmulateInstructionARM64::Unpredictable which)
Definition: EmulateInstructionARM64.cpp:93
lldb_private::Bits64
static uint64_t Bits64(const uint64_t bits, const uint32_t msbit, const uint32_t lsbit)
Definition: InstructionUtils.h:21
EmulateInstructionARM64::GetRegisterInfo
llvm::Optional< lldb_private::RegisterInfo > GetRegisterInfo(lldb::RegisterKind reg_kind, uint32_t reg_num) override
Definition: EmulateInstructionARM64.cpp:147
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:1153
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
lldb_private::gpr_fp_arm64
@ gpr_fp_arm64
Definition: lldb-arm64-register-enums.h:47