LLDB  mainline
DisassemblerLLVMC.cpp
Go to the documentation of this file.
1 //===-- DisassemblerLLVMC.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 
9 #include "DisassemblerLLVMC.h"
10 
11 #include "llvm-c/Disassembler.h"
12 #include "llvm/ADT/SmallString.h"
13 #include "llvm/MC/MCAsmInfo.h"
14 #include "llvm/MC/MCContext.h"
15 #include "llvm/MC/MCDisassembler/MCDisassembler.h"
16 #include "llvm/MC/MCDisassembler/MCExternalSymbolizer.h"
17 #include "llvm/MC/MCDisassembler/MCRelocationInfo.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/MC/MCInstPrinter.h"
20 #include "llvm/MC/MCInstrInfo.h"
21 #include "llvm/MC/MCRegisterInfo.h"
22 #include "llvm/MC/MCSubtargetInfo.h"
23 #include "llvm/MC/MCTargetOptions.h"
24 #include "llvm/MC/TargetRegistry.h"
25 #include "llvm/Support/ErrorHandling.h"
26 #include "llvm/Support/ScopedPrinter.h"
27 #include "llvm/Support/TargetSelect.h"
28 
29 #include "lldb/Core/Address.h"
30 #include "lldb/Core/Module.h"
33 #include "lldb/Target/Process.h"
36 #include "lldb/Target/StackFrame.h"
37 #include "lldb/Target/Target.h"
39 #include "lldb/Utility/Log.h"
41 #include "lldb/Utility/Stream.h"
42 
43 using namespace lldb;
44 using namespace lldb_private;
45 
47 
49 public:
50  static std::unique_ptr<MCDisasmInstance>
51  Create(const char *triple, const char *cpu, const char *features_str,
52  unsigned flavor, DisassemblerLLVMC &owner);
53 
54  ~MCDisasmInstance() = default;
55 
56  uint64_t GetMCInst(const uint8_t *opcode_data, size_t opcode_data_len,
57  lldb::addr_t pc, llvm::MCInst &mc_inst) const;
58  void PrintMCInst(llvm::MCInst &mc_inst, std::string &inst_string,
59  std::string &comments_string);
60  void SetStyle(bool use_hex_immed, HexImmediateStyle hex_style);
61  bool CanBranch(llvm::MCInst &mc_inst) const;
62  bool HasDelaySlot(llvm::MCInst &mc_inst) const;
63  bool IsCall(llvm::MCInst &mc_inst) const;
64  bool IsLoad(llvm::MCInst &mc_inst) const;
65  bool IsAuthenticated(llvm::MCInst &mc_inst) const;
66 
67 private:
68  MCDisasmInstance(std::unique_ptr<llvm::MCInstrInfo> &&instr_info_up,
69  std::unique_ptr<llvm::MCRegisterInfo> &&reg_info_up,
70  std::unique_ptr<llvm::MCSubtargetInfo> &&subtarget_info_up,
71  std::unique_ptr<llvm::MCAsmInfo> &&asm_info_up,
72  std::unique_ptr<llvm::MCContext> &&context_up,
73  std::unique_ptr<llvm::MCDisassembler> &&disasm_up,
74  std::unique_ptr<llvm::MCInstPrinter> &&instr_printer_up);
75 
76  std::unique_ptr<llvm::MCInstrInfo> m_instr_info_up;
77  std::unique_ptr<llvm::MCRegisterInfo> m_reg_info_up;
78  std::unique_ptr<llvm::MCSubtargetInfo> m_subtarget_info_up;
79  std::unique_ptr<llvm::MCAsmInfo> m_asm_info_up;
80  std::unique_ptr<llvm::MCContext> m_context_up;
81  std::unique_ptr<llvm::MCDisassembler> m_disasm_up;
82  std::unique_ptr<llvm::MCInstPrinter> m_instr_printer_up;
83 };
84 
86 public:
88  const lldb_private::Address &address,
89  AddressClass addr_class)
90  : Instruction(address, addr_class),
91  m_disasm_wp(std::static_pointer_cast<DisassemblerLLVMC>(
92  disasm.shared_from_this())),
93  m_using_file_addr(false) {}
94 
95  ~InstructionLLVMC() override = default;
96 
97  bool DoesBranch() override {
98  VisitInstruction();
99  return m_does_branch;
100  }
101 
102  bool HasDelaySlot() override {
103  VisitInstruction();
104  return m_has_delay_slot;
105  }
106 
107  bool IsLoad() override {
108  VisitInstruction();
109  return m_is_load;
110  }
111 
112  bool IsAuthenticated() override {
113  VisitInstruction();
114  return m_is_authenticated;
115  }
116 
118  DisassemblerScope disasm(*this);
119  return GetDisasmToUse(is_alternate_isa, disasm);
120  }
121 
122  size_t Decode(const lldb_private::Disassembler &disassembler,
123  const lldb_private::DataExtractor &data,
124  lldb::offset_t data_offset) override {
125  // All we have to do is read the opcode which can be easy for some
126  // architectures
127  bool got_op = false;
128  DisassemblerScope disasm(*this);
129  if (disasm) {
130  const ArchSpec &arch = disasm->GetArchitecture();
131  const lldb::ByteOrder byte_order = data.GetByteOrder();
132 
133  const uint32_t min_op_byte_size = arch.GetMinimumOpcodeByteSize();
134  const uint32_t max_op_byte_size = arch.GetMaximumOpcodeByteSize();
135  if (min_op_byte_size == max_op_byte_size) {
136  // Fixed size instructions, just read that amount of data.
137  if (!data.ValidOffsetForDataOfSize(data_offset, min_op_byte_size))
138  return false;
139 
140  switch (min_op_byte_size) {
141  case 1:
142  m_opcode.SetOpcode8(data.GetU8(&data_offset), byte_order);
143  got_op = true;
144  break;
145 
146  case 2:
147  m_opcode.SetOpcode16(data.GetU16(&data_offset), byte_order);
148  got_op = true;
149  break;
150 
151  case 4:
152  m_opcode.SetOpcode32(data.GetU32(&data_offset), byte_order);
153  got_op = true;
154  break;
155 
156  case 8:
157  m_opcode.SetOpcode64(data.GetU64(&data_offset), byte_order);
158  got_op = true;
159  break;
160 
161  default:
162  m_opcode.SetOpcodeBytes(data.PeekData(data_offset, min_op_byte_size),
163  min_op_byte_size);
164  got_op = true;
165  break;
166  }
167  }
168  if (!got_op) {
169  bool is_alternate_isa = false;
170  DisassemblerLLVMC::MCDisasmInstance *mc_disasm_ptr =
171  GetDisasmToUse(is_alternate_isa, disasm);
172 
173  const llvm::Triple::ArchType machine = arch.GetMachine();
174  if (machine == llvm::Triple::arm || machine == llvm::Triple::thumb) {
175  if (machine == llvm::Triple::thumb || is_alternate_isa) {
176  uint32_t thumb_opcode = data.GetU16(&data_offset);
177  if ((thumb_opcode & 0xe000) != 0xe000 ||
178  ((thumb_opcode & 0x1800u) == 0)) {
179  m_opcode.SetOpcode16(thumb_opcode, byte_order);
180  m_is_valid = true;
181  } else {
182  thumb_opcode <<= 16;
183  thumb_opcode |= data.GetU16(&data_offset);
184  m_opcode.SetOpcode16_2(thumb_opcode, byte_order);
185  m_is_valid = true;
186  }
187  } else {
188  m_opcode.SetOpcode32(data.GetU32(&data_offset), byte_order);
189  m_is_valid = true;
190  }
191  } else {
192  // The opcode isn't evenly sized, so we need to actually use the llvm
193  // disassembler to parse it and get the size.
194  uint8_t *opcode_data =
195  const_cast<uint8_t *>(data.PeekData(data_offset, 1));
196  const size_t opcode_data_len = data.BytesLeft(data_offset);
197  const addr_t pc = m_address.GetFileAddress();
198  llvm::MCInst inst;
199 
200  const size_t inst_size =
201  mc_disasm_ptr->GetMCInst(opcode_data, opcode_data_len, pc, inst);
202  if (inst_size == 0)
203  m_opcode.Clear();
204  else {
205  m_opcode.SetOpcodeBytes(opcode_data, inst_size);
206  m_is_valid = true;
207  }
208  }
209  }
210  return m_opcode.GetByteSize();
211  }
212  return 0;
213  }
214 
215  void AppendComment(std::string &description) {
216  if (m_comment.empty())
217  m_comment.swap(description);
218  else {
219  m_comment.append(", ");
220  m_comment.append(description);
221  }
222  }
223 
225  const lldb_private::ExecutionContext *exe_ctx) override {
226  DataExtractor data;
227  const AddressClass address_class = GetAddressClass();
228 
229  if (m_opcode.GetData(data)) {
230  std::string out_string;
231  std::string comment_string;
232 
233  DisassemblerScope disasm(*this, exe_ctx);
234  if (disasm) {
236 
237  if (address_class == AddressClass::eCodeAlternateISA)
238  mc_disasm_ptr = disasm->m_alternate_disasm_up.get();
239  else
240  mc_disasm_ptr = disasm->m_disasm_up.get();
241 
242  lldb::addr_t pc = m_address.GetFileAddress();
243  m_using_file_addr = true;
244 
245  const bool data_from_file = disasm->m_data_from_file;
246  bool use_hex_immediates = true;
247  Disassembler::HexImmediateStyle hex_style = Disassembler::eHexStyleC;
248 
249  if (exe_ctx) {
250  Target *target = exe_ctx->GetTargetPtr();
251  if (target) {
252  use_hex_immediates = target->GetUseHexImmediates();
253  hex_style = target->GetHexImmediateStyle();
254 
255  if (!data_from_file) {
256  const lldb::addr_t load_addr = m_address.GetLoadAddress(target);
257  if (load_addr != LLDB_INVALID_ADDRESS) {
258  pc = load_addr;
259  m_using_file_addr = false;
260  }
261  }
262  }
263  }
264 
265  const uint8_t *opcode_data = data.GetDataStart();
266  const size_t opcode_data_len = data.GetByteSize();
267  llvm::MCInst inst;
268  size_t inst_size =
269  mc_disasm_ptr->GetMCInst(opcode_data, opcode_data_len, pc, inst);
270 
271  if (inst_size > 0) {
272  mc_disasm_ptr->SetStyle(use_hex_immediates, hex_style);
273  mc_disasm_ptr->PrintMCInst(inst, out_string, comment_string);
274 
275  if (!comment_string.empty()) {
276  AppendComment(comment_string);
277  }
278  }
279 
280  if (inst_size == 0) {
281  m_comment.assign("unknown opcode");
282  inst_size = m_opcode.GetByteSize();
283  StreamString mnemonic_strm;
284  lldb::offset_t offset = 0;
285  lldb::ByteOrder byte_order = data.GetByteOrder();
286  switch (inst_size) {
287  case 1: {
288  const uint8_t uval8 = data.GetU8(&offset);
289  m_opcode.SetOpcode8(uval8, byte_order);
290  m_opcode_name.assign(".byte");
291  mnemonic_strm.Printf("0x%2.2x", uval8);
292  } break;
293  case 2: {
294  const uint16_t uval16 = data.GetU16(&offset);
295  m_opcode.SetOpcode16(uval16, byte_order);
296  m_opcode_name.assign(".short");
297  mnemonic_strm.Printf("0x%4.4x", uval16);
298  } break;
299  case 4: {
300  const uint32_t uval32 = data.GetU32(&offset);
301  m_opcode.SetOpcode32(uval32, byte_order);
302  m_opcode_name.assign(".long");
303  mnemonic_strm.Printf("0x%8.8x", uval32);
304  } break;
305  case 8: {
306  const uint64_t uval64 = data.GetU64(&offset);
307  m_opcode.SetOpcode64(uval64, byte_order);
308  m_opcode_name.assign(".quad");
309  mnemonic_strm.Printf("0x%16.16" PRIx64, uval64);
310  } break;
311  default:
312  if (inst_size == 0)
313  return;
314  else {
315  const uint8_t *bytes = data.PeekData(offset, inst_size);
316  if (bytes == nullptr)
317  return;
318  m_opcode_name.assign(".byte");
319  m_opcode.SetOpcodeBytes(bytes, inst_size);
320  mnemonic_strm.Printf("0x%2.2x", bytes[0]);
321  for (uint32_t i = 1; i < inst_size; ++i)
322  mnemonic_strm.Printf(" 0x%2.2x", bytes[i]);
323  }
324  break;
325  }
326  m_mnemonics = std::string(mnemonic_strm.GetString());
327  return;
328  }
329 
330  static RegularExpression s_regex(
331  llvm::StringRef("[ \t]*([^ ^\t]+)[ \t]*([^ ^\t].*)?"));
332 
333  llvm::SmallVector<llvm::StringRef, 4> matches;
334  if (s_regex.Execute(out_string, &matches)) {
335  m_opcode_name = matches[1].str();
336  m_mnemonics = matches[2].str();
337  }
338  }
339  }
340  }
341 
342  bool IsValid() const { return m_is_valid; }
343 
344  bool UsingFileAddress() const { return m_using_file_addr; }
345  size_t GetByteSize() const { return m_opcode.GetByteSize(); }
346 
347  /// Grants exclusive access to the disassembler and initializes it with the
348  /// given InstructionLLVMC and an optional ExecutionContext.
350  std::shared_ptr<DisassemblerLLVMC> m_disasm;
351 
352  public:
354  InstructionLLVMC &i,
355  const lldb_private::ExecutionContext *exe_ctx = nullptr)
356  : m_disasm(i.m_disasm_wp.lock()) {
357  m_disasm->m_mutex.lock();
358  m_disasm->m_inst = &i;
359  m_disasm->m_exe_ctx = exe_ctx;
360  }
361  ~DisassemblerScope() { m_disasm->m_mutex.unlock(); }
362 
363  /// Evaluates to true if this scope contains a valid disassembler.
364  operator bool() const { return static_cast<bool>(m_disasm); }
365 
366  std::shared_ptr<DisassemblerLLVMC> operator->() { return m_disasm; }
367  };
368 
369  static llvm::StringRef::const_iterator
370  ConsumeWhitespace(llvm::StringRef::const_iterator osi,
371  llvm::StringRef::const_iterator ose) {
372  while (osi != ose) {
373  switch (*osi) {
374  default:
375  return osi;
376  case ' ':
377  case '\t':
378  break;
379  }
380  ++osi;
381  }
382 
383  return osi;
384  }
385 
386  static std::pair<bool, llvm::StringRef::const_iterator>
387  ConsumeChar(llvm::StringRef::const_iterator osi, const char c,
388  llvm::StringRef::const_iterator ose) {
389  bool found = false;
390 
391  osi = ConsumeWhitespace(osi, ose);
392  if (osi != ose && *osi == c) {
393  found = true;
394  ++osi;
395  }
396 
397  return std::make_pair(found, osi);
398  }
399 
400  static std::pair<Operand, llvm::StringRef::const_iterator>
401  ParseRegisterName(llvm::StringRef::const_iterator osi,
402  llvm::StringRef::const_iterator ose) {
403  Operand ret;
404  ret.m_type = Operand::Type::Register;
405  std::string str;
406 
407  osi = ConsumeWhitespace(osi, ose);
408 
409  while (osi != ose) {
410  if (*osi >= '0' && *osi <= '9') {
411  if (str.empty()) {
412  return std::make_pair(Operand(), osi);
413  } else {
414  str.push_back(*osi);
415  }
416  } else if (*osi >= 'a' && *osi <= 'z') {
417  str.push_back(*osi);
418  } else {
419  switch (*osi) {
420  default:
421  if (str.empty()) {
422  return std::make_pair(Operand(), osi);
423  } else {
424  ret.m_register = ConstString(str);
425  return std::make_pair(ret, osi);
426  }
427  case '%':
428  if (!str.empty()) {
429  return std::make_pair(Operand(), osi);
430  }
431  break;
432  }
433  }
434  ++osi;
435  }
436 
437  ret.m_register = ConstString(str);
438  return std::make_pair(ret, osi);
439  }
440 
441  static std::pair<Operand, llvm::StringRef::const_iterator>
442  ParseImmediate(llvm::StringRef::const_iterator osi,
443  llvm::StringRef::const_iterator ose) {
444  Operand ret;
445  ret.m_type = Operand::Type::Immediate;
446  std::string str;
447  bool is_hex = false;
448 
449  osi = ConsumeWhitespace(osi, ose);
450 
451  while (osi != ose) {
452  if (*osi >= '0' && *osi <= '9') {
453  str.push_back(*osi);
454  } else if (*osi >= 'a' && *osi <= 'f') {
455  if (is_hex) {
456  str.push_back(*osi);
457  } else {
458  return std::make_pair(Operand(), osi);
459  }
460  } else {
461  switch (*osi) {
462  default:
463  if (str.empty()) {
464  return std::make_pair(Operand(), osi);
465  } else {
466  ret.m_immediate = strtoull(str.c_str(), nullptr, 0);
467  return std::make_pair(ret, osi);
468  }
469  case 'x':
470  if (!str.compare("0")) {
471  is_hex = true;
472  str.push_back(*osi);
473  } else {
474  return std::make_pair(Operand(), osi);
475  }
476  break;
477  case '#':
478  case '$':
479  if (!str.empty()) {
480  return std::make_pair(Operand(), osi);
481  }
482  break;
483  case '-':
484  if (str.empty()) {
485  ret.m_negative = true;
486  } else {
487  return std::make_pair(Operand(), osi);
488  }
489  }
490  }
491  ++osi;
492  }
493 
494  ret.m_immediate = strtoull(str.c_str(), nullptr, 0);
495  return std::make_pair(ret, osi);
496  }
497 
498  // -0x5(%rax,%rax,2)
499  static std::pair<Operand, llvm::StringRef::const_iterator>
500  ParseIntelIndexedAccess(llvm::StringRef::const_iterator osi,
501  llvm::StringRef::const_iterator ose) {
502  std::pair<Operand, llvm::StringRef::const_iterator> offset_and_iterator =
503  ParseImmediate(osi, ose);
504  if (offset_and_iterator.first.IsValid()) {
505  osi = offset_and_iterator.second;
506  }
507 
508  bool found = false;
509  std::tie(found, osi) = ConsumeChar(osi, '(', ose);
510  if (!found) {
511  return std::make_pair(Operand(), osi);
512  }
513 
514  std::pair<Operand, llvm::StringRef::const_iterator> base_and_iterator =
515  ParseRegisterName(osi, ose);
516  if (base_and_iterator.first.IsValid()) {
517  osi = base_and_iterator.second;
518  } else {
519  return std::make_pair(Operand(), osi);
520  }
521 
522  std::tie(found, osi) = ConsumeChar(osi, ',', ose);
523  if (!found) {
524  return std::make_pair(Operand(), osi);
525  }
526 
527  std::pair<Operand, llvm::StringRef::const_iterator> index_and_iterator =
528  ParseRegisterName(osi, ose);
529  if (index_and_iterator.first.IsValid()) {
530  osi = index_and_iterator.second;
531  } else {
532  return std::make_pair(Operand(), osi);
533  }
534 
535  std::tie(found, osi) = ConsumeChar(osi, ',', ose);
536  if (!found) {
537  return std::make_pair(Operand(), osi);
538  }
539 
540  std::pair<Operand, llvm::StringRef::const_iterator>
541  multiplier_and_iterator = ParseImmediate(osi, ose);
542  if (index_and_iterator.first.IsValid()) {
543  osi = index_and_iterator.second;
544  } else {
545  return std::make_pair(Operand(), osi);
546  }
547 
548  std::tie(found, osi) = ConsumeChar(osi, ')', ose);
549  if (!found) {
550  return std::make_pair(Operand(), osi);
551  }
552 
553  Operand product;
554  product.m_type = Operand::Type::Product;
555  product.m_children.push_back(index_and_iterator.first);
556  product.m_children.push_back(multiplier_and_iterator.first);
557 
558  Operand index;
559  index.m_type = Operand::Type::Sum;
560  index.m_children.push_back(base_and_iterator.first);
561  index.m_children.push_back(product);
562 
563  if (offset_and_iterator.first.IsValid()) {
564  Operand offset;
565  offset.m_type = Operand::Type::Sum;
566  offset.m_children.push_back(offset_and_iterator.first);
567  offset.m_children.push_back(index);
568 
569  Operand deref;
570  deref.m_type = Operand::Type::Dereference;
571  deref.m_children.push_back(offset);
572  return std::make_pair(deref, osi);
573  } else {
574  Operand deref;
575  deref.m_type = Operand::Type::Dereference;
576  deref.m_children.push_back(index);
577  return std::make_pair(deref, osi);
578  }
579  }
580 
581  // -0x10(%rbp)
582  static std::pair<Operand, llvm::StringRef::const_iterator>
583  ParseIntelDerefAccess(llvm::StringRef::const_iterator osi,
584  llvm::StringRef::const_iterator ose) {
585  std::pair<Operand, llvm::StringRef::const_iterator> offset_and_iterator =
586  ParseImmediate(osi, ose);
587  if (offset_and_iterator.first.IsValid()) {
588  osi = offset_and_iterator.second;
589  }
590 
591  bool found = false;
592  std::tie(found, osi) = ConsumeChar(osi, '(', ose);
593  if (!found) {
594  return std::make_pair(Operand(), osi);
595  }
596 
597  std::pair<Operand, llvm::StringRef::const_iterator> base_and_iterator =
598  ParseRegisterName(osi, ose);
599  if (base_and_iterator.first.IsValid()) {
600  osi = base_and_iterator.second;
601  } else {
602  return std::make_pair(Operand(), osi);
603  }
604 
605  std::tie(found, osi) = ConsumeChar(osi, ')', ose);
606  if (!found) {
607  return std::make_pair(Operand(), osi);
608  }
609 
610  if (offset_and_iterator.first.IsValid()) {
611  Operand offset;
612  offset.m_type = Operand::Type::Sum;
613  offset.m_children.push_back(offset_and_iterator.first);
614  offset.m_children.push_back(base_and_iterator.first);
615 
616  Operand deref;
617  deref.m_type = Operand::Type::Dereference;
618  deref.m_children.push_back(offset);
619  return std::make_pair(deref, osi);
620  } else {
621  Operand deref;
622  deref.m_type = Operand::Type::Dereference;
623  deref.m_children.push_back(base_and_iterator.first);
624  return std::make_pair(deref, osi);
625  }
626  }
627 
628  // [sp, #8]!
629  static std::pair<Operand, llvm::StringRef::const_iterator>
630  ParseARMOffsetAccess(llvm::StringRef::const_iterator osi,
631  llvm::StringRef::const_iterator ose) {
632  bool found = false;
633  std::tie(found, osi) = ConsumeChar(osi, '[', ose);
634  if (!found) {
635  return std::make_pair(Operand(), osi);
636  }
637 
638  std::pair<Operand, llvm::StringRef::const_iterator> base_and_iterator =
639  ParseRegisterName(osi, ose);
640  if (base_and_iterator.first.IsValid()) {
641  osi = base_and_iterator.second;
642  } else {
643  return std::make_pair(Operand(), osi);
644  }
645 
646  std::tie(found, osi) = ConsumeChar(osi, ',', ose);
647  if (!found) {
648  return std::make_pair(Operand(), osi);
649  }
650 
651  std::pair<Operand, llvm::StringRef::const_iterator> offset_and_iterator =
652  ParseImmediate(osi, ose);
653  if (offset_and_iterator.first.IsValid()) {
654  osi = offset_and_iterator.second;
655  }
656 
657  std::tie(found, osi) = ConsumeChar(osi, ']', ose);
658  if (!found) {
659  return std::make_pair(Operand(), osi);
660  }
661 
662  Operand offset;
663  offset.m_type = Operand::Type::Sum;
664  offset.m_children.push_back(offset_and_iterator.first);
665  offset.m_children.push_back(base_and_iterator.first);
666 
667  Operand deref;
668  deref.m_type = Operand::Type::Dereference;
669  deref.m_children.push_back(offset);
670  return std::make_pair(deref, osi);
671  }
672 
673  // [sp]
674  static std::pair<Operand, llvm::StringRef::const_iterator>
675  ParseARMDerefAccess(llvm::StringRef::const_iterator osi,
676  llvm::StringRef::const_iterator ose) {
677  bool found = false;
678  std::tie(found, osi) = ConsumeChar(osi, '[', ose);
679  if (!found) {
680  return std::make_pair(Operand(), osi);
681  }
682 
683  std::pair<Operand, llvm::StringRef::const_iterator> base_and_iterator =
684  ParseRegisterName(osi, ose);
685  if (base_and_iterator.first.IsValid()) {
686  osi = base_and_iterator.second;
687  } else {
688  return std::make_pair(Operand(), osi);
689  }
690 
691  std::tie(found, osi) = ConsumeChar(osi, ']', ose);
692  if (!found) {
693  return std::make_pair(Operand(), osi);
694  }
695 
696  Operand deref;
697  deref.m_type = Operand::Type::Dereference;
698  deref.m_children.push_back(base_and_iterator.first);
699  return std::make_pair(deref, osi);
700  }
701 
702  static void DumpOperand(const Operand &op, Stream &s) {
703  switch (op.m_type) {
704  case Operand::Type::Dereference:
705  s.PutCString("*");
706  DumpOperand(op.m_children[0], s);
707  break;
708  case Operand::Type::Immediate:
709  if (op.m_negative) {
710  s.PutCString("-");
711  }
712  s.PutCString(llvm::to_string(op.m_immediate));
713  break;
714  case Operand::Type::Invalid:
715  s.PutCString("Invalid");
716  break;
717  case Operand::Type::Product:
718  s.PutCString("(");
719  DumpOperand(op.m_children[0], s);
720  s.PutCString("*");
721  DumpOperand(op.m_children[1], s);
722  s.PutCString(")");
723  break;
724  case Operand::Type::Register:
726  break;
727  case Operand::Type::Sum:
728  s.PutCString("(");
729  DumpOperand(op.m_children[0], s);
730  s.PutCString("+");
731  DumpOperand(op.m_children[1], s);
732  s.PutCString(")");
733  break;
734  }
735  }
736 
738  llvm::SmallVectorImpl<Instruction::Operand> &operands) override {
739  const char *operands_string = GetOperands(nullptr);
740 
741  if (!operands_string) {
742  return false;
743  }
744 
745  llvm::StringRef operands_ref(operands_string);
746 
747  llvm::StringRef::const_iterator osi = operands_ref.begin();
748  llvm::StringRef::const_iterator ose = operands_ref.end();
749 
750  while (osi != ose) {
751  Operand operand;
752  llvm::StringRef::const_iterator iter;
753 
754  if ((std::tie(operand, iter) = ParseIntelIndexedAccess(osi, ose),
755  operand.IsValid()) ||
756  (std::tie(operand, iter) = ParseIntelDerefAccess(osi, ose),
757  operand.IsValid()) ||
758  (std::tie(operand, iter) = ParseARMOffsetAccess(osi, ose),
759  operand.IsValid()) ||
760  (std::tie(operand, iter) = ParseARMDerefAccess(osi, ose),
761  operand.IsValid()) ||
762  (std::tie(operand, iter) = ParseRegisterName(osi, ose),
763  operand.IsValid()) ||
764  (std::tie(operand, iter) = ParseImmediate(osi, ose),
765  operand.IsValid())) {
766  osi = iter;
767  operands.push_back(operand);
768  } else {
769  return false;
770  }
771 
772  std::pair<bool, llvm::StringRef::const_iterator> found_and_iter =
773  ConsumeChar(osi, ',', ose);
774  if (found_and_iter.first) {
775  osi = found_and_iter.second;
776  }
777 
778  osi = ConsumeWhitespace(osi, ose);
779  }
780 
781  DisassemblerSP disasm_sp = m_disasm_wp.lock();
782 
783  if (disasm_sp && operands.size() > 1) {
784  // TODO tie this into the MC Disassembler's notion of clobbers.
785  switch (disasm_sp->GetArchitecture().GetMachine()) {
786  default:
787  break;
788  case llvm::Triple::x86:
789  case llvm::Triple::x86_64:
790  operands[operands.size() - 1].m_clobbered = true;
791  break;
792  case llvm::Triple::arm:
793  operands[0].m_clobbered = true;
794  break;
795  }
796  }
797 
798  if (Log *log =
800  StreamString ss;
801 
802  ss.Printf("[%s] expands to %zu operands:\n", operands_string,
803  operands.size());
804  for (const Operand &operand : operands) {
805  ss.PutCString(" ");
806  DumpOperand(operand, ss);
807  ss.PutCString("\n");
808  }
809 
810  log->PutString(ss.GetString());
811  }
812 
813  return true;
814  }
815 
816  bool IsCall() override {
817  VisitInstruction();
818  return m_is_call;
819  }
820 
821 protected:
822  std::weak_ptr<DisassemblerLLVMC> m_disasm_wp;
823 
824  bool m_is_valid = false;
826  bool m_has_visited_instruction = false;
827 
828  // Be conservative. If we didn't understand the instruction, say it:
829  // - Might branch
830  // - Does not have a delay slot
831  // - Is not a call
832  // - Is not a load
833  // - Is not an authenticated instruction
834  bool m_does_branch = true;
835  bool m_has_delay_slot = false;
836  bool m_is_call = false;
837  bool m_is_load = false;
838  bool m_is_authenticated = false;
839 
841  if (m_has_visited_instruction)
842  return;
843 
844  DisassemblerScope disasm(*this);
845  if (!disasm)
846  return;
847 
848  DataExtractor data;
849  if (!m_opcode.GetData(data))
850  return;
851 
852  bool is_alternate_isa;
853  lldb::addr_t pc = m_address.GetFileAddress();
854  DisassemblerLLVMC::MCDisasmInstance *mc_disasm_ptr =
855  GetDisasmToUse(is_alternate_isa, disasm);
856  const uint8_t *opcode_data = data.GetDataStart();
857  const size_t opcode_data_len = data.GetByteSize();
858  llvm::MCInst inst;
859  const size_t inst_size =
860  mc_disasm_ptr->GetMCInst(opcode_data, opcode_data_len, pc, inst);
861  if (inst_size == 0)
862  return;
863 
864  m_has_visited_instruction = true;
865  m_does_branch = mc_disasm_ptr->CanBranch(inst);
866  m_has_delay_slot = mc_disasm_ptr->HasDelaySlot(inst);
867  m_is_call = mc_disasm_ptr->IsCall(inst);
868  m_is_load = mc_disasm_ptr->IsLoad(inst);
869  m_is_authenticated = mc_disasm_ptr->IsAuthenticated(inst);
870  }
871 
872 private:
874  GetDisasmToUse(bool &is_alternate_isa, DisassemblerScope &disasm) {
875  is_alternate_isa = false;
876  if (disasm) {
877  if (disasm->m_alternate_disasm_up) {
878  const AddressClass address_class = GetAddressClass();
879 
880  if (address_class == AddressClass::eCodeAlternateISA) {
881  is_alternate_isa = true;
882  return disasm->m_alternate_disasm_up.get();
883  }
884  }
885  return disasm->m_disasm_up.get();
886  }
887  return nullptr;
888  }
889 };
890 
891 std::unique_ptr<DisassemblerLLVMC::MCDisasmInstance>
892 DisassemblerLLVMC::MCDisasmInstance::Create(const char *triple, const char *cpu,
893  const char *features_str,
894  unsigned flavor,
895  DisassemblerLLVMC &owner) {
896  using Instance = std::unique_ptr<DisassemblerLLVMC::MCDisasmInstance>;
897 
899  const llvm::Target *curr_target =
900  llvm::TargetRegistry::lookupTarget(triple, Status);
901  if (!curr_target)
902  return Instance();
903 
904  std::unique_ptr<llvm::MCInstrInfo> instr_info_up(
905  curr_target->createMCInstrInfo());
906  if (!instr_info_up)
907  return Instance();
908 
909  std::unique_ptr<llvm::MCRegisterInfo> reg_info_up(
910  curr_target->createMCRegInfo(triple));
911  if (!reg_info_up)
912  return Instance();
913 
914  std::unique_ptr<llvm::MCSubtargetInfo> subtarget_info_up(
915  curr_target->createMCSubtargetInfo(triple, cpu, features_str));
916  if (!subtarget_info_up)
917  return Instance();
918 
919  llvm::MCTargetOptions MCOptions;
920  std::unique_ptr<llvm::MCAsmInfo> asm_info_up(
921  curr_target->createMCAsmInfo(*reg_info_up, triple, MCOptions));
922  if (!asm_info_up)
923  return Instance();
924 
925  std::unique_ptr<llvm::MCContext> context_up(
926  new llvm::MCContext(llvm::Triple(triple), asm_info_up.get(),
927  reg_info_up.get(), subtarget_info_up.get()));
928  if (!context_up)
929  return Instance();
930 
931  std::unique_ptr<llvm::MCDisassembler> disasm_up(
932  curr_target->createMCDisassembler(*subtarget_info_up, *context_up));
933  if (!disasm_up)
934  return Instance();
935 
936  std::unique_ptr<llvm::MCRelocationInfo> rel_info_up(
937  curr_target->createMCRelocationInfo(triple, *context_up));
938  if (!rel_info_up)
939  return Instance();
940 
941  std::unique_ptr<llvm::MCSymbolizer> symbolizer_up(
942  curr_target->createMCSymbolizer(
943  triple, nullptr, DisassemblerLLVMC::SymbolLookupCallback, &owner,
944  context_up.get(), std::move(rel_info_up)));
945  disasm_up->setSymbolizer(std::move(symbolizer_up));
946 
947  unsigned asm_printer_variant =
948  flavor == ~0U ? asm_info_up->getAssemblerDialect() : flavor;
949 
950  std::unique_ptr<llvm::MCInstPrinter> instr_printer_up(
951  curr_target->createMCInstPrinter(llvm::Triple{triple},
952  asm_printer_variant, *asm_info_up,
953  *instr_info_up, *reg_info_up));
954  if (!instr_printer_up)
955  return Instance();
956 
957  return Instance(
958  new MCDisasmInstance(std::move(instr_info_up), std::move(reg_info_up),
959  std::move(subtarget_info_up), std::move(asm_info_up),
960  std::move(context_up), std::move(disasm_up),
961  std::move(instr_printer_up)));
962 }
963 
965  std::unique_ptr<llvm::MCInstrInfo> &&instr_info_up,
966  std::unique_ptr<llvm::MCRegisterInfo> &&reg_info_up,
967  std::unique_ptr<llvm::MCSubtargetInfo> &&subtarget_info_up,
968  std::unique_ptr<llvm::MCAsmInfo> &&asm_info_up,
969  std::unique_ptr<llvm::MCContext> &&context_up,
970  std::unique_ptr<llvm::MCDisassembler> &&disasm_up,
971  std::unique_ptr<llvm::MCInstPrinter> &&instr_printer_up)
972  : m_instr_info_up(std::move(instr_info_up)),
973  m_reg_info_up(std::move(reg_info_up)),
974  m_subtarget_info_up(std::move(subtarget_info_up)),
975  m_asm_info_up(std::move(asm_info_up)),
976  m_context_up(std::move(context_up)), m_disasm_up(std::move(disasm_up)),
977  m_instr_printer_up(std::move(instr_printer_up)) {
980 }
981 
983  const uint8_t *opcode_data, size_t opcode_data_len, lldb::addr_t pc,
984  llvm::MCInst &mc_inst) const {
985  llvm::ArrayRef<uint8_t> data(opcode_data, opcode_data_len);
986  llvm::MCDisassembler::DecodeStatus status;
987 
988  uint64_t new_inst_size;
989  status = m_disasm_up->getInstruction(mc_inst, new_inst_size, data, pc,
990  llvm::nulls());
991  if (status == llvm::MCDisassembler::Success)
992  return new_inst_size;
993  else
994  return 0;
995 }
996 
998  llvm::MCInst &mc_inst, std::string &inst_string,
999  std::string &comments_string) {
1000  llvm::raw_string_ostream inst_stream(inst_string);
1001  llvm::raw_string_ostream comments_stream(comments_string);
1002 
1003  m_instr_printer_up->setCommentStream(comments_stream);
1004  m_instr_printer_up->printInst(&mc_inst, 0, llvm::StringRef(),
1005  *m_subtarget_info_up, inst_stream);
1006  m_instr_printer_up->setCommentStream(llvm::nulls());
1007  comments_stream.flush();
1008 
1009  static std::string g_newlines("\r\n");
1010 
1011  for (size_t newline_pos = 0;
1012  (newline_pos = comments_string.find_first_of(g_newlines, newline_pos)) !=
1013  comments_string.npos;
1014  /**/) {
1015  comments_string.replace(comments_string.begin() + newline_pos,
1016  comments_string.begin() + newline_pos + 1, 1, ' ');
1017  }
1018 }
1019 
1021  bool use_hex_immed, HexImmediateStyle hex_style) {
1022  m_instr_printer_up->setPrintImmHex(use_hex_immed);
1023  switch (hex_style) {
1024  case eHexStyleC:
1025  m_instr_printer_up->setPrintHexStyle(llvm::HexStyle::C);
1026  break;
1027  case eHexStyleAsm:
1028  m_instr_printer_up->setPrintHexStyle(llvm::HexStyle::Asm);
1029  break;
1030  }
1031 }
1032 
1034  llvm::MCInst &mc_inst) const {
1035  return m_instr_info_up->get(mc_inst.getOpcode())
1036  .mayAffectControlFlow(mc_inst, *m_reg_info_up);
1037 }
1038 
1040  llvm::MCInst &mc_inst) const {
1041  return m_instr_info_up->get(mc_inst.getOpcode()).hasDelaySlot();
1042 }
1043 
1044 bool DisassemblerLLVMC::MCDisasmInstance::IsCall(llvm::MCInst &mc_inst) const {
1045  return m_instr_info_up->get(mc_inst.getOpcode()).isCall();
1046 }
1047 
1048 bool DisassemblerLLVMC::MCDisasmInstance::IsLoad(llvm::MCInst &mc_inst) const {
1049  return m_instr_info_up->get(mc_inst.getOpcode()).mayLoad();
1050 }
1051 
1053  llvm::MCInst &mc_inst) const {
1054  auto InstrDesc = m_instr_info_up->get(mc_inst.getOpcode());
1055 
1056  // Treat software auth traps (brk 0xc470 + aut key, where 0x70 == 'p', 0xc4
1057  // == 'a' + 'c') as authenticated instructions for reporting purposes, in
1058  // addition to the standard authenticated instructions specified in ARMv8.3.
1059  bool IsBrkC47x = false;
1060  if (InstrDesc.isTrap() && mc_inst.getNumOperands() == 1) {
1061  const llvm::MCOperand &Op0 = mc_inst.getOperand(0);
1062  if (Op0.isImm() && Op0.getImm() >= 0xc470 && Op0.getImm() <= 0xc474)
1063  IsBrkC47x = true;
1064  }
1065 
1066  return InstrDesc.isAuthenticated() || IsBrkC47x;
1067 }
1068 
1070  const char *flavor_string)
1071  : Disassembler(arch, flavor_string), m_exe_ctx(nullptr), m_inst(nullptr),
1073  m_adrp_insn() {
1074  if (!FlavorValidForArchSpec(arch, m_flavor.c_str())) {
1075  m_flavor.assign("default");
1076  }
1077 
1078  unsigned flavor = ~0U;
1079  llvm::Triple triple = arch.GetTriple();
1080 
1081  // So far the only supported flavor is "intel" on x86. The base class will
1082  // set this correctly coming in.
1083  if (triple.getArch() == llvm::Triple::x86 ||
1084  triple.getArch() == llvm::Triple::x86_64) {
1085  if (m_flavor == "intel") {
1086  flavor = 1;
1087  } else if (m_flavor == "att") {
1088  flavor = 0;
1089  }
1090  }
1091 
1092  ArchSpec thumb_arch(arch);
1093  if (triple.getArch() == llvm::Triple::arm) {
1094  std::string thumb_arch_name(thumb_arch.GetTriple().getArchName().str());
1095  // Replace "arm" with "thumb" so we get all thumb variants correct
1096  if (thumb_arch_name.size() > 3) {
1097  thumb_arch_name.erase(0, 3);
1098  thumb_arch_name.insert(0, "thumb");
1099  } else {
1100  thumb_arch_name = "thumbv8.7a";
1101  }
1102  thumb_arch.GetTriple().setArchName(llvm::StringRef(thumb_arch_name));
1103  }
1104 
1105  // If no sub architecture specified then use the most recent arm architecture
1106  // so the disassembler will return all instruction. Without it we will see a
1107  // lot of unknow opcode in case the code uses instructions which are not
1108  // available in the oldest arm version (used when no sub architecture is
1109  // specified)
1110  if (triple.getArch() == llvm::Triple::arm &&
1111  triple.getSubArch() == llvm::Triple::NoSubArch)
1112  triple.setArchName("armv8.7a");
1113 
1114  std::string features_str = "";
1115  const char *triple_str = triple.getTriple().c_str();
1116 
1117  // ARM Cortex M0-M7 devices only execute thumb instructions
1118  if (arch.IsAlwaysThumbInstructions()) {
1119  triple_str = thumb_arch.GetTriple().getTriple().c_str();
1120  features_str += "+fp-armv8,";
1121  }
1122 
1123  const char *cpu = "";
1124 
1125  switch (arch.GetCore()) {
1126  case ArchSpec::eCore_mips32:
1127  case ArchSpec::eCore_mips32el:
1128  cpu = "mips32";
1129  break;
1130  case ArchSpec::eCore_mips32r2:
1131  case ArchSpec::eCore_mips32r2el:
1132  cpu = "mips32r2";
1133  break;
1134  case ArchSpec::eCore_mips32r3:
1135  case ArchSpec::eCore_mips32r3el:
1136  cpu = "mips32r3";
1137  break;
1138  case ArchSpec::eCore_mips32r5:
1139  case ArchSpec::eCore_mips32r5el:
1140  cpu = "mips32r5";
1141  break;
1142  case ArchSpec::eCore_mips32r6:
1143  case ArchSpec::eCore_mips32r6el:
1144  cpu = "mips32r6";
1145  break;
1146  case ArchSpec::eCore_mips64:
1147  case ArchSpec::eCore_mips64el:
1148  cpu = "mips64";
1149  break;
1150  case ArchSpec::eCore_mips64r2:
1151  case ArchSpec::eCore_mips64r2el:
1152  cpu = "mips64r2";
1153  break;
1154  case ArchSpec::eCore_mips64r3:
1155  case ArchSpec::eCore_mips64r3el:
1156  cpu = "mips64r3";
1157  break;
1158  case ArchSpec::eCore_mips64r5:
1159  case ArchSpec::eCore_mips64r5el:
1160  cpu = "mips64r5";
1161  break;
1162  case ArchSpec::eCore_mips64r6:
1163  case ArchSpec::eCore_mips64r6el:
1164  cpu = "mips64r6";
1165  break;
1166  default:
1167  cpu = "";
1168  break;
1169  }
1170 
1171  if (arch.IsMIPS()) {
1172  uint32_t arch_flags = arch.GetFlags();
1173  if (arch_flags & ArchSpec::eMIPSAse_msa)
1174  features_str += "+msa,";
1175  if (arch_flags & ArchSpec::eMIPSAse_dsp)
1176  features_str += "+dsp,";
1177  if (arch_flags & ArchSpec::eMIPSAse_dspr2)
1178  features_str += "+dspr2,";
1179  }
1180 
1181  // If any AArch64 variant, enable latest ISA with any optional
1182  // extensions like SVE.
1183  if (triple.isAArch64()) {
1184  features_str += "+v8.7a,+sve2,+mte";
1185 
1186  if (triple.getVendor() == llvm::Triple::Apple)
1187  cpu = "apple-latest";
1188  }
1189 
1190  // We use m_disasm_up.get() to tell whether we are valid or not, so if this
1191  // isn't good for some reason, we won't be valid and FindPlugin will fail and
1192  // we won't get used.
1193  m_disasm_up = MCDisasmInstance::Create(triple_str, cpu, features_str.c_str(),
1194  flavor, *this);
1195 
1196  llvm::Triple::ArchType llvm_arch = triple.getArch();
1197 
1198  // For arm CPUs that can execute arm or thumb instructions, also create a
1199  // thumb instruction disassembler.
1200  if (llvm_arch == llvm::Triple::arm) {
1201  std::string thumb_triple(thumb_arch.GetTriple().getTriple());
1203  MCDisasmInstance::Create(thumb_triple.c_str(), "", features_str.c_str(),
1204  flavor, *this);
1205  if (!m_alternate_disasm_up)
1206  m_disasm_up.reset();
1207 
1208  } else if (arch.IsMIPS()) {
1209  /* Create alternate disassembler for MIPS16 and microMIPS */
1210  uint32_t arch_flags = arch.GetFlags();
1211  if (arch_flags & ArchSpec::eMIPSAse_mips16)
1212  features_str += "+mips16,";
1213  else if (arch_flags & ArchSpec::eMIPSAse_micromips)
1214  features_str += "+micromips,";
1215 
1217  triple_str, cpu, features_str.c_str(), flavor, *this);
1218  if (!m_alternate_disasm_up)
1219  m_disasm_up.reset();
1220  }
1221 }
1222 
1224 
1226  const char *flavor) {
1227  if (arch.GetTriple().getArch() != llvm::Triple::UnknownArch) {
1228  std::unique_ptr<DisassemblerLLVMC> disasm_up(
1229  new DisassemblerLLVMC(arch, flavor));
1230 
1231  if (disasm_up.get() && disasm_up->IsValid())
1232  return disasm_up.release();
1233  }
1234  return nullptr;
1235 }
1236 
1238  const DataExtractor &data,
1239  lldb::offset_t data_offset,
1240  size_t num_instructions,
1241  bool append, bool data_from_file) {
1242  if (!append)
1244 
1245  if (!IsValid())
1246  return 0;
1247 
1248  m_data_from_file = data_from_file;
1249  uint32_t data_cursor = data_offset;
1250  const size_t data_byte_size = data.GetByteSize();
1251  uint32_t instructions_parsed = 0;
1252  Address inst_addr(base_addr);
1253 
1254  while (data_cursor < data_byte_size &&
1255  instructions_parsed < num_instructions) {
1256 
1257  AddressClass address_class = AddressClass::eCode;
1258 
1260  address_class = inst_addr.GetAddressClass();
1261 
1262  InstructionSP inst_sp(
1263  new InstructionLLVMC(*this, inst_addr, address_class));
1264 
1265  if (!inst_sp)
1266  break;
1267 
1268  uint32_t inst_size = inst_sp->Decode(*this, data, data_cursor);
1269 
1270  if (inst_size == 0)
1271  break;
1272 
1273  m_instruction_list.Append(inst_sp);
1274  data_cursor += inst_size;
1275  inst_addr.Slide(inst_size);
1276  instructions_parsed++;
1277  }
1278 
1279  return data_cursor - data_offset;
1280 }
1281 
1283  PluginManager::RegisterPlugin(GetPluginNameStatic(),
1284  "Disassembler that uses LLVM MC to disassemble "
1285  "i386, x86_64, ARM, and ARM64.",
1286  CreateInstance);
1287 
1288  llvm::InitializeAllTargetInfos();
1289  llvm::InitializeAllTargetMCs();
1290  llvm::InitializeAllAsmParsers();
1291  llvm::InitializeAllDisassemblers();
1292 }
1293 
1295  PluginManager::UnregisterPlugin(CreateInstance);
1296 }
1297 
1299  static ConstString g_name("llvm-mc");
1300  return g_name;
1301 }
1302 
1303 int DisassemblerLLVMC::OpInfoCallback(void *disassembler, uint64_t pc,
1304  uint64_t offset, uint64_t size,
1305  int tag_type, void *tag_bug) {
1306  return static_cast<DisassemblerLLVMC *>(disassembler)
1307  ->OpInfo(pc, offset, size, tag_type, tag_bug);
1308 }
1309 
1310 const char *DisassemblerLLVMC::SymbolLookupCallback(void *disassembler,
1311  uint64_t value,
1312  uint64_t *type, uint64_t pc,
1313  const char **name) {
1314  return static_cast<DisassemblerLLVMC *>(disassembler)
1315  ->SymbolLookup(value, type, pc, name);
1316 }
1317 
1319  const lldb_private::ArchSpec &arch, const char *flavor) {
1320  llvm::Triple triple = arch.GetTriple();
1321  if (flavor == nullptr || strcmp(flavor, "default") == 0)
1322  return true;
1323 
1324  if (triple.getArch() == llvm::Triple::x86 ||
1325  triple.getArch() == llvm::Triple::x86_64) {
1326  return strcmp(flavor, "intel") == 0 || strcmp(flavor, "att") == 0;
1327  } else
1328  return false;
1329 }
1330 
1331 bool DisassemblerLLVMC::IsValid() const { return m_disasm_up.operator bool(); }
1332 
1333 int DisassemblerLLVMC::OpInfo(uint64_t PC, uint64_t Offset, uint64_t Size,
1334  int tag_type, void *tag_bug) {
1335  switch (tag_type) {
1336  default:
1337  break;
1338  case 1:
1339  memset(tag_bug, 0, sizeof(::LLVMOpInfo1));
1340  break;
1341  }
1342  return 0;
1343 }
1344 
1345 const char *DisassemblerLLVMC::SymbolLookup(uint64_t value, uint64_t *type_ptr,
1346  uint64_t pc, const char **name) {
1347  if (*type_ptr) {
1348  if (m_exe_ctx && m_inst) {
1349  // std::string remove_this_prior_to_checkin;
1350  Target *target = m_exe_ctx ? m_exe_ctx->GetTargetPtr() : nullptr;
1351  Address value_so_addr;
1352  Address pc_so_addr;
1353  if (target->GetArchitecture().GetMachine() == llvm::Triple::aarch64 ||
1354  target->GetArchitecture().GetMachine() == llvm::Triple::aarch64_be ||
1355  target->GetArchitecture().GetMachine() == llvm::Triple::aarch64_32) {
1356  if (*type_ptr == LLVMDisassembler_ReferenceType_In_ARM64_ADRP) {
1357  m_adrp_address = pc;
1358  m_adrp_insn = value;
1359  *name = nullptr;
1360  *type_ptr = LLVMDisassembler_ReferenceType_InOut_None;
1361  return nullptr;
1362  }
1363  // If this instruction is an ADD and
1364  // the previous instruction was an ADRP and
1365  // the ADRP's register and this ADD's register are the same,
1366  // then this is a pc-relative address calculation.
1367  if (*type_ptr == LLVMDisassembler_ReferenceType_In_ARM64_ADDXri &&
1368  m_adrp_insn.hasValue() && m_adrp_address == pc - 4 &&
1369  (m_adrp_insn.getValue() & 0x1f) == ((value >> 5) & 0x1f)) {
1370  uint32_t addxri_inst;
1371  uint64_t adrp_imm, addxri_imm;
1372  // Get immlo and immhi bits, OR them together to get the ADRP imm
1373  // value.
1374  adrp_imm = ((m_adrp_insn.getValue() & 0x00ffffe0) >> 3) |
1375  ((m_adrp_insn.getValue() >> 29) & 0x3);
1376  // if high bit of immhi after right-shifting set, sign extend
1377  if (adrp_imm & (1ULL << 20))
1378  adrp_imm |= ~((1ULL << 21) - 1);
1379 
1380  addxri_inst = value;
1381  addxri_imm = (addxri_inst >> 10) & 0xfff;
1382  // check if 'sh' bit is set, shift imm value up if so
1383  // (this would make no sense, ADRP already gave us this part)
1384  if ((addxri_inst >> (12 + 5 + 5)) & 1)
1385  addxri_imm <<= 12;
1386  value = (m_adrp_address & 0xfffffffffffff000LL) + (adrp_imm << 12) +
1387  addxri_imm;
1388  }
1390  m_adrp_insn.reset();
1391  }
1392 
1393  if (m_inst->UsingFileAddress()) {
1394  ModuleSP module_sp(m_inst->GetAddress().GetModule());
1395  if (module_sp) {
1396  module_sp->ResolveFileAddress(value, value_so_addr);
1397  module_sp->ResolveFileAddress(pc, pc_so_addr);
1398  }
1399  } else if (target && !target->GetSectionLoadList().IsEmpty()) {
1400  target->GetSectionLoadList().ResolveLoadAddress(value, value_so_addr);
1401  target->GetSectionLoadList().ResolveLoadAddress(pc, pc_so_addr);
1402  }
1403 
1404  SymbolContext sym_ctx;
1405  const SymbolContextItem resolve_scope =
1406  eSymbolContextFunction | eSymbolContextSymbol;
1407  if (pc_so_addr.IsValid() && pc_so_addr.GetModule()) {
1408  pc_so_addr.GetModule()->ResolveSymbolContextForAddress(
1409  pc_so_addr, resolve_scope, sym_ctx);
1410  }
1411 
1412  if (value_so_addr.IsValid() && value_so_addr.GetSection()) {
1413  StreamString ss;
1414 
1415  bool format_omitting_current_func_name = false;
1416  if (sym_ctx.symbol || sym_ctx.function) {
1417  AddressRange range;
1418  if (sym_ctx.GetAddressRange(resolve_scope, 0, false, range) &&
1419  range.GetBaseAddress().IsValid() &&
1420  range.ContainsLoadAddress(value_so_addr, target)) {
1421  format_omitting_current_func_name = true;
1422  }
1423  }
1424 
1425  // If the "value" address (the target address we're symbolicating) is
1426  // inside the same SymbolContext as the current instruction pc
1427  // (pc_so_addr), don't print the full function name - just print it
1428  // with DumpStyleNoFunctionName style, e.g. "<+36>".
1429  if (format_omitting_current_func_name) {
1430  value_so_addr.Dump(&ss, target, Address::DumpStyleNoFunctionName,
1431  Address::DumpStyleSectionNameOffset);
1432  } else {
1433  value_so_addr.Dump(
1434  &ss, target,
1435  Address::DumpStyleResolvedDescriptionNoFunctionArguments,
1436  Address::DumpStyleSectionNameOffset);
1437  }
1438 
1439  if (!ss.GetString().empty()) {
1440  // If Address::Dump returned a multi-line description, most commonly
1441  // seen when we have multiple levels of inlined functions at an
1442  // address, only show the first line.
1443  std::string str = std::string(ss.GetString());
1444  size_t first_eol_char = str.find_first_of("\r\n");
1445  if (first_eol_char != std::string::npos) {
1446  str.erase(first_eol_char);
1447  }
1448  m_inst->AppendComment(str);
1449  }
1450  }
1451  }
1452  }
1453 
1454  // TODO: llvm-objdump sets the type_ptr to the
1455  // LLVMDisassembler_ReferenceType_Out_* values
1456  // based on where value_so_addr is pointing, with
1457  // Mach-O specific augmentations in MachODump.cpp. e.g.
1458  // see what AArch64ExternalSymbolizer::tryAddingSymbolicOperand
1459  // handles.
1460  *type_ptr = LLVMDisassembler_ReferenceType_InOut_None;
1461  *name = nullptr;
1462  return nullptr;
1463 }
1464 
1465 // PluginInterface protocol
RegularExpression.h
DisassemblerLLVMC::m_inst
InstructionLLVMC * m_inst
Definition: DisassemblerLLVMC.h:72
lldb_private::AddressRange::GetBaseAddress
Address & GetBaseAddress()
Get accessor for the base address of the range.
Definition: AddressRange.h:209
lldb_private::ArchSpec::GetMinimumOpcodeByteSize
uint32_t GetMinimumOpcodeByteSize() const
Definition: ArchSpec.cpp:916
InstructionLLVMC::IsValid
bool IsValid() const
Definition: DisassemblerLLVMC.cpp:342
InstructionLLVMC::ParseIntelDerefAccess
static std::pair< Operand, llvm::StringRef::const_iterator > ParseIntelDerefAccess(llvm::StringRef::const_iterator osi, llvm::StringRef::const_iterator ose)
Definition: DisassemblerLLVMC.cpp:583
DisassemblerLLVMC::m_disasm_up
std::unique_ptr< MCDisasmInstance > m_disasm_up
Definition: DisassemblerLLVMC.h:85
lldb_private::ExecutionContext
Definition: ExecutionContext.h:292
lldb_private::ArchSpec
Definition: ArchSpec.h:33
lldb_private::ArchSpec::IsMIPS
bool IsMIPS() const
if MIPS architecture return true.
Definition: ArchSpec.cpp:545
lldb_private::Instruction::Operand::m_immediate
lldb::addr_t m_immediate
Definition: Disassembler.h:195
lldb_private::RegularExpression
Definition: RegularExpression.h:18
DisassemblerLLVMC::GetPluginName
lldb_private::ConstString GetPluginName() override
Definition: DisassemblerLLVMC.cpp:1466
lldb_private::Instruction::Operand::m_negative
bool m_negative
Definition: Disassembler.h:197
InstructionLLVMC::UsingFileAddress
bool UsingFileAddress() const
Definition: DisassemblerLLVMC.cpp:344
lldb_private::ArchSpec::GetMaximumOpcodeByteSize
uint32_t GetMaximumOpcodeByteSize() const
Definition: ArchSpec.cpp:923
lldb_private::Address::IsValid
bool IsValid() const
Check if the object state is valid.
Definition: Address.h:336
lldb_private::Instruction::Operand::m_register
ConstString m_register
Definition: Disassembler.h:196
lldb_private::ArchSpec::GetMachine
llvm::Triple::ArchType GetMachine() const
Returns a machine family for the current architecture.
Definition: ArchSpec.cpp:667
DisassemblerLLVMC::MCDisasmInstance::m_asm_info_up
std::unique_ptr< llvm::MCAsmInfo > m_asm_info_up
Definition: DisassemblerLLVMC.cpp:79
lldb_private::AddressClass
AddressClass
Definition: lldb-private-enumerations.h:48
DisassemblerLLVMC::OpInfo
int OpInfo(uint64_t PC, uint64_t Offset, uint64_t Size, int TagType, void *TagBug)
Definition: DisassemblerLLVMC.cpp:1333
DisassemblerLLVMC::MCDisasmInstance::MCDisasmInstance
MCDisasmInstance(std::unique_ptr< llvm::MCInstrInfo > &&instr_info_up, std::unique_ptr< llvm::MCRegisterInfo > &&reg_info_up, std::unique_ptr< llvm::MCSubtargetInfo > &&subtarget_info_up, std::unique_ptr< llvm::MCAsmInfo > &&asm_info_up, std::unique_ptr< llvm::MCContext > &&context_up, std::unique_ptr< llvm::MCDisassembler > &&disasm_up, std::unique_ptr< llvm::MCInstPrinter > &&instr_printer_up)
Definition: DisassemblerLLVMC.cpp:964
lldb_private::SymbolContext::GetAddressRange
bool GetAddressRange(uint32_t scope, uint32_t range_idx, bool use_inline_block_range, AddressRange &range) const
Get the address range contained within a symbol context.
Definition: SymbolContext.cpp:379
lldb_private::ArchSpec::GetCore
Core GetCore() const
Definition: ArchSpec.h:423
DisassemblerLLVMC::MCDisasmInstance::m_reg_info_up
std::unique_ptr< llvm::MCRegisterInfo > m_reg_info_up
Definition: DisassemblerLLVMC.cpp:77
InstructionLLVMC::DisassemblerScope
Grants exclusive access to the disassembler and initializes it with the given InstructionLLVMC and an...
Definition: DisassemblerLLVMC.cpp:349
Module.h
lldb_private::DataExtractor::PeekData
const uint8_t * PeekData(lldb::offset_t offset, lldb::offset_t length) const
Peek at a bytes at offset.
Definition: DataExtractor.h:832
DisassemblerLLVMC::MCDisasmInstance::m_subtarget_info_up
std::unique_ptr< llvm::MCSubtargetInfo > m_subtarget_info_up
Definition: DisassemblerLLVMC.cpp:78
DisassemblerLLVMC::SymbolLookup
const char * SymbolLookup(uint64_t ReferenceValue, uint64_t *ReferenceType, uint64_t ReferencePC, const char **ReferenceName)
Definition: DisassemblerLLVMC.cpp:1345
lldb_private::ArchSpec::GetFlags
uint32_t GetFlags() const
Definition: ArchSpec.h:514
DisassemblerLLVMC::DisassemblerLLVMC
DisassemblerLLVMC(const lldb_private::ArchSpec &arch, const char *flavor)
Definition: DisassemblerLLVMC.cpp:1069
SectionLoadList.h
InstructionLLVMC::ConsumeChar
static std::pair< bool, llvm::StringRef::const_iterator > ConsumeChar(llvm::StringRef::const_iterator osi, const char c, llvm::StringRef::const_iterator ose)
Definition: DisassemblerLLVMC.cpp:387
lldb::offset_t
uint64_t offset_t
Definition: lldb-types.h:87
InstructionLLVMC
Definition: DisassemblerLLVMC.cpp:85
StackFrame.h
lldb_private::Instruction
Definition: Disassembler.h:58
lldb_private::Stream
Definition: Stream.h:28
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::Instruction::Operand::m_children
std::vector< Operand > m_children
Definition: Disassembler.h:194
DisassemblerLLVMC::~DisassemblerLLVMC
~DisassemblerLLVMC() override
arm64_dwarf::x3
@ x3
Definition: ARM64_DWARF_Registers.h:20
InstructionLLVMC::IsAuthenticated
bool IsAuthenticated() override
Definition: DisassemblerLLVMC.cpp:112
lldb_private::SymbolContext
Definition: SymbolContext.h:33
lldb_private::Target
Definition: Target.h:450
lldb_private::DataExtractor::GetU64
uint64_t GetU64(lldb::offset_t *offset_ptr) const
Extract a uint64_t value from *offset_ptr.
Definition: DataExtractor.cpp:476
DisassemblerLLVMC::MCDisasmInstance::m_instr_printer_up
std::unique_ptr< llvm::MCInstPrinter > m_instr_printer_up
Definition: DisassemblerLLVMC.cpp:82
lldb_private::StreamString::GetString
llvm::StringRef GetString() const
Definition: StreamString.cpp:51
InstructionLLVMC::DisassemblerScope::~DisassemblerScope
~DisassemblerScope()
Definition: DisassemblerLLVMC.cpp:361
InstructionLLVMC::DumpOperand
static void DumpOperand(const Operand &op, Stream &s)
Definition: DisassemblerLLVMC.cpp:702
Process.h
InstructionLLVMC::ParseRegisterName
static std::pair< Operand, llvm::StringRef::const_iterator > ParseRegisterName(llvm::StringRef::const_iterator osi, llvm::StringRef::const_iterator ose)
Definition: DisassemblerLLVMC.cpp:401
DisassemblerLLVMC::m_adrp_address
lldb::addr_t m_adrp_address
Definition: DisassemblerLLVMC.h:79
DisassemblerLLVMC::FlavorValidForArchSpec
bool FlavorValidForArchSpec(const lldb_private::ArchSpec &arch, const char *flavor) override
Definition: DisassemblerLLVMC.cpp:1318
DisassemblerLLVMC::IsValid
bool IsValid() const
Definition: DisassemblerLLVMC.cpp:1331
InstructionLLVMC::m_using_file_addr
bool m_using_file_addr
Definition: DisassemblerLLVMC.cpp:825
InstructionLLVMC::ParseOperands
bool ParseOperands(llvm::SmallVectorImpl< Instruction::Operand > &operands) override
Definition: DisassemblerLLVMC.cpp:737
Target.h
InstructionLLVMC::GetDisasmToUse
DisassemblerLLVMC::MCDisasmInstance * GetDisasmToUse(bool &is_alternate_isa)
Definition: DisassemblerLLVMC.cpp:117
lldb_private::Disassembler::m_flavor
std::string m_flavor
Definition: Disassembler.h:530
lldb_private::SymbolContext::symbol
Symbol * symbol
The Symbol for a given query.
Definition: SymbolContext.h:323
DisassemblerLLVMC::MCDisasmInstance::m_instr_info_up
std::unique_ptr< llvm::MCInstrInfo > m_instr_info_up
Definition: DisassemblerLLVMC.cpp:76
InstructionLLVMC::Decode
size_t Decode(const lldb_private::Disassembler &disassembler, const lldb_private::DataExtractor &data, lldb::offset_t data_offset) override
Definition: DisassemblerLLVMC.cpp:122
lldb_private::Disassembler::eHexStyleC
@ eHexStyleC
Definition: Disassembler.h:382
InstructionLLVMC::ParseARMOffsetAccess
static std::pair< Operand, llvm::StringRef::const_iterator > ParseARMOffsetAccess(llvm::StringRef::const_iterator osi, llvm::StringRef::const_iterator ose)
Definition: DisassemblerLLVMC.cpp:630
lldb_private::Address::GetAddressClass
AddressClass GetAddressClass() const
Definition: Address.cpp:1009
lldb_private::DataExtractor
Definition: DataExtractor.h:48
lldb_private::ConstString::GetStringRef
llvm::StringRef GetStringRef() const
Get the string value as a llvm::StringRef.
Definition: ConstString.h:202
lldb_private::Disassembler::eHexStyleAsm
@ eHexStyleAsm
Definition: Disassembler.h:383
Log.h
DisassemblerLLVMC::DecodeInstructions
size_t DecodeInstructions(const lldb_private::Address &base_addr, const lldb_private::DataExtractor &data, lldb::offset_t data_offset, size_t num_instructions, bool append, bool data_from_file) override
Definition: DisassemblerLLVMC.cpp:1237
DisassemblerLLVMC::m_alternate_disasm_up
std::unique_ptr< MCDisasmInstance > m_alternate_disasm_up
Definition: DisassemblerLLVMC.h:87
InstructionLLVMC::VisitInstruction
void VisitInstruction()
Definition: DisassemblerLLVMC.cpp:840
DisassemblerLLVMC::MCDisasmInstance::IsLoad
bool IsLoad(llvm::MCInst &mc_inst) const
Definition: DisassemblerLLVMC.cpp:1048
InstructionLLVMC::IsLoad
bool IsLoad() override
Definition: DisassemblerLLVMC.cpp:107
DisassemblerLLVMC
Definition: DisassemblerLLVMC.h:23
lldb_private::SymbolContext::function
Function * function
The Function for a given query.
Definition: SymbolContext.h:320
lldb_private::DataExtractor::GetDataStart
const uint8_t * GetDataStart() const
Get the data start pointer.
Definition: DataExtractor.h:422
lldb_private::Instruction::GetAddress
const Address & GetAddress() const
Definition: Disassembler.h:65
lldb_private::DataExtractor::GetByteOrder
lldb::ByteOrder GetByteOrder() const
Get the current byte order value.
Definition: DataExtractor.h:594
lldb_private::ConstString
Definition: ConstString.h:40
DisassemblerLLVMC::m_adrp_insn
llvm::Optional< uint32_t > m_adrp_insn
Definition: DisassemblerLLVMC.h:80
DisassemblerLLVMC.h
lldb_private::StreamString
Definition: StreamString.h:23
lldb_private::DataExtractor::GetU8
uint8_t GetU8(lldb::offset_t *offset_ptr) const
Extract a uint8_t value from *offset_ptr.
Definition: DataExtractor.cpp:318
lldb_private::AddressRange
Definition: AddressRange.h:25
lldb_private::GetLogIfAllCategoriesSet
Log * GetLogIfAllCategoriesSet(uint32_t mask)
Definition: Logging.cpp:58
lldb_private::Instruction::Operand
Definition: Disassembler.h:185
lldb_private::Disassembler::m_instruction_list
InstructionList m_instruction_list
Definition: Disassembler.h:528
DisassemblerLLVMC::GetPluginNameStatic
static lldb_private::ConstString GetPluginNameStatic()
Definition: DisassemblerLLVMC.cpp:1298
string
string(SUBSTRING ${p} 10 -1 pStripped) if($
Definition: Plugins/CMakeLists.txt:40
lldb_private::Address::GetSection
lldb::SectionSP GetSection() const
Get const accessor for the section.
Definition: Address.h:420
lldb_private::SectionLoadList::ResolveLoadAddress
bool ResolveLoadAddress(lldb::addr_t load_addr, Address &so_addr, bool allow_section_end=false) const
Definition: SectionLoadList.cpp:208
Address.h
InstructionLLVMC::m_disasm_wp
std::weak_ptr< DisassemblerLLVMC > m_disasm_wp
Definition: DisassemblerLLVMC.cpp:822
DisassemblerLLVMC::MCDisasmInstance::IsAuthenticated
bool IsAuthenticated(llvm::MCInst &mc_inst) const
Definition: DisassemblerLLVMC.cpp:1052
DisassemblerLLVMC::Initialize
static void Initialize()
Definition: DisassemblerLLVMC.cpp:1282
InstructionLLVMC::HasDelaySlot
bool HasDelaySlot() override
Definition: DisassemblerLLVMC.cpp:102
InstructionLLVMC::IsCall
bool IsCall() override
Definition: DisassemblerLLVMC.cpp:816
InstructionLLVMC::DoesBranch
bool DoesBranch() override
Definition: DisassemblerLLVMC.cpp:97
DisassemblerLLVMC::MCDisasmInstance::m_disasm_up
std::unique_ptr< llvm::MCDisassembler > m_disasm_up
Definition: DisassemblerLLVMC.cpp:81
lldb_private::SectionLoadList::IsEmpty
bool IsEmpty() const
Definition: SectionLoadList.cpp:37
lldb_private::Target::GetArchitecture
const ArchSpec & GetArchitecture() const
Definition: Target.h:966
DisassemblerLLVMC::CreateInstance
static lldb_private::Disassembler * CreateInstance(const lldb_private::ArchSpec &arch, const char *flavor)
Definition: DisassemblerLLVMC.cpp:1225
DisassemblerLLVMC::SymbolLookupCallback
static const char * SymbolLookupCallback(void *DisInfo, uint64_t ReferenceValue, uint64_t *ReferenceType, uint64_t ReferencePC, const char **ReferenceName)
Definition: DisassemblerLLVMC.cpp:1310
lldb_private::Status
Definition: Status.h:44
DisassemblerLLVMC::MCDisasmInstance::Create
static std::unique_ptr< MCDisasmInstance > Create(const char *triple, const char *cpu, const char *features_str, unsigned flavor, DisassemblerLLVMC &owner)
Definition: DisassemblerLLVMC.cpp:892
InstructionLLVMC::ParseImmediate
static std::pair< Operand, llvm::StringRef::const_iterator > ParseImmediate(llvm::StringRef::const_iterator osi, llvm::StringRef::const_iterator ose)
Definition: DisassemblerLLVMC.cpp:442
DisassemblerLLVMC::OpInfoCallback
static int OpInfoCallback(void *DisInfo, uint64_t PC, uint64_t Offset, uint64_t Size, int TagType, void *TagBug)
Definition: DisassemblerLLVMC.cpp:1303
uint32_t
DisassemblerLLVMC::m_exe_ctx
const lldb_private::ExecutionContext * m_exe_ctx
Definition: DisassemblerLLVMC.h:71
lldb_private::ArchSpec::IsAlwaysThumbInstructions
bool IsAlwaysThumbInstructions() const
Detect whether this architecture uses thumb code exclusively.
Definition: ArchSpec.cpp:1434
lldb_private::Address
Definition: Address.h:59
InstructionLLVMC::DisassemblerScope::DisassemblerScope
DisassemblerScope(InstructionLLVMC &i, const lldb_private::ExecutionContext *exe_ctx=nullptr)
Definition: DisassemblerLLVMC.cpp:353
lldb_private::TargetProperties::GetHexImmediateStyle
Disassembler::HexImmediateStyle GetHexImmediateStyle() const
Definition: Target.cpp:4226
lldb_private::Disassembler::HexImmediateStyle
HexImmediateStyle
Definition: Disassembler.h:381
InstructionLLVMC::InstructionLLVMC
InstructionLLVMC(DisassemblerLLVMC &disasm, const lldb_private::Address &address, AddressClass addr_class)
Definition: DisassemblerLLVMC.cpp:87
InstructionLLVMC::ParseARMDerefAccess
static std::pair< Operand, llvm::StringRef::const_iterator > ParseARMDerefAccess(llvm::StringRef::const_iterator osi, llvm::StringRef::const_iterator ose)
Definition: DisassemblerLLVMC.cpp:675
DisassemblerLLVMC::InstructionLLVMC
friend class InstructionLLVMC
Definition: DisassemblerLLVMC.h:49
lldb_private::Address::Dump
bool Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style=DumpStyleInvalid, uint32_t addr_byte_size=UINT32_MAX) const
Dump a description of this object to a Stream.
Definition: Address.cpp:405
uint16_t
DisassemblerLLVMC::MCDisasmInstance
Definition: DisassemblerLLVMC.cpp:48
lldb_private::DataExtractor::GetU32
uint32_t GetU32(lldb::offset_t *offset_ptr) const
Extract a uint32_t value from *offset_ptr.
Definition: DataExtractor.cpp:427
lldb_private::Target::GetSectionLoadList
SectionLoadList & GetSectionLoadList()
Definition: Target.h:1039
LLDB_INVALID_ADDRESS
#define LLDB_INVALID_ADDRESS
Definition: lldb-defines.h:86
lldb_private::Instruction::Operand::m_type
enum lldb_private::Instruction::Operand::Type m_type
lldb_private::TargetProperties::GetUseHexImmediates
bool GetUseHexImmediates() const
Definition: Target.cpp:4195
DataExtractor.h
lldb_private::Stream::Printf
size_t Printf(const char *format,...) __attribute__((format(printf
Output printf formatted output to the stream.
Definition: Stream.cpp:107
lldb_private::InstructionList::Clear
void Clear()
Definition: Disassembler.cpp:984
DisassemblerLLVMC::MCDisasmInstance::CanBranch
bool CanBranch(llvm::MCInst &mc_inst) const
Definition: DisassemblerLLVMC.cpp:1033
SymbolContext.h
DisassemblerLLVMC::m_data_from_file
bool m_data_from_file
Definition: DisassemblerLLVMC.h:74
lldb_private::DataExtractor::BytesLeft
lldb::offset_t BytesLeft(lldb::offset_t offset) const
Definition: DataExtractor.h:976
lldb_private::Disassembler
Definition: Disassembler.h:368
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
lldb_private::DataExtractor::GetU16
uint16_t GetU16(lldb::offset_t *offset_ptr) const
Extract a uint16_t value from *offset_ptr.
Definition: DataExtractor.cpp:349
DisassemblerLLVMC::Terminate
static void Terminate()
Definition: DisassemblerLLVMC.cpp:1294
lldb_private::RegularExpression::Execute
bool Execute(llvm::StringRef string, llvm::SmallVectorImpl< llvm::StringRef > *matches=nullptr) const
Execute a regular expression match using the compiled regular expression that is already in this obje...
Definition: RegularExpression.cpp:23
lldb_private::Address::GetModule
lldb::ModuleSP GetModule() const
Get accessor for the module for this address.
Definition: Address.cpp:282
InstructionLLVMC::ParseIntelIndexedAccess
static std::pair< Operand, llvm::StringRef::const_iterator > ParseIntelIndexedAccess(llvm::StringRef::const_iterator osi, llvm::StringRef::const_iterator ose)
Definition: DisassemblerLLVMC.cpp:500
lldb_private::InstructionList::Append
void Append(lldb::InstructionSP &inst_sp)
Definition: Disassembler.cpp:986
Stream.h
LLDB_PLUGIN_DEFINE
#define LLDB_PLUGIN_DEFINE(PluginName)
Definition: PluginManager.h:31
lldb_private::Log
Definition: Log.h:49
lldb_private::Stream::PutCString
size_t PutCString(llvm::StringRef cstr)
Output a C string to the stream.
Definition: Stream.cpp:63
llvm::SmallVectorImpl
Definition: Disassembler.h:42
InstructionLLVMC::GetDisasmToUse
DisassemblerLLVMC::MCDisasmInstance * GetDisasmToUse(bool &is_alternate_isa, DisassemblerScope &disasm)
Definition: DisassemblerLLVMC.cpp:874
DisassemblerLLVMC::MCDisasmInstance::IsCall
bool IsCall(llvm::MCInst &mc_inst) const
Definition: DisassemblerLLVMC.cpp:1044
lldb_private::AddressRange::ContainsLoadAddress
bool ContainsLoadAddress(const Address &so_addr, Target *target) const
Check if a section offset so_addr when represented as a load address is contained within this object'...
Definition: AddressRange.cpp:102
lldb_private::DataExtractor::GetByteSize
uint64_t GetByteSize() const
Get the number of bytes contained in this object.
Definition: DataExtractor.h:270
lldb_private::Instruction::Operand::IsValid
bool IsValid()
Definition: Disassembler.h:200
lldb_private::Address::Slide
bool Slide(int64_t offset)
Definition: Address.h:440
lldb_private::DataExtractor::ValidOffsetForDataOfSize
bool ValidOffsetForDataOfSize(lldb::offset_t offset, lldb::offset_t length) const
Test the availability of length bytes of data from offset.
Definition: DataExtractor.h:965
lldb
Definition: SBAddress.h:15
InstructionLLVMC::DisassemblerScope::operator->
std::shared_ptr< DisassemblerLLVMC > operator->()
Definition: DisassemblerLLVMC.cpp:366
LIBLLDB_LOG_PROCESS
#define LIBLLDB_LOG_PROCESS
Definition: Logging.h:15
DisassemblerLLVMC::MCDisasmInstance::SetStyle
void SetStyle(bool use_hex_immed, HexImmediateStyle hex_style)
Definition: DisassemblerLLVMC.cpp:1020
InstructionLLVMC::DisassemblerScope::m_disasm
std::shared_ptr< DisassemblerLLVMC > m_disasm
Definition: DisassemblerLLVMC.cpp:350
RegisterContext.h
InstructionLLVMC::ConsumeWhitespace
static llvm::StringRef::const_iterator ConsumeWhitespace(llvm::StringRef::const_iterator osi, llvm::StringRef::const_iterator ose)
Definition: DisassemblerLLVMC.cpp:370
DisassemblerLLVMC::MCDisasmInstance::m_context_up
std::unique_ptr< llvm::MCContext > m_context_up
Definition: DisassemblerLLVMC.cpp:80
InstructionLLVMC::CalculateMnemonicOperandsAndComment
void CalculateMnemonicOperandsAndComment(const lldb_private::ExecutionContext *exe_ctx) override
Definition: DisassemblerLLVMC.cpp:224
InstructionLLVMC::GetByteSize
size_t GetByteSize() const
Definition: DisassemblerLLVMC.cpp:345
lldb_private::ExecutionContext::GetTargetPtr
Target * GetTargetPtr() const
Returns a pointer to the target object.
Definition: ExecutionContext.cpp:200
ExecutionContext.h
InstructionLLVMC::AppendComment
void AppendComment(std::string &description)
Definition: DisassemblerLLVMC.cpp:215
DisassemblerLLVMC::MCDisasmInstance::PrintMCInst
void PrintMCInst(llvm::MCInst &mc_inst, std::string &inst_string, std::string &comments_string)
Definition: DisassemblerLLVMC.cpp:997
DisassemblerLLVMC::MCDisasmInstance::HasDelaySlot
bool HasDelaySlot(llvm::MCInst &mc_inst) const
Definition: DisassemblerLLVMC.cpp:1039
lldb::ByteOrder
ByteOrder
Byte ordering definitions.
Definition: lldb-enumerations.h:138
DisassemblerLLVMC::MCDisasmInstance::GetMCInst
uint64_t GetMCInst(const uint8_t *opcode_data, size_t opcode_data_len, lldb::addr_t pc, llvm::MCInst &mc_inst) const
Definition: DisassemblerLLVMC.cpp:982