blob: bacce93c24e49a2309c3a982f67b317ac648d9e2 [file] [log] [blame]
Eugene Zelenkoab7f6d02015-10-21 18:46:17 +00001//===-- UnwindAssemblyInstEmulation.h ---------------------------*- C++ -*-===//
Greg Claytonffc922e32011-04-25 21:05:07 +00002//
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
Eugene Zelenkoab7f6d02015-10-21 18:46:17 +000013// C Includes
14// C++ Includes
15// Other libraries and framework includes
16// Project includes
Greg Clayton2ed751b2011-04-26 04:39:08 +000017#include "lldb/Core/EmulateInstruction.h"
Greg Clayton7349bd92011-05-09 20:18:18 +000018#include "lldb/Core/RegisterValue.h"
Greg Claytone5b34982011-04-29 22:50:31 +000019#include "lldb/Symbol/UnwindPlan.h"
Greg Clayton7be25422011-04-25 21:14:26 +000020#include "lldb/Target/UnwindAssembly.h"
Kate Stoneb9c1b512016-09-06 20:57:50 +000021#include "lldb/lldb-private.h"
Greg Claytonffc922e32011-04-25 21:05:07 +000022
Kate Stoneb9c1b512016-09-06 20:57:50 +000023class UnwindAssemblyInstEmulation : public lldb_private::UnwindAssembly {
Greg Claytonffc922e32011-04-25 21:05:07 +000024public:
Kate Stoneb9c1b512016-09-06 20:57:50 +000025 ~UnwindAssemblyInstEmulation() override = default;
Greg Claytonffc922e32011-04-25 21:05:07 +000026
Kate Stoneb9c1b512016-09-06 20:57:50 +000027 bool GetNonCallSiteUnwindPlanFromAssembly(
28 lldb_private::AddressRange &func, lldb_private::Thread &thread,
29 lldb_private::UnwindPlan &unwind_plan) override;
Greg Claytonffc922e32011-04-25 21:05:07 +000030
Kate Stoneb9c1b512016-09-06 20:57:50 +000031 bool
32 AugmentUnwindPlanFromCallSite(lldb_private::AddressRange &func,
33 lldb_private::Thread &thread,
34 lldb_private::UnwindPlan &unwind_plan) override;
Greg Claytonffc922e32011-04-25 21:05:07 +000035
Kate Stoneb9c1b512016-09-06 20:57:50 +000036 bool GetFastUnwindPlan(lldb_private::AddressRange &func,
37 lldb_private::Thread &thread,
38 lldb_private::UnwindPlan &unwind_plan) override;
Greg Claytonffc922e32011-04-25 21:05:07 +000039
Kate Stoneb9c1b512016-09-06 20:57:50 +000040 // thread may be NULL in which case we only use the Target (e.g. if this is
41 // called pre-process-launch).
42 bool
43 FirstNonPrologueInsn(lldb_private::AddressRange &func,
44 const lldb_private::ExecutionContext &exe_ctx,
45 lldb_private::Address &first_non_prologue_insn) override;
Greg Claytonffc922e32011-04-25 21:05:07 +000046
Kate Stoneb9c1b512016-09-06 20:57:50 +000047 static lldb_private::UnwindAssembly *
48 CreateInstance(const lldb_private::ArchSpec &arch);
Greg Claytonffc922e32011-04-25 21:05:07 +000049
Kate Stoneb9c1b512016-09-06 20:57:50 +000050 //------------------------------------------------------------------
51 // PluginInterface protocol
52 //------------------------------------------------------------------
53 static void Initialize();
Greg Claytonffc922e32011-04-25 21:05:07 +000054
Kate Stoneb9c1b512016-09-06 20:57:50 +000055 static void Terminate();
Greg Claytonffc922e32011-04-25 21:05:07 +000056
Kate Stoneb9c1b512016-09-06 20:57:50 +000057 static lldb_private::ConstString GetPluginNameStatic();
Greg Claytonffc922e32011-04-25 21:05:07 +000058
Kate Stoneb9c1b512016-09-06 20:57:50 +000059 static const char *GetPluginDescriptionStatic();
Greg Claytonffc922e32011-04-25 21:05:07 +000060
Kate Stoneb9c1b512016-09-06 20:57:50 +000061 lldb_private::ConstString GetPluginName() override;
62
63 uint32_t GetPluginVersion() override;
64
Greg Claytonffc922e32011-04-25 21:05:07 +000065private:
Kate Stoneb9c1b512016-09-06 20:57:50 +000066 // Call CreateInstance to get an instance of this class
67 UnwindAssemblyInstEmulation(const lldb_private::ArchSpec &arch,
68 lldb_private::EmulateInstruction *inst_emulator)
69 : UnwindAssembly(arch), m_inst_emulator_ap(inst_emulator),
70 m_range_ptr(NULL), m_thread_ptr(NULL), m_unwind_plan_ptr(NULL),
71 m_curr_row(), m_cfa_reg_info(), m_fp_is_cfa(false), m_register_values(),
72 m_pushed_regs(), m_curr_row_modified(false),
73 m_forward_branch_offset(0) {
74 if (m_inst_emulator_ap.get()) {
75 m_inst_emulator_ap->SetBaton(this);
76 m_inst_emulator_ap->SetCallbacks(ReadMemory, WriteMemory, ReadRegister,
77 WriteRegister);
Eugene Zelenkoab7f6d02015-10-21 18:46:17 +000078 }
Kate Stoneb9c1b512016-09-06 20:57:50 +000079 }
Eugene Zelenkoab7f6d02015-10-21 18:46:17 +000080
Kate Stoneb9c1b512016-09-06 20:57:50 +000081 static size_t
82 ReadMemory(lldb_private::EmulateInstruction *instruction, void *baton,
83 const lldb_private::EmulateInstruction::Context &context,
84 lldb::addr_t addr, void *dst, size_t length);
Greg Clayton2ed751b2011-04-26 04:39:08 +000085
Kate Stoneb9c1b512016-09-06 20:57:50 +000086 static size_t
87 WriteMemory(lldb_private::EmulateInstruction *instruction, void *baton,
88 const lldb_private::EmulateInstruction::Context &context,
89 lldb::addr_t addr, const void *dst, size_t length);
Greg Clayton2ed751b2011-04-26 04:39:08 +000090
Kate Stoneb9c1b512016-09-06 20:57:50 +000091 static bool ReadRegister(lldb_private::EmulateInstruction *instruction,
92 void *baton,
93 const lldb_private::RegisterInfo *reg_info,
94 lldb_private::RegisterValue &reg_value);
Greg Clayton31f1d2f2011-05-11 18:39:18 +000095
Kate Stoneb9c1b512016-09-06 20:57:50 +000096 static bool
97 WriteRegister(lldb_private::EmulateInstruction *instruction, void *baton,
98 const lldb_private::EmulateInstruction::Context &context,
99 const lldb_private::RegisterInfo *reg_info,
100 const lldb_private::RegisterValue &reg_value);
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000101
Kate Stoneb9c1b512016-09-06 20:57:50 +0000102 // size_t
103 // ReadMemory (lldb_private::EmulateInstruction *instruction,
104 // const lldb_private::EmulateInstruction::Context &context,
105 // lldb::addr_t addr,
106 // void *dst,
107 // size_t length);
Greg Clayton31f1d2f2011-05-11 18:39:18 +0000108
Kate Stoneb9c1b512016-09-06 20:57:50 +0000109 size_t WriteMemory(lldb_private::EmulateInstruction *instruction,
110 const lldb_private::EmulateInstruction::Context &context,
111 lldb::addr_t addr, const void *dst, size_t length);
Greg Clayton2ed751b2011-04-26 04:39:08 +0000112
Kate Stoneb9c1b512016-09-06 20:57:50 +0000113 bool ReadRegister(lldb_private::EmulateInstruction *instruction,
114 const lldb_private::RegisterInfo *reg_info,
115 lldb_private::RegisterValue &reg_value);
Greg Clayton2ed751b2011-04-26 04:39:08 +0000116
Kate Stoneb9c1b512016-09-06 20:57:50 +0000117 bool WriteRegister(lldb_private::EmulateInstruction *instruction,
118 const lldb_private::EmulateInstruction::Context &context,
119 const lldb_private::RegisterInfo *reg_info,
120 const lldb_private::RegisterValue &reg_value);
Jason Molenda7cd5e832012-10-23 03:08:31 +0000121
Kate Stoneb9c1b512016-09-06 20:57:50 +0000122 static uint64_t
123 MakeRegisterKindValuePair(const lldb_private::RegisterInfo &reg_info);
Tamas Berghammer44ff9cce2015-06-24 11:27:32 +0000124
Kate Stoneb9c1b512016-09-06 20:57:50 +0000125 void SetRegisterValue(const lldb_private::RegisterInfo &reg_info,
126 const lldb_private::RegisterValue &reg_value);
127
128 bool GetRegisterValue(const lldb_private::RegisterInfo &reg_info,
129 lldb_private::RegisterValue &reg_value);
130
131 std::unique_ptr<lldb_private::EmulateInstruction> m_inst_emulator_ap;
132 lldb_private::AddressRange *m_range_ptr;
133 lldb_private::Thread *m_thread_ptr;
134 lldb_private::UnwindPlan *m_unwind_plan_ptr;
135 lldb_private::UnwindPlan::RowSP m_curr_row;
136 typedef std::map<uint64_t, uint64_t> PushedRegisterToAddrMap;
137 uint64_t m_initial_sp;
138 lldb_private::RegisterInfo m_cfa_reg_info;
139 bool m_fp_is_cfa;
140 typedef std::map<uint64_t, lldb_private::RegisterValue> RegisterValueMap;
141 RegisterValueMap m_register_values;
142 PushedRegisterToAddrMap m_pushed_regs;
143
144 // While processing the instruction stream, we need to communicate some state
145 // change
146 // information up to the higher level loop that makes decisions about how to
147 // push
148 // the unwind instructions for the UnwindPlan we're constructing.
149
150 // The instruction we're processing updated the UnwindPlan::Row contents
151 bool m_curr_row_modified;
152 // The instruction is branching forward with the given offset. 0 value means
153 // no branching.
154 uint32_t m_forward_branch_offset;
Greg Claytonffc922e32011-04-25 21:05:07 +0000155};
156
157#endif // liblldb_UnwindAssemblyInstEmulation_h_