Exemple #1
0
size_t
Disassembler::Disassemble
(
    Debugger &debugger,
    const ArchSpec &arch,
    const ExecutionContext &exe_ctx,
    SymbolContextList &sc_list,
    uint32_t num_mixed_context_lines,
    bool show_bytes,
    Stream &strm
)
{
    size_t success_count = 0;
    const size_t count = sc_list.GetSize();
    SymbolContext sc;
    AddressRange range;
    for (size_t i=0; i<count; ++i)
    {
        if (sc_list.GetContextAtIndex(i, sc) == false)
            break;
        if (sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, range))
        {
            if (Disassemble (debugger, arch, exe_ctx, range, num_mixed_context_lines, show_bytes, strm))
            {
                ++success_count;
                strm.EOL();
            }
        }
    }
    return success_count;
}
size_t
ModuleList::FindFunctionSymbols (const ConstString &name,
                                 uint32_t name_type_mask,
                                 SymbolContextList& sc_list)
{
    const size_t old_size = sc_list.GetSize();

    if (name_type_mask & eFunctionNameTypeAuto)
    {
        ConstString lookup_name;
        uint32_t lookup_name_type_mask = 0;
        bool match_name_after_lookup = false;
        Module::PrepareForFunctionNameLookup (name, name_type_mask,
                                              eLanguageTypeUnknown, // TODO: add support
                                              lookup_name,
                                              lookup_name_type_mask,
                                              match_name_after_lookup);
    
        Mutex::Locker locker(m_modules_mutex);
        collection::const_iterator pos, end = m_modules.end();
        for (pos = m_modules.begin(); pos != end; ++pos)
        {
            (*pos)->FindFunctionSymbols (lookup_name,
                                   lookup_name_type_mask,
                                   sc_list);
        }
        
        if (match_name_after_lookup)
        {
            SymbolContext sc;
            size_t i = old_size;
            while (i < sc_list.GetSize())
            {
                if (sc_list.GetContextAtIndex(i, sc))
                {
                    const char *func_name = sc.GetFunctionName().GetCString();
                    if (func_name != nullptr && strstr(func_name, name.GetCString()) == nullptr)
                    {
                        // Remove the current context
                        sc_list.RemoveContextAtIndex(i);
                        // Don't increment i and continue in the loop
                        continue;
                    }
                }
                ++i;
            }
        }
    }
    else
    {
        Mutex::Locker locker(m_modules_mutex);
        collection::const_iterator pos, end = m_modules.end();
        for (pos = m_modules.begin(); pos != end; ++pos)
        {
            (*pos)->FindFunctionSymbols (name, name_type_mask, sc_list);
        }
    }

    return sc_list.GetSize() - old_size;
}
Exemple #3
0
bool
Variable::DumpDeclaration (Stream *s, bool show_fullpaths, bool show_module)
{
    bool dumped_declaration_info = false;
    if (m_owner_scope)
    {
        SymbolContext sc;
        m_owner_scope->CalculateSymbolContext(&sc);
        sc.block = nullptr;
        sc.line_entry.Clear();
        bool show_inlined_frames = false;
        const bool show_function_arguments = true;
        const bool show_function_name = true;
    
        dumped_declaration_info = sc.DumpStopContext (s, 
                                                      nullptr,
                                                      Address(), 
                                                      show_fullpaths, 
                                                      show_module, 
                                                      show_inlined_frames,
                                                      show_function_arguments,
                                                      show_function_name);
        
        if (sc.function)
            s->PutChar(':');
    }
    if (m_declaration.DumpStopContext (s, false))
        dumped_declaration_info = true;
    return dumped_declaration_info;
}
Searcher::CallbackReturn
CommandCompletions::SymbolCompleter::SearchCallback(SearchFilter &filter,
                                                    SymbolContext &context,
                                                    Address *addr,
                                                    bool complete)
{
    if (context.module_sp)
    {
        SymbolContextList sc_list;        
        const bool include_symbols = true;
        const bool include_inlines = true;
        const bool append = true;
        context.module_sp->FindFunctions (m_regex, include_symbols, include_inlines, append, sc_list);

        SymbolContext sc;
        // Now add the functions & symbols to the list - only add if unique:
        for (uint32_t i = 0; i < sc_list.GetSize(); i++)
        {
            if (sc_list.GetContextAtIndex(i, sc))
            {
                ConstString func_name = sc.GetFunctionName(Mangled::ePreferDemangled);
                if (!func_name.IsEmpty())
                    m_match_set.insert (func_name);
            }
        }
    }
    return Searcher::eCallbackReturnContinue;
}
ThreadPlanSP
DynamicLoaderPOSIXDYLD::GetStepThroughTrampolinePlan(Thread &thread, bool stop)
{
    LogSP log(GetLogIfAnyCategoriesSet(LIBLLDB_LOG_DYNAMIC_LOADER));
    ThreadPlanSP thread_plan_sp;

    StackFrame *frame = thread.GetStackFrameAtIndex(0).get();
    const SymbolContext &context = frame->GetSymbolContext(eSymbolContextSymbol);
    Symbol *sym = context.symbol;

    if (sym == NULL || !sym->IsTrampoline())
        return thread_plan_sp;

    const ConstString &sym_name = sym->GetMangled().GetName(Mangled::ePreferMangled);
    if (!sym_name)
        return thread_plan_sp;

    SymbolContextList target_symbols;
    Target &target = thread.GetProcess().GetTarget();
    ModuleList &images = target.GetImages();

    images.FindSymbolsWithNameAndType(sym_name, eSymbolTypeCode, target_symbols);
    size_t num_targets = target_symbols.GetSize();
    if (!num_targets)
        return thread_plan_sp;

    typedef std::vector<lldb::addr_t> AddressVector;
    AddressVector addrs;
    for (size_t i = 0; i < num_targets; ++i)
    {
        SymbolContext context;
        AddressRange range;
        if (target_symbols.GetContextAtIndex(i, context))
        {
            context.GetAddressRange(eSymbolContextEverything, 0, false, range);
            lldb::addr_t addr = range.GetBaseAddress().GetLoadAddress(&target);
            if (addr != LLDB_INVALID_ADDRESS)
                addrs.push_back(addr);
        }
    }

    if (addrs.size() > 0) 
    {
        AddressVector::iterator start = addrs.begin();
        AddressVector::iterator end = addrs.end();

        std::sort(start, end);
        addrs.erase(std::unique(start, end), end);
        thread_plan_sp.reset(new ThreadPlanRunToAddress(thread, addrs, stop));
    }

    return thread_plan_sp;
}
bool
ThreadPlanStepInRange::DefaultShouldStopHereCallback (ThreadPlan *current_plan, Flags &flags, FrameComparison operation, void *baton)
{
    bool should_stop_here = true;
    StackFrame *frame = current_plan->GetThread().GetStackFrameAtIndex(0).get();
    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));

    // First see if the ThreadPlanShouldStopHere default implementation thinks we should get out of here:
    should_stop_here = ThreadPlanShouldStopHere::DefaultShouldStopHereCallback (current_plan, flags, operation, baton);
    if (!should_stop_here)
        return should_stop_here;
    
    if (should_stop_here && current_plan->GetKind() == eKindStepInRange && operation == eFrameCompareYounger)
    {
        ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (current_plan);
        if (step_in_range_plan->m_step_into_target)
        {
            SymbolContext sc = frame->GetSymbolContext(eSymbolContextFunction|eSymbolContextBlock|eSymbolContextSymbol);
            if (sc.symbol != NULL)
            {
                // First try an exact match, since that's cheap with ConstStrings.  Then do a strstr compare.
                if (step_in_range_plan->m_step_into_target == sc.GetFunctionName())
                {
                    should_stop_here = true;
                }
                else
                {
                    const char *target_name = step_in_range_plan->m_step_into_target.AsCString();
                    const char *function_name = sc.GetFunctionName().AsCString();
                    
                    if (function_name == NULL)
                        should_stop_here = false;
                    else if (strstr (function_name, target_name) == NULL)
                        should_stop_here = false;
                }
                if (log && !should_stop_here)
                    log->Printf("Stepping out of frame %s which did not match step into target %s.",
                                sc.GetFunctionName().AsCString(),
                                step_in_range_plan->m_step_into_target.AsCString());
            }
        }
        
        if (should_stop_here)
        {
            ThreadPlanStepInRange *step_in_range_plan = static_cast<ThreadPlanStepInRange *> (current_plan);
            // Don't log the should_step_out here, it's easier to do it in FrameMatchesAvoidCriteria.
            should_stop_here = !step_in_range_plan->FrameMatchesAvoidCriteria ();
        }
    }
    
    return should_stop_here;
}
bool
SystemRuntimeMacOSX::SafeToCallFunctionsOnThisThread (ThreadSP thread_sp)
{
    if (thread_sp && thread_sp->GetStackFrameCount() > 0 && thread_sp->GetFrameWithConcreteFrameIndex(0))
    {
        const SymbolContext sym_ctx (thread_sp->GetFrameWithConcreteFrameIndex(0)->GetSymbolContext (eSymbolContextSymbol));
        static ConstString g_select_symbol ("__select");
        if (sym_ctx.GetFunctionName() == g_select_symbol)
        {
            return false;
        }
    }
    return true;
}
Exemple #8
0
size_t
Disassembler::Disassemble
(
    Debugger &debugger,
    const ArchSpec &arch,
    const char *plugin_name,
    const char *flavor,
    const ExecutionContext &exe_ctx,
    SymbolContextList &sc_list,
    uint32_t num_instructions,
    uint32_t num_mixed_context_lines,
    uint32_t options,
    Stream &strm
)
{
    size_t success_count = 0;
    const size_t count = sc_list.GetSize();
    SymbolContext sc;
    AddressRange range;
    const uint32_t scope = eSymbolContextBlock | eSymbolContextFunction | eSymbolContextSymbol;
    const bool use_inline_block_range = true;
    for (size_t i=0; i<count; ++i)
    {
        if (sc_list.GetContextAtIndex(i, sc) == false)
            break;
        for (uint32_t range_idx = 0; sc.GetAddressRange(scope, range_idx, use_inline_block_range, range); ++range_idx)
        {
            if (Disassemble (debugger, 
                             arch, 
                             plugin_name,
                             flavor,
                             exe_ctx, 
                             range, 
                             num_instructions,
                             num_mixed_context_lines, 
                             options, 
                             strm))
            {
                ++success_count;
                strm.EOL();
            }
        }
    }
    return success_count;
}
 void StackTrace::OutputToStream(std::ostream* os)
 {
     SymbolContext* context = SymbolContext::Get();
     DWORD error = context->init_error();
     if(error != ERROR_SUCCESS)
     {
         (*os) << "Error initializing symbols (" << error
             << ").  Dumping unresolved backtrace:\n";
         for(int i=0; (i<count_)&&os->good(); ++i)
         {
             (*os) << "\t" << trace_[i] << "\n";
         }
     }
     else
     {
         (*os) << "Backtrace:\n";
         context->OutputTraceToStream(trace_, count_, os);
     }
 }
