Bug Summary

File:tools/lldb/source/Symbol/Symbol.cpp
Location:line 647, column 39
Description:Branch condition evaluates to a garbage value

Annotated Source Code

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