blob: 2620eedac616da6c19f8f26387232108924e12ba [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,
Johnny Chen80ab18e2011-05-12 22:25:53 +000080 llvm::Triple::ArchType arch_type) :
Greg Clayton889fbd02011-03-26 19:14:58 +000081 Instruction (addr, addr_class),
Greg Claytonabe0fed2011-04-18 08:33:37 +000082 m_disassembler (disassembler),
Johnny Chen80ab18e2011-05-12 22:25:53 +000083 m_arch_type (arch_type)
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
Johnny Chen80ab18e2011-05-12 22:25:53 +0000157 // FIXME!!!
158 /* Remove the following section of code related to force_raw .... */
159 bool force_raw = m_arch_type == llvm::Triple::arm ||
160 m_arch_type == llvm::Triple::thumb;
Greg Claytonf15996e2011-04-07 22:46:35 +0000161 if (!raw)
Johnny Chen80ab18e2011-05-12 22:25:53 +0000162 raw = force_raw;
163 /* .... when we fix the edis for arm/thumb. */
Greg Claytonabe0fed2011-04-18 08:33:37 +0000164
165 if (!raw)
Greg Claytonf15996e2011-04-07 22:46:35 +0000166 numTokens = EDNumTokens(m_inst);
Chris Lattner24943d22010-06-08 16:52:24 +0000167
168 int currentOpIndex = -1;
169
Greg Claytonf15996e2011-04-07 22:46:35 +0000170 bool printTokenized = false;
171
172 if (numTokens != -1 && !raw)
Sean Callanan8541f2f2010-07-23 02:19:15 +0000173 {
174 addr_t base_addr = LLDB_INVALID_ADDRESS;
Greg Claytonf15996e2011-04-07 22:46:35 +0000175
Greg Clayton5c4c7462010-10-06 03:09:58 +0000176 if (exe_ctx && exe_ctx->target && !exe_ctx->target->GetSectionLoadList().IsEmpty())
177 base_addr = GetAddress().GetLoadAddress (exe_ctx->target);
Sean Callanan8541f2f2010-07-23 02:19:15 +0000178 if (base_addr == LLDB_INVALID_ADDRESS)
Greg Clayton5c4c7462010-10-06 03:09:58 +0000179 base_addr = GetAddress().GetFileAddress ();
Greg Claytonf15996e2011-04-07 22:46:35 +0000180
Johnny Chen80ab18e2011-05-12 22:25:53 +0000181 lldb::addr_t PC = base_addr + EDInstByteSize(m_inst);
182
183 // When executing an ARM instruction, PC reads as the address of the
184 // current instruction plus 8. And for Thumb, it is plus 4.
185 if (m_arch_type == llvm::Triple::arm)
186 PC = base_addr + 8;
187 else if (m_arch_type == llvm::Triple::thumb)
188 PC = base_addr + 4;
189
190 RegisterReaderArg rra(PC, m_disassembler);
Johnny Chenc5272bf2011-05-12 18:48:11 +0000191
Chris Lattner24943d22010-06-08 16:52:24 +0000192 printTokenized = true;
193
194 // Handle the opcode column.
195
196 StreamString opcode;
197
198 int tokenIndex = 0;
199
200 EDTokenRef token;
201 const char *tokenStr;
202
203 if (EDGetToken(&token, m_inst, tokenIndex))
204 printTokenized = false;
205
206 if (!printTokenized || !EDTokenIsOpcode(token))
207 printTokenized = false;
208
209 if (!printTokenized || EDGetTokenString(&tokenStr, token))
210 printTokenized = false;
211
212 // Put the token string into our opcode string
213 opcode.PutCString(tokenStr);
214
215 // If anything follows, it probably starts with some whitespace. Skip it.
216
217 tokenIndex++;
218
219 if (printTokenized && tokenIndex < numTokens)
220 {
221 if(!printTokenized || EDGetToken(&token, m_inst, tokenIndex))
222 printTokenized = false;
223
224 if(!printTokenized || !EDTokenIsWhitespace(token))
225 printTokenized = false;
226 }
227
228 tokenIndex++;
229
230 // Handle the operands and the comment.
231
232 StreamString operands;
233 StreamString comment;
234
235 if (printTokenized)
236 {
237 bool show_token;
238
239 for (; tokenIndex < numTokens; ++tokenIndex)
240 {
241 if (EDGetToken(&token, m_inst, tokenIndex))
242 return;
243
Johnny Chen6d61ebf2011-05-18 22:08:52 +0000244 int operandIndex = EDOperandIndexForToken(token);
Chris Lattner24943d22010-06-08 16:52:24 +0000245
Johnny Chen6d61ebf2011-05-18 22:08:52 +0000246 if (operandIndex >= 0)
247 {
248 if (operandIndex != currentOpIndex)
Chris Lattner24943d22010-06-08 16:52:24 +0000249 {
Johnny Chen6d61ebf2011-05-18 22:08:52 +0000250 show_token = true;
251
252 currentOpIndex = operandIndex;
253 EDOperandRef operand;
254
255 if (!EDGetOperand(&operand, m_inst, currentOpIndex))
Chris Lattner24943d22010-06-08 16:52:24 +0000256 {
Johnny Chen6d61ebf2011-05-18 22:08:52 +0000257 if (EDOperandIsMemory(operand))
Chris Lattner24943d22010-06-08 16:52:24 +0000258 {
Johnny Chen6d61ebf2011-05-18 22:08:52 +0000259 uint64_t operand_value;
260
261 if (!EDEvaluateOperand(&operand_value, operand, IPRegisterReader, &rra))
Chris Lattner24943d22010-06-08 16:52:24 +0000262 {
Johnny Chen6d61ebf2011-05-18 22:08:52 +0000263 if (EDInstIsBranch(m_inst))
Chris Lattner24943d22010-06-08 16:52:24 +0000264 {
Johnny Chen6d61ebf2011-05-18 22:08:52 +0000265 operands.Printf("0x%llx ", operand_value);
266 show_token = false;
267 }
268 else
269 {
270 // Put the address value into the comment
271 comment.Printf("0x%llx ", operand_value);
272 }
Chris Lattner24943d22010-06-08 16:52:24 +0000273
Johnny Chen6d61ebf2011-05-18 22:08:52 +0000274 lldb_private::Address so_addr;
275 if (exe_ctx && exe_ctx->target && !exe_ctx->target->GetSectionLoadList().IsEmpty())
276 {
277 if (exe_ctx->target->GetSectionLoadList().ResolveLoadAddress (operand_value, so_addr))
278 so_addr.Dump(&comment, exe_scope, Address::DumpStyleResolvedDescriptionNoModule, Address::DumpStyleSectionNameOffset);
279 }
280 else
281 {
282 Module *module = GetAddress().GetModule();
283 if (module)
Chris Lattner24943d22010-06-08 16:52:24 +0000284 {
Johnny Chen6d61ebf2011-05-18 22:08:52 +0000285 if (module->ResolveFileAddress (operand_value, so_addr))
Greg Claytoncf7f1ad2010-07-01 01:26:43 +0000286 so_addr.Dump(&comment, exe_scope, Address::DumpStyleResolvedDescriptionNoModule, Address::DumpStyleSectionNameOffset);
Greg Clayton70436352010-06-30 23:03:03 +0000287 }
Johnny Chen6d61ebf2011-05-18 22:08:52 +0000288 }
289 } // EDEvaluateOperand
290 } // EDOperandIsMemory
291 } // EDGetOperand
292 } // operandIndex != currentOpIndex
293 } // operandIndex >= 0
Chris Lattner24943d22010-06-08 16:52:24 +0000294
295 if (show_token)
296 {
297 if(EDGetTokenString(&tokenStr, token))
298 {
299 printTokenized = false;
300 break;
301 }
302
303 operands.PutCString(tokenStr);
304 }
305 } // for (tokenIndex)
306
307 if (printTokenized)
308 {
309 if (operands.GetString().empty())
310 {
311 s->PutCString(opcode.GetString().c_str());
312 }
313 else
314 {
315 PadString(s, opcode.GetString(), opcodeColumnWidth);
316
317 if (comment.GetString().empty())
318 {
319 s->PutCString(operands.GetString().c_str());
320 }
321 else
322 {
323 PadString(s, operands.GetString(), operandColumnWidth);
324
325 s->PutCString("; ");
326 s->PutCString(comment.GetString().c_str());
327 } // else (comment.GetString().empty())
328 } // else (operands.GetString().empty())
329 } // printTokenized
330 } // for (tokenIndex)
331 } // numTokens != -1
332
333 if (!printTokenized)
334 {
335 const char *str;
336
337 if (EDGetInstString(&str, m_inst))
338 return;
339 else
Greg Claytonf15996e2011-04-07 22:46:35 +0000340 s->Write(str, strlen(str) - 1);
Chris Lattner24943d22010-06-08 16:52:24 +0000341 }
342}
343
344bool
Caroline Ticeaf591802011-04-05 23:22:54 +0000345InstructionLLVM::DoesBranch() const
Chris Lattner24943d22010-06-08 16:52:24 +0000346{
347 return EDInstIsBranch(m_inst);
348}
349
350size_t
Caroline Ticeaf591802011-04-05 23:22:54 +0000351InstructionLLVM::Decode (const Disassembler &disassembler,
352 const lldb_private::DataExtractor &data,
353 uint32_t data_offset)
Chris Lattner24943d22010-06-08 16:52:24 +0000354{
355 if (EDCreateInsts(&m_inst, 1, m_disassembler, DataExtractorByteReader, data_offset, (void*)(&data)))
Greg Clayton7bc39082011-03-24 23:53:38 +0000356 {
357 const int byte_size = EDInstByteSize(m_inst);
358 uint32_t offset = data_offset;
359 // Make a copy of the opcode in m_opcode
360 switch (disassembler.GetArchitecture().GetMachine())
361 {
362 case llvm::Triple::x86:
363 case llvm::Triple::x86_64:
364 m_opcode.SetOpcodeBytes (data.PeekData (data_offset, byte_size), byte_size);
365 break;
366
367 case llvm::Triple::arm:
Greg Clayton7bc39082011-03-24 23:53:38 +0000368 case llvm::Triple::thumb:
Greg Clayton149731c2011-03-25 18:03:16 +0000369 switch (byte_size)
370 {
371 case 2:
372 m_opcode.SetOpcode16 (data.GetU16 (&offset));
373 break;
374
375 case 4:
Caroline Tice6b8d3b52011-04-19 23:30:03 +0000376 {
377 if (GetAddressClass() == eAddressClassCodeAlternateISA)
378 {
379 // If it is a 32-bit THUMB instruction, we need to swap the upper & lower halves.
380 uint32_t orig_bytes = data.GetU32 (&offset);
381 uint16_t upper_bits = (orig_bytes >> 16) & ((1u << 16) - 1);
382 uint16_t lower_bits = orig_bytes & ((1u << 16) - 1);
383 uint32_t swapped = (lower_bits << 16) | upper_bits;
384 m_opcode.SetOpcode32 (swapped);
385 }
386 else
387 m_opcode.SetOpcode32 (data.GetU32 (&offset));
388 }
Greg Clayton149731c2011-03-25 18:03:16 +0000389 break;
390
391 default:
392 assert (!"Invalid ARM opcode size");
393 break;
394 }
Greg Clayton7bc39082011-03-24 23:53:38 +0000395 break;
396
397 default:
398 assert (!"This shouldn't happen since we control the architecture we allow DisassemblerLLVM to be created for");
399 break;
400 }
401 return byte_size;
402 }
Chris Lattner24943d22010-06-08 16:52:24 +0000403 else
404 return 0;
405}
406
Chris Lattner24943d22010-06-08 16:52:24 +0000407static inline EDAssemblySyntax_t
Greg Claytoncf015052010-06-11 03:25:34 +0000408SyntaxForArchSpec (const ArchSpec &arch)
Chris Lattner24943d22010-06-08 16:52:24 +0000409{
Greg Clayton940b1032011-02-23 00:35:02 +0000410 switch (arch.GetMachine ())
Greg Clayton5e4f4a22011-02-16 00:00:43 +0000411 {
Greg Clayton940b1032011-02-23 00:35:02 +0000412 case llvm::Triple::x86:
413 case llvm::Triple::x86_64:
Chris Lattner24943d22010-06-08 16:52:24 +0000414 return kEDAssemblySyntaxX86ATT;
Sean Callanand151c8a2011-03-09 01:02:51 +0000415 case llvm::Triple::arm:
Greg Clayton889fbd02011-03-26 19:14:58 +0000416 case llvm::Triple::thumb:
Sean Callanand151c8a2011-03-09 01:02:51 +0000417 return kEDAssemblySyntaxARMUAL;
Greg Clayton5e4f4a22011-02-16 00:00:43 +0000418 default:
419 break;
420 }
Greg Claytoncf015052010-06-11 03:25:34 +0000421 return (EDAssemblySyntax_t)0; // default
Chris Lattner24943d22010-06-08 16:52:24 +0000422}
423
424Disassembler *
425DisassemblerLLVM::CreateInstance(const ArchSpec &arch)
426{
Greg Clayton5e4f4a22011-02-16 00:00:43 +0000427 std::auto_ptr<DisassemblerLLVM> disasm_ap (new DisassemblerLLVM(arch));
428
Caroline Tice080bf612011-04-05 18:46:00 +0000429 if (disasm_ap.get() && disasm_ap->IsValid())
Greg Clayton5e4f4a22011-02-16 00:00:43 +0000430 return disasm_ap.release();
Chris Lattner24943d22010-06-08 16:52:24 +0000431
Greg Claytoncf015052010-06-11 03:25:34 +0000432 return NULL;
Chris Lattner24943d22010-06-08 16:52:24 +0000433}
434
435DisassemblerLLVM::DisassemblerLLVM(const ArchSpec &arch) :
Greg Claytonb01000f2011-01-17 03:46:26 +0000436 Disassembler (arch),
Greg Claytonb1888f22011-03-19 01:12:21 +0000437 m_disassembler (NULL),
438 m_disassembler_thumb (NULL) // For ARM only
Chris Lattner24943d22010-06-08 16:52:24 +0000439{
Greg Clayton5e4f4a22011-02-16 00:00:43 +0000440 const std::string &arch_triple = arch.GetTriple().str();
441 if (!arch_triple.empty())
Greg Claytoncf015052010-06-11 03:25:34 +0000442 {
Greg Clayton5e4f4a22011-02-16 00:00:43 +0000443 if (EDGetDisassembler(&m_disassembler, arch_triple.c_str(), SyntaxForArchSpec (arch)))
444 m_disassembler = NULL;
Greg Claytonb1888f22011-03-19 01:12:21 +0000445 llvm::Triple::ArchType llvm_arch = arch.GetTriple().getArch();
Greg Clayton889fbd02011-03-26 19:14:58 +0000446 // Don't have the lldb::Triple::thumb architecture here. If someone specifies
447 // "thumb" as the architecture, we want a thumb only disassembler. But if any
448 // architecture starting with "arm" if specified, we want to auto detect the
449 // arm/thumb code automatically using the AddressClass from section offset
450 // addresses.
Greg Claytonb1888f22011-03-19 01:12:21 +0000451 if (llvm_arch == llvm::Triple::arm)
452 {
453 if (EDGetDisassembler(&m_disassembler_thumb, "thumb-apple-darwin", kEDAssemblySyntaxARMUAL))
454 m_disassembler_thumb = NULL;
455 }
Greg Claytoncf015052010-06-11 03:25:34 +0000456 }
Chris Lattner24943d22010-06-08 16:52:24 +0000457}
458
459DisassemblerLLVM::~DisassemblerLLVM()
460{
461}
462
463size_t
Greg Clayton70436352010-06-30 23:03:03 +0000464DisassemblerLLVM::DecodeInstructions
Chris Lattner24943d22010-06-08 16:52:24 +0000465(
Greg Clayton5c4c7462010-10-06 03:09:58 +0000466 const Address &base_addr,
Chris Lattner24943d22010-06-08 16:52:24 +0000467 const DataExtractor& data,
468 uint32_t data_offset,
Jim Inghamaa3e3e12011-03-22 01:48:42 +0000469 uint32_t num_instructions,
470 bool append
Chris Lattner24943d22010-06-08 16:52:24 +0000471)
472{
Greg Claytonb01000f2011-01-17 03:46:26 +0000473 if (m_disassembler == NULL)
474 return 0;
475
Chris Lattner24943d22010-06-08 16:52:24 +0000476 size_t total_inst_byte_size = 0;
477
Jim Inghamaa3e3e12011-03-22 01:48:42 +0000478 if (!append)
479 m_instruction_list.Clear();
Chris Lattner24943d22010-06-08 16:52:24 +0000480
481 while (data.ValidOffset(data_offset) && num_instructions)
482 {
Greg Clayton5c4c7462010-10-06 03:09:58 +0000483 Address inst_addr (base_addr);
484 inst_addr.Slide(data_offset);
Greg Claytonb1888f22011-03-19 01:12:21 +0000485
486 bool use_thumb = false;
487 // If we have a thumb disassembler, then we have an ARM architecture
488 // so we need to check what the instruction address class is to make
489 // sure we shouldn't be disassembling as thumb...
Greg Clayton889fbd02011-03-26 19:14:58 +0000490 AddressClass inst_address_class = eAddressClassInvalid;
Greg Claytonb1888f22011-03-19 01:12:21 +0000491 if (m_disassembler_thumb)
492 {
Greg Clayton889fbd02011-03-26 19:14:58 +0000493 inst_address_class = inst_addr.GetAddressClass ();
494 if (inst_address_class == eAddressClassCodeAlternateISA)
Greg Claytonb1888f22011-03-19 01:12:21 +0000495 use_thumb = true;
496 }
Johnny Chen80ab18e2011-05-12 22:25:53 +0000497
Greg Clayton7bc39082011-03-24 23:53:38 +0000498 InstructionSP inst_sp (new InstructionLLVM (inst_addr,
Greg Clayton889fbd02011-03-26 19:14:58 +0000499 inst_address_class,
Greg Claytonabe0fed2011-04-18 08:33:37 +0000500 use_thumb ? m_disassembler_thumb : m_disassembler,
Johnny Chen1608c872011-05-18 18:22:16 +0000501 use_thumb ? llvm::Triple::thumb : m_arch.GetMachine()));
Chris Lattner24943d22010-06-08 16:52:24 +0000502
Greg Clayton889fbd02011-03-26 19:14:58 +0000503 size_t inst_byte_size = inst_sp->Decode (*this, data, data_offset);
Chris Lattner24943d22010-06-08 16:52:24 +0000504
505 if (inst_byte_size == 0)
506 break;
507
Greg Clayton5c4c7462010-10-06 03:09:58 +0000508 m_instruction_list.Append (inst_sp);
Chris Lattner24943d22010-06-08 16:52:24 +0000509
510 total_inst_byte_size += inst_byte_size;
511 data_offset += inst_byte_size;
512 num_instructions--;
513 }
514
515 return total_inst_byte_size;
516}
517
518void
519DisassemblerLLVM::Initialize()
520{
521 PluginManager::RegisterPlugin (GetPluginNameStatic(),
522 GetPluginDescriptionStatic(),
523 CreateInstance);
524}
525
526void
527DisassemblerLLVM::Terminate()
528{
529 PluginManager::UnregisterPlugin (CreateInstance);
530}
531
532
533const char *
534DisassemblerLLVM::GetPluginNameStatic()
535{
Greg Clayton149731c2011-03-25 18:03:16 +0000536 return "llvm";
Chris Lattner24943d22010-06-08 16:52:24 +0000537}
538
539const char *
540DisassemblerLLVM::GetPluginDescriptionStatic()
541{
Greg Clayton149731c2011-03-25 18:03:16 +0000542 return "Disassembler that uses LLVM opcode tables to disassemble i386, x86_64 and ARM.";
Chris Lattner24943d22010-06-08 16:52:24 +0000543}
544
545//------------------------------------------------------------------
546// PluginInterface protocol
547//------------------------------------------------------------------
548const char *
549DisassemblerLLVM::GetPluginName()
550{
551 return "DisassemblerLLVM";
552}
553
554const char *
555DisassemblerLLVM::GetShortPluginName()
556{
557 return GetPluginNameStatic();
558}
559
560uint32_t
561DisassemblerLLVM::GetPluginVersion()
562{
563 return 1;
564}
565