diff options
author | Greg Clayton <gclayton@apple.com> | 2010-08-30 18:11:35 +0000 |
---|---|---|
committer | Greg Clayton <gclayton@apple.com> | 2010-08-30 18:11:35 +0000 |
commit | 59e8fc1c7404de213591bc416bb7800539bfc575 (patch) | |
tree | ece73e90414bf24f5f03a292aaa6bd7777b5fa5e | |
parent | e2f8bdac14c92de971852eb41dd0f70d202953f4 (diff) | |
download | bcm5719-llvm-59e8fc1c7404de213591bc416bb7800539bfc575.tar.gz bcm5719-llvm-59e8fc1c7404de213591bc416bb7800539bfc575.zip |
Clarified the intent of the SymbolContextScope class in the header
documentation. Symbol now inherits from the symbol
context scope so that the StackID can use a "SymbolContextScope *"
instead of a blockID (which could have been the same as some other
blockID from another symbol file).
Modified the stacks that are created on subsequent stops to reuse
the previous stack frame objects which will allow for some internal
optimization using pointer comparisons during stepping.
llvm-svn: 112495
-rw-r--r-- | lldb/include/lldb/Core/Address.h | 27 | ||||
-rw-r--r-- | lldb/include/lldb/Symbol/Symbol.h | 20 | ||||
-rw-r--r-- | lldb/include/lldb/Symbol/SymbolContextScope.h | 54 | ||||
-rw-r--r-- | lldb/include/lldb/Symbol/Variable.h | 18 | ||||
-rw-r--r-- | lldb/include/lldb/Target/StackFrame.h | 49 | ||||
-rw-r--r-- | lldb/include/lldb/Target/StackID.h | 38 | ||||
-rw-r--r-- | lldb/source/Core/Address.cpp | 9 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/Utility/UnwindLibUnwind.cpp | 2 | ||||
-rw-r--r-- | lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp | 2 | ||||
-rw-r--r-- | lldb/source/Symbol/Symbol.cpp | 45 | ||||
-rw-r--r-- | lldb/source/Symbol/Variable.cpp | 10 | ||||
-rw-r--r-- | lldb/source/Target/StackFrame.cpp | 157 | ||||
-rw-r--r-- | lldb/source/Target/StackFrameList.cpp | 155 | ||||
-rw-r--r-- | lldb/source/Target/StackID.cpp | 29 |
14 files changed, 406 insertions, 209 deletions
diff --git a/lldb/include/lldb/Core/Address.h b/lldb/include/lldb/Core/Address.h index 35491d7a846..85f0e9a6cbf 100644 --- a/lldb/include/lldb/Core/Address.h +++ b/lldb/include/lldb/Core/Address.h @@ -51,8 +51,7 @@ namespace lldb_private { /// this happens, breakpoints that are in one of these sections can be /// set/cleared. //---------------------------------------------------------------------- -class Address : - public SymbolContextScope +class Address { public: //------------------------------------------------------------------ @@ -98,7 +97,6 @@ public: /// offset (LLDB_INVALID_ADDRESS). //------------------------------------------------------------------ Address () : - SymbolContextScope(), m_section (NULL), m_offset (LLDB_INVALID_ADDRESS) { @@ -114,7 +112,6 @@ public: /// A const Address object reference to copy. //------------------------------------------------------------------ Address (const Address& rhs) : - SymbolContextScope(rhs), m_section (rhs.m_section), m_offset (rhs.m_offset) { @@ -134,7 +131,6 @@ public: /// The offset in bytes into \a section. //------------------------------------------------------------------ Address (const Section* section, lldb::addr_t offset) : - SymbolContextScope(), m_section (section), m_offset (offset) { @@ -433,27 +429,24 @@ public: SetSection (const Section* section) { m_section = section; } //------------------------------------------------------------------ - /// @copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*) + /// Reconstruct a symbol context from ad address. /// - /// @see SymbolContextScope - //------------------------------------------------------------------ - void - CalculateSymbolContext (SymbolContext *sc); - - //------------------------------------------------------------------ - /// @copydoc SymbolContextScope::DumpSymbolContext(Stream*) + /// This class doesn't inherit from SymbolContextScope because many + /// address objects have short lifespans. Address objects that are + /// section offset can reconstruct their symbol context by looking + /// up the address in the module found in the section. /// - /// @see SymbolContextScope + /// @see SymbolContextScope::CalculateSymbolContext(SymbolContext*) //------------------------------------------------------------------ void - DumpSymbolContext (Stream *s); + CalculateSymbolContext (SymbolContext *sc); protected: //------------------------------------------------------------------ // Member variables. //------------------------------------------------------------------ - const Section* m_section; ///< The section for the address, can be NULL. - lldb::addr_t m_offset; ///< Offset into section if \a m_section != NULL, else the absolute address value. + const Section* m_section; ///< The section for the address, can be NULL. + lldb::addr_t m_offset; ///< Offset into section if \a m_section != NULL, else the absolute address value. }; //bool operator< (const Address& lhs, const Address& rhs); diff --git a/lldb/include/lldb/Symbol/Symbol.h b/lldb/include/lldb/Symbol/Symbol.h index ee4c2b4b7b7..019c6d4885c 100644 --- a/lldb/include/lldb/Symbol/Symbol.h +++ b/lldb/include/lldb/Symbol/Symbol.h @@ -14,11 +14,13 @@ #include "lldb/Core/AddressRange.h" #include "lldb/Core/Mangled.h" #include "lldb/Core/UserID.h" +#include "lldb/Symbol/SymbolContextScope.h" namespace lldb_private { class Symbol : - public UserID // Used to uniquely identify this symbol in its symbol table + public UserID, // Used to uniquely identify this symbol in its symbol table + public SymbolContextScope { public: // ObjectFile readers can classify their symbol table entries and searches can be made @@ -162,6 +164,22 @@ public: uint32_t GetPrologueByteSize (); + //------------------------------------------------------------------ + /// @copydoc SymbolContextScope::CalculateSymbolContext(SymbolContext*) + /// + /// @see SymbolContextScope + //------------------------------------------------------------------ + virtual void + CalculateSymbolContext (SymbolContext *sc); + + //------------------------------------------------------------------ + /// @copydoc SymbolContextScope::DumpSymbolContext(Stream*) + /// + /// @see SymbolContextScope + //------------------------------------------------------------------ + virtual void + DumpSymbolContext (Stream *s); + protected: Mangled m_mangled; // uniqued symbol name/mangled name pair diff --git a/lldb/include/lldb/Symbol/SymbolContextScope.h b/lldb/include/lldb/Symbol/SymbolContextScope.h index 9b9b9d698ae..7394da27a97 100644 --- a/lldb/include/lldb/Symbol/SymbolContextScope.h +++ b/lldb/include/lldb/Symbol/SymbolContextScope.h @@ -20,23 +20,47 @@ namespace lldb_private { //---------------------------------------------------------------------- /// @class SymbolContextScope SymbolContextScope.h "lldb/Symbol/SymbolContextScope.h" -/// @brief Inherit from this if your object can reconstruct its symbol -/// context. +/// @brief Inherit from this if your object is part of a symbol context +/// and can reconstruct its symbol context. /// -/// Many objects that have pointers back to parent objects that own them -/// that all inherit from this pure virtual class can reconstruct their -/// symbol context without having to keep a complete SymbolContextScope -/// object in the object state. Examples of these objects include: -/// Module, CompileUnit, Function, and Block. +/// Many objects that are part of a symbol context that have pointers +/// back to parent objects that own them. Any members of a symbol +/// context that, once they are built, will not go away, can inherit +/// from this pure virtual class and can then reconstruct their symbol +/// context without having to keep a complete SymbolContext object in +/// the object. /// -/// Other objects can contain a valid pointer to an instance of this -/// class so they can reconstruct the symbol context in which they are -/// scoped. Example objects include: Variable and Type. Such objects -/// can be scoped at a variety of levels: -/// @li module level for a built built in types. -/// @li file level for compile unit types and variables. -/// @li function or block level for types and variables defined in -/// a function body. +/// Examples of these objects include: +/// @li Module +/// @li CompileUnit +/// @li Function +/// @li Block +/// @li Symbol +/// +/// Other objects can store a "SymbolContextScope *" using any pointers +/// to one of the above objects. This allows clients to hold onto a +/// pointer that uniquely will identify a symbol context. Those clients +/// can then always reconstruct the symbol context using the pointer, or +/// use it to uniquely identify a symbol context for an object. +/// +/// Example objects include that currently use "SymbolContextScope *" +/// objects include: +/// @li Variable objects that can reconstruct where they are scoped +/// by making sure the SymbolContextScope * comes from the scope +/// in which the variable was declared. If a variable is a global, +/// the appropriate CompileUnit * will be used when creating the +/// variable. A static function variables, can the Block scope +/// in which the variable is defined. Function arguments can use +/// the Function object as their scope. The SymbolFile parsers +/// will set these correctly as the variables are parsed. +/// @li Type objects that know exactly in which scope they +/// originated much like the variables above. +/// @li StackID objects that are able to know that if the CFA +/// (stack pointer at the beginning of a function) and the +/// start PC for the function/symbol and the SymbolContextScope +/// pointer (a unique pointer that identifies a symbol context +/// location) match within the same thread, that the stack +/// frame is the same as the previous stack frame. /// /// Objects that adhere to this protocol can reconstruct enough of a /// symbol context to allow functions that take a symbol context to be diff --git a/lldb/include/lldb/Symbol/Variable.h b/lldb/include/lldb/Symbol/Variable.h index 0844943e9ca..514e1aa8290 100644 --- a/lldb/include/lldb/Symbol/Variable.h +++ b/lldb/include/lldb/Symbol/Variable.h @@ -29,7 +29,7 @@ public: Variable(lldb::user_id_t uid, const ConstString& name, Type *type, lldb::ValueType scope, - SymbolContextScope *context, + SymbolContextScope *owner_scope, Declaration* decl, const DWARFExpression& location, bool external, @@ -105,14 +105,14 @@ public: IsInScope (StackFrame *frame); protected: - ConstString m_name; // Name of the variable - Type * m_type; // The type pointer of the variable (int, struct, class, etc) - lldb::ValueType m_scope; // global, parameter, local - SymbolContextScope *m_context;// The symbol file scope that this variable was defined in - Declaration m_declaration; // Declaration location for this item. - DWARFExpression m_location; // The location of this variable that can be fed to DWARFExpression::Evaluate() - uint8_t m_external:1, // Visible outside the containing compile unit? - m_artificial:1; // Non-zero if the variable is not explicitly declared in source + ConstString m_name; // Name of the variable + Type *m_type; // The type pointer of the variable (int, struct, class, etc) + lldb::ValueType m_scope; // global, parameter, local + SymbolContextScope *m_owner_scope; // The symbol file scope that this variable was defined in + Declaration m_declaration; // Declaration location for this item. + DWARFExpression m_location; // The location of this variable that can be fed to DWARFExpression::Evaluate() + uint8_t m_external:1, // Visible outside the containing compile unit? + m_artificial:1; // Non-zero if the variable is not explicitly declared in source private: Variable(const Variable& rhs); Variable& operator=(const Variable& rhs); diff --git a/lldb/include/lldb/Target/StackFrame.h b/lldb/include/lldb/Target/StackFrame.h index c9db4abc164..2732708dd4c 100644 --- a/lldb/include/lldb/Target/StackFrame.h +++ b/lldb/include/lldb/Target/StackFrame.h @@ -33,9 +33,29 @@ public: //------------------------------------------------------------------ // Constructors and Destructors //------------------------------------------------------------------ - StackFrame (lldb::user_id_t frame_idx, lldb::user_id_t concrete_frame_idx, Thread &thread, lldb::addr_t cfa, lldb::addr_t pc, const SymbolContext *sc_ptr); - StackFrame (lldb::user_id_t frame_idx, lldb::user_id_t concrete_frame_idx, Thread &thread, const lldb::RegisterContextSP ®_context_sp, lldb::addr_t cfa, lldb::addr_t pc, const SymbolContext *sc_ptr); - StackFrame (lldb::user_id_t frame_idx, lldb::user_id_t concrete_frame_idx, Thread &thread, const lldb::RegisterContextSP ®_context_sp, lldb::addr_t cfa, const Address& pc, const SymbolContext *sc_ptr); + StackFrame (lldb::user_id_t frame_idx, + lldb::user_id_t unwind_frame_idx, + Thread &thread, + lldb::addr_t cfa, + lldb::addr_t pc, + const SymbolContext *sc_ptr); + + StackFrame (lldb::user_id_t frame_idx, + lldb::user_id_t unwind_frame_idx, + Thread &thread, + const lldb::RegisterContextSP ®_context_sp, + lldb::addr_t cfa, + lldb::addr_t pc, + const SymbolContext *sc_ptr); + + StackFrame (lldb::user_id_t frame_idx, + lldb::user_id_t unwind_frame_idx, + Thread &thread, + const lldb::RegisterContextSP ®_context_sp, + lldb::addr_t cfa, + const Address& pc, + const SymbolContext *sc_ptr); + virtual ~StackFrame (); Thread & @@ -95,9 +115,9 @@ public: } uint32_t - GetConcreteFrameIndex () const + GetUnwindFrameIndex () const { - return m_concrete_frame_index; + return m_unwind_frame_index; } //------------------------------------------------------------------ @@ -121,29 +141,26 @@ public: protected: friend class StackFrameList; - //------------------------------------------------------------------ - // Classes that inherit from StackFrame can see and modify these - //------------------------------------------------------------------ void - SetInlineBlockID (lldb::user_id_t inline_block_id) - { - m_id.SetInlineBlockID(inline_block_id); - } - + SetSymbolContextScope (SymbolContextScope *symbol_scope); + void - UpdateCurrentFrameFromPreviousFrame (StackFrame &frame); + UpdateCurrentFrameFromPreviousFrame (StackFrame &prev_frame); + void + UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame); + private: //------------------------------------------------------------------ // For StackFrame only //------------------------------------------------------------------ Thread &m_thread; uint32_t m_frame_index; - uint32_t m_concrete_frame_index; + uint32_t m_unwind_frame_index; lldb::RegisterContextSP m_reg_context_sp; StackID m_id; Address m_frame_code_addr; // The frame code address (might not be the same as the actual PC for inlined frames) as a section/offset address - SymbolContext m_sc; + SymbolContext m_sc; Flags m_flags; Scalar m_frame_base; Error m_frame_base_error; diff --git a/lldb/include/lldb/Target/StackID.h b/lldb/include/lldb/Target/StackID.h index ac6cc838307..00f0a4f63fa 100644 --- a/lldb/include/lldb/Target/StackID.h +++ b/lldb/include/lldb/Target/StackID.h @@ -28,22 +28,22 @@ public: StackID () : m_start_pc (LLDB_INVALID_ADDRESS), m_cfa (LLDB_INVALID_ADDRESS), - m_inline_block_id (LLDB_INVALID_UID) + m_symbol_scope (NULL) { } explicit - StackID (lldb::addr_t start_pc, lldb::addr_t cfa, lldb::user_id_t inline_block_id) : - m_start_pc (), + StackID (lldb::addr_t start_pc, lldb::addr_t cfa, SymbolContextScope *symbol_scope) : + m_start_pc (start_pc), m_cfa (cfa), - m_inline_block_id (inline_block_id) + m_symbol_scope (symbol_scope) { } StackID (const StackID& rhs) : m_start_pc (rhs.m_start_pc), m_cfa (rhs.m_cfa), - m_inline_block_id (rhs.m_inline_block_id) + m_symbol_scope (rhs.m_symbol_scope) { } @@ -69,18 +69,21 @@ public: return m_cfa; } - lldb::user_id_t - GetInlineBlockID () const + SymbolContextScope * + GetSymbolContextScope () const { - return m_inline_block_id; + return m_symbol_scope; } void - SetInlineBlockID (lldb::user_id_t inline_block_id) + SetSymbolContextScope (SymbolContextScope *symbol_scope) { - m_inline_block_id = inline_block_id; + m_symbol_scope = symbol_scope; } + void + Dump (Stream *s); + //------------------------------------------------------------------ // Operators //------------------------------------------------------------------ @@ -91,7 +94,7 @@ public: { m_start_pc = rhs.m_start_pc; m_cfa = rhs.m_cfa; - m_inline_block_id = rhs.m_inline_block_id; + m_symbol_scope = rhs.m_symbol_scope; } return *this; } @@ -103,10 +106,15 @@ protected: lldb::addr_t m_start_pc; // The start address for the function/symbol for this frame lldb::addr_t m_cfa; // The call frame address (stack pointer) value // at the beginning of the function that uniquely - // identifies this frame (along with m_inline_block_id below) - lldb::user_id_t m_inline_block_id; // The inline height of a stack frame. Zero is the actual - // value for the place where a thread stops, 1 and above - // are for the inlined frames above the concrete base frame. + // identifies this frame (along with m_symbol_scope below) + SymbolContextScope *m_symbol_scope; // If NULL, there is no block or symbol for this frame. + // If not NULL, this will either be the scope for the + // lexical block for the frame, or the scope + // for the symbol. Symbol context scopes are + // always be unique pointers since the are part + // of the Block and Symbol objects and can easily + // be used to tell if a stack ID is the same as + // another. }; bool operator== (const StackID& lhs, const StackID& rhs); diff --git a/lldb/source/Core/Address.cpp b/lldb/source/Core/Address.cpp index bea7493ee9d..070e11d72ce 100644 --- a/lldb/source/Core/Address.cpp +++ b/lldb/source/Core/Address.cpp @@ -241,7 +241,6 @@ ReadCStringFromMemory (ExecutionContextScope *exe_scope, const Address &address, } Address::Address (addr_t address, const SectionList * sections) : - SymbolContextScope(), m_section (NULL), m_offset (LLDB_INVALID_ADDRESS) { @@ -707,14 +706,6 @@ Address::CalculateSymbolContext (SymbolContext *sc) } void -Address::DumpSymbolContext (Stream *s) -{ - SymbolContext sc; - CalculateSymbolContext (&sc); - sc.Dump (s, NULL); -} - -void Address::DumpDebug(Stream *s) const { *s << (void *)this << ": " << "Address"; diff --git a/lldb/source/Plugins/Process/Utility/UnwindLibUnwind.cpp b/lldb/source/Plugins/Process/Utility/UnwindLibUnwind.cpp index e080bc39479..bbc58a21cc0 100644 --- a/lldb/source/Plugins/Process/Utility/UnwindLibUnwind.cpp +++ b/lldb/source/Plugins/Process/Utility/UnwindLibUnwind.cpp @@ -65,7 +65,7 @@ UnwindLibUnwind::GetFrameInfoAtIndex (uint32_t idx, addr_t& cfa, addr_t& pc) RegisterContext * UnwindLibUnwind::CreateRegisterContextForFrame (StackFrame *frame) { - uint32_t idx = frame->GetConcreteFrameIndex (); + uint32_t idx = frame->GetUnwindFrameIndex (); const uint32_t frame_count = GetFrameCount(); if (idx < frame_count) return new LibUnwindRegisterContext (m_thread, frame, m_cursors[idx]); diff --git a/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp b/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp index 4ef6338bb37..f620b07835e 100644 --- a/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp +++ b/lldb/source/Plugins/Process/Utility/UnwindMacOSXFrameBackchain.cpp @@ -66,7 +66,7 @@ UnwindMacOSXFrameBackchain::GetFrameInfoAtIndex (uint32_t idx, addr_t& cfa, addr RegisterContext * UnwindMacOSXFrameBackchain::CreateRegisterContextForFrame (StackFrame *frame) { - uint32_t idx = frame->GetConcreteFrameIndex (); + uint32_t idx = frame->GetUnwindFrameIndex (); const uint32_t frame_count = GetFrameCount(); if (idx < frame_count) return new RegisterContextMacOSXFrameBackchain (m_thread, frame, m_cursors[idx]); diff --git a/lldb/source/Symbol/Symbol.cpp b/lldb/source/Symbol/Symbol.cpp index 6c91dd41958..7ea719300bb 100644 --- a/lldb/source/Symbol/Symbol.cpp +++ b/lldb/source/Symbol/Symbol.cpp @@ -19,6 +19,7 @@ using namespace lldb_private; Symbol::Symbol() : + SymbolContextScope (), UserID (), m_mangled (), m_type (eSymbolTypeInvalid), @@ -51,6 +52,7 @@ Symbol::Symbol uint32_t size, uint32_t flags ) : + SymbolContextScope (), UserID (symID), m_mangled (name, name_is_mangled), m_type (type), @@ -81,6 +83,7 @@ Symbol::Symbol const AddressRange &range, uint32_t flags ) : + SymbolContextScope (), UserID (symID), m_mangled (name, name_is_mangled), m_type (type), @@ -99,6 +102,7 @@ Symbol::Symbol } Symbol::Symbol(const Symbol& rhs): + SymbolContextScope (rhs), UserID (rhs), m_mangled (rhs.m_mangled), m_type (rhs.m_type), @@ -121,6 +125,7 @@ Symbol::operator= (const Symbol& rhs) { if (this != &rhs) { + SymbolContextScope::operator= (rhs); UserID::operator= (rhs); m_mangled = rhs.m_mangled; m_type = rhs.m_type; @@ -335,3 +340,43 @@ Symbol::GetTypeAsString() const return "<unknown SymbolType>"; } + +void +Symbol::CalculateSymbolContext (SymbolContext *sc) +{ + // Symbols can reconstruct the symbol and the module in the symbol context + sc->symbol = this; + const AddressRange *range = GetAddressRangePtr(); + if (range) + { + Module *module = range->GetBaseAddress().GetModule (); + if (module) + { + sc->module_sp = module->GetSP(); + return; + } + } + sc->module_sp.reset(); +} + +void +Symbol::DumpSymbolContext (Stream *s) +{ + bool dumped_module = false; + const AddressRange *range = GetAddressRangePtr(); + if (range) + { + Module *module = range->GetBaseAddress().GetModule (); + if (module) + { + dumped_module = true; + module->DumpSymbolContext(s); + } + } + if (dumped_module) + s->PutCString(", "); + + s->Printf("Symbol{0x%8.8x}", GetID()); +} + + diff --git a/lldb/source/Symbol/Variable.cpp b/lldb/source/Symbol/Variable.cpp index cb3d1c6cf15..a5c74e60f1a 100644 --- a/lldb/source/Symbol/Variable.cpp +++ b/lldb/source/Symbol/Variable.cpp @@ -37,7 +37,7 @@ Variable::Variable(lldb::user_id_t uid, m_name(name), m_type(type), m_scope(scope), - m_context(context), + m_owner_scope(context), m_declaration(decl_ptr), m_location(location), m_external(external), @@ -82,10 +82,10 @@ Variable::Dump(Stream *s, bool show_context) const } } - if (show_context && m_context != NULL) + if (show_context && m_owner_scope != NULL) { s->PutCString(", context = ( "); - m_context->DumpSymbolContext(s); + m_owner_scope->DumpSymbolContext(s); s->PutCString(" )"); } @@ -117,8 +117,8 @@ Variable::MemorySize() const void Variable::CalculateSymbolContext (SymbolContext *sc) { - if (m_context) - m_context->CalculateSymbolContext(sc); + if (m_owner_scope) + m_owner_scope->CalculateSymbolContext(sc); else sc->Clear(); } diff --git a/lldb/source/Target/StackFrame.cpp b/lldb/source/Target/StackFrame.cpp index 967df8815f2..4aef251c297 100644 --- a/lldb/source/Target/StackFrame.cpp +++ b/lldb/source/Target/StackFrame.cpp @@ -29,26 +29,26 @@ using namespace lldb_private; // The first bits in the flags are reserved for the SymbolContext::Scope bits // so we know if we have tried to look up information in our internal symbol // context (m_sc) already. -#define RESOLVED_FRAME_ADDR (uint32_t(eSymbolContextEverything + 1)) -#define RESOLVED_FRAME_ID (RESOLVED_FRAME_ADDR << 1) -#define GOT_FRAME_BASE (RESOLVED_FRAME_ID << 1) -#define FRAME_IS_OBSOLETE (GOT_FRAME_BASE << 1) -#define RESOLVED_VARIABLES (FRAME_IS_OBSOLETE << 1) +#define RESOLVED_FRAME_CODE_ADDR (uint32_t(eSymbolContextEverything + 1)) +#define RESOLVED_FRAME_ID_START_ADDR (RESOLVED_FRAME_CODE_ADDR << 1) +#define RESOLVED_FRAME_ID_SYMBOL_SCOPE (RESOLVED_FRAME_ID_START_ADDR << 1) +#define GOT_FRAME_BASE (RESOLVED_FRAME_ID_SYMBOL_SCOPE << 1) +#define RESOLVED_VARIABLES (GOT_FRAME_BASE << 1) StackFrame::StackFrame ( lldb::user_id_t frame_idx, - lldb::user_id_t concrete_frame_index, + lldb::user_id_t unwind_frame_index, Thread &thread, lldb::addr_t cfa, lldb::addr_t pc, const SymbolContext *sc_ptr ) : m_frame_index (frame_idx), - m_concrete_frame_index (concrete_frame_index), + m_unwind_frame_index (unwind_frame_index), m_thread (thread), m_reg_context_sp (), - m_id (LLDB_INVALID_UID, cfa, LLDB_INVALID_UID), + m_id (LLDB_INVALID_ADDRESS, cfa, NULL), m_frame_code_addr (NULL, pc), m_sc (), m_flags (), @@ -67,7 +67,7 @@ StackFrame::StackFrame StackFrame::StackFrame ( lldb::user_id_t frame_idx, - lldb::user_id_t concrete_frame_index, + lldb::user_id_t unwind_frame_index, Thread &thread, const RegisterContextSP ®_context_sp, lldb::addr_t cfa, @@ -75,10 +75,10 @@ StackFrame::StackFrame const SymbolContext *sc_ptr ) : m_frame_index (frame_idx), - m_concrete_frame_index (concrete_frame_index), + m_unwind_frame_index (unwind_frame_index), m_thread (thread), m_reg_context_sp (reg_context_sp), - m_id (LLDB_INVALID_UID, cfa, LLDB_INVALID_UID), + m_id (LLDB_INVALID_ADDRESS, cfa, NULL), m_frame_code_addr (NULL, pc), m_sc (), m_flags (), @@ -103,7 +103,7 @@ StackFrame::StackFrame StackFrame::StackFrame ( lldb::user_id_t frame_idx, - lldb::user_id_t concrete_frame_index, + lldb::user_id_t unwind_frame_index, Thread &thread, const RegisterContextSP ®_context_sp, lldb::addr_t cfa, @@ -111,10 +111,10 @@ StackFrame::StackFrame const SymbolContext *sc_ptr ) : m_frame_index (frame_idx), - m_concrete_frame_index (concrete_frame_index), + m_unwind_frame_index (unwind_frame_index), m_thread (thread), m_reg_context_sp (reg_context_sp), - m_id (LLDB_INVALID_UID, cfa, LLDB_INVALID_UID), + m_id (LLDB_INVALID_ADDRESS, cfa, NULL), m_frame_code_addr (pc_addr), m_sc (), m_flags (), @@ -160,41 +160,92 @@ StackFrame::GetStackID() // Make sure we have resolved our stack ID's start PC before we give // it out to any external clients. This allows us to not have to lookup // this information if it is never asked for. - if (m_flags.IsClear(RESOLVED_FRAME_ID) && m_id.GetStartAddress() == LLDB_INVALID_ADDRESS) + if (m_flags.IsClear(RESOLVED_FRAME_ID_START_ADDR)) { - m_flags.Set (RESOLVED_FRAME_ID); + m_flags.Set (RESOLVED_FRAME_ID_START_ADDR); - // Resolve our PC to section offset if we haven't alreday done so - // and if we don't have a module. The resolved address section will - // contain the module to which it belongs. - if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_ADDR)) - GetFrameCodeAddress(); + if (m_id.GetStartAddress() == LLDB_INVALID_ADDRESS) + { + // Resolve our PC to section offset if we haven't alreday done so + // and if we don't have a module. The resolved address section will + // contain the module to which it belongs. + if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR)) + GetFrameCodeAddress(); - if (GetSymbolContext (eSymbolContextFunction).function) + if (GetSymbolContext (eSymbolContextFunction).function) + { + m_id.SetStartAddress (m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (&m_thread.GetProcess())); + } + else if (GetSymbolContext (eSymbolContextSymbol).symbol) + { + AddressRange *symbol_range_ptr = m_sc.symbol->GetAddressRangePtr(); + if (symbol_range_ptr) + m_id.SetStartAddress(symbol_range_ptr->GetBaseAddress().GetLoadAddress (&m_thread.GetProcess())); + } + + // We didn't find a function or symbol, just use the frame code address + // which will be the same as the PC in the frame. + if (m_id.GetStartAddress() == LLDB_INVALID_ADDRESS) + m_id.SetStartAddress (m_frame_code_addr.GetLoadAddress (&m_thread.GetProcess())); + } + } + + if (m_flags.IsClear (RESOLVED_FRAME_ID_SYMBOL_SCOPE)) + { + if (m_id.GetSymbolContextScope ()) { - m_id.SetStartAddress (m_sc.function->GetAddressRange().GetBaseAddress().GetLoadAddress (&m_thread.GetProcess())); + m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE); } - else if (GetSymbolContext (eSymbolContextSymbol).symbol) + else { - AddressRange *symbol_range_ptr = m_sc.symbol->GetAddressRangePtr(); - if (symbol_range_ptr) - m_id.SetStartAddress(symbol_range_ptr->GetBaseAddress().GetLoadAddress (&m_thread.GetProcess())); + GetSymbolContext (eSymbolContextFunction | eSymbolContextBlock); + + if (m_sc.block) + { + Block *inline_block = m_sc.block->GetContainingInlinedBlock(); + if (inline_block) + { + // Use the block with the inlined function info + // as the symbol context since we want this frame + // to have only the variables for the inlined function + SetSymbolContextScope (inline_block); + } + else + { + // This block is not inlined with means it has no + // inlined parents either, so we want to use the top + // most function block. + SetSymbolContextScope (&m_sc.function->GetBlock(false)); + } + } + else + { + // The current stack frame doesn't have a block. Check to see + // if it has a symbol. If it does we will use this as the + // symbol scope. It is ok if "m_sc.symbol" is NULL below as + // it will set the symbol context to NULL and set the + // RESOLVED_FRAME_ID_SYMBOL_SCOPE flag bit. + GetSymbolContext (eSymbolContextSymbol); + SetSymbolContextScope (m_sc.symbol); + } } - - // We didn't find a function or symbol, just use the frame code address - // which will be the same as the PC in the frame. - if (m_id.GetStartAddress() == LLDB_INVALID_ADDRESS) - m_id.SetStartAddress (m_frame_code_addr.GetLoadAddress (&m_thread.GetProcess())); } return m_id; } +void +StackFrame::SetSymbolContextScope (SymbolContextScope *symbol_scope) +{ + m_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE); + m_id.SetSymbolContextScope (symbol_scope); +} + Address& StackFrame::GetFrameCodeAddress() { - if (m_flags.IsClear(RESOLVED_FRAME_ADDR) && !m_frame_code_addr.IsSectionOffset()) + if (m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR) && !m_frame_code_addr.IsSectionOffset()) { - m_flags.Set (RESOLVED_FRAME_ADDR); + m_flags.Set (RESOLVED_FRAME_CODE_ADDR); // Resolve the PC into a temporary address because if ResolveLoadAddress // fails to resolve the address, it will clear the address object... @@ -263,7 +314,7 @@ StackFrame::GetSymbolContext (uint32_t resolve_scope) // Resolve our PC to section offset if we haven't alreday done so // and if we don't have a module. The resolved address section will // contain the module to which it belongs - if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_ADDR)) + if (!m_sc.module_sp && m_flags.IsClear(RESOLVED_FRAME_CODE_ADDR)) GetFrameCodeAddress(); // If this is not frame zero, then we need to subtract 1 from the PC @@ -479,7 +530,11 @@ StackFrame::GetValueObjectList() bool StackFrame::IsInlined () { - return m_id.GetInlineBlockID() != LLDB_INVALID_UID; + if (m_sc.block == NULL) + GetSymbolContext (eSymbolContextBlock); + if (m_sc.block) + return m_sc.block->GetContainingInlinedBlock() != NULL; + return false; } Target * @@ -532,13 +587,35 @@ StackFrame::Dump (Stream *strm, bool show_frame_index) } void -StackFrame::UpdateCurrentFrameFromPreviousFrame (StackFrame &frame) +StackFrame::UpdateCurrentFrameFromPreviousFrame (StackFrame &prev_frame) { - assert (GetStackID() == frame.GetStackID()); // TODO: remove this after some testing - m_variable_list_sp = frame.m_variable_list_sp; - m_value_object_list.Swap (frame.m_value_object_list); + assert (GetStackID() == prev_frame.GetStackID()); // TODO: remove this after some testing + m_variable_list_sp = prev_frame.m_variable_list_sp; + m_value_object_list.Swap (prev_frame.m_value_object_list); if (!m_disassembly.GetString().empty()) m_disassembly.GetString().swap (m_disassembly.GetString()); } +void +StackFrame::UpdatePreviousFrameFromCurrentFrame (StackFrame &curr_frame) +{ + assert (GetStackID() == curr_frame.GetStackID()); // TODO: remove this after some testing + assert (&m_thread == &curr_frame.m_thread); + m_frame_index = curr_frame.m_frame_index; + m_unwind_frame_index = curr_frame.m_unwind_frame_index; + m_reg_context_sp = curr_frame.m_reg_context_sp; + m_frame_code_addr = curr_frame.m_frame_code_addr; + assert (m_sc.target_sp.get() == NULL || curr_frame.m_sc.target_sp.get() == NULL || m_sc.target_sp.get() == curr_frame.m_sc.target_sp.get()); + assert (m_sc.module_sp.get() == NULL || curr_frame.m_sc.module_sp.get() == NULL || m_sc.module_sp.get() == curr_frame.m_sc.module_sp.get()); + assert (m_sc.comp_unit == NULL || curr_frame.m_sc.comp_unit == NULL || m_sc.comp_unit == curr_frame.m_sc.comp_unit); + assert (m_sc.function == NULL || curr_frame.m_sc.function == NULL || m_sc.function == curr_frame.m_sc.function); + assert (m_sc.symbol == NULL || curr_frame.m_sc.symbol == NULL || m_sc.symbol == curr_frame.m_sc.symbol); + m_sc = curr_frame.m_sc; + m_flags.Clear(GOT_FRAME_BASE | eSymbolContextEverything); + m_flags.Set (m_sc.GetResolvedMask()); + m_frame_base.Clear(); + m_frame_base_error.Clear(); +} + + diff --git a/lldb/source/Target/StackFrameList.cpp b/lldb/source/Target/StackFrameList.cpp index be4e6e46da2..75351ff4a2e 100644 --- a/lldb/source/Target/StackFrameList.cpp +++ b/lldb/source/Target/StackFrameList.cpp @@ -16,6 +16,7 @@ #include "lldb/Core/StreamFile.h" #include "lldb/Symbol/Block.h" #include "lldb/Symbol/Function.h" +#include "lldb/Symbol/Symbol.h" #include "lldb/Target/RegisterContext.h" #include "lldb/Target/StackFrame.h" #include "lldb/Target/Thread.h" @@ -60,7 +61,8 @@ StackFrameList::GetNumFrames() StreamFile s(stdout); #endif Unwind *unwinder = m_thread.GetUnwinder (); - addr_t pc, cfa; + addr_t pc = LLDB_INVALID_ADDRESS; + addr_t cfa = LLDB_INVALID_ADDRESS; // If we are going to show inlined stack frames as actual frames, // we need to calculate all concrete frames first, then iterate @@ -77,12 +79,13 @@ StackFrameList::GetNumFrames() // if we need to if (m_frames.empty()) { + cfa = m_thread.m_reg_context_sp->GetSP(); m_thread.GetRegisterContext(); unwind_frame_sp.reset (new StackFrame (m_frames.size(), idx, m_thread, m_thread.m_reg_context_sp, - m_thread.m_reg_context_sp->GetSP(), + cfa, m_thread.m_reg_context_sp->GetPC(), NULL)); m_frames.push_back (unwind_frame_sp); @@ -90,6 +93,7 @@ StackFrameList::GetNumFrames() else { unwind_frame_sp = m_frames.front(); + cfa = unwind_frame_sp->m_id.GetCallFrameAddress(); } } else @@ -100,48 +104,64 @@ StackFrameList::GetNumFrames() m_frames.push_back (unwind_frame_sp); } - Block *block = unwind_frame_sp->GetSymbolContext (eSymbolContextBlock).block; + Block *unwind_block = unwind_frame_sp->GetSymbolContext (eSymbolContextBlock).block; - if (block) + if (unwind_block) { - for (block = block->GetContainingInlinedBlock(); block != NULL; block = block->GetInlinedParent ()) + Block *inlined_block = unwind_block->GetContainingInlinedBlock(); + if (inlined_block) { - SymbolContext inline_sc; - Block *parent_block = block->GetInlinedParent(); + for (; inlined_block != NULL; inlined_block = inlined_block->GetInlinedParent ()) + { + SymbolContext inline_sc; + Block *parent_block = inlined_block->GetInlinedParent(); - const bool is_inlined_frame = parent_block != NULL; - - if (parent_block == NULL) - parent_block = block->GetParent(); + const bool is_inlined_frame = parent_block != NULL; - parent_block->CalculateSymbolContext (&inline_sc); - - Address previous_frame_lookup_addr (m_frames.back()->GetFrameCodeAddress()); - if (unwind_frame_sp->GetFrameIndex() > 0 && m_frames.back().get() == unwind_frame_sp.get()) - previous_frame_lookup_addr.Slide (-1); - - AddressRange range; - block->GetRangeContainingAddress (previous_frame_lookup_addr, range); - - const InlineFunctionInfo* inline_info = block->InlinedFunctionInfo(); - assert (inline_info); - inline_sc.line_entry.range.GetBaseAddress() = m_frames.back()->GetFrameCodeAddress(); - inline_sc.line_entry.file = inline_info->GetCallSite().GetFile(); - inline_sc.line_entry.line = inline_info->GetCallSite().GetLine(); - inline_sc.line_entry.column = inline_info->GetCallSite().GetColumn(); - - StackFrameSP frame_sp(new StackFrame (m_frames.size(), - idx, - m_thread, - unwind_frame_sp->GetRegisterContextSP (), - unwind_frame_sp->GetStackID().GetCallFrameAddress(), // CFA - range.GetBaseAddress(), - &inline_sc)); // The symbol context for this inline frame + if (parent_block == NULL) + parent_block = inlined_block->GetParent(); + + parent_block->CalculateSymbolContext (&inline_sc); + + Address previous_frame_lookup_addr (m_frames.back()->GetFrameCodeAddress()); + if (unwind_frame_sp->GetFrameIndex() > 0 && m_frames.back().get() == unwind_frame_sp.get()) + previous_frame_lookup_addr.Slide (-1); - if (is_inlined_frame) - frame_sp->SetInlineBlockID (block->GetID()); + AddressRange range; + inlined_block->GetRangeContainingAddress (previous_frame_lookup_addr, range); - m_frames.push_back (frame_sp); + const InlineFunctionInfo* inline_info = inlined_block->InlinedFunctionInfo(); + assert (inline_info); + inline_sc.line_entry.range.GetBaseAddress() = m_frames.back()->GetFrameCodeAddress(); + inline_sc.line_entry.file = inline_info->GetCallSite().GetFile(); + inline_sc.line_entry.line = inline_info->GetCallSite().GetLine(); + inline_sc.line_entry.column = inline_info->GetCallSite().GetColumn(); + + StackFrameSP frame_sp(new StackFrame (m_frames.size(), + idx, + m_thread, + unwind_frame_sp->GetRegisterContextSP (), + cfa, + range.GetBaseAddress(), + &inline_sc)); // The symbol context for this inline frame + + if (is_inlined_frame) + { + // Use the block with the inlined function info + // as the symbol context since we want this frame + // to have only the variables for the inlined function + frame_sp->SetSymbolContextScope (parent_block); + } + else + { + // This block is not inlined with means it has no + // inlined parents either, so we want to use the top + // most function block. + frame_sp->SetSymbolContextScope (&unwind_frame_sp->GetSymbolContext (eSymbolContextFunction).function->GetBlock(false)); + } + + m_frames.push_back (frame_sp); + } } } } @@ -188,34 +208,15 @@ StackFrameList::GetNumFrames() if (curr_frame == NULL || prev_frame == NULL) break; - // Do a quick sanity check to see if the CFA values are the same. - if (curr_frame->m_id.GetCallFrameAddress() != prev_frame->m_id.GetCallFrameAddress()) + // Check the stack ID to make sure they are equal + if (curr_frame->GetStackID() != prev_frame->GetStackID()) break; - // Now check our function or symbol - SymbolContext curr_sc (curr_frame->GetSymbolContext (eSymbolContextFunction | eSymbolContextBlock | eSymbolContextSymbol)); - SymbolContext prev_sc (prev_frame->GetSymbolContext (eSymbolContextFunction | eSymbolContextBlock | eSymbolContextSymbol)); - if (curr_sc.function && curr_sc.function == prev_sc.function) - { - // Same function - if (curr_sc.block != prev_sc.block) - { - // Same function different block - if (m_show_inlined_frames) - break; - } - } - else if (curr_sc.symbol && curr_sc.symbol == prev_sc.symbol) - { - // Same symbol - } - else if (curr_frame->GetFrameCodeAddress() != prev_frame->GetFrameCodeAddress()) - { - // No symbols for this frame and the PC was different - break; - } - - curr_frame->UpdateCurrentFrameFromPreviousFrame (*prev_frame); + prev_frame->UpdatePreviousFrameFromCurrentFrame (*curr_frame); + // Now copy the fixed up previous frame into the current frames + // so the pointer doesn't change + m_frames[curr_frame_idx] = prev_frame_sp; + //curr_frame->UpdateCurrentFrameFromPreviousFrame (*prev_frame); #if defined (DEBUG_STACK_FRAMES) s.Printf("\n Copying previous frame to current frame"); @@ -253,7 +254,10 @@ StackFrameList::Dump (Stream *s) StackFrame *frame = (*pos).get(); s->Printf("%p: ", frame); if (frame) + { + frame->GetStackID().Dump (s); frame->Dump(s, true); + } else s->Printf("frame #%u", std::distance (begin, pos)); s->EOL(); @@ -289,17 +293,6 @@ StackFrameList::GetFrameAtIndex (uint32_t idx) m_thread.m_reg_context_sp->GetPC(), NULL)); - if (m_show_inlined_frames) - { - Block *block = frame_sp->GetSymbolContext (eSymbolContextBlock).block; - - if (block) - { - Block *inline_block = block->GetContainingInlinedBlock(); - if (inline_block) - frame_sp->SetInlineBlockID (inline_block->GetID()); - } - } SetFrameAtIndex(idx, frame_sp); } else if (idx < GetNumFrames()) @@ -318,11 +311,23 @@ StackFrameList::GetFrameAtIndex (uint32_t idx) if (unwinder->GetFrameInfoAtIndex(idx, cfa, pc)) { frame_sp.reset (new StackFrame (idx, idx, m_thread, cfa, pc, NULL)); + + Function *function = frame_sp->GetSymbolContext (eSymbolContextFunction).function; + if (function) + { + // When we aren't showing inline functions we always use + // the top most function block as the scope. + frame_sp->SetSymbolContextScope (&function->GetBlock(false)); + } + else + { + // Set the symbol scope from the symbol regardless if it is NULL or valid. + frame_sp->SetSymbolContextScope (frame_sp->GetSymbolContext (eSymbolContextSymbol).symbol); + } SetFrameAtIndex(idx, frame_sp); } } } - } return frame_sp; } diff --git a/lldb/source/Target/StackID.cpp b/lldb/source/Target/StackID.cpp index 6d34d3b1770..215e85e8fea 100644 --- a/lldb/source/Target/StackID.cpp +++ b/lldb/source/Target/StackID.cpp @@ -13,15 +13,36 @@ // C++ Includes // Other libraries and framework includes // Project includes +#include "lldb/Core/Stream.h" +#include "lldb/Symbol/Block.h" +#include "lldb/Symbol/Symbol.h" +#include "lldb/Symbol/SymbolContext.h" using namespace lldb_private; +void +StackID::Dump (Stream *s) +{ + s->Printf("StackID (start_pc = 0x%16.16llx, cfa = 0x%16.16llx, symbol_scope = %p", (uint64_t)m_start_pc, (uint64_t)m_cfa, m_symbol_scope); + if (m_symbol_scope) + { + SymbolContext sc; + + m_symbol_scope->CalculateSymbolContext (&sc); + if (sc.block) + s->Printf(" (Block {0x%8.8x})", sc.block->GetID()); + else if (sc.symbol) + s->Printf(" (Symbol{0x%8.8x})", sc.symbol->GetID()); + } + s->PutCString(") "); +} + bool lldb_private::operator== (const StackID& lhs, const StackID& rhs) { return lhs.GetCallFrameAddress() == rhs.GetCallFrameAddress() && - lhs.GetInlineBlockID() == rhs.GetInlineBlockID() && + lhs.GetSymbolContextScope() == rhs.GetSymbolContextScope() && lhs.GetStartAddress() == rhs.GetStartAddress(); } @@ -29,14 +50,12 @@ bool lldb_private::operator!= (const StackID& lhs, const StackID& rhs) { return lhs.GetCallFrameAddress() != rhs.GetCallFrameAddress() || - lhs.GetInlineBlockID() != rhs.GetInlineBlockID() || + lhs.GetSymbolContextScope() != rhs.GetSymbolContextScope() || lhs.GetStartAddress() != rhs.GetStartAddress(); } bool lldb_private::operator< (const StackID& lhs, const StackID& rhs) { - if (lhs.GetCallFrameAddress() < rhs.GetCallFrameAddress()) - return true; - return lhs.GetInlineBlockID() < rhs.GetInlineBlockID(); + return lhs.GetCallFrameAddress() < rhs.GetCallFrameAddress(); } |