brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.9 KiB · c196a9b Raw
145 lines · c
1//===-- EmulateInstructionRISCV.h -----------------------------------------===//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_INSTRUCTION_RISCV_EMULATEINSTRUCTIONRISCV_H10#define LLDB_SOURCE_PLUGINS_INSTRUCTION_RISCV_EMULATEINSTRUCTIONRISCV_H11 12#include "RISCVInstructions.h"13 14#include "lldb/Core/EmulateInstruction.h"15#include "lldb/Interpreter/OptionValue.h"16#include "lldb/Utility/Log.h"17#include "lldb/Utility/RegisterValue.h"18#include "lldb/Utility/Status.h"19#include <optional>20 21namespace lldb_private {22 23class RISCVSingleStepBreakpointLocationsPredictor24    : public SingleStepBreakpointLocationsPredictor {25public:26  RISCVSingleStepBreakpointLocationsPredictor(27      std::unique_ptr<EmulateInstruction> emulator)28      : SingleStepBreakpointLocationsPredictor{std::move(emulator)} {}29 30  BreakpointLocations GetBreakpointLocations(Status &status) override;31 32  llvm::Expected<unsigned> GetBreakpointSize(lldb::addr_t bp_addr) override;33 34private:35  static bool FoundLoadReserve(const RISCVInst &inst) {36    return std::holds_alternative<LR_W>(inst) ||37           std::holds_alternative<LR_D>(inst);38  }39 40  static bool FoundStoreConditional(const RISCVInst &inst) {41    return std::holds_alternative<SC_W>(inst) ||42           std::holds_alternative<SC_D>(inst);43  }44 45  BreakpointLocations HandleAtomicSequence(lldb::addr_t pc, Status &error);46 47  static constexpr size_t s_max_atomic_sequence_length = 64;48};49 50class EmulateInstructionRISCV : public EmulateInstruction {51public:52  static llvm::StringRef GetPluginNameStatic() { return "riscv"; }53 54  static llvm::StringRef GetPluginDescriptionStatic() {55    return "Emulate instructions for the RISC-V architecture.";56  }57 58  static bool SupportsThisInstructionType(InstructionType inst_type) {59    switch (inst_type) {60    case eInstructionTypeAny:61    case eInstructionTypePCModifying:62      return true;63    case eInstructionTypePrologueEpilogue:64      return true;65    case eInstructionTypeAll:66      return false;67    }68    llvm_unreachable("Fully covered switch above!");69  }70 71  static bool SupportsThisArch(const ArchSpec &arch);72 73  static lldb_private::EmulateInstruction *74  CreateInstance(const lldb_private::ArchSpec &arch, InstructionType inst_type);75 76  static void Initialize();77 78  static void Terminate();79 80public:81  EmulateInstructionRISCV(const ArchSpec &arch) : EmulateInstruction(arch) {}82 83  llvm::StringRef GetPluginName() override { return GetPluginNameStatic(); }84 85  bool SupportsEmulatingInstructionsOfType(InstructionType inst_type) override {86    return SupportsThisInstructionType(inst_type);87  }88 89  bool CreateFunctionEntryUnwind(UnwindPlan &unwind_plan) override;90  bool SetTargetTriple(const ArchSpec &arch) override;91  bool ReadInstruction() override;92  std::optional<uint32_t> GetLastInstrSize() override { return m_last_size; }93  bool EvaluateInstruction(uint32_t options) override;94  bool TestEmulation(Stream &out_stream, ArchSpec &arch,95                     OptionValueDictionary *test_data) override;96  std::optional<RegisterInfo> GetRegisterInfo(lldb::RegisterKind reg_kind,97                                              uint32_t reg_num) override;98 99  bool SetInstruction(const Opcode &opcode, const Address &inst_addr,100                      Target *target) override;101  std::optional<DecodeResult> ReadInstructionAt(lldb::addr_t addr);102  std::optional<DecodeResult> Decode(uint32_t inst);103  bool Execute(DecodeResult inst, bool ignore_cond);104 105  template <typename T>106  std::enable_if_t<std::is_integral_v<T>, std::optional<T>>107  ReadMem(uint64_t addr) {108    EmulateInstructionRISCV::Context ctx;109    ctx.type = EmulateInstruction::eContextRegisterLoad;110    ctx.SetNoArgs();111    bool success = false;112    T result = ReadMemoryUnsigned(ctx, addr, sizeof(T), T(), &success);113    if (!success)114      return {}; // aka return false115    return result;116  }117 118  template <typename T> bool WriteMem(uint64_t addr, uint64_t value) {119    EmulateInstructionRISCV::Context ctx;120    ctx.type = EmulateInstruction::eContextRegisterStore;121    ctx.SetNoArgs();122    return WriteMemoryUnsigned(ctx, addr, value, sizeof(T));123  }124 125  llvm::RoundingMode GetRoundingMode();126  bool SetAccruedExceptions(llvm::APFloatBase::opStatus);127 128private:129  BreakpointLocationsPredictorCreator130  GetSingleStepBreakpointLocationsPredictorCreator() override {131    return [](std::unique_ptr<EmulateInstruction> emulator_up) {132      return std::make_unique<RISCVSingleStepBreakpointLocationsPredictor>(133          std::move(emulator_up));134    };135  }136  /// Last decoded instruction from m_opcode137  DecodeResult m_decoded;138  /// Last decoded instruction size estimate.139  std::optional<uint32_t> m_last_size;140};141 142} // namespace lldb_private143 144#endif // LLDB_SOURCE_PLUGINS_INSTRUCTION_RISCV_EMULATEINSTRUCTIONRISCV_H145