[Lldb-commits] [lldb] r176454 - <rdar://problem/13338643>
Greg Clayton
gclayton at apple.com
Mon Mar 4 13:46:17 PST 2013
Author: gclayton
Date: Mon Mar 4 15:46:16 2013
New Revision: 176454
URL: http://llvm.org/viewvc/llvm-project?rev=176454&view=rev
Log:
<rdar://problem/13338643>
DWARF with .o files now uses 40-60% less memory!
Big fixes include:
- Change line table internal representation to contain "file addresses". Since each line table is owned by a compile unit that is owned by a module, it makes address translation into lldb_private::Address easy to do when needed.
- Removed linked address members/methods from lldb_private::Section and lldb_private::Address
- lldb_private::LineTable can now relink itself using a FileRangeMap to make it easier to re-link line tables in the future
- Added ObjectFile::ClearSymtab() so that we can get rid of the object file symbol tables after we parse them once since they are not needed and kept memory allocated for no reason
- Moved the m_sections_ap (std::auto_ptr to section list) and m_symtab_ap (std::auto_ptr to the lldb_private::Symtab) out of each of the ObjectFile subclasses and put it into lldb_private::ObjectFile.
- Changed how the debug map is parsed and stored to be able to:
- Lazily parse the debug map for each object file
- not require the address map for a .o file until debug information is linked for a .o file
Modified:
lldb/trunk/include/lldb/Core/Address.h
lldb/trunk/include/lldb/Core/RangeMap.h
lldb/trunk/include/lldb/Core/Section.h
lldb/trunk/include/lldb/Expression/DWARFExpression.h
lldb/trunk/include/lldb/Symbol/LineTable.h
lldb/trunk/include/lldb/Symbol/ObjectFile.h
lldb/trunk/source/Core/Address.cpp
lldb/trunk/source/Core/Section.cpp
lldb/trunk/source/Expression/DWARFExpression.cpp
lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.h
lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h
lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp
lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
lldb/trunk/source/Symbol/Function.cpp
lldb/trunk/source/Symbol/LineTable.cpp
lldb/trunk/source/Symbol/ObjectFile.cpp
lldb/trunk/source/Symbol/Symtab.cpp
Modified: lldb/trunk/include/lldb/Core/Address.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Address.h?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Address.h (original)
+++ lldb/trunk/include/lldb/Core/Address.h Mon Mar 4 15:46:16 2013
@@ -393,12 +393,6 @@ public:
bool
ResolveAddressUsingFileSections (lldb::addr_t addr, const SectionList *sections);
- bool
- IsLinkedAddress () const;
-
- void
- ResolveLinkedAddress ();
-
//------------------------------------------------------------------
/// Set the address to represent \a load_addr.
///
Modified: lldb/trunk/include/lldb/Core/RangeMap.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/RangeMap.h?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/RangeMap.h (original)
+++ lldb/trunk/include/lldb/Core/RangeMap.h Mon Mar 4 15:46:16 2013
@@ -10,6 +10,8 @@
#ifndef liblldb_RangeMap_h_
#define liblldb_RangeMap_h_
+#include <vector>
+
#include "lldb/lldb-private.h"
#include "llvm/ADT/SmallVector.h"
@@ -171,7 +173,6 @@ namespace lldb_private {
typedef B BaseType;
typedef S SizeType;
typedef Range<B,S> Entry;
- //typedef std::vector<Entry> Collection;
typedef llvm::SmallVector<Entry, N> Collection;
RangeArray () :
@@ -445,90 +446,48 @@ namespace lldb_private {
Collection m_entries;
};
- //----------------------------------------------------------------------
- // A simple range with data class where you get to define the type of
- // the range base "B", the type used for the range byte size "S", and
- // the type for the associated data "T".
- //----------------------------------------------------------------------
- template <typename B, typename S, typename T>
- struct RangeData : public Range<B,S>
+ template <typename B, typename S>
+ class RangeVector
{
- typedef T DataType;
-
- DataType data;
-
- RangeData () :
- Range<B,S> (),
- data ()
- {
- }
+ public:
+ typedef B BaseType;
+ typedef S SizeType;
+ typedef Range<B,S> Entry;
+ typedef std::vector<Entry> Collection;
- RangeData (B base, S size, DataType d) :
- Range<B,S> (base, size),
- data (d)
+ RangeVector () :
+ m_entries ()
{
}
- bool
- operator < (const RangeData &rhs) const
+ ~RangeVector()
{
- if (this->base == rhs.base)
- {
- if (this->size == rhs.size)
- return this->data < rhs.data;
- else
- return this->size < rhs.size;
- }
- return this->base < rhs.base;
}
- bool
- operator == (const RangeData &rhs) const
+ void
+ Append (const Entry &entry)
{
- return this->GetRangeBase() == rhs.GetRangeBase() &&
- this->GetByteSize() == rhs.GetByteSize() &&
- this->data == rhs.data;
+ m_entries.push_back (entry);
}
bool
- operator != (const RangeData &rhs) const
- {
- return this->GetRangeBase() != rhs.GetRangeBase() ||
- this->GetByteSize() != rhs.GetByteSize() ||
- this->data != rhs.data;
- }
- };
-
- template <typename B, typename S, typename T, unsigned N>
- class RangeDataArray
- {
- public:
- typedef RangeData<B,S,T> Entry;
- //typedef std::vector<Entry> Collection;
- typedef llvm::SmallVector<Entry, N> Collection;
-
-
- RangeDataArray ()
- {
- }
-
- ~RangeDataArray()
+ RemoveEntrtAtIndex (uint32_t idx)
{
+ if (idx < m_entries.size())
+ {
+ m_entries.erase (m_entries.begin() + idx);
+ return true;
+ }
+ return false;
}
void
- Append (const Entry &entry)
- {
- m_entries.push_back (entry);
- }
-
- void
Sort ()
{
if (m_entries.size() > 1)
std::stable_sort (m_entries.begin(), m_entries.end());
}
-
+
#ifdef ASSERT_RANGEMAP_ARE_SORTED
bool
IsSorted () const
@@ -544,47 +503,86 @@ namespace lldb_private {
return true;
}
#endif
-
void
- CombineConsecutiveEntriesWithEqualData ()
+ CombineConsecutiveRanges ()
{
#ifdef ASSERT_RANGEMAP_ARE_SORTED
assert (IsSorted());
#endif
- typename Collection::iterator pos;
- typename Collection::iterator end;
- typename Collection::iterator prev;
- bool can_combine = false;
- // First we determine if we can combine any of the Entry objects so we
- // don't end up allocating and making a new collection for no reason
- for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
+ // Can't combine if ranges if we have zero or one range
+ if (m_entries.size() > 1)
{
- if (prev != end && prev->data == pos->data)
+ // The list should be sorted prior to calling this function
+ typename Collection::iterator pos;
+ typename Collection::iterator end;
+ typename Collection::iterator prev;
+ bool can_combine = false;
+ // First we determine if we can combine any of the Entry objects so we
+ // don't end up allocating and making a new collection for no reason
+ for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
{
- can_combine = true;
- break;
+ if (prev != end && prev->Overlap(*pos))
+ {
+ can_combine = true;
+ break;
+ }
}
- }
-
- // We we can combine at least one entry, then we make a new collection
- // and populate it accordingly, and then swap it into place.
- if (can_combine)
- {
- Collection minimal_ranges;
- for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
+
+ // We we can combine at least one entry, then we make a new collection
+ // and populate it accordingly, and then swap it into place.
+ if (can_combine)
{
- if (prev != end && prev->data == pos->data)
- minimal_ranges.back().SetRangeEnd (pos->GetRangeEnd());
- else
- minimal_ranges.push_back (*pos);
+ Collection minimal_ranges;
+ for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
+ {
+ if (prev != end && prev->Overlap(*pos))
+ minimal_ranges.back().SetRangeEnd (std::max<BaseType>(prev->GetRangeEnd(), pos->GetRangeEnd()));
+ else
+ minimal_ranges.push_back (*pos);
+ }
+ // Use the swap technique in case our new vector is much smaller.
+ // We must swap when using the STL because std::vector objects never
+ // release or reduce the memory once it has been allocated/reserved.
+ m_entries.swap (minimal_ranges);
}
- // Use the swap technique in case our new vector is much smaller.
- // We must swap when using the STL because std::vector objects never
- // release or reduce the memory once it has been allocated/reserved.
- m_entries.swap (minimal_ranges);
}
}
-
+
+
+ BaseType
+ GetMinRangeBase (BaseType fail_value) const
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ if (m_entries.empty())
+ return fail_value;
+ // m_entries must be sorted, so if we aren't empty, we grab the
+ // first range's base
+ return m_entries.front().GetRangeBase();
+ }
+
+ BaseType
+ GetMaxRangeEnd (BaseType fail_value) const
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ if (m_entries.empty())
+ return fail_value;
+ // m_entries must be sorted, so if we aren't empty, we grab the
+ // last range's end
+ return m_entries.back().GetRangeEnd();
+ }
+
+ void
+ Slide (BaseType slide)
+ {
+ typename Collection::iterator pos, end;
+ for (pos = m_entries.begin(), end = m_entries.end(); pos != end; ++pos)
+ pos->Slide (slide);
+ }
+
void
Clear ()
{
@@ -610,14 +608,30 @@ namespace lldb_private {
return &m_entries[i];
return NULL;
}
-
+
// Clients must ensure that "i" is a valid index prior to calling this function
const Entry &
GetEntryRef (size_t i) const
{
return m_entries[i];
}
-
+
+ Entry *
+ Back()
+ {
+ if (m_entries.empty())
+ return NULL;
+ return &m_entries.back();
+ }
+
+ const Entry *
+ Back() const
+ {
+ if (m_entries.empty())
+ return NULL;
+ return &m_entries.back();
+ }
+
static bool
BaseLessThan (const Entry& lhs, const Entry& rhs)
{
@@ -630,7 +644,7 @@ namespace lldb_private {
#ifdef ASSERT_RANGEMAP_ARE_SORTED
assert (IsSorted());
#endif
- if ( !m_entries.empty() )
+ if (!m_entries.empty())
{
Entry entry (addr, 1);
typename Collection::const_iterator begin = m_entries.begin();
@@ -650,62 +664,30 @@ namespace lldb_private {
}
return UINT32_MAX;
}
-
- Entry *
- FindEntryThatContains (B addr)
- {
-#ifdef ASSERT_RANGEMAP_ARE_SORTED
- assert (IsSorted());
-#endif
- if ( !m_entries.empty() )
- {
- Entry entry;
- entry.SetRangeBase(addr);
- entry.SetByteSize(1);
- typename Collection::iterator begin = m_entries.begin();
- typename Collection::iterator end = m_entries.end();
- typename Collection::iterator pos = std::lower_bound (begin, end, entry, BaseLessThan);
-
- if (pos != end && pos->Contains(addr))
- {
- return &(*pos);
- }
- else if (pos != begin)
- {
- --pos;
- if (pos->Contains(addr))
- {
- return &(*pos);
- }
- }
- }
- return NULL;
- }
+
const Entry *
FindEntryThatContains (B addr) const
{
#ifdef ASSERT_RANGEMAP_ARE_SORTED
assert (IsSorted());
#endif
- if ( !m_entries.empty() )
+ if (!m_entries.empty())
{
- Entry entry;
- entry.SetRangeBase(addr);
- entry.SetByteSize(1);
+ Entry entry (addr, 1);
typename Collection::const_iterator begin = m_entries.begin();
typename Collection::const_iterator end = m_entries.end();
typename Collection::const_iterator pos = std::lower_bound (begin, end, entry, BaseLessThan);
if (pos != end && pos->Contains(addr))
{
- return &(*pos);
+ return &(*pos);
}
else if (pos != begin)
{
--pos;
if (pos->Contains(addr))
{
- return &(*pos);
+ return &(*pos);
}
}
}
@@ -718,7 +700,7 @@ namespace lldb_private {
#ifdef ASSERT_RANGEMAP_ARE_SORTED
assert (IsSorted());
#endif
- if ( !m_entries.empty() )
+ if (!m_entries.empty())
{
typename Collection::const_iterator begin = m_entries.begin();
typename Collection::const_iterator end = m_entries.end();
@@ -726,32 +708,336 @@ namespace lldb_private {
if (pos != end && pos->Contains(range))
{
- return &(*pos);
+ return &(*pos);
}
else if (pos != begin)
{
--pos;
if (pos->Contains(range))
{
- return &(*pos);
+ return &(*pos);
}
}
}
return NULL;
}
- Entry *
- Back()
- {
- if (!m_entries.empty())
- return &m_entries.back();
- return NULL;
- }
+ protected:
+ Collection m_entries;
+ };
- const Entry *
- Back() const
- {
- if (!m_entries.empty())
+ //----------------------------------------------------------------------
+ // A simple range with data class where you get to define the type of
+ // the range base "B", the type used for the range byte size "S", and
+ // the type for the associated data "T".
+ //----------------------------------------------------------------------
+ template <typename B, typename S, typename T>
+ struct RangeData : public Range<B,S>
+ {
+ typedef T DataType;
+
+ DataType data;
+
+ RangeData () :
+ Range<B,S> (),
+ data ()
+ {
+ }
+
+ RangeData (B base, S size) :
+ Range<B,S> (base, size),
+ data ()
+ {
+ }
+
+ RangeData (B base, S size, DataType d) :
+ Range<B,S> (base, size),
+ data (d)
+ {
+ }
+
+ bool
+ operator < (const RangeData &rhs) const
+ {
+ if (this->base == rhs.base)
+ {
+ if (this->size == rhs.size)
+ return this->data < rhs.data;
+ else
+ return this->size < rhs.size;
+ }
+ return this->base < rhs.base;
+ }
+
+ bool
+ operator == (const RangeData &rhs) const
+ {
+ return this->GetRangeBase() == rhs.GetRangeBase() &&
+ this->GetByteSize() == rhs.GetByteSize() &&
+ this->data == rhs.data;
+ }
+
+ bool
+ operator != (const RangeData &rhs) const
+ {
+ return this->GetRangeBase() != rhs.GetRangeBase() ||
+ this->GetByteSize() != rhs.GetByteSize() ||
+ this->data != rhs.data;
+ }
+ };
+
+ template <typename B, typename S, typename T, unsigned N>
+ class RangeDataArray
+ {
+ public:
+ typedef RangeData<B,S,T> Entry;
+ typedef llvm::SmallVector<Entry, N> Collection;
+
+
+ RangeDataArray ()
+ {
+ }
+
+ ~RangeDataArray()
+ {
+ }
+
+ void
+ Append (const Entry &entry)
+ {
+ m_entries.push_back (entry);
+ }
+
+ void
+ Sort ()
+ {
+ if (m_entries.size() > 1)
+ std::stable_sort (m_entries.begin(), m_entries.end());
+ }
+
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ bool
+ IsSorted () const
+ {
+ typename Collection::const_iterator pos, end, prev;
+ // First we determine if we can combine any of the Entry objects so we
+ // don't end up allocating and making a new collection for no reason
+ for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
+ {
+ if (prev != end && *pos < *prev)
+ return false;
+ }
+ return true;
+ }
+#endif
+
+ void
+ CombineConsecutiveEntriesWithEqualData ()
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ typename Collection::iterator pos;
+ typename Collection::iterator end;
+ typename Collection::iterator prev;
+ bool can_combine = false;
+ // First we determine if we can combine any of the Entry objects so we
+ // don't end up allocating and making a new collection for no reason
+ for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
+ {
+ if (prev != end && prev->data == pos->data)
+ {
+ can_combine = true;
+ break;
+ }
+ }
+
+ // We we can combine at least one entry, then we make a new collection
+ // and populate it accordingly, and then swap it into place.
+ if (can_combine)
+ {
+ Collection minimal_ranges;
+ for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
+ {
+ if (prev != end && prev->data == pos->data)
+ minimal_ranges.back().SetRangeEnd (pos->GetRangeEnd());
+ else
+ minimal_ranges.push_back (*pos);
+ }
+ // Use the swap technique in case our new vector is much smaller.
+ // We must swap when using the STL because std::vector objects never
+ // release or reduce the memory once it has been allocated/reserved.
+ m_entries.swap (minimal_ranges);
+ }
+ }
+
+ void
+ Clear ()
+ {
+ m_entries.clear();
+ }
+
+ bool
+ IsEmpty () const
+ {
+ return m_entries.empty();
+ }
+
+ size_t
+ GetSize () const
+ {
+ return m_entries.size();
+ }
+
+ const Entry *
+ GetEntryAtIndex (size_t i) const
+ {
+ if (i<m_entries.size())
+ return &m_entries[i];
+ return NULL;
+ }
+
+ // Clients must ensure that "i" is a valid index prior to calling this function
+ const Entry &
+ GetEntryRef (size_t i) const
+ {
+ return m_entries[i];
+ }
+
+ static bool
+ BaseLessThan (const Entry& lhs, const Entry& rhs)
+ {
+ return lhs.GetRangeBase() < rhs.GetRangeBase();
+ }
+
+ uint32_t
+ FindEntryIndexThatContains (B addr) const
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ if ( !m_entries.empty() )
+ {
+ Entry entry (addr, 1);
+ typename Collection::const_iterator begin = m_entries.begin();
+ typename Collection::const_iterator end = m_entries.end();
+ typename Collection::const_iterator pos = std::lower_bound (begin, end, entry, BaseLessThan);
+
+ if (pos != end && pos->Contains(addr))
+ {
+ return std::distance (begin, pos);
+ }
+ else if (pos != begin)
+ {
+ --pos;
+ if (pos->Contains(addr))
+ return std::distance (begin, pos);
+ }
+ }
+ return UINT32_MAX;
+ }
+
+ Entry *
+ FindEntryThatContains (B addr)
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ if ( !m_entries.empty() )
+ {
+ Entry entry;
+ entry.SetRangeBase(addr);
+ entry.SetByteSize(1);
+ typename Collection::iterator begin = m_entries.begin();
+ typename Collection::iterator end = m_entries.end();
+ typename Collection::iterator pos = std::lower_bound (begin, end, entry, BaseLessThan);
+
+ if (pos != end && pos->Contains(addr))
+ {
+ return &(*pos);
+ }
+ else if (pos != begin)
+ {
+ --pos;
+ if (pos->Contains(addr))
+ {
+ return &(*pos);
+ }
+ }
+ }
+ return NULL;
+ }
+ const Entry *
+ FindEntryThatContains (B addr) const
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ if ( !m_entries.empty() )
+ {
+ Entry entry;
+ entry.SetRangeBase(addr);
+ entry.SetByteSize(1);
+ typename Collection::const_iterator begin = m_entries.begin();
+ typename Collection::const_iterator end = m_entries.end();
+ typename Collection::const_iterator pos = std::lower_bound (begin, end, entry, BaseLessThan);
+
+ if (pos != end && pos->Contains(addr))
+ {
+ return &(*pos);
+ }
+ else if (pos != begin)
+ {
+ --pos;
+ if (pos->Contains(addr))
+ {
+ return &(*pos);
+ }
+ }
+ }
+ return NULL;
+ }
+
+ const Entry *
+ FindEntryThatContains (const Entry &range) const
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ if ( !m_entries.empty() )
+ {
+ typename Collection::const_iterator begin = m_entries.begin();
+ typename Collection::const_iterator end = m_entries.end();
+ typename Collection::const_iterator pos = std::lower_bound (begin, end, range, BaseLessThan);
+
+ if (pos != end && pos->Contains(range))
+ {
+ return &(*pos);
+ }
+ else if (pos != begin)
+ {
+ --pos;
+ if (pos->Contains(range))
+ {
+ return &(*pos);
+ }
+ }
+ }
+ return NULL;
+ }
+
+ Entry *
+ Back()
+ {
+ if (!m_entries.empty())
+ return &m_entries.back();
+ return NULL;
+ }
+
+ const Entry *
+ Back() const
+ {
+ if (!m_entries.empty())
return &m_entries.back();
return NULL;
}
@@ -759,7 +1045,268 @@ namespace lldb_private {
protected:
Collection m_entries;
};
+
+ // Same as RangeDataArray, but uses std::vector as to not
+ // require static storage of N items in the class itself
+ template <typename B, typename S, typename T>
+ class RangeDataVector
+ {
+ public:
+ typedef RangeData<B,S,T> Entry;
+ typedef std::vector<Entry> Collection;
+
+ RangeDataVector ()
+ {
+ }
+
+ ~RangeDataVector()
+ {
+ }
+
+ void
+ Append (const Entry &entry)
+ {
+ m_entries.push_back (entry);
+ }
+
+ void
+ Sort ()
+ {
+ if (m_entries.size() > 1)
+ std::stable_sort (m_entries.begin(), m_entries.end());
+ }
+
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ bool
+ IsSorted () const
+ {
+ typename Collection::const_iterator pos, end, prev;
+ // First we determine if we can combine any of the Entry objects so we
+ // don't end up allocating and making a new collection for no reason
+ for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
+ {
+ if (prev != end && *pos < *prev)
+ return false;
+ }
+ return true;
+ }
+#endif
+
+ void
+ CombineConsecutiveEntriesWithEqualData ()
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ typename Collection::iterator pos;
+ typename Collection::iterator end;
+ typename Collection::iterator prev;
+ bool can_combine = false;
+ // First we determine if we can combine any of the Entry objects so we
+ // don't end up allocating and making a new collection for no reason
+ for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
+ {
+ if (prev != end && prev->data == pos->data)
+ {
+ can_combine = true;
+ break;
+ }
+ }
+
+ // We we can combine at least one entry, then we make a new collection
+ // and populate it accordingly, and then swap it into place.
+ if (can_combine)
+ {
+ Collection minimal_ranges;
+ for (pos = m_entries.begin(), end = m_entries.end(), prev = end; pos != end; prev = pos++)
+ {
+ if (prev != end && prev->data == pos->data)
+ minimal_ranges.back().SetRangeEnd (pos->GetRangeEnd());
+ else
+ minimal_ranges.push_back (*pos);
+ }
+ // Use the swap technique in case our new vector is much smaller.
+ // We must swap when using the STL because std::vector objects never
+ // release or reduce the memory once it has been allocated/reserved.
+ m_entries.swap (minimal_ranges);
+ }
+ }
+
+ void
+ Clear ()
+ {
+ m_entries.clear();
+ }
+
+ bool
+ IsEmpty () const
+ {
+ return m_entries.empty();
+ }
+
+ size_t
+ GetSize () const
+ {
+ return m_entries.size();
+ }
+
+ const Entry *
+ GetEntryAtIndex (size_t i) const
+ {
+ if (i<m_entries.size())
+ return &m_entries[i];
+ return NULL;
+ }
+
+ // Clients must ensure that "i" is a valid index prior to calling this function
+ const Entry &
+ GetEntryRef (size_t i) const
+ {
+ return m_entries[i];
+ }
+
+ static bool
+ BaseLessThan (const Entry& lhs, const Entry& rhs)
+ {
+ return lhs.GetRangeBase() < rhs.GetRangeBase();
+ }
+
+ uint32_t
+ FindEntryIndexThatContains (B addr) const
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ if ( !m_entries.empty() )
+ {
+ Entry entry (addr, 1);
+ typename Collection::const_iterator begin = m_entries.begin();
+ typename Collection::const_iterator end = m_entries.end();
+ typename Collection::const_iterator pos = std::lower_bound (begin, end, entry, BaseLessThan);
+
+ if (pos != end && pos->Contains(addr))
+ {
+ return std::distance (begin, pos);
+ }
+ else if (pos != begin)
+ {
+ --pos;
+ if (pos->Contains(addr))
+ return std::distance (begin, pos);
+ }
+ }
+ return UINT32_MAX;
+ }
+
+ Entry *
+ FindEntryThatContains (B addr)
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ if ( !m_entries.empty() )
+ {
+ Entry entry;
+ entry.SetRangeBase(addr);
+ entry.SetByteSize(1);
+ typename Collection::iterator begin = m_entries.begin();
+ typename Collection::iterator end = m_entries.end();
+ typename Collection::iterator pos = std::lower_bound (begin, end, entry, BaseLessThan);
+
+ if (pos != end && pos->Contains(addr))
+ {
+ return &(*pos);
+ }
+ else if (pos != begin)
+ {
+ --pos;
+ if (pos->Contains(addr))
+ {
+ return &(*pos);
+ }
+ }
+ }
+ return NULL;
+ }
+ const Entry *
+ FindEntryThatContains (B addr) const
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ if ( !m_entries.empty() )
+ {
+ Entry entry;
+ entry.SetRangeBase(addr);
+ entry.SetByteSize(1);
+ typename Collection::const_iterator begin = m_entries.begin();
+ typename Collection::const_iterator end = m_entries.end();
+ typename Collection::const_iterator pos = std::lower_bound (begin, end, entry, BaseLessThan);
+
+ if (pos != end && pos->Contains(addr))
+ {
+ return &(*pos);
+ }
+ else if (pos != begin)
+ {
+ --pos;
+ if (pos->Contains(addr))
+ {
+ return &(*pos);
+ }
+ }
+ }
+ return NULL;
+ }
+
+ const Entry *
+ FindEntryThatContains (const Entry &range) const
+ {
+#ifdef ASSERT_RANGEMAP_ARE_SORTED
+ assert (IsSorted());
+#endif
+ if ( !m_entries.empty() )
+ {
+ typename Collection::const_iterator begin = m_entries.begin();
+ typename Collection::const_iterator end = m_entries.end();
+ typename Collection::const_iterator pos = std::lower_bound (begin, end, range, BaseLessThan);
+ if (pos != end && pos->Contains(range))
+ {
+ return &(*pos);
+ }
+ else if (pos != begin)
+ {
+ --pos;
+ if (pos->Contains(range))
+ {
+ return &(*pos);
+ }
+ }
+ }
+ return NULL;
+ }
+
+ Entry *
+ Back()
+ {
+ if (!m_entries.empty())
+ return &m_entries.back();
+ return NULL;
+ }
+
+ const Entry *
+ Back() const
+ {
+ if (!m_entries.empty())
+ return &m_entries.back();
+ return NULL;
+ }
+
+ protected:
+ Collection m_entries;
+ };
+
//----------------------------------------------------------------------
// A simple range with data class where you get to define the type of
@@ -816,7 +1363,6 @@ namespace lldb_private {
{
public:
typedef AddressData<B,T> Entry;
- //typedef std::vector<Entry> Collection;
typedef llvm::SmallVector<Entry, N> Collection;
Modified: lldb/trunk/include/lldb/Core/Section.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Core/Section.h?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Core/Section.h (original)
+++ lldb/trunk/include/lldb/Core/Section.h Mon Mar 4 15:46:16 2013
@@ -61,9 +61,6 @@ public:
lldb::SectionSP
FindSectionContainingFileAddress (lldb::addr_t addr, uint32_t depth = UINT32_MAX) const;
- lldb::SectionSP
- FindSectionContainingLinkedFileAddress (lldb::addr_t vm_addr, uint32_t depth) const;
-
bool
GetSectionData (const DataExtractor& module_data, DataExtractor& section_data) const;
@@ -93,16 +90,6 @@ public:
protected:
collection m_sections;
-
- typedef RangeDataArray<uint64_t, uint64_t, collection::size_type, 1> SectionRangeCache;
- mutable SectionRangeCache m_range_cache;
-#ifdef LLDB_CONFIGURATION_DEBUG
- mutable bool m_finalized;
-#endif
-
- void BuildRangeCache() const;
-
- void InvalidateRangeCache() const;
};
@@ -120,8 +107,8 @@ public:
lldb::SectionType sect_type,
lldb::addr_t file_vm_addr,
lldb::addr_t vm_size,
- uint64_t file_offset,
- uint64_t file_size,
+ lldb::offset_t file_offset,
+ lldb::offset_t file_size,
uint32_t flags);
// Create a section that is a child of parent_section_sp
@@ -132,8 +119,8 @@ public:
lldb::SectionType sect_type,
lldb::addr_t file_vm_addr,
lldb::addr_t vm_size,
- uint64_t file_offset,
- uint64_t file_size,
+ lldb::offset_t file_offset,
+ lldb::offset_t file_size,
uint32_t flags);
~Section ();
@@ -168,26 +155,26 @@ public:
bool
ResolveContainedAddress (lldb::addr_t offset, Address &so_addr) const;
- uint64_t
+ lldb::offset_t
GetFileOffset () const
{
return m_file_offset;
}
void
- SetFileOffset (uint64_t file_offset)
+ SetFileOffset (lldb::offset_t file_offset)
{
m_file_offset = file_offset;
}
- uint64_t
+ lldb::offset_t
GetFileSize () const
{
return m_file_size;
}
void
- SetFileSize (uint64_t file_size)
+ SetFileSize (lldb::offset_t file_size)
{
m_file_size = file_size;
}
@@ -239,31 +226,14 @@ public:
IsDescendant (const Section *section);
const ConstString&
- GetName () const;
-
- bool
- Slide (lldb::addr_t slide_amount, bool slide_children);
-
- void
- SetLinkedLocation (const lldb::SectionSP &linked_section_sp, uint64_t linked_offset);
-
- bool
- ContainsLinkedFileAddress (lldb::addr_t vm_addr) const;
-
- lldb::SectionSP
- GetLinkedSection () const
+ GetName () const
{
- return m_linked_section_wp.lock();
+ return m_name;
}
- uint64_t
- GetLinkedOffset () const
- {
- return m_linked_offset;
- }
+ bool
+ Slide (lldb::addr_t slide_amount, bool slide_children);
- lldb::addr_t
- GetLinkedFileAddress () const;
lldb::SectionType
GetType () const
@@ -304,8 +274,8 @@ protected:
lldb::addr_t m_file_addr; // The absolute file virtual address range of this section if m_parent == NULL,
// offset from parent file virtual address if m_parent != NULL
lldb::addr_t m_byte_size; // Size in bytes that this section will occupy in memory at runtime
- uint64_t m_file_offset; // Object file offset (if any)
- uint64_t m_file_size; // Object file size (can be smaller than m_byte_size for zero filled sections...)
+ lldb::offset_t m_file_offset; // Object file offset (if any)
+ lldb::offset_t m_file_size; // Object file size (can be smaller than m_byte_size for zero filled sections...)
SectionList m_children; // Child sections
bool m_fake:1, // If true, then this section only can contain the address if one of its
// children contains an address. This allows for gaps between the children
@@ -313,8 +283,6 @@ protected:
// hits unless the children contain the address.
m_encrypted:1, // Set to true if the contents are encrypted
m_thread_specific:1;// This section is thread specific
- lldb::SectionWP m_linked_section_wp;
- uint64_t m_linked_offset;
private:
DISALLOW_COPY_AND_ASSIGN (Section);
};
Modified: lldb/trunk/include/lldb/Expression/DWARFExpression.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Expression/DWARFExpression.h?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Expression/DWARFExpression.h (original)
+++ lldb/trunk/include/lldb/Expression/DWARFExpression.h Mon Mar 4 15:46:16 2013
@@ -139,21 +139,20 @@ public:
/// us detect if a variable is a global or static variable since
/// there is no other indication from DWARF debug info.
///
- /// @param[in] file_addr
- /// The file address to search for in the location.
+ /// @param[in] op_addr_idx
+ /// The DW_OP_addr index to retrieve in case there is more than
+ /// one DW_OP_addr opcode in the location byte stream.
///
/// @param[out] error
/// If the location stream contains unknown DW_OP opcodes or the
/// data is missing, \a error will be set to \b true.
///
/// @return
- /// True if IsLocationList() is false and the \a file_addr was
- /// is contained in a DW_OP_addr location opcode or if \a file_addr
- /// was invalid and there are any DW_OP_addr opcodes, false
- /// otherwise.
+ /// LLDB_INVALID_ADDRESS if the location doesn't contain a
+ /// DW_OP_addr for \a op_addr_idx, otherwise a valid file address
//------------------------------------------------------------------
- bool
- LocationContains_DW_OP_addr (lldb::addr_t file_addr, bool &error) const;
+ lldb::addr_t
+ GetLocation_DW_OP_addr (uint32_t op_addr_idx, bool &error) const;
bool
Update_DW_OP_addr (lldb::addr_t file_addr);
Modified: lldb/trunk/include/lldb/Symbol/LineTable.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/LineTable.h?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/LineTable.h (original)
+++ lldb/trunk/include/lldb/Symbol/LineTable.h Mon Mar 4 15:46:16 2013
@@ -75,8 +75,7 @@ public:
// Called when you can't guarantee the addresses are in increasing order
void
- InsertLineEntry (const lldb::SectionSP& section_sp,
- lldb::addr_t section_offset,
+ InsertLineEntry (lldb::addr_t file_addr,
uint32_t line,
uint16_t column,
uint16_t file_idx,
@@ -94,8 +93,7 @@ public:
// inserted in this line table.
void
AppendLineEntryToSequence (LineSequence* sequence,
- const lldb::SectionSP& section_sp,
- lldb::addr_t section_offset,
+ lldb::addr_t file_addr,
uint32_t line,
uint16_t column,
uint16_t file_idx,
@@ -253,15 +251,29 @@ public:
size_t
GetContiguousFileAddressRanges (FileAddressRanges &file_ranges, bool append);
+ //------------------------------------------------------------------
+ /// Given a file range link map, relink the current line table
+ /// and return a fixed up line table.
+ ///
+ /// @param[out] file_range_map
+ /// A collection of file ranges that maps to new file ranges
+ /// that will be used when linking the line table.
+ ///
+ /// @return
+ /// A new line table if at least one line table entry was able
+ /// to be mapped.
+ //------------------------------------------------------------------
+ typedef RangeDataVector<lldb::addr_t, lldb::addr_t, lldb::addr_t> FileRangeMap;
+
+ LineTable *
+ LinkLineTable (const FileRangeMap &file_range_map);
+
protected:
struct Entry
{
- enum { kInvalidSectIdx = UINT32_MAX };
-
Entry () :
- sect_idx (kInvalidSectIdx),
- sect_offset (0),
+ file_addr (LLDB_INVALID_ADDRESS),
line (0),
column (0),
file_idx (0),
@@ -273,8 +285,7 @@ protected:
{
}
- Entry ( uint32_t _sect_idx,
- lldb::addr_t _sect_offset,
+ Entry ( lldb::addr_t _file_addr,
uint32_t _line,
uint16_t _column,
uint16_t _file_idx,
@@ -283,8 +294,7 @@ protected:
bool _is_prologue_end,
bool _is_epilogue_begin,
bool _is_terminal_entry) :
- sect_idx (_sect_idx),
- sect_offset (_sect_offset),
+ file_addr (_file_addr),
line (_line),
column (_column),
file_idx (_file_idx),
@@ -294,10 +304,6 @@ protected:
is_epilogue_begin (_is_epilogue_begin),
is_terminal_entry (_is_terminal_entry)
{
- // We have reserved 32 bits for the section offset which should
- // be enough, but if it isn't then we need to make m_section_offset
- // bigger
- assert(_sect_offset <= UINT32_MAX);
}
int
@@ -306,8 +312,7 @@ protected:
void
Clear ()
{
- sect_idx = kInvalidSectIdx;
- sect_offset = 0;
+ file_addr = LLDB_INVALID_ADDRESS;
line = 0;
column = 0;
file_idx = 0;
@@ -323,7 +328,7 @@ protected:
{
// Compare the sections before calling
#define SCALAR_COMPARE(a,b) if (a < b) return -1; if (a > b) return +1
- SCALAR_COMPARE (lhs.sect_offset, rhs.sect_offset);
+ SCALAR_COMPARE (lhs.file_addr, rhs.file_addr);
SCALAR_COMPARE (lhs.line, rhs.line);
SCALAR_COMPARE (lhs.column, rhs.column);
SCALAR_COMPARE (lhs.is_start_of_statement, rhs.is_start_of_statement);
@@ -350,16 +355,13 @@ protected:
static bool EntryAddressLessThan (const Entry& lhs, const Entry& rhs)
{
- if (lhs.sect_idx == rhs.sect_idx)
- return lhs.sect_offset < rhs.sect_offset;
- return lhs.sect_idx < rhs.sect_idx;
+ return lhs.file_addr < rhs.file_addr;
}
//------------------------------------------------------------------
// Member variables.
//------------------------------------------------------------------
- uint32_t sect_idx; ///< The section index for this line entry.
- uint32_t sect_offset; ///< The offset into the section for this line entry.
+ lldb::addr_t file_addr; ///< The file address for this line entry
uint32_t line; ///< The source line number, or zero if there is no line number information.
uint16_t column; ///< The column number of the source line, or zero if there is no column information.
uint16_t file_idx:11, ///< The file index into CompileUnit's file table, or zero if there is no file information.
@@ -386,7 +388,6 @@ protected:
// Member variables.
//------------------------------------------------------------------
CompileUnit* m_comp_unit; ///< The compile unit that this line table belongs to.
- SectionList m_section_list; ///< The list of sections that at least one of the line entries exists in.
entry_collection m_entries; ///< The collection of line entries in this line table.
//------------------------------------------------------------------
@@ -406,14 +407,12 @@ protected:
virtual void
Clear();
- entry_collection m_seq_entries; ///< The collection of line entries in this sequence.
+ entry_collection m_entries; ///< The collection of line entries in this sequence.
};
bool
ConvertEntryAtIndexToLineEntry (uint32_t idx, LineEntry &line_entry);
- lldb_private::Section *
- GetSectionForEntryIndex (uint32_t idx);
private:
DISALLOW_COPY_AND_ASSIGN (LineTable);
};
Modified: lldb/trunk/include/lldb/Symbol/ObjectFile.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/include/lldb/Symbol/ObjectFile.h?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/include/lldb/Symbol/ObjectFile.h (original)
+++ lldb/trunk/include/lldb/Symbol/ObjectFile.h Mon Mar 4 15:46:16 2013
@@ -351,6 +351,17 @@ public:
GetSymtab () = 0;
//------------------------------------------------------------------
+ /// Frees the symbol table.
+ ///
+ /// This function should only be used when an object file is
+ ///
+ /// @return
+ /// The symbol table for this object file.
+ //------------------------------------------------------------------
+ virtual void
+ ClearSymtab ();
+
+ //------------------------------------------------------------------
/// Gets the UUID for this object file.
///
/// If the object file format contains a UUID, the value should be
@@ -610,6 +621,8 @@ protected:
lldb_private::UnwindTable m_unwind_table; /// < Table of FuncUnwinders objects created for this ObjectFile's functions
lldb::ProcessWP m_process_wp;
const lldb::addr_t m_memory_addr;
+ std::auto_ptr<lldb_private::SectionList> m_sections_ap;
+ std::auto_ptr<lldb_private::Symtab> m_symtab_ap;
//------------------------------------------------------------------
/// Sets the architecture for a module. At present the architecture
Modified: lldb/trunk/source/Core/Address.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Address.cpp?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Core/Address.cpp (original)
+++ lldb/trunk/source/Core/Address.cpp Mon Mar 4 15:46:16 2013
@@ -1015,29 +1015,6 @@ lldb_private::operator!= (const Address&
a.GetOffset() != rhs.GetOffset();
}
-bool
-Address::IsLinkedAddress () const
-{
- SectionSP section_sp (GetSection());
- return section_sp && section_sp->GetLinkedSection();
-}
-
-
-void
-Address::ResolveLinkedAddress ()
-{
- SectionSP section_sp (GetSection());
- if (section_sp)
- {
- SectionSP linked_section_sp (section_sp->GetLinkedSection());
- if (linked_section_sp)
- {
- m_offset += section_sp->GetLinkedOffset();
- m_section_wp = linked_section_sp;
- }
- }
-}
-
AddressClass
Address::GetAddressClass () const
{
Modified: lldb/trunk/source/Core/Section.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Core/Section.cpp?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Core/Section.cpp (original)
+++ lldb/trunk/source/Core/Section.cpp Mon Mar 4 15:46:16 2013
@@ -21,8 +21,8 @@ Section::Section (const ModuleSP &module
SectionType sect_type,
addr_t file_addr,
addr_t byte_size,
- uint64_t file_offset,
- uint64_t file_size,
+ lldb::offset_t file_offset,
+ lldb::offset_t file_size,
uint32_t flags) :
ModuleChild (module_sp),
UserID (sect_id),
@@ -37,9 +37,7 @@ Section::Section (const ModuleSP &module
m_children (),
m_fake (false),
m_encrypted (false),
- m_thread_specific (false),
- m_linked_section_wp(),
- m_linked_offset (0)
+ m_thread_specific (false)
{
// printf ("Section::Section(%p): module=%p, sect_id = 0x%16.16" PRIx64 ", addr=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), file [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), flags = 0x%8.8x, name = %s\n",
// this, module_sp.get(), sect_id, file_addr, file_addr + byte_size, file_offset, file_offset + file_size, flags, name.GetCString());
@@ -52,8 +50,8 @@ Section::Section (const lldb::SectionSP
SectionType sect_type,
addr_t file_addr,
addr_t byte_size,
- uint64_t file_offset,
- uint64_t file_size,
+ lldb::offset_t file_offset,
+ lldb::offset_t file_size,
uint32_t flags) :
ModuleChild (module_sp),
UserID (sect_id),
@@ -68,9 +66,7 @@ Section::Section (const lldb::SectionSP
m_children (),
m_fake (false),
m_encrypted (false),
- m_thread_specific (false),
- m_linked_section_wp(),
- m_linked_offset (0)
+ m_thread_specific (false)
{
// printf ("Section::Section(%p): module=%p, sect_id = 0x%16.16" PRIx64 ", addr=[0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), file [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 "), flags = 0x%8.8x, name = %s.%s\n",
// this, module_sp.get(), sect_id, file_addr, file_addr + byte_size, file_offset, file_offset + file_size, flags, parent_section_sp->GetName().GetCString(), name.GetCString());
@@ -83,15 +79,6 @@ Section::~Section()
// printf ("Section::~Section(%p)\n", this);
}
-const ConstString&
-Section::GetName() const
-{
- SectionSP linked_section_sp (m_linked_section_wp.lock());
- if (linked_section_sp)
- return linked_section_sp->GetName();
- return m_name;
-}
-
addr_t
Section::GetFileAddress () const
{
@@ -119,43 +106,21 @@ Section::GetOffset () const
return 0;
}
-
-addr_t
-Section::GetLinkedFileAddress () const
-{
- SectionSP linked_section_sp (m_linked_section_wp.lock());
- if (linked_section_sp)
- return linked_section_sp->GetFileAddress() + m_linked_offset;
- return LLDB_INVALID_ADDRESS;
-}
-
-
addr_t
Section::GetLoadBaseAddress (Target *target) const
{
addr_t load_base_addr = LLDB_INVALID_ADDRESS;
- SectionSP linked_section_sp (m_linked_section_wp.lock());
- if (linked_section_sp)
+ SectionSP parent_sp (GetParent ());
+ if (parent_sp)
{
- load_base_addr = linked_section_sp->GetLoadBaseAddress(target);
+ load_base_addr = parent_sp->GetLoadBaseAddress (target);
if (load_base_addr != LLDB_INVALID_ADDRESS)
- load_base_addr += m_linked_offset;
+ load_base_addr += GetOffset();
}
else
{
- SectionSP parent_sp (GetParent ());
- if (parent_sp)
- {
- load_base_addr = parent_sp->GetLoadBaseAddress (target);
- if (load_base_addr != LLDB_INVALID_ADDRESS)
- load_base_addr += GetOffset();
- }
- else
- {
- load_base_addr = target->GetSectionLoadList().GetSectionLoadAddress (const_cast<Section *>(this)->shared_from_this());
- }
+ load_base_addr = target->GetSectionLoadList().GetSectionLoadAddress (const_cast<Section *>(this)->shared_from_this());
}
-
return load_base_addr;
}
@@ -174,22 +139,13 @@ Section::ResolveContainedAddress (addr_t
return child_section->ResolveContainedAddress (offset - child_offset, so_addr);
}
}
- SectionSP linked_section_sp (m_linked_section_wp.lock());
- if (linked_section_sp)
- {
- so_addr.SetOffset(m_linked_offset + offset);
- so_addr.SetSection(linked_section_sp);
- }
- else
- {
- so_addr.SetOffset(offset);
- so_addr.SetSection(const_cast<Section *>(this)->shared_from_this());
-
+ so_addr.SetOffset(offset);
+ so_addr.SetSection(const_cast<Section *>(this)->shared_from_this());
+
#ifdef LLDB_CONFIGURATION_DEBUG
- // For debug builds, ensure that there are no orphaned (i.e., moduleless) sections.
- assert(GetModule().get());
+ // For debug builds, ensure that there are no orphaned (i.e., moduleless) sections.
+ assert(GetModule().get());
#endif
- }
return true;
}
@@ -208,21 +164,6 @@ Section::ContainsFileAddress (addr_t vm_
return false;
}
-bool
-Section::ContainsLinkedFileAddress (addr_t vm_addr) const
-{
- const addr_t linked_file_addr = GetLinkedFileAddress();
- if (linked_file_addr != LLDB_INVALID_ADDRESS)
- {
- if (linked_file_addr <= vm_addr)
- {
- const addr_t offset = vm_addr - linked_file_addr;
- return offset < GetByteSize();
- }
- }
- return false;
-}
-
int
Section::Compare (const Section& a, const Section& b)
{
@@ -261,12 +202,11 @@ Section::Dump (Stream *s, Target *target
bool resolved = true;
addr_t addr = LLDB_INVALID_ADDRESS;
- SectionSP linked_section_sp (m_linked_section_wp.lock());
if (GetByteSize() == 0)
s->Printf("%39s", "");
else
{
- if (target && linked_section_sp.get() == NULL)
+ if (target)
addr = GetLoadBaseAddress (target);
if (addr == LLDB_INVALID_ADDRESS)
@@ -286,35 +226,6 @@ Section::Dump (Stream *s, Target *target
s->EOL();
- if (linked_section_sp)
- {
- addr = LLDB_INVALID_ADDRESS;
- resolved = true;
- if (target)
- {
- addr = linked_section_sp->GetLoadBaseAddress(target);
- if (addr != LLDB_INVALID_ADDRESS)
- addr += m_linked_offset;
- }
-
- if (addr == LLDB_INVALID_ADDRESS)
- {
- if (target)
- resolved = false;
- addr = linked_section_sp->GetFileAddress() + m_linked_offset;
- }
-
- int indent = 28 + s->GetIndentLevel();
- s->Printf("%*.*s", indent, indent, "");
- VMRange linked_range(addr, addr + m_byte_size);
- linked_range.Dump (s, 0);
- indent = 3 * (sizeof(uint32_t) * 2 + 2 + 1) + 1;
- s->Printf("%c%*.*s", resolved ? ' ' : '*', indent, indent, "");
-
- linked_section_sp->DumpName(s);
- s->Printf(" + 0x%" PRIx64 "\n", m_linked_offset);
- }
-
if (depth > 0)
m_children.Dump(s, target, false, depth - 1);
}
@@ -371,22 +282,10 @@ Section::Slide (addr_t slide_amount, boo
return false;
}
-void
-Section::SetLinkedLocation (const lldb::SectionSP &linked_section_sp, uint64_t linked_offset)
-{
- if (linked_section_sp)
- m_module_wp = linked_section_sp->GetModule();
- m_linked_section_wp = linked_section_sp;
- m_linked_offset = linked_offset;
-}
-
#pragma mark SectionList
SectionList::SectionList () :
m_sections()
-#ifdef LLDB_CONFIGURATION_DEBUG
- , m_finalized(false)
-#endif
{
}
@@ -401,7 +300,6 @@ SectionList::AddSection (const lldb::Sec
assert (section_sp.get());
size_t section_index = m_sections.size();
m_sections.push_back(section_sp);
- InvalidateRangeCache();
return section_index;
}
@@ -441,7 +339,6 @@ SectionList::ReplaceSection (user_id_t s
if ((*sect_iter)->GetID() == sect_id)
{
*sect_iter = sect_sp;
- InvalidateRangeCache();
return true;
}
else if (depth > 0)
@@ -575,71 +472,6 @@ SectionList::FindSectionContainingFileAd
return sect_sp;
}
-void
-SectionList::BuildRangeCache() const
-{
- m_range_cache.Clear();
-
- for (collection::size_type idx = 0, last_idx = m_sections.size();
- idx < last_idx;
- ++idx)
- {
- Section *sect = m_sections[idx].get();
-
- addr_t linked_file_address = sect->GetLinkedFileAddress();
-
- if (linked_file_address != LLDB_INVALID_ADDRESS)
- m_range_cache.Append(SectionRangeCache::Entry(linked_file_address, sect->GetByteSize(), idx));
- }
-
- m_range_cache.Sort();
-
-#ifdef LLDB_CONFIGURATION_DEBUG
- m_finalized = true;
-#endif
-}
-
-void
-SectionList::InvalidateRangeCache() const
-{
-#ifdef LLDB_CONFIGURATION_DEBUG
- assert(!m_finalized);
-#endif
- m_range_cache.Clear();
-}
-
-SectionSP
-SectionList::FindSectionContainingLinkedFileAddress (addr_t vm_addr, uint32_t depth) const
-{
- //if (m_range_cache.IsEmpty())
- // BuildRangeCache();
-#ifdef LLDB_CONFIGURATION_DEBUG
- assert(m_finalized);
-#endif
-
- SectionRangeCache::Entry *entry = m_range_cache.FindEntryThatContains(vm_addr);
-
- if (entry)
- return m_sections[entry->data];
-
- if (depth == 0)
- return SectionSP();
-
- for (const_iterator si = m_sections.begin(), se = m_sections.end();
- si != se;
- ++si)
- {
- Section *sect = si->get();
-
- SectionSP sect_sp = sect->GetChildren().FindSectionContainingLinkedFileAddress(vm_addr, depth - 1);
-
- if (sect_sp)
- return sect_sp;
- }
-
- return SectionSP();
-}
-
bool
SectionList::ContainsSection(user_id_t sect_id) const
{
@@ -681,15 +513,12 @@ SectionList::Slide (addr_t slide_amount,
if ((*pos)->Slide(slide_amount, slide_children))
++count;
}
- InvalidateRangeCache();
return count;
}
void
SectionList::Finalize ()
{
- BuildRangeCache();
-
for (const_iterator si = m_sections.begin(), se = m_sections.end();
si != se;
++si)
Modified: lldb/trunk/source/Expression/DWARFExpression.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Expression/DWARFExpression.cpp?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Expression/DWARFExpression.cpp (original)
+++ lldb/trunk/source/Expression/DWARFExpression.cpp Mon Mar 4 15:46:16 2013
@@ -1009,24 +1009,25 @@ GetOpcodeDataSize (const DataExtractor &
return LLDB_INVALID_OFFSET;
}
-bool
-DWARFExpression::LocationContains_DW_OP_addr (lldb::addr_t file_addr, bool &error) const
+lldb::addr_t
+DWARFExpression::GetLocation_DW_OP_addr (uint32_t op_addr_idx, bool &error) const
{
error = false;
if (IsLocationList())
- return false;
+ return LLDB_INVALID_ADDRESS;
lldb::offset_t offset = 0;
+ uint32_t curr_op_addr_idx = 0;
while (m_data.ValidOffset(offset))
{
const uint8_t op = m_data.GetU8(&offset);
if (op == DW_OP_addr)
{
- if (file_addr == LLDB_INVALID_ADDRESS)
- return true;
- addr_t op_file_addr = m_data.GetAddress(&offset);
- if (op_file_addr == file_addr)
- return true;
+ const lldb::addr_t op_file_addr = m_data.GetAddress(&offset);
+ if (curr_op_addr_idx == op_addr_idx)
+ return op_file_addr;
+ else
+ ++curr_op_addr_idx;
}
else
{
@@ -1039,7 +1040,7 @@ DWARFExpression::LocationContains_DW_OP_
offset += op_arg_size;
}
}
- return false;
+ return LLDB_INVALID_ADDRESS;
}
bool
Modified: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.cpp Mon Mar 4 15:46:16 2013
@@ -254,8 +254,6 @@ ObjectFileELF::ObjectFileELF (const lldb
m_header(),
m_program_headers(),
m_section_headers(),
- m_sections_ap(),
- m_symtab_ap(),
m_filespec_ap(),
m_shstr_data()
{
Modified: lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h (original)
+++ lldb/trunk/source/Plugins/ObjectFile/ELF/ObjectFileELF.h Mon Mar 4 15:46:16 2013
@@ -153,12 +153,6 @@ private:
/// Collection of symbols from the dynamic table.
DynamicSymbolColl m_dynamic_symbols;
- /// List of sections present in this ELF object file.
- mutable std::auto_ptr<lldb_private::SectionList> m_sections_ap;
-
- /// Table of all non-dynamic symbols present in this object file.
- mutable std::auto_ptr<lldb_private::Symtab> m_symtab_ap;
-
/// List of file specifications corresponding to the modules (shared
/// libraries) on which this object file depends.
mutable std::auto_ptr<lldb_private::FileSpecList> m_filespec_ap;
Modified: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp (original)
+++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp Mon Mar 4 15:46:16 2013
@@ -501,8 +501,6 @@ ObjectFileMachO::ObjectFileMachO(const l
lldb::offset_t file_offset,
lldb::offset_t length) :
ObjectFile(module_sp, file, file_offset, length, data_sp, data_offset),
- m_sections_ap(),
- m_symtab_ap(),
m_mach_segments(),
m_mach_sections(),
m_entry_point_address(),
@@ -518,8 +516,6 @@ ObjectFileMachO::ObjectFileMachO (const
const lldb::ProcessSP &process_sp,
lldb::addr_t header_addr) :
ObjectFile(module_sp, process_sp, header_addr, header_data_sp),
- m_sections_ap(),
- m_symtab_ap(),
m_mach_segments(),
m_mach_sections(),
m_entry_point_address(),
Modified: lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h (original)
+++ lldb/trunk/source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.h Mon Mar 4 15:46:16 2013
@@ -146,8 +146,6 @@ public:
protected:
llvm::MachO::mach_header m_header;
- mutable std::auto_ptr<lldb_private::SectionList> m_sections_ap;
- mutable std::auto_ptr<lldb_private::Symtab> m_symtab_ap;
static const lldb_private::ConstString &GetSegmentNameTEXT();
static const lldb_private::ConstString &GetSegmentNameDATA();
static const lldb_private::ConstString &GetSegmentNameOBJC();
@@ -157,7 +155,7 @@ protected:
llvm::MachO::dysymtab_command m_dysymtab;
std::vector<llvm::MachO::segment_command_64> m_mach_segments;
std::vector<llvm::MachO::section_64> m_mach_sections;
- typedef lldb_private::RangeArray<uint32_t, uint32_t, 1> FileRangeArray;
+ typedef lldb_private::RangeVector<uint32_t, uint32_t> FileRangeArray;
lldb_private::Address m_entry_point_address;
FileRangeArray m_thread_context_offsets;
bool m_thread_context_offsets_valid;
Modified: lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h (original)
+++ lldb/trunk/source/Plugins/ObjectFile/PECOFF/ObjectFilePECOFF.h Mon Mar 4 15:46:16 2013
@@ -229,8 +229,6 @@ protected:
typedef SectionHeaderColl::iterator SectionHeaderCollIter;
typedef SectionHeaderColl::const_iterator SectionHeaderCollConstIter;
private:
- mutable std::auto_ptr<lldb_private::SectionList> m_sections_ap;
- mutable std::auto_ptr<lldb_private::Symtab> m_symtab_ap;
dos_header_t m_dos_header;
coff_header_t m_coff_header;
coff_opt_header_t m_coff_header_opt;
Modified: lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.h?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.h (original)
+++ lldb/trunk/source/Plugins/Process/mach-core/ProcessMachCore.h Mon Mar 4 15:46:16 2013
@@ -130,7 +130,7 @@ private:
// For ProcessMachCore only
//------------------------------------------------------------------
typedef lldb_private::Range<uint32_t, uint32_t> FileRange;
- typedef lldb_private::RangeDataArray<lldb::addr_t, lldb::addr_t, FileRange, 1> VMRangeToFileOffset;
+ typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, FileRange> VMRangeToFileOffset;
VMRangeToFileOffset m_core_aranges;
lldb::ModuleSP m_core_module_sp;
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/DWARFDebugMacinfo.h Mon Mar 4 15:46:16 2013
@@ -7,8 +7,8 @@
//
//===----------------------------------------------------------------------===//
-#ifndef SymbolFileDWARF_DWARFDebugLine_h_
-#define SymbolFileDWARF_DWARFDebugLine_h_
+#ifndef SymbolFileDWARF_DWARFDebugMacinfo_h_
+#define SymbolFileDWARF_DWARFDebugMacinfo_h_
#include "SymbolFileDWARF.h"
@@ -26,4 +26,4 @@ public:
};
-#endif // SymbolFileDWARF_DWARFDebugLine_h_
+#endif // SymbolFileDWARF_DWARFDebugMacinfo_h_
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/LogChannelDWARF.cpp Mon Mar 4 15:46:16 2013
@@ -182,9 +182,9 @@ LogChannelDWARF::ListCategories (Stream
" line - log the parsing if .debug_line\n"
" pubnames - log the parsing if .debug_pubnames\n"
" pubtypes - log the parsing if .debug_pubtypes\n"
- " lookups - log any lookups that happen by name, regex, or address\n\n"
- " completion - log struct/unions/class type completions\n\n"
- " map - log insertions of object files into DWARF debug maps\n\n",
+ " lookups - log any lookups that happen by name, regex, or address\n"
+ " completion - log struct/unions/class type completions\n"
+ " map - log insertions of object files into DWARF debug maps\n",
SymbolFileDWARF::GetPluginNameStatic());
}
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.cpp Mon Mar 4 15:46:16 2013
@@ -891,28 +891,40 @@ SymbolFileDWARF::ParseCompileUnitFunctio
assert(func_type == NULL || func_type != DIE_IS_BEING_PARSED);
- func_range.GetBaseAddress().ResolveLinkedAddress();
-
- const user_id_t func_user_id = MakeUserID(die->GetOffset());
- func_sp.reset(new Function (sc.comp_unit,
- func_user_id, // UserID is the DIE offset
- func_user_id,
- func_name,
- func_type,
- func_range)); // first address range
-
- if (func_sp.get() != NULL)
- {
- if (frame_base.IsValid())
- func_sp->GetFrameBaseExpression() = frame_base;
- sc.comp_unit->AddFunction(func_sp);
- return func_sp.get();
+ if (FixupAddress (func_range.GetBaseAddress()))
+ {
+ const user_id_t func_user_id = MakeUserID(die->GetOffset());
+ func_sp.reset(new Function (sc.comp_unit,
+ MakeUserID(func_user_id), // UserID is the DIE offset
+ MakeUserID(func_user_id),
+ func_name,
+ func_type,
+ func_range)); // first address range
+
+ if (func_sp.get() != NULL)
+ {
+ if (frame_base.IsValid())
+ func_sp->GetFrameBaseExpression() = frame_base;
+ sc.comp_unit->AddFunction(func_sp);
+ return func_sp.get();
+ }
}
}
}
return NULL;
}
+bool
+SymbolFileDWARF::FixupAddress (Address &addr)
+{
+ SymbolFileDWARFDebugMap * debug_map_symfile = GetDebugMapSymfile ();
+ if (debug_map_symfile)
+ {
+ return debug_map_symfile->LinkOSOAddress(addr);
+ }
+ // This is a normal DWARF file, no address fixups need to happen
+ return true;
+}
lldb::LanguageType
SymbolFileDWARF::ParseCompileUnitLanguage (const SymbolContext& sc)
{
@@ -983,15 +995,7 @@ SymbolFileDWARF::ParseCompileUnitSupport
struct ParseDWARFLineTableCallbackInfo
{
LineTable* line_table;
- const SectionList *section_list;
- lldb::addr_t prev_sect_file_base_addr;
- lldb::addr_t curr_sect_file_base_addr;
- bool is_oso_for_debug_map;
- bool prev_in_final_executable;
- DWARFDebugLine::Row prev_row;
- SectionSP prev_section_sp;
- SectionSP curr_section_sp;
- llvm::OwningPtr<LineSequence> curr_sequence_ap;
+ std::auto_ptr<LineSequence> sequence_ap;
};
//----------------------------------------------------------------------
@@ -1000,7 +1004,6 @@ struct ParseDWARFLineTableCallbackInfo
static void
ParseDWARFLineTableCallback(dw_offset_t offset, const DWARFDebugLine::State& state, void* userData)
{
- LineTable* line_table = ((ParseDWARFLineTableCallbackInfo*)userData)->line_table;
if (state.row == DWARFDebugLine::State::StartParsingLineTable)
{
// Just started parsing the line table
@@ -1012,166 +1015,32 @@ ParseDWARFLineTableCallback(dw_offset_t
else
{
ParseDWARFLineTableCallbackInfo* info = (ParseDWARFLineTableCallbackInfo*)userData;
- // We have a new row, lets append it
-
- if (info->curr_section_sp.get() == NULL || info->curr_section_sp->ContainsFileAddress(state.address) == false)
- {
- info->prev_section_sp = info->curr_section_sp;
- info->prev_sect_file_base_addr = info->curr_sect_file_base_addr;
- // If this is an end sequence entry, then we subtract one from the
- // address to make sure we get an address that is not the end of
- // a section.
- if (state.end_sequence && state.address != 0)
- info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address - 1);
- else
- info->curr_section_sp = info->section_list->FindSectionContainingFileAddress (state.address);
-
- if (info->curr_section_sp.get())
- info->curr_sect_file_base_addr = info->curr_section_sp->GetFileAddress ();
- else
- info->curr_sect_file_base_addr = 0;
- }
- if (info->curr_section_sp.get())
- {
- lldb::addr_t curr_line_section_offset = state.address - info->curr_sect_file_base_addr;
- // Check for the fancy section magic to determine if we
-
- if (info->is_oso_for_debug_map)
- {
- // When this is a debug map object file that contains DWARF
- // (referenced from an N_OSO debug map nlist entry) we will have
- // a file address in the file range for our section from the
- // original .o file, and a load address in the executable that
- // contains the debug map.
- //
- // If the sections for the file range and load range are
- // different, we have a remapped section for the function and
- // this address is resolved. If they are the same, then the
- // function for this address didn't make it into the final
- // executable.
- bool curr_in_final_executable = (bool) info->curr_section_sp->GetLinkedSection ();
-
- // If we are doing DWARF with debug map, then we need to carefully
- // add each line table entry as there may be gaps as functions
- // get moved around or removed.
- if (!info->prev_row.end_sequence && info->prev_section_sp.get())
- {
- if (info->prev_in_final_executable)
- {
- bool terminate_previous_entry = false;
- if (!curr_in_final_executable)
- {
- // Check for the case where the previous line entry
- // in a function made it into the final executable,
- // yet the current line entry falls in a function
- // that didn't. The line table used to be contiguous
- // through this address range but now it isn't. We
- // need to terminate the previous line entry so
- // that we can reconstruct the line range correctly
- // for it and to keep the line table correct.
- terminate_previous_entry = true;
- }
- else if (info->curr_section_sp.get() != info->prev_section_sp.get())
- {
- // Check for cases where the line entries used to be
- // contiguous address ranges, but now they aren't.
- // This can happen when order files specify the
- // ordering of the functions.
- lldb::addr_t prev_line_section_offset = info->prev_row.address - info->prev_sect_file_base_addr;
- Section *curr_sect = info->curr_section_sp.get();
- Section *prev_sect = info->prev_section_sp.get();
- assert (curr_sect->GetLinkedSection());
- assert (prev_sect->GetLinkedSection());
- lldb::addr_t object_file_addr_delta = state.address - info->prev_row.address;
- lldb::addr_t curr_linked_file_addr = curr_sect->GetLinkedFileAddress() + curr_line_section_offset;
- lldb::addr_t prev_linked_file_addr = prev_sect->GetLinkedFileAddress() + prev_line_section_offset;
- lldb::addr_t linked_file_addr_delta = curr_linked_file_addr - prev_linked_file_addr;
- if (object_file_addr_delta != linked_file_addr_delta)
- terminate_previous_entry = true;
- }
-
- if (terminate_previous_entry)
- {
- line_table->InsertLineEntry (info->prev_section_sp,
- state.address - info->prev_sect_file_base_addr,
- info->prev_row.line,
- info->prev_row.column,
- info->prev_row.file,
- false, // is_stmt
- false, // basic_block
- false, // state.prologue_end
- false, // state.epilogue_begin
- true); // end_sequence);
- }
- }
- }
-
- if (curr_in_final_executable)
- {
- line_table->InsertLineEntry (info->curr_section_sp,
- curr_line_section_offset,
- state.line,
- state.column,
- state.file,
- state.is_stmt,
- state.basic_block,
- state.prologue_end,
- state.epilogue_begin,
- state.end_sequence);
- info->prev_section_sp = info->curr_section_sp;
- }
- else
- {
- // If the current address didn't make it into the final
- // executable, the current section will be the __text
- // segment in the .o file, so we need to clear this so
- // we can catch the next function that did make it into
- // the final executable.
- info->prev_section_sp.reset();
- info->curr_section_sp.reset();
- }
+ LineTable* line_table = info->line_table;
- info->prev_in_final_executable = curr_in_final_executable;
- }
- else
- {
- // We are not in an object file that contains DWARF for an
- // N_OSO, this is just a normal DWARF file. The DWARF spec
- // guarantees that the addresses will be in increasing order
- // for a sequence, but the line table for a single compile unit
- // may contain multiple sequences so we append entries to the
- // current sequence until we find its end, then we merge the
- // sequence into the main line table collection.
-
- // If this is our first time here, we need to create a
- // sequence container.
- if (!info->curr_sequence_ap)
- {
- info->curr_sequence_ap.reset(line_table->CreateLineSequenceContainer());
- assert(info->curr_sequence_ap);
- }
- line_table->AppendLineEntryToSequence(info->curr_sequence_ap.get(),
- info->curr_section_sp,
- curr_line_section_offset,
- state.line,
- state.column,
- state.file,
- state.is_stmt,
- state.basic_block,
- state.prologue_end,
- state.epilogue_begin,
- state.end_sequence);
- if (state.end_sequence)
- {
- // First, put the current sequence into the line table.
- line_table->InsertSequence(info->curr_sequence_ap.get());
- // Then, empty it to prepare for the next sequence.
- info->curr_sequence_ap->Clear();
- }
- }
+ // If this is our first time here, we need to create a
+ // sequence container.
+ if (!info->sequence_ap.get())
+ {
+ info->sequence_ap.reset(line_table->CreateLineSequenceContainer());
+ assert(info->sequence_ap.get());
+ }
+ line_table->AppendLineEntryToSequence (info->sequence_ap.get(),
+ state.address,
+ state.line,
+ state.column,
+ state.file,
+ state.is_stmt,
+ state.basic_block,
+ state.prologue_end,
+ state.epilogue_begin,
+ state.end_sequence);
+ if (state.end_sequence)
+ {
+ // First, put the current sequence into the line table.
+ line_table->InsertSequence(info->sequence_ap.get());
+ // Then, empty it to prepare for the next sequence.
+ info->sequence_ap->Clear();
}
-
- info->prev_row = state;
}
}
@@ -1194,22 +1063,23 @@ SymbolFileDWARF::ParseCompileUnitLineTab
std::auto_ptr<LineTable> line_table_ap(new LineTable(sc.comp_unit));
if (line_table_ap.get())
{
- ParseDWARFLineTableCallbackInfo info = {
- line_table_ap.get(),
- m_obj_file->GetSectionList(),
- 0,
- 0,
- GetDebugMapSymfile () != NULL,
- false,
- DWARFDebugLine::Row(),
- SectionSP(),
- SectionSP(),
- llvm::OwningPtr<LineSequence>()
- };
+ ParseDWARFLineTableCallbackInfo info;
+ info.line_table = line_table_ap.get();
lldb::offset_t offset = cu_line_offset;
DWARFDebugLine::ParseStatementTable(get_debug_line_data(), &offset, ParseDWARFLineTableCallback, &info);
- sc.comp_unit->SetLineTable(line_table_ap.release());
- return true;
+ if (m_debug_map_symfile)
+ {
+ // We have an object file that has a line table with addresses
+ // that are not linked. We need to link the line table and convert
+ // the addresses that are relative to the .o file into addresses
+ // for the main executable.
+ sc.comp_unit->SetLineTable (m_debug_map_symfile->LinkOSOLineTable (this, line_table_ap.get()));
+ }
+ else
+ {
+ sc.comp_unit->SetLineTable(line_table_ap.release());
+ return true;
+ }
}
}
}
@@ -2672,19 +2542,19 @@ SymbolFileDWARF::ResolveSymbolContext (c
LineTable *line_table = sc.comp_unit->GetLineTable();
if (line_table != NULL)
{
- if (so_addr.IsLinkedAddress())
+ // And address that makes it into this function should be in terms
+ // of this debug file if there is no debug map, or it will be an
+ // address in the .o file which needs to be fixed up to be in terms
+ // of the debug map executable. Either way, calling FixupAddress()
+ // will work for us.
+ Address exe_so_addr (so_addr);
+ if (FixupAddress(exe_so_addr))
{
- Address linked_addr (so_addr);
- linked_addr.ResolveLinkedAddress();
- if (line_table->FindLineEntryByAddress (linked_addr, sc.line_entry))
+ if (line_table->FindLineEntryByAddress (exe_so_addr, sc.line_entry))
{
resolved |= eSymbolContextLineEntry;
}
}
- else if (line_table->FindLineEntryByAddress (so_addr, sc.line_entry))
- {
- resolved |= eSymbolContextLineEntry;
- }
}
}
@@ -6976,14 +6846,13 @@ SymbolFileDWARF::ParseVariablesForContex
if (info == NULL)
return 0;
- uint32_t cu_idx = UINT32_MAX;
- DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID(), &cu_idx).get();
-
- if (dwarf_cu == NULL)
- return 0;
-
if (sc.function)
{
+ DWARFCompileUnit* dwarf_cu = info->GetCompileUnitContainingDIE(sc.function->GetID()).get();
+
+ if (dwarf_cu == NULL)
+ return 0;
+
const DWARFDebugInfoEntry *function_die = dwarf_cu->GetDIEPtr(sc.function->GetID());
dw_addr_t func_lo_pc = function_die->GetAttributeValueAsUnsigned (this, dwarf_cu, DW_AT_low_pc, LLDB_INVALID_ADDRESS);
@@ -6998,6 +6867,11 @@ SymbolFileDWARF::ParseVariablesForContex
}
else if (sc.comp_unit)
{
+ DWARFCompileUnit* dwarf_cu = info->GetCompileUnit(sc.comp_unit->GetID()).get();
+
+ if (dwarf_cu == NULL)
+ return 0;
+
uint32_t vars_added = 0;
VariableListSP variables (sc.comp_unit->GetVariableList(false));
@@ -7232,10 +7106,10 @@ SymbolFileDWARF::ParseVariableDIE
{
bool op_error = false;
// Check if the location has a DW_OP_addr with any address value...
- addr_t location_has_op_addr = false;
+ lldb::addr_t location_DW_OP_addr = LLDB_INVALID_ADDRESS;
if (!location_is_const_value_data)
{
- location_has_op_addr = location.LocationContains_DW_OP_addr (LLDB_INVALID_ADDRESS, op_error);
+ location_DW_OP_addr = location.GetLocation_DW_OP_addr (0, op_error);
if (op_error)
{
StreamString strm;
@@ -7244,67 +7118,63 @@ SymbolFileDWARF::ParseVariableDIE
}
}
- if (location_has_op_addr)
+ if (location_DW_OP_addr != LLDB_INVALID_ADDRESS)
{
if (is_external)
- {
scope = eValueTypeVariableGlobal;
-
- if (GetDebugMapSymfile ())
+ else
+ scope = eValueTypeVariableStatic;
+
+
+ SymbolFileDWARFDebugMap *debug_map_symfile = GetDebugMapSymfile ();
+
+ if (debug_map_symfile)
+ {
+ // When leaving the DWARF in the .o files on darwin,
+ // when we have a global variable that wasn't initialized,
+ // the .o file might not have allocated a virtual
+ // address for the global variable. In this case it will
+ // have created a symbol for the global variable
+ // that is undefined/data and external and the value will
+ // be the byte size of the variable. When we do the
+ // address map in SymbolFileDWARFDebugMap we rely on
+ // having an address, we need to do some magic here
+ // so we can get the correct address for our global
+ // variable. The address for all of these entries
+ // will be zero, and there will be an undefined symbol
+ // in this object file, and the executable will have
+ // a matching symbol with a good address. So here we
+ // dig up the correct address and replace it in the
+ // location for the variable, and set the variable's
+ // symbol context scope to be that of the main executable
+ // so the file address will resolve correctly.
+ bool linked_oso_file_addr = false;
+ if (is_external && location_DW_OP_addr == 0)
{
- // When leaving the DWARF in the .o files on darwin,
- // when we have a global variable that wasn't initialized,
- // the .o file might not have allocated a virtual
- // address for the global variable. In this case it will
- // have created a symbol for the global variable
- // that is undefined/data and external and the value will
- // be the byte size of the variable. When we do the
- // address map in SymbolFileDWARFDebugMap we rely on
- // having an address, we need to do some magic here
- // so we can get the correct address for our global
- // variable. The address for all of these entries
- // will be zero, and there will be an undefined symbol
- // in this object file, and the executable will have
- // a matching symbol with a good address. So here we
- // dig up the correct address and replace it in the
- // location for the variable, and set the variable's
- // symbol context scope to be that of the main executable
- // so the file address will resolve correctly.
- if (location.LocationContains_DW_OP_addr (0, op_error))
+
+ // we have a possible uninitialized extern global
+ ConstString const_name(mangled ? mangled : name);
+ ObjectFile *debug_map_objfile = debug_map_symfile->GetObjectFile();
+ if (debug_map_objfile)
{
-
- // we have a possible uninitialized extern global
- Symtab *symtab = m_obj_file->GetSymtab();
- if (symtab)
+ Symtab *debug_map_symtab = debug_map_objfile->GetSymtab();
+ if (debug_map_symtab)
{
- ConstString const_name(mangled ? mangled : name);
- Symbol *o_symbol = symtab->FindFirstSymbolWithNameAndType (const_name,
- eSymbolTypeAny,
- Symtab::eDebugNo,
- Symtab::eVisibilityExtern);
-
- if (o_symbol)
+ Symbol *exe_symbol = debug_map_symtab->FindFirstSymbolWithNameAndType (const_name,
+ eSymbolTypeData,
+ Symtab::eDebugYes,
+ Symtab::eVisibilityExtern);
+ if (exe_symbol)
{
- ObjectFile *debug_map_objfile = m_debug_map_symfile->GetObjectFile();
- if (debug_map_objfile)
+ if (exe_symbol->ValueIsAddress())
{
- Symtab *debug_map_symtab = debug_map_objfile->GetSymtab();
- Symbol *defined_symbol = debug_map_symtab->FindFirstSymbolWithNameAndType (const_name,
- eSymbolTypeData,
- Symtab::eDebugYes,
- Symtab::eVisibilityExtern);
- if (defined_symbol)
+ const addr_t exe_file_addr = exe_symbol->GetAddress().GetFileAddress();
+ if (exe_file_addr != LLDB_INVALID_ADDRESS)
{
- if (defined_symbol->ValueIsAddress())
+ if (location.Update_DW_OP_addr (exe_file_addr))
{
- const addr_t defined_addr = defined_symbol->GetAddress().GetFileAddress();
- if (defined_addr != LLDB_INVALID_ADDRESS)
- {
- if (location.Update_DW_OP_addr (defined_addr))
- {
- symbol_context_scope = defined_symbol;
- }
- }
+ linked_oso_file_addr = true;
+ symbol_context_scope = exe_symbol;
}
}
}
@@ -7312,10 +7182,23 @@ SymbolFileDWARF::ParseVariableDIE
}
}
}
- }
- else
- {
- scope = eValueTypeVariableStatic;
+
+ if (!linked_oso_file_addr)
+ {
+ // The DW_OP_addr is not zero, but it contains a .o file address which
+ // needs to be linked up correctly.
+ const lldb::addr_t exe_file_addr = debug_map_symfile->LinkOSOFileAddress(this, location_DW_OP_addr);
+ if (exe_file_addr != LLDB_INVALID_ADDRESS)
+ {
+ // Update the file address for this variable
+ location.Update_DW_OP_addr (exe_file_addr);
+ }
+ else
+ {
+ // Variable didn't make it into the final executable
+ return var_sp;
+ }
+ }
}
}
else
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARF.h Mon Mar 4 15:46:16 2013
@@ -541,6 +541,9 @@ protected:
const DWARFDebugInfoEntry *dst_class_die,
llvm::SmallVectorImpl <const DWARFDebugInfoEntry *> &failures);
+ bool
+ FixupAddress (lldb_private::Address &addr);
+
lldb::ModuleWP m_debug_map_module_wp;
SymbolFileDWARFDebugMap * m_debug_map_symfile;
clang::TranslationUnitDecl * m_clang_tu_decl;
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.cpp Mon Mar 4 15:46:16 2013
@@ -14,6 +14,8 @@
#include "lldb/Core/PluginManager.h"
#include "lldb/Core/RegularExpression.h"
#include "lldb/Core/Section.h"
+
+//#define DEBUG_OSO_DMAP // DO NOT CHECKIN WITH THIS NOT COMMENTED OUT
#if defined(DEBUG_OSO_DMAP)
#include "lldb/Core/StreamFile.h"
#endif
@@ -21,6 +23,7 @@
#include "lldb/Symbol/ClangExternalASTSourceCallbacks.h"
#include "lldb/Symbol/CompileUnit.h"
+#include "lldb/Symbol/LineTable.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolVendor.h"
#include "lldb/Symbol/VariableList.h"
@@ -35,207 +38,171 @@ using namespace lldb_private;
// (so we can fixup the object file sections) and also for "Module::GetSymbolVendor()"
// (so we can fixup the symbol file id.
-class DebugMapModule : public Module
+
+
+
+const SymbolFileDWARFDebugMap::FileRangeMap &
+SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile)
{
-public:
- DebugMapModule (const ModuleSP &exe_module_sp,
- uint32_t cu_idx,
- const FileSpec& file_spec,
- const ArchSpec& arch,
- const ConstString *object_name,
- off_t object_offset) :
- Module (file_spec, arch, object_name, object_offset),
- m_exe_module_wp (exe_module_sp),
- m_cu_idx (cu_idx)
- {
- LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
- if (log)
- log->Printf("%p: DebugMapModule::DebugMapModule (exe_module=%p, cu_idx=%u, oso_path='%s/%s', object_name='%s')",
- this,
- exe_module_sp.get(),
- cu_idx,
- file_spec.GetDirectory().GetCString(),
- file_spec.GetFilename().GetCString(),
- object_name ? object_name->GetCString() : "");
- }
+ if (file_range_map_valid)
+ return file_range_map;
- virtual
- ~DebugMapModule ()
+ file_range_map_valid = true;
+
+ Module *oso_module = exe_symfile->GetModuleByCompUnitInfo (this);
+ ObjectFile *oso_objfile = oso_module->GetObjectFile();
+
+ LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
+ if (log)
{
- LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
- if (log)
- log->Printf("%p: DebugMapModule::~DebugMapModule ()", this);
+ ConstString object_name (oso_module->GetObjectName());
+ log->Printf("%p: SymbolFileDWARFDebugMap::CompileUnitInfo::GetFileRangeMap ('%s/%s%s%s%s')",
+ this,
+ oso_module->GetFileSpec().GetDirectory().GetCString(),
+ oso_module->GetFileSpec().GetFilename().GetCString(),
+ object_name ? "(" : "",
+ object_name ? object_name.GetCString() : "",
+ object_name ? ")" : "");
}
+
- virtual ObjectFile *
- GetObjectFile ()
+ std::vector<SymbolFileDWARFDebugMap::CompileUnitInfo *> cu_infos;
+ if (exe_symfile->GetCompUnitInfosForModule(oso_module, cu_infos))
{
- Mutex::Locker locker (m_mutex);
- if (m_did_load_objfile == false)
+ for (auto comp_unit_info : cu_infos)
{
- ModuleSP exe_module_sp (m_exe_module_wp.lock());
- if (exe_module_sp)
+ Symtab *exe_symtab = exe_symfile->GetObjectFile()->GetSymtab();
+ ModuleSP oso_module_sp (oso_objfile->GetModule());
+ Symtab *oso_symtab = oso_objfile->GetSymtab();
+#if defined(DEBUG_OSO_DMAP)
+ StreamFile s(stdout, false);
+ s << "OSO symtab:\n";
+ oso_symtab->Dump(&s, NULL, eSortOrderNone);
+ s << "OSO sections before:\n";
+ oso_objfile->GetSectionList()->Dump(&s, NULL, true, UINT32_MAX);
+#endif
+
+ ///const uint32_t fun_resolve_flags = SymbolContext::Module | eSymbolContextCompUnit | eSymbolContextFunction;
+ //SectionList *oso_sections = oso_objfile->Sections();
+ // Now we need to make sections that map from zero based object
+ // file addresses to where things eneded up in the main executable.
+
+ assert (comp_unit_info->first_symbol_index != UINT32_MAX);
+ // End index is one past the last valid symbol index
+ const uint32_t oso_end_idx = comp_unit_info->last_symbol_index + 1;
+ for (uint32_t idx = comp_unit_info->first_symbol_index + 2; // Skip the N_SO and N_OSO
+ idx < oso_end_idx;
+ ++idx)
{
- ObjectFile *exe_objfile = exe_module_sp->GetObjectFile();
- ObjectFile *oso_objfile = Module::GetObjectFile();
- SymbolVendor *exe_sym_vendor = exe_module_sp->GetSymbolVendor();
-
- if (exe_objfile && oso_objfile && exe_sym_vendor)
+ Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx);
+ if (exe_symbol)
{
- SymbolFileDWARFDebugMap *exe_symfile = (SymbolFileDWARFDebugMap *)exe_sym_vendor->GetSymbolFile();
- if (exe_symfile)
+ if (exe_symbol->IsDebug() == false)
+ continue;
+
+ switch (exe_symbol->GetType())
{
- std::vector<SymbolFileDWARFDebugMap::CompileUnitInfo *> cu_infos;
- if (exe_symfile->GetCompUnitInfosForModule(this, cu_infos))
+ default:
+ break;
+
+ case eSymbolTypeCode:
{
- for (auto comp_unit_info : cu_infos)
+ // For each N_FUN, or function that we run into in the debug map
+ // we make a new section that we add to the sections found in the
+ // .o file. This new section has the file address set to what the
+ // addresses are in the .o file, and the load address is adjusted
+ // to match where it ended up in the final executable! We do this
+ // before we parse any dwarf info so that when it goes get parsed
+ // all section/offset addresses that get registered will resolve
+ // correctly to the new addresses in the main executable.
+
+ // First we find the original symbol in the .o file's symbol table
+ Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(Mangled::ePreferMangled),
+ eSymbolTypeCode,
+ Symtab::eDebugNo,
+ Symtab::eVisibilityAny);
+ if (oso_fun_symbol)
{
- // Set the ID of the symbol file DWARF to the index of the OSO
- // shifted left by 32 bits to provide a unique prefix for any
- // UserID's that get created in the symbol file.
- //comp_unit_info->exe_sections_sp.reset(new SectionList);
+ // Add the inverse OSO file address to debug map entry mapping
+ exe_symfile->AddOSOFileRange (this,
+ exe_symbol->GetAddress().GetFileAddress(),
+ oso_fun_symbol->GetAddress().GetFileAddress(),
+ std::min<addr_t>(exe_symbol->GetByteSize(), oso_fun_symbol->GetByteSize()));
- Symtab *exe_symtab = exe_objfile->GetSymtab();
- ModuleSP oso_module_sp (oso_objfile->GetModule());
- Symtab *oso_symtab = oso_objfile->GetSymtab();
- //#define DEBUG_OSO_DMAP // Do not check in with this defined...
-#if defined(DEBUG_OSO_DMAP)
- StreamFile s(stdout);
- s << "OSO symtab:\n";
- oso_symtab->Dump(&s, NULL);
- s << "OSO sections before:\n";
- oso_objfile->GetSectionList()->Dump(&s, NULL, true);
-#endif
-
- ///const uint32_t fun_resolve_flags = SymbolContext::Module | eSymbolContextCompUnit | eSymbolContextFunction;
- //SectionList *oso_sections = oso_objfile->Sections();
- // Now we need to make sections that map from zero based object
- // file addresses to where things eneded up in the main executable.
-
- assert (comp_unit_info->first_symbol_index != UINT32_MAX);
- // End index is one past the last valid symbol index
- const uint32_t oso_end_idx = comp_unit_info->last_symbol_index + 1;
- uint32_t sect_id = 0x10000;
- for (uint32_t idx = comp_unit_info->first_symbol_index + 2; // Skip the N_SO and N_OSO
- idx < oso_end_idx;
- ++idx)
- {
- Symbol *exe_symbol = exe_symtab->SymbolAtIndex(idx);
- if (exe_symbol)
- {
- if (exe_symbol->IsDebug() == false)
- continue;
-
- switch (exe_symbol->GetType())
- {
- default:
- break;
-
- case eSymbolTypeCode:
- {
- // For each N_FUN, or function that we run into in the debug map
- // we make a new section that we add to the sections found in the
- // .o file. This new section has the file address set to what the
- // addresses are in the .o file, and the load address is adjusted
- // to match where it ended up in the final executable! We do this
- // before we parse any dwarf info so that when it goes get parsed
- // all section/offset addresses that get registered will resolve
- // correctly to the new addresses in the main executable.
-
- // First we find the original symbol in the .o file's symbol table
- Symbol *oso_fun_symbol = oso_symtab->FindFirstSymbolWithNameAndType(exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), eSymbolTypeCode, Symtab::eDebugNo, Symtab::eVisibilityAny);
- if (oso_fun_symbol)
- {
- // If we found the symbol, then we
- SectionSP exe_fun_section (exe_symbol->GetAddress().GetSection());
- SectionSP oso_fun_section (oso_fun_symbol->GetAddress().GetSection());
- if (oso_fun_section)
- {
- // Now we create a section that we will add as a child of the
- // section in which the .o symbol (the N_FUN) exists.
-
- // We use the exe_symbol size because the one in the .o file
- // will just be a symbol with no size, and the exe_symbol
- // size will reflect any size changes (ppc has been known to
- // shrink function sizes when it gets rid of jump islands that
- // aren't needed anymore).
- SectionSP oso_fun_section_sp (new Section (oso_fun_symbol->GetAddress().GetSection(),
- oso_module_sp, // Module (the .o file)
- sect_id++, // Section ID starts at 0x10000 and increments so the section IDs don't overlap with the standard mach IDs
- exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), // Name the section the same as the symbol for which is was generated!
- eSectionTypeDebug,
- oso_fun_symbol->GetAddress().GetOffset(), // File VM address offset in the current section
- exe_symbol->GetByteSize(), // File size (we need the size from the executable)
- 0, 0, 0));
-
- oso_fun_section_sp->SetLinkedLocation (exe_fun_section,
- exe_symbol->GetAddress().GetFileAddress() - exe_fun_section->GetFileAddress());
- oso_fun_section->GetChildren().AddSection(oso_fun_section_sp);
- }
- }
- }
- break;
-
- case eSymbolTypeData:
- {
- // For each N_GSYM we remap the address for the global by making
- // a new section that we add to the sections found in the .o file.
- // This new section has the file address set to what the
- // addresses are in the .o file, and the load address is adjusted
- // to match where it ended up in the final executable! We do this
- // before we parse any dwarf info so that when it goes get parsed
- // all section/offset addresses that get registered will resolve
- // correctly to the new addresses in the main executable. We
- // initially set the section size to be 1 byte, but will need to
- // fix up these addresses further after all globals have been
- // parsed to span the gaps, or we can find the global variable
- // sizes from the DWARF info as we are parsing.
-
- // Next we find the non-stab entry that corresponds to the N_GSYM in the .o file
- Symbol *oso_gsym_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(),
- eSymbolTypeData,
- Symtab::eDebugNo,
- Symtab::eVisibilityAny);
-
- if (exe_symbol && oso_gsym_symbol && exe_symbol->ValueIsAddress() && oso_gsym_symbol->ValueIsAddress())
- {
- // If we found the symbol, then we
- SectionSP exe_gsym_section (exe_symbol->GetAddress().GetSection());
- SectionSP oso_gsym_section (oso_gsym_symbol->GetAddress().GetSection());
- if (oso_gsym_section)
- {
- SectionSP oso_gsym_section_sp (new Section (oso_gsym_symbol->GetAddress().GetSection(),
- oso_module_sp, // Module (the .o file)
- sect_id++, // Section ID starts at 0x10000 and increments so the section IDs don't overlap with the standard mach IDs
- exe_symbol->GetMangled().GetName(Mangled::ePreferMangled), // Name the section the same as the symbol for which is was generated!
- eSectionTypeDebug,
- oso_gsym_symbol->GetAddress().GetOffset(), // File VM address offset in the current section
- 1, // We don't know the size of the global, just do the main address for now.
- 0, 0, 0));
-
- oso_gsym_section_sp->SetLinkedLocation (exe_gsym_section,
- exe_symbol->GetAddress().GetFileAddress() - exe_gsym_section->GetFileAddress());
- oso_gsym_section->GetChildren().AddSection(oso_gsym_section_sp);
- }
- }
- }
- break;
- }
- }
- }
- oso_objfile->GetSectionList()->Finalize(); // Now that we're done adding sections, finalize to build fast-lookup caches
- #if defined(DEBUG_OSO_DMAP)
- s << "OSO sections after:\n";
- oso_objfile->GetSectionList()->Dump(&s, NULL, true);
- #endif
}
}
+ break;
+
+ case eSymbolTypeData:
+ {
+ // For each N_GSYM we remap the address for the global by making
+ // a new section that we add to the sections found in the .o file.
+ // This new section has the file address set to what the
+ // addresses are in the .o file, and the load address is adjusted
+ // to match where it ended up in the final executable! We do this
+ // before we parse any dwarf info so that when it goes get parsed
+ // all section/offset addresses that get registered will resolve
+ // correctly to the new addresses in the main executable. We
+ // initially set the section size to be 1 byte, but will need to
+ // fix up these addresses further after all globals have been
+ // parsed to span the gaps, or we can find the global variable
+ // sizes from the DWARF info as we are parsing.
+
+ // Next we find the non-stab entry that corresponds to the N_GSYM in the .o file
+ Symbol *oso_gsym_symbol = oso_symtab->FindFirstSymbolWithNameAndType (exe_symbol->GetMangled().GetName(Mangled::ePreferMangled),
+ eSymbolTypeData,
+ Symtab::eDebugNo,
+ Symtab::eVisibilityAny);
+
+ if (exe_symbol && oso_gsym_symbol &&
+ exe_symbol->ValueIsAddress() &&
+ oso_gsym_symbol->ValueIsAddress())
+ {
+ // Add the inverse OSO file address to debug map entry mapping
+ exe_symfile->AddOSOFileRange (this,
+ exe_symbol->GetAddress().GetFileAddress(),
+ oso_gsym_symbol->GetAddress().GetFileAddress(),
+ std::min<addr_t>(exe_symbol->GetByteSize(), oso_gsym_symbol->GetByteSize()));
+ }
+ }
+ break;
}
}
}
+
+ exe_symfile->FinalizeOSOFileRanges (this);
+#if defined(DEBUG_OSO_DMAP)
+ s << "OSO sections after:\n";
+ oso_objfile->GetSectionList()->Dump(&s, NULL, true, UINT32_MAX);
+#endif
+ // We don't need the symbols anymore for the .o files
+ oso_objfile->ClearSymtab();
}
- return m_objfile_sp.get();
}
+ return file_range_map;
+}
+
+
+class DebugMapModule : public Module
+{
+public:
+ DebugMapModule (const ModuleSP &exe_module_sp,
+ uint32_t cu_idx,
+ const FileSpec& file_spec,
+ const ArchSpec& arch,
+ const ConstString *object_name,
+ off_t object_offset) :
+ Module (file_spec, arch, object_name, object_offset),
+ m_exe_module_wp (exe_module_sp),
+ m_cu_idx (cu_idx)
+ {
+ }
+
+ virtual
+ ~DebugMapModule ()
+ {
+ }
+
virtual SymbolVendor*
GetSymbolVendor(bool can_create = true, lldb_private::Stream *feedback_strm = NULL)
@@ -356,14 +323,12 @@ SymbolFileDWARFDebugMap::InitializeObjec
GetClangASTContext().SetExternalSource (ast_source_ap);
}
-
-
void
SymbolFileDWARFDebugMap::InitOSO()
{
if (m_flags.test(kHaveInitializedOSOs))
return;
-
+
m_flags.set(kHaveInitializedOSOs);
// In order to get the abilities of this plug-in, we look at the list of
// N_OSO entries (object files) from the symbol table and make sure that
@@ -376,10 +341,6 @@ SymbolFileDWARFDebugMap::InitOSO()
LogSP log (LogChannelDWARF::GetLogIfAll(DWARF_LOG_DEBUG_MAP));
std::vector<uint32_t> oso_indexes;
-#if defined(DEBUG_OSO_DMAP)
-// StreamFile s(stdout);
-// symtab->Dump(&s, NULL, eSortOrderNone);
-#endif
// When a mach-o symbol is encoded, the n_type field is encoded in bits
// 23:16, and the n_desc field is encoded in bits 15:0.
//
@@ -399,7 +360,31 @@ SymbolFileDWARFDebugMap::InitOSO()
symtab->SortSymbolIndexesByValue(m_func_indexes, true);
symtab->SortSymbolIndexesByValue(m_glob_indexes, true);
+ for (uint32_t sym_idx : m_func_indexes)
+ {
+ const Symbol *symbol = symtab->SymbolAtIndex(sym_idx);
+ lldb::addr_t file_addr = symbol->GetAddress().GetFileAddress();
+ lldb::addr_t byte_size = symbol->GetByteSize();
+ DebugMap::Entry debug_map_entry(file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS));
+ m_debug_map.Append(debug_map_entry);
+ }
+ for (uint32_t sym_idx : m_glob_indexes)
+ {
+ const Symbol *symbol = symtab->SymbolAtIndex(sym_idx);
+ lldb::addr_t file_addr = symbol->GetAddress().GetFileAddress();
+ lldb::addr_t byte_size = symbol->GetByteSize();
+ DebugMap::Entry debug_map_entry(file_addr, byte_size, OSOEntry(sym_idx, LLDB_INVALID_ADDRESS));
+ m_debug_map.Append(debug_map_entry);
+ }
+ m_debug_map.Sort();
+
+#if defined(DEBUG_OSO_DMAP)
+ StreamFile s(stdout, false);
+ symtab->Dump(&s, NULL, m_func_indexes);
+ symtab->Dump(&s, NULL, m_glob_indexes);
+#endif
m_compile_unit_infos.resize(oso_index_count);
+
// s.Printf("%s N_OSO symbols:\n", __PRETTY_FUNCTION__);
// symtab->Dump(&s, oso_indexes);
@@ -643,34 +628,20 @@ SymbolFileDWARFDebugMap::ParseCompileUni
FileSpec so_file_spec;
if (GetFileSpecForSO (cu_idx, so_file_spec))
{
- Module *oso_module = GetModuleByOSOIndex (cu_idx);
- if (oso_module)
- {
- // User zero as the ID to match the compile unit at offset
- // zero in each .o file since each .o file can only have
- // one compile unit for now.
- lldb::user_id_t cu_id = 0;
- m_compile_unit_infos[cu_idx].compile_unit_sp.reset (new CompileUnit (oso_module->shared_from_this(),
- NULL,
- so_file_spec,
- cu_id,
- eLanguageTypeUnknown));
- }
-
- if (!m_compile_unit_infos[cu_idx].compile_unit_sp)
- {
- m_compile_unit_infos[cu_idx].compile_unit_sp.reset(new CompileUnit (m_obj_file->GetModule(),
- NULL,
- so_file_spec,
- cu_idx,
- eLanguageTypeUnknown));
- }
+ // User zero as the ID to match the compile unit at offset
+ // zero in each .o file since each .o file can only have
+ // one compile unit for now.
+ lldb::user_id_t cu_id = 0;
+ m_compile_unit_infos[cu_idx].compile_unit_sp.reset(new CompileUnit (m_obj_file->GetModule(),
+ NULL,
+ so_file_spec,
+ cu_id,
+ eLanguageTypeUnknown));
if (m_compile_unit_infos[cu_idx].compile_unit_sp)
{
// Let our symbol vendor know about this compile unit
- m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex (cu_idx,
- m_compile_unit_infos[cu_idx].compile_unit_sp);
+ m_obj_file->GetModule()->GetSymbolVendor()->SetCompileUnitAtIndex (cu_idx, m_compile_unit_infos[cu_idx].compile_unit_sp);
}
}
}
@@ -779,7 +750,7 @@ SymbolFileDWARFDebugMap::ResolveTypeUID(
const uint64_t oso_idx = GetOSOIndexFromUserID (type_uid);
SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
if (oso_dwarf)
- oso_dwarf->ResolveTypeUID (type_uid);
+ return oso_dwarf->ResolveTypeUID (type_uid);
return NULL;
}
@@ -798,30 +769,30 @@ SymbolFileDWARFDebugMap::ResolveSymbolCo
if (symtab)
{
const addr_t exe_file_addr = exe_so_addr.GetFileAddress();
- sc.symbol = symtab->FindSymbolContainingFileAddress (exe_file_addr, &m_func_indexes[0], m_func_indexes.size());
- if (sc.symbol != NULL)
+ const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains (exe_file_addr);
+ if (debug_map_entry)
{
- resolved_flags |= eSymbolContextSymbol;
- uint32_t oso_idx = 0;
- CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithID (sc.symbol->GetID(), &oso_idx);
- if (comp_unit_info)
- {
- SymbolFileDWARF *oso_dwarf = GetSymbolFileByOSOIndex (oso_idx);
- ObjectFile *oso_objfile = GetObjectFileByOSOIndex (oso_idx);
- if (oso_dwarf && oso_objfile)
- {
- SectionList *oso_section_list = oso_objfile->GetSectionList();
+ sc.symbol = symtab->SymbolAtIndex(debug_map_entry->data.GetExeSymbolIndex());
- SectionSP oso_symbol_section_sp (oso_section_list->FindSectionContainingLinkedFileAddress (exe_file_addr, UINT32_MAX));
+ if (sc.symbol != NULL)
+ {
+ resolved_flags |= eSymbolContextSymbol;
- if (oso_symbol_section_sp)
+ uint32_t oso_idx = 0;
+ CompileUnitInfo* comp_unit_info = GetCompileUnitInfoForSymbolWithID (sc.symbol->GetID(), &oso_idx);
+ if (comp_unit_info)
+ {
+ Module *oso_module = GetModuleByCompUnitInfo (comp_unit_info);
+ if (oso_module)
{
- const addr_t linked_file_addr = oso_symbol_section_sp->GetLinkedFileAddress();
- Address oso_so_addr (oso_symbol_section_sp, exe_file_addr - linked_file_addr);
- if (oso_so_addr.IsSectionOffset())
- resolved_flags |= oso_dwarf->ResolveSymbolContext (oso_so_addr, resolve_scope, sc);
+ lldb::addr_t oso_file_addr = exe_file_addr - debug_map_entry->GetRangeBase() + debug_map_entry->data.GetOSOFileAddress();
+ Address oso_so_addr;
+ if (oso_module->ResolveFileAddress(oso_file_addr, oso_so_addr))
+ {
+ resolved_flags |= oso_module->GetSymbolVendor()->ResolveSymbolContext (oso_so_addr, resolve_scope, sc);
+ }
}
}
}
@@ -1307,6 +1278,24 @@ SymbolFileDWARFDebugMap::GetCompileUnit
return lldb::CompUnitSP();
}
+SymbolFileDWARFDebugMap::CompileUnitInfo *
+SymbolFileDWARFDebugMap::GetCompileUnitInfo (SymbolFileDWARF *oso_dwarf)
+{
+ if (oso_dwarf)
+ {
+ const uint32_t cu_count = GetNumCompileUnits();
+ for (uint32_t cu_idx=0; cu_idx<cu_count; ++cu_idx)
+ {
+ SymbolFileDWARF *oso_symfile = GetSymbolFileByCompUnitInfo (&m_compile_unit_infos[cu_idx]);
+ if (oso_symfile == oso_dwarf)
+ {
+ return &m_compile_unit_infos[cu_idx];
+ }
+ }
+ }
+ return NULL;
+}
+
void
SymbolFileDWARFDebugMap::SetCompileUnit (SymbolFileDWARF *oso_dwarf, const CompUnitSP &cu_sp)
@@ -1415,4 +1404,99 @@ SymbolFileDWARFDebugMap::GetClangDeclCon
return NULL;
}
+bool
+SymbolFileDWARFDebugMap::AddOSOFileRange (CompileUnitInfo *cu_info,
+ lldb::addr_t exe_file_addr,
+ lldb::addr_t oso_file_addr,
+ lldb::addr_t oso_byte_size)
+{
+ assert (cu_info);// REMOVE THIS PRIOR TO CHECKIN
+ const uint32_t debug_map_idx = m_debug_map.FindEntryIndexThatContains(exe_file_addr);
+ if (debug_map_idx != UINT32_MAX)
+ {
+ DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(exe_file_addr);
+ assert (debug_map_entry);// REMOVE THIS PRIOR TO CHECKIN
+ debug_map_entry->data.SetOSOFileAddress(oso_file_addr);
+ cu_info->file_range_map.Append(FileRangeMap::Entry(oso_file_addr, oso_byte_size, exe_file_addr));
+ return true;
+ }
+ return false;
+}
+
+void
+SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (CompileUnitInfo *cu_info)
+{
+ cu_info->file_range_map.Sort();
+#if defined(DEBUG_OSO_DMAP)
+ const FileRangeMap &oso_file_range_map = cu_info->GetFileRangeMap(this);
+ const size_t n = oso_file_range_map.GetSize();
+ printf ("SymbolFileDWARFDebugMap::FinalizeOSOFileRanges (cu_info = %p)\n", cu_info);
+ for (size_t i=0; i<n; ++i)
+ {
+ const FileRangeMap::Entry &entry = oso_file_range_map.GetEntryRef(i);
+ printf ("oso [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ") ==> exe [0x%16.16" PRIx64 " - 0x%16.16" PRIx64 ")\n",
+ entry.GetRangeBase(), entry.GetRangeEnd(),
+ entry.data, entry.data + entry.GetByteSize());
+ }
+#endif
+}
+
+lldb::addr_t
+SymbolFileDWARFDebugMap::LinkOSOFileAddress (SymbolFileDWARF *oso_symfile, lldb::addr_t oso_file_addr)
+{
+ CompileUnitInfo *cu_info = GetCompileUnitInfo (oso_symfile);
+ if (cu_info)
+ {
+ const FileRangeMap::Entry *oso_range_entry = cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr);
+ if (oso_range_entry)
+ {
+ const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(oso_range_entry->data);
+ if (debug_map_entry)
+ {
+ const lldb::addr_t offset = oso_file_addr - oso_range_entry->GetRangeBase();
+ const lldb::addr_t exe_file_addr = debug_map_entry->GetRangeBase() + offset;
+ return exe_file_addr;
+ }
+ }
+ }
+ return LLDB_INVALID_ADDRESS;
+}
+
+bool
+SymbolFileDWARFDebugMap::LinkOSOAddress (Address &addr)
+{
+ // Make sure this address hasn't been fixed already
+ Module *exe_module = GetObjectFile()->GetModule().get();
+ Module *addr_module = addr.GetModule().get();
+ if (addr_module == exe_module)
+ return true; // Address is already in terms of the main executable module
+
+ CompileUnitInfo *cu_info = GetCompileUnitInfo ((SymbolFileDWARF *)addr_module->GetSymbolVendor()->GetSymbolFile());
+ if (cu_info)
+ {
+ const lldb::addr_t oso_file_addr = addr.GetFileAddress();
+ const FileRangeMap::Entry *oso_range_entry = cu_info->GetFileRangeMap(this).FindEntryThatContains(oso_file_addr);
+ if (oso_range_entry)
+ {
+ const DebugMap::Entry *debug_map_entry = m_debug_map.FindEntryThatContains(oso_range_entry->data);
+ if (debug_map_entry)
+ {
+ const lldb::addr_t offset = oso_file_addr - oso_range_entry->GetRangeBase();
+ const lldb::addr_t exe_file_addr = debug_map_entry->GetRangeBase() + offset;
+ return exe_module->ResolveFileAddress(exe_file_addr, addr);
+ }
+ }
+ }
+ return true;
+}
+
+LineTable *
+SymbolFileDWARFDebugMap::LinkOSOLineTable (SymbolFileDWARF *oso_dwarf, LineTable *line_table)
+{
+ CompileUnitInfo *cu_info = GetCompileUnitInfo (oso_dwarf);
+ if (cu_info)
+ return line_table->LinkLineTable(cu_info->GetFileRangeMap(this));
+ return NULL;
+}
+
Modified: lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h (original)
+++ lldb/trunk/source/Plugins/SymbolFile/DWARF/SymbolFileDWARFDebugMap.h Mon Mar 4 15:46:16 2013
@@ -16,6 +16,7 @@
#include "clang/AST/CharUnits.h"
+#include "lldb/Core/RangeMap.h"
#include "lldb/Symbol/SymbolFile.h"
#include "UniqueDWARFASTType.h"
@@ -143,6 +144,8 @@ protected:
typedef STD_SHARED_PTR(OSOInfo) OSOInfoSP;
+ typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, lldb::addr_t> FileRangeMap;
+
//------------------------------------------------------------------
// Class specific types
//------------------------------------------------------------------
@@ -156,6 +159,9 @@ protected:
uint32_t last_symbol_index;
uint32_t first_symbol_id;
uint32_t last_symbol_id;
+ FileRangeMap file_range_map;
+ bool file_range_map_valid;
+
CompileUnitInfo() :
so_file (),
@@ -165,9 +171,14 @@ protected:
first_symbol_index (UINT32_MAX),
last_symbol_index (UINT32_MAX),
first_symbol_id (UINT32_MAX),
- last_symbol_id (UINT32_MAX)
+ last_symbol_id (UINT32_MAX),
+ file_range_map (),
+ file_range_map_valid (false)
{
}
+
+ const FileRangeMap &
+ GetFileRangeMap(SymbolFileDWARFDebugMap *exe_symfile);
};
//------------------------------------------------------------------
@@ -240,6 +251,9 @@ protected:
lldb::CompUnitSP
GetCompileUnit (SymbolFileDWARF *oso_dwarf);
+
+ CompileUnitInfo *
+ GetCompileUnitInfo (SymbolFileDWARF *oso_dwarf);
lldb::TypeSP
FindDefinitionTypeForDWARFDeclContext (const DWARFDeclContext &die_decl_ctx);
@@ -258,6 +272,58 @@ protected:
{
return m_unique_ast_type_map;
}
+
+
+ //------------------------------------------------------------------
+ // OSOEntry
+ //------------------------------------------------------------------
+ class OSOEntry
+ {
+ public:
+
+ OSOEntry () :
+ m_exe_sym_idx (UINT32_MAX),
+ m_oso_file_addr (LLDB_INVALID_ADDRESS)
+ {
+ }
+
+ OSOEntry (uint32_t exe_sym_idx,
+ lldb::addr_t oso_file_addr) :
+ m_exe_sym_idx (exe_sym_idx),
+ m_oso_file_addr (oso_file_addr)
+ {
+ }
+
+ uint32_t
+ GetExeSymbolIndex () const
+ {
+ return m_exe_sym_idx;
+ }
+
+ bool
+ operator < (const OSOEntry &rhs) const
+ {
+ return m_exe_sym_idx < rhs.m_exe_sym_idx;
+ }
+
+ lldb::addr_t
+ GetOSOFileAddress () const
+ {
+ return m_oso_file_addr;
+ }
+
+ void
+ SetOSOFileAddress (lldb::addr_t oso_file_addr)
+ {
+ m_oso_file_addr = oso_file_addr;
+ }
+ protected:
+ uint32_t m_exe_sym_idx;
+ lldb::addr_t m_oso_file_addr;
+ };
+
+ typedef lldb_private::RangeDataVector<lldb::addr_t, lldb::addr_t, OSOEntry> DebugMap;
+
//------------------------------------------------------------------
// Member Variables
//------------------------------------------------------------------
@@ -268,6 +334,77 @@ protected:
std::map<lldb_private::ConstString, OSOInfoSP> m_oso_map;
UniqueDWARFASTTypeMap m_unique_ast_type_map;
lldb_private::LazyBool m_supports_DW_AT_APPLE_objc_complete_type;
+ DebugMap m_debug_map;
+
+ //------------------------------------------------------------------
+ // When an object file from the debug map gets parsed in
+ // SymbolFileDWARF, it needs to tell the debug map about the object
+ // files addresses by calling this function once for each N_FUN,
+ // N_GSYM and N_STSYM and after all entries in the debug map have
+ // been matched up, FinalizeOSOFileRanges() should be called.
+ //------------------------------------------------------------------
+ bool
+ AddOSOFileRange (CompileUnitInfo *cu_info,
+ lldb::addr_t exe_file_addr,
+ lldb::addr_t oso_file_addr,
+ lldb::addr_t oso_byte_size);
+
+ //------------------------------------------------------------------
+ // Called after calling AddOSOFileRange() for each object file debug
+ // map entry to finalize the info for the unlinked compile unit.
+ //------------------------------------------------------------------
+ void
+ FinalizeOSOFileRanges (CompileUnitInfo *cu_info);
+
+ //------------------------------------------------------------------
+ /// Convert \a addr from a .o file address, to an executable address.
+ ///
+ /// @param[in] addr
+ /// A section offset address from a .o file
+ ///
+ /// @return
+ /// Returns true if \a addr was converted to be an executable
+ /// section/offset address, false otherwise.
+ //------------------------------------------------------------------
+ bool
+ LinkOSOAddress (lldb_private::Address &addr);
+
+ //------------------------------------------------------------------
+ /// Convert a .o file "file address" to an executable "file address".
+ ///
+ /// @param[in] oso_symfile
+ /// The DWARF symbol file that contains \a oso_file_addr
+ ///
+ /// @param[in] oso_file_addr
+ /// A .o file "file address" to convert.
+ ///
+ /// @return
+ /// LLDB_INVALID_ADDRESS if \a oso_file_addr is not in the
+ /// linked executable, otherwise a valid "file address" from the
+ /// linked executable that contains the debug map.
+ //------------------------------------------------------------------
+ lldb::addr_t
+ LinkOSOFileAddress (SymbolFileDWARF *oso_symfile, lldb::addr_t oso_file_addr);
+
+ //------------------------------------------------------------------
+ /// Given a line table full of lines with "file adresses" that are
+ /// for a .o file represented by \a oso_symfile, link a new line table
+ /// and return it.
+ ///
+ /// @param[in] oso_symfile
+ /// The DWARF symbol file that produced the \a line_table
+ ///
+ /// @param[in] addr
+ /// A section offset address from a .o file
+ ///
+ /// @return
+ /// Returns a valid line table full of linked addresses, or NULL
+ /// if none of the line table adresses exist in the main
+ /// executable.
+ //------------------------------------------------------------------
+ lldb_private::LineTable *
+ LinkOSOLineTable (SymbolFileDWARF *oso_symfile,
+ lldb_private::LineTable *line_table);
};
#endif // #ifndef SymbolFileDWARF_SymbolFileDWARFDebugMap_h_
Modified: lldb/trunk/source/Symbol/Function.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Function.cpp?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/Function.cpp (original)
+++ lldb/trunk/source/Symbol/Function.cpp Mon Mar 4 15:46:16 2013
@@ -392,13 +392,7 @@ Function::CalculateSymbolContextModule (
{
SectionSP section_sp (m_range.GetBaseAddress().GetSection());
if (section_sp)
- {
- SectionSP linked_section_sp (section_sp->GetLinkedSection());
- if (linked_section_sp)
- return linked_section_sp->GetModule();
- else
- return section_sp->GetModule();
- }
+ return section_sp->GetModule();
return this->GetCompileUnit()->GetModule();
}
Modified: lldb/trunk/source/Symbol/LineTable.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/LineTable.cpp?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/LineTable.cpp (original)
+++ lldb/trunk/source/Symbol/LineTable.cpp Mon Mar 4 15:46:16 2013
@@ -8,6 +8,7 @@
//===----------------------------------------------------------------------===//
#include "lldb/Core/Address.h"
+#include "lldb/Core/Module.h"
#include "lldb/Core/Section.h"
#include "lldb/Core/Stream.h"
#include "lldb/Symbol/CompileUnit.h"
@@ -22,7 +23,6 @@ using namespace lldb_private;
//----------------------------------------------------------------------
LineTable::LineTable(CompileUnit* comp_unit) :
m_comp_unit(comp_unit),
- m_section_list(),
m_entries()
{
}
@@ -37,8 +37,7 @@ LineTable::~LineTable()
void
LineTable::InsertLineEntry
(
- const SectionSP& section_sp,
- lldb::addr_t section_offset,
+ lldb::addr_t file_addr,
uint32_t line,
uint16_t column,
uint16_t file_idx,
@@ -49,21 +48,7 @@ LineTable::InsertLineEntry
bool is_terminal_entry
)
{
- SectionSP line_section_sp;
- SectionSP linked_section_sp (section_sp->GetLinkedSection());
- if (linked_section_sp)
- {
- section_offset += section_sp->GetLinkedOffset();
- line_section_sp = linked_section_sp;
- }
- else
- {
- line_section_sp = section_sp;
- }
- assert(line_section_sp.get());
-
- uint32_t sect_idx = m_section_list.AddUniqueSection (line_section_sp);
- Entry entry(sect_idx, section_offset, line, column, file_idx, is_start_of_statement, is_start_of_basic_block, is_prologue_end, is_epilogue_begin, is_terminal_entry);
+ Entry entry(file_addr, line, column, file_idx, is_start_of_statement, is_start_of_basic_block, is_prologue_end, is_epilogue_begin, is_terminal_entry);
entry_collection::iterator begin_pos = m_entries.begin();
entry_collection::iterator end_pos = m_entries.end();
@@ -85,7 +70,7 @@ LineSequence::LineSequence()
void
LineTable::LineSequenceImpl::Clear()
{
- m_seq_entries.clear();
+ m_entries.clear();
}
LineSequence* LineTable::CreateLineSequenceContainer ()
@@ -97,8 +82,7 @@ void
LineTable::AppendLineEntryToSequence
(
LineSequence* sequence,
- const SectionSP& section_sp,
- lldb::addr_t section_offset,
+ lldb::addr_t file_addr,
uint32_t line,
uint16_t column,
uint16_t file_idx,
@@ -111,9 +95,8 @@ LineTable::AppendLineEntryToSequence
{
assert(sequence != NULL);
LineSequenceImpl* seq = reinterpret_cast<LineSequenceImpl*>(sequence);
- uint32_t sect_idx = m_section_list.AddUniqueSection (section_sp);
- Entry entry(sect_idx, section_offset, line, column, file_idx, is_start_of_statement, is_start_of_basic_block, is_prologue_end, is_epilogue_begin, is_terminal_entry);
- seq->m_seq_entries.push_back (entry);
+ Entry entry(file_addr, line, column, file_idx, is_start_of_statement, is_start_of_basic_block, is_prologue_end, is_epilogue_begin, is_terminal_entry);
+ seq->m_entries.push_back (entry);
}
void
@@ -121,17 +104,17 @@ LineTable::InsertSequence (LineSequence*
{
assert(sequence != NULL);
LineSequenceImpl* seq = reinterpret_cast<LineSequenceImpl*>(sequence);
- if (seq->m_seq_entries.empty())
+ if (seq->m_entries.empty())
return;
- Entry& entry = seq->m_seq_entries.front();
-
+ Entry& entry = seq->m_entries.front();
+
// If the first entry address in this sequence is greater than or equal to
// the address of the last item in our entry collection, just append.
if (m_entries.empty() || !Entry::EntryAddressLessThan(entry, m_entries.back()))
{
m_entries.insert(m_entries.end(),
- seq->m_seq_entries.begin(),
- seq->m_seq_entries.end());
+ seq->m_entries.begin(),
+ seq->m_entries.end());
return;
}
@@ -149,7 +132,7 @@ LineTable::InsertSequence (LineSequence*
assert(prev_pos->is_terminal_entry);
}
#endif
- m_entries.insert(pos, seq->m_seq_entries.begin(), seq->m_seq_entries.end());
+ m_entries.insert(pos, seq->m_entries.begin(), seq->m_entries.end());
}
//----------------------------------------------------------------------
@@ -161,37 +144,23 @@ LineTable::Entry::LessThanBinaryPredicat
bool
LineTable::Entry::LessThanBinaryPredicate::operator() (const LineTable::Entry& a, const LineTable::Entry& b) const
{
- if (a.sect_idx == b.sect_idx)
- {
- #define LT_COMPARE(a,b) if (a != b) return a < b
- LT_COMPARE (a.sect_offset, b.sect_offset);
- // b and a reversed on purpose below.
- LT_COMPARE (b.is_terminal_entry, a.is_terminal_entry);
- LT_COMPARE (a.line, b.line);
- LT_COMPARE (a.column, b.column);
- LT_COMPARE (a.is_start_of_statement, b.is_start_of_statement);
- LT_COMPARE (a.is_start_of_basic_block, b.is_start_of_basic_block);
- // b and a reversed on purpose below.
- LT_COMPARE (b.is_prologue_end, a.is_prologue_end);
- LT_COMPARE (a.is_epilogue_begin, b.is_epilogue_begin);
- LT_COMPARE (a.file_idx, b.file_idx);
- return false;
- #undef LT_COMPARE
- }
-
- const Section *a_section = m_line_table->GetSectionForEntryIndex (a.sect_idx);
- const Section *b_section = m_line_table->GetSectionForEntryIndex (b.sect_idx);
- return Section::Compare(*a_section, *b_section) < 0;
+ #define LT_COMPARE(a,b) if (a != b) return a < b
+ LT_COMPARE (a.file_addr, b.file_addr);
+ // b and a reversed on purpose below.
+ LT_COMPARE (b.is_terminal_entry, a.is_terminal_entry);
+ LT_COMPARE (a.line, b.line);
+ LT_COMPARE (a.column, b.column);
+ LT_COMPARE (a.is_start_of_statement, b.is_start_of_statement);
+ LT_COMPARE (a.is_start_of_basic_block, b.is_start_of_basic_block);
+ // b and a reversed on purpose below.
+ LT_COMPARE (b.is_prologue_end, a.is_prologue_end);
+ LT_COMPARE (a.is_epilogue_begin, b.is_epilogue_begin);
+ LT_COMPARE (a.file_idx, b.file_idx);
+ return false;
+ #undef LT_COMPARE
}
-Section *
-LineTable::GetSectionForEntryIndex (uint32_t idx)
-{
- if (idx < m_section_list.GetSize())
- return m_section_list.GetSectionAtIndex(idx).get();
- return NULL;
-}
uint32_t
LineTable::GetSize() const
@@ -218,69 +187,69 @@ LineTable::FindLineEntryByAddress (const
*index_ptr = UINT32_MAX;
bool success = false;
- uint32_t sect_idx = m_section_list.FindSectionIndex (so_addr.GetSection().get());
- if (sect_idx != UINT32_MAX)
+
+ if (so_addr.GetModule().get() == m_comp_unit->GetModule().get())
{
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)
+ search_entry.file_addr = so_addr.GetFileAddress();
+ if (search_entry.file_addr != LLDB_INVALID_ADDRESS)
{
- if (pos != begin_pos)
+ 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->sect_offset != search_entry.sect_offset)
- --pos;
- else if (pos->sect_offset == search_entry.sect_offset)
+ if (pos != begin_pos)
{
- // 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)
+ if (pos->file_addr != search_entry.file_addr)
+ --pos;
+ else if (pos->file_addr == search_entry.file_addr)
{
- // 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 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)
{
- if (pos->sect_offset != search_entry.sect_offset)
- pos = end_pos;
+ // 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->file_addr != search_entry.file_addr)
+ 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)
+
+ if (pos != end_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;
+ // 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->file_addr == search_entry.file_addr &&
+ prev_pos->is_terminal_entry == false)
+ --pos;
+ else
+ break;
+ }
}
}
- }
- }
-
- // Make sure we have a valid match and that the match isn't a terminating
- // entry for a previous line...
- if (pos != end_pos && pos->is_terminal_entry == false)
- {
- uint32_t match_idx = std::distance (begin_pos, pos);
- success = ConvertEntryAtIndexToLineEntry(match_idx, line_entry);
- if (index_ptr != NULL && success)
- *index_ptr = match_idx;
+ }
+
+ // Make sure we have a valid match and that the match isn't a terminating
+ // entry for a previous line...
+ if (pos != end_pos && pos->is_terminal_entry == false)
+ {
+ uint32_t match_idx = std::distance (begin_pos, pos);
+ success = ConvertEntryAtIndexToLineEntry(match_idx, line_entry);
+ if (index_ptr != NULL && success)
+ *index_ptr = match_idx;
+ }
}
}
}
@@ -294,32 +263,24 @@ LineTable::ConvertEntryAtIndexToLineEntr
if (idx < m_entries.size())
{
const Entry& entry = m_entries[idx];
- line_entry.range.GetBaseAddress().SetSection(m_section_list.GetSectionAtIndex (entry.sect_idx));
- line_entry.range.GetBaseAddress().SetOffset(entry.sect_offset);
- if (!entry.is_terminal_entry && idx + 1 < m_entries.size())
+ ModuleSP module_sp (m_comp_unit->GetModule());
+ if (module_sp && module_sp->ResolveFileAddress(entry.file_addr, line_entry.range.GetBaseAddress()))
{
- const Entry& next_entry = m_entries[idx+1];
- if (next_entry.sect_idx == entry.sect_idx)
- {
- line_entry.range.SetByteSize(next_entry.sect_offset - entry.sect_offset);
- }
+ if (!entry.is_terminal_entry && idx + 1 < m_entries.size())
+ line_entry.range.SetByteSize(m_entries[idx+1].file_addr - entry.file_addr);
else
- {
- Address next_line_addr(m_section_list.GetSectionAtIndex (next_entry.sect_idx), next_entry.sect_offset);
- line_entry.range.SetByteSize(next_line_addr.GetFileAddress() - line_entry.range.GetBaseAddress().GetFileAddress());
- }
+ line_entry.range.SetByteSize(0);
+
+ line_entry.file = m_comp_unit->GetSupportFiles().GetFileSpecAtIndex (entry.file_idx);
+ line_entry.line = entry.line;
+ line_entry.column = entry.column;
+ line_entry.is_start_of_statement = entry.is_start_of_statement;
+ line_entry.is_start_of_basic_block = entry.is_start_of_basic_block;
+ line_entry.is_prologue_end = entry.is_prologue_end;
+ line_entry.is_epilogue_begin = entry.is_epilogue_begin;
+ line_entry.is_terminal_entry = entry.is_terminal_entry;
+ return true;
}
- else
- line_entry.range.SetByteSize(0);
- line_entry.file = m_comp_unit->GetSupportFiles().GetFileSpecAtIndex (entry.file_idx);
- line_entry.line = entry.line;
- line_entry.column = entry.column;
- line_entry.is_start_of_statement = entry.is_start_of_statement;
- line_entry.is_start_of_basic_block = entry.is_start_of_basic_block;
- line_entry.is_prologue_end = entry.is_prologue_end;
- line_entry.is_epilogue_begin = entry.is_epilogue_begin;
- line_entry.is_terminal_entry = entry.is_terminal_entry;
- return true;
}
return false;
}
@@ -503,7 +464,6 @@ LineTable::GetContiguousFileAddressRange
const size_t count = m_entries.size();
LineEntry line_entry;
- std::vector<addr_t> section_base_file_addrs (m_section_list.GetSize(), LLDB_INVALID_ADDRESS);
FileAddressRanges::Entry range (LLDB_INVALID_ADDRESS, 0);
for (size_t idx = 0; idx < count; ++idx)
{
@@ -513,23 +473,89 @@ LineTable::GetContiguousFileAddressRange
{
if (range.GetRangeBase() != LLDB_INVALID_ADDRESS)
{
- if (section_base_file_addrs[entry.sect_idx] == LLDB_INVALID_ADDRESS)
- section_base_file_addrs[entry.sect_idx] = m_section_list.GetSectionAtIndex (entry.sect_idx)->GetFileAddress();
- range.SetRangeEnd(section_base_file_addrs[entry.sect_idx] + entry.sect_offset);
+ range.SetRangeEnd(entry.file_addr);
file_ranges.Append(range);
range.Clear(LLDB_INVALID_ADDRESS);
}
}
else if (range.GetRangeBase() == LLDB_INVALID_ADDRESS)
{
- if (section_base_file_addrs[entry.sect_idx] == LLDB_INVALID_ADDRESS)
- section_base_file_addrs[entry.sect_idx] = m_section_list.GetSectionAtIndex (entry.sect_idx)->GetFileAddress();
- range.SetRangeBase(section_base_file_addrs[entry.sect_idx] + entry.sect_offset);
+ range.SetRangeBase(entry.file_addr);
}
}
return file_ranges.GetSize() - initial_count;
}
+LineTable *
+LineTable::LinkLineTable (const FileRangeMap &file_range_map)
+{
+ std::auto_ptr<LineTable> line_table_ap (new LineTable (m_comp_unit));
+ LineSequenceImpl sequence;
+ const size_t count = m_entries.size();
+ LineEntry line_entry;
+ const FileRangeMap::Entry *file_range_entry = NULL;
+ const FileRangeMap::Entry *prev_file_range_entry = NULL;
+ lldb::addr_t prev_file_addr = LLDB_INVALID_ADDRESS;
+ bool prev_entry_was_linked = false;
+ for (size_t idx = 0; idx < count; ++idx)
+ {
+ const Entry& entry = m_entries[idx];
+
+ const bool end_sequence = entry.is_terminal_entry;
+ const lldb::addr_t lookup_file_addr = entry.file_addr - (end_sequence ? 1 : 0);
+ if (file_range_entry == NULL || !file_range_entry->Contains(lookup_file_addr))
+ {
+ prev_file_range_entry = file_range_entry;
+ file_range_entry = file_range_map.FindEntryThatContains(lookup_file_addr);
+ }
+
+ if (file_range_entry)
+ {
+ // This entry has an address remapping and it needs to have its address relinked
+ sequence.m_entries.push_back(entry);
+ // Fix tha addresss
+ const lldb::addr_t linked_file_addr = entry.file_addr - file_range_entry->GetRangeBase() + file_range_entry->data;
+// if (linked_file_addr == 0x000000000128b7d5)
+// puts("remove this");
+ sequence.m_entries.back().file_addr = linked_file_addr;
+ }
+ else if (prev_entry_was_linked)
+ {
+ // This entry doesn't have a remapping and it needs to be removed.
+ // Watch out in case we need to terminate a previous entry needs to
+ // be terminated now that one line entry in a sequence is not longer valid.
+ if (!entry.is_terminal_entry &&
+ !sequence.m_entries.empty() &&
+ !sequence.m_entries.back().is_terminal_entry)
+ {
+ assert (prev_file_addr != LLDB_INVALID_ADDRESS);
+ sequence.m_entries.push_back(sequence.m_entries.back());
+ const lldb::addr_t linked_file_addr = std::min<lldb::addr_t>(entry.file_addr,prev_file_range_entry->GetRangeEnd()) - prev_file_range_entry->GetRangeBase() + prev_file_range_entry->data;
+ sequence.m_entries.back().file_addr = linked_file_addr;
+ sequence.m_entries.back().is_terminal_entry = true;
+ }
+ }
+
+ // If we have items in the sequence and the last entry is a terminal entry,
+ // insert this sequence into our new line table.
+ if (!sequence.m_entries.empty() && sequence.m_entries.back().is_terminal_entry)
+ {
+ line_table_ap->InsertSequence (&sequence);
+ sequence.Clear();
+ prev_entry_was_linked = false;
+ prev_file_addr = LLDB_INVALID_ADDRESS;
+ }
+ else
+ {
+ prev_entry_was_linked = file_range_entry != NULL;
+ prev_file_addr = entry.file_addr;
+ }
+ }
+ if (line_table_ap->m_entries.empty())
+ return NULL;
+ return line_table_ap.release();
+}
+
Modified: lldb/trunk/source/Symbol/ObjectFile.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/ObjectFile.cpp?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/ObjectFile.cpp (original)
+++ lldb/trunk/source/Symbol/ObjectFile.cpp Mon Mar 4 15:46:16 2013
@@ -200,8 +200,10 @@ ObjectFile::ObjectFile (const lldb::Modu
m_data (),
m_unwind_table (*this),
m_process_wp(),
- m_memory_addr (LLDB_INVALID_ADDRESS)
-{
+ m_memory_addr (LLDB_INVALID_ADDRESS),
+ m_sections_ap (),
+ m_symtab_ap ()
+{
if (file_spec_ptr)
m_file = *file_spec_ptr;
if (data_sp)
@@ -209,12 +211,16 @@ ObjectFile::ObjectFile (const lldb::Modu
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
if (log)
{
+ const ConstString object_name (module_sp->GetObjectName());
if (m_file)
{
- log->Printf ("%p ObjectFile::ObjectFile () module = %s/%s, file = %s/%s, file_offset = 0x%8.8" PRIx64 ", size = %" PRIu64 "\n",
+ log->Printf ("%p ObjectFile::ObjectFile() module = %p (%s%s%s%s), file = %s/%s, file_offset = 0x%8.8" PRIx64 ", size = %" PRIu64,
this,
- module_sp->GetFileSpec().GetDirectory().AsCString(),
+ module_sp.get(),
module_sp->GetFileSpec().GetFilename().AsCString(),
+ object_name ? "(" : "",
+ object_name ? object_name.GetCString() : "",
+ object_name ? ")" : "",
m_file.GetDirectory().AsCString(),
m_file.GetFilename().AsCString(),
m_file_offset,
@@ -222,10 +228,13 @@ ObjectFile::ObjectFile (const lldb::Modu
}
else
{
- log->Printf ("%p ObjectFile::ObjectFile () module = %s/%s, file = <NULL>, file_offset = 0x%8.8" PRIx64 ", size = %" PRIu64 "\n",
+ log->Printf ("%p ObjectFile::ObjectFile() module = %p (%s%s%s%s), file = <NULL>, file_offset = 0x%8.8" PRIx64 ", size = %" PRIu64,
this,
- module_sp->GetFileSpec().GetDirectory().AsCString(),
+ module_sp.get(),
module_sp->GetFileSpec().GetFilename().AsCString(),
+ object_name ? "(" : "",
+ object_name ? object_name.GetCString() : "",
+ object_name ? ")" : "",
m_file_offset,
m_length);
}
@@ -246,17 +255,23 @@ ObjectFile::ObjectFile (const lldb::Modu
m_data (),
m_unwind_table (*this),
m_process_wp (process_sp),
- m_memory_addr (header_addr)
-{
+ m_memory_addr (header_addr),
+ m_sections_ap (),
+ m_symtab_ap ()
+{
if (header_data_sp)
m_data.SetData (header_data_sp, 0, header_data_sp->GetByteSize());
LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
if (log)
{
- log->Printf ("%p ObjectFile::ObjectFile () module = %s/%s, process = %p, header_addr = 0x%" PRIx64 "\n",
+ const ConstString object_name (module_sp->GetObjectName());
+ log->Printf ("%p ObjectFile::ObjectFile() module = %p (%s%s%s%s), process = %p, header_addr = 0x%" PRIx64,
this,
- module_sp->GetFileSpec().GetDirectory().AsCString(),
+ module_sp.get(),
module_sp->GetFileSpec().GetFilename().AsCString(),
+ object_name ? "(" : "",
+ object_name ? object_name.GetCString() : "",
+ object_name ? ")" : "",
process_sp.get(),
m_memory_addr);
}
@@ -519,3 +534,20 @@ ObjectFile::SplitArchivePathWithObject (
return false;
}
+void
+ObjectFile::ClearSymtab ()
+{
+ ModuleSP module_sp(GetModule());
+ if (module_sp)
+ {
+ lldb_private::Mutex::Locker locker(module_sp->GetMutex());
+ LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_OBJECT));
+ if (log)
+ {
+ log->Printf ("%p ObjectFile::ClearSymtab () symtab = %p",
+ this,
+ m_symtab_ap.get());
+ }
+ m_symtab_ap.reset();
+ }
+}
Modified: lldb/trunk/source/Symbol/Symtab.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/source/Symbol/Symtab.cpp?rev=176454&r1=176453&r2=176454&view=diff
==============================================================================
--- lldb/trunk/source/Symbol/Symtab.cpp (original)
+++ lldb/trunk/source/Symbol/Symtab.cpp Mon Mar 4 15:46:16 2013
@@ -11,6 +11,7 @@
#include "lldb/Core/Module.h"
#include "lldb/Core/RegularExpression.h"
+#include "lldb/Core/Section.h"
#include "lldb/Core/Timer.h"
#include "lldb/Symbol/ObjectFile.h"
#include "lldb/Symbol/SymbolContext.h"
@@ -882,13 +883,13 @@ Symtab::CalculateSymbolSize (Symbol *sym
if (!m_addr_indexes_computed)
InitAddressIndexes();
const size_t num_addr_indexes = m_addr_indexes.size();
+ const lldb::addr_t symbol_file_addr = symbol->GetAddress().GetFileAddress();
SymbolSearchInfo info = FindIndexPtrForSymbolContainingAddress (this,
- symbol->GetAddress().GetFileAddress(),
+ symbol_file_addr,
&m_addr_indexes.front(),
num_addr_indexes);
if (info.match_index_ptr != NULL)
{
- const lldb::addr_t curr_file_addr = symbol->GetAddress().GetFileAddress();
// We can figure out the address range of all symbols except the
// last one by taking the delta between the current symbol and
// the next symbol
@@ -899,15 +900,32 @@ Symtab::CalculateSymbolSize (Symbol *sym
{
Symbol *next_symbol = SymbolAtIndex(m_addr_indexes[addr_index]);
if (next_symbol == NULL)
- break;
-
- const lldb::addr_t next_file_addr = next_symbol->GetAddress().GetFileAddress();
- if (next_file_addr > curr_file_addr)
{
- byte_size = next_file_addr - curr_file_addr;
- symbol->SetByteSize(byte_size);
- symbol->SetSizeIsSynthesized(true);
- break;
+ // No next symbol take the size to be the remaining bytes in the section
+ // in which the symbol resides
+ SectionSP section_sp (m_objfile->GetSectionList()->FindSectionContainingFileAddress (symbol_file_addr));
+ if (section_sp)
+ {
+ const lldb::addr_t end_section_file_addr = section_sp->GetFileAddress() + section_sp->GetByteSize();
+ if (end_section_file_addr > symbol_file_addr)
+ {
+ byte_size = end_section_file_addr - symbol_file_addr;
+ symbol->SetByteSize(byte_size);
+ symbol->SetSizeIsSynthesized(true);
+ break;
+ }
+ }
+ }
+ else
+ {
+ const lldb::addr_t next_file_addr = next_symbol->GetAddress().GetFileAddress();
+ if (next_file_addr > symbol_file_addr)
+ {
+ byte_size = next_file_addr - symbol_file_addr;
+ symbol->SetByteSize(byte_size);
+ symbol->SetSizeIsSynthesized(true);
+ break;
+ }
}
}
}
More information about the lldb-commits
mailing list