brintos

brintos / llvm-project-archived public Read only

0
0
Text · 6.6 KiB · 6c0492f Raw
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 &reg_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 &reg_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 &reg_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 &reg_value);119 120  static uint64_t121  MakeRegisterKindValuePair(const lldb_private::RegisterInfo &reg_info);122 123  void SetRegisterValue(const lldb_private::RegisterInfo &reg_info,124                        const lldb_private::RegisterValue &reg_value);125 126  bool GetRegisterValue(const lldb_private::RegisterInfo &reg_info,127                        lldb_private::RegisterValue &reg_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