Esempio n. 1
0
bool
Block::GetRangeContainingAddress (const Address& addr, AddressRange &range)
{
    Function *function = CalculateSymbolContextFunction();
    if (function)
    {
        const AddressRange &func_range = function->GetAddressRange();
        if (addr.GetSection() == func_range.GetBaseAddress().GetSection())
        {
            const addr_t addr_offset = addr.GetOffset();
            const addr_t func_offset = func_range.GetBaseAddress().GetOffset();
            if (addr_offset >= func_offset && addr_offset < func_offset + func_range.GetByteSize())
            {
                addr_t offset = addr_offset - func_offset;
                
                const Range *range_ptr = m_ranges.FindEntryThatContains (offset);

                if (range_ptr)
                {
                    range.GetBaseAddress() = func_range.GetBaseAddress();
                    range.GetBaseAddress().SetOffset(func_offset + range_ptr->GetRangeBase());
                    range.SetByteSize(range_ptr->GetByteSize());
                    return true;
                }
            }
        }
    }
    range.Clear();
    return false;
}
Esempio n. 2
0
bool
Disassembler::Disassemble
(
    Debugger &debugger,
    const ArchSpec &arch,
    const ExecutionContext &exe_ctx,
    uint32_t num_mixed_context_lines,
    bool show_bytes,
    Stream &strm
)
{
    AddressRange range;
    if (exe_ctx.frame)
    {
        SymbolContext sc(exe_ctx.frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
        if (sc.function)
        {
            range = sc.function->GetAddressRange();
        }
        else if (sc.symbol && sc.symbol->GetAddressRangePtr())
        {
            range = *sc.symbol->GetAddressRangePtr();
        }
        else
        {
            range.GetBaseAddress() = exe_ctx.frame->GetPC();
        }

        if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
            range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE);
    }

    return Disassemble(debugger, arch, exe_ctx, range, num_mixed_context_lines, show_bytes, strm);
}
Esempio n. 3
0
lldb::DisassemblerSP
Disassembler::DisassembleRange
(
    const ArchSpec &arch,
    const char *plugin_name,
    const char *flavor,
    const ExecutionContext &exe_ctx,
    const AddressRange &range,
    bool prefer_file_cache
)
{
    lldb::DisassemblerSP disasm_sp;
    if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid())
    {
        disasm_sp = Disassembler::FindPluginForTarget(exe_ctx.GetTargetSP(), arch, flavor, plugin_name);

        if (disasm_sp)
        {
            size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, NULL, prefer_file_cache);
            if (bytes_disassembled == 0)
                disasm_sp.reset();
        }
    }
    return disasm_sp;
}
Esempio n. 4
0
bool
SymbolContext::GetAddressRange (uint32_t scope, AddressRange &range) const
{
    if ((scope & eSymbolContextLineEntry) && line_entry.IsValid())
    {
        range = line_entry.range;
        return true;
    }
    else if ((scope & eSymbolContextFunction) && function != NULL)
    {
        range = function->GetAddressRange();
        return true;
    }
    else if ((scope & eSymbolContextSymbol) && symbol != NULL && symbol->GetAddressRangePtr())
    {
        range = *symbol->GetAddressRangePtr();

        if (range.GetByteSize() == 0)
        {
            if (module_sp)
            {
                ObjectFile *objfile = module_sp->GetObjectFile();
                if (objfile)
                {
                    Symtab *symtab = objfile->GetSymtab();
                    if (symtab)
                        range.SetByteSize(symtab->CalculateSymbolSize (symbol));
                }
            }
        }
        return true;
    }
    range.Clear();
    return false;
}
Esempio n. 5
0
FWObject* AddressObjectMaker::createAddressRange(ObjectSignature &sig)
{
    FWObject *obj = findMatchingObject(sig);
    if (obj) return obj;

    QString addr1 = sig.address_range_start;
    QString addr2 = sig.address_range_end;
    QString name = QString("range-%1-%2").arg(addr1).arg(addr2);

    AddressRange *ar = AddressRange::cast(
        ObjectMaker::createObject(AddressRange::TYPENAME, name.toStdString()));

    try
    {
        ar->setRangeStart( InetAddr(addr1.toStdString()) );
    } catch (FWException &ex)
    {
        error_tracker->registerError(
            QString("Error converting address '%1'").arg(addr1));
    }

    try
    {
        ar->setRangeEnd( InetAddr(addr2.toStdString()) );
    } catch (FWException &ex)
    {
        error_tracker->registerError(
            QString("Error converting address '%1'").arg(addr2));
    }

    return ar;
}
Esempio n. 6
0
void Dropper::handleInternalDrag( QDropEvent* dropEvent, AbstractByteArrayView* sourceByteArrayView )
{
    // get drag origin
    AddressRange selection = sourceByteArrayView->tableRanges()->removeSelection();

    ByteArrayTableCursor* tableCursor = mByteArrayView->tableCursor();
    AbstractByteArrayModel* byteArrayModel = mByteArrayView->byteArrayModel();

    Address insertIndex = tableCursor->realIndex();

    // is this a move?
    if( dropEvent->proposedAction() == Qt::MoveAction )
    {
        // ignore the copy hold in the event but only move
        Address newCursorIndex;
        // need to swap?
        if( selection.end() < insertIndex )
        {
            newCursorIndex = insertIndex;
            const Address firstIndex = selection.start();
            selection.set( selection.nextBehindEnd(), insertIndex-1 );
            insertIndex = firstIndex;
        }
        else
            newCursorIndex = insertIndex + selection.width();

        const bool success = byteArrayModel->swap( insertIndex, selection );
        if( success )
        {
            tableCursor->gotoCIndex( newCursorIndex );
            emit mByteArrayView->cursorPositionChanged( tableCursor->realIndex() );
        }
    }
    // is a copy
    else
    {
        // TODO: should this be a method of AbstractByteArrayModel, to reuse piece data?

        // get data
        const QByteArray data =
            dropEvent->mimeData()->data( QLatin1String(DropperOctetStreamFormatName) );

        if( !data.isEmpty() )
        {
            if( mByteArrayView->isOverwriteMode() )
            {
                const Size length = mByteArrayView->layout()->length();
                if( !tableCursor->isBehind() && length > 0 )
                {
                    AddressRange overwriteRange = AddressRange::fromWidth( insertIndex, data.size() );
                    overwriteRange.restrictEndTo( length-1 );
                    if( overwriteRange.isValid() )
                        byteArrayModel->replace( overwriteRange, reinterpret_cast<const Byte*>(data.constData()), overwriteRange.width() );
                }
            }
            else
                byteArrayModel->insert( insertIndex, reinterpret_cast<const Byte*>(data.constData()), data.size() );
        }
    }
}
ThreadPlanSP ThreadPlanShouldStopHere::DefaultStepFromHereCallback(
    ThreadPlan *current_plan, Flags &flags, FrameComparison operation,
    void *baton) {
  const bool stop_others = false;
  const size_t frame_index = 0;
  ThreadPlanSP return_plan_sp;
  // If we are stepping through code at line number 0, then we need to step over
  // this range.  Otherwise
  // we will step out.
  Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_STEP));

  StackFrame *frame = current_plan->GetThread().GetStackFrameAtIndex(0).get();
  if (!frame)
    return return_plan_sp;
  SymbolContext sc;
  sc = frame->GetSymbolContext(eSymbolContextLineEntry | eSymbolContextSymbol);

  if (sc.line_entry.line == 0) {
    AddressRange range = sc.line_entry.range;

    // If the whole function is marked line 0 just step out, that's easier &
    // faster than continuing
    // to step through it.
    bool just_step_out = false;
    if (sc.symbol && sc.symbol->ValueIsAddress()) {
      Address symbol_end = sc.symbol->GetAddress();
      symbol_end.Slide(sc.symbol->GetByteSize() - 1);
      if (range.ContainsFileAddress(sc.symbol->GetAddress()) &&
          range.ContainsFileAddress(symbol_end)) {
        if (log)
          log->Printf("Stopped in a function with only line 0 lines, just "
                      "stepping out.");
        just_step_out = true;
      }
    }
    if (!just_step_out) {
      if (log)
        log->Printf("ThreadPlanShouldStopHere::DefaultStepFromHereCallback "
                    "Queueing StepInRange plan to step through line 0 code.");

      return_plan_sp = current_plan->GetThread().QueueThreadPlanForStepInRange(
          false, range, sc, NULL, eOnlyDuringStepping, eLazyBoolCalculate,
          eLazyBoolNo);
    }
  }

  if (!return_plan_sp)
    return_plan_sp =
        current_plan->GetThread().QueueThreadPlanForStepOutNoShouldStop(
            false, nullptr, true, stop_others, eVoteNo, eVoteNoOpinion,
            frame_index, true);
  return return_plan_sp;
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
bool
SymbolContext::GetAddressRange (uint32_t scope, 
                                uint32_t range_idx, 
                                bool use_inline_block_range,
                                AddressRange &range) const
{
    if ((scope & eSymbolContextLineEntry) && line_entry.IsValid())
    {
        range = line_entry.range;
        return true;
    }
    
    if ((scope & eSymbolContextBlock) && (block != NULL))
    {
        if (use_inline_block_range)
        {
            Block *inline_block = block->GetContainingInlinedBlock();
            if (inline_block)
                return inline_block->GetRangeAtIndex (range_idx, range);
        }
        else
        {
            return block->GetRangeAtIndex (range_idx, range);
        }
    }

    if ((scope & eSymbolContextFunction) && (function != NULL))
    {
        if (range_idx == 0)
        {
            range = function->GetAddressRange();
            return true;
        }            
    } 
    
    if ((scope & eSymbolContextSymbol) && (symbol != NULL))
    {
        if (range_idx == 0)
        {
            if (symbol->ValueIsAddress())
            {
                range.GetBaseAddress() = symbol->GetAddress();
                range.SetByteSize (symbol->GetByteSize());
                return true;
            }
        }
    }
    range.Clear();
    return false;
}
Esempio n. 10
0
size_t
Disassembler::ParseInstructions (const ExecutionContext *exe_ctx,
                                 const AddressRange &range,
                                 Stream *error_strm_ptr,
                                 bool prefer_file_cache)
{
    if (exe_ctx)
    {
        Target *target = exe_ctx->GetTargetPtr();
        const addr_t byte_size = range.GetByteSize();
        if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid())
            return 0;

        DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
        DataBufferSP data_sp(heap_buffer);

        Error error;
        lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
        const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(),
                                                      prefer_file_cache, 
                                                      heap_buffer->GetBytes(), 
                                                      heap_buffer->GetByteSize(), 
                                                      error,
                                                      &load_addr);
        
        if (bytes_read > 0)
        {
            if (bytes_read != heap_buffer->GetByteSize())
                heap_buffer->SetByteSize (bytes_read);
            DataExtractor data (data_sp, 
                                m_arch.GetByteOrder(),
                                m_arch.GetAddressByteSize());
            const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS;
            return DecodeInstructions (range.GetBaseAddress(), data, 0, UINT32_MAX, false, data_from_file);
        }
        else if (error_strm_ptr)
        {
            const char *error_cstr = error.AsCString();
            if (error_cstr)
            {
                error_strm_ptr->Printf("error: %s\n", error_cstr);
            }
        }
    }
    else if (error_strm_ptr)
    {
        error_strm_ptr->PutCString("error: invalid execution context\n");
    }
    return 0;
}
Esempio n. 11
0
lldb::SBAddress
SBBlock::GetRangeStartAddress (uint32_t idx)
{
    lldb::SBAddress sb_addr;
    if (m_opaque_ptr)
    {
        AddressRange range;
        if (m_opaque_ptr->GetRangeAtIndex(idx, range))
        {
            sb_addr.ref() = range.GetBaseAddress();
        }
    }
    return sb_addr;
}
Esempio n. 12
0
lldb::SBAddress
SBBlock::GetRangeEndAddress (uint32_t idx)
{
    lldb::SBAddress sb_addr;
    if (m_opaque_ptr)
    {
        AddressRange range;
        if (m_opaque_ptr->GetRangeAtIndex(idx, range))
        {
            sb_addr.ref() = range.GetBaseAddress();
            sb_addr.ref().Slide(range.GetByteSize());
        }
    }
    return sb_addr;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void OverflowSamples::visit(const AddressRange& range,
                            const OverflowSampleVisitor& visitor) const
{
    std::vector<boost::uint64_t> samples(1);
    bool terminate = false;
    
    for (std::map<Address, boost::uint64_t>::const_iterator
             i = dm_samples.lower_bound(range.begin()),
             i_end = dm_samples.upper_bound(range.end());
         !terminate && (i != i_end);
         ++i)
    {
        samples[0] = i->second;
        terminate |= !visitor(i->first, samples);
    }
}
Esempio n. 14
0
Symbol::Symbol
(
    uint32_t symID,
    const char *name,
    bool name_is_mangled,
    SymbolType type,
    bool external,
    bool is_debug,
    bool is_trampoline,
    bool is_artificial,
    const AddressRange &range,
    bool size_is_valid,
    uint32_t flags
) :
    SymbolContextScope (),
    m_uid (symID),
    m_type_data (0),
    m_type_data_resolved (false),
    m_is_synthetic (is_artificial),
    m_is_debug (is_debug),
    m_is_external (external),
    m_size_is_sibling (false),
    m_size_is_synthesized (false),
    m_size_is_valid (size_is_valid || range.GetByteSize() > 0),
    m_demangled_is_synthesized (false),
    m_type (type),
    m_mangled (ConstString(name), name_is_mangled),
    m_addr_range (range),
    m_flags (flags)
{
}
Esempio n. 15
0
bool UnwindAssemblyInstEmulation::GetNonCallSiteUnwindPlanFromAssembly(
    AddressRange &range, Thread &thread, UnwindPlan &unwind_plan) {
  std::vector<uint8_t> function_text(range.GetByteSize());
  ProcessSP process_sp(thread.GetProcess());
  if (process_sp) {
    Error error;
    const bool prefer_file_cache = true;
    if (process_sp->GetTarget().ReadMemory(
            range.GetBaseAddress(), prefer_file_cache, function_text.data(),
            range.GetByteSize(), error) != range.GetByteSize()) {
      return false;
    }
  }
  return GetNonCallSiteUnwindPlanFromAssembly(
      range, function_text.data(), function_text.size(), unwind_plan);
}
Esempio n. 16
0
Symbol::Symbol
(
    uint32_t symID,
    const Mangled &mangled,
    SymbolType type,
    bool external,
    bool is_debug,
    bool is_trampoline,
    bool is_artificial,
    const AddressRange &range,
    bool size_is_valid,
    bool contains_linker_annotations,
    uint32_t flags
) :
    SymbolContextScope (),
    m_uid (symID),
    m_type_data (0),
    m_type_data_resolved (false),
    m_is_synthetic (is_artificial),
    m_is_debug (is_debug),
    m_is_external (external),
    m_size_is_sibling (false),
    m_size_is_synthesized (false),
    m_size_is_valid (size_is_valid || range.GetByteSize() > 0),
    m_demangled_is_synthesized (false),
    m_contains_linker_annotations (contains_linker_annotations),
    m_type (type),
    m_mangled (mangled),
    m_addr_range (range),
    m_flags (flags)
{
}
Esempio n. 17
0
bool
Block::GetRangeAtIndex (uint32_t range_idx, AddressRange &range)
{
    if (range_idx < m_ranges.GetSize())
    {
        Function *function = CalculateSymbolContextFunction();
        if (function)
        {
            const Range &vm_range = m_ranges.GetEntryRef(range_idx);
            range.GetBaseAddress() = function->GetAddressRange().GetBaseAddress();
            range.GetBaseAddress().Slide(vm_range.GetRangeBase ());
            range.SetByteSize (vm_range.GetByteSize());
            return true;
        }
    }
    return false;
}
Esempio n. 18
0
bool AddressRange::Extend(const AddressRange &rhs_range) {
  addr_t lhs_end_addr = GetBaseAddress().GetFileAddress() + GetByteSize();
  addr_t rhs_base_addr = rhs_range.GetBaseAddress().GetFileAddress();

  if (!ContainsFileAddress(rhs_range.GetBaseAddress()) &&
      lhs_end_addr != rhs_base_addr)
    // The ranges don't intersect at all on the right side of this range.
    return false;

  addr_t rhs_end_addr = rhs_base_addr + rhs_range.GetByteSize();
  if (lhs_end_addr >= rhs_end_addr)
    // The rhs range totally overlaps this one, nothing to add.
    return false;

  m_byte_size += rhs_end_addr - lhs_end_addr;
  return true;
}
bool UnwindAssembly_x86::FirstNonPrologueInsn(
    AddressRange &func, const ExecutionContext &exe_ctx,
    Address &first_non_prologue_insn) {

  if (!func.GetBaseAddress().IsValid())
    return false;

  Target *target = exe_ctx.GetTargetPtr();
  if (target == nullptr)
    return false;

  if (m_assembly_inspection_engine == nullptr)
    return false;

  const bool prefer_file_cache = true;
  std::vector<uint8_t> function_text(func.GetByteSize());
  Status error;
  if (target->ReadMemory(func.GetBaseAddress(), prefer_file_cache,
                         function_text.data(), func.GetByteSize(),
                         error) == func.GetByteSize()) {
    size_t offset;
    if (m_assembly_inspection_engine->FindFirstNonPrologueInstruction(
            function_text.data(), func.GetByteSize(), offset)) {
      first_non_prologue_insn = func.GetBaseAddress();
      first_non_prologue_insn.Slide(offset);
    }
    return true;
  }
  return false;
}
Esempio n. 20
0
void AddressRangeTest::testSetGetWidth()
{
    AddressRange addressRange;
    // end, width by width
    addressRange.setStart( Start );
    addressRange.setEndByWidth( Width );
    QCOMPARE( addressRange.end(), End );
    QCOMPARE( addressRange.width(), Width );
    // start, width by width
    addressRange.setEnd( End );
    addressRange.setStartByWidth( Width );
    QCOMPARE( addressRange.start(), Start );
    QCOMPARE( addressRange.width(), Width );
}
Esempio n. 21
0
void AddressRangeTest::testSplitAtLocal()
{
    AddressRange addressRange( Start, End );

    // split at start
    AddressRange splitAddressRange = addressRange.splitAtLocal( 0 );
    QVERIFY( !addressRange.isValid() );
    QCOMPARE( splitAddressRange.start(), Start );
    QCOMPARE( splitAddressRange.end(),   End );

    // split at one after start
    addressRange.set( Start, End );
    splitAddressRange = addressRange.splitAtLocal( 1 );
    QCOMPARE( addressRange.start(), Start );
    QCOMPARE( addressRange.end(), Start );
    QCOMPARE( splitAddressRange.start(), Start+1 );
    QCOMPARE( splitAddressRange.end(),   End );

    // split at mid
    const Address Mid = Width/2;
    addressRange.set( Start, End );
    splitAddressRange = addressRange.splitAtLocal( Mid );
    QCOMPARE( addressRange.start(), Start );
    QCOMPARE( addressRange.end(), Start+Mid-1 );
    QCOMPARE( splitAddressRange.start(), Start+Mid );
    QCOMPARE( splitAddressRange.end(),   End );

    // split at one before end
    addressRange.set( Start, End );
    splitAddressRange = addressRange.splitAtLocal( Width-1 );
    QCOMPARE( addressRange.start(), Start );
    QCOMPARE( addressRange.end(), End-1 );
    QCOMPARE( splitAddressRange.start(), End );
    QCOMPARE( splitAddressRange.end(),   End );

    // split at start so the split is the full
    addressRange.set( Start, End );
    splitAddressRange = addressRange.splitAtLocal( Width );
    QCOMPARE( addressRange.start(), Start );
    QCOMPARE( addressRange.end(), End );
    QVERIFY( !splitAddressRange.isValid() );
}
Esempio n. 22
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;
}
Esempio n. 23
0
size_t
Disassembler::ParseInstructions
(
    const ExecutionContext *exe_ctx,
    const AddressRange &range,
    DataExtractor& data
)
{
    Target *target = exe_ctx->target;

    const addr_t byte_size = range.GetByteSize();
    if (target == NULL || byte_size == 0 || !range.GetBaseAddress().IsValid())
        return 0;

    DataBufferHeap *heap_buffer = new DataBufferHeap (byte_size, '\0');
    DataBufferSP data_sp(heap_buffer);

    Error error;
    const size_t bytes_read = target->ReadMemory (range.GetBaseAddress(), heap_buffer->GetBytes(), heap_buffer->GetByteSize(), error);
    
    if (bytes_read > 0)
    {
        if (bytes_read != heap_buffer->GetByteSize())
            heap_buffer->SetByteSize (bytes_read);

        data.SetData(data_sp);
        if (exe_ctx->process)
        {
            data.SetByteOrder(exe_ctx->process->GetByteOrder());
            data.SetAddressByteSize(exe_ctx->process->GetAddressByteSize());
        }
        else
        {
            data.SetByteOrder(target->GetArchitecture().GetDefaultEndian());
            data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
        }
        return DecodeInstructions (data, 0, UINT32_MAX);
    }

    return 0;
}
Esempio n. 24
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;
}
Esempio n. 25
0
lldb::DisassemblerSP
Disassembler::DisassembleRange
(
    const ArchSpec &arch,
    const char *plugin_name,
    const ExecutionContext &exe_ctx,
    const AddressRange &range
)
{
    lldb::DisassemblerSP disasm_sp;
    if (range.GetByteSize() > 0 && range.GetBaseAddress().IsValid())
    {
        disasm_sp.reset (Disassembler::FindPlugin(arch, plugin_name));

        if (disasm_sp)
        {
            size_t bytes_disassembled = disasm_sp->ParseInstructions (&exe_ctx, range, NULL);
            if (bytes_disassembled == 0)
                disasm_sp.reset();
        }
    }
    return disasm_sp;
}
Esempio n. 26
0
void AddressRangeTest::testLocalRange()
{
    AddressRange addressRange( Start, End );

    AddressRange localRange = addressRange.localRange( AddressRange(Start,End) );
    QCOMPARE( localRange.start(), 0 );
    QCOMPARE( localRange.end(), Width-1 );

    localRange = addressRange.localRange( AddressRange(Start+1,End) );
    QCOMPARE( localRange.start(), 1 );
    QCOMPARE( localRange.end(), Width-1 );

    localRange = addressRange.localRange( AddressRange(Start,End-1) );
    QCOMPARE( localRange.start(), 0 );
    QCOMPARE( localRange.end(), Width-2 );

    localRange = addressRange.localRange( AddressRange(Start+1,End-1) );
    QCOMPARE( localRange.start(), 1 );
    QCOMPARE( localRange.end(), Width-2 );
}
Esempio n. 27
0
void AddressRangeTest::testSubRange()
{
    AddressRange addressRange( Start, End );

    AddressRange subRange = addressRange.subRange( AddressRange::fromWidth(Width) );
    QCOMPARE( subRange.start(), Start );
    QCOMPARE( subRange.end(), End );

    subRange = addressRange.subRange( AddressRange(1,Width-1) );
    QCOMPARE( subRange.start(), Start+1 );
    QCOMPARE( subRange.end(), End );

    subRange = addressRange.subRange( AddressRange(0,Width-2) );
    QCOMPARE( subRange.start(), Start );
    QCOMPARE( subRange.end(), End-1 );

    subRange = addressRange.subRange( AddressRange(1,Width-2) );
    QCOMPARE( subRange.start(), Start+1 );
    QCOMPARE( subRange.end(), End-1 );
}
Esempio n. 28
0
void AddressRangeTest::testConstructorByWidth()
{
    AddressRange addressRange = AddressRange::fromWidth( Start, Width );

    QCOMPARE( addressRange.start(), Start );
    QCOMPARE( addressRange.end(), End );
    QCOMPARE( addressRange.width(), Width );

    addressRange = AddressRange::fromWidth( Width );

    QCOMPARE( addressRange.start(), 0 );
    QCOMPARE( addressRange.end(), Width-1 );
    QCOMPARE( addressRange.width(), Width );
}
Esempio n. 29
0
bool
Disassembler::Disassemble
(
    Debugger &debugger,
    const ArchSpec &arch,
    const char *plugin_name,
    const char *flavor,
    const ExecutionContext &exe_ctx,
    uint32_t num_instructions,
    uint32_t num_mixed_context_lines,
    uint32_t options,
    Stream &strm
)
{
    AddressRange range;
    StackFrame *frame = exe_ctx.GetFramePtr();
    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();
        }

        if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
            range.SetByteSize (DEFAULT_DISASM_BYTE_SIZE);
    }

    return Disassemble (debugger, 
                        arch, 
                        plugin_name,
                        flavor,
                        exe_ctx, 
                        range, 
                        num_instructions, 
                        num_mixed_context_lines, 
                        options, 
                        strm);
}
Esempio n. 30
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;
}