RegisterContextLLDB.h revision 269024
1//===-- RegisterContextLLDB.h --------------------------------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef lldb_RegisterContextLLDB_h_
11#define lldb_RegisterContextLLDB_h_
12
13#include <vector>
14
15#include "lldb/lldb-private.h"
16#include "lldb/Target/RegisterContext.h"
17#include "lldb/Symbol/UnwindPlan.h"
18#include "lldb/Symbol/SymbolContext.h"
19#include "UnwindLLDB.h"
20
21namespace lldb_private {
22
23class UnwindLLDB;
24
25class RegisterContextLLDB : public lldb_private::RegisterContext
26{
27public:
28    typedef std::shared_ptr<RegisterContextLLDB> SharedPtr;
29
30    RegisterContextLLDB (lldb_private::Thread &thread,
31                         const SharedPtr& next_frame,
32                         lldb_private::SymbolContext& sym_ctx,
33                         uint32_t frame_number, lldb_private::UnwindLLDB& unwind_lldb);
34
35    ///
36    // pure virtual functions from the base class that we must implement
37    ///
38
39    virtual
40    ~RegisterContextLLDB () { }
41
42    virtual void
43    InvalidateAllRegisters ();
44
45    virtual size_t
46    GetRegisterCount ();
47
48    virtual const lldb_private::RegisterInfo *
49    GetRegisterInfoAtIndex (size_t reg);
50
51    virtual size_t
52    GetRegisterSetCount ();
53
54    virtual const lldb_private::RegisterSet *
55    GetRegisterSet (size_t reg_set);
56
57    virtual bool
58    ReadRegister (const lldb_private::RegisterInfo *reg_info, lldb_private::RegisterValue &value);
59
60    virtual bool
61    WriteRegister (const lldb_private::RegisterInfo *reg_info, const lldb_private::RegisterValue &value);
62
63    virtual bool
64    ReadAllRegisterValues (lldb::DataBufferSP &data_sp);
65
66    virtual bool
67    WriteAllRegisterValues (const lldb::DataBufferSP &data_sp);
68
69    virtual uint32_t
70    ConvertRegisterKindToRegisterNumber (uint32_t kind, uint32_t num);
71
72    bool
73    IsValid () const;
74
75    bool
76    IsTrapHandlerFrame () const;
77
78    bool
79    GetCFA (lldb::addr_t& cfa);
80
81    bool
82    GetStartPC (lldb::addr_t& start_pc);
83
84    bool
85    ReadPC (lldb::addr_t& start_pc);
86
87private:
88
89    enum FrameType
90    {
91        eNormalFrame,
92        eTrapHandlerFrame,
93        eDebuggerFrame,  // a debugger inferior function call frame; we get caller's registers from debugger
94        eSkipFrame,      // The unwind resulted in a bogus frame but may get back on track so we don't want to give up yet
95        eNotAValidFrame  // this frame is invalid for some reason - most likely it is past the top (end) of the stack
96    };
97
98    // UnwindLLDB needs to pass around references to RegisterLocations
99    friend class UnwindLLDB;
100
101    // Indicates whether this frame is frame zero -- the currently
102    // executing frame -- or not.
103    bool
104    IsFrameZero () const;
105
106    void
107    InitializeZerothFrame ();
108
109    void
110    InitializeNonZerothFrame();
111
112    SharedPtr
113    GetNextFrame () const;
114
115    SharedPtr
116    GetPrevFrame () const;
117
118    // A SkipFrame occurs when the unwind out of frame 0 didn't go right -- we've got one bogus frame at frame #1.
119    // There is a good chance we'll get back on track if we follow the frame pointer chain (or whatever is appropriate
120    // on this ABI) so we allow one invalid frame to be in the stack.  Ideally we'll mark this frame specially at some
121    // point and indicate to the user that the unwinder had a hiccup.  Often when this happens we will miss a frame of
122    // the program's actual stack in the unwind and we want to flag that for the user somehow.
123    bool
124    IsSkipFrame () const;
125
126
127    //------------------------------------------------------------------
128    /// Determines if a SymbolContext is a trap handler or not
129    ///
130    /// Given a SymbolContext, determines if this is a trap handler function
131    /// aka asynchronous signal handler.
132    ///
133    /// @return
134    ///     Returns true if the SymbolContext is a trap handler.
135    //------------------------------------------------------------------
136    bool
137    IsTrapHandlerSymbol (lldb_private::Process *process, const lldb_private::SymbolContext &m_sym_ctx) const;
138
139    // Provide a location for where THIS function saved the CALLER's register value
140    // Or a frame "below" this one saved it, i.e. a function called by this one, preserved a register that this
141    // function didn't modify/use.
142    //
143    // The RegisterLocation type may be set to eRegisterNotAvailable -- this will happen for a volatile register
144    // being queried mid-stack.  Instead of floating frame 0's contents of that register up the stack (which may
145    // or may not be the value of that reg when the function was executing), we won't return any value.
146    //
147    // If a non-volatile register (a "preserved" register) is requested mid-stack and no frames "below" the requested
148    // stack have saved the register anywhere, it is safe to assume that frame 0's register values are still the same
149    // as the requesting frame's.
150    lldb_private::UnwindLLDB::RegisterSearchResult
151    SavedLocationForRegister (uint32_t lldb_regnum, lldb_private::UnwindLLDB::RegisterLocation &regloc);
152
153    bool
154    ReadRegisterValueFromRegisterLocation (lldb_private::UnwindLLDB::RegisterLocation regloc,
155                                           const lldb_private::RegisterInfo *reg_info,
156                                           lldb_private::RegisterValue &value);
157
158    bool
159    WriteRegisterValueToRegisterLocation (lldb_private::UnwindLLDB::RegisterLocation regloc,
160                                          const lldb_private::RegisterInfo *reg_info,
161                                          const lldb_private::RegisterValue &value);
162
163    //------------------------------------------------------------------
164    /// If the unwind has to the caller frame has failed, try something else
165    ///
166    /// If lldb is using an assembly language based UnwindPlan for a frame and
167    /// the unwind to the caller frame fails, try falling back to a generic
168    /// UnwindPlan (architecture default unwindplan) to see if that might work
169    /// better.  This is mostly helping to work around problems where the
170    /// assembly language inspection fails on hand-written assembly code.
171    ///
172    /// @return
173    ///     Returns true if a fallback unwindplan was found & was installed.
174    //------------------------------------------------------------------
175    bool
176    TryFallbackUnwindPlan ();
177
178    // Get the contents of a general purpose (address-size) register for this frame
179    // (usually retrieved from the next frame)
180    bool
181    ReadGPRValue (int register_kind, uint32_t regnum, lldb::addr_t &value);
182
183    lldb::UnwindPlanSP
184    GetFastUnwindPlanForFrame ();
185
186    lldb::UnwindPlanSP
187    GetFullUnwindPlanForFrame ();
188
189    void
190    UnwindLogMsg (const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
191
192    void
193    UnwindLogMsgVerbose (const char *fmt, ...) __attribute__ ((format (printf, 2, 3)));
194
195    bool
196    IsUnwindPlanValidForCurrentPC(lldb::UnwindPlanSP unwind_plan_sp, int &valid_pc_offset);
197
198
199    lldb_private::Thread& m_thread;
200
201    ///
202    // The following tell us how to retrieve the CALLER's register values (ie the "previous" frame, aka the frame above)
203    // i.e. where THIS frame saved them
204    ///
205
206    lldb::UnwindPlanSP m_fast_unwind_plan_sp;     // may be NULL
207    lldb::UnwindPlanSP m_full_unwind_plan_sp;
208    lldb::UnwindPlanSP m_fallback_unwind_plan_sp; // may be NULL
209
210    bool m_all_registers_available;               // Can we retrieve all regs or just nonvolatile regs?
211    int m_frame_type;                             // enum FrameType
212
213    lldb::addr_t m_cfa;
214    lldb_private::Address m_start_pc;
215    lldb_private::Address m_current_pc;
216
217    int m_current_offset;                         // how far into the function we've executed; -1 if unknown
218                                                  // 0 if no instructions have been executed yet.
219
220    int m_current_offset_backed_up_one;           // how far into the function we've executed; -1 if unknown
221                                                  // 0 if no instructions have been executed yet.
222                                                  // On architectures where the return address on the stack points
223                                                  // to the instruction after the CALL, this value will have 1
224                                                  // subtracted from it.  Else a function that ends in a CALL will
225                                                  // have an offset pointing into the next function's address range.
226                                                  // m_current_pc has the actual address of the "current" pc.
227
228    lldb_private::SymbolContext& m_sym_ctx;
229    bool m_sym_ctx_valid;                         // if ResolveSymbolContextForAddress fails, don't try to use m_sym_ctx
230
231    uint32_t m_frame_number;                      // What stack frame this RegisterContext is
232
233    std::map<uint32_t, lldb_private::UnwindLLDB::RegisterLocation> m_registers; // where to find reg values for this frame
234
235    lldb_private::UnwindLLDB& m_parent_unwind;    // The UnwindLLDB that is creating this RegisterContextLLDB
236
237    //------------------------------------------------------------------
238    // For RegisterContextLLDB only
239    //------------------------------------------------------------------
240
241    DISALLOW_COPY_AND_ASSIGN (RegisterContextLLDB);
242};
243
244} // namespace lldb_private
245
246#endif  // lldb_RegisterContextLLDB_h_
247