blob: 23a788b16b5cf20d2f614291e62e222f6b070b50 [file] [log] [blame]
Chris Lattner24943d22010-06-08 16:52:24 +00001//===-- DisassemblerLLVM.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 "DisassemblerLLVM.h"
11
12#include "llvm-c/EnhancedDisassembly.h"
13
14#include "lldb/Core/Address.h"
15#include "lldb/Core/DataExtractor.h"
16#include "lldb/Core/Disassembler.h"
17#include "lldb/Core/Module.h"
18#include "lldb/Core/PluginManager.h"
19#include "lldb/Core/Stream.h"
20#include "lldb/Core/StreamString.h"
21#include "lldb/Symbol/SymbolContext.h"
22
23#include "lldb/Target/ExecutionContext.h"
24#include "lldb/Target/Process.h"
25#include "lldb/Target/RegisterContext.h"
26#include "lldb/Target/Target.h"
27
Greg Claytonb01000f2011-01-17 03:46:26 +000028#include <assert.h>
Chris Lattner24943d22010-06-08 16:52:24 +000029
30using namespace lldb;
31using namespace lldb_private;
32
33
Greg Claytonb1888f22011-03-19 01:12:21 +000034static int
Greg Clayton7bc39082011-03-24 23:53:38 +000035DataExtractorByteReader (uint8_t *byte, uint64_t address, void *arg)
Chris Lattner24943d22010-06-08 16:52:24 +000036{
37 DataExtractor &extractor = *((DataExtractor *)arg);
38
39 if (extractor.ValidOffset(address))
40 {
41 *byte = *(extractor.GetDataStart() + address);
42 return 0;
43 }
44 else
45 {
46 return -1;
47 }
48}
49
50namespace {
51 struct RegisterReaderArg {
52 const lldb::addr_t instructionPointer;
53 const EDDisassemblerRef disassembler;
54
55 RegisterReaderArg(lldb::addr_t ip,
56 EDDisassemblerRef dis) :
57 instructionPointer(ip),
58 disassembler(dis)
59 {
60 }
61 };
62}
63
64static int IPRegisterReader(uint64_t *value, unsigned regID, void* arg)
65{
66 uint64_t instructionPointer = ((RegisterReaderArg*)arg)->instructionPointer;
67 EDDisassemblerRef disassembler = ((RegisterReaderArg*)arg)->disassembler;
68
Greg Claytonb1888f22011-03-19 01:12:21 +000069 if (EDRegisterIsProgramCounter(disassembler, regID)) {
Chris Lattner24943d22010-06-08 16:52:24 +000070 *value = instructionPointer;
71 return 0;
72 }
73
74 return -1;
75}
76
Caroline Ticeaf591802011-04-05 23:22:54 +000077InstructionLLVM::InstructionLLVM (const Address &addr,
78 AddressClass addr_class,
Greg Claytonabe0fed2011-04-18 08:33:37 +000079 EDDisassemblerRef disassembler,
80 bool force_raw) :
Greg Clayton889fbd02011-03-26 19:14:58 +000081 Instruction (addr, addr_class),
Greg Claytonabe0fed2011-04-18 08:33:37 +000082 m_disassembler (disassembler),
83 m_force_raw (force_raw)
Chris Lattner24943d22010-06-08 16:52:24 +000084{
85}
86
Caroline Ticeaf591802011-04-05 23:22:54 +000087InstructionLLVM::~InstructionLLVM()
Chris Lattner24943d22010-06-08 16:52:24 +000088{
89}
90
91static void
92PadString(Stream *s, const std::string &str, size_t width)
93{
94 int diff = width - str.length();
95
96 if (diff > 0)
97 s->Printf("%s%*.*s", str.c_str(), diff, diff, "");
98 else
99 s->Printf("%s ", str.c_str());
100}
101
102void
Caroline Ticeaf591802011-04-05 23:22:54 +0000103InstructionLLVM::Dump
Chris Lattner24943d22010-06-08 16:52:24 +0000104(
105 Stream *s,
Greg Clayton889fbd02011-03-26 19:14:58 +0000106 uint32_t max_opcode_byte_size,
Greg Clayton5c4c7462010-10-06 03:09:58 +0000107 bool show_address,
Greg Clayton149731c2011-03-25 18:03:16 +0000108 bool show_bytes,
Greg Clayton5c4c7462010-10-06 03:09:58 +0000109 const lldb_private::ExecutionContext* exe_ctx,
Chris Lattner24943d22010-06-08 16:52:24 +0000110 bool raw
111)
112{
113 const size_t opcodeColumnWidth = 7;
114 const size_t operandColumnWidth = 25;
115
Greg Clayton5c4c7462010-10-06 03:09:58 +0000116 ExecutionContextScope *exe_scope = NULL;
117 if (exe_ctx)
118 exe_scope = exe_ctx->GetBestExecutionContextScope();
119
Chris Lattner24943d22010-06-08 16:52:24 +0000120 // If we have an address, print it out
Sean Callanan91557b02010-11-10 01:38:28 +0000121 if (GetAddress().IsValid() && show_address)
Greg Clayton70436352010-06-30 23:03:03 +0000122 {
Greg Clayton5c4c7462010-10-06 03:09:58 +0000123 if (GetAddress().Dump (s,
124 exe_scope,
125 Address::DumpStyleLoadAddress,
126 Address::DumpStyleModuleWithFileAddress,
127 0))
Greg Clayton70436352010-06-30 23:03:03 +0000128 s->PutCString(": ");
129 }
Chris Lattner24943d22010-06-08 16:52:24 +0000130
131 // If we are supposed to show bytes, "bytes" will be non-NULL.
Greg Clayton149731c2011-03-25 18:03:16 +0000132 if (show_bytes)
Chris Lattner24943d22010-06-08 16:52:24 +0000133 {
Greg Clayton149731c2011-03-25 18:03:16 +0000134 if (m_opcode.GetType() == Opcode::eTypeBytes)
Chris Lattner24943d22010-06-08 16:52:24 +0000135 {
Greg Clayton149731c2011-03-25 18:03:16 +0000136 // x86_64 and i386 are the only ones that use bytes right now so
137 // pad out the byte dump to be able to always show 15 bytes (3 chars each)
138 // plus a space
Greg Clayton889fbd02011-03-26 19:14:58 +0000139 if (max_opcode_byte_size > 0)
140 m_opcode.Dump (s, max_opcode_byte_size * 3 + 1);
141 else
142 m_opcode.Dump (s, 15 * 3 + 1);
Greg Clayton149731c2011-03-25 18:03:16 +0000143 }
144 else
145 {
146 // Else, we have ARM which can show up to a uint32_t 0x00000000 (10 spaces)
147 // plus two for padding...
Greg Clayton889fbd02011-03-26 19:14:58 +0000148 if (max_opcode_byte_size > 0)
149 m_opcode.Dump (s, max_opcode_byte_size * 3 + 1);
150 else
151 m_opcode.Dump (s, 12);
Chris Lattner24943d22010-06-08 16:52:24 +0000152 }
153 }
154
Greg Claytonf15996e2011-04-07 22:46:35 +0000155 int numTokens = -1;
156
157 if (!raw)
Greg Claytonabe0fed2011-04-18 08:33:37 +0000158 raw = m_force_raw;
159
160 if (!raw)
Greg Claytonf15996e2011-04-07 22:46:35 +0000161 numTokens = EDNumTokens(m_inst);
Chris Lattner24943d22010-06-08 16:52:24 +0000162
163 int currentOpIndex = -1;
164
Greg Claytonf15996e2011-04-07 22:46:35 +0000165 bool printTokenized = false;
166
167 if (numTokens != -1 && !raw)
Sean Callanan8541f2f2010-07-23 02:19:15 +0000168 {
169 addr_t base_addr = LLDB_INVALID_ADDRESS;
Greg Claytonf15996e2011-04-07 22:46:35 +0000170
171 RegisterReaderArg rra(base_addr + EDInstByteSize(m_inst), m_disassembler);
172
Greg Clayton5c4c7462010-10-06 03:09:58 +0000173 if (exe_ctx && exe_ctx->target && !exe_ctx->target->GetSectionLoadList().IsEmpty())
174 base_addr = GetAddress().GetLoadAddress (exe_ctx->target);
Sean Callanan8541f2f2010-07-23 02:19:15 +0000175 if (base_addr == LLDB_INVALID_ADDRESS)
Greg Clayton5c4c7462010-10-06 03:09:58 +0000176 base_addr = GetAddress().GetFileAddress ();
Greg Claytonf15996e2011-04-07 22:46:35 +0000177
Chris Lattner24943d22010-06-08 16:52:24 +0000178 printTokenized = true;
179
180 // Handle the opcode column.
181
182 StreamString opcode;
183
184 int tokenIndex = 0;
185
186 EDTokenRef token;
187 const char *tokenStr;
188
189 if (EDGetToken(&token, m_inst, tokenIndex))
190 printTokenized = false;
191
192 if (!printTokenized || !EDTokenIsOpcode(token))
193 printTokenized = false;
194
195 if (!printTokenized || EDGetTokenString(&tokenStr, token))
196 printTokenized = false;
197
198 // Put the token string into our opcode string
199 opcode.PutCString(tokenStr);
200
201 // If anything follows, it probably starts with some whitespace. Skip it.
202
203 tokenIndex++;
204
205 if (printTokenized && tokenIndex < numTokens)
206 {
207 if(!printTokenized || EDGetToken(&token, m_inst, tokenIndex))
208 printTokenized = false;
209
210 if(!printTokenized || !EDTokenIsWhitespace(token))
211 printTokenized = false;
212 }
213
214 tokenIndex++;
215
216 // Handle the operands and the comment.
217
218 StreamString operands;
219 StreamString comment;
220
221 if (printTokenized)
222 {
223 bool show_token;
224
225 for (; tokenIndex < numTokens; ++tokenIndex)
226 {
227 if (EDGetToken(&token, m_inst, tokenIndex))
228 return;
229
230 if (raw)
231 {
232 show_token = true;
233 }
234 else
235 {
236 int operandIndex = EDOperandIndexForToken(token);
237
238 if (operandIndex >= 0)
239 {
240 if (operandIndex != currentOpIndex)
241 {
242 show_token = true;
243
244 currentOpIndex = operandIndex;
245 EDOperandRef operand;
246
247 if (!EDGetOperand(&operand, m_inst, currentOpIndex))
248 {
249 if (EDOperandIsMemory(operand))
250 {
251 uint64_t operand_value;
252
Greg Claytonf15996e2011-04-07 22:46:35 +0000253 if (!EDEvaluateOperand(&operand_value, operand, IPRegisterReader, &rra))
Chris Lattner24943d22010-06-08 16:52:24 +0000254 {
255 if (EDInstIsBranch(m_inst))
256 {
257 operands.Printf("0x%llx ", operand_value);
258 show_token = false;
259 }
260 else
261 {
262 // Put the address value into the comment
263 comment.Printf("0x%llx ", operand_value);
264 }
265
266 lldb_private::Address so_addr;
Greg Clayton5c4c7462010-10-06 03:09:58 +0000267 if (exe_ctx && exe_ctx->target && !exe_ctx->target->GetSectionLoadList().IsEmpty())
Chris Lattner24943d22010-06-08 16:52:24 +0000268 {
Greg Clayton5c4c7462010-10-06 03:09:58 +0000269 if (exe_ctx->target->GetSectionLoadList().ResolveLoadAddress (operand_value, so_addr))
Greg Claytoncf7f1ad2010-07-01 01:26:43 +0000270 so_addr.Dump(&comment, exe_scope, Address::DumpStyleResolvedDescriptionNoModule, Address::DumpStyleSectionNameOffset);
Greg Clayton70436352010-06-30 23:03:03 +0000271 }
Greg Clayton5c4c7462010-10-06 03:09:58 +0000272 else
Greg Clayton70436352010-06-30 23:03:03 +0000273 {
Greg Clayton5c4c7462010-10-06 03:09:58 +0000274 Module *module = GetAddress().GetModule();
Greg Clayton70436352010-06-30 23:03:03 +0000275 if (module)
Chris Lattner24943d22010-06-08 16:52:24 +0000276 {
Greg Clayton70436352010-06-30 23:03:03 +0000277 if (module->ResolveFileAddress (operand_value, so_addr))
Greg Claytoncf7f1ad2010-07-01 01:26:43 +0000278 so_addr.Dump(&comment, exe_scope, Address::DumpStyleResolvedDescriptionNoModule, Address::DumpStyleSectionNameOffset);
Chris Lattner24943d22010-06-08 16:52:24 +0000279 }
280 }
Greg Clayton70436352010-06-30 23:03:03 +0000281
Chris Lattner24943d22010-06-08 16:52:24 +0000282 } // EDEvaluateOperand
283 } // EDOperandIsMemory
284 } // EDGetOperand
285 } // operandIndex != currentOpIndex
286 } // operandIndex >= 0
287 } // else(raw)
288
289 if (show_token)
290 {
291 if(EDGetTokenString(&tokenStr, token))
292 {
293 printTokenized = false;
294 break;
295 }
296
297 operands.PutCString(tokenStr);
298 }
299 } // for (tokenIndex)
300
301 if (printTokenized)
302 {
303 if (operands.GetString().empty())
304 {
305 s->PutCString(opcode.GetString().c_str());
306 }
307 else
308 {
309 PadString(s, opcode.GetString(), opcodeColumnWidth);
310
311 if (comment.GetString().empty())
312 {
313 s->PutCString(operands.GetString().c_str());
314 }
315 else
316 {
317 PadString(s, operands.GetString(), operandColumnWidth);
318
319 s->PutCString("; ");
320 s->PutCString(comment.GetString().c_str());
321 } // else (comment.GetString().empty())
322 } // else (operands.GetString().empty())
323 } // printTokenized
324 } // for (tokenIndex)
325 } // numTokens != -1
326
327 if (!printTokenized)
328 {
329 const char *str;
330
331 if (EDGetInstString(&str, m_inst))
332 return;
333 else
Greg Claytonf15996e2011-04-07 22:46:35 +0000334 s->Write(str, strlen(str) - 1);
Chris Lattner24943d22010-06-08 16:52:24 +0000335 }
336}
337
338bool
Caroline Ticeaf591802011-04-05 23:22:54 +0000339InstructionLLVM::DoesBranch() const
Chris Lattner24943d22010-06-08 16:52:24 +0000340{
341 return EDInstIsBranch(m_inst);
342}
343
344size_t
Caroline Ticeaf591802011-04-05 23:22:54 +0000345InstructionLLVM::Decode (const Disassembler &disassembler,
346 const lldb_private::DataExtractor &data,
347 uint32_t data_offset)
Chris Lattner24943d22010-06-08 16:52:24 +0000348{
349 if (EDCreateInsts(&m_inst, 1, m_disassembler, DataExtractorByteReader, data_offset, (void*)(&data)))
Greg Clayton7bc39082011-03-24 23:53:38 +0000350 {
351 const int byte_size = EDInstByteSize(m_inst);
352 uint32_t offset = data_offset;
353 // Make a copy of the opcode in m_opcode
354 switch (disassembler.GetArchitecture().GetMachine())
355 {
356 case llvm::Triple::x86:
357 case llvm::Triple::x86_64:
358 m_opcode.SetOpcodeBytes (data.PeekData (data_offset, byte_size), byte_size);
359 break;
360
361 case llvm::Triple::arm:
Greg Clayton7bc39082011-03-24 23:53:38 +0000362 case llvm::Triple::thumb:
Greg Clayton149731c2011-03-25 18:03:16 +0000363 switch (byte_size)
364 {
365 case 2:
366 m_opcode.SetOpcode16 (data.GetU16 (&offset));
367 break;
368
369 case 4:
Caroline Tice6b8d3b52011-04-19 23:30:03 +0000370 {
371 if (GetAddressClass() == eAddressClassCodeAlternateISA)
372 {
373 // If it is a 32-bit THUMB instruction, we need to swap the upper & lower halves.
374 uint32_t orig_bytes = data.GetU32 (&offset);
375 uint16_t upper_bits = (orig_bytes >> 16) & ((1u << 16) - 1);
376 uint16_t lower_bits = orig_bytes & ((1u << 16) - 1);
377 uint32_t swapped = (lower_bits << 16) | upper_bits;
378 m_opcode.SetOpcode32 (swapped);
379 }
380 else
381 m_opcode.SetOpcode32 (data.GetU32 (&offset));
382 }
Greg Clayton149731c2011-03-25 18:03:16 +0000383 break;
384
385 default:
386 assert (!"Invalid ARM opcode size");
387 break;
388 }
Greg Clayton7bc39082011-03-24 23:53:38 +0000389 break;
390
391 default:
392 assert (!"This shouldn't happen since we control the architecture we allow DisassemblerLLVM to be created for");
393 break;
394 }
395 return byte_size;
396 }
Chris Lattner24943d22010-06-08 16:52:24 +0000397 else
398 return 0;
399}
400
Chris Lattner24943d22010-06-08 16:52:24 +0000401static inline EDAssemblySyntax_t
Greg Claytoncf015052010-06-11 03:25:34 +0000402SyntaxForArchSpec (const ArchSpec &arch)
Chris Lattner24943d22010-06-08 16:52:24 +0000403{
Greg Clayton940b1032011-02-23 00:35:02 +0000404 switch (arch.GetMachine ())
Greg Clayton5e4f4a22011-02-16 00:00:43 +0000405 {
Greg Clayton940b1032011-02-23 00:35:02 +0000406 case llvm::Triple::x86:
407 case llvm::Triple::x86_64:
Chris Lattner24943d22010-06-08 16:52:24 +0000408 return kEDAssemblySyntaxX86ATT;
Sean Callanand151c8a2011-03-09 01:02:51 +0000409 case llvm::Triple::arm:
Greg Clayton889fbd02011-03-26 19:14:58 +0000410 case llvm::Triple::thumb:
Sean Callanand151c8a2011-03-09 01:02:51 +0000411 return kEDAssemblySyntaxARMUAL;
Greg Clayton5e4f4a22011-02-16 00:00:43 +0000412 default:
413 break;
414 }
Greg Claytoncf015052010-06-11 03:25:34 +0000415 return (EDAssemblySyntax_t)0; // default
Chris Lattner24943d22010-06-08 16:52:24 +0000416}
417
418Disassembler *
419DisassemblerLLVM::CreateInstance(const ArchSpec &arch)
420{
Greg Clayton5e4f4a22011-02-16 00:00:43 +0000421 std::auto_ptr<DisassemblerLLVM> disasm_ap (new DisassemblerLLVM(arch));
422
Caroline Tice080bf612011-04-05 18:46:00 +0000423 if (disasm_ap.get() && disasm_ap->IsValid())
Greg Clayton5e4f4a22011-02-16 00:00:43 +0000424 return disasm_ap.release();
Chris Lattner24943d22010-06-08 16:52:24 +0000425
Greg Claytoncf015052010-06-11 03:25:34 +0000426 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000427}
428
429DisassemblerLLVM::DisassemblerLLVM(const ArchSpec &arch) :
Greg Claytonb01000f2011-01-17 03:46:26 +0000430 Disassembler (arch),
Greg Claytonb1888f22011-03-19 01:12:21 +0000431 m_disassembler (NULL),
432 m_disassembler_thumb (NULL) // For ARM only
Chris Lattner24943d22010-06-08 16:52:24 +0000433{
Greg Clayton5e4f4a22011-02-16 00:00:43 +0000434 const std::string &arch_triple = arch.GetTriple().str();
435 if (!arch_triple.empty())
Greg Claytoncf015052010-06-11 03:25:34 +0000436 {
Greg Clayton5e4f4a22011-02-16 00:00:43 +0000437 if (EDGetDisassembler(&m_disassembler, arch_triple.c_str(), SyntaxForArchSpec (arch)))
438 m_disassembler = NULL;
Greg Claytonb1888f22011-03-19 01:12:21 +0000439 llvm::Triple::ArchType llvm_arch = arch.GetTriple().getArch();
Greg Clayton889fbd02011-03-26 19:14:58 +0000440 // Don't have the lldb::Triple::thumb architecture here. If someone specifies
441 // "thumb" as the architecture, we want a thumb only disassembler. But if any
442 // architecture starting with "arm" if specified, we want to auto detect the
443 // arm/thumb code automatically using the AddressClass from section offset
444 // addresses.
Greg Claytonb1888f22011-03-19 01:12:21 +0000445 if (llvm_arch == llvm::Triple::arm)
446 {
447 if (EDGetDisassembler(&m_disassembler_thumb, "thumb-apple-darwin", kEDAssemblySyntaxARMUAL))
448 m_disassembler_thumb = NULL;
449 }
Greg Claytoncf015052010-06-11 03:25:34 +0000450 }
Chris Lattner24943d22010-06-08 16:52:24 +0000451}
452
453DisassemblerLLVM::~DisassemblerLLVM()
454{
455}
456
457size_t
Greg Clayton70436352010-06-30 23:03:03 +0000458DisassemblerLLVM::DecodeInstructions
Chris Lattner24943d22010-06-08 16:52:24 +0000459(
Greg Clayton5c4c7462010-10-06 03:09:58 +0000460 const Address &base_addr,
Chris Lattner24943d22010-06-08 16:52:24 +0000461 const DataExtractor& data,
462 uint32_t data_offset,
Jim Inghamaa3e3e12011-03-22 01:48:42 +0000463 uint32_t num_instructions,
464 bool append
Chris Lattner24943d22010-06-08 16:52:24 +0000465)
466{
Greg Claytonb01000f2011-01-17 03:46:26 +0000467 if (m_disassembler == NULL)
468 return 0;
469
Chris Lattner24943d22010-06-08 16:52:24 +0000470 size_t total_inst_byte_size = 0;
471
Jim Inghamaa3e3e12011-03-22 01:48:42 +0000472 if (!append)
473 m_instruction_list.Clear();
Chris Lattner24943d22010-06-08 16:52:24 +0000474
475 while (data.ValidOffset(data_offset) && num_instructions)
476 {
Greg Clayton5c4c7462010-10-06 03:09:58 +0000477 Address inst_addr (base_addr);
478 inst_addr.Slide(data_offset);
Greg Claytonb1888f22011-03-19 01:12:21 +0000479
480 bool use_thumb = false;
481 // If we have a thumb disassembler, then we have an ARM architecture
482 // so we need to check what the instruction address class is to make
483 // sure we shouldn't be disassembling as thumb...
Greg Clayton889fbd02011-03-26 19:14:58 +0000484 AddressClass inst_address_class = eAddressClassInvalid;
Greg Claytonb1888f22011-03-19 01:12:21 +0000485 if (m_disassembler_thumb)
486 {
Greg Clayton889fbd02011-03-26 19:14:58 +0000487 inst_address_class = inst_addr.GetAddressClass ();
488 if (inst_address_class == eAddressClassCodeAlternateISA)
Greg Claytonb1888f22011-03-19 01:12:21 +0000489 use_thumb = true;
490 }
Greg Claytonabe0fed2011-04-18 08:33:37 +0000491 bool force_raw = false;
492 switch (m_arch.GetMachine())
493 {
494 case llvm::Triple::arm:
495 case llvm::Triple::thumb:
496 force_raw = true;
497 break;
498 default:
499 break;
500 }
Greg Clayton7bc39082011-03-24 23:53:38 +0000501 InstructionSP inst_sp (new InstructionLLVM (inst_addr,
Greg Clayton889fbd02011-03-26 19:14:58 +0000502 inst_address_class,
Greg Claytonabe0fed2011-04-18 08:33:37 +0000503 use_thumb ? m_disassembler_thumb : m_disassembler,
504 force_raw));
Chris Lattner24943d22010-06-08 16:52:24 +0000505
Greg Clayton889fbd02011-03-26 19:14:58 +0000506 size_t inst_byte_size = inst_sp->Decode (*this, data, data_offset);
Chris Lattner24943d22010-06-08 16:52:24 +0000507
508 if (inst_byte_size == 0)
509 break;
510
Greg Clayton5c4c7462010-10-06 03:09:58 +0000511 m_instruction_list.Append (inst_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000512
513 total_inst_byte_size += inst_byte_size;
514 data_offset += inst_byte_size;
515 num_instructions--;
516 }
517
518 return total_inst_byte_size;
519}
520
521void
522DisassemblerLLVM::Initialize()
523{
524 PluginManager::RegisterPlugin (GetPluginNameStatic(),
525 GetPluginDescriptionStatic(),
526 CreateInstance);
527}
528
529void
530DisassemblerLLVM::Terminate()
531{
532 PluginManager::UnregisterPlugin (CreateInstance);
533}
534
535
536const char *
537DisassemblerLLVM::GetPluginNameStatic()
538{
Greg Clayton149731c2011-03-25 18:03:16 +0000539 return "llvm";
Chris Lattner24943d22010-06-08 16:52:24 +0000540}
541
542const char *
543DisassemblerLLVM::GetPluginDescriptionStatic()
544{
Greg Clayton149731c2011-03-25 18:03:16 +0000545 return "Disassembler that uses LLVM opcode tables to disassemble i386, x86_64 and ARM.";
Chris Lattner24943d22010-06-08 16:52:24 +0000546}
547
548//------------------------------------------------------------------
549// PluginInterface protocol
550//------------------------------------------------------------------
551const char *
552DisassemblerLLVM::GetPluginName()
553{
554 return "DisassemblerLLVM";
555}
556
557const char *
558DisassemblerLLVM::GetShortPluginName()
559{
560 return GetPluginNameStatic();
561}
562
563uint32_t
564DisassemblerLLVM::GetPluginVersion()
565{
566 return 1;
567}
568