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 
19 class UnwindAssemblyInstEmulation : public lldb_private::UnwindAssembly
20 {
21 public:
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 const char *
57     GetPluginNameStatic();
58 
59     static const char *
60     GetPluginDescriptionStatic();
61 
62     virtual const char *
63     GetPluginName();
64 
65     virtual const char *
66     GetShortPluginName();
67 
68     virtual uint32_t
69     GetPluginVersion();
70 
71 private:
72 
73     static size_t
74     ReadMemory (lldb_private::EmulateInstruction *instruction,
75                 void *baton,
76                 const lldb_private::EmulateInstruction::Context &context,
77                 lldb::addr_t addr,
78                 void *dst,
79                 size_t length);
80 
81     static size_t
82     WriteMemory (lldb_private::EmulateInstruction *instruction,
83                  void *baton,
84                  const lldb_private::EmulateInstruction::Context &context,
85                  lldb::addr_t addr,
86                  const void *dst,
87                  size_t length);
88 
89     static bool
90     ReadRegister (lldb_private::EmulateInstruction *instruction,
91                   void *baton,
92                   const lldb_private::RegisterInfo *reg_info,
93                   lldb_private::RegisterValue &reg_value);
94 
95     static bool
96     WriteRegister (lldb_private::EmulateInstruction *instruction,
97                    void *baton,
98                    const lldb_private::EmulateInstruction::Context &context,
99                    const lldb_private::RegisterInfo *reg_info,
100                    const lldb_private::RegisterValue &reg_value);
101 
102 
103 //    size_t
104 //    ReadMemory (lldb_private::EmulateInstruction *instruction,
105 //                const lldb_private::EmulateInstruction::Context &context,
106 //                lldb::addr_t addr,
107 //                void *dst,
108 //                size_t length);
109 
110     size_t
111     WriteMemory (lldb_private::EmulateInstruction *instruction,
112                  const lldb_private::EmulateInstruction::Context &context,
113                  lldb::addr_t addr,
114                  const void *dst,
115                  size_t length);
116 
117     bool
118     ReadRegister (lldb_private::EmulateInstruction *instruction,
119                   const lldb_private::RegisterInfo *reg_info,
120                   lldb_private::RegisterValue &reg_value);
121 
122     bool
123     WriteRegister (lldb_private::EmulateInstruction *instruction,
124                    const lldb_private::EmulateInstruction::Context &context,
125                    const lldb_private::RegisterInfo *reg_info,
126                    const lldb_private::RegisterValue &reg_value);
127 
128     // Call CreateInstance to get an instance of this class
129     UnwindAssemblyInstEmulation (const lldb_private::ArchSpec &arch,
130                                  lldb_private::EmulateInstruction *inst_emulator) :
131         UnwindAssembly (arch),
132         m_inst_emulator_ap (inst_emulator),
133         m_range_ptr (NULL),
134         m_thread_ptr (NULL),
135         m_unwind_plan_ptr (NULL),
136         m_curr_row (),
137         m_cfa_reg_info (),
138         m_fp_is_cfa (false),
139         m_register_values (),
140         m_pushed_regs(),
141         m_curr_row_modified (false),
142         m_curr_insn_is_branch_immediate (false),
143         m_curr_insn_restored_a_register (false)
144     {
145         if (m_inst_emulator_ap.get())
146         {
147             m_inst_emulator_ap->SetBaton (this);
148             m_inst_emulator_ap->SetCallbacks (ReadMemory, WriteMemory, ReadRegister, WriteRegister);
149         }
150     }
151 
152     static uint64_t
153     MakeRegisterKindValuePair (const lldb_private::RegisterInfo &reg_info);
154 
155     void
156     SetRegisterValue (const lldb_private::RegisterInfo &reg_info,
157                       const lldb_private::RegisterValue &reg_value);
158 
159     bool
160     GetRegisterValue (const lldb_private::RegisterInfo &reg_info,
161                       lldb_private::RegisterValue &reg_value);
162 
163     std::unique_ptr<lldb_private::EmulateInstruction> m_inst_emulator_ap;
164     lldb_private::AddressRange* m_range_ptr;
165     lldb_private::Thread* m_thread_ptr;
166     lldb_private::UnwindPlan* m_unwind_plan_ptr;
167     lldb_private::UnwindPlan::RowSP m_curr_row;
168     typedef std::map<uint64_t, uint64_t> PushedRegisterToAddrMap;
169     uint64_t m_initial_sp;
170     lldb_private::RegisterInfo m_cfa_reg_info;
171     bool m_fp_is_cfa;
172     typedef std::map<uint64_t, lldb_private::RegisterValue> RegisterValueMap;
173     RegisterValueMap m_register_values;
174     PushedRegisterToAddrMap m_pushed_regs;
175 
176     // While processing the instruction stream, we need to communicate some state change
177     // information up to the higher level loop that makes decisions about how to push
178     // the unwind instructions for the UnwindPlan we're constructing.
179 
180     // The instruction we're processing updated the UnwindPlan::Row contents
181     bool m_curr_row_modified;
182     // The instruction we're examining is a branch immediate instruction
183     bool m_curr_insn_is_branch_immediate;
184     // The instruction we're processing restored a caller's reg value (e.g. in an epilogue)
185     bool m_curr_insn_restored_a_register;
186 };
187 
188 #endif // liblldb_UnwindAssemblyInstEmulation_h_
189