blob: 7522a1ced160ab1d6bc41bf7befa1eede4ec7565 [file] [log] [blame]
Sean Callanan95e5c632012-02-17 00:53:45 +00001//===-- 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/Support/TargetSelect.h"
14
15#include "lldb/Core/Address.h"
16#include "lldb/Core/DataExtractor.h"
Greg Clayton1f746072012-08-29 21:13:06 +000017#include "lldb/Core/Module.h"
Sean Callanan95e5c632012-02-17 00:53:45 +000018#include "lldb/Core/Stream.h"
19#include "lldb/Symbol/SymbolContext.h"
20#include "lldb/Target/ExecutionContext.h"
21#include "lldb/Target/Process.h"
22#include "lldb/Target/RegisterContext.h"
23#include "lldb/Target/Target.h"
24#include "lldb/Target/StackFrame.h"
25
26#include <regex.h>
27
28using namespace lldb;
29using namespace lldb_private;
30
31class InstructionLLVMC : public lldb_private::Instruction
32{
33public:
34 InstructionLLVMC (DisassemblerLLVMC &disasm,
35 const lldb_private::Address &address,
Greg Claytonc8e0c242012-04-13 00:07:34 +000036 AddressClass addr_class) :
Sean Callanan95e5c632012-02-17 00:53:45 +000037 Instruction(address, addr_class),
Sean Callanan95e5c632012-02-17 00:53:45 +000038 m_is_valid(false),
Bill Wendlinge6eeef02012-04-06 00:09:59 +000039 m_disasm(disasm),
Sean Callanan7e6d4e52012-08-01 18:50:59 +000040 m_disasm_sp(disasm.shared_from_this()),
Sean Callanan7725a462012-03-02 23:22:53 +000041 m_does_branch(eLazyBoolCalculate)
Sean Callanan95e5c632012-02-17 00:53:45 +000042 {
43 }
44
45 virtual
46 ~InstructionLLVMC ()
47 {
48 }
49
50 static void
51 PadToWidth (lldb_private::StreamString &ss,
52 int new_width)
53 {
54 int old_width = ss.GetSize();
55
56 if (old_width < new_width)
57 {
58 ss.Printf("%*s", new_width - old_width, "");
59 }
60 }
Sean Callanan95e5c632012-02-17 00:53:45 +000061
Sean Callanan95e5c632012-02-17 00:53:45 +000062 virtual bool
63 DoesBranch () const
64 {
Sean Callanan7725a462012-03-02 23:22:53 +000065 return m_does_branch == eLazyBoolYes;
Sean Callanan95e5c632012-02-17 00:53:45 +000066 }
67
68 virtual size_t
69 Decode (const lldb_private::Disassembler &disassembler,
70 const lldb_private::DataExtractor &data,
71 uint32_t data_offset)
72 {
Greg Claytonba812f42012-05-10 02:52:23 +000073 // All we have to do is read the opcode which can be easy for some
74 // architetures
75 bool got_op = false;
76 const ArchSpec &arch = m_disasm.GetArchitecture();
Sean Callanan95e5c632012-02-17 00:53:45 +000077
Greg Claytonba812f42012-05-10 02:52:23 +000078 const uint32_t min_op_byte_size = arch.GetMinimumOpcodeByteSize();
79 const uint32_t max_op_byte_size = arch.GetMaximumOpcodeByteSize();
80 if (min_op_byte_size == max_op_byte_size)
81 {
82 // Fixed size instructions, just read that amount of data.
83 if (!data.ValidOffsetForDataOfSize(data_offset, min_op_byte_size))
84 return false;
85
86 switch (min_op_byte_size)
87 {
88 case 1:
89 m_opcode.SetOpcode8 (data.GetU8 (&data_offset));
90 got_op = true;
91 break;
92
93 case 2:
94 m_opcode.SetOpcode16 (data.GetU16 (&data_offset));
95 got_op = true;
96 break;
97
98 case 4:
99 m_opcode.SetOpcode32 (data.GetU32 (&data_offset));
100 got_op = true;
101 break;
102
103 case 8:
104 m_opcode.SetOpcode64 (data.GetU64 (&data_offset));
105 got_op = true;
106 break;
107
108 default:
109 m_opcode.SetOpcodeBytes(data.PeekData(data_offset, min_op_byte_size), min_op_byte_size);
110 got_op = true;
111 break;
112 }
113 }
114 if (!got_op)
115 {
116 ::LLVMDisasmContextRef disasm_context = m_disasm.m_disasm_context;
117
118 bool is_altnernate_isa = false;
119 if (m_disasm.m_alternate_disasm_context)
120 {
121 const AddressClass address_class = GetAddressClass ();
122
123 if (address_class == eAddressClassCodeAlternateISA)
124 {
125 disasm_context = m_disasm.m_alternate_disasm_context;
126 is_altnernate_isa = true;
127 }
128 }
129 const llvm::Triple::ArchType machine = arch.GetMachine();
130 if (machine == llvm::Triple::arm || machine == llvm::Triple::thumb)
131 {
132 if (machine == llvm::Triple::thumb || is_altnernate_isa)
133 {
Greg Clayton79101b52012-08-07 01:29:29 +0000134 uint32_t thumb_opcode = data.GetU16(&data_offset);
Greg Claytonba812f42012-05-10 02:52:23 +0000135 if ((thumb_opcode & 0xe000) != 0xe000 || ((thumb_opcode & 0x1800u) == 0))
136 {
137 m_opcode.SetOpcode16 (thumb_opcode);
Sean Callanan5c97c2f2012-08-06 23:42:52 +0000138 m_is_valid = true;
Greg Claytonba812f42012-05-10 02:52:23 +0000139 }
140 else
141 {
Greg Clayton79101b52012-08-07 01:29:29 +0000142 thumb_opcode <<= 16;
143 thumb_opcode |= data.GetU16(&data_offset);
144 m_opcode.SetOpcode16_2 (thumb_opcode);
Greg Claytonba812f42012-05-10 02:52:23 +0000145 m_is_valid = true;
146 }
147 }
148 else
149 {
150 m_opcode.SetOpcode32 (data.GetU32(&data_offset));
Sean Callanan5c97c2f2012-08-06 23:42:52 +0000151 m_is_valid = true;
Greg Claytonba812f42012-05-10 02:52:23 +0000152 }
153 }
154 else
155 {
156 // The opcode isn't evenly sized, so we need to actually use the llvm
157 // disassembler to parse it and get the size.
158 char out_string[512];
159 m_disasm.Lock(this, NULL);
160 uint8_t *opcode_data = const_cast<uint8_t *>(data.PeekData (data_offset, 1));
161 const size_t opcode_data_len = data.GetByteSize() - data_offset;
162 const addr_t pc = m_address.GetFileAddress();
163 const size_t inst_size = ::LLVMDisasmInstruction (disasm_context,
164 opcode_data,
165 opcode_data_len,
166 pc, // PC value
167 out_string,
168 sizeof(out_string));
169 // The address lookup function could have caused us to fill in our comment
170 m_comment.clear();
171 m_disasm.Unlock();
172 if (inst_size == 0)
173 m_opcode.Clear();
174 else
175 {
176 m_opcode.SetOpcodeBytes(opcode_data, inst_size);
177 m_is_valid = true;
178 }
179 }
180 }
Sean Callanan95e5c632012-02-17 00:53:45 +0000181 return m_opcode.GetByteSize();
182 }
183
184 void
Greg Claytonba812f42012-05-10 02:52:23 +0000185 AppendComment (std::string &description)
Sean Callanan95e5c632012-02-17 00:53:45 +0000186 {
Greg Claytonba812f42012-05-10 02:52:23 +0000187 if (m_comment.empty())
188 m_comment.swap (description);
Sean Callanan95e5c632012-02-17 00:53:45 +0000189 else
Greg Claytonba812f42012-05-10 02:52:23 +0000190 {
191 m_comment.append(", ");
192 m_comment.append(description);
193 }
Sean Callanan95e5c632012-02-17 00:53:45 +0000194 }
195
196 virtual void
Greg Claytonba812f42012-05-10 02:52:23 +0000197 CalculateMnemonicOperandsAndComment (const lldb_private::ExecutionContext *exe_ctx)
Sean Callanan95e5c632012-02-17 00:53:45 +0000198 {
Greg Claytonba812f42012-05-10 02:52:23 +0000199 DataExtractor data;
200 const AddressClass address_class = GetAddressClass ();
201
Sean Callanancd4ae1a2012-08-07 01:44:58 +0000202 if (m_opcode.GetData(data))
Greg Claytonba812f42012-05-10 02:52:23 +0000203 {
204 char out_string[512];
205
206 ::LLVMDisasmContextRef disasm_context;
207
208 if (address_class == eAddressClassCodeAlternateISA)
209 disasm_context = m_disasm.m_alternate_disasm_context;
210 else
211 disasm_context = m_disasm.m_disasm_context;
212
213 lldb::addr_t pc = LLDB_INVALID_ADDRESS;
214
215 if (exe_ctx)
216 {
217 Target *target = exe_ctx->GetTargetPtr();
218 if (target)
219 pc = m_address.GetLoadAddress(target);
220 }
221
222 if (pc == LLDB_INVALID_ADDRESS)
223 pc = m_address.GetFileAddress();
224
225 m_disasm.Lock(this, exe_ctx);
226 uint8_t *opcode_data = const_cast<uint8_t *>(data.PeekData (0, 1));
227 const size_t opcode_data_len = data.GetByteSize();
228 size_t inst_size = ::LLVMDisasmInstruction (disasm_context,
229 opcode_data,
230 opcode_data_len,
231 pc,
232 out_string,
233 sizeof(out_string));
234
235 m_disasm.Unlock();
236
237 if (inst_size == 0)
238 {
239 m_comment.assign ("unknown opcode");
240 inst_size = m_opcode.GetByteSize();
241 StreamString mnemonic_strm;
242 uint32_t offset = 0;
243 switch (inst_size)
244 {
245 case 1:
246 {
247 const uint8_t uval8 = data.GetU8 (&offset);
248 m_opcode.SetOpcode8 (uval8);
249 m_opcode_name.assign (".byte");
250 mnemonic_strm.Printf("0x%2.2x", uval8);
251 }
252 break;
253 case 2:
254 {
255 const uint16_t uval16 = data.GetU16(&offset);
256 m_opcode.SetOpcode16(uval16);
257 m_opcode_name.assign (".short");
258 mnemonic_strm.Printf("0x%4.4x", uval16);
259 }
260 break;
261 case 4:
262 {
263 const uint32_t uval32 = data.GetU32(&offset);
264 m_opcode.SetOpcode32(uval32);
265 m_opcode_name.assign (".long");
266 mnemonic_strm.Printf("0x%8.8x", uval32);
267 }
268 break;
269 case 8:
270 {
271 const uint64_t uval64 = data.GetU64(&offset);
272 m_opcode.SetOpcode64(uval64);
273 m_opcode_name.assign (".quad");
Daniel Malead01b2952012-11-29 21:49:15 +0000274 mnemonic_strm.Printf("0x%16.16" PRIx64, uval64);
Greg Claytonba812f42012-05-10 02:52:23 +0000275 }
276 break;
277 default:
278 if (inst_size == 0)
279 return;
280 else
281 {
282 const uint8_t *bytes = data.PeekData(offset, inst_size);
283 if (bytes == NULL)
284 return;
285 m_opcode_name.assign (".byte");
286 m_opcode.SetOpcodeBytes(bytes, inst_size);
287 mnemonic_strm.Printf("0x%2.2x", bytes[0]);
288 for (uint32_t i=1; i<inst_size; ++i)
289 mnemonic_strm.Printf(" 0x%2.2x", bytes[i]);
290 }
291 break;
292 }
293 m_mnemocics.swap(mnemonic_strm.GetString());
294 return;
295 }
296 else
297 {
298 if (m_does_branch == eLazyBoolCalculate)
299 {
300 if (StringRepresentsBranch (out_string, strlen(out_string)))
301 m_does_branch = eLazyBoolYes;
302 else
303 m_does_branch = eLazyBoolNo;
304 }
305 }
306
307 if (!s_regex_compiled)
308 {
309 ::regcomp(&s_regex, "[ \t]*([^ ^\t]+)[ \t]*([^ ^\t].*)?", REG_EXTENDED);
310 s_regex_compiled = true;
311 }
312
313 ::regmatch_t matches[3];
314
315 if (!::regexec(&s_regex, out_string, sizeof(matches) / sizeof(::regmatch_t), matches, 0))
316 {
317 if (matches[1].rm_so != -1)
318 m_opcode_name.assign(out_string + matches[1].rm_so, matches[1].rm_eo - matches[1].rm_so);
319 if (matches[2].rm_so != -1)
320 m_mnemocics.assign(out_string + matches[2].rm_so, matches[2].rm_eo - matches[2].rm_so);
321 }
322 }
Sean Callanan95e5c632012-02-17 00:53:45 +0000323 }
324
325 bool
326 IsValid ()
327 {
328 return m_is_valid;
329 }
330
331 size_t
332 GetByteSize ()
333 {
334 return m_opcode.GetByteSize();
335 }
336protected:
Sean Callanan95e5c632012-02-17 00:53:45 +0000337
Sean Callanan7725a462012-03-02 23:22:53 +0000338 bool StringRepresentsBranch (const char *data, size_t size)
339 {
340 const char *cursor = data;
341
342 bool inWhitespace = true;
343
344 while (inWhitespace && cursor < data + size)
345 {
346 switch (*cursor)
347 {
348 default:
349 inWhitespace = false;
350 break;
351 case ' ':
352 break;
353 case '\t':
354 break;
355 }
356
357 if (inWhitespace)
358 ++cursor;
359 }
360
361 if (cursor >= data + size)
362 return false;
363
364 llvm::Triple::ArchType arch = m_disasm.GetArchitecture().GetMachine();
365
366 switch (arch)
367 {
368 default:
369 return false;
370 case llvm::Triple::x86:
371 case llvm::Triple::x86_64:
372 switch (cursor[0])
373 {
374 default:
375 return false;
376 case 'j':
377 return true;
378 case 'c':
379 if (cursor[1] == 'a' &&
380 cursor[2] == 'l' &&
381 cursor[3] == 'l')
382 return true;
383 else
384 return false;
385 }
386 case llvm::Triple::arm:
387 case llvm::Triple::thumb:
388 switch (cursor[0])
389 {
390 default:
391 return false;
392 case 'b':
393 {
394 switch (cursor[1])
395 {
396 default:
Sean Callanan7725a462012-03-02 23:22:53 +0000397 return true;
Sean Callanan62ecb9b2012-04-10 21:51:12 +0000398 case 'f':
399 case 'i':
400 case 'k':
401 return false;
Sean Callanan7725a462012-03-02 23:22:53 +0000402 }
Sean Callanan7725a462012-03-02 23:22:53 +0000403 }
404 case 'c':
405 {
406 switch (cursor[1])
407 {
408 default:
409 return false;
410 case 'b':
411 return true;
412 }
413 }
414 }
415 }
416
417 return false;
418 }
419
Sean Callanan95e5c632012-02-17 00:53:45 +0000420 bool m_is_valid;
421 DisassemblerLLVMC &m_disasm;
Sean Callanan7e6d4e52012-08-01 18:50:59 +0000422 DisassemblerSP m_disasm_sp; // for ownership
Sean Callanan7725a462012-03-02 23:22:53 +0000423 LazyBool m_does_branch;
Sean Callanan95e5c632012-02-17 00:53:45 +0000424
425 static bool s_regex_compiled;
426 static ::regex_t s_regex;
427};
428
429bool InstructionLLVMC::s_regex_compiled = false;
430::regex_t InstructionLLVMC::s_regex;
431
432Disassembler *
433DisassemblerLLVMC::CreateInstance (const ArchSpec &arch)
434{
Greg Clayton9e6cffc2012-09-19 22:25:17 +0000435 if (arch.GetTriple().getArch() != llvm::Triple::UnknownArch)
436 {
437 std::auto_ptr<DisassemblerLLVMC> disasm_ap (new DisassemblerLLVMC(arch));
Sean Callanan95e5c632012-02-17 00:53:45 +0000438
Greg Clayton9e6cffc2012-09-19 22:25:17 +0000439 if (disasm_ap.get() && disasm_ap->IsValid())
440 return disasm_ap.release();
441 }
Sean Callanan95e5c632012-02-17 00:53:45 +0000442 return NULL;
443}
444
445DisassemblerLLVMC::DisassemblerLLVMC (const ArchSpec &arch) :
446 Disassembler(arch),
Greg Claytonba812f42012-05-10 02:52:23 +0000447 m_exe_ctx (NULL),
448 m_inst (NULL),
449 m_disasm_context (NULL),
450 m_alternate_disasm_context (NULL)
Sean Callanan95e5c632012-02-17 00:53:45 +0000451{
452 m_disasm_context = ::LLVMCreateDisasm(arch.GetTriple().getTriple().c_str(),
453 (void*)this,
454 /*TagType=*/1,
Sean Callanan6f298a62012-02-23 23:43:28 +0000455 NULL,
Sean Callanan95e5c632012-02-17 00:53:45 +0000456 DisassemblerLLVMC::SymbolLookupCallback);
457
458 if (arch.GetTriple().getArch() == llvm::Triple::arm)
459 {
Greg Claytonba812f42012-05-10 02:52:23 +0000460 ArchSpec thumb_arch(arch);
461 thumb_arch.GetTriple().setArchName(llvm::StringRef("thumbv7"));
462 std::string thumb_triple(thumb_arch.GetTriple().getTriple());
463
464 m_alternate_disasm_context = ::LLVMCreateDisasm(thumb_triple.c_str(),
Sean Callanan95e5c632012-02-17 00:53:45 +0000465 (void*)this,
466 /*TagType=*/1,
Sean Callanan6f298a62012-02-23 23:43:28 +0000467 NULL,
Sean Callanan95e5c632012-02-17 00:53:45 +0000468 DisassemblerLLVMC::SymbolLookupCallback);
469 }
470}
471
472DisassemblerLLVMC::~DisassemblerLLVMC()
473{
Sean Callanan2b54db72012-04-06 17:59:49 +0000474 if (m_disasm_context)
475 {
476 ::LLVMDisasmDispose(m_disasm_context);
477 m_disasm_context = NULL;
478 }
479 if (m_alternate_disasm_context)
480 {
481 ::LLVMDisasmDispose(m_alternate_disasm_context);
482 m_alternate_disasm_context = NULL;
483 }
Sean Callanan95e5c632012-02-17 00:53:45 +0000484}
485
486size_t
487DisassemblerLLVMC::DecodeInstructions (const Address &base_addr,
488 const DataExtractor& data,
489 uint32_t data_offset,
490 uint32_t num_instructions,
491 bool append)
492{
493 if (!append)
494 m_instruction_list.Clear();
495
496 if (!IsValid())
497 return 0;
498
499 uint32_t data_cursor = data_offset;
Greg Claytonba812f42012-05-10 02:52:23 +0000500 const size_t data_byte_size = data.GetByteSize();
Sean Callanan95e5c632012-02-17 00:53:45 +0000501 uint32_t instructions_parsed = 0;
Greg Claytonba812f42012-05-10 02:52:23 +0000502 Address inst_addr(base_addr);
Sean Callanan95e5c632012-02-17 00:53:45 +0000503
Greg Claytonba812f42012-05-10 02:52:23 +0000504 while (data_cursor < data_byte_size && instructions_parsed < num_instructions)
Sean Callanan95e5c632012-02-17 00:53:45 +0000505 {
Sean Callanan95e5c632012-02-17 00:53:45 +0000506
Greg Claytonba812f42012-05-10 02:52:23 +0000507 AddressClass address_class = eAddressClassCode;
Sean Callanan95e5c632012-02-17 00:53:45 +0000508
509 if (m_alternate_disasm_context)
Greg Claytonba812f42012-05-10 02:52:23 +0000510 address_class = inst_addr.GetAddressClass ();
Sean Callanan95e5c632012-02-17 00:53:45 +0000511
512 InstructionSP inst_sp(new InstructionLLVMC(*this,
Greg Claytonba812f42012-05-10 02:52:23 +0000513 inst_addr,
Sean Callanan95e5c632012-02-17 00:53:45 +0000514 address_class));
515
516 if (!inst_sp)
Greg Claytonba812f42012-05-10 02:52:23 +0000517 break;
518
Sean Callanan95e5c632012-02-17 00:53:45 +0000519 uint32_t inst_size = inst_sp->Decode(*this, data, data_cursor);
520
Greg Claytonba812f42012-05-10 02:52:23 +0000521 if (inst_size == 0)
522 break;
523
Sean Callanan95e5c632012-02-17 00:53:45 +0000524 m_instruction_list.Append(inst_sp);
Sean Callanan95e5c632012-02-17 00:53:45 +0000525 data_cursor += inst_size;
Greg Claytonba812f42012-05-10 02:52:23 +0000526 inst_addr.Slide(inst_size);
Sean Callanan95e5c632012-02-17 00:53:45 +0000527 instructions_parsed++;
528 }
529
530 return data_cursor - data_offset;
531}
532
533void
534DisassemblerLLVMC::Initialize()
535{
536 PluginManager::RegisterPlugin (GetPluginNameStatic(),
537 GetPluginDescriptionStatic(),
538 CreateInstance);
539
540 llvm::InitializeAllTargetInfos();
541 llvm::InitializeAllTargetMCs();
542 llvm::InitializeAllAsmParsers();
543 llvm::InitializeAllDisassemblers();
544}
545
546void
547DisassemblerLLVMC::Terminate()
548{
549 PluginManager::UnregisterPlugin (CreateInstance);
550}
551
552
553const char *
554DisassemblerLLVMC::GetPluginNameStatic()
555{
Greg Claytonf8712de2012-03-22 00:49:15 +0000556 return "llvm-mc";
Sean Callanan95e5c632012-02-17 00:53:45 +0000557}
558
559const char *
560DisassemblerLLVMC::GetPluginDescriptionStatic()
561{
Greg Claytonf8712de2012-03-22 00:49:15 +0000562 return "Disassembler that uses LLVM MC to disassemble i386, x86_64 and ARM.";
Sean Callanan95e5c632012-02-17 00:53:45 +0000563}
564
Greg Claytonba812f42012-05-10 02:52:23 +0000565int DisassemblerLLVMC::OpInfoCallback (void *disassembler,
566 uint64_t pc,
567 uint64_t offset,
568 uint64_t size,
569 int tag_type,
570 void *tag_bug)
Sean Callanan95e5c632012-02-17 00:53:45 +0000571{
Greg Claytonba812f42012-05-10 02:52:23 +0000572 return static_cast<DisassemblerLLVMC*>(disassembler)->OpInfo (pc,
573 offset,
574 size,
575 tag_type,
576 tag_bug);
Sean Callanan95e5c632012-02-17 00:53:45 +0000577}
578
Greg Claytonba812f42012-05-10 02:52:23 +0000579const char *DisassemblerLLVMC::SymbolLookupCallback (void *disassembler,
580 uint64_t value,
581 uint64_t *type,
582 uint64_t pc,
583 const char **name)
Sean Callanan95e5c632012-02-17 00:53:45 +0000584{
Greg Claytonba812f42012-05-10 02:52:23 +0000585 return static_cast<DisassemblerLLVMC*>(disassembler)->SymbolLookup(value,
586 type,
587 pc,
588 name);
Sean Callanan95e5c632012-02-17 00:53:45 +0000589}
590
591int DisassemblerLLVMC::OpInfo (uint64_t PC,
592 uint64_t Offset,
593 uint64_t Size,
Greg Claytonba812f42012-05-10 02:52:23 +0000594 int tag_type,
595 void *tag_bug)
Sean Callanan95e5c632012-02-17 00:53:45 +0000596{
Greg Claytonba812f42012-05-10 02:52:23 +0000597 switch (tag_type)
Sean Callanan95e5c632012-02-17 00:53:45 +0000598 {
599 default:
600 break;
601 case 1:
Greg Claytonba812f42012-05-10 02:52:23 +0000602 bzero (tag_bug, sizeof(::LLVMOpInfo1));
Sean Callanan95e5c632012-02-17 00:53:45 +0000603 break;
604 }
605 return 0;
606}
607
Greg Claytonba812f42012-05-10 02:52:23 +0000608const char *DisassemblerLLVMC::SymbolLookup (uint64_t value,
609 uint64_t *type_ptr,
610 uint64_t pc,
611 const char **name)
Sean Callanan95e5c632012-02-17 00:53:45 +0000612{
Greg Claytonba812f42012-05-10 02:52:23 +0000613 if (*type_ptr)
614 {
615 if (m_exe_ctx && m_inst)
616 {
617 //std::string remove_this_prior_to_checkin;
618 Address reference_address;
Sean Callanan95e5c632012-02-17 00:53:45 +0000619
Greg Claytonba812f42012-05-10 02:52:23 +0000620 Target *target = m_exe_ctx ? m_exe_ctx->GetTargetPtr() : NULL;
621
622 if (target && !target->GetSectionLoadList().IsEmpty())
623 target->GetSectionLoadList().ResolveLoadAddress(value, reference_address);
624 else
625 {
626 ModuleSP module_sp(m_inst->GetAddress().GetModule());
627 if (module_sp)
628 module_sp->ResolveFileAddress(value, reference_address);
629 }
630
Sean Callanan6f298a62012-02-23 23:43:28 +0000631 if (reference_address.IsValid() && reference_address.GetSection())
Sean Callanan95e5c632012-02-17 00:53:45 +0000632 {
Sean Callanan95e5c632012-02-17 00:53:45 +0000633 StreamString ss;
634
Sean Callanan6f298a62012-02-23 23:43:28 +0000635 reference_address.Dump (&ss,
636 target,
637 Address::DumpStyleResolvedDescriptionNoModule,
638 Address::DumpStyleSectionNameOffset);
Sean Callanan95e5c632012-02-17 00:53:45 +0000639
Sean Callanan745af462012-03-22 20:04:23 +0000640 if (!ss.GetString().empty())
Greg Claytonba812f42012-05-10 02:52:23 +0000641 {
642 //remove_this_prior_to_checkin = ss.GetString();
643 //if (*type_ptr)
644 m_inst->AppendComment(ss.GetString());
645 }
Sean Callanan95e5c632012-02-17 00:53:45 +0000646 }
Daniel Malead01b2952012-11-29 21:49:15 +0000647 //printf ("DisassemblerLLVMC::SymbolLookup (value=0x%16.16" PRIx64 ", type=%" PRIu64 ", pc=0x%16.16" PRIx64 ", name=\"%s\") m_exe_ctx=%p, m_inst=%p\n", value, *type_ptr, pc, remove_this_prior_to_checkin.c_str(), m_exe_ctx, m_inst);
Sean Callanan95e5c632012-02-17 00:53:45 +0000648 }
649 }
Greg Claytonba812f42012-05-10 02:52:23 +0000650
651 *type_ptr = LLVMDisassembler_ReferenceType_InOut_None;
652 *name = NULL;
653 return NULL;
Sean Callanan95e5c632012-02-17 00:53:45 +0000654}
655
656//------------------------------------------------------------------
657// PluginInterface protocol
658//------------------------------------------------------------------
659const char *
660DisassemblerLLVMC::GetPluginName()
661{
662 return "DisassemblerLLVMC";
663}
664
665const char *
666DisassemblerLLVMC::GetShortPluginName()
667{
668 return GetPluginNameStatic();
669}
670
671uint32_t
672DisassemblerLLVMC::GetPluginVersion()
673{
674 return 1;
675}
676