1 //===-- Symbol.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 "lldb/Symbol/Symbol.h" 11 12 #include "lldb/Core/Module.h" 13 #include "lldb/Core/ModuleSpec.h" 14 #include "lldb/Core/Section.h" 15 #include "lldb/Core/Stream.h" 16 #include "lldb/Symbol/ObjectFile.h" 17 #include "lldb/Symbol/Symtab.h" 18 #include "lldb/Symbol/Function.h" 19 #include "lldb/Target/Process.h" 20 #include "lldb/Target/Target.h" 21 #include "lldb/Symbol/SymbolVendor.h" 22 23 using namespace lldb; 24 using namespace lldb_private; 25 26 27 Symbol::Symbol() : 28 SymbolContextScope (), 29 m_uid (UINT32_MAX), 30 m_type_data (0), 31 m_type_data_resolved (false), 32 m_is_synthetic (false), 33 m_is_debug (false), 34 m_is_external (false), 35 m_size_is_sibling (false), 36 m_size_is_synthesized (false), 37 m_size_is_valid (false), 38 m_demangled_is_synthesized (false), 39 m_contains_linker_annotations (false), 40 m_type (eSymbolTypeInvalid), 41 m_mangled (), 42 m_addr_range (), 43 m_flags () 44 { 45 } 46 47 Symbol::Symbol 48 ( 49 uint32_t symID, 50 const char *name, 51 bool name_is_mangled, 52 SymbolType type, 53 bool external, 54 bool is_debug, 55 bool is_trampoline, 56 bool is_artificial, 57 const lldb::SectionSP §ion_sp, 58 addr_t offset, 59 addr_t size, 60 bool size_is_valid, 61 bool contains_linker_annotations, 62 uint32_t flags 63 ) : 64 SymbolContextScope (), 65 m_uid (symID), 66 m_type_data (0), 67 m_type_data_resolved (false), 68 m_is_synthetic (is_artificial), 69 m_is_debug (is_debug), 70 m_is_external (external), 71 m_size_is_sibling (false), 72 m_size_is_synthesized (false), 73 m_size_is_valid (size_is_valid || size > 0), 74 m_demangled_is_synthesized (false), 75 m_contains_linker_annotations (contains_linker_annotations), 76 m_type (type), 77 m_mangled (ConstString(name), name_is_mangled), 78 m_addr_range (section_sp, offset, size), 79 m_flags (flags) 80 { 81 } 82 83 Symbol::Symbol 84 ( 85 uint32_t symID, 86 const Mangled &mangled, 87 SymbolType type, 88 bool external, 89 bool is_debug, 90 bool is_trampoline, 91 bool is_artificial, 92 const AddressRange &range, 93 bool size_is_valid, 94 bool contains_linker_annotations, 95 uint32_t flags 96 ) : 97 SymbolContextScope (), 98 m_uid (symID), 99 m_type_data (0), 100 m_type_data_resolved (false), 101 m_is_synthetic (is_artificial), 102 m_is_debug (is_debug), 103 m_is_external (external), 104 m_size_is_sibling (false), 105 m_size_is_synthesized (false), 106 m_size_is_valid (size_is_valid || range.GetByteSize() > 0), 107 m_demangled_is_synthesized (false), 108 m_contains_linker_annotations (contains_linker_annotations), 109 m_type (type), 110 m_mangled (mangled), 111 m_addr_range (range), 112 m_flags (flags) 113 { 114 } 115 116 Symbol::Symbol(const Symbol& rhs): 117 SymbolContextScope (rhs), 118 m_uid (rhs.m_uid), 119 m_type_data (rhs.m_type_data), 120 m_type_data_resolved (rhs.m_type_data_resolved), 121 m_is_synthetic (rhs.m_is_synthetic), 122 m_is_debug (rhs.m_is_debug), 123 m_is_external (rhs.m_is_external), 124 m_size_is_sibling (rhs.m_size_is_sibling), 125 m_size_is_synthesized (false), 126 m_size_is_valid (rhs.m_size_is_valid), 127 m_demangled_is_synthesized (rhs.m_demangled_is_synthesized), 128 m_contains_linker_annotations (rhs.m_contains_linker_annotations), 129 m_type (rhs.m_type), 130 m_mangled (rhs.m_mangled), 131 m_addr_range (rhs.m_addr_range), 132 m_flags (rhs.m_flags) 133 { 134 } 135 136 const Symbol& 137 Symbol::operator= (const Symbol& rhs) 138 { 139 if (this != &rhs) 140 { 141 SymbolContextScope::operator= (rhs); 142 m_uid = rhs.m_uid; 143 m_type_data = rhs.m_type_data; 144 m_type_data_resolved = rhs.m_type_data_resolved; 145 m_is_synthetic = rhs.m_is_synthetic; 146 m_is_debug = rhs.m_is_debug; 147 m_is_external = rhs.m_is_external; 148 m_size_is_sibling = rhs.m_size_is_sibling; 149 m_size_is_synthesized = rhs.m_size_is_sibling; 150 m_size_is_valid = rhs.m_size_is_valid; 151 m_demangled_is_synthesized = rhs.m_demangled_is_synthesized; 152 m_contains_linker_annotations = rhs.m_contains_linker_annotations; 153 m_type = rhs.m_type; 154 m_mangled = rhs.m_mangled; 155 m_addr_range = rhs.m_addr_range; 156 m_flags = rhs.m_flags; 157 } 158 return *this; 159 } 160 161 void 162 Symbol::Clear() 163 { 164 m_uid = UINT32_MAX; 165 m_mangled.Clear(); 166 m_type_data = 0; 167 m_type_data_resolved = false; 168 m_is_synthetic = false; 169 m_is_debug = false; 170 m_is_external = false; 171 m_size_is_sibling = false; 172 m_size_is_synthesized = false; 173 m_size_is_valid = false; 174 m_demangled_is_synthesized = false; 175 m_contains_linker_annotations = false; 176 m_type = eSymbolTypeInvalid; 177 m_flags = 0; 178 m_addr_range.Clear(); 179 } 180 181 bool 182 Symbol::ValueIsAddress() const 183 { 184 return m_addr_range.GetBaseAddress().GetSection().get() != nullptr; 185 } 186 187 ConstString 188 Symbol::GetDisplayName () const 189 { 190 if (!m_mangled) 191 return ConstString(); 192 return m_mangled.GetDisplayDemangledName(GetLanguage()); 193 } 194 195 ConstString 196 Symbol::GetReExportedSymbolName() const 197 { 198 if (m_type == eSymbolTypeReExported) 199 { 200 // For eSymbolTypeReExported, the "const char *" from a ConstString 201 // is used as the offset in the address range base address. We can 202 // then make this back into a string that is the re-exported name. 203 intptr_t str_ptr = m_addr_range.GetBaseAddress().GetOffset(); 204 if (str_ptr != 0) 205 return ConstString((const char *)str_ptr); 206 else 207 return GetName(); 208 } 209 return ConstString(); 210 } 211 212 FileSpec 213 Symbol::GetReExportedSymbolSharedLibrary() const 214 { 215 if (m_type == eSymbolTypeReExported) 216 { 217 // For eSymbolTypeReExported, the "const char *" from a ConstString 218 // is used as the offset in the address range base address. We can 219 // then make this back into a string that is the re-exported name. 220 intptr_t str_ptr = m_addr_range.GetByteSize(); 221 if (str_ptr != 0) 222 return FileSpec((const char *)str_ptr, false); 223 } 224 return FileSpec(); 225 } 226 227 void 228 Symbol::SetReExportedSymbolName(const ConstString &name) 229 { 230 SetType (eSymbolTypeReExported); 231 // For eSymbolTypeReExported, the "const char *" from a ConstString 232 // is used as the offset in the address range base address. 233 m_addr_range.GetBaseAddress().SetOffset((uintptr_t)name.GetCString()); 234 } 235 236 bool 237 Symbol::SetReExportedSymbolSharedLibrary(const FileSpec &fspec) 238 { 239 if (m_type == eSymbolTypeReExported) 240 { 241 // For eSymbolTypeReExported, the "const char *" from a ConstString 242 // is used as the offset in the address range base address. 243 m_addr_range.SetByteSize((uintptr_t)ConstString(fspec.GetPath().c_str()).GetCString()); 244 return true; 245 } 246 return false; 247 248 } 249 250 uint32_t 251 Symbol::GetSiblingIndex() const 252 { 253 return m_size_is_sibling ? m_addr_range.GetByteSize() : UINT32_MAX; 254 } 255 256 bool 257 Symbol::IsTrampoline () const 258 { 259 return m_type == eSymbolTypeTrampoline; 260 } 261 262 bool 263 Symbol::IsIndirect () const 264 { 265 return m_type == eSymbolTypeResolver; 266 } 267 268 void 269 Symbol::GetDescription (Stream *s, lldb::DescriptionLevel level, Target *target) const 270 { 271 s->Printf("id = {0x%8.8x}", m_uid); 272 273 if (m_addr_range.GetBaseAddress().GetSection()) 274 { 275 if (ValueIsAddress()) 276 { 277 const lldb::addr_t byte_size = GetByteSize(); 278 if (byte_size > 0) 279 { 280 s->PutCString (", range = "); 281 m_addr_range.Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress); 282 } 283 else 284 { 285 s->PutCString (", address = "); 286 m_addr_range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress); 287 } 288 } 289 else 290 s->Printf (", value = 0x%16.16" PRIx64, m_addr_range.GetBaseAddress().GetOffset()); 291 } 292 else 293 { 294 if (m_size_is_sibling) 295 s->Printf (", sibling = %5" PRIu64, m_addr_range.GetBaseAddress().GetOffset()); 296 else 297 s->Printf (", value = 0x%16.16" PRIx64, m_addr_range.GetBaseAddress().GetOffset()); 298 } 299 ConstString demangled = m_mangled.GetDemangledName(GetLanguage()); 300 if (demangled) 301 s->Printf(", name=\"%s\"", demangled.AsCString()); 302 if (m_mangled.GetMangledName()) 303 s->Printf(", mangled=\"%s\"", m_mangled.GetMangledName().AsCString()); 304 305 } 306 307 void 308 Symbol::Dump(Stream *s, Target *target, uint32_t index) const 309 { 310 s->Printf("[%5u] %6u %c%c%c %-15s ", 311 index, 312 GetID(), 313 m_is_debug ? 'D' : ' ', 314 m_is_synthetic ? 'S' : ' ', 315 m_is_external ? 'X' : ' ', 316 GetTypeAsString()); 317 318 // Make sure the size of the symbol is up to date before dumping 319 GetByteSize(); 320 321 ConstString name = m_mangled.GetName(GetLanguage()); 322 if (ValueIsAddress()) 323 { 324 if (!m_addr_range.GetBaseAddress().Dump(s, nullptr, Address::DumpStyleFileAddress)) 325 s->Printf("%*s", 18, ""); 326 327 s->PutChar(' '); 328 329 if (!m_addr_range.GetBaseAddress().Dump(s, target, Address::DumpStyleLoadAddress)) 330 s->Printf("%*s", 18, ""); 331 332 const char *format = m_size_is_sibling ? 333 " Sibling -> [%5llu] 0x%8.8x %s\n": 334 " 0x%16.16" PRIx64 " 0x%8.8x %s\n"; 335 s->Printf( format, 336 GetByteSize(), 337 m_flags, 338 name.AsCString("")); 339 } 340 else if (m_type == eSymbolTypeReExported) 341 { 342 s->Printf (" 0x%8.8x %s", 343 m_flags, 344 name.AsCString("")); 345 346 ConstString reexport_name = GetReExportedSymbolName(); 347 intptr_t shlib = m_addr_range.GetByteSize(); 348 if (shlib) 349 s->Printf(" -> %s`%s\n", (const char *)shlib, reexport_name.GetCString()); 350 else 351 s->Printf(" -> %s\n", reexport_name.GetCString()); 352 } 353 else 354 { 355 const char *format = m_size_is_sibling ? 356 "0x%16.16" PRIx64 " Sibling -> [%5llu] 0x%8.8x %s\n": 357 "0x%16.16" PRIx64 " 0x%16.16" PRIx64 " 0x%8.8x %s\n"; 358 s->Printf( format, 359 m_addr_range.GetBaseAddress().GetOffset(), 360 GetByteSize(), 361 m_flags, 362 name.AsCString("")); 363 } 364 } 365 366 uint32_t 367 Symbol::GetPrologueByteSize () 368 { 369 if (m_type == eSymbolTypeCode || m_type == eSymbolTypeResolver) 370 { 371 if (!m_type_data_resolved) 372 { 373 m_type_data_resolved = true; 374 375 const Address &base_address = m_addr_range.GetBaseAddress(); 376 Function *function = base_address.CalculateSymbolContextFunction(); 377 if (function) 378 { 379 // Functions have line entries which can also potentially have end of prologue information. 380 // So if this symbol points to a function, use the prologue information from there. 381 m_type_data = function->GetPrologueByteSize(); 382 } 383 else 384 { 385 ModuleSP module_sp (base_address.GetModule()); 386 SymbolContext sc; 387 if (module_sp) 388 { 389 uint32_t resolved_flags = module_sp->ResolveSymbolContextForAddress (base_address, 390 eSymbolContextLineEntry, 391 sc); 392 if (resolved_flags & eSymbolContextLineEntry) 393 { 394 // Default to the end of the first line entry. 395 m_type_data = sc.line_entry.range.GetByteSize(); 396 397 // Set address for next line. 398 Address addr (base_address); 399 addr.Slide (m_type_data); 400 401 // Check the first few instructions and look for one that has a line number that is 402 // different than the first entry. This is also done in Function::GetPrologueByteSize(). 403 uint16_t total_offset = m_type_data; 404 for (int idx = 0; idx < 6; ++idx) 405 { 406 SymbolContext sc_temp; 407 resolved_flags = module_sp->ResolveSymbolContextForAddress (addr, eSymbolContextLineEntry, sc_temp); 408 // Make sure we got line number information... 409 if (!(resolved_flags & eSymbolContextLineEntry)) 410 break; 411 412 // If this line number is different than our first one, use it and we're done. 413 if (sc_temp.line_entry.line != sc.line_entry.line) 414 { 415 m_type_data = total_offset; 416 break; 417 } 418 419 // Slide addr up to the next line address. 420 addr.Slide (sc_temp.line_entry.range.GetByteSize()); 421 total_offset += sc_temp.line_entry.range.GetByteSize(); 422 // If we've gone too far, bail out. 423 if (total_offset >= m_addr_range.GetByteSize()) 424 break; 425 } 426 427 // Sanity check - this may be a function in the middle of code that has debug information, but 428 // not for this symbol. So the line entries surrounding us won't lie inside our function. 429 // In that case, the line entry will be bigger than we are, so we do that quick check and 430 // if that is true, we just return 0. 431 if (m_type_data >= m_addr_range.GetByteSize()) 432 m_type_data = 0; 433 } 434 else 435 { 436 // TODO: expose something in Process to figure out the 437 // size of a function prologue. 438 m_type_data = 0; 439 } 440 } 441 } 442 } 443 return m_type_data; 444 } 445 return 0; 446 } 447 448 bool 449 Symbol::Compare(const ConstString& name, SymbolType type) const 450 { 451 if (type == eSymbolTypeAny || m_type == type) 452 return m_mangled.GetMangledName() == name || m_mangled.GetDemangledName(GetLanguage()) == name; 453 return false; 454 } 455 456 #define ENUM_TO_CSTRING(x) case eSymbolType##x: return #x; 457 458 const char * 459 Symbol::GetTypeAsString() const 460 { 461 switch (m_type) 462 { 463 ENUM_TO_CSTRING(Invalid); 464 ENUM_TO_CSTRING(Absolute); 465 ENUM_TO_CSTRING(Code); 466 ENUM_TO_CSTRING(Resolver); 467 ENUM_TO_CSTRING(Data); 468 ENUM_TO_CSTRING(Trampoline); 469 ENUM_TO_CSTRING(Runtime); 470 ENUM_TO_CSTRING(Exception); 471 ENUM_TO_CSTRING(SourceFile); 472 ENUM_TO_CSTRING(HeaderFile); 473 ENUM_TO_CSTRING(ObjectFile); 474 ENUM_TO_CSTRING(CommonBlock); 475 ENUM_TO_CSTRING(Block); 476 ENUM_TO_CSTRING(Local); 477 ENUM_TO_CSTRING(Param); 478 ENUM_TO_CSTRING(Variable); 479 ENUM_TO_CSTRING(VariableType); 480 ENUM_TO_CSTRING(LineEntry); 481 ENUM_TO_CSTRING(LineHeader); 482 ENUM_TO_CSTRING(ScopeBegin); 483 ENUM_TO_CSTRING(ScopeEnd); 484 ENUM_TO_CSTRING(Additional); 485 ENUM_TO_CSTRING(Compiler); 486 ENUM_TO_CSTRING(Instrumentation); 487 ENUM_TO_CSTRING(Undefined); 488 ENUM_TO_CSTRING(ObjCClass); 489 ENUM_TO_CSTRING(ObjCMetaClass); 490 ENUM_TO_CSTRING(ObjCIVar); 491 ENUM_TO_CSTRING(ReExported); 492 default: 493 break; 494 } 495 return "<unknown SymbolType>"; 496 } 497 498 void 499 Symbol::CalculateSymbolContext (SymbolContext *sc) 500 { 501 // Symbols can reconstruct the symbol and the module in the symbol context 502 sc->symbol = this; 503 if (ValueIsAddress()) 504 sc->module_sp = GetAddressRef().GetModule(); 505 else 506 sc->module_sp.reset(); 507 } 508 509 ModuleSP 510 Symbol::CalculateSymbolContextModule () 511 { 512 if (ValueIsAddress()) 513 return GetAddressRef().GetModule(); 514 return ModuleSP(); 515 } 516 517 Symbol * 518 Symbol::CalculateSymbolContextSymbol () 519 { 520 return this; 521 } 522 523 void 524 Symbol::DumpSymbolContext (Stream *s) 525 { 526 bool dumped_module = false; 527 if (ValueIsAddress()) 528 { 529 ModuleSP module_sp (GetAddressRef().GetModule()); 530 if (module_sp) 531 { 532 dumped_module = true; 533 module_sp->DumpSymbolContext(s); 534 } 535 } 536 if (dumped_module) 537 s->PutCString(", "); 538 539 s->Printf("Symbol{0x%8.8x}", GetID()); 540 } 541 542 lldb::addr_t 543 Symbol::GetByteSize () const 544 { 545 return m_addr_range.GetByteSize(); 546 } 547 548 549 Symbol * 550 Symbol::ResolveReExportedSymbolInModuleSpec (Target &target, 551 ConstString &reexport_name, 552 ModuleSpec &module_spec, 553 ModuleList &seen_modules) const 554 { 555 ModuleSP module_sp; 556 if (module_spec.GetFileSpec()) 557 { 558 // Try searching for the module file spec first using the full path 559 module_sp = target.GetImages().FindFirstModule(module_spec); 560 if (!module_sp) 561 { 562 // Next try and find the module by basename in case environment 563 // variables or other runtime trickery causes shared libraries 564 // to be loaded from alternate paths 565 module_spec.GetFileSpec().GetDirectory().Clear(); 566 module_sp = target.GetImages().FindFirstModule(module_spec); 567 } 568 } 569 570 if (module_sp) 571 { 572 // There should not be cycles in the reexport list, but we don't want to crash if there are so make sure 573 // we haven't seen this before: 574 if (!seen_modules.AppendIfNeeded(module_sp)) 575 return nullptr; 576 577 lldb_private::SymbolContextList sc_list; 578 module_sp->FindSymbolsWithNameAndType(reexport_name, eSymbolTypeAny, sc_list); 579 const size_t num_scs = sc_list.GetSize(); 580 if (num_scs > 0) 581 { 582 for (size_t i=0; i<num_scs; ++i) 583 { 584 lldb_private::SymbolContext sc; 585 if (sc_list.GetContextAtIndex(i, sc)) 586 { 587 if (sc.symbol->IsExternal()) 588 return sc.symbol; 589 } 590 } 591 } 592 // If we didn't find the symbol in this module, it may be because this module re-exports some 593 // whole other library. We have to search those as well: 594 seen_modules.Append(module_sp); 595 596 FileSpecList reexported_libraries = module_sp->GetObjectFile()->GetReExportedLibraries(); 597 size_t num_reexported_libraries = reexported_libraries.GetSize(); 598 for (size_t idx = 0; idx < num_reexported_libraries; idx++) 599 { 600 ModuleSpec reexported_module_spec; 601 reexported_module_spec.GetFileSpec() = reexported_libraries.GetFileSpecAtIndex(idx); 602 Symbol *result_symbol = ResolveReExportedSymbolInModuleSpec(target, 603 reexport_name, 604 reexported_module_spec, 605 seen_modules); 606 if (result_symbol) 607 return result_symbol; 608 } 609 } 610 return nullptr; 611 } 612 613 Symbol * 614 Symbol::ResolveReExportedSymbol (Target &target) const 615 { 616 ConstString reexport_name (GetReExportedSymbolName()); 617 if (reexport_name) 618 { 619 ModuleSpec module_spec; 620 ModuleList seen_modules; 621 module_spec.GetFileSpec() = GetReExportedSymbolSharedLibrary(); 622 if (module_spec.GetFileSpec()) 623 { 624 return ResolveReExportedSymbolInModuleSpec(target, reexport_name, module_spec, seen_modules); 625 } 626 } 627 return nullptr; 628 } 629 630 lldb::addr_t 631 Symbol::GetFileAddress () const 632 { 633 if (ValueIsAddress()) 634 return GetAddressRef().GetFileAddress(); 635 else 636 return LLDB_INVALID_ADDRESS; 637 } 638 639 lldb::addr_t 640 Symbol::GetLoadAddress (Target *target) const 641 { 642 if (ValueIsAddress()) 643 return GetAddressRef().GetLoadAddress(target); 644 else 645 return LLDB_INVALID_ADDRESS; 646 } 647 648 ConstString 649 Symbol::GetName () const 650 { 651 return m_mangled.GetName(GetLanguage()); 652 } 653 654 ConstString 655 Symbol::GetNameNoArguments () const 656 { 657 return m_mangled.GetName(GetLanguage(), Mangled::ePreferDemangledWithoutArguments); 658 } 659 660 661 lldb::addr_t 662 Symbol::ResolveCallableAddress(Target &target) const 663 { 664 if (GetType() == lldb::eSymbolTypeUndefined) 665 return LLDB_INVALID_ADDRESS; 666 667 Address func_so_addr; 668 669 bool is_indirect = IsIndirect(); 670 if (GetType() == eSymbolTypeReExported) 671 { 672 Symbol *reexported_symbol = ResolveReExportedSymbol(target); 673 if (reexported_symbol) 674 { 675 func_so_addr = reexported_symbol->GetAddress(); 676 is_indirect = reexported_symbol->IsIndirect(); 677 } 678 } 679 else 680 { 681 func_so_addr = GetAddress(); 682 is_indirect = IsIndirect(); 683 } 684 685 if (func_so_addr.IsValid()) 686 { 687 if (!target.GetProcessSP() && is_indirect) 688 { 689 // can't resolve indirect symbols without calling a function... 690 return LLDB_INVALID_ADDRESS; 691 } 692 693 lldb::addr_t load_addr = func_so_addr.GetCallableLoadAddress (&target, is_indirect); 694 695 if (load_addr != LLDB_INVALID_ADDRESS) 696 { 697 return load_addr; 698 } 699 } 700 701 return LLDB_INVALID_ADDRESS; 702 } 703 704 705 lldb::DisassemblerSP 706 Symbol::GetInstructions (const ExecutionContext &exe_ctx, 707 const char *flavor, 708 bool prefer_file_cache) 709 { 710 ModuleSP module_sp (m_addr_range.GetBaseAddress().GetModule()); 711 if (module_sp) 712 { 713 const bool prefer_file_cache = false; 714 return Disassembler::DisassembleRange (module_sp->GetArchitecture(), 715 nullptr, 716 flavor, 717 exe_ctx, 718 m_addr_range, 719 prefer_file_cache); 720 } 721 return lldb::DisassemblerSP(); 722 } 723 724 bool 725 Symbol::GetDisassembly (const ExecutionContext &exe_ctx, 726 const char *flavor, 727 bool prefer_file_cache, 728 Stream &strm) 729 { 730 lldb::DisassemblerSP disassembler_sp = GetInstructions (exe_ctx, flavor, prefer_file_cache); 731 if (disassembler_sp) 732 { 733 const bool show_address = true; 734 const bool show_bytes = false; 735 disassembler_sp->GetInstructionList().Dump (&strm, show_address, show_bytes, &exe_ctx); 736 return true; 737 } 738 return false; 739 } 740