]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/tools/lldb/source/Plugins/Disassembler/llvm/DisassemblerLLVMC.cpp
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.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 #include "DisassemblerLLVMC.h"
11
12 #include "llvm-c/Disassembler.h"
13 #include "llvm/ADT/OwningPtr.h"
14 #include "llvm/MC/MCAsmInfo.h"
15 #include "llvm/MC/MCContext.h"
16 #include "llvm/MC/MCDisassembler.h"
17 #include "llvm/MC/MCInst.h"
18 #include "llvm/MC/MCInstPrinter.h"
19 #include "llvm/MC/MCInstrInfo.h"
20 #include "llvm/MC/MCRegisterInfo.h"
21 #include "llvm/MC/MCRelocationInfo.h"
22 #include "llvm/MC/MCSubtargetInfo.h"
23 #include "llvm/Support/ErrorHandling.h"
24 #include "llvm/Support/MemoryObject.h"
25 #include "llvm/Support/TargetRegistry.h"
26 #include "llvm/Support/TargetSelect.h"
27 #include "llvm/ADT/SmallString.h"
28
29
30 #include "lldb/Core/Address.h"
31 #include "lldb/Core/DataExtractor.h"
32 #include "lldb/Core/Module.h"
33 #include "lldb/Core/Stream.h"
34 #include "lldb/Symbol/SymbolContext.h"
35 #include "lldb/Target/ExecutionContext.h"
36 #include "lldb/Target/Process.h"
37 #include "lldb/Target/RegisterContext.h"
38 #include "lldb/Target/SectionLoadList.h"
39 #include "lldb/Target/Target.h"
40 #include "lldb/Target/StackFrame.h"
41
42 #include "lldb/Core/RegularExpression.h"
43
44 using namespace lldb;
45 using namespace lldb_private;
46
47 class InstructionLLVMC : public lldb_private::Instruction
48 {
49 public:
50     InstructionLLVMC (DisassemblerLLVMC &disasm,
51                       const lldb_private::Address &address, 
52                       AddressClass addr_class) :
53         Instruction (address, addr_class),
54         m_disasm_sp (disasm.shared_from_this()),
55         m_does_branch (eLazyBoolCalculate),
56         m_is_valid (false),
57         m_using_file_addr (false)
58     {
59     }
60     
61     virtual
62     ~InstructionLLVMC ()
63     {
64     }
65     
66     virtual bool
67     DoesBranch ()
68     {
69         if (m_does_branch == eLazyBoolCalculate)
70         {
71             GetDisassemblerLLVMC().Lock(this, NULL);
72             DataExtractor data;
73             if (m_opcode.GetData(data))
74             {
75                 bool is_alternate_isa;
76                 lldb::addr_t pc = m_address.GetFileAddress();
77
78                 DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa);
79                 const uint8_t *opcode_data = data.GetDataStart();
80                 const size_t opcode_data_len = data.GetByteSize();
81                 llvm::MCInst inst;
82                 const size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data,
83                                                                    opcode_data_len,
84                                                                    pc,
85                                                                    inst);
86                 // Be conservative, if we didn't understand the instruction, say it might branch...
87                 if (inst_size == 0)
88                     m_does_branch = eLazyBoolYes;
89                 else
90                 {
91                     const bool can_branch = mc_disasm_ptr->CanBranch(inst);
92                     if (can_branch)
93                         m_does_branch = eLazyBoolYes;
94                     else
95                         m_does_branch = eLazyBoolNo;
96                 }
97             }
98             GetDisassemblerLLVMC().Unlock();
99         }
100         return m_does_branch == eLazyBoolYes;
101     }
102     
103     DisassemblerLLVMC::LLVMCDisassembler *
104     GetDisasmToUse (bool &is_alternate_isa)
105     {
106         is_alternate_isa = false;
107         DisassemblerLLVMC &llvm_disasm = GetDisassemblerLLVMC();
108         if (llvm_disasm.m_alternate_disasm_ap.get() != NULL)
109         {
110             const AddressClass address_class = GetAddressClass ();
111         
112             if (address_class == eAddressClassCodeAlternateISA)
113             {
114                 is_alternate_isa = true;
115                 return llvm_disasm.m_alternate_disasm_ap.get();
116             }
117         }
118         return llvm_disasm.m_disasm_ap.get();
119     }
120     
121     virtual size_t
122     Decode (const lldb_private::Disassembler &disassembler,
123             const lldb_private::DataExtractor &data,
124             lldb::offset_t data_offset)
125     {
126         // All we have to do is read the opcode which can be easy for some
127         // architectures
128         bool got_op = false;
129         DisassemblerLLVMC &llvm_disasm = GetDisassemblerLLVMC();
130         const ArchSpec &arch = llvm_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         {
137             // Fixed size instructions, just read that amount of data.
138             if (!data.ValidOffsetForDataOfSize(data_offset, min_op_byte_size))
139                 return false;
140
141             switch (min_op_byte_size)
142             {
143                 case 1:
144                     m_opcode.SetOpcode8  (data.GetU8  (&data_offset), byte_order);
145                     got_op = true;
146                     break;
147
148                 case 2:
149                     m_opcode.SetOpcode16 (data.GetU16 (&data_offset), byte_order);
150                     got_op = true;
151                     break;
152
153                 case 4:
154                     m_opcode.SetOpcode32 (data.GetU32 (&data_offset), byte_order);
155                     got_op = true;
156                     break;
157
158                 case 8:
159                     m_opcode.SetOpcode64 (data.GetU64 (&data_offset), byte_order);
160                     got_op = true;
161                     break;
162
163                 default:
164                     m_opcode.SetOpcodeBytes(data.PeekData(data_offset, min_op_byte_size), min_op_byte_size);
165                     got_op = true;
166                     break;
167             }
168         }
169         if (!got_op)
170         {
171             bool is_alternate_isa = false;
172             DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr = GetDisasmToUse (is_alternate_isa);
173             
174             const llvm::Triple::ArchType machine = arch.GetMachine();
175             if (machine == llvm::Triple::arm || machine == llvm::Triple::thumb)
176             {
177                 if (machine == llvm::Triple::thumb || is_alternate_isa)
178                 {
179                     uint32_t thumb_opcode = data.GetU16(&data_offset);
180                     if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
181                     {
182                         m_opcode.SetOpcode16 (thumb_opcode, byte_order);
183                         m_is_valid = true;
184                     }
185                     else
186                     {
187                         thumb_opcode <<= 16;
188                         thumb_opcode |= data.GetU16(&data_offset);
189                         m_opcode.SetOpcode16_2 (thumb_opcode, byte_order);
190                         m_is_valid = true;
191                     }
192                 }
193                 else
194                 {
195                     m_opcode.SetOpcode32 (data.GetU32(&data_offset), byte_order);
196                     m_is_valid = true;
197                 }
198             }
199             else
200             {
201                 // The opcode isn't evenly sized, so we need to actually use the llvm
202                 // disassembler to parse it and get the size.
203                 uint8_t *opcode_data = const_cast<uint8_t *>(data.PeekData (data_offset, 1));
204                 const size_t opcode_data_len = data.BytesLeft(data_offset);
205                 const addr_t pc = m_address.GetFileAddress();
206                 llvm::MCInst inst;
207                 
208                 llvm_disasm.Lock(this, NULL);
209                 const size_t inst_size = mc_disasm_ptr->GetMCInst(opcode_data,
210                                                                   opcode_data_len,
211                                                                   pc,
212                                                                   inst);
213                 llvm_disasm.Unlock();
214                 if (inst_size == 0)
215                     m_opcode.Clear();
216                 else
217                 {
218                     m_opcode.SetOpcodeBytes(opcode_data, inst_size);
219                     m_is_valid = true;
220                 }
221             }
222         }
223         return m_opcode.GetByteSize();
224     }
225     
226     void
227     AppendComment (std::string &description)
228     {
229         if (m_comment.empty())
230             m_comment.swap (description);
231         else
232         {
233             m_comment.append(", ");
234             m_comment.append(description);
235         }
236     }
237     
238     virtual void
239     CalculateMnemonicOperandsAndComment (const lldb_private::ExecutionContext *exe_ctx)
240     {
241         DataExtractor data;
242         const AddressClass address_class = GetAddressClass ();
243
244         if (m_opcode.GetData(data))
245         {
246             char out_string[512];
247             
248             DisassemblerLLVMC &llvm_disasm = GetDisassemblerLLVMC();
249
250             DisassemblerLLVMC::LLVMCDisassembler *mc_disasm_ptr;
251             
252             if (address_class == eAddressClassCodeAlternateISA)
253                 mc_disasm_ptr = llvm_disasm.m_alternate_disasm_ap.get();
254             else
255                 mc_disasm_ptr = llvm_disasm.m_disasm_ap.get();
256             
257             lldb::addr_t pc = m_address.GetFileAddress();
258             m_using_file_addr = true;
259             
260             const bool data_from_file = GetDisassemblerLLVMC().m_data_from_file;
261             bool use_hex_immediates = true;
262             Disassembler::HexImmediateStyle hex_style = Disassembler::eHexStyleC;
263
264             if (exe_ctx)
265             {
266                 Target *target = exe_ctx->GetTargetPtr();
267                 if (target)
268                 {
269                     use_hex_immediates = target->GetUseHexImmediates();
270                     hex_style = target->GetHexImmediateStyle();
271
272                     if (!data_from_file)
273                     {
274                         const lldb::addr_t load_addr = m_address.GetLoadAddress(target);
275                         if (load_addr != LLDB_INVALID_ADDRESS)
276                         {
277                             pc = load_addr;
278                             m_using_file_addr = false;
279                         }
280                     }
281                 }
282             }
283             
284             llvm_disasm.Lock(this, exe_ctx);
285             
286             const uint8_t *opcode_data = data.GetDataStart();
287             const size_t opcode_data_len = data.GetByteSize();
288             llvm::MCInst inst;
289             size_t inst_size = mc_disasm_ptr->GetMCInst (opcode_data,
290                                                          opcode_data_len,
291                                                          pc,
292                                                          inst);
293
294             if (inst_size > 0)
295             {
296                 mc_disasm_ptr->SetStyle(use_hex_immediates, hex_style);
297                 mc_disasm_ptr->PrintMCInst(inst, out_string, sizeof(out_string));
298             }
299
300             llvm_disasm.Unlock();
301             
302             if (inst_size == 0)
303             {
304                 m_comment.assign ("unknown opcode");
305                 inst_size = m_opcode.GetByteSize();
306                 StreamString mnemonic_strm;
307                 lldb::offset_t offset = 0;
308                 lldb::ByteOrder byte_order = data.GetByteOrder();
309                 switch (inst_size)
310                 {
311                     case 1:
312                         {
313                             const uint8_t uval8 = data.GetU8 (&offset);
314                             m_opcode.SetOpcode8 (uval8, byte_order);
315                             m_opcode_name.assign (".byte");
316                             mnemonic_strm.Printf("0x%2.2x", uval8);
317                         }
318                         break;
319                     case 2:
320                         {
321                             const uint16_t uval16 = data.GetU16(&offset);
322                             m_opcode.SetOpcode16(uval16, byte_order);
323                             m_opcode_name.assign (".short");
324                             mnemonic_strm.Printf("0x%4.4x", uval16);
325                         }
326                         break;
327                     case 4:
328                         {
329                             const uint32_t uval32 = data.GetU32(&offset);
330                             m_opcode.SetOpcode32(uval32, byte_order);
331                             m_opcode_name.assign (".long");
332                             mnemonic_strm.Printf("0x%8.8x", uval32);
333                         }
334                         break;
335                     case 8:
336                         {
337                             const uint64_t uval64 = data.GetU64(&offset);
338                             m_opcode.SetOpcode64(uval64, byte_order);
339                             m_opcode_name.assign (".quad");
340                             mnemonic_strm.Printf("0x%16.16" PRIx64, uval64);
341                         }
342                         break;
343                     default:
344                         if (inst_size == 0)
345                             return;
346                         else
347                         {
348                             const uint8_t *bytes = data.PeekData(offset, inst_size);
349                             if (bytes == NULL)
350                                 return;
351                             m_opcode_name.assign (".byte");
352                             m_opcode.SetOpcodeBytes(bytes, inst_size);
353                             mnemonic_strm.Printf("0x%2.2x", bytes[0]);
354                             for (uint32_t i=1; i<inst_size; ++i)
355                                 mnemonic_strm.Printf(" 0x%2.2x", bytes[i]);
356                         }
357                         break;
358                 }
359                 m_mnemonics.swap(mnemonic_strm.GetString());
360                 return;
361             }
362             else
363             {
364                 if (m_does_branch == eLazyBoolCalculate)
365                 {
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             
375             static RegularExpression s_regex("[ \t]*([^ ^\t]+)[ \t]*([^ ^\t].*)?", REG_EXTENDED);
376             
377             RegularExpression::Match matches(3);
378             
379             if (s_regex.Execute(out_string, &matches))
380             {
381                 matches.GetMatchAtIndex(out_string, 1, m_opcode_name);
382                 matches.GetMatchAtIndex(out_string, 2, m_mnemonics);
383             }
384         }
385     }
386     
387     bool
388     IsValid () const
389     {
390         return m_is_valid;
391     }
392     
393     bool
394     UsingFileAddress() const
395     {
396         return m_using_file_addr;
397     }
398     size_t
399     GetByteSize () const
400     {
401         return m_opcode.GetByteSize();
402     }
403     
404     DisassemblerLLVMC &
405     GetDisassemblerLLVMC ()
406     {
407         return *(DisassemblerLLVMC *)m_disasm_sp.get();
408     }
409 protected:
410     
411     DisassemblerSP          m_disasm_sp; // for ownership
412     LazyBool                m_does_branch;
413     bool                    m_is_valid;
414     bool                    m_using_file_addr;
415 };
416
417
418
419 DisassemblerLLVMC::LLVMCDisassembler::LLVMCDisassembler (const char *triple, unsigned flavor, DisassemblerLLVMC &owner):
420     m_is_valid(true)
421 {
422     std::string Error;
423     const llvm::Target *curr_target = llvm::TargetRegistry::lookupTarget(triple, Error);
424     if (!curr_target)
425     {
426         m_is_valid = false;
427         return;
428     }
429     
430     m_instr_info_ap.reset(curr_target->createMCInstrInfo());
431     m_reg_info_ap.reset (curr_target->createMCRegInfo(triple));
432     
433     std::string features_str;
434
435     m_subtarget_info_ap.reset(curr_target->createMCSubtargetInfo(triple, "",
436                                                                 features_str));
437     
438     std::unique_ptr<llvm::MCRegisterInfo> reg_info(curr_target->createMCRegInfo(triple));
439     m_asm_info_ap.reset(curr_target->createMCAsmInfo(*reg_info, triple));
440
441     if (m_instr_info_ap.get() == NULL || m_reg_info_ap.get() == NULL || m_subtarget_info_ap.get() == NULL || m_asm_info_ap.get() == NULL)
442     {
443         m_is_valid = false;
444         return;
445     }
446     
447     m_context_ap.reset(new llvm::MCContext(m_asm_info_ap.get(), m_reg_info_ap.get(), 0));
448     
449     m_disasm_ap.reset(curr_target->createMCDisassembler(*m_subtarget_info_ap.get()));
450     if (m_disasm_ap.get() && m_context_ap.get())
451     {
452         llvm::OwningPtr<llvm::MCRelocationInfo> RelInfo(curr_target->createMCRelocationInfo(triple, *m_context_ap.get()));
453         if (!RelInfo)
454         {
455             m_is_valid = false;
456             return;
457         }
458         m_disasm_ap->setupForSymbolicDisassembly(NULL,
459                                                  DisassemblerLLVMC::SymbolLookupCallback,
460                                                  (void *) &owner,
461                                                  m_context_ap.get(),
462                                                  RelInfo);
463         
464         unsigned asm_printer_variant;
465         if (flavor == ~0U)
466             asm_printer_variant = m_asm_info_ap->getAssemblerDialect();
467         else
468         {
469             asm_printer_variant = flavor;
470         }
471         
472         m_instr_printer_ap.reset(curr_target->createMCInstPrinter(asm_printer_variant,
473                                                                   *m_asm_info_ap.get(),
474                                                                   *m_instr_info_ap.get(),
475                                                                   *m_reg_info_ap.get(),
476                                                                   *m_subtarget_info_ap.get()));
477         if (m_instr_printer_ap.get() == NULL)
478         {
479             m_disasm_ap.reset();
480             m_is_valid = false;
481         }
482     }
483     else
484         m_is_valid = false;
485 }
486
487 DisassemblerLLVMC::LLVMCDisassembler::~LLVMCDisassembler()
488 {
489 }
490
491 namespace {
492     // This is the memory object we use in GetInstruction.
493     class LLDBDisasmMemoryObject : public llvm::MemoryObject {
494       const uint8_t *m_bytes;
495       uint64_t m_size;
496       uint64_t m_base_PC;
497     public:
498       LLDBDisasmMemoryObject(const uint8_t *bytes, uint64_t size, uint64_t basePC) :
499                          m_bytes(bytes), m_size(size), m_base_PC(basePC) {}
500      
501       uint64_t getBase() const { return m_base_PC; }
502       uint64_t getExtent() const { return m_size; }
503
504       int readByte(uint64_t addr, uint8_t *byte) const {
505         if (addr - m_base_PC >= m_size)
506           return -1;
507         *byte = m_bytes[addr - m_base_PC];
508         return 0;
509       }
510     };
511 } // End Anonymous Namespace
512
513 uint64_t
514 DisassemblerLLVMC::LLVMCDisassembler::GetMCInst (const uint8_t *opcode_data,
515                                                  size_t opcode_data_len,
516                                                  lldb::addr_t pc,
517                                                  llvm::MCInst &mc_inst)
518 {
519     LLDBDisasmMemoryObject memory_object (opcode_data, opcode_data_len, pc);
520     llvm::MCDisassembler::DecodeStatus status;
521
522     uint64_t new_inst_size;
523     status = m_disasm_ap->getInstruction(mc_inst,
524                                          new_inst_size,
525                                          memory_object,
526                                          pc,
527                                          llvm::nulls(),
528                                          llvm::nulls());
529     if (status == llvm::MCDisassembler::Success)
530         return new_inst_size;
531     else
532         return 0;
533 }
534
535 uint64_t
536 DisassemblerLLVMC::LLVMCDisassembler::PrintMCInst (llvm::MCInst &mc_inst,
537                                                    char *dst,
538                                                    size_t dst_len)
539 {
540     llvm::StringRef unused_annotations;
541     llvm::SmallString<64> inst_string;
542     llvm::raw_svector_ostream inst_stream(inst_string);
543     m_instr_printer_ap->printInst (&mc_inst, inst_stream, unused_annotations);
544     inst_stream.flush();
545     const size_t output_size = std::min(dst_len - 1, inst_string.size());
546     std::memcpy(dst, inst_string.data(), output_size);
547     dst[output_size] = '\0';
548     
549     return output_size;
550 }
551
552 void
553 DisassemblerLLVMC::LLVMCDisassembler::SetStyle (bool use_hex_immed, HexImmediateStyle hex_style)
554 {
555     m_instr_printer_ap->setPrintImmHex(use_hex_immed);
556     switch(hex_style)
557     {
558     case eHexStyleC:      m_instr_printer_ap->setPrintImmHex(llvm::HexStyle::C); break;
559     case eHexStyleAsm:    m_instr_printer_ap->setPrintImmHex(llvm::HexStyle::Asm); break;
560     }
561 }
562
563 bool
564 DisassemblerLLVMC::LLVMCDisassembler::CanBranch (llvm::MCInst &mc_inst)
565 {
566     return m_instr_info_ap->get(mc_inst.getOpcode()).mayAffectControlFlow(mc_inst, *m_reg_info_ap.get());
567 }
568
569 bool
570 DisassemblerLLVMC::FlavorValidForArchSpec (const lldb_private::ArchSpec &arch, const char *flavor)
571 {
572     llvm::Triple triple = arch.GetTriple();
573     if (flavor == NULL || strcmp (flavor, "default") == 0)
574         return true;
575     
576     if (triple.getArch() == llvm::Triple::x86 || triple.getArch() == llvm::Triple::x86_64)
577     {
578         if (strcmp (flavor, "intel") == 0 || strcmp (flavor, "att") == 0)
579             return true;
580         else
581             return false;
582     }
583     else
584         return false;
585 }
586     
587
588 Disassembler *
589 DisassemblerLLVMC::CreateInstance (const ArchSpec &arch, const char *flavor)
590 {
591     if (arch.GetTriple().getArch() != llvm::Triple::UnknownArch)
592     {
593         std::unique_ptr<DisassemblerLLVMC> disasm_ap (new DisassemblerLLVMC(arch, flavor));
594     
595         if (disasm_ap.get() && disasm_ap->IsValid())
596             return disasm_ap.release();
597     }
598     return NULL;
599 }
600
601 DisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch, const char *flavor_string) :
602     Disassembler(arch, flavor_string),
603     m_exe_ctx (NULL),
604     m_inst (NULL),
605     m_data_from_file (false)
606 {
607     if (!FlavorValidForArchSpec (arch, m_flavor.c_str()))
608     {
609         m_flavor.assign("default");
610     }
611     
612     const char *triple = arch.GetTriple().getTriple().c_str();
613     unsigned flavor = ~0U;
614     
615     // So far the only supported flavor is "intel" on x86.  The base class will set this
616     // correctly coming in.
617     if (arch.GetTriple().getArch() == llvm::Triple::x86
618         || arch.GetTriple().getArch() == llvm::Triple::x86_64)
619     {
620         if (m_flavor == "intel")
621         {
622             flavor = 1;
623         }
624         else if (m_flavor == "att")
625         {
626             flavor = 0;
627         }
628     }
629     
630     ArchSpec thumb_arch(arch);
631     if (arch.GetTriple().getArch() == llvm::Triple::arm)
632     {
633         std::string thumb_arch_name (thumb_arch.GetTriple().getArchName().str());
634         // Replace "arm" with "thumb" so we get all thumb variants correct
635         if (thumb_arch_name.size() > 3)
636         {
637             thumb_arch_name.erase(0,3);
638             thumb_arch_name.insert(0, "thumb");
639         }
640         else
641         {
642             thumb_arch_name = "thumbv7";
643         }
644         thumb_arch.GetTriple().setArchName(llvm::StringRef(thumb_arch_name.c_str()));
645     }
646     
647     // Cortex-M3 devices (e.g. armv7m) can only execute thumb (T2) instructions, 
648     // so hardcode the primary disassembler to thumb mode.  Same for Cortex-M4 (armv7em).
649     //
650     // Handle the Cortex-M0 (armv6m) the same; the ISA is a subset of the T and T32
651     // instructions defined in ARMv7-A.  
652
653     if (arch.GetTriple().getArch() == llvm::Triple::arm
654         && (arch.GetCore() == ArchSpec::Core::eCore_arm_armv7m 
655             || arch.GetCore() == ArchSpec::Core::eCore_arm_armv7em
656             || arch.GetCore() == ArchSpec::Core::eCore_arm_armv6m))
657     {
658         triple = thumb_arch.GetTriple().getTriple().c_str();
659     }
660
661     m_disasm_ap.reset (new LLVMCDisassembler(triple, flavor, *this));
662     if (!m_disasm_ap->IsValid())
663     {
664         // We use m_disasm_ap.get() to tell whether we are valid or not, so if this isn't good for some reason,
665         // we reset it, and then we won't be valid and FindPlugin will fail and we won't get used.
666         m_disasm_ap.reset();
667     }
668
669     // For arm CPUs that can execute arm or thumb instructions, also create a thumb instruction disassembler.
670     if (arch.GetTriple().getArch() == llvm::Triple::arm)
671     {
672         std::string thumb_triple(thumb_arch.GetTriple().getTriple());
673         m_alternate_disasm_ap.reset(new LLVMCDisassembler(thumb_triple.c_str(), flavor, *this));
674         if (!m_alternate_disasm_ap->IsValid())
675         {
676             m_disasm_ap.reset();
677             m_alternate_disasm_ap.reset();
678         }
679     }
680 }
681
682 DisassemblerLLVMC::~DisassemblerLLVMC()
683 {
684 }
685
686 size_t
687 DisassemblerLLVMC::DecodeInstructions (const Address &base_addr,
688                                        const DataExtractor& data,
689                                        lldb::offset_t data_offset,
690                                        size_t num_instructions,
691                                        bool append,
692                                        bool data_from_file)
693 {
694     if (!append)
695         m_instruction_list.Clear();
696     
697     if (!IsValid())
698         return 0;
699     
700     m_data_from_file = data_from_file;
701     uint32_t data_cursor = data_offset;
702     const size_t data_byte_size = data.GetByteSize();
703     uint32_t instructions_parsed = 0;
704     Address inst_addr(base_addr);
705     
706     while (data_cursor < data_byte_size && instructions_parsed < num_instructions)
707     {
708         
709         AddressClass address_class = eAddressClassCode;
710         
711         if (m_alternate_disasm_ap.get() != NULL)
712             address_class = inst_addr.GetAddressClass ();
713         
714         InstructionSP inst_sp(new InstructionLLVMC(*this,
715                                                    inst_addr, 
716                                                    address_class));
717         
718         if (!inst_sp)
719             break;
720         
721         uint32_t inst_size = inst_sp->Decode(*this, data, data_cursor);
722                 
723         if (inst_size == 0)
724             break;
725
726         m_instruction_list.Append(inst_sp);
727         data_cursor += inst_size;
728         inst_addr.Slide(inst_size);
729         instructions_parsed++;
730     }
731     
732     return data_cursor - data_offset;
733 }
734
735 void
736 DisassemblerLLVMC::Initialize()
737 {
738     PluginManager::RegisterPlugin (GetPluginNameStatic(),
739                                    "Disassembler that uses LLVM MC to disassemble i386, x86_64 and ARM.",
740                                    CreateInstance);
741     
742     llvm::InitializeAllTargetInfos();
743     llvm::InitializeAllTargetMCs();
744     llvm::InitializeAllAsmParsers();
745     llvm::InitializeAllDisassemblers();
746 }
747
748 void
749 DisassemblerLLVMC::Terminate()
750 {
751     PluginManager::UnregisterPlugin (CreateInstance);
752 }
753
754
755 ConstString
756 DisassemblerLLVMC::GetPluginNameStatic()
757 {
758     static ConstString g_name("llvm-mc");
759     return g_name;
760 }
761
762 int DisassemblerLLVMC::OpInfoCallback (void *disassembler,
763                                        uint64_t pc,
764                                        uint64_t offset,
765                                        uint64_t size,
766                                        int tag_type,
767                                        void *tag_bug)
768 {
769     return static_cast<DisassemblerLLVMC*>(disassembler)->OpInfo (pc,
770                                                                   offset,
771                                                                   size,
772                                                                   tag_type,
773                                                                   tag_bug);
774 }
775
776 const char *DisassemblerLLVMC::SymbolLookupCallback (void *disassembler,
777                                                      uint64_t value,
778                                                      uint64_t *type,
779                                                      uint64_t pc,
780                                                      const char **name)
781 {
782     return static_cast<DisassemblerLLVMC*>(disassembler)->SymbolLookup(value,
783                                                                        type,
784                                                                        pc,
785                                                                        name);
786 }
787
788 int DisassemblerLLVMC::OpInfo (uint64_t PC,
789                                uint64_t Offset,
790                                uint64_t Size,
791                                int tag_type,
792                                void *tag_bug)
793 {
794     switch (tag_type)
795     {
796     default:
797         break;
798     case 1:
799         memset (tag_bug, 0, sizeof(::LLVMOpInfo1));
800         break;
801     }
802     return 0;
803 }
804
805 const char *DisassemblerLLVMC::SymbolLookup (uint64_t value,
806                                              uint64_t *type_ptr,
807                                              uint64_t pc,
808                                              const char **name)
809 {
810     if (*type_ptr)
811     {
812         if (m_exe_ctx && m_inst)
813         {        
814             //std::string remove_this_prior_to_checkin;
815             Target *target = m_exe_ctx ? m_exe_ctx->GetTargetPtr() : NULL;
816             Address value_so_addr;
817             if (m_inst->UsingFileAddress())
818             {
819                 ModuleSP module_sp(m_inst->GetAddress().GetModule());
820                 if (module_sp)
821                     module_sp->ResolveFileAddress(value, value_so_addr);
822             }
823             else if (target && !target->GetSectionLoadList().IsEmpty())
824             {
825                 target->GetSectionLoadList().ResolveLoadAddress(value, value_so_addr);
826             }
827             
828             if (value_so_addr.IsValid() && value_so_addr.GetSection())
829             {
830                 StreamString ss;
831                 
832                 value_so_addr.Dump (&ss,
833                                     target,
834                                     Address::DumpStyleResolvedDescriptionNoModule,
835                                     Address::DumpStyleSectionNameOffset);
836                 
837                 if (!ss.GetString().empty())
838                 {
839                     m_inst->AppendComment(ss.GetString());
840                 }
841             }
842         }
843     }
844
845     *type_ptr = LLVMDisassembler_ReferenceType_InOut_None;
846     *name = NULL;
847     return NULL;
848 }
849
850 //------------------------------------------------------------------
851 // PluginInterface protocol
852 //------------------------------------------------------------------
853 ConstString
854 DisassemblerLLVMC::GetPluginName()
855 {
856     return GetPluginNameStatic();
857 }
858
859 uint32_t
860 DisassemblerLLVMC::GetPluginVersion()
861 {
862     return 1;
863 }
864