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; }
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); }
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; }
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; }
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; }
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; }
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 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; }
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; }
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; }
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); } }
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) { }
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); }
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) { }
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; }
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; }
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 ); }
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() ); }
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; }
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; }
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; }
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; }
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 ); }
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 ); }
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 ); }
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); }
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; }