diff --git a/lldb/include/lldb/Core/Address.h b/lldb/include/lldb/Core/Address.h index 35491d7a846c..85f0e9a6cbf6 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 + /// 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::CalculateSymbolContext(SymbolContext*) //------------------------------------------------------------------ void CalculateSymbolContext (SymbolContext *sc); - //------------------------------------------------------------------ - /// @copydoc SymbolContextScope::DumpSymbolContext(Stream*) - /// - /// @see SymbolContextScope - //------------------------------------------------------------------ - void - DumpSymbolContext (Stream *s); - 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 ee4c2b4b7b75..019c6d4885cf 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 9b9b9d698ae3..7394da27a97e 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 0844943e9caa..514e1aa8290d 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 c9db4abc1645..2732708dd4c7 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 &prev_frame); void - UpdateCurrentFrameFromPreviousFrame (StackFrame &frame); - + 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 ac6cc8383071..00f0a4f63fa1 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 bea7493ee9d4..070e11d72ced 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) { @@ -706,14 +705,6 @@ Address::CalculateSymbolContext (SymbolContext *sc) } } -void -Address::DumpSymbolContext (Stream *s) -{ - SymbolContext sc; - CalculateSymbolContext (&sc); - sc.Dump (s, NULL); -} - void Address::DumpDebug(Stream *s) const { diff --git a/lldb/source/Plugins/Process/Utility/UnwindLibUnwind.cpp b/lldb/source/Plugins/Process/Utility/UnwindLibUnwind.cpp index e080bc394797..bbc58a21cc0f 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 4ef6338bb376..f620b07835e2 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 6c91dd41958b..7ea719300bb6 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 ""; } + +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 cb3d1c6cf156..a5c74e60f1ac 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 967df8815f23..4aef251c2974 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 (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())); + { + // 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) + { + 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_flags.Set (RESOLVED_FRAME_ID_SYMBOL_SCOPE); + } + else + { + 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); + } + } } 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 be4e6e46da2d..75351ff4a2e0 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); - if (is_inlined_frame) - frame_sp->SetInlineBlockID (block->GetID()); + 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); - m_frames.push_back (frame_sp); + AddressRange range; + inlined_block->GetRangeContainingAddress (previous_frame_lookup_addr, range); + + 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 6d34d3b1770a..215e85e8fea1 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(); }