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