bool
CommandObjectDisassemble::DoExecute (Args& command, CommandReturnObject &result)
{
    Target *target = m_interpreter.GetDebugger().GetSelectedTarget().get();
    if (target == NULL)
    {
        result.AppendError ("invalid target, create a debug target using the 'target create' command");
        result.SetStatus (eReturnStatusFailed);
        return false;
    }
    if (!m_options.arch.IsValid())
        m_options.arch = target->GetArchitecture();

    if (!m_options.arch.IsValid())
    {
        result.AppendError ("use the --arch option or set the target architecure to disassemble");
        result.SetStatus (eReturnStatusFailed);
        return false;
    }

    const char *plugin_name = m_options.GetPluginName ();
    const char *flavor_string = m_options.GetFlavorString();

    DisassemblerSP disassembler = Disassembler::FindPlugin(m_options.arch, flavor_string, plugin_name);

    if (!disassembler)
    {
        if (plugin_name)
        {
            result.AppendErrorWithFormat ("Unable to find Disassembler plug-in named '%s' that supports the '%s' architecture.\n",
                                          plugin_name,
                                          m_options.arch.GetArchitectureName());
        }
        else
            result.AppendErrorWithFormat ("Unable to find Disassembler plug-in for the '%s' architecture.\n", 
                                          m_options.arch.GetArchitectureName());
        result.SetStatus (eReturnStatusFailed);
        return false;
    }
    else if (flavor_string != NULL && !disassembler->FlavorValidForArchSpec(m_options.arch, flavor_string))
        result.AppendWarningWithFormat("invalid disassembler flavor \"%s\", using default.\n", flavor_string);

    result.SetStatus (eReturnStatusSuccessFinishResult);

    if (command.GetArgumentCount() != 0)
    {
        result.AppendErrorWithFormat ("\"disassemble\" arguments are specified as options.\n");
        GetOptions()->GenerateOptionUsage (result.GetErrorStream(), this);
        result.SetStatus (eReturnStatusFailed);
        return false;
    }
    
    if (m_options.show_mixed && m_options.num_lines_context == 0)
        m_options.num_lines_context = 1;

    // Always show the PC in the disassembly
    uint32_t options = Disassembler::eOptionMarkPCAddress;

    // Mark the source line for the current PC only if we are doing mixed source and assembly
    if (m_options.show_mixed)
        options |= Disassembler::eOptionMarkPCSourceLine;

    if (m_options.show_bytes)
        options |= Disassembler::eOptionShowBytes;

    if (m_options.raw)
        options |= Disassembler::eOptionRawOuput;

    if (!m_options.func_name.empty())
    {
        ConstString name(m_options.func_name.c_str());
        
        if (Disassembler::Disassemble (m_interpreter.GetDebugger(), 
                                       m_options.arch,
                                       plugin_name,
                                       flavor_string,
                                       m_exe_ctx,
                                       name,
                                       NULL,    // Module *
                                       m_options.num_instructions,
                                       m_options.show_mixed ? m_options.num_lines_context : 0,
                                       options,
                                       result.GetOutputStream()))
        {
            result.SetStatus (eReturnStatusSuccessFinishResult);
        }
        else
        {
            result.AppendErrorWithFormat ("Unable to find symbol with name '%s'.\n", name.GetCString());
            result.SetStatus (eReturnStatusFailed);
        }
    } 
    else
    {
        std::vector<AddressRange> ranges;
        AddressRange range;
        StackFrame *frame = m_exe_ctx.GetFramePtr();
        if (m_options.frame_line)
        {
            if (frame == NULL)
            {
                result.AppendError ("Cannot disassemble around the current line without a selected frame.\n");
                result.SetStatus (eReturnStatusFailed);
                return false;
            }
            LineEntry pc_line_entry (frame->GetSymbolContext(eSymbolContextLineEntry).line_entry);
            if (pc_line_entry.IsValid())
            {
                range = pc_line_entry.range;
            }
            else
            {
                m_options.at_pc = true; // No line entry, so just disassemble around the current pc
                m_options.show_mixed = false;
            }
        }
        else if (m_options.current_function)
        {
            if (frame == NULL)
            {
                result.AppendError ("Cannot disassemble around the current function without a selected frame.\n");
                result.SetStatus (eReturnStatusFailed);
                return false;
            }
            Symbol *symbol = frame->GetSymbolContext(eSymbolContextSymbol).symbol;
            if (symbol)
            {
                range.GetBaseAddress() = symbol->GetAddress();
                range.SetByteSize(symbol->GetByteSize());
            }
        }

        // Did the "m_options.frame_line" find a valid range already? If so
        // skip the rest...
        if (range.GetByteSize() == 0)
        {
            if (m_options.at_pc)
            {
                if (frame == NULL)
                {
                    result.AppendError ("Cannot disassemble around the current PC without a selected frame.\n");
                    result.SetStatus (eReturnStatusFailed);
                    return false;
                }
                range.GetBaseAddress() = frame->GetFrameCodeAddress();
                if (m_options.num_instructions == 0)
                {
                    // Disassembling at the PC always disassembles some number of instructions (not the whole function).
                    m_options.num_instructions = DEFAULT_DISASM_NUM_INS;
                }
                ranges.push_back(range);
            }
            else
            {
                range.GetBaseAddress().SetOffset (m_options.start_addr);
                if (range.GetBaseAddress().IsValid())
                {
                    if (m_options.end_addr != LLDB_INVALID_ADDRESS)
                    {
                        if (m_options.end_addr <= m_options.start_addr)
                        {
                            result.AppendErrorWithFormat ("End address before start address.\n");
                            result.SetStatus (eReturnStatusFailed);
                            return false;            
                        }
                        range.SetByteSize (m_options.end_addr - m_options.start_addr);
                    }
                    ranges.push_back(range);
                }
                else
                {
                    if (m_options.symbol_containing_addr != LLDB_INVALID_ADDRESS 
                        && target)
                    {
                        if (!target->GetSectionLoadList().IsEmpty())
                        {
                            bool failed = false;
                            Address symbol_containing_address;
                            if (target->GetSectionLoadList().ResolveLoadAddress (m_options.symbol_containing_addr, symbol_containing_address))
                            {
                                ModuleSP module_sp (symbol_containing_address.GetModule());
                                SymbolContext sc;
                                bool resolve_tail_call_address = true; // PC can be one past the address range of the function.
                                module_sp->ResolveSymbolContextForAddress (symbol_containing_address, eSymbolContextEverything, sc,
                                                                           resolve_tail_call_address);
                                if (sc.function || sc.symbol)
                                {
                                    sc.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, range);
                                }
                                else
                                {
                                    failed = true;
                                }
                            }
                            else
                            {
                                failed = true;
                            }
                            if (failed)
                            {
                                result.AppendErrorWithFormat ("Could not find function bounds for address 0x%" PRIx64 "\n", m_options.symbol_containing_addr);
                                result.SetStatus (eReturnStatusFailed);
                                return false;
                            }
                            ranges.push_back(range);
                        }
                        else
                        {
                            for (lldb::ModuleSP module_sp : target->GetImages().Modules())
                            {
                                lldb::addr_t file_addr = m_options.symbol_containing_addr;
                                Address file_address;
                                if (module_sp->ResolveFileAddress(file_addr, file_address))
                                {
                                    SymbolContext sc;
                                    bool resolve_tail_call_address = true; // PC can be one past the address range of the function.
                                    module_sp->ResolveSymbolContextForAddress (file_address, eSymbolContextEverything, sc, resolve_tail_call_address);
                                    if (sc.function || sc.symbol)
                                    {
                                        sc.GetAddressRange (eSymbolContextFunction | eSymbolContextSymbol, 0, false, range);
                                        ranges.push_back(range);
                                    }
                                }
                            }
                            
                        }
                    }
                }
            }
        }
        else
            ranges.push_back(range);

        if (m_options.num_instructions != 0)
        {
            if (ranges.size() == 0)
            {
                // The default action is to disassemble the current frame function.
                if (frame)
                {
                    SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
                    if (sc.function)
                        range.GetBaseAddress() = sc.function->GetAddressRange().GetBaseAddress();
                    else if (sc.symbol && sc.symbol->ValueIsAddress())
                        range.GetBaseAddress() = sc.symbol->GetAddress();
                    else
                        range.GetBaseAddress() = frame->GetFrameCodeAddress();
                }
                
                if (!range.GetBaseAddress().IsValid())
                {
                    result.AppendError ("invalid frame");
                    result.SetStatus (eReturnStatusFailed);
                    return false;
                }
            }
            
            bool print_sc_header = ranges.size() > 1;
            for (AddressRange cur_range : ranges)
            {
                if (Disassembler::Disassemble (m_interpreter.GetDebugger(),
                                               m_options.arch,
                                               plugin_name,
                                               flavor_string,
                                               m_exe_ctx,
                                               cur_range.GetBaseAddress(),
                                               m_options.num_instructions,
                                               m_options.show_mixed ? m_options.num_lines_context : 0,
                                               options,
                                               result.GetOutputStream()))
                {
                    result.SetStatus (eReturnStatusSuccessFinishResult);
                }
                else
                {
                    if (m_options.start_addr != LLDB_INVALID_ADDRESS)
                        result.AppendErrorWithFormat ("Failed to disassemble memory at 0x%8.8" PRIx64 ".\n", m_options.start_addr);
                    else if (m_options.symbol_containing_addr != LLDB_INVALID_ADDRESS)
                        result.AppendErrorWithFormat ("Failed to disassemble memory in function at 0x%8.8" PRIx64 ".\n", m_options.symbol_containing_addr);
                    result.SetStatus (eReturnStatusFailed);
                }
            }
            if (print_sc_header)
                result.AppendMessage("\n");
        }
        else
        {
            if (ranges.size() == 0)
            {
                // The default action is to disassemble the current frame function.
                if (frame)
                {
                    SymbolContext sc(frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
                    if (sc.function)
                        range = sc.function->GetAddressRange();
                    else if (sc.symbol && sc.symbol->ValueIsAddress())
                    {
                        range.GetBaseAddress() = sc.symbol->GetAddress();
                        range.SetByteSize (sc.symbol->GetByteSize());
                    }
                    else
                        range.GetBaseAddress() = frame->GetFrameCodeAddress();
                }
                else
                {
                    result.AppendError ("invalid frame");
                    result.SetStatus (eReturnStatusFailed);
                    return false;
                }
                ranges.push_back(range);
            }
            
            bool print_sc_header = ranges.size() > 1;
            for (AddressRange cur_range : ranges)
            {
                if (cur_range.GetByteSize() == 0)
                    cur_range.SetByteSize(DEFAULT_DISASM_BYTE_SIZE);

                if (Disassembler::Disassemble (m_interpreter.GetDebugger(),
                                               m_options.arch,
                                               plugin_name,
                                               flavor_string,
                                               m_exe_ctx,
                                               cur_range,
                                               m_options.num_instructions,
                                               m_options.show_mixed ? m_options.num_lines_context : 0,
                                               options,
                                               result.GetOutputStream()))
                {
                    result.SetStatus (eReturnStatusSuccessFinishResult);
                }
                else
                {
                    result.AppendErrorWithFormat ("Failed to disassemble memory at 0x%8.8" PRIx64 ".\n", m_options.start_addr);
                    result.SetStatus (eReturnStatusFailed);            
                }
                if (print_sc_header)
                    result.AppendMessage("\n");
            }
        }
    }

    return result.Succeeded();
}
Ejemplo n.º 2
0
AddressClass
ObjectFile::GetAddressClass (addr_t file_addr)
{
    Symtab *symtab = GetSymtab(ObjectFile::eSymtabFromUnifiedSectionList);
    if (symtab)
    {
        Symbol *symbol = symtab->FindSymbolContainingFileAddress(file_addr);
        if (symbol)
        {
            if (symbol->ValueIsAddress())
            {
                const SectionSP section_sp (symbol->GetAddress().GetSection());
                if (section_sp)
                {
                    const SectionType section_type = section_sp->GetType();
                    switch (section_type)
                    {
                    case eSectionTypeInvalid:               return eAddressClassUnknown;
                    case eSectionTypeCode:                  return eAddressClassCode;
                    case eSectionTypeContainer:             return eAddressClassUnknown;
                    case eSectionTypeData:
                    case eSectionTypeDataCString:
                    case eSectionTypeDataCStringPointers:
                    case eSectionTypeDataSymbolAddress:
                    case eSectionTypeData4:
                    case eSectionTypeData8:
                    case eSectionTypeData16:
                    case eSectionTypeDataPointers:
                    case eSectionTypeZeroFill:
                    case eSectionTypeDataObjCMessageRefs:
                    case eSectionTypeDataObjCCFStrings:
                        return eAddressClassData;
                    case eSectionTypeDebug:
                    case eSectionTypeDWARFDebugAbbrev:
                    case eSectionTypeDWARFDebugAranges:
                    case eSectionTypeDWARFDebugFrame:
                    case eSectionTypeDWARFDebugInfo:
                    case eSectionTypeDWARFDebugLine:
                    case eSectionTypeDWARFDebugLoc:
                    case eSectionTypeDWARFDebugMacInfo:
                    case eSectionTypeDWARFDebugPubNames:
                    case eSectionTypeDWARFDebugPubTypes:
                    case eSectionTypeDWARFDebugRanges:
                    case eSectionTypeDWARFDebugStr:
                    case eSectionTypeDWARFAppleNames:
                    case eSectionTypeDWARFAppleTypes:
                    case eSectionTypeDWARFAppleNamespaces:
                    case eSectionTypeDWARFAppleObjC:
                        return eAddressClassDebug;
                    case eSectionTypeEHFrame:               return eAddressClassRuntime;
                    case eSectionTypeELFSymbolTable:
                    case eSectionTypeELFDynamicSymbols:
                    case eSectionTypeELFRelocationEntries:
                    case eSectionTypeELFDynamicLinkInfo:
                    case eSectionTypeOther:                 return eAddressClassUnknown;
                    }
                }
            }
            
            const SymbolType symbol_type = symbol->GetType();
            switch (symbol_type)
            {
            case eSymbolTypeAny:            return eAddressClassUnknown;
            case eSymbolTypeAbsolute:       return eAddressClassUnknown;
            case eSymbolTypeCode:           return eAddressClassCode;
            case eSymbolTypeTrampoline:     return eAddressClassCode;
            case eSymbolTypeResolver:       return eAddressClassCode;
            case eSymbolTypeData:           return eAddressClassData;
            case eSymbolTypeRuntime:        return eAddressClassRuntime;
            case eSymbolTypeException:      return eAddressClassRuntime;
            case eSymbolTypeSourceFile:     return eAddressClassDebug;
            case eSymbolTypeHeaderFile:     return eAddressClassDebug;
            case eSymbolTypeObjectFile:     return eAddressClassDebug;
            case eSymbolTypeCommonBlock:    return eAddressClassDebug;
            case eSymbolTypeBlock:          return eAddressClassDebug;
            case eSymbolTypeLocal:          return eAddressClassData;
            case eSymbolTypeParam:          return eAddressClassData;
            case eSymbolTypeVariable:       return eAddressClassData;
            case eSymbolTypeVariableType:   return eAddressClassDebug;
            case eSymbolTypeLineEntry:      return eAddressClassDebug;
            case eSymbolTypeLineHeader:     return eAddressClassDebug;
            case eSymbolTypeScopeBegin:     return eAddressClassDebug;
            case eSymbolTypeScopeEnd:       return eAddressClassDebug;
            case eSymbolTypeAdditional:     return eAddressClassUnknown;
            case eSymbolTypeCompiler:       return eAddressClassDebug;
            case eSymbolTypeInstrumentation:return eAddressClassDebug;
            case eSymbolTypeUndefined:      return eAddressClassUnknown;
            case eSymbolTypeObjCClass:      return eAddressClassRuntime;
            case eSymbolTypeObjCMetaClass:  return eAddressClassRuntime;
            case eSymbolTypeObjCIVar:       return eAddressClassRuntime;
            }
        }
    }
    return eAddressClassUnknown;
}
Ejemplo n.º 3
0
bool
Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, DumpStyle fallback_style, uint32_t addr_size) const
{
    // If the section was NULL, only load address is going to work unless we are
    // trying to deref a pointer
    SectionSP section_sp (GetSection());
    if (!section_sp && style != DumpStyleResolvedPointerDescription)
        style = DumpStyleLoadAddress;

    ExecutionContext exe_ctx (exe_scope);
    Target *target = exe_ctx.GetTargetPtr();
    // If addr_byte_size is UINT32_MAX, then determine the correct address
    // byte size for the process or default to the size of addr_t
    if (addr_size == UINT32_MAX)
    {
        if (target)
            addr_size = target->GetArchitecture().GetAddressByteSize ();
        else
            addr_size = sizeof(addr_t);
    }

    Address so_addr;
    switch (style)
    {
    case DumpStyleInvalid:
        return false;

    case DumpStyleSectionNameOffset:
        if (section_sp)
        {
            section_sp->DumpName(s);
            s->Printf (" + %" PRIu64, m_offset.load());
        }
        else
        {
            s->Address(m_offset, addr_size);
        }
        break;

    case DumpStyleSectionPointerOffset:
        s->Printf("(Section *)%p + ", static_cast<void*>(section_sp.get()));
        s->Address(m_offset, addr_size);
        break;

    case DumpStyleModuleWithFileAddress:
        if (section_sp)
        {
            s->Printf("%s[", section_sp->GetModule()->GetFileSpec().GetFilename().AsCString("<Unknown>"));
        }
    // Fall through
    case DumpStyleFileAddress:
    {
        addr_t file_addr = GetFileAddress();
        if (file_addr == LLDB_INVALID_ADDRESS)
        {
            if (fallback_style != DumpStyleInvalid)
                return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
            return false;
        }
        s->Address (file_addr, addr_size);
        if (style == DumpStyleModuleWithFileAddress && section_sp)
            s->PutChar(']');
    }
    break;

    case DumpStyleLoadAddress:
    {
        addr_t load_addr = GetLoadAddress (target);
        if (load_addr == LLDB_INVALID_ADDRESS)
        {
            if (fallback_style != DumpStyleInvalid)
                return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
            return false;
        }
        s->Address (load_addr, addr_size);
    }
    break;

    case DumpStyleResolvedDescription:
    case DumpStyleResolvedDescriptionNoModule:
    case DumpStyleResolvedDescriptionNoFunctionArguments:
        if (IsSectionOffset())
        {
            uint32_t pointer_size = 4;
            ModuleSP module_sp (GetModule());
            if (target)
                pointer_size = target->GetArchitecture().GetAddressByteSize();
            else if (module_sp)
                pointer_size = module_sp->GetArchitecture().GetAddressByteSize();

            bool showed_info = false;
            if (section_sp)
            {
                SectionType sect_type = section_sp->GetType();
                switch (sect_type)
                {
                case eSectionTypeData:
                    if (module_sp)
                    {
                        SymbolVendor *sym_vendor = module_sp->GetSymbolVendor();
                        if (sym_vendor)
                        {
                            Symtab *symtab = sym_vendor->GetSymtab();
                            if (symtab)
                            {
                                const addr_t file_Addr = GetFileAddress();
                                Symbol *symbol = symtab->FindSymbolContainingFileAddress (file_Addr);
                                if (symbol)
                                {
                                    const char *symbol_name = symbol->GetName().AsCString();
                                    if (symbol_name)
                                    {
                                        s->PutCString(symbol_name);
                                        addr_t delta = file_Addr - symbol->GetAddress().GetFileAddress();
                                        if (delta)
                                            s->Printf(" + %" PRIu64, delta);
                                        showed_info = true;
                                    }
                                }
                            }
                        }
                    }
                    break;

                case eSectionTypeDataCString:
                    // Read the C string from memory and display it
                    showed_info = true;
                    ReadCStringFromMemory (exe_scope, *this, s);
                    break;

                case eSectionTypeDataCStringPointers:
                {
                    if (ReadAddress (exe_scope, *this, pointer_size, so_addr))
                    {
#if VERBOSE_OUTPUT
                        s->PutCString("(char *)");
                        so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
                        s->PutCString(": ");
#endif
                        showed_info = true;
                        ReadCStringFromMemory (exe_scope, so_addr, s);
                    }
                }
                break;

                case eSectionTypeDataObjCMessageRefs:
                {
                    if (ReadAddress (exe_scope, *this, pointer_size, so_addr))
                    {
                        if (target && so_addr.IsSectionOffset())
                        {
                            SymbolContext func_sc;
                            target->GetImages().ResolveSymbolContextForAddress (so_addr,
                                    eSymbolContextEverything,
                                    func_sc);
                            if (func_sc.function || func_sc.symbol)
                            {
                                showed_info = true;
#if VERBOSE_OUTPUT
                                s->PutCString ("(objc_msgref *) -> { (func*)");
                                so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
#else
                                s->PutCString ("{ ");
#endif
                                Address cstr_addr(*this);
                                cstr_addr.SetOffset(cstr_addr.GetOffset() + pointer_size);
                                func_sc.DumpStopContext(s, exe_scope, so_addr, true, true, false, true);
                                if (ReadAddress (exe_scope, cstr_addr, pointer_size, so_addr))
                                {
#if VERBOSE_OUTPUT
                                    s->PutCString("), (char *)");
                                    so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
                                    s->PutCString(" (");
#else
                                    s->PutCString(", ");
#endif
                                    ReadCStringFromMemory (exe_scope, so_addr, s);
                                }
#if VERBOSE_OUTPUT
                                s->PutCString(") }");
#else
                                s->PutCString(" }");
#endif
                            }
                        }
                    }
                }
                break;

                case eSectionTypeDataObjCCFStrings:
                {
                    Address cfstring_data_addr(*this);
                    cfstring_data_addr.SetOffset(cfstring_data_addr.GetOffset() + (2 * pointer_size));
                    if (ReadAddress (exe_scope, cfstring_data_addr, pointer_size, so_addr))
                    {
#if VERBOSE_OUTPUT
                        s->PutCString("(CFString *) ");
                        cfstring_data_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);
                        s->PutCString(" -> @");
#else
                        s->PutChar('@');
#endif
                        if (so_addr.Dump(s, exe_scope, DumpStyleResolvedDescription))
                            showed_info = true;
                    }
                }
                break;

                case eSectionTypeData4:
                    // Read the 4 byte data and display it
                    showed_info = true;
                    s->PutCString("(uint32_t) ");
                    DumpUInt (exe_scope, *this, 4, s);
                    break;

                case eSectionTypeData8:
                    // Read the 8 byte data and display it
                    showed_info = true;
                    s->PutCString("(uint64_t) ");
                    DumpUInt (exe_scope, *this, 8, s);
                    break;

                case eSectionTypeData16:
                    // Read the 16 byte data and display it
                    showed_info = true;
                    s->PutCString("(uint128_t) ");
                    DumpUInt (exe_scope, *this, 16, s);
                    break;

                case eSectionTypeDataPointers:
                    // Read the pointer data and display it
                {
                    if (ReadAddress (exe_scope, *this, pointer_size, so_addr))
                    {
                        s->PutCString ("(void *)");
                        so_addr.Dump(s, exe_scope, DumpStyleLoadAddress, DumpStyleFileAddress);

                        showed_info = true;
                        if (so_addr.IsSectionOffset())
                        {
                            SymbolContext pointer_sc;
                            if (target)
                            {
                                target->GetImages().ResolveSymbolContextForAddress (so_addr,
                                        eSymbolContextEverything,
                                        pointer_sc);
                                if (pointer_sc.function || pointer_sc.symbol)
                                {
                                    s->PutCString(": ");
                                    pointer_sc.DumpStopContext(s, exe_scope, so_addr, true, false, false, true);
                                }
                            }
                        }
                    }
                }
                break;

                default:
                    break;
                }
            }

            if (!showed_info)
            {
                if (module_sp)
                {
                    SymbolContext sc;
                    module_sp->ResolveSymbolContextForAddress(*this, eSymbolContextEverything, sc);
                    if (sc.function || sc.symbol)
                    {
                        bool show_stop_context = true;
                        const bool show_module = (style == DumpStyleResolvedDescription);
                        const bool show_fullpaths = false;
                        const bool show_inlined_frames = true;
                        const bool show_function_arguments = (style != DumpStyleResolvedDescriptionNoFunctionArguments);
                        if (sc.function == NULL && sc.symbol != NULL)
                        {
                            // If we have just a symbol make sure it is in the right section
                            if (sc.symbol->ValueIsAddress())
                            {
                                if (sc.symbol->GetAddress().GetSection() != GetSection())
                                {
                                    // don't show the module if the symbol is a trampoline symbol
                                    show_stop_context = false;
                                }
                            }
                        }
                        if (show_stop_context)
                        {
                            // We have a function or a symbol from the same
                            // sections as this address.
                            sc.DumpStopContext (s,
                                                exe_scope,
                                                *this,
                                                show_fullpaths,
                                                show_module,
                                                show_inlined_frames,
                                                show_function_arguments);
                        }
                        else
                        {
                            // We found a symbol but it was in a different
                            // section so it isn't the symbol we should be
                            // showing, just show the section name + offset
                            Dump (s, exe_scope, DumpStyleSectionNameOffset);
                        }
                    }
                }
            }
        }
        else
        {
            if (fallback_style != DumpStyleInvalid)
                return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
            return false;
        }
        break;

    case DumpStyleDetailedSymbolContext:
        if (IsSectionOffset())
        {
            ModuleSP module_sp (GetModule());
            if (module_sp)
            {
                SymbolContext sc;
                module_sp->ResolveSymbolContextForAddress(*this, eSymbolContextEverything, sc);
                if (sc.symbol)
                {
                    // If we have just a symbol make sure it is in the same section
                    // as our address. If it isn't, then we might have just found
                    // the last symbol that came before the address that we are
                    // looking up that has nothing to do with our address lookup.
                    if (sc.symbol->ValueIsAddress() && sc.symbol->GetAddress().GetSection() != GetSection())
                        sc.symbol = NULL;
                }
                sc.GetDescription(s, eDescriptionLevelBrief, target);

                if (sc.block)
                {
                    bool can_create = true;
                    bool get_parent_variables = true;
                    bool stop_if_block_is_inlined_function = false;
                    VariableList variable_list;
                    sc.block->AppendVariables (can_create,
                                               get_parent_variables,
                                               stop_if_block_is_inlined_function,
                                               &variable_list);

                    const size_t num_variables = variable_list.GetSize();
                    for (size_t var_idx = 0; var_idx < num_variables; ++var_idx)
                    {
                        Variable *var = variable_list.GetVariableAtIndex (var_idx).get();
                        if (var && var->LocationIsValidForAddress (*this))
                        {
                            s->Indent();
                            s->Printf ("   Variable: id = {0x%8.8" PRIx64 "}, name = \"%s\", type= \"%s\", location =",
                                       var->GetID(),
                                       var->GetName().GetCString(),
                                       var->GetType()->GetName().GetCString());
                            var->DumpLocationForAddress(s, *this);
                            s->PutCString(", decl = ");
                            var->GetDeclaration().DumpStopContext(s, false);
                            s->EOL();
                        }
                    }
                }
            }
        }
        else
        {
            if (fallback_style != DumpStyleInvalid)
                return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
            return false;
        }
        break;
    case DumpStyleResolvedPointerDescription:
    {
        Process *process = exe_ctx.GetProcessPtr();
        if (process)
        {
            addr_t load_addr = GetLoadAddress (target);
            if (load_addr != LLDB_INVALID_ADDRESS)
            {
                Error memory_error;
                addr_t dereferenced_load_addr = process->ReadPointerFromMemory(load_addr, memory_error);
                if (dereferenced_load_addr != LLDB_INVALID_ADDRESS)
                {
                    Address dereferenced_addr;
                    if (dereferenced_addr.SetLoadAddress(dereferenced_load_addr, target))
                    {
                        StreamString strm;
                        if (dereferenced_addr.Dump (&strm, exe_scope, DumpStyleResolvedDescription, DumpStyleInvalid, addr_size))
                        {
                            s->Address (dereferenced_load_addr, addr_size, " -> ", " ");
                            s->Write(strm.GetData(), strm.GetSize());
                            return true;
                        }
                    }
                }
            }
        }
        if (fallback_style != DumpStyleInvalid)
            return Dump (s, exe_scope, fallback_style, DumpStyleInvalid, addr_size);
        return false;
    }
    break;
    }

    return true;
}