Exemple #10
0
bool
ThreadPlanStepInRange::FrameMatchesAvoidRegexp ()
{
    StackFrame *frame = GetThread().GetStackFrameAtIndex(0).get();

    const RegularExpression *avoid_regexp_to_use = m_avoid_regexp_ap.get();
    if (avoid_regexp_to_use == NULL)
        avoid_regexp_to_use = GetThread().GetSymbolsToAvoidRegexp();
        
    if (avoid_regexp_to_use != NULL)
    {
        SymbolContext sc = frame->GetSymbolContext(eSymbolContextFunction|eSymbolContextBlock|eSymbolContextSymbol);
        if (sc.symbol != NULL)
        {
            const char *frame_function_name = sc.GetFunctionName().GetCString();
            if (frame_function_name)
               return avoid_regexp_to_use->Execute(frame_function_name);
        }
    }
    return false;
}
Exemple #11
0
uint32_t
Module::ResolveSymbolContextForAddress (const Address& so_addr, uint32_t resolve_scope, SymbolContext& sc)
{
    Mutex::Locker locker (m_mutex);
    uint32_t resolved_flags = 0;

    // Clear the result symbol context in case we don't find anything
    sc.Clear();

    // Get the section from the section/offset address.
    const Section *section = so_addr.GetSection();

    // Make sure the section matches this module before we try and match anything
    if (section && section->GetModule() == this)
    {
        // If the section offset based address resolved itself, then this
        // is the right module.
        sc.module_sp = GetSP();
        resolved_flags |= eSymbolContextModule;

        // Resolve the compile unit, function, block, line table or line
        // entry if requested.
        if (resolve_scope & eSymbolContextCompUnit    ||
            resolve_scope & eSymbolContextFunction    ||
            resolve_scope & eSymbolContextBlock       ||
            resolve_scope & eSymbolContextLineEntry   )
        {
            SymbolVendor *symbols = GetSymbolVendor ();
            if (symbols)
                resolved_flags |= symbols->ResolveSymbolContext (so_addr, resolve_scope, sc);
        }

        // Resolve the symbol if requested, but don't re-look it up if we've already found it.
        if (resolve_scope & eSymbolContextSymbol && !(resolved_flags & eSymbolContextSymbol))
        {
            ObjectFile* ofile = GetObjectFile();
            if (ofile)
            {
                Symtab *symtab = ofile->GetSymtab();
                if (symtab)
                {
                    if (so_addr.IsSectionOffset())
                    {
                        sc.symbol = symtab->FindSymbolContainingFileAddress(so_addr.GetFileAddress());
                        if (sc.symbol)
                            resolved_flags |= eSymbolContextSymbol;
                    }
                }
            }
        }
    }
    return resolved_flags;
}
void
BreakpointResolverName::LookupInfo::Prune (SymbolContextList &sc_list, size_t start_idx) const
{
    if (match_name_after_lookup && name)
    {
        SymbolContext sc;
        size_t i = start_idx;
        while (i < sc_list.GetSize())
        {
            if (!sc_list.GetContextAtIndex(i, sc))
                break;
            ConstString full_name (sc.GetFunctionName());
            if (full_name && ::strstr(full_name.GetCString(), name.GetCString()) == NULL)
            {
                sc_list.RemoveContextAtIndex(i);
            }
            else
            {
                ++i;
            }
        }
    }
}
Exemple #13
0
FuncUnwindersSP
UnwindTable::GetUncachedFuncUnwindersContainingAddress (const Address& addr, SymbolContext &sc)
{
    FuncUnwindersSP no_unwind_found;
    Initialize();

    AddressRange range;
    if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0, false, range) || !range.GetBaseAddress().IsValid())
    {
        // Does the eh_frame unwind info has a function bounds for this addr?
        if (m_eh_frame == NULL || !m_eh_frame->GetAddressRange (addr, range))
        {
            return no_unwind_found;
        }
    }

    FuncUnwindersSP func_unwinder_sp(new FuncUnwinders(*this, m_assembly_profiler, range));
    return func_unwinder_sp;
}
Exemple #14
0
llvm::Optional<AddressRange> UnwindTable::GetAddressRange(const Address &addr,
                                                          SymbolContext &sc) {
  AddressRange range;

  // First check the symbol context
  if (sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0,
                         false, range) &&
      range.GetBaseAddress().IsValid())
    return range;

  // Does the eh_frame unwind info has a function bounds for this addr?
  if (m_eh_frame_up && m_eh_frame_up->GetAddressRange(addr, range))
    return range;

  // Try debug_frame as well
  if (m_debug_frame_up && m_debug_frame_up->GetAddressRange(addr, range))
    return range;

  return llvm::None;
}
Exemple #15
0
FuncUnwindersSP
UnwindTable::GetFuncUnwindersContainingAddress (const Address& addr, SymbolContext &sc)
{
    FuncUnwindersSP no_unwind_found;

    Initialize();

    // There is an UnwindTable per object file, so we can safely use file handles
    addr_t file_addr = addr.GetFileAddress();
    iterator end = m_unwinds.end ();
    iterator insert_pos = end;
    if (!m_unwinds.empty())
    {
        insert_pos = m_unwinds.lower_bound (file_addr);
        iterator pos = insert_pos;
        if ((pos == m_unwinds.end ()) || (pos != m_unwinds.begin() && pos->second->GetFunctionStartAddress() != addr))
            --pos;

        if (pos->second->ContainsAddress (addr))
            return pos->second;
    }

    AddressRange range;
    if (!sc.GetAddressRange(eSymbolContextFunction | eSymbolContextSymbol, 0, false, range) || !range.GetBaseAddress().IsValid())
    {
        // Does the eh_frame unwind info has a function bounds for this addr?
        if (m_eh_frame == NULL || !m_eh_frame->GetAddressRange (addr, range))
        {
            return no_unwind_found;
        }
    }

    FuncUnwindersSP func_unwinder_sp(new FuncUnwinders(*this, m_assembly_profiler, range));
    m_unwinds.insert (insert_pos, std::make_pair(range.GetBaseAddress().GetFileAddress(), func_unwinder_sp));
//    StreamFile s(stdout);
//    Dump (s);
    return func_unwinder_sp;
}
Exemple #16
0
bool
lldb_private::InferiorCallMunmap (Process *process,
                                  addr_t addr,
                                  addr_t length)
{
    Thread *thread = process->GetThreadList().GetSelectedThread().get();
    if (thread == NULL)
        return false;

    const bool append = true;
    const bool include_symbols = true;
    const bool include_inlines = false;
    SymbolContextList sc_list;
    const uint32_t count
        = process->GetTarget().GetImages().FindFunctions (ConstString ("munmap"),
                eFunctionNameTypeFull,
                include_symbols,
                include_inlines,
                append,
                sc_list);
    if (count > 0)
    {
        SymbolContext sc;
        if (sc_list.GetContextAtIndex(0, sc))
        {
            const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol;
            const bool use_inline_block_range = false;
            EvaluateExpressionOptions options;
            options.SetStopOthers(true);
            options.SetUnwindOnError(true);
            options.SetIgnoreBreakpoints(true);
            options.SetTryAllThreads(true);
            options.SetDebug (false);
            options.SetTimeoutUsec(500000);

            AddressRange munmap_range;
            if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, munmap_range))
            {
                lldb::addr_t args[] = { addr, length };
                lldb::ThreadPlanSP call_plan_sp (new ThreadPlanCallFunction (*thread,
                                                 munmap_range.GetBaseAddress(),
                                                 CompilerType(),
                                                 args,
                                                 options));
                if (call_plan_sp)
                {
                    StreamFile error_strm;
                    // This plan is a utility plan, so set it to discard itself when done.
                    call_plan_sp->SetIsMasterPlan (true);
                    call_plan_sp->SetOkayToDiscard(true);

                    StackFrame *frame = thread->GetStackFrameAtIndex (0).get();
                    if (frame)
                    {
                        ExecutionContext exe_ctx;
                        frame->CalculateExecutionContext (exe_ctx);
                        ExpressionResults result = process->RunThreadPlan (exe_ctx,
                                                   call_plan_sp,
                                                   options,
                                                   error_strm);
                        if (result == eExpressionCompleted)
                        {
                            return true;
                        }
                    }
                }
            }
        }
    }

    return false;
}
Searcher::CallbackReturn
BreakpointResolverName::SearchCallback(SearchFilter &filter,
                                       SymbolContext &context, Address *addr,
                                       bool containing) {
  SymbolContextList func_list;
  // SymbolContextList sym_list;

  uint32_t i;
  bool new_location;
  Address break_addr;
  assert(m_breakpoint != nullptr);

  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_BREAKPOINTS));

  if (m_class_name) {
    if (log)
      log->Warning("Class/method function specification not supported yet.\n");
    return Searcher::eCallbackReturnStop;
  }
  bool filter_by_cu =
      (filter.GetFilterRequiredItems() & eSymbolContextCompUnit) != 0;
  bool filter_by_language = (m_language != eLanguageTypeUnknown);
  const bool include_symbols = !filter_by_cu;
  const bool include_inlines = true;
  const bool append = true;

  switch (m_match_type) {
  case Breakpoint::Exact:
    if (context.module_sp) {
      for (const auto &lookup : m_lookups) {
        const size_t start_func_idx = func_list.GetSize();
        context.module_sp->FindFunctions(
            lookup.GetLookupName(), nullptr, lookup.GetNameTypeMask(),
            include_symbols, include_inlines, append, func_list);

        const size_t end_func_idx = func_list.GetSize();

        if (start_func_idx < end_func_idx)
          lookup.Prune(func_list, start_func_idx);
      }
    }
    break;
  case Breakpoint::Regexp:
    if (context.module_sp) {
      context.module_sp->FindFunctions(
          m_regex,
          !filter_by_cu, // include symbols only if we aren't filtering by CU
          include_inlines, append, func_list);
    }
    break;
  case Breakpoint::Glob:
    if (log)
      log->Warning("glob is not supported yet.");
    break;
  }

  // If the filter specifies a Compilation Unit, remove the ones that don't
  // pass at this point.
  if (filter_by_cu || filter_by_language) {
    uint32_t num_functions = func_list.GetSize();

    for (size_t idx = 0; idx < num_functions; idx++) {
      bool remove_it = false;
      SymbolContext sc;
      func_list.GetContextAtIndex(idx, sc);
      if (filter_by_cu) {
        if (!sc.comp_unit || !filter.CompUnitPasses(*sc.comp_unit))
          remove_it = true;
      }

      if (filter_by_language) {
        LanguageType sym_language = sc.GetLanguage();
        if ((Language::GetPrimaryLanguage(sym_language) !=
             Language::GetPrimaryLanguage(m_language)) &&
            (sym_language != eLanguageTypeUnknown)) {
          remove_it = true;
        }
      }

      if (remove_it) {
        func_list.RemoveContextAtIndex(idx);
        num_functions--;
        idx--;
      }
    }
  }

  // Remove any duplicates between the function list and the symbol list
  SymbolContext sc;
  if (func_list.GetSize()) {
    for (i = 0; i < func_list.GetSize(); i++) {
      if (func_list.GetContextAtIndex(i, sc)) {
        bool is_reexported = false;

        if (sc.block && sc.block->GetInlinedFunctionInfo()) {
          if (!sc.block->GetStartAddress(break_addr))
            break_addr.Clear();
        } else if (sc.function) {
          break_addr = sc.function->GetAddressRange().GetBaseAddress();
          if (m_skip_prologue && break_addr.IsValid()) {
            const uint32_t prologue_byte_size =
                sc.function->GetPrologueByteSize();
            if (prologue_byte_size)
              break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size);
          }
        } else if (sc.symbol) {
          if (sc.symbol->GetType() == eSymbolTypeReExported) {
            const Symbol *actual_symbol =
                sc.symbol->ResolveReExportedSymbol(m_breakpoint->GetTarget());
            if (actual_symbol) {
              is_reexported = true;
              break_addr = actual_symbol->GetAddress();
            }
          } else {
            break_addr = sc.symbol->GetAddress();
          }

          if (m_skip_prologue && break_addr.IsValid()) {
            const uint32_t prologue_byte_size =
                sc.symbol->GetPrologueByteSize();
            if (prologue_byte_size)
              break_addr.SetOffset(break_addr.GetOffset() + prologue_byte_size);
            else {
              const Architecture *arch =
                  m_breakpoint->GetTarget().GetArchitecturePlugin();
              if (arch)
                arch->AdjustBreakpointAddress(*sc.symbol, break_addr);
            }
          }
        }

        if (break_addr.IsValid()) {
          if (filter.AddressPasses(break_addr)) {
            BreakpointLocationSP bp_loc_sp(
                AddLocation(break_addr, &new_location));
            bp_loc_sp->SetIsReExported(is_reexported);
            if (bp_loc_sp && new_location && !m_breakpoint->IsInternal()) {
              if (log) {
                StreamString s;
                bp_loc_sp->GetDescription(&s, lldb::eDescriptionLevelVerbose);
                log->Printf("Added location: %s\n", s.GetData());
              }
            }
          }
        }
      }
    }
  }

  return Searcher::eCallbackReturnContinue;
}
Exemple #18
0
bool
Disassembler::Disassemble
(
    Debugger &debugger,
    const ArchSpec &arch,
    const ExecutionContext &exe_ctx,
    const AddressRange &disasm_range,
    uint32_t num_mixed_context_lines,
    bool show_bytes,
    Stream &strm
)
{
    if (disasm_range.GetByteSize())
    {
        Disassembler *disassembler = Disassembler::FindPlugin(arch);

        if (disassembler)
        {
            AddressRange range(disasm_range);
            
            Process *process = exe_ctx.process;

            // If we weren't passed in a section offset address range,
            // try and resolve it to something
            if (range.GetBaseAddress().IsSectionOffset() == false)
            {
                if (process && process->IsAlive())
                {
                    process->ResolveLoadAddress (range.GetBaseAddress().GetOffset(), range.GetBaseAddress());
                }
                else if (exe_ctx.target)
                {
                    exe_ctx.target->GetImages().ResolveFileAddress (range.GetBaseAddress().GetOffset(), range.GetBaseAddress());
                }
            }


            DataExtractor data;
            size_t bytes_disassembled = disassembler->ParseInstructions (&exe_ctx, range, data);
            if (bytes_disassembled == 0)
            {
                return false;
            }
            else
            {
                // We got some things disassembled...
                size_t num_instructions = disassembler->GetInstructionList().GetSize();
                uint32_t offset = 0;
                SymbolContext sc;
                SymbolContext prev_sc;
                AddressRange sc_range;
                if (num_mixed_context_lines)
                    strm.IndentMore ();


                Address addr(range.GetBaseAddress());
    
                // We extract the section to make sure we don't transition out
                // of the current section when disassembling
                const Section *addr_section = addr.GetSection();
                Module *range_module = range.GetBaseAddress().GetModule();

                for (size_t i=0; i<num_instructions; ++i)
                {
                    Disassembler::Instruction *inst = disassembler->GetInstructionList().GetInstructionAtIndex (i);
                    if (inst)
                    {
                        addr_t file_addr = addr.GetFileAddress();
                        if (addr_section == NULL || addr_section->ContainsFileAddress (file_addr) == false)
                        {
                            if (range_module)
                                range_module->ResolveFileAddress (file_addr, addr);
                            else if (exe_ctx.target)
                                exe_ctx.target->GetImages().ResolveFileAddress (file_addr, addr);
                                
                            addr_section = addr.GetSection();
                        }

                        prev_sc = sc;

                        if (addr_section)
                        {
                            Module *module = addr_section->GetModule();
                            uint32_t resolved_mask = module->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
                            if (resolved_mask)
                            {
                                if (prev_sc.function != sc.function || prev_sc.symbol != sc.symbol)
                                {
                                    if (prev_sc.function || prev_sc.symbol)
                                        strm.EOL();

                                    strm << sc.module_sp->GetFileSpec().GetFilename();
                                    
                                    if (sc.function)
                                        strm << '`' << sc.function->GetMangled().GetName();
                                    else if (sc.symbol)
                                        strm << '`' << sc.symbol->GetMangled().GetName();
                                    strm << ":\n";
                                }

                                if (num_mixed_context_lines && !sc_range.ContainsFileAddress (addr))
                                {
                                    sc.GetAddressRange (eSymbolContextEverything, sc_range);
                                        
                                    if (sc != prev_sc)
                                    {
                                        if (offset != 0)
                                            strm.EOL();

                                        sc.DumpStopContext(&strm, process, addr);

                                        if (sc.comp_unit && sc.line_entry.IsValid())
                                        {
                                            debugger.GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.line_entry.file,
                                                                                                           sc.line_entry.line,
                                                                                                           num_mixed_context_lines,
                                                                                                           num_mixed_context_lines,
                                                                                                           num_mixed_context_lines ? "->" : "",
                                                                                                           &strm);
                                        }
                                    }
                                }
                            }
                            else
                            {
                                sc.Clear();
                            }
                        }
                        if (num_mixed_context_lines)
                            strm.IndentMore ();
                        strm.Indent();
                        size_t inst_byte_size = inst->GetByteSize();
                        inst->Dump(&strm, &addr, show_bytes ? &data : NULL, offset, exe_ctx, show_bytes);
                        strm.EOL();
                        offset += inst_byte_size;
                        
                        addr.SetOffset (addr.GetOffset() + inst_byte_size);

                        if (num_mixed_context_lines)
                            strm.IndentLess ();
                    }
                    else
                    {
                        break;
                    }
                }
                if (num_mixed_context_lines)
                    strm.IndentLess ();

            }
        }
        return true;
    }
    return false;
}
Exemple #19
0
bool Address::Dump(Stream *s, ExecutionContextScope *exe_scope, DumpStyle style,
                   DumpStyle fallback_style, uint32_t addr_size) const {
  // If the section was nullptr, 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);
    } 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) {
      ModuleSP module_sp = section_sp->GetModule();
      if (module_sp)
        s->Printf("%s[", module_sp->GetFileSpec().GetFilename().AsCString(
                             "<Unknown>"));
      else
        s->Printf("%s[", "<Unknown>");
    }
    LLVM_FALLTHROUGH;
  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);

    /*
     * MIPS:
     * Display address in compressed form for MIPS16 or microMIPS
     * if the address belongs to eAddressClassCodeAlternateISA.
    */
    if (target) {
      const llvm::Triple::ArchType llvm_arch =
          target->GetArchitecture().GetMachine();
      if (llvm_arch == llvm::Triple::mips ||
          llvm_arch == llvm::Triple::mipsel ||
          llvm_arch == llvm::Triple::mips64 ||
          llvm_arch == llvm::Triple::mips64el)
        load_addr = GetCallableLoadAddress(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:
  case DumpStyleNoFunctionName:
    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->GetAddressRef().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 != nullptr || func_sc.symbol != nullptr) {
                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, 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 != nullptr ||
                    pointer_sc.symbol != nullptr) {
                  s->PutCString(": ");
                  pointer_sc.DumpStopContext(s, exe_scope, so_addr, true, false,
                                             false, true, 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);
            const bool show_function_name = (style != DumpStyleNoFunctionName);
            if (sc.function == nullptr && sc.symbol != nullptr) {
              // If we have just a symbol make sure it is in the right section
              if (sc.symbol->ValueIsAddress()) {
                if (sc.symbol->GetAddressRef().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, show_function_name);
            } 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 | eSymbolContextVariable, 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->GetAddressRef().GetSection() != GetSection())
            sc.symbol = nullptr;
        }
        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 *) { return true; },
                                    &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\"",
                        var->GetID(), var->GetName().GetCString());
              Type *type = var->GetType();
              if (type)
                s->Printf(", type = \"%s\"", type->GetName().GetCString());
              else
                s->PutCString(", type = <unknown>");
              s->PutCString(", location = ");
              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;
}
Exemple #20
0
    bool
    DoExecute (Args& command, CommandReturnObject &result)
    {
        const int argc = command.GetArgumentCount();

        if (argc != 0)
        {
            result.AppendErrorWithFormat("'%s' takes no arguments, only flags.\n", GetCommandName());
            result.SetStatus (eReturnStatusFailed);
            return false;
        }

        ExecutionContext exe_ctx(m_interpreter.GetExecutionContext());
        Target *target = exe_ctx.GetTargetPtr();

        if (target == NULL)
            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;
        }

        SymbolContextList sc_list;
        if (!m_options.symbol_name.empty())
        {
            // Displaying the source for a symbol:
            ConstString name(m_options.symbol_name.c_str());
            bool include_symbols = false;
            bool include_inlines = true;
            bool append = true;
            size_t num_matches = 0;
            
            if (m_options.modules.size() > 0)
            {
                ModuleList matching_modules;
                for (unsigned i = 0, e = m_options.modules.size(); i != e; i++)
                {
                    FileSpec module_file_spec(m_options.modules[i].c_str(), false);
                    if (module_file_spec)
                    {
                        ModuleSpec module_spec (module_file_spec);
                        matching_modules.Clear();
                        target->GetImages().FindModules (module_spec, matching_modules);
                        num_matches += matching_modules.FindFunctions (name, eFunctionNameTypeAuto, include_symbols, include_inlines, append, sc_list);
                    }
                }
            }
            else
            {
                num_matches = target->GetImages().FindFunctions (name, eFunctionNameTypeAuto, include_symbols, include_inlines, append, sc_list);
            }
            
            SymbolContext sc;

            if (num_matches == 0)
            {
                result.AppendErrorWithFormat("Could not find function named: \"%s\".\n", m_options.symbol_name.c_str());
                result.SetStatus (eReturnStatusFailed);
                return false;
            }
            
            sc_list.GetContextAtIndex (0, sc);
            FileSpec start_file;
            uint32_t start_line;
            uint32_t end_line;
            FileSpec end_file;
            if (sc.function != NULL)
            {
                sc.function->GetStartLineSourceInfo (start_file, start_line);
                if (start_line == 0)
                {
                    result.AppendErrorWithFormat("Could not find line information for start of function: \"%s\".\n", m_options.symbol_name.c_str());
                    result.SetStatus (eReturnStatusFailed);
                    return false;
                }
                sc.function->GetEndLineSourceInfo (end_file, end_line);
            }
            else
            {
                result.AppendErrorWithFormat("Could not find function info for: \"%s\".\n", m_options.symbol_name.c_str());
                result.SetStatus (eReturnStatusFailed);
                return false;
            }

            if (num_matches > 1)
            {
                // This could either be because there are multiple functions of this name, in which case
                // we'll have to specify this further...  Or it could be because there are multiple inlined instances
                // of one function.  So run through the matches and if they all have the same file & line then we can just
                // list one.
                
                bool found_multiple = false;
                
                for (size_t i = 1; i < num_matches; i++)
                {
                    SymbolContext scratch_sc;
                    sc_list.GetContextAtIndex (i, scratch_sc);
                    if (scratch_sc.function != NULL)
                    {
                        FileSpec scratch_file;
                        uint32_t scratch_line;
                        scratch_sc.function->GetStartLineSourceInfo (scratch_file, scratch_line);
                        if (scratch_file != start_file 
                            || scratch_line != start_line)
                        {
                            found_multiple = true;
                            break;
                        }
                    }
                }
                if (found_multiple)
                {
                    StreamString s;
                    for (size_t i = 0; i < num_matches; i++)
                    {
                        SymbolContext scratch_sc;
                        sc_list.GetContextAtIndex (i, scratch_sc);
                        if (scratch_sc.function != NULL)
                        {
                            s.Printf("\n%lu: ", i); 
                            scratch_sc.function->Dump (&s, true);
                        }
                    }
                    result.AppendErrorWithFormat("Multiple functions found matching: %s: \n%s\n", 
                                                 m_options.symbol_name.c_str(),
                                                 s.GetData());
                    result.SetStatus (eReturnStatusFailed);
                    return false;
                }
            }
            
                
            // This is a little hacky, but the first line table entry for a function points to the "{" that 
            // starts the function block.  It would be nice to actually get the function
            // declaration in there too.  So back up a bit, but not further than what you're going to display.
            size_t lines_to_back_up = m_options.num_lines >= 10 ? 5 : m_options.num_lines/2;
            uint32_t line_no;
            if (start_line <= lines_to_back_up)
                line_no = 1;
            else
                line_no = start_line - lines_to_back_up;
                
            // For fun, if the function is shorter than the number of lines we're supposed to display, 
            // only display the function...
            if (end_line != 0)
            {
                if (m_options.num_lines > end_line - line_no)
                    m_options.num_lines = end_line - line_no;
            }
            
            char path_buf[PATH_MAX];
            start_file.GetPath(path_buf, sizeof(path_buf));
            
            if (m_options.show_bp_locs)
            {
                const bool show_inlines = true;
                m_breakpoint_locations.Reset (start_file, 0, show_inlines);
                SearchFilter target_search_filter (exe_ctx.GetTargetSP());
                target_search_filter.Search (m_breakpoint_locations);
            }
            else
                m_breakpoint_locations.Clear();

            result.AppendMessageWithFormat("File: %s.\n", path_buf);
            target->GetSourceManager().DisplaySourceLinesWithLineNumbers (start_file,
                                                                          line_no,
                                                                          0,
                                                                          m_options.num_lines,
                                                                          "",
                                                                          &result.GetOutputStream(),
                                                                          GetBreakpointLocations ());
            
            result.SetStatus (eReturnStatusSuccessFinishResult);
            return true;

        }
        else if (m_options.address != LLDB_INVALID_ADDRESS)
        {
            SymbolContext sc;
            Address so_addr;
            StreamString error_strm;

            if (target->GetSectionLoadList().IsEmpty())
            {
                // The target isn't loaded yet, we need to lookup the file address
                // in all modules
                const ModuleList &module_list = target->GetImages();
                const uint32_t num_modules = module_list.GetSize();
                for (uint32_t i=0; i<num_modules; ++i)
                {
                    ModuleSP module_sp (module_list.GetModuleAtIndex(i));
                    if (module_sp && module_sp->ResolveFileAddress(m_options.address, so_addr))
                    {
                        sc.Clear();
                        if (module_sp->ResolveSymbolContextForAddress (so_addr, eSymbolContextEverything, sc) & eSymbolContextLineEntry)
                            sc_list.Append(sc);
                    }
                }
                
                if (sc_list.GetSize() == 0)
                {
                    result.AppendErrorWithFormat("no modules have source information for file address 0x%" PRIx64 ".\n",
                                                 m_options.address);
                    result.SetStatus (eReturnStatusFailed);
                    return false;
                }
            }
            else
            {
                // The target has some things loaded, resolve this address to a
                // compile unit + file + line and display
                if (target->GetSectionLoadList().ResolveLoadAddress (m_options.address, so_addr))
                {
                    ModuleSP module_sp (so_addr.GetModule());
                    if (module_sp)
                    {
                        sc.Clear();
                        if (module_sp->ResolveSymbolContextForAddress (so_addr, eSymbolContextEverything, sc) & eSymbolContextLineEntry)
                        {
                            sc_list.Append(sc);
                        }
                        else
                        {
                            so_addr.Dump(&error_strm, NULL, Address::DumpStyleModuleWithFileAddress);
                            result.AppendErrorWithFormat("address resolves to %s, but there is no line table information available for this address.\n",
                                                         error_strm.GetData());
                            result.SetStatus (eReturnStatusFailed);
                            return false;
                        }
                    }
                }

                if (sc_list.GetSize() == 0)
                {
                    result.AppendErrorWithFormat("no modules contain load address 0x%" PRIx64 ".\n", m_options.address);
                    result.SetStatus (eReturnStatusFailed);
                    return false;
                }
            }
            uint32_t num_matches = sc_list.GetSize();
            for (uint32_t i=0; i<num_matches; ++i)
            {
                sc_list.GetContextAtIndex(i, sc);
                if (sc.comp_unit)
                {
                    if (m_options.show_bp_locs)
                    {
                        m_breakpoint_locations.Clear();
                        const bool show_inlines = true;
                        m_breakpoint_locations.Reset (*sc.comp_unit, 0, show_inlines);
                        SearchFilter target_search_filter (target->shared_from_this());
                        target_search_filter.Search (m_breakpoint_locations);
                    }
                    
                    bool show_fullpaths = true;
                    bool show_module = true;
                    bool show_inlined_frames = true;
                    sc.DumpStopContext(&result.GetOutputStream(),
                                       exe_ctx.GetBestExecutionContextScope(),
                                       sc.line_entry.range.GetBaseAddress(),
                                       show_fullpaths,
                                       show_module,
                                       show_inlined_frames);
                    result.GetOutputStream().EOL();
                    
                    size_t lines_to_back_up = m_options.num_lines >= 10 ? 5 : m_options.num_lines/2;

                    target->GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.comp_unit,
                                                                                  sc.line_entry.line,
                                                                                  lines_to_back_up,
                                                                                  m_options.num_lines - lines_to_back_up,
                                                                                  "->",
                                                                                  &result.GetOutputStream(),
                                                                                  GetBreakpointLocations ());
                    result.SetStatus (eReturnStatusSuccessFinishResult);
                }
            }
        }
        else if (m_options.file_name.empty())
        {
            // Last valid source manager context, or the current frame if no
            // valid last context in source manager.
            // One little trick here, if you type the exact same list command twice in a row, it is
            // more likely because you typed it once, then typed it again
            if (m_options.start_line == 0)
            {
                if (target->GetSourceManager().DisplayMoreWithLineNumbers (&result.GetOutputStream(),
                                                                                               GetBreakpointLocations ()))
                {
                    result.SetStatus (eReturnStatusSuccessFinishResult);
                }
            }
            else
            {
                if (m_options.show_bp_locs)
                {
                    SourceManager::FileSP last_file_sp (target->GetSourceManager().GetLastFile ());
                    if (last_file_sp)
                    {
                        const bool show_inlines = true;
                        m_breakpoint_locations.Reset (last_file_sp->GetFileSpec(), 0, show_inlines);
                        SearchFilter target_search_filter (target->shared_from_this());
                        target_search_filter.Search (m_breakpoint_locations);
                    }
                }
                else
                    m_breakpoint_locations.Clear();

                if (target->GetSourceManager().DisplaySourceLinesWithLineNumbersUsingLastFile(
                            m_options.start_line,   // Line to display
                            0,                      // Lines before line to display
                            m_options.num_lines,    // Lines after line to display
                            "",                     // Don't mark "line"
                            &result.GetOutputStream(),
                            GetBreakpointLocations ()))
                {
                    result.SetStatus (eReturnStatusSuccessFinishResult);
                }

            }
        }
        else
        {
            const char *filename = m_options.file_name.c_str();

            bool check_inlines = false;
            SymbolContextList sc_list;
            size_t num_matches = 0;
            
            if (m_options.modules.size() > 0)
            {
                ModuleList matching_modules;
                for (unsigned i = 0, e = m_options.modules.size(); i != e; i++)
                {
                    FileSpec module_file_spec(m_options.modules[i].c_str(), false);
                    if (module_file_spec)
                    {
                        ModuleSpec module_spec (module_file_spec);
                        matching_modules.Clear();
                        target->GetImages().FindModules (module_spec, matching_modules);
                        num_matches += matching_modules.ResolveSymbolContextForFilePath (filename,
                                                                                         0,
                                                                                         check_inlines,
                                                                                         eSymbolContextModule | eSymbolContextCompUnit,
                                                                                         sc_list);
                    }
                }
            }
            else
            {
                num_matches = target->GetImages().ResolveSymbolContextForFilePath (filename,
                                                                                   0,
                                                                                   check_inlines,
                                                                                   eSymbolContextModule | eSymbolContextCompUnit,
                                                                                   sc_list);
            }
            
            if (num_matches == 0)
            {
                result.AppendErrorWithFormat("Could not find source file \"%s\".\n", 
                                             m_options.file_name.c_str());
                result.SetStatus (eReturnStatusFailed);
                return false;
            }
            
            if (num_matches > 1)
            {
                SymbolContext sc;
                bool got_multiple = false;
                FileSpec *test_cu_spec = NULL;

                for (unsigned i = 0; i < num_matches; i++)
                {
                    sc_list.GetContextAtIndex(i, sc);
                    if (sc.comp_unit)
                    {
                        if (test_cu_spec)
                        {
                            if (test_cu_spec != static_cast<FileSpec *> (sc.comp_unit))
                                got_multiple = true;
                                break;
                        }
                        else
                            test_cu_spec = sc.comp_unit;
                    }
                }
                if (got_multiple)
                {
                    result.AppendErrorWithFormat("Multiple source files found matching: \"%s.\"\n", 
                                                 m_options.file_name.c_str());
                    result.SetStatus (eReturnStatusFailed);
                    return false;
                }
            }
            
            SymbolContext sc;
            if (sc_list.GetContextAtIndex(0, sc))
            {
                if (sc.comp_unit)
                {
                    if (m_options.show_bp_locs)
                    {
                        const bool show_inlines = true;
                        m_breakpoint_locations.Reset (*sc.comp_unit, 0, show_inlines);
                        SearchFilter target_search_filter (target->shared_from_this());
                        target_search_filter.Search (m_breakpoint_locations);
                    }
                    else
                        m_breakpoint_locations.Clear();

                    target->GetSourceManager().DisplaySourceLinesWithLineNumbers (sc.comp_unit,
                                                                                  m_options.start_line,
                                                                                  0,
                                                                                  m_options.num_lines,
                                                                                  "",
                                                                                  &result.GetOutputStream(),
                                                                                  GetBreakpointLocations ());

                    result.SetStatus (eReturnStatusSuccessFinishResult);
                }
                else
                {
                    result.AppendErrorWithFormat("No comp unit found for: \"%s.\"\n", 
                                                 m_options.file_name.c_str());
                    result.SetStatus (eReturnStatusFailed);
                    return false;
                }
            }
        }
        return result.Succeeded();
    }
