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