diff options
Diffstat (limited to 'lldb/include')
-rw-r--r-- | lldb/include/lldb/Core/Address.h | 2 | ||||
-rw-r--r-- | lldb/include/lldb/Core/PluginManager.h | 35 | ||||
-rw-r--r-- | lldb/include/lldb/Symbol/DWARFCallFrameInfo.h | 297 | ||||
-rw-r--r-- | lldb/include/lldb/Symbol/FuncUnwinders.h | 91 | ||||
-rw-r--r-- | lldb/include/lldb/Symbol/ObjectFile.h | 20 | ||||
-rw-r--r-- | lldb/include/lldb/Symbol/UnwindPlan.h | 224 | ||||
-rw-r--r-- | lldb/include/lldb/Symbol/UnwindTable.h | 55 | ||||
-rw-r--r-- | lldb/include/lldb/Target/RegisterContext.h | 3 | ||||
-rw-r--r-- | lldb/include/lldb/Utility/ArchDefaultUnwindPlan.h | 42 | ||||
-rw-r--r-- | lldb/include/lldb/Utility/UnwindAssemblyProfiler.h | 49 | ||||
-rw-r--r-- | lldb/include/lldb/lldb-enumerations.h | 9 | ||||
-rw-r--r-- | lldb/include/lldb/lldb-forward-rtti.h | 1 | ||||
-rw-r--r-- | lldb/include/lldb/lldb-forward.h | 21 | ||||
-rw-r--r-- | lldb/include/lldb/lldb-private-interfaces.h | 2 | ||||
-rw-r--r-- | lldb/include/lldb/lldb-types.h | 1 |
15 files changed, 598 insertions, 254 deletions
diff --git a/lldb/include/lldb/Core/Address.h b/lldb/include/lldb/Core/Address.h index 85f0e9a6cbf..ee56173efc7 100644 --- a/lldb/include/lldb/Core/Address.h +++ b/lldb/include/lldb/Core/Address.h @@ -429,7 +429,7 @@ public: SetSection (const Section* section) { m_section = section; } //------------------------------------------------------------------ - /// Reconstruct a symbol context from ad address. + /// Reconstruct a symbol context from an address. /// /// This class doesn't inherit from SymbolContextScope because many /// address objects have short lifespans. Address objects that are diff --git a/lldb/include/lldb/Core/PluginManager.h b/lldb/include/lldb/Core/PluginManager.h index fbd12a56dbb..9225140e42d 100644 --- a/lldb/include/lldb/Core/PluginManager.h +++ b/lldb/include/lldb/Core/PluginManager.h @@ -178,6 +178,41 @@ public: static SymbolVendorCreateInstance GetSymbolVendorCreateCallbackForPluginName (const char *name); + + //------------------------------------------------------------------ + // UnwindAssemblyProfiler + //------------------------------------------------------------------ + static bool + RegisterPlugin (const char *name, + const char *description, + UnwindAssemblyProfilerCreateInstance create_callback); + + static bool + UnregisterPlugin (UnwindAssemblyProfilerCreateInstance create_callback); + + static UnwindAssemblyProfilerCreateInstance + GetUnwindAssemblyProfilerCreateCallbackAtIndex (uint32_t idx); + + static UnwindAssemblyProfilerCreateInstance + GetUnwindAssemblyProfilerCreateCallbackForPluginName (const char *name); + + //------------------------------------------------------------------ + // ArchDefaultUnwindPlan + //------------------------------------------------------------------ + static bool + RegisterPlugin (const char *name, + const char *description, + ArchDefaultUnwindPlanCreateInstance create_callback); + + static bool + UnregisterPlugin (ArchDefaultUnwindPlanCreateInstance create_callback); + + static ArchDefaultUnwindPlanCreateInstance + GetArchDefaultUnwindPlanCreateCallbackAtIndex (uint32_t idx); + + static ArchDefaultUnwindPlanCreateInstance + GetArchDefaultUnwindPlanCreateCallbackForPluginName (const char *name); + }; diff --git a/lldb/include/lldb/Symbol/DWARFCallFrameInfo.h b/lldb/include/lldb/Symbol/DWARFCallFrameInfo.h index 34c71a799db..035a92e6486 100644 --- a/lldb/include/lldb/Symbol/DWARFCallFrameInfo.h +++ b/lldb/include/lldb/Symbol/DWARFCallFrameInfo.h @@ -10,301 +10,120 @@ #ifndef liblldb_DWARFCallFrameInfo_h_ #define liblldb_DWARFCallFrameInfo_h_ -// C Includes -// C++ Includes #include <map> -// Other libraries and framework includes -// Project includes #include "lldb/lldb-private.h" #include "lldb/Core/DataExtractor.h" #include "lldb/Core/Flags.h" #include "lldb/Core/AddressRange.h" #include "lldb/Core/VMRange.h" #include "lldb/Core/dwarf.h" +#include "lldb/Symbol/UnwindPlan.h" +#include "lldb/Symbol/ObjectFile.h" namespace lldb_private { -//---------------------------------------------------------------------- -// DWARFCallFrameInfo -// -// State that describes all register locations for a given address -// range. -//---------------------------------------------------------------------- + +// DWARFCallFrameInfo is a class which can read eh_frame and DWARF +// Call Frame Information FDEs. It stores little information internally. +// Only two APIs are exported - one to find the high/low pc values +// of a function given a text address via the information in the +// eh_frame / debug_frame, and one to generate an UnwindPlan based +// on the FDE in the eh_frame / debug_frame section. class DWARFCallFrameInfo { public: - enum - { - CFI_AUG_MAX_SIZE = 8, - CFI_HEADER_SIZE = 8 - }; - - class Row; - - class RegisterLocation - { - public: - - enum Type - { - unspecified, // not specified, we may be able to assume this is the same register. - // gcc doesn't specify all initial values so we really don't know... - isUndefined, // reg is not available - isSame, // reg is unchanged - atCFAPlusOffset,// reg = deref(CFA + offset) - isCFAPlusOffset,// reg = CFA + offset - inOtherRegister,// reg = other reg - atDWARFExpression, // reg = deref(eval(dwarf_expr)) - isDWARFExpression // reg = eval(dwarf_expr) - }; - RegisterLocation(); + DWARFCallFrameInfo (ObjectFile& objfile, lldb::SectionSP& section, uint32_t reg_kind, bool is_eh_frame); - bool - operator == (const RegisterLocation& rhs) const; - - void - Dump(Stream *s, const DWARFCallFrameInfo &cfi, Thread *thread, const Row *row, uint32_t reg_num) const; - - void - SetUnspecified(); - - void - SetUndefined(); - - void - SetSame() ; - - void - SetAtCFAPlusOffset (int64_t offset); - - void - SetIsCFAPlusOffset (int64_t offset); - - void - SetInRegister (uint32_t reg_num); + ~DWARFCallFrameInfo(); - void - SetAtDWARFExpression (const uint8_t *opcodes, uint32_t len); + // Locate an AddressRange that includes the provided Address in this + // object's eh_frame/debug_info + // Returns true if a range is found to cover that address. + bool + GetAddressRange (Address addr, AddressRange &range); - void - SetIsDWARFExpression (const uint8_t *opcodes, uint32_t len); + // Return an UnwindPlan based on the call frame information encoded + // in the FDE of this DWARFCallFrameInfo section. + bool + GetUnwindPlan (Address addr, UnwindPlan& unwind_plan); - protected: - Type m_type; // How do we locate this register? - union - { - // For m_type == atCFAPlusOffset or m_type == isCFAPlusOffset - int32_t offset; - // For m_type == inOtherRegister - uint32_t reg_num; // The register number - // For m_type == atDWARFExpression or m_type == isDWARFExpression - struct { - const uint8_t *opcodes; - uint32_t length; - } expr; - } m_location; - }; - class Row +private: + enum { - public: - - Row (); - - ~Row (); - - void - Clear(); - - void - Dump(Stream* s, const DWARFCallFrameInfo &cfi, Thread *thread, lldb::addr_t base_addr) const; - - bool - GetRegisterInfo (uint32_t reg_num, RegisterLocation& register_location) const; - - void - SetRegisterInfo (uint32_t reg_num, const RegisterLocation& register_location); - - lldb::addr_t - GetOffset() const - { - return m_offset; - } - - void - SetOffset(lldb::addr_t offset) - { - m_offset = offset; - } - - void - SlideOffset (lldb::addr_t slide) - { - m_offset += slide; - } - - uint32_t - GetCFARegister () const - { - return m_cfa_reg_num; - } - - void - SetCFARegister (uint32_t reg_num) - { - m_cfa_reg_num = reg_num; - } - - int32_t - GetCFAOffset () const - { - return m_cfa_offset; - } - - void - SetCFAOffset (int32_t offset) - { - m_cfa_offset = offset; - } - - protected: - typedef std::map<uint32_t, RegisterLocation> collection; - lldb::addr_t m_offset; // The an offset into the DBAddressRange that owns this row. - uint32_t m_cfa_reg_num; // The Call Frame Address register number - int32_t m_cfa_offset; // The offset from the CFA for this row - collection m_register_locations; + CFI_AUG_MAX_SIZE = 8, + CFI_HEADER_SIZE = 8 }; - //------------------------------------------------------------------ - // Common Information Entry (CIE) - //------------------------------------------------------------------ -protected: - struct CIE { - typedef lldb::SharedPtr<CIE>::Type shared_ptr; dw_offset_t cie_offset; uint8_t version; - char augmentation[CFI_AUG_MAX_SIZE]; // This is typically empty or very short. If we ever run into the limit, make this a NSData pointer + char augmentation[CFI_AUG_MAX_SIZE]; // This is typically empty or very short. uint32_t code_align; int32_t data_align; uint32_t return_addr_reg_num; dw_offset_t inst_offset; // offset of CIE instructions in mCFIData uint32_t inst_length; // length of CIE instructions in mCFIData uint8_t ptr_encoding; + lldb_private::UnwindPlan::Row initial_row; - CIE(dw_offset_t offset); - ~CIE(); - - void - Dump(Stream *s, Thread* threadState, const ArchSpec *arch, uint32_t reg_kind) const; + CIE(dw_offset_t offset) : cie_offset(offset), initial_row() {} }; - //------------------------------------------------------------------ - // Frame Description Entry (FDE) - //------------------------------------------------------------------ -public: + typedef lldb::SharedPtr<CIE>::Type CIESP; - class FDE + struct FDEEntry { - public: - typedef lldb::SharedPtr<FDE>::Type shared_ptr; - - FDE (uint32_t offset, const AddressRange &range); - ~FDE(); - - const AddressRange & - GetAddressRange() const; - - void - AppendRow (const Row &row); - - bool - IsValidRowIndex (uint32_t idx) const; - - void - Dump (Stream *s, const DWARFCallFrameInfo &cfi, Thread* thread) const; - - const Row& - GetRowAtIndex (uint32_t idx); + AddressRange bounds; // function bounds + dw_offset_t offset; // offset to this FDE within the Section - protected: - typedef std::vector<Row> collection; - uint32_t m_fde_offset; - AddressRange m_range; - collection m_row_list; - private: - DISALLOW_COPY_AND_ASSIGN (FDE); + inline bool + operator<(const DWARFCallFrameInfo::FDEEntry& b) const + { + if (bounds.GetBaseAddress().GetOffset() < b.bounds.GetBaseAddress().GetOffset()) + return true; + else + return false; + } }; - DWARFCallFrameInfo(ObjectFile *objfile, lldb_private::Section *section, uint32_t reg_kind); - - ~DWARFCallFrameInfo(); + typedef std::map<off_t, CIESP> cie_map_t; bool IsEHFrame() const; - const ArchSpec * - GetArchitecture() const; - - uint32_t - GetRegisterKind () const; - - void - SetRegisterKind (uint32_t reg_kind); - - void - Index (); - -// bool UnwindRegister (const uint32_t reg_num, const Thread* currState, const Row* row, Thread* unwindState); -// uint32_t UnwindThreadState(const Thread* curr_state, bool is_first_frame, Thread* unwound_state); - const FDE * - FindFDE(const Address &addr); - - void - Dump(Stream *s, Thread *thread) const; + bool + GetFDEEntryByAddress (Address addr, FDEEntry& fde_entry); void - ParseAll(); -protected: + GetFDEIndex (); - enum - { - eFlagParsedIndex = (1 << 0) - }; + bool + FDEToUnwindPlan (uint32_t offset, Address startaddr, UnwindPlan& unwind_plan); - typedef std::map<off_t, CIE::shared_ptr> cie_map_t; - struct FDEInfo - { - off_t fde_offset; - FDE::shared_ptr fde_sp; - FDEInfo (off_t offset); - FDEInfo (); + const CIE* + GetCIE(dw_offset_t cie_offset); - }; - typedef std::map<VMRange, FDEInfo> fde_map_t; + ObjectFile& m_objfile; + lldb::SectionSP m_section; + uint32_t m_reg_kind; + Flags m_flags; + cie_map_t m_cie_map; - ObjectFile * m_objfile; - lldb_private::Section * m_section; - uint32_t m_reg_kind; - Flags m_flags; - DataExtractor m_cfi_data; - cie_map_t m_cie_map; - fde_map_t m_fde_map; + DataExtractor m_cfi_data; + bool m_cfi_data_initialized; // only copy the section into the DE once - const CIE* - GetCIE (uint32_t offset); + std::vector<FDEEntry> m_fde_index; + bool m_fde_index_initialized; // only scan the section for FDEs once - void - ParseInstructions(const CIE *cie, FDE *fde, uint32_t instr_offset, uint32_t instr_length); + bool m_is_eh_frame; - CIE::shared_ptr + CIESP ParseCIE (const uint32_t cie_offset); - FDE::shared_ptr - ParseFDE (const uint32_t fde_offset); }; } // namespace lldb_private diff --git a/lldb/include/lldb/Symbol/FuncUnwinders.h b/lldb/include/lldb/Symbol/FuncUnwinders.h new file mode 100644 index 00000000000..21833b58901 --- /dev/null +++ b/lldb/include/lldb/Symbol/FuncUnwinders.h @@ -0,0 +1,91 @@ +#ifndef liblldb_FuncUnwinders_h +#define liblldb_FuncUnwinders_h + +#include "lldb/lldb-private.h" +#include "lldb/lldb-forward.h" +#include "lldb/lldb-forward-rtti.h" +#include "lldb/Core/AddressRange.h" +#include "lldb/Core/ArchSpec.h" +#include <memory> + +namespace lldb_private { + +class UnwindTable; + +class FuncUnwinders +{ +public: + // FuncUnwinders objects are used to track UnwindPlans for a function + // (named or not - really just an address range) + + // We'll record three different UnwindPlans for each address range: + // 1. Unwinding from a call site (a valid exception throw location) + // This is often sourced from the eh_frame exception handling info + // 2. Unwinding from a non-call site (any location in the function) + // This is often done by analyzing the function prologue assembly + // langauge instructions + // 3. A fast unwind method for this function which only retrieves a + // limited set of registers necessary to walk the stack + // 4. An architectural default unwind plan when none of the above are + // available for some reason. + + // Additionally, FuncUnwinds object can be asked where the prologue + // instructions are finished for migrating breakpoints past the + // stack frame setup instructions when we don't have line table information. + + FuncUnwinders (lldb_private::UnwindTable& unwind_table, lldb_private::UnwindAssemblyProfiler *assembly_profiler, AddressRange range); + + ~FuncUnwinders (); + + UnwindPlan* + GetUnwindPlanAtCallSite (); + + UnwindPlan* + GetUnwindPlanAtNonCallSite (lldb_private::Thread& thread); + + UnwindPlan* + GetUnwindPlanFastUnwind (lldb_private::Thread& Thread); + + UnwindPlan* + GetUnwindPlanArchitectureDefault (lldb_private::Thread& thread); + + Address& + GetFirstNonPrologueInsn (Target& target); + + const Address& + GetFunctionStartAddress () const; + + bool + ContainsAddress (const Address& addr) const + { + return m_range.ContainsFileAddress (addr); + } + +protected: + + UnwindTable& m_unwind_table; + UnwindAssemblyProfiler *m_assembly_profiler; + AddressRange m_range; + + UnwindPlan* m_unwind_at_call_site; + UnwindPlan* m_unwind_at_non_call_site; + UnwindPlan* m_fast_unwind; + UnwindPlan* m_arch_default_unwind; + + Address m_first_non_prologue_insn; + +}; // class FuncUnwinders + +inline bool +operator<(const FuncUnwinders& a, const FuncUnwinders& b) +{ + if (a.GetFunctionStartAddress().GetOffset() < b.GetFunctionStartAddress().GetOffset()) + return true; + else + return false; +} + +} // namespace lldb_private + + +#endif //liblldb_FuncUnwinders_h diff --git a/lldb/include/lldb/Symbol/ObjectFile.h b/lldb/include/lldb/Symbol/ObjectFile.h index 715c81da5aa..9b25b546937 100644 --- a/lldb/include/lldb/Symbol/ObjectFile.h +++ b/lldb/include/lldb/Symbol/ObjectFile.h @@ -16,6 +16,7 @@ #include "lldb/Core/ModuleChild.h" #include "lldb/Core/PluginInterface.h" #include "lldb/Symbol/Symtab.h" +#include "lldb/Symbol/UnwindTable.h" namespace lldb_private { @@ -66,7 +67,8 @@ public: m_file (), // This file could be different from the original module's file m_offset (offset), m_length (length), - m_data (headerDataSP, lldb::eByteOrderHost, 4) + m_data (headerDataSP, lldb::eByteOrderHost, 4), + m_unwind_table (*this) { if (file_spec_ptr) m_file = *file_spec_ptr; @@ -294,6 +296,21 @@ public: virtual bool ParseHeader () = 0; + //------------------------------------------------------------------ + /// Returns a reference to the UnwindTable for this ObjectFile + /// + /// The UnwindTable contains FuncUnwinders objects for any function in + /// this ObjectFile. If a FuncUnwinders object hasn't been created yet + /// (i.e. the function has yet to be unwound in a stack walk), it + /// will be created when requested. Specifically, we do not create + /// FuncUnwinders objects for functions until they are needed. + /// + /// @return + /// Returns the unwind table for this object file. + //------------------------------------------------------------------ + virtual lldb_private::UnwindTable& + GetUnwindTable () { return m_unwind_table; } + protected: //------------------------------------------------------------------ // Member variables. @@ -302,6 +319,7 @@ protected: lldb::addr_t m_offset; ///< The offset in bytes into the file, or the address in memory lldb::addr_t m_length; ///< The length of this object file if it is known (can be zero if length is unknown or can't be determined). DataExtractor m_data; ///< The data for this object file so things can be parsed lazily. + lldb_private::UnwindTable m_unwind_table; /// < Table of FuncUnwinders objects created for this ObjectFile's functions //------------------------------------------------------------------ /// Sets the architecture for a module. At present the architecture diff --git a/lldb/include/lldb/Symbol/UnwindPlan.h b/lldb/include/lldb/Symbol/UnwindPlan.h new file mode 100644 index 00000000000..a678fe09604 --- /dev/null +++ b/lldb/include/lldb/Symbol/UnwindPlan.h @@ -0,0 +1,224 @@ +#ifndef liblldb_UnwindPlan_h +#define liblldb_UnwindPlan_h + +#include "lldb/lldb-private.h" +#include "lldb/Core/AddressRange.h" +#include "lldb/Core/Stream.h" + +#include <map> +#include <vector> + +namespace lldb_private { + +// The UnwindPlan object specifies how to unwind out of a function - where +// this function saves the caller's register values before modifying them +// (for non-volatile aka saved registers) and how to find this frame's +// Canonical Frame Address (CFA). + +// Most commonly, registers are saved on the stack, offset some bytes from +// the Canonical Frame Address, or CFA, which is the starting address of +// this function's stack frame (the CFA is same as the eh_frame's CFA, +// whatever that may be on a given architecture). +// The CFA address for the stack frame does not change during +// the lifetime of the function. + +// Internally, the UnwindPlan is structured as a vector of register locations +// organized by code address in the function, showing which registers have been +// saved at that point and where they are saved. +// It can be thought of as the expanded table form of the DWARF CFI +// encoded information. + +// Other unwind information sources will be converted into UnwindPlans before +// being added to a FuncUnwinders object. The unwind source may be +// an eh_frame FDE, a DWARF debug_frame FDE, or assembly language based +// prologue analysis. +// The UnwindPlan is the canonical form of this information that the unwinder +// code will use when walking the stack. + +class UnwindPlan { +public: + + class Row { + public: + class RegisterLocation + { + public: + + typedef enum RestoreType + { + unspecified, // not specified, we may be able to assume this + // is the same register. gcc doesn't specify all + // initial values so we really don't know... + isUndefined, // reg is not available, e.g. volatile reg + isSame, // reg is unchanged + atCFAPlusOffset, // reg = deref(CFA + offset) + isCFAPlusOffset, // reg = CFA + offset + inOtherRegister, // reg = other reg + atDWARFExpression, // reg = deref(eval(dwarf_expr)) + isDWARFExpression // reg = eval(dwarf_expr) + }; + + RegisterLocation() : m_type(unspecified) { } + + bool + operator == (const RegisterLocation& rhs) const; + + void SetUnspecified(); + + void SetUndefined(); + + void SetSame(); + + void SetAtCFAPlusOffset (int32_t offset); + + void SetIsCFAPlusOffset (int32_t offset); + + void SetInRegister (uint32_t reg_num); + + RestoreType GetLocationType () const { return m_type; } + + int32_t GetOffset () const { return m_location.offset; } + + uint32_t GetRegNum () const { return m_location.reg_num; } + + void GetDWARFExpr (const uint8_t **opcodes, uint16_t& len) const { *opcodes = m_location.expr.opcodes; len = m_location.expr.length; } + + void + SetAtDWARFExpression (const uint8_t *opcodes, uint32_t len); + + void + SetIsDWARFExpression (const uint8_t *opcodes, uint32_t len); + + void + Dump (Stream &s) const; + + private: + RestoreType m_type; // How do we locate this register? + union + { + // For m_type == atCFAPlusOffset or m_type == isCFAPlusOffset + int32_t offset; + // For m_type == inOtherRegister + uint32_t reg_num; // The register number + // For m_type == atDWARFExpression or m_type == isDWARFExpression + struct { + const uint8_t *opcodes; + uint16_t length; + } expr; + } m_location; + }; + + public: + Row (); + + bool + GetRegisterInfo (uint32_t reg_num, RegisterLocation& register_location) const; + + void + SetRegisterInfo (uint32_t reg_num, const RegisterLocation register_location); + + lldb::addr_t + GetOffset() const + { + return m_offset; + } + + void + SetOffset(lldb::addr_t offset) + { + m_offset = offset; + } + + void + SlideOffset(lldb::addr_t offset) + { + m_offset += offset; + } + + uint32_t + GetCFARegister () const + { + return m_cfa_reg_num; + } + + void + SetCFARegister (uint32_t reg_num) + { + m_cfa_reg_num = reg_num; + } + + int32_t + GetCFAOffset () const + { + return m_cfa_offset; + } + + void + SetCFAOffset (int32_t offset) + { + m_cfa_offset = offset; + } + + void + Clear (); + + void + Dump (Stream& s, int register_kind, Thread* thread) const; + + protected: + typedef std::map<uint32_t, RegisterLocation> collection; + lldb::addr_t m_offset; // Offset into the function for this row + uint32_t m_cfa_reg_num; // The Call Frame Address register number + int32_t m_cfa_offset; // The offset from the CFA for this row + collection m_register_locations; + + }; // class Row + +public: + + UnwindPlan () : m_register_kind(-1), m_row_list(), m_plan_valid_address_range() { } + + void Dump (Stream& s, Process* process, Thread* thread) const; + + void + AppendRow (const Row& row); + + const Row* + GetRowForFunctionOffset (int offset) const; + + void + SetRegisterKind (uint32_t rk); + + uint32_t + GetRegisterKind (void) const; + + // This UnwindPlan may not be valid at every address of the function span. + // For instance, a FastUnwindPlan will not be valid at the prologue setup + // instructions - only in the body of the function. + void + SetPlanValidAddressRange (const AddressRange& range); + + bool + PlanValidAtAddress (Address addr); + + bool + IsValidRowIndex (uint32_t idx) const; + + const UnwindPlan::Row& + GetRowAtIndex (uint32_t idx) const; + + int + GetRowCount () const; + +private: + + typedef std::vector<Row> collection; + collection m_row_list; + AddressRange m_plan_valid_address_range; + uint32_t m_register_kind; // The RegisterKind these register numbers are in terms of - will need to be + // translated to lldb native reg nums at unwind time +}; // class UnwindPlan + +} // namespace lldb_private + +#endif //liblldb_UnwindPlan_h diff --git a/lldb/include/lldb/Symbol/UnwindTable.h b/lldb/include/lldb/Symbol/UnwindTable.h new file mode 100644 index 00000000000..0ed76f7354f --- /dev/null +++ b/lldb/include/lldb/Symbol/UnwindTable.h @@ -0,0 +1,55 @@ +//===-- Symtab.h ------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + + +#ifndef liblldb_UnwindTable_h +#define liblldb_UnwindTable_h + +#include <vector> + +#include "lldb/lldb-private.h" + +namespace lldb_private { + +// A class which holds all the FuncUnwinders objects for a given ObjectFile. +// The UnwindTable is populated with FuncUnwinders objects lazily during +// the debug session. + +class UnwindTable +{ +public: + UnwindTable(ObjectFile& objfile); + ~UnwindTable(); + + lldb_private::DWARFCallFrameInfo * + GetEHFrameInfo (); + + lldb::FuncUnwindersSP + GetFuncUnwindersContainingAddress (const Address& addr, SymbolContext &sc); + +private: + void initialize (); + + typedef std::vector<lldb::FuncUnwindersSP> collection; + typedef collection::iterator iterator; + typedef collection::const_iterator const_iterator; + + ObjectFile& m_object_file; + collection m_unwinds; + + bool m_initialized; // delay some initialization until ObjectFile is set up + + UnwindAssemblyProfiler* m_assembly_profiler; + + DWARFCallFrameInfo* m_eh_frame; +}; + +} // namespace lldb_private + +#endif // liblldb_UnwindTable_h diff --git a/lldb/include/lldb/Target/RegisterContext.h b/lldb/include/lldb/Target/RegisterContext.h index 1028b6abfdf..1f97a79789d 100644 --- a/lldb/include/lldb/Target/RegisterContext.h +++ b/lldb/include/lldb/Target/RegisterContext.h @@ -142,6 +142,9 @@ public: bool WriteRegisterFromUnsigned (uint32_t reg, uint64_t uval); + bool + ConvertBetweenRegisterKinds (int source_rk, uint32_t source_regnum, int target_rk, uint32_t target_regnum); + //------------------------------------------------------------------ // lldb::ExecutionContextScope pure virtual functions //------------------------------------------------------------------ diff --git a/lldb/include/lldb/Utility/ArchDefaultUnwindPlan.h b/lldb/include/lldb/Utility/ArchDefaultUnwindPlan.h new file mode 100644 index 00000000000..b907558bedf --- /dev/null +++ b/lldb/include/lldb/Utility/ArchDefaultUnwindPlan.h @@ -0,0 +1,42 @@ +//===---------------------ArchDefaultUnwindPlan.h ---------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef utility_ArchDefaultUnwindPlan_h_ +#define utility_ArchDefaultUnwindPlan_h_ + +#include "lldb-private.h" +#include "lldb/Core/PluginInterface.h" + +namespace lldb_private { + +class ArchDefaultUnwindPlan : + public PluginInterface +{ +public: + + virtual + ~ArchDefaultUnwindPlan(); + + virtual lldb_private::UnwindPlan* + GetArchDefaultUnwindPlan (Thread& thread, Address current_pc) = 0; + + static ArchDefaultUnwindPlan* + FindPlugin (const ArchSpec &arch); + +protected: + ArchDefaultUnwindPlan(); +private: + DISALLOW_COPY_AND_ASSIGN (ArchDefaultUnwindPlan); +}; + +} // namespace lldb_private + +#endif //utility_ArchDefaultUnwindPlan_h_ + + diff --git a/lldb/include/lldb/Utility/UnwindAssemblyProfiler.h b/lldb/include/lldb/Utility/UnwindAssemblyProfiler.h new file mode 100644 index 00000000000..7c127df5c3e --- /dev/null +++ b/lldb/include/lldb/Utility/UnwindAssemblyProfiler.h @@ -0,0 +1,49 @@ +//===---------------------UnwindAssemblyProfiler.h --------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef utility_UnwindAssemblyProfiler_h_ +#define utility_UnwindAssemblyProfiler_h_ + +#include "lldb-private.h" +#include "lldb/Core/PluginInterface.h" + +namespace lldb_private { + +class UnwindAssemblyProfiler : + public PluginInterface +{ +public: + + virtual + ~UnwindAssemblyProfiler(); + + virtual bool + GetNonCallSiteUnwindPlanFromAssembly (lldb_private::AddressRange& func, Thread& thread, lldb_private::UnwindPlan& unwind_plan) = 0; + + virtual bool + GetFastUnwindPlan (lldb_private::AddressRange& func, Thread& thread, lldb_private::UnwindPlan &unwind_plan) = 0; + + // thread may be NULL in which case we only use the Target (e.g. if this is called pre-process-launch). + virtual bool + FirstNonPrologueInsn (lldb_private::AddressRange& func, Target& target, Thread* thread, lldb_private::Address& first_non_prologue_insn) = 0; + + static UnwindAssemblyProfiler* + FindPlugin (const ArchSpec &arch); + +protected: + UnwindAssemblyProfiler(); +private: + DISALLOW_COPY_AND_ASSIGN (UnwindAssemblyProfiler); +}; + +} // namespace lldb_private + +#endif //utility_UnwindAssemblyProfiler_h_ + + diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index e5db86a3ca2..4bbd375d054 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -198,10 +198,11 @@ typedef enum ScriptLanguage //---------------------------------------------------------------------- typedef enum RegisterKind { - eRegisterKindGCC = 0, - eRegisterKindDWARF, - eRegisterKindGeneric, - eRegisterKindGDB, + eRegisterKindGCC = 0, // the register numbers seen in eh_frame + eRegisterKindDWARF, // the register numbers seen DWARF + eRegisterKindGeneric, // insn ptr reg, stack ptr reg, etc not specific to any particular target + eRegisterKindGDB, // the register numbers gdb uses (matches stabs numbers?) + eRegisterKindLLDB, // lldb's internal register numbers kNumRegisterKinds } RegisterKind; diff --git a/lldb/include/lldb/lldb-forward-rtti.h b/lldb/include/lldb/lldb-forward-rtti.h index 83069c8db55..44b5029b3ca 100644 --- a/lldb/include/lldb/lldb-forward-rtti.h +++ b/lldb/include/lldb/lldb-forward-rtti.h @@ -59,6 +59,7 @@ namespace lldb { typedef SharedPtr<lldb_private::Thread>::Type ThreadSP; typedef SharedPtr<lldb_private::ThreadPlan>::Type ThreadPlanSP; typedef SharedPtr<lldb_private::Type>::Type TypeSP; + typedef SharedPtr<lldb_private::FuncUnwinders>::Type FuncUnwindersSP; typedef SharedPtr<lldb_private::UserSettingsController>::Type UserSettingsControllerSP; typedef SharedPtr<lldb_private::ValueObject>::Type ValueObjectSP; typedef SharedPtr<lldb_private::Variable>::Type VariableSP; diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h index d80ebb43c10..ca5ebb9d389 100644 --- a/lldb/include/lldb/lldb-forward.h +++ b/lldb/include/lldb/lldb-forward.h @@ -22,33 +22,33 @@ class Address; class AddressRange; class AddressResolver; class ArchSpec; +class ArchDefaultUnwindPlan; class Args; class Baton; class Block; class Breakpoint; class BreakpointID; class BreakpointIDList; -class BreakpointSite; -class BreakpointSiteList; class BreakpointList; class BreakpointLocation; class BreakpointLocationCollection; class BreakpointLocationList; class BreakpointOptions; class BreakpointResolver; +class BreakpointSite; +class BreakpointSiteList; class Broadcaster; class ClangASTContext; class ClangExpression; class ClangExpressionDeclMap; class ClangExpressionVariableList; class ClangExpressionVariableStore; -class Debugger; class CommandInterpreter; class CommandObject; class CommandReturnObject; class Communication; -class Condition; class CompileUnit; +class Condition; class Connection; class ConnectionFileDescriptor; class ConstString; @@ -57,6 +57,7 @@ class DWARFExpression; class DataBuffer; class DataExtractor; class Debugger; +class Debugger; class Declaration; class Disassembler; class DynamicLoader; @@ -68,12 +69,12 @@ class ExecutionContextScope; class FileSpec; class FileSpecList; class Flags; +class FuncUnwinders; class Function; class FunctionInfo; class InlineFunctionInfo; class InputReader; class InstanceSettings; -struct LineEntry; class LineTable; class Listener; class Log; @@ -123,19 +124,22 @@ class Thread; class ThreadList; class ThreadPlan; class ThreadPlanBase; +class ThreadPlanRunToAddress; class ThreadPlanStepInstruction; class ThreadPlanStepOut; class ThreadPlanStepOverBreakpoint; -class ThreadPlanStepThrough; class ThreadPlanStepRange; -class ThreadPlanRunToAddress; +class ThreadPlanStepThrough; class ThreadSpec; class TimeValue; class Type; class TypeList; +class UUID; class Unwind; +class UnwindAssemblyProfiler; +class UnwindPlan; +class UnwindTable; class UserSettingsController; -class UUID; class VMRange; class Value; class ValueList; @@ -144,6 +148,7 @@ class ValueObjectList; class Variable; class VariableList; class WatchpointLocation; +struct LineEntry; } // namespace lldb_private diff --git a/lldb/include/lldb/lldb-private-interfaces.h b/lldb/include/lldb/lldb-private-interfaces.h index b14fdae2f75..592ba75ac2f 100644 --- a/lldb/include/lldb/lldb-private-interfaces.h +++ b/lldb/include/lldb/lldb-private-interfaces.h @@ -28,6 +28,8 @@ namespace lldb_private typedef bool (*BreakpointHitCallback) (void *baton, StoppointCallbackContext *context, lldb::user_id_t break_id, lldb::user_id_t break_loc_id); typedef bool (*WatchpointHitCallback) (void *baton, StoppointCallbackContext *context, lldb::user_id_t watch_id, uint32_t type); typedef ThreadPlan * (*ThreadPlanShouldStopHereCallback) (ThreadPlan *current_plan, Flags &flags, void *baton); + typedef UnwindAssemblyProfiler* (*UnwindAssemblyProfilerCreateInstance) (const ArchSpec &arch); + typedef ArchDefaultUnwindPlan* (*ArchDefaultUnwindPlanCreateInstance) (const ArchSpec &arch); } // namespace lldb_private #endif // #if defined(__cplusplus) diff --git a/lldb/include/lldb/lldb-types.h b/lldb/include/lldb/lldb-types.h index 91d94553a41..94aedfd8069 100644 --- a/lldb/include/lldb/lldb-types.h +++ b/lldb/include/lldb/lldb-types.h @@ -107,7 +107,6 @@ namespace lldb { uint32_t byte_offset; // The byte offset in the register context data where this register's value is found lldb::Encoding encoding; // Encoding of the register bits lldb::Format format; // Default display format - uint32_t reg; // The native register number for this register uint32_t kinds[kNumRegisterKinds]; // Holds all of the various register numbers for all register kinds } RegisterInfo; |