size_t Target::ReadMemoryFromFileCache (const Address& addr, void *dst, size_t dst_len, Error &error) { const Section *section = addr.GetSection(); if (section && section->GetModule()) { ObjectFile *objfile = section->GetModule()->GetObjectFile(); if (objfile) { size_t bytes_read = section->ReadSectionDataFromObjectFile (objfile, addr.GetOffset(), dst, dst_len); if (bytes_read > 0) return bytes_read; else error.SetErrorStringWithFormat("error reading data from section %s", section->GetName().GetCString()); } else { error.SetErrorString("address isn't from a object file"); } } else { error.SetErrorString("address doesn't contain a section that points to a section in a object file"); } return 0; }
lldb::SBAddress SBValue::GetAddress() { Address addr; if (m_opaque_sp) { Target* target = m_opaque_sp->GetUpdatePoint().GetTargetSP().get(); if (target) { lldb::addr_t value = LLDB_INVALID_ADDRESS; Mutex::Locker api_locker (target->GetAPIMutex()); const bool scalar_is_load_address = true; AddressType addr_type; value = m_opaque_sp->GetAddressOf(scalar_is_load_address, &addr_type); if (addr_type == eAddressTypeFile) { Module* module = m_opaque_sp->GetModule(); if (module) module->ResolveFileAddress(value, addr); } else if (addr_type == eAddressTypeLoad) { // no need to check the return value on this.. if it can actually do the resolve // addr will be in the form (section,offset), otherwise it will simply be returned // as (NULL, value) addr.SetLoadAddress(value, target); } } } LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) log->Printf ("SBValue(%p)::GetAddress () => (%s,%llu)", m_opaque_sp.get(), (addr.GetSection() ? addr.GetSection()->GetName().GetCString() : "NULL"), addr.GetOffset()); return SBAddress(new Address(addr)); }
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; }
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; }
lldb::SBAddress SBValue::GetAddress() { Address addr; ValueLocker locker; lldb::ValueObjectSP value_sp(GetSP(locker)); if (value_sp) { TargetSP target_sp (value_sp->GetTargetSP()); if (target_sp) { lldb::addr_t value = LLDB_INVALID_ADDRESS; const bool scalar_is_load_address = true; AddressType addr_type; value = value_sp->GetAddressOf(scalar_is_load_address, &addr_type); if (addr_type == eAddressTypeFile) { ModuleSP module_sp (value_sp->GetModule()); if (module_sp) module_sp->ResolveFileAddress(value, addr); } else if (addr_type == eAddressTypeLoad) { // no need to check the return value on this.. if it can actually do the resolve // addr will be in the form (section,offset), otherwise it will simply be returned // as (NULL, value) addr.SetLoadAddress(value, target_sp.get()); } } } Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); if (log) log->Printf ("SBValue(%p)::GetAddress () => (%s,%" PRIu64 ")", value_sp.get(), (addr.GetSection() ? addr.GetSection()->GetName().GetCString() : "NULL"), addr.GetOffset()); return SBAddress(new Address(addr)); }
bool AddressRange::ContainsFileAddress(const Address &addr) const { if (addr.GetSection() == m_base_addr.GetSection()) return (addr.GetOffset() - m_base_addr.GetOffset()) < GetByteSize(); addr_t file_base_addr = GetBaseAddress().GetFileAddress(); if (file_base_addr == LLDB_INVALID_ADDRESS) return false; addr_t file_addr = addr.GetFileAddress(); if (file_addr == LLDB_INVALID_ADDRESS) return false; if (file_base_addr <= file_addr) return (file_addr - file_base_addr) < GetByteSize(); return false; }
bool AddressRange::ContainsLoadAddress(const Address &addr, Target *target) const { if (addr.GetSection() == m_base_addr.GetSection()) return (addr.GetOffset() - m_base_addr.GetOffset()) < GetByteSize(); addr_t load_base_addr = GetBaseAddress().GetLoadAddress(target); if (load_base_addr == LLDB_INVALID_ADDRESS) return false; addr_t load_addr = addr.GetLoadAddress(target); if (load_addr == LLDB_INVALID_ADDRESS) return false; if (load_base_addr <= load_addr) return (load_addr - load_base_addr) < GetByteSize(); return false; }
uint32_t Block::GetRangeIndexContainingAddress (const Address& addr) { 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; return m_ranges.FindEntryIndexThatContains (offset); } } } return UINT32_MAX; }
// The operator != checks for exact inequality only (differing section, or // different offset) bool lldb_private::operator!=(const Address &a, const Address &rhs) { return a.GetOffset() != rhs.GetOffset() || a.GetSection() != rhs.GetSection(); }
// The operator == checks for exact equality only (same section, same offset) bool lldb_private::operator==(const Address &a, const Address &rhs) { return a.GetOffset() == rhs.GetOffset() && a.GetSection() == rhs.GetSection(); }
bool LineTable::FindLineEntryByAddress (const Address &so_addr, LineEntry& line_entry, uint32_t *index_ptr) { if (index_ptr != NULL ) *index_ptr = UINT32_MAX; bool success = false; uint32_t sect_idx = m_section_list.FindSectionIndex (so_addr.GetSection()); if (sect_idx != UINT32_MAX) { Entry search_entry; search_entry.sect_idx = sect_idx; search_entry.sect_offset = so_addr.GetOffset(); entry_collection::const_iterator begin_pos = m_entries.begin(); entry_collection::const_iterator end_pos = m_entries.end(); entry_collection::const_iterator pos = lower_bound(begin_pos, end_pos, search_entry, Entry::EntryAddressLessThan); if (pos != end_pos) { if (pos != begin_pos) { if (pos->sect_offset != search_entry.sect_offset) --pos; else if (pos->sect_offset == search_entry.sect_offset) { // If this is a termination entry, it should't match since // entries with the "is_terminal_entry" member set to true // are termination entries that define the range for the // previous entry. if (pos->is_terminal_entry) { // The matching entry is a terminal entry, so we skip // ahead to the next entry to see if there is another // entry following this one whose section/offset matches. ++pos; if (pos != end_pos) { if (pos->sect_offset != search_entry.sect_offset) pos = end_pos; } } if (pos != end_pos) { // While in the same section/offset backup to find the first // line entry that matches the address in case there are // multiple while (pos != begin_pos) { entry_collection::const_iterator prev_pos = pos - 1; if (prev_pos->sect_idx == search_entry.sect_idx && prev_pos->sect_offset == search_entry.sect_offset && prev_pos->is_terminal_entry == false) --pos; else break; } } } } if (pos != end_pos) { uint32_t match_idx = std::distance (begin_pos, pos); success = ConvertEntryAtIndexToLineEntry(match_idx, line_entry); if (index_ptr != NULL && success) *index_ptr = match_idx; } } } return success; }