diff options
author | Greg Clayton <gclayton@apple.com> | 2013-11-06 02:29:13 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2013-11-06 02:29:13 +0000 |
commit | cae5652838cae65f83aec74728cfdb360c26d42b (patch) | |
tree | 7bee06e68b0b79ed397321297f78ca623cc689c9 | |
parent | 37f5bb1b28216031ea905fc80e781c158bced5e4 (diff) | |
download | bcm5719-llvm-cae5652838cae65f83aec74728cfdb360c26d42b.tar.gz bcm5719-llvm-cae5652838cae65f83aec74728cfdb360c26d42b.zip |
Improve lldb_private::Address to detect when section was deleted and not return bogus values for GetLoadAddress() and GetFileAddress().
llvm-svn: 194120
-rw-r--r-- | lldb/include/lldb/Core/Address.h | 12 | ||||
-rw-r--r-- | lldb/source/Core/Address.cpp | 57 |
2 files changed, 54 insertions, 15 deletions
diff --git a/lldb/include/lldb/Core/Address.h b/lldb/include/lldb/Core/Address.h index 60cd4a86bd4..da7cc5c03d3 100644 --- a/lldb/include/lldb/Core/Address.h +++ b/lldb/include/lldb/Core/Address.h @@ -540,6 +540,18 @@ protected: //------------------------------------------------------------------ lldb::SectionWP m_section_wp; ///< The section for the address, can be NULL. std::atomic<lldb::addr_t> m_offset; ///< Offset into section if \a m_section_wp is valid... + + //------------------------------------------------------------------ + // Returns true if the m_section_wp once had a reference to a valid + // section shared pointer, but no longer does. This can happen if + // we have an address from a module that gets unloaded and deleted. + // This function should only be called if GetSection() returns an + // empty shared pointer and you want to know if this address used to + // have a valid section. + //------------------------------------------------------------------ + bool + SectionWasDeleted() const; + }; diff --git a/lldb/source/Core/Address.cpp b/lldb/source/Core/Address.cpp index 170b0c1ff1a..1e79f332ffc 100644 --- a/lldb/source/Core/Address.cpp +++ b/lldb/source/Core/Address.cpp @@ -280,6 +280,12 @@ Address::GetFileAddress () const // address by adding the file base address to our offset return sect_file_addr + m_offset; } + else if (SectionWasDeleted()) + { + // Used to have a valid section but it got deleted so the + // offset doesn't mean anything without the section + return LLDB_INVALID_ADDRESS; + } // No section, we just return the offset since it is the value in this case return m_offset; } @@ -288,25 +294,33 @@ addr_t Address::GetLoadAddress (Target *target) const { SectionSP section_sp (GetSection()); - if (!section_sp) - { - // No section, we just return the offset since it is the value in this case - return m_offset; - } - - if (target) + if (section_sp) { - addr_t sect_load_addr = section_sp->GetLoadBaseAddress (target); - - if (sect_load_addr != LLDB_INVALID_ADDRESS) + if (target) { - // We have a valid file range, so we can return the file based - // address by adding the file base address to our offset - return sect_load_addr + m_offset; + addr_t sect_load_addr = section_sp->GetLoadBaseAddress (target); + + if (sect_load_addr != LLDB_INVALID_ADDRESS) + { + // We have a valid file range, so we can return the file based + // address by adding the file base address to our offset + return sect_load_addr + m_offset; + } } } - // The section isn't resolved or no process was supplied so we can't - // return a valid file address. + else if (SectionWasDeleted()) + { + // Used to have a valid section but it got deleted so the + // offset doesn't mean anything without the section + return LLDB_INVALID_ADDRESS; + } + else + { + // We don't have a section so the offset is the load address + return m_offset; + } + // The section isn't resolved or an invalid target was passed in + // so we can't return a valid load address. return LLDB_INVALID_ADDRESS; } @@ -766,6 +780,19 @@ Address::Dump (Stream *s, ExecutionContextScope *exe_scope, DumpStyle style, Dum return true; } +bool +Address::SectionWasDeleted() const +{ + lldb::SectionWP empty_section_wp; + + // If either call to "std::weak_ptr::owner_before(...) value returns true, this + // indicates that m_section_wp once contained (possibly still does) a reference + // to a valid shared pointer. This helps us know if we had a valid reference to + // a section which is now invalid because the module it was in was unloaded/deleted, + // or if the address doesn't have a valid reference to a section. + return empty_section_wp.owner_before(m_section_wp) || m_section_wp.owner_before(empty_section_wp); +} + uint32_t Address::CalculateSymbolContext (SymbolContext *sc, uint32_t resolve_scope) const { |