1//===-- UnwindAssemblyInstEmulation.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 liblldb_UnwindAssemblyInstEmulation_h_
11#define liblldb_UnwindAssemblyInstEmulation_h_
12
13#include "lldb/lldb-private.h"
14#include "lldb/Core/EmulateInstruction.h"
15#include "lldb/Core/RegisterValue.h"
16#include "lldb/Symbol/UnwindPlan.h"
17#include "lldb/Target/UnwindAssembly.h"
18
19class UnwindAssemblyInstEmulation : public lldb_private::UnwindAssembly
20{
21public:
22
23    virtual
24    ~UnwindAssemblyInstEmulation ()
25    {
26    }
27
28    virtual bool
29    GetNonCallSiteUnwindPlanFromAssembly (lldb_private::AddressRange& func,
30                                          lldb_private::Thread& thread,
31                                          lldb_private::UnwindPlan& unwind_plan);
32
33    virtual bool
34    GetFastUnwindPlan (lldb_private::AddressRange& func,
35                       lldb_private::Thread& thread,
36                       lldb_private::UnwindPlan &unwind_plan);
37
38    // thread may be NULL in which case we only use the Target (e.g. if this is called pre-process-launch).
39    virtual bool
40    FirstNonPrologueInsn (lldb_private::AddressRange& func,
41                          const lldb_private::ExecutionContext &exe_ctx,
42                          lldb_private::Address& first_non_prologue_insn);
43
44    static lldb_private::UnwindAssembly *
45    CreateInstance (const lldb_private::ArchSpec &arch);
46
47    //------------------------------------------------------------------
48    // PluginInterface protocol
49    //------------------------------------------------------------------
50    static void
51    Initialize();
52
53    static void
54    Terminate();
55
56    static lldb_private::ConstString
57    GetPluginNameStatic();
58
59    static const char *
60    GetPluginDescriptionStatic();
61
62    virtual lldb_private::ConstString
63    GetPluginName();
64
65    virtual uint32_t
66    GetPluginVersion();
67
68private:
69
70    static size_t
71    ReadMemory (lldb_private::EmulateInstruction *instruction,
72                void *baton,
73                const lldb_private::EmulateInstruction::Context &context,
74                lldb::addr_t addr,
75                void *dst,
76                size_t length);
77
78    static size_t
79    WriteMemory (lldb_private::EmulateInstruction *instruction,
80                 void *baton,
81                 const lldb_private::EmulateInstruction::Context &context,
82                 lldb::addr_t addr,
83                 const void *dst,
84                 size_t length);
85
86    static bool
87    ReadRegister (lldb_private::EmulateInstruction *instruction,
88                  void *baton,
89                  const lldb_private::RegisterInfo *reg_info,
90                  lldb_private::RegisterValue &reg_value);
91
92    static bool
93    WriteRegister (lldb_private::EmulateInstruction *instruction,
94                   void *baton,
95                   const lldb_private::EmulateInstruction::Context &context,
96                   const lldb_private::RegisterInfo *reg_info,
97                   const lldb_private::RegisterValue &reg_value);
98
99
100//    size_t
101//    ReadMemory (lldb_private::EmulateInstruction *instruction,
102//                const lldb_private::EmulateInstruction::Context &context,
103//                lldb::addr_t addr,
104//                void *dst,
105//                size_t length);
106
107    size_t
108    WriteMemory (lldb_private::EmulateInstruction *instruction,
109                 const lldb_private::EmulateInstruction::Context &context,
110                 lldb::addr_t addr,
111                 const void *dst,
112                 size_t length);
113
114    bool
115    ReadRegister (lldb_private::EmulateInstruction *instruction,
116                  const lldb_private::RegisterInfo *reg_info,
117                  lldb_private::RegisterValue &reg_value);
118
119    bool
120    WriteRegister (lldb_private::EmulateInstruction *instruction,
121                   const lldb_private::EmulateInstruction::Context &context,
122                   const lldb_private::RegisterInfo *reg_info,
123                   const lldb_private::RegisterValue &reg_value);
124
125    // Call CreateInstance to get an instance of this class
126    UnwindAssemblyInstEmulation (const lldb_private::ArchSpec &arch,
127                                 lldb_private::EmulateInstruction *inst_emulator) :
128        UnwindAssembly (arch),
129        m_inst_emulator_ap (inst_emulator),
130        m_range_ptr (NULL),
131        m_thread_ptr (NULL),
132        m_unwind_plan_ptr (NULL),
133        m_curr_row (),
134        m_cfa_reg_info (),
135        m_fp_is_cfa (false),
136        m_register_values (),
137        m_pushed_regs(),
138        m_curr_row_modified (false),
139        m_curr_insn_is_branch_immediate (false),
140        m_curr_insn_restored_a_register (false)
141    {
142        if (m_inst_emulator_ap.get())
143        {
144            m_inst_emulator_ap->SetBaton (this);
145            m_inst_emulator_ap->SetCallbacks (ReadMemory, WriteMemory, ReadRegister, WriteRegister);
146        }
147    }
148
149    static uint64_t
150    MakeRegisterKindValuePair (const lldb_private::RegisterInfo &reg_info);
151
152    void
153    SetRegisterValue (const lldb_private::RegisterInfo &reg_info,
154                      const lldb_private::RegisterValue &reg_value);
155
156    bool
157    GetRegisterValue (const lldb_private::RegisterInfo &reg_info,
158                      lldb_private::RegisterValue &reg_value);
159
160    std::unique_ptr<lldb_private::EmulateInstruction> m_inst_emulator_ap;
161    lldb_private::AddressRange* m_range_ptr;
162    lldb_private::Thread* m_thread_ptr;
163    lldb_private::UnwindPlan* m_unwind_plan_ptr;
164    lldb_private::UnwindPlan::RowSP m_curr_row;
165    typedef std::map<uint64_t, uint64_t> PushedRegisterToAddrMap;
166    uint64_t m_initial_sp;
167    lldb_private::RegisterInfo m_cfa_reg_info;
168    bool m_fp_is_cfa;
169    typedef std::map<uint64_t, lldb_private::RegisterValue> RegisterValueMap;
170    RegisterValueMap m_register_values;
171    PushedRegisterToAddrMap m_pushed_regs;
172
173    // While processing the instruction stream, we need to communicate some state change
174    // information up to the higher level loop that makes decisions about how to push
175    // the unwind instructions for the UnwindPlan we're constructing.
176
177    // The instruction we're processing updated the UnwindPlan::Row contents
178    bool m_curr_row_modified;
179    // The instruction we're examining is a branch immediate instruction
180    bool m_curr_insn_is_branch_immediate;
181    // The instruction we're processing restored a caller's reg value (e.g. in an epilogue)
182    bool m_curr_insn_restored_a_register;
183};
184
185#endif // liblldb_UnwindAssemblyInstEmulation_h_
186