1 //===-- UnwindAssemblyInstEmulation.h ---------------------------*- C++ -*-===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #ifndef LLDB_SOURCE_PLUGINS_UNWINDASSEMBLY_INSTEMULATION_UNWINDASSEMBLYINSTEMULATION_H
10 #define LLDB_SOURCE_PLUGINS_UNWINDASSEMBLY_INSTEMULATION_UNWINDASSEMBLYINSTEMULATION_H
12 #include "lldb/Core/EmulateInstruction.h"
13 #include "lldb/Symbol/UnwindPlan.h"
14 #include "lldb/Target/UnwindAssembly.h"
15 #include "lldb/Utility/RegisterValue.h"
16 #include "lldb/lldb-private.h"
18 class UnwindAssemblyInstEmulation
: public lldb_private::UnwindAssembly
{
20 ~UnwindAssemblyInstEmulation() override
= default;
22 bool GetNonCallSiteUnwindPlanFromAssembly(
23 lldb_private::AddressRange
&func
, lldb_private::Thread
&thread
,
24 lldb_private::UnwindPlan
&unwind_plan
) override
;
27 GetNonCallSiteUnwindPlanFromAssembly(lldb_private::AddressRange
&func
,
28 uint8_t *opcode_data
, size_t opcode_size
,
29 lldb_private::UnwindPlan
&unwind_plan
);
32 AugmentUnwindPlanFromCallSite(lldb_private::AddressRange
&func
,
33 lldb_private::Thread
&thread
,
34 lldb_private::UnwindPlan
&unwind_plan
) override
;
36 bool GetFastUnwindPlan(lldb_private::AddressRange
&func
,
37 lldb_private::Thread
&thread
,
38 lldb_private::UnwindPlan
&unwind_plan
) override
;
40 // thread may be NULL in which case we only use the Target (e.g. if this is
41 // called pre-process-launch).
43 FirstNonPrologueInsn(lldb_private::AddressRange
&func
,
44 const lldb_private::ExecutionContext
&exe_ctx
,
45 lldb_private::Address
&first_non_prologue_insn
) override
;
47 static lldb_private::UnwindAssembly
*
48 CreateInstance(const lldb_private::ArchSpec
&arch
);
50 // PluginInterface protocol
51 static void Initialize();
53 static void Terminate();
55 static llvm::StringRef
GetPluginNameStatic() { return "inst-emulation"; }
57 static llvm::StringRef
GetPluginDescriptionStatic();
59 llvm::StringRef
GetPluginName() override
{ return GetPluginNameStatic(); }
62 // Call CreateInstance to get an instance of this class
63 UnwindAssemblyInstEmulation(const lldb_private::ArchSpec
&arch
,
64 lldb_private::EmulateInstruction
*inst_emulator
)
65 : UnwindAssembly(arch
), m_inst_emulator_up(inst_emulator
),
66 m_range_ptr(nullptr), m_unwind_plan_ptr(nullptr), m_curr_row(),
67 m_initial_sp(0), m_cfa_reg_info(), m_fp_is_cfa(false),
68 m_register_values(), m_pushed_regs(), m_curr_row_modified(false),
69 m_forward_branch_offset(0) {
70 if (m_inst_emulator_up
) {
71 m_inst_emulator_up
->SetBaton(this);
72 m_inst_emulator_up
->SetCallbacks(ReadMemory
, WriteMemory
, ReadRegister
,
78 ReadMemory(lldb_private::EmulateInstruction
*instruction
, void *baton
,
79 const lldb_private::EmulateInstruction::Context
&context
,
80 lldb::addr_t addr
, void *dst
, size_t length
);
83 WriteMemory(lldb_private::EmulateInstruction
*instruction
, void *baton
,
84 const lldb_private::EmulateInstruction::Context
&context
,
85 lldb::addr_t addr
, const void *dst
, size_t length
);
87 static bool ReadRegister(lldb_private::EmulateInstruction
*instruction
,
89 const lldb_private::RegisterInfo
*reg_info
,
90 lldb_private::RegisterValue
®_value
);
93 WriteRegister(lldb_private::EmulateInstruction
*instruction
, void *baton
,
94 const lldb_private::EmulateInstruction::Context
&context
,
95 const lldb_private::RegisterInfo
*reg_info
,
96 const lldb_private::RegisterValue
®_value
);
99 // ReadMemory (lldb_private::EmulateInstruction *instruction,
100 // const lldb_private::EmulateInstruction::Context &context,
101 // lldb::addr_t addr,
105 size_t WriteMemory(lldb_private::EmulateInstruction
*instruction
,
106 const lldb_private::EmulateInstruction::Context
&context
,
107 lldb::addr_t addr
, const void *dst
, size_t length
);
109 bool ReadRegister(lldb_private::EmulateInstruction
*instruction
,
110 const lldb_private::RegisterInfo
*reg_info
,
111 lldb_private::RegisterValue
®_value
);
113 bool WriteRegister(lldb_private::EmulateInstruction
*instruction
,
114 const lldb_private::EmulateInstruction::Context
&context
,
115 const lldb_private::RegisterInfo
*reg_info
,
116 const lldb_private::RegisterValue
®_value
);
119 MakeRegisterKindValuePair(const lldb_private::RegisterInfo
®_info
);
121 void SetRegisterValue(const lldb_private::RegisterInfo
®_info
,
122 const lldb_private::RegisterValue
®_value
);
124 bool GetRegisterValue(const lldb_private::RegisterInfo
®_info
,
125 lldb_private::RegisterValue
®_value
);
127 std::unique_ptr
<lldb_private::EmulateInstruction
> m_inst_emulator_up
;
128 lldb_private::AddressRange
*m_range_ptr
;
129 lldb_private::UnwindPlan
*m_unwind_plan_ptr
;
130 lldb_private::UnwindPlan::RowSP m_curr_row
;
131 typedef std::map
<uint64_t, uint64_t> PushedRegisterToAddrMap
;
132 uint64_t m_initial_sp
;
133 lldb_private::RegisterInfo m_cfa_reg_info
;
135 typedef std::map
<uint64_t, lldb_private::RegisterValue
> RegisterValueMap
;
136 RegisterValueMap m_register_values
;
137 PushedRegisterToAddrMap m_pushed_regs
;
139 // While processing the instruction stream, we need to communicate some state
141 // information up to the higher level loop that makes decisions about how to
143 // the unwind instructions for the UnwindPlan we're constructing.
145 // The instruction we're processing updated the UnwindPlan::Row contents
146 bool m_curr_row_modified
;
147 // The instruction is branching forward with the given offset. 0 value means
149 uint32_t m_forward_branch_offset
;
152 #endif // LLDB_SOURCE_PLUGINS_UNWINDASSEMBLY_INSTEMULATION_UNWINDASSEMBLYINSTEMULATION_H