summaryrefslogtreecommitdiffstats
path: root/lldb/include
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/include')
-rw-r--r--lldb/include/lldb/Core/Address.h2
-rw-r--r--lldb/include/lldb/Core/PluginManager.h35
-rw-r--r--lldb/include/lldb/Symbol/DWARFCallFrameInfo.h297
-rw-r--r--lldb/include/lldb/Symbol/FuncUnwinders.h91
-rw-r--r--lldb/include/lldb/Symbol/ObjectFile.h20
-rw-r--r--lldb/include/lldb/Symbol/UnwindPlan.h224
-rw-r--r--lldb/include/lldb/Symbol/UnwindTable.h55
-rw-r--r--lldb/include/lldb/Target/RegisterContext.h3
-rw-r--r--lldb/include/lldb/Utility/ArchDefaultUnwindPlan.h42
-rw-r--r--lldb/include/lldb/Utility/UnwindAssemblyProfiler.h49
-rw-r--r--lldb/include/lldb/lldb-enumerations.h9
-rw-r--r--lldb/include/lldb/lldb-forward-rtti.h1
-rw-r--r--lldb/include/lldb/lldb-forward.h21
-rw-r--r--lldb/include/lldb/lldb-private-interfaces.h2
-rw-r--r--lldb/include/lldb/lldb-types.h1
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;
OpenPOWER on IntegriCloud