159 lines · c
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-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLDB_SOURCE_PLUGINS_UNWINDASSEMBLY_INSTEMULATION_UNWINDASSEMBLYINSTEMULATION_H10#define LLDB_SOURCE_PLUGINS_UNWINDASSEMBLY_INSTEMULATION_UNWINDASSEMBLYINSTEMULATION_H11 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 18class UnwindAssemblyInstEmulation : public lldb_private::UnwindAssembly {19public: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 bool27 GetNonCallSiteUnwindPlanFromAssembly(lldb_private::AddressRange &func,28 uint8_t *opcode_data, size_t opcode_size,29 lldb_private::UnwindPlan &unwind_plan);30 31 bool32 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 is41 // called pre-process-launch).42 bool43 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 protocol51 static void Initialize();52 53 static void Terminate();54 55 static llvm::StringRef GetPluginNameStatic() { return "inst-emulation"; }56 57 static llvm::StringRef GetPluginDescriptionStatic();58 59 llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }60 61private:62 // Call CreateInstance to get an instance of this class63 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),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 // Initialize the CFA with a known value. In the 32 bit case it will be74 // 0x80000000, and in the 64 bit case 0x8000000000000000. We use the address75 // byte size to be safe for any future address sizes76 m_initial_cfa = (1ull << ((m_arch.GetAddressByteSize() * 8) - 1));77 }78 79 static size_t80 ReadMemory(lldb_private::EmulateInstruction *instruction, void *baton,81 const lldb_private::EmulateInstruction::Context &context,82 lldb::addr_t addr, void *dst, size_t length);83 84 static size_t85 WriteMemory(lldb_private::EmulateInstruction *instruction, void *baton,86 const lldb_private::EmulateInstruction::Context &context,87 lldb::addr_t addr, const void *dst, size_t length);88 89 static bool ReadRegister(lldb_private::EmulateInstruction *instruction,90 void *baton,91 const lldb_private::RegisterInfo *reg_info,92 lldb_private::RegisterValue ®_value);93 94 static bool95 WriteRegister(lldb_private::EmulateInstruction *instruction, void *baton,96 const lldb_private::EmulateInstruction::Context &context,97 const lldb_private::RegisterInfo *reg_info,98 const lldb_private::RegisterValue ®_value);99 100 // size_t101 // ReadMemory (lldb_private::EmulateInstruction *instruction,102 // const lldb_private::EmulateInstruction::Context &context,103 // lldb::addr_t addr,104 // void *dst,105 // size_t length);106 107 size_t WriteMemory(lldb_private::EmulateInstruction *instruction,108 const lldb_private::EmulateInstruction::Context &context,109 lldb::addr_t addr, const void *dst, size_t length);110 111 bool ReadRegister(lldb_private::EmulateInstruction *instruction,112 const lldb_private::RegisterInfo *reg_info,113 lldb_private::RegisterValue ®_value);114 115 bool WriteRegister(lldb_private::EmulateInstruction *instruction,116 const lldb_private::EmulateInstruction::Context &context,117 const lldb_private::RegisterInfo *reg_info,118 const lldb_private::RegisterValue ®_value);119 120 static uint64_t121 MakeRegisterKindValuePair(const lldb_private::RegisterInfo ®_info);122 123 void SetRegisterValue(const lldb_private::RegisterInfo ®_info,124 const lldb_private::RegisterValue ®_value);125 126 bool GetRegisterValue(const lldb_private::RegisterInfo ®_info,127 lldb_private::RegisterValue ®_value);128 129 typedef std::map<uint64_t, lldb_private::RegisterValue> RegisterValueMap;130 struct UnwindState {131 lldb_private::UnwindPlan::Row row = {};132 lldb_private::RegisterInfo cfa_reg_info = {};133 bool fp_is_cfa = false;134 RegisterValueMap register_values = {};135 };136 137 std::unique_ptr<lldb_private::EmulateInstruction> m_inst_emulator_up;138 lldb_private::AddressRange *m_range_ptr;139 lldb_private::UnwindPlan *m_unwind_plan_ptr;140 UnwindState m_state;141 uint64_t m_initial_cfa;142 typedef std::map<uint64_t, uint64_t> PushedRegisterToAddrMap;143 PushedRegisterToAddrMap m_pushed_regs;144 145 // While processing the instruction stream, we need to communicate some state146 // change147 // information up to the higher level loop that makes decisions about how to148 // push149 // the unwind instructions for the UnwindPlan we're constructing.150 151 // The instruction we're processing updated the UnwindPlan::Row contents152 bool m_curr_row_modified;153 // The instruction is branching forward with the given offset. 0 value means154 // no branching.155 uint32_t m_forward_branch_offset;156};157 158#endif // LLDB_SOURCE_PLUGINS_UNWINDASSEMBLY_INSTEMULATION_UNWINDASSEMBLYINSTEMULATION_H159