mirror of
https://github.com/momo5502/emulator.git
synced 2026-01-22 13:13:57 +00:00
116 lines
4.0 KiB
C++
116 lines
4.0 KiB
C++
#pragma once
|
|
#include <chrono>
|
|
#include <functional>
|
|
#include <cassert>
|
|
|
|
#include "memory_manager.hpp"
|
|
|
|
struct emulator_hook;
|
|
|
|
using memory_operation = memory_permission;
|
|
|
|
enum class instruction_hook_continuation : bool
|
|
{
|
|
run_instruction = false,
|
|
skip_instruction = true,
|
|
};
|
|
|
|
enum class memory_violation_continuation : bool
|
|
{
|
|
stop = false,
|
|
resume = true,
|
|
};
|
|
|
|
enum class memory_violation_type : uint8_t
|
|
{
|
|
unmapped,
|
|
protection,
|
|
};
|
|
|
|
using instruction_hook_callback = std::function<instruction_hook_continuation()>;
|
|
|
|
using interrupt_hook_callback = std::function<void(int interrupt)>;
|
|
using simple_memory_hook_callback = std::function<void(uint64_t address, size_t size)>;
|
|
using complex_memory_hook_callback = std::function<void(uint64_t address, size_t size, memory_operation operation)>;
|
|
using memory_violation_hook_callback = std::function<memory_violation_continuation(
|
|
uint64_t address, size_t size, memory_operation operation,
|
|
memory_violation_type type)>;
|
|
|
|
class emulator : public memory_manager, public utils::serializable
|
|
{
|
|
public:
|
|
emulator() = default;
|
|
|
|
emulator(const emulator&) = delete;
|
|
emulator& operator=(const emulator&) = delete;
|
|
|
|
emulator(emulator&&) = delete;
|
|
emulator& operator=(emulator&&) = delete;
|
|
|
|
virtual void start(uint64_t start, uint64_t end = 0, std::chrono::microseconds timeout = {}, size_t count = 0) = 0;
|
|
virtual void stop() = 0;
|
|
|
|
virtual void read_raw_register(int reg, void* value, size_t size) = 0;
|
|
virtual void write_raw_register(int reg, const void* value, size_t size) = 0;
|
|
|
|
virtual emulator_hook* hook_memory_violation(uint64_t address, size_t size,
|
|
memory_violation_hook_callback callback) = 0;
|
|
|
|
virtual emulator_hook* hook_memory_access(uint64_t address, size_t size, memory_operation filter,
|
|
complex_memory_hook_callback callback) = 0;
|
|
virtual emulator_hook* hook_instruction(int instruction_type, instruction_hook_callback callback) = 0;
|
|
|
|
virtual emulator_hook* hook_interrupt(interrupt_hook_callback callback) = 0;
|
|
|
|
virtual void delete_hook(emulator_hook* hook) = 0;
|
|
|
|
emulator_hook* hook_memory_violation(memory_violation_hook_callback callback)
|
|
{
|
|
return this->hook_memory_violation(0, std::numeric_limits<size_t>::max(), std::move(callback));
|
|
}
|
|
|
|
emulator_hook* hook_memory_read(const uint64_t address, const size_t size, simple_memory_hook_callback callback)
|
|
{
|
|
return this->hook_simple_memory_access(address, size, std::move(callback), memory_operation::read);
|
|
}
|
|
|
|
emulator_hook* hook_memory_write(const uint64_t address, const size_t size, simple_memory_hook_callback callback)
|
|
{
|
|
return this->hook_simple_memory_access(address, size, std::move(callback), memory_operation::write);
|
|
}
|
|
|
|
emulator_hook* hook_memory_execution(const uint64_t address, const size_t size,
|
|
simple_memory_hook_callback callback)
|
|
{
|
|
return this->hook_simple_memory_access(address, size, std::move(callback), memory_operation::exec);
|
|
}
|
|
|
|
void serialize(utils::buffer_serializer& buffer) const final
|
|
{
|
|
this->serialize_memory_state(buffer);
|
|
this->serialize_state(buffer);
|
|
}
|
|
|
|
void deserialize(utils::buffer_deserializer& buffer) final
|
|
{
|
|
this->deserialize_memory_state(buffer);
|
|
this->deserialize_state(buffer);
|
|
}
|
|
|
|
private:
|
|
emulator_hook* hook_simple_memory_access(const uint64_t address, const size_t size,
|
|
simple_memory_hook_callback callback, const memory_operation operation)
|
|
{
|
|
assert((static_cast<uint8_t>(operation) & (static_cast<uint8_t>(operation) - 1)) == 0);
|
|
return this->hook_memory_access(address, size, operation,
|
|
[c = std::move(callback)](const uint64_t a, const size_t s,
|
|
memory_operation)
|
|
{
|
|
c(a, s);
|
|
});
|
|
}
|
|
|
|
virtual void serialize_state(utils::buffer_serializer& buffer) const = 0;
|
|
virtual void deserialize_state(utils::buffer_deserializer& buffer) = 0;
|
|
};
|