1 //===-- UnwindAssemblyInstEmulation.h ---------------------------*- C++ -*-===// 2 // 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 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLDB_SOURCE_PLUGINS_UNWINDASSEMBLY_INSTEMULATION_UNWINDASSEMBLYINSTEMULATION_H 10 #define LLDB_SOURCE_PLUGINS_UNWINDASSEMBLY_INSTEMULATION_UNWINDASSEMBLYINSTEMULATION_H 11 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" 17 18 class UnwindAssemblyInstEmulation : public lldb_private::UnwindAssembly { 19 public: 20 ~UnwindAssemblyInstEmulation() override = default; 21 22 bool GetNonCallSiteUnwindPlanFromAssembly( 23 lldb_private::AddressRange &func, lldb_private::Thread &thread, 24 lldb_private::UnwindPlan &unwind_plan) override; 25 26 bool 27 GetNonCallSiteUnwindPlanFromAssembly(lldb_private::AddressRange &func, 28 uint8_t *opcode_data, size_t opcode_size, 29 lldb_private::UnwindPlan &unwind_plan); 30 31 bool 32 AugmentUnwindPlanFromCallSite(lldb_private::AddressRange &func, 33 lldb_private::Thread &thread, 34 lldb_private::UnwindPlan &unwind_plan) override; 35 36 bool GetFastUnwindPlan(lldb_private::AddressRange &func, 37 lldb_private::Thread &thread, 38 lldb_private::UnwindPlan &unwind_plan) override; 39 40 // 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; 46 47 static lldb_private::UnwindAssembly * 48 CreateInstance(const lldb_private::ArchSpec &arch); 49 50 // PluginInterface protocol 51 static void Initialize(); 52 53 static void Terminate(); 54 GetPluginNameStatic()55 static llvm::StringRef GetPluginNameStatic() { return "inst-emulation"; } 56 57 static llvm::StringRef GetPluginDescriptionStatic(); 58 GetPluginName()59 llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); } 60 61 private: 62 // Call CreateInstance to get an instance of this class UnwindAssemblyInstEmulation(const lldb_private::ArchSpec & arch,lldb_private::EmulateInstruction * inst_emulator)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_initial_sp(0), 67 m_curr_row_modified(false), m_forward_branch_offset(0) { 68 if (m_inst_emulator_up) { 69 m_inst_emulator_up->SetBaton(this); 70 m_inst_emulator_up->SetCallbacks(ReadMemory, WriteMemory, ReadRegister, 71 WriteRegister); 72 } 73 } 74 75 static size_t 76 ReadMemory(lldb_private::EmulateInstruction *instruction, void *baton, 77 const lldb_private::EmulateInstruction::Context &context, 78 lldb::addr_t addr, void *dst, size_t length); 79 80 static size_t 81 WriteMemory(lldb_private::EmulateInstruction *instruction, void *baton, 82 const lldb_private::EmulateInstruction::Context &context, 83 lldb::addr_t addr, const void *dst, size_t length); 84 85 static bool ReadRegister(lldb_private::EmulateInstruction *instruction, 86 void *baton, 87 const lldb_private::RegisterInfo *reg_info, 88 lldb_private::RegisterValue ®_value); 89 90 static bool 91 WriteRegister(lldb_private::EmulateInstruction *instruction, void *baton, 92 const lldb_private::EmulateInstruction::Context &context, 93 const lldb_private::RegisterInfo *reg_info, 94 const lldb_private::RegisterValue ®_value); 95 96 // size_t 97 // ReadMemory (lldb_private::EmulateInstruction *instruction, 98 // const lldb_private::EmulateInstruction::Context &context, 99 // lldb::addr_t addr, 100 // void *dst, 101 // size_t length); 102 103 size_t WriteMemory(lldb_private::EmulateInstruction *instruction, 104 const lldb_private::EmulateInstruction::Context &context, 105 lldb::addr_t addr, const void *dst, size_t length); 106 107 bool ReadRegister(lldb_private::EmulateInstruction *instruction, 108 const lldb_private::RegisterInfo *reg_info, 109 lldb_private::RegisterValue ®_value); 110 111 bool WriteRegister(lldb_private::EmulateInstruction *instruction, 112 const lldb_private::EmulateInstruction::Context &context, 113 const lldb_private::RegisterInfo *reg_info, 114 const lldb_private::RegisterValue ®_value); 115 116 static uint64_t 117 MakeRegisterKindValuePair(const lldb_private::RegisterInfo ®_info); 118 119 void SetRegisterValue(const lldb_private::RegisterInfo ®_info, 120 const lldb_private::RegisterValue ®_value); 121 122 bool GetRegisterValue(const lldb_private::RegisterInfo ®_info, 123 lldb_private::RegisterValue ®_value); 124 125 typedef std::map<uint64_t, lldb_private::RegisterValue> RegisterValueMap; 126 struct UnwindState { 127 lldb_private::UnwindPlan::Row row = {}; 128 lldb_private::RegisterInfo cfa_reg_info = {}; 129 bool fp_is_cfa = false; 130 RegisterValueMap register_values = {}; 131 }; 132 133 std::unique_ptr<lldb_private::EmulateInstruction> m_inst_emulator_up; 134 lldb_private::AddressRange *m_range_ptr; 135 lldb_private::UnwindPlan *m_unwind_plan_ptr; 136 UnwindState m_state; 137 typedef std::map<uint64_t, uint64_t> PushedRegisterToAddrMap; 138 uint64_t m_initial_sp; 139 PushedRegisterToAddrMap m_pushed_regs; 140 141 // While processing the instruction stream, we need to communicate some state 142 // change 143 // information up to the higher level loop that makes decisions about how to 144 // push 145 // the unwind instructions for the UnwindPlan we're constructing. 146 147 // The instruction we're processing updated the UnwindPlan::Row contents 148 bool m_curr_row_modified; 149 // The instruction is branching forward with the given offset. 0 value means 150 // no branching. 151 uint32_t m_forward_branch_offset; 152 }; 153 154 #endif // LLDB_SOURCE_PLUGINS_UNWINDASSEMBLY_INSTEMULATION_UNWINDASSEMBLYINSTEMULATION_H 155