Exemple #21
0
void
BreakpointLocation::GetDescription (Stream *s, lldb::DescriptionLevel level)
{
    SymbolContext sc;
    
    // If the description level is "initial" then the breakpoint is printing out our initial state,
    // and we should let it decide how it wants to print our label.
    if (level != eDescriptionLevelInitial)
    {
        s->Indent();
        BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID());
    }
    
    if (level == lldb::eDescriptionLevelBrief)
        return;

    if (level != eDescriptionLevelInitial)
        s->PutCString(": ");

    if (level == lldb::eDescriptionLevelVerbose)
        s->IndentMore();

    if (m_address.IsSectionOffset())
    {
        m_address.CalculateSymbolContext(&sc);

        if (level == lldb::eDescriptionLevelFull || level == eDescriptionLevelInitial)
        {
            if (IsReExported())
                s->PutCString ("re-exported target = ");
            else
                s->PutCString("where = ");
            sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, false, true, false, true, true);
        }
        else
        {
            if (sc.module_sp)
            {
                s->EOL();
                s->Indent("module = ");
                sc.module_sp->GetFileSpec().Dump (s);
            }

            if (sc.comp_unit != NULL)
            {
                s->EOL();
                s->Indent("compile unit = ");
                static_cast<FileSpec*>(sc.comp_unit)->GetFilename().Dump (s);

                if (sc.function != NULL)
                {
                    s->EOL();
                    s->Indent("function = ");
                    s->PutCString (sc.function->GetName().AsCString("<unknown>"));
                }

                if (sc.line_entry.line > 0)
                {
                    s->EOL();
                    s->Indent("location = ");
                    sc.line_entry.DumpStopContext (s, true);
                }

            }
            else
            {
                // If we don't have a comp unit, see if we have a symbol we can print.
                if (sc.symbol)
                {
                    s->EOL();
                    if (IsReExported())
                        s->Indent ("re-exported target = ");
                    else
                        s->Indent("symbol = ");
                    s->PutCString(sc.symbol->GetName().AsCString("<unknown>"));
                }
            }
        }
    }

    if (level == lldb::eDescriptionLevelVerbose)
    {
        s->EOL();
        s->Indent();
    }
    
    if (m_address.IsSectionOffset() && (level == eDescriptionLevelFull || level == eDescriptionLevelInitial))
        s->Printf (", ");
    s->Printf ("address = ");
    
    ExecutionContextScope *exe_scope = NULL;
    Target *target = &m_owner.GetTarget();
    if (target)
        exe_scope = target->GetProcessSP().get();
    if (exe_scope == NULL)
        exe_scope = target;

    if (level == eDescriptionLevelInitial)
        m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleFileAddress);
    else
        m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);
    
    if (IsIndirect() && m_bp_site_sp)
    {
        Address resolved_address;
        resolved_address.SetLoadAddress(m_bp_site_sp->GetLoadAddress(), target);
        Symbol *resolved_symbol = resolved_address.CalculateSymbolContextSymbol();
        if (resolved_symbol)
        {
            if (level == eDescriptionLevelFull || level == eDescriptionLevelInitial)
                s->Printf (", ");
            else if (level == lldb::eDescriptionLevelVerbose)
            {
                s->EOL();
                s->Indent();
            }
            s->Printf ("indirect target = %s", resolved_symbol->GetName().GetCString());
        }
    }

    if (level == lldb::eDescriptionLevelVerbose)
    {
        s->EOL();
        s->Indent();
        s->Printf("resolved = %s\n", IsResolved() ? "true" : "false");

        s->Indent();
        s->Printf ("hit count = %-4u\n", GetHitCount());

        if (m_options_ap.get())
        {
            s->Indent();
            m_options_ap->GetDescription (s, level);
            s->EOL();
        }
        s->IndentLess();
    }
    else if (level != eDescriptionLevelInitial)
    {
        s->Printf(", %sresolved, hit count = %u ",
                  (IsResolved() ? "" : "un"),
                  GetHitCount());
        if (m_options_ap.get())
        {
            m_options_ap->GetDescription (s, level);
        }
    }
}
Exemple #22
0
bool 
Disassembler::PrintInstructions
(
    Disassembler *disasm_ptr,
    Debugger &debugger,
    const ArchSpec &arch,
    const ExecutionContext &exe_ctx,
    uint32_t num_instructions,
    uint32_t num_mixed_context_lines,
    uint32_t options,
    Stream &strm
)
{
    // We got some things disassembled...
    size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize();
    
    if (num_instructions > 0 && num_instructions < num_instructions_found)
        num_instructions_found = num_instructions;
        
    const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize ();
    uint32_t offset = 0;
    SymbolContext sc;
    SymbolContext prev_sc;
    AddressRange sc_range;
    const Address *pc_addr_ptr = NULL;
    ExecutionContextScope *exe_scope = exe_ctx.GetBestExecutionContextScope();
    Frame *frame = exe_ctx.GetFramePtr();

    TargetSP target_sp (exe_ctx.GetTargetSP());
    SourceManager &source_manager = target_sp ? target_sp->GetSourceManager() : debugger.GetSourceManager();

    if (frame)
        pc_addr_ptr = &frame->GetFrameCodeAddress();
    const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol;
    const bool use_inline_block_range = false;
    for (size_t i=0; i<num_instructions_found; ++i)
    {
        Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
        if (inst)
        {
            const Address &addr = inst->GetAddress();
            const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr;

            prev_sc = sc;

            ModuleSP module_sp (addr.GetModule());
            if (module_sp)
            {
                uint32_t resolved_mask = module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
                if (resolved_mask)
                {
                    if (num_mixed_context_lines)
                    {
                        if (!sc_range.ContainsFileAddress (addr))
                        {
                            sc.GetAddressRange (scope, 0, use_inline_block_range, sc_range);
                            
                            if (sc != prev_sc)
                            {
                                if (offset != 0)
                                    strm.EOL();
                                
                                sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false);
                                strm.EOL();
                                
                                if (sc.comp_unit && sc.line_entry.IsValid())
                                {
                                    source_manager.DisplaySourceLinesWithLineNumbers (sc.line_entry.file,
                                                                                      sc.line_entry.line,
                                                                                      num_mixed_context_lines,
                                                                                      num_mixed_context_lines,
                                                                                      ((inst_is_at_pc && (options & eOptionMarkPCSourceLine)) ? "->" : ""),
                                                                                      &strm);
                                }
                            }
                        }
                    }
                    else if ((sc.function || sc.symbol) && (sc.function != prev_sc.function || sc.symbol != prev_sc.symbol))
                    {
                        if (prev_sc.function || prev_sc.symbol)
                            strm.EOL();

                        bool show_fullpaths = false;
                        bool show_module = true;
                        bool show_inlined_frames = true;
                        sc.DumpStopContext (&strm, 
                                            exe_scope, 
                                            addr, 
                                            show_fullpaths,
                                            show_module,
                                            show_inlined_frames);
                        
                        strm << ":\n";
                    }
                }
                else
                {
                    sc.Clear(true);
                }
            }

            if ((options & eOptionMarkPCAddress) && pc_addr_ptr)
            {
                strm.PutCString(inst_is_at_pc ? "-> " : "   ");
            }
            const bool show_bytes = (options & eOptionShowBytes) != 0;
            inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx);
            strm.EOL();            
        }
        else
        {
            break;
        }
    }
        
    return true;
}
bool
ThreadPlanStepInRange::FrameMatchesAvoidCriteria ()
{
    StackFrame *frame = GetThread().GetStackFrameAtIndex(0).get();
    
    // Check the library list first, as that's cheapest:
    bool libraries_say_avoid = false;

    FileSpecList libraries_to_avoid (GetThread().GetLibrariesToAvoid());
    size_t num_libraries = libraries_to_avoid.GetSize();
    if (num_libraries > 0)
    {
        SymbolContext sc(frame->GetSymbolContext(eSymbolContextModule));
        FileSpec frame_library(sc.module_sp->GetFileSpec());
        
        if (frame_library)
        {
            for (size_t i = 0; i < num_libraries; i++)
            {
                const FileSpec &file_spec(libraries_to_avoid.GetFileSpecAtIndex(i));
                if (FileSpec::Equal (file_spec, frame_library, false))
                {
                    libraries_say_avoid = true;
                    break;
                }
            }
        }
    }
    if (libraries_say_avoid)
        return true;
    
    const RegularExpression *avoid_regexp_to_use = m_avoid_regexp_ap.get();
    if (avoid_regexp_to_use == NULL)
        avoid_regexp_to_use = GetThread().GetSymbolsToAvoidRegexp();
        
    if (avoid_regexp_to_use != NULL)
    {
        SymbolContext sc = frame->GetSymbolContext(eSymbolContextFunction|eSymbolContextBlock|eSymbolContextSymbol);
        if (sc.symbol != NULL)
        {
            const char *frame_function_name = sc.GetFunctionName().GetCString();
            if (frame_function_name)
            {
                size_t num_matches = 0;
                Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
                if (log)
                    num_matches = 1;
                
                RegularExpression::Match regex_match(num_matches);

                bool return_value = avoid_regexp_to_use->Execute(frame_function_name, &regex_match);
                if (return_value)
                {
                    if (log)
                    {
                        std::string match;
                        regex_match.GetMatchAtIndex(frame_function_name,0, match);
                        log->Printf ("Stepping out of function \"%s\" because it matches the avoid regexp \"%s\" - match substring: \"%s\".",
                                     frame_function_name,
                                     avoid_regexp_to_use->GetText(),
                                     match.c_str());
                    }

                }
                return return_value;
            }
        }
    }
    return false;
}
bool
SystemRuntimeMacOSX::BacktraceRecordingHeadersInitialized ()
{
    if (m_lib_backtrace_recording_info.queue_info_version != 0)
        return true;

    addr_t queue_info_version_address = LLDB_INVALID_ADDRESS;
    addr_t queue_info_data_offset_address = LLDB_INVALID_ADDRESS;
    addr_t item_info_version_address = LLDB_INVALID_ADDRESS;
    addr_t item_info_data_offset_address = LLDB_INVALID_ADDRESS;
    Target &target = m_process->GetTarget();


    static ConstString introspection_dispatch_queue_info_version ("__introspection_dispatch_queue_info_version");
    SymbolContextList sc_list;
    if (m_process->GetTarget().GetImages().FindSymbolsWithNameAndType (introspection_dispatch_queue_info_version, eSymbolTypeData, sc_list) > 0)
    {
        SymbolContext sc;
        sc_list.GetContextAtIndex (0, sc);
        AddressRange addr_range;
        sc.GetAddressRange (eSymbolContextSymbol, 0, false, addr_range);
        queue_info_version_address = addr_range.GetBaseAddress().GetLoadAddress(&target);
    }
    sc_list.Clear();

    static ConstString introspection_dispatch_queue_info_data_offset ("__introspection_dispatch_queue_info_data_offset");
    if (m_process->GetTarget().GetImages().FindSymbolsWithNameAndType (introspection_dispatch_queue_info_data_offset, eSymbolTypeData, sc_list) > 0)
    {
        SymbolContext sc;
        sc_list.GetContextAtIndex (0, sc);
        AddressRange addr_range;
        sc.GetAddressRange (eSymbolContextSymbol, 0, false, addr_range);
        queue_info_data_offset_address = addr_range.GetBaseAddress().GetLoadAddress(&target);
    }
    sc_list.Clear();

    static ConstString introspection_dispatch_item_info_version ("__introspection_dispatch_item_info_version");
    if (m_process->GetTarget().GetImages().FindSymbolsWithNameAndType (introspection_dispatch_item_info_version, eSymbolTypeData, sc_list) > 0)
    {
        SymbolContext sc;
        sc_list.GetContextAtIndex (0, sc);
        AddressRange addr_range;
        sc.GetAddressRange (eSymbolContextSymbol, 0, false, addr_range);
        item_info_version_address = addr_range.GetBaseAddress().GetLoadAddress(&target);
    }
    sc_list.Clear();

    static ConstString introspection_dispatch_item_info_data_offset ("__introspection_dispatch_item_info_data_offset");
    if (m_process->GetTarget().GetImages().FindSymbolsWithNameAndType (introspection_dispatch_item_info_data_offset, eSymbolTypeData, sc_list) > 0)
    {
        SymbolContext sc;
        sc_list.GetContextAtIndex (0, sc);
        AddressRange addr_range;
        sc.GetAddressRange (eSymbolContextSymbol, 0, false, addr_range);
        item_info_data_offset_address = addr_range.GetBaseAddress().GetLoadAddress(&target);
    }

    if (queue_info_version_address != LLDB_INVALID_ADDRESS
            && queue_info_data_offset_address != LLDB_INVALID_ADDRESS
            && item_info_version_address != LLDB_INVALID_ADDRESS
            && item_info_data_offset_address != LLDB_INVALID_ADDRESS)
    {
        Error error;
        m_lib_backtrace_recording_info.queue_info_version = m_process->ReadUnsignedIntegerFromMemory (queue_info_version_address, 2, 0, error);
        if (error.Success())
        {
            m_lib_backtrace_recording_info.queue_info_data_offset = m_process->ReadUnsignedIntegerFromMemory (queue_info_data_offset_address, 2, 0, error);
            if (error.Success())
            {
                m_lib_backtrace_recording_info.item_info_version = m_process->ReadUnsignedIntegerFromMemory (item_info_version_address, 2, 0, error);
                if (error.Success())
                {
                    m_lib_backtrace_recording_info.item_info_data_offset = m_process->ReadUnsignedIntegerFromMemory (item_info_data_offset_address, 2, 0, error);
                    if (!error.Success())
                    {
                        m_lib_backtrace_recording_info.queue_info_version = 0;
                    }
                }
                else
                {
                    m_lib_backtrace_recording_info.queue_info_version = 0;
                }
            }
            else
            {
                m_lib_backtrace_recording_info.queue_info_version = 0;
            }
        }
    }

    return m_lib_backtrace_recording_info.queue_info_version != 0;
}
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();
}
Exemple #26
0
size_t
ModuleList::FindFunctions (const ConstString &name, 
                           uint32_t name_type_mask, 
                           bool include_symbols,
                           bool include_inlines,
                           bool append, 
                           SymbolContextList &sc_list) const
{
    if (!append)
        sc_list.Clear();
    
    const size_t old_size = sc_list.GetSize();
    
    if (name_type_mask & eFunctionNameTypeAuto)
    {
        ConstString lookup_name;
        uint32_t lookup_name_type_mask = 0;
        bool match_name_after_lookup = false;
        Module::PrepareForFunctionNameLookup (name, name_type_mask,
                                              lookup_name,
                                              lookup_name_type_mask,
                                              match_name_after_lookup);
    
        Mutex::Locker locker(m_modules_mutex);
        collection::const_iterator pos, end = m_modules.end();
        for (pos = m_modules.begin(); pos != end; ++pos)
        {
            (*pos)->FindFunctions (lookup_name,
                                   NULL,
                                   lookup_name_type_mask,
                                   include_symbols,
                                   include_inlines,
                                   true,
                                   sc_list);
        }
        
        if (match_name_after_lookup)
        {
            SymbolContext sc;
            size_t i = old_size;
            while (i<sc_list.GetSize())
            {
                if (sc_list.GetContextAtIndex(i, sc))
                {
                    const char *func_name = sc.GetFunctionName().GetCString();
                    if (func_name && strstr (func_name, name.GetCString()) == NULL)
                    {
                        // Remove the current context
                        sc_list.RemoveContextAtIndex(i);
                        // Don't increment i and continue in the loop
                        continue;
                    }
                }
                ++i;
            }
        }

    }
    else
    {
        Mutex::Locker locker(m_modules_mutex);
        collection::const_iterator pos, end = m_modules.end();
        for (pos = m_modules.begin(); pos != end; ++pos)
        {
            (*pos)->FindFunctions (name, NULL, name_type_mask, include_symbols, include_inlines, true, sc_list);
        }
    }
    return sc_list.GetSize() - old_size;
}
Exemple #27
0
bool 
Disassembler::PrintInstructions
(
    Disassembler *disasm_ptr,
    Debugger &debugger,
    const ArchSpec &arch,
    const ExecutionContext &exe_ctx,
    uint32_t num_instructions,
    uint32_t num_mixed_context_lines,
    uint32_t options,
    Stream &strm
)
{
    // We got some things disassembled...
    size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize();
    
    if (num_instructions > 0 && num_instructions < num_instructions_found)
        num_instructions_found = num_instructions;
        
    const uint32_t max_opcode_byte_size = disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize ();
    uint32_t offset = 0;
    SymbolContext sc;
    SymbolContext prev_sc;
    AddressRange sc_range;
    const Address *pc_addr_ptr = NULL;
    StackFrame *frame = exe_ctx.GetFramePtr();

    TargetSP target_sp (exe_ctx.GetTargetSP());
    SourceManager &source_manager = target_sp ? target_sp->GetSourceManager() : debugger.GetSourceManager();

    if (frame)
    {
        pc_addr_ptr = &frame->GetFrameCodeAddress();
    }
    const uint32_t scope = eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol;
    const bool use_inline_block_range = false;

    const FormatEntity::Entry *disassembly_format = NULL;
    FormatEntity::Entry format;
    if (exe_ctx.HasTargetScope())
    {
        disassembly_format = exe_ctx.GetTargetRef().GetDebugger().GetDisassemblyFormat ();
    }
    else
    {
        FormatEntity::Parse("${addr}: ", format);
        disassembly_format = &format;
    }

    // First pass: step through the list of instructions, 
    // find how long the initial addresses strings are, insert padding 
    // in the second pass so the opcodes all line up nicely.
    size_t address_text_size = 0;
    for (size_t i = 0; i < num_instructions_found; ++i)
    {
        Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
        if (inst)
        {
            const Address &addr = inst->GetAddress();
            ModuleSP module_sp (addr.GetModule());
            if (module_sp)
            {
                const uint32_t resolve_mask = eSymbolContextFunction | eSymbolContextSymbol;
                uint32_t resolved_mask = module_sp->ResolveSymbolContextForAddress(addr, resolve_mask, sc);
                if (resolved_mask)
                {
                    StreamString strmstr;
                    Debugger::FormatDisassemblerAddress (disassembly_format, &sc, NULL, &exe_ctx, &addr, strmstr);
                    size_t cur_line = strmstr.GetSizeOfLastLine();
                    if (cur_line > address_text_size)
                        address_text_size = cur_line;
                }
                sc.Clear(false);
            }
        }
    }

    for (size_t i = 0; i < num_instructions_found; ++i)
    {
        Instruction *inst = disasm_ptr->GetInstructionList().GetInstructionAtIndex (i).get();
        if (inst)
        {
            const Address &addr = inst->GetAddress();
            const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr;

            prev_sc = sc;

            ModuleSP module_sp (addr.GetModule());
            if (module_sp)
            {
                uint32_t resolved_mask = module_sp->ResolveSymbolContextForAddress(addr, eSymbolContextEverything, sc);
                if (resolved_mask)
                {
                    if (num_mixed_context_lines)
                    {
                        if (!sc_range.ContainsFileAddress (addr))
                        {
                            sc.GetAddressRange (scope, 0, use_inline_block_range, sc_range);
                            
                            if (sc != prev_sc)
                            {
                                if (offset != 0)
                                    strm.EOL();
                                
                                sc.DumpStopContext(&strm, exe_ctx.GetProcessPtr(), addr, false, true, false, false, true);
                                strm.EOL();
                                
                                if (sc.comp_unit && sc.line_entry.IsValid())
                                {
                                    source_manager.DisplaySourceLinesWithLineNumbers (sc.line_entry.file,
                                                                                      sc.line_entry.line,
                                                                                      num_mixed_context_lines,
                                                                                      num_mixed_context_lines,
                                                                                      ((inst_is_at_pc && (options & eOptionMarkPCSourceLine)) ? "->" : ""),
                                                                                      &strm);
                                }
                            }
                        }
                    }
                }
                else
                {
                    sc.Clear(true);
                }
            }

            const bool show_bytes = (options & eOptionShowBytes) != 0;
            inst->Dump (&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, &sc, &prev_sc, NULL, address_text_size);
            strm.EOL();            
        }
        else
        {
            break;
        }
    }
        
    return true;
}
Exemple #28
0
void
BreakpointLocation::GetDescription (Stream *s, lldb::DescriptionLevel level)
{
    SymbolContext sc;
    s->Indent();
    BreakpointID::GetCanonicalReference(s, m_owner.GetID(), GetID());

    if (level == lldb::eDescriptionLevelBrief)
        return;

    s->PutCString(": ");

    if (level == lldb::eDescriptionLevelVerbose)
        s->IndentMore();

    if (m_address.IsSectionOffset())
    {
        m_address.CalculateSymbolContext(&sc);

        if (level == lldb::eDescriptionLevelFull)
        {
            s->PutCString("where = ");
            sc.DumpStopContext (s, m_owner.GetTarget().GetProcessSP().get(), m_address, false, true, false);
        }
        else
        {
            if (sc.module_sp)
            {
                s->EOL();
                s->Indent("module = ");
                sc.module_sp->GetFileSpec().Dump (s);
            }

            if (sc.comp_unit != NULL)
            {
                s->EOL();
                s->Indent("compile unit = ");
                static_cast<FileSpec*>(sc.comp_unit)->GetFilename().Dump (s);

                if (sc.function != NULL)
                {
                    s->EOL();
                    s->Indent("function = ");
                    s->PutCString (sc.function->GetMangled().GetName().AsCString("<unknown>"));
                }

                if (sc.line_entry.line > 0)
                {
                    s->EOL();
                    s->Indent("location = ");
                    sc.line_entry.DumpStopContext (s, true);
                }

            }
            else
            {
                // If we don't have a comp unit, see if we have a symbol we can print.
                if (sc.symbol)
                {
                    s->EOL();
                    s->Indent("symbol = ");
                    s->PutCString(sc.symbol->GetMangled().GetName().AsCString("<unknown>"));
                }
            }
        }
    }

    if (level == lldb::eDescriptionLevelVerbose)
    {
        s->EOL();
        s->Indent();
    }
    s->Printf ("%saddress = ", (level == lldb::eDescriptionLevelFull && m_address.IsSectionOffset()) ? ", " : "");
    ExecutionContextScope *exe_scope = NULL;
    Target *target = &m_owner.GetTarget();
    if (target)
        exe_scope = target->GetProcessSP().get();
    if (exe_scope == NULL)
        exe_scope = target;

    m_address.Dump(s, exe_scope, Address::DumpStyleLoadAddress, Address::DumpStyleModuleWithFileAddress);

    if (level == lldb::eDescriptionLevelVerbose)
    {
        s->EOL();
        s->Indent();
        s->Printf("resolved = %s\n", IsResolved() ? "true" : "false");

        s->Indent();
        s->Printf ("hit count = %-4u\n", GetHitCount());

        if (m_options_ap.get())
        {
            s->Indent();
            m_options_ap->GetDescription (s, level);
            s->EOL();
        }
        s->IndentLess();
    }
    else
    {
        s->Printf(", %sresolved, hit count = %u ",
                  (IsResolved() ? "" : "un"),
                  GetHitCount());
        if (m_options_ap.get())
        {
            m_options_ap->GetDescription (s, level);
        }
    }
}
bool
SymbolContext::GetParentOfInlinedScope (const Address &curr_frame_pc, 
                                        SymbolContext &next_frame_sc, 
                                        Address &next_frame_pc) const
{
    next_frame_sc.Clear(false);
    next_frame_pc.Clear();

    if (block)
    {
        //const addr_t curr_frame_file_addr = curr_frame_pc.GetFileAddress();
        
        // In order to get the parent of an inlined function we first need to
        // see if we are in an inlined block as "this->block" could be an 
        // inlined block, or a parent of "block" could be. So lets check if
        // this block or one of this blocks parents is an inlined function.
        Block *curr_inlined_block = block->GetContainingInlinedBlock();
        if (curr_inlined_block)
        {
            // "this->block" is contained in an inline function block, so to
            // get the scope above the inlined block, we get the parent of the
            // inlined block itself
            Block *next_frame_block = curr_inlined_block->GetParent();
            // Now calculate the symbol context of the containing block
            next_frame_block->CalculateSymbolContext (&next_frame_sc);
            
            // If we get here we weren't able to find the return line entry using the nesting of the blocks and
            // the line table.  So just use the call site info from our inlined block.
            
            AddressRange range;
            if (curr_inlined_block->GetRangeContainingAddress (curr_frame_pc, range))
            {
                // To see there this new frame block it, we need to look at the
                // call site information from 
                const InlineFunctionInfo* curr_inlined_block_inlined_info = curr_inlined_block->GetInlinedFunctionInfo();
                next_frame_pc = range.GetBaseAddress();
                next_frame_sc.line_entry.range.GetBaseAddress() = next_frame_pc;
                next_frame_sc.line_entry.file = curr_inlined_block_inlined_info->GetCallSite().GetFile();
                next_frame_sc.line_entry.line = curr_inlined_block_inlined_info->GetCallSite().GetLine();
                next_frame_sc.line_entry.column = curr_inlined_block_inlined_info->GetCallSite().GetColumn();
                return true;
            }
            else
            {
                Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_SYMBOLS));

                if (log)
                {
                    log->Printf ("warning: inlined block 0x%8.8" PRIx64 " doesn't have a range that contains file address 0x%" PRIx64,
                                 curr_inlined_block->GetID(), curr_frame_pc.GetFileAddress());
                }
#ifdef LLDB_CONFIGURATION_DEBUG
                else
                {
                    ObjectFile *objfile = NULL;
                    if (module_sp)
                    {
                        SymbolVendor *symbol_vendor = module_sp->GetSymbolVendor();
                        if (symbol_vendor)
                        {
                            SymbolFile *symbol_file = symbol_vendor->GetSymbolFile();
                            if (symbol_file)
                                objfile = symbol_file->GetObjectFile();
                        }
                    }
                    if (objfile)
                    {
                        Host::SystemLog (Host::eSystemLogWarning, 
                                         "warning: inlined block 0x%8.8" PRIx64 " doesn't have a range that contains file address 0x%" PRIx64 " in %s\n",
                                         curr_inlined_block->GetID(), 
                                         curr_frame_pc.GetFileAddress(),
                                         objfile->GetFileSpec().GetPath().c_str());
                    }
                    else
                    {
                        Host::SystemLog (Host::eSystemLogWarning, 
                                         "warning: inlined block 0x%8.8" PRIx64 " doesn't have a range that contains file address 0x%" PRIx64 "\n",
                                         curr_inlined_block->GetID(), 
                                         curr_frame_pc.GetFileAddress());
                    }
                }
#endif
            }
        }
    }
    
    return false;
}
Exemple #30
0
bool
lldb_private::InferiorCallMmap (Process *process,
                                addr_t &allocated_addr,
                                addr_t addr,
                                addr_t length,
                                unsigned prot,
                                unsigned flags,
                                addr_t fd,
                                addr_t offset)
{
    Thread *thread = process->GetThreadList().GetSelectedThread().get();
    if (thread == NULL)
        return false;

    const bool append = true;
    const bool include_symbols = true;
    const bool include_inlines = false;
    SymbolContextList sc_list;
    const uint32_t count
        = process->GetTarget().GetImages().FindFunctions (ConstString ("mmap"),
                eFunctionNameTypeFull,
                include_symbols,
                include_inlines,
                append,
                sc_list);
    if (count > 0)
    {
        SymbolContext sc;
        if (sc_list.GetContextAtIndex(0, sc))
        {
            const uint32_t range_scope = eSymbolContextFunction | eSymbolContextSymbol;
            const bool use_inline_block_range = false;
            EvaluateExpressionOptions options;
            options.SetStopOthers(true);
            options.SetUnwindOnError(true);
            options.SetIgnoreBreakpoints(true);
            options.SetTryAllThreads(true);
            options.SetDebug (false);
            options.SetTimeoutUsec(500000);

            addr_t prot_arg, flags_arg = 0;
            if (prot == eMmapProtNone)
                prot_arg = PROT_NONE;
            else {
                prot_arg = 0;
                if (prot & eMmapProtExec)
                    prot_arg |= PROT_EXEC;
                if (prot & eMmapProtRead)
                    prot_arg |= PROT_READ;
                if (prot & eMmapProtWrite)
                    prot_arg |= PROT_WRITE;
            }

            const ArchSpec arch =  process->GetTarget().GetArchitecture();
            flags_arg = process->GetTarget().GetPlatform()->ConvertMmapFlagsToPlatform(arch,flags);

            AddressRange mmap_range;
            if (sc.GetAddressRange(range_scope, 0, use_inline_block_range, mmap_range))
            {
                ClangASTContext *clang_ast_context = process->GetTarget().GetScratchClangASTContext();
                CompilerType clang_void_ptr_type = clang_ast_context->GetBasicType(eBasicTypeVoid).GetPointerType();
                lldb::addr_t args[] = { addr, length, prot_arg, flags_arg, fd, offset };
                lldb::ThreadPlanSP call_plan_sp (new ThreadPlanCallFunction (*thread,
                                                 mmap_range.GetBaseAddress(),
                                                 clang_void_ptr_type,
                                                 args,
                                                 options));
                if (call_plan_sp)
                {
                    StreamFile error_strm;
                    // This plan is a utility plan, so set it to discard itself when done.
                    call_plan_sp->SetIsMasterPlan (true);
                    call_plan_sp->SetOkayToDiscard(true);

                    StackFrame *frame = thread->GetStackFrameAtIndex (0).get();
                    if (frame)
                    {
                        ExecutionContext exe_ctx;
                        frame->CalculateExecutionContext (exe_ctx);
                        ExpressionResults result = process->RunThreadPlan (exe_ctx,
                                                   call_plan_sp,
                                                   options,
                                                   error_strm);
                        if (result == eExpressionCompleted)
                        {

                            allocated_addr = call_plan_sp->GetReturnValueObject()->GetValueAsUnsigned(LLDB_INVALID_ADDRESS);
                            if (process->GetAddressByteSize() == 4)
                            {
                                if (allocated_addr == UINT32_MAX)
                                    return false;
                            }
                            else if (process->GetAddressByteSize() == 8)
                            {
                                if (allocated_addr == UINT64_MAX)
                                    return false;
                            }
                            return true;
                        }
                    }
                }
            }
        }
    }

    return false;
}