mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-09-21 09:55:14 +00:00
Compare commits
5 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 74b5e10dc5 | |||
| a277b62fe4 | |||
| 908b1e9a37 | |||
| 847e91c3a8 | |||
| 2d1eb0dab9 |
@@ -788,7 +788,7 @@ int Java_org_yuzu_yuzu_1emu_NativeLibrary_installFileToNand(JNIEnv* env, jobject
|
|||||||
jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_doesUpdateMatchProgram(JNIEnv* env, jobject jobj,
|
jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_doesUpdateMatchProgram(JNIEnv* env, jobject jobj,
|
||||||
jstring jprogramId,
|
jstring jprogramId,
|
||||||
jstring jupdatePath) {
|
jstring jupdatePath) {
|
||||||
u64 program_id = EmulationSession::GetProgramId(env, jprogramId);
|
const u64 program_id = FileSys::GetBaseTitleID(EmulationSession::GetProgramId(env, jprogramId));
|
||||||
std::string updatePath = Common::Android::GetJString(env, jupdatePath);
|
std::string updatePath = Common::Android::GetJString(env, jupdatePath);
|
||||||
std::shared_ptr<FileSys::NSP> nsp = std::make_shared<FileSys::NSP>(
|
std::shared_ptr<FileSys::NSP> nsp = std::make_shared<FileSys::NSP>(
|
||||||
EmulationSession::GetInstance().System().GetFilesystem()->OpenFile(
|
EmulationSession::GetInstance().System().GetFilesystem()->OpenFile(
|
||||||
@@ -796,7 +796,7 @@ jboolean Java_org_yuzu_yuzu_1emu_NativeLibrary_doesUpdateMatchProgram(JNIEnv* en
|
|||||||
for (const auto& item : nsp->GetNCAs()) {
|
for (const auto& item : nsp->GetNCAs()) {
|
||||||
for (const auto& nca_details : item.second) {
|
for (const auto& nca_details : item.second) {
|
||||||
if (nca_details.second->GetName().ends_with(".cnmt.nca")) {
|
if (nca_details.second->GetName().ends_with(".cnmt.nca")) {
|
||||||
auto update_id = nca_details.second->GetTitleId() & ~0xFFFULL;
|
const auto update_id = FileSys::GetBaseTitleID(nca_details.second->GetTitleId());
|
||||||
if (update_id == program_id) {
|
if (update_id == program_id) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
+18
-20
@@ -17,35 +17,33 @@
|
|||||||
|
|
||||||
namespace Common {
|
namespace Common {
|
||||||
|
|
||||||
|
// glibc, mlibc, musl, and newlib all define their own variants of strerror_r
|
||||||
|
// We don't need to use the preprocessor, we can just select depending on return type
|
||||||
|
template<typename T> std::string HandleStrerrorR(T r, char *err_str);
|
||||||
|
template<> std::string HandleStrerrorR(char* r, char *) { return std::string{r}; }
|
||||||
|
template<> std::string HandleStrerrorR(const char* r, char *) { return std::string{r}; }
|
||||||
|
template<> std::string HandleStrerrorR(int r, char *err_str) {
|
||||||
|
return std::string{r != 0
|
||||||
|
? "(strerror_r failed to format error)"
|
||||||
|
: err_str};
|
||||||
|
}
|
||||||
|
|
||||||
std::string NativeErrorToString(int e) {
|
std::string NativeErrorToString(int e) {
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
LPSTR err_str;
|
LPSTR err_str;
|
||||||
|
|
||||||
DWORD res = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
DWORD res = FormatMessageA(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER |
|
||||||
FORMAT_MESSAGE_IGNORE_INSERTS,
|
FORMAT_MESSAGE_IGNORE_INSERTS,
|
||||||
nullptr, e, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
nullptr, e, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
|
||||||
reinterpret_cast<LPSTR>(&err_str), 1, nullptr);
|
LPSTR(&err_str), 1, nullptr);
|
||||||
if (!res) {
|
if (res) {
|
||||||
return "(FormatMessageA failed to format error)";
|
std::string ret(err_str);
|
||||||
|
LocalFree(err_str);
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
std::string ret(err_str);
|
return "(FormatMessageA failed to format error)";
|
||||||
LocalFree(err_str);
|
|
||||||
return ret;
|
|
||||||
#else
|
#else
|
||||||
char err_str[255];
|
char err_str[255];
|
||||||
#if defined(__ANDROID__) || \
|
return HandleStrerrorR(strerror_r(e, err_str, sizeof(err_str)), err_str);
|
||||||
(defined(__GLIBC__) && (_GNU_SOURCE || (_POSIX_C_SOURCE < 200112L && _XOPEN_SOURCE < 600)))
|
|
||||||
// Thread safe (GNU-specific)
|
|
||||||
const char* str = strerror_r(e, err_str, sizeof(err_str));
|
|
||||||
return std::string(str);
|
|
||||||
#else
|
|
||||||
// Thread safe (XSI-compliant)
|
|
||||||
int second_err = strerror_r(e, err_str, sizeof(err_str));
|
|
||||||
if (second_err != 0) {
|
|
||||||
return "(strerror_r failed to format error)";
|
|
||||||
}
|
|
||||||
return std::string(err_str);
|
|
||||||
#endif // GLIBC etc.
|
|
||||||
#endif // _WIN32
|
#endif // _WIN32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@
|
|||||||
#include "common/logging.h"
|
#include "common/logging.h"
|
||||||
#include "common/uuid.h"
|
#include "common/uuid.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/file_sys/registered_cache.h"
|
|
||||||
#include "core/file_sys/savedata_factory.h"
|
#include "core/file_sys/savedata_factory.h"
|
||||||
#include "core/file_sys/vfs/vfs.h"
|
#include "core/file_sys/vfs/vfs.h"
|
||||||
|
|
||||||
@@ -62,24 +61,17 @@ SaveDataFactory::SaveDataFactory(Core::System& system_, ProgramId program_id_,
|
|||||||
|
|
||||||
SaveDataFactory::~SaveDataFactory() = default;
|
SaveDataFactory::~SaveDataFactory() = default;
|
||||||
|
|
||||||
std::string SaveDataFactory::GetSaveDataPath(SaveDataSpaceId space, SaveDataType type, u64 title_id, u128 user_id, u64 save_id) const {
|
|
||||||
if (type == SaveDataType::Account || type == SaveDataType::Device) {
|
|
||||||
const auto requested_id = title_id != 0 ? title_id : program_id;
|
|
||||||
const auto parent_id = system.GetContentProvider().GetParentApplicationId(requested_id);
|
|
||||||
title_id = parent_id.value_or(requested_id);
|
|
||||||
}
|
|
||||||
return GetFullPath(program_id, dir, space, type, title_id, user_id, save_id);
|
|
||||||
}
|
|
||||||
|
|
||||||
VirtualDir SaveDataFactory::Create(SaveDataSpaceId space, const SaveDataAttribute& meta) const {
|
VirtualDir SaveDataFactory::Create(SaveDataSpaceId space, const SaveDataAttribute& meta) const {
|
||||||
const auto save_directory = GetSaveDataPath(space, meta.type, meta.program_id, meta.user_id, meta.system_save_data_id);
|
const auto save_directory = GetFullPath(program_id, dir, space, meta.type, meta.program_id,
|
||||||
|
meta.user_id, meta.system_save_data_id);
|
||||||
|
|
||||||
return dir->CreateDirectoryRelative(save_directory);
|
return dir->CreateDirectoryRelative(save_directory);
|
||||||
}
|
}
|
||||||
|
|
||||||
VirtualDir SaveDataFactory::Open(SaveDataSpaceId space, const SaveDataAttribute& meta) const {
|
VirtualDir SaveDataFactory::Open(SaveDataSpaceId space, const SaveDataAttribute& meta) const {
|
||||||
|
|
||||||
const auto save_directory = GetSaveDataPath(space, meta.type, meta.program_id, meta.user_id, meta.system_save_data_id);
|
const auto save_directory = GetFullPath(program_id, dir, space, meta.type, meta.program_id,
|
||||||
|
meta.user_id, meta.system_save_data_id);
|
||||||
|
|
||||||
auto out = dir->GetDirectoryRelative(save_directory);
|
auto out = dir->GetDirectoryRelative(save_directory);
|
||||||
|
|
||||||
@@ -162,7 +154,8 @@ std::string SaveDataFactory::GetUserGameSaveDataRoot(u128 user_id, bool future)
|
|||||||
|
|
||||||
SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id,
|
SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id,
|
||||||
u128 user_id) const {
|
u128 user_id) const {
|
||||||
const auto path = GetSaveDataPath(SaveDataSpaceId::User, type, title_id, user_id, 0);
|
const auto path =
|
||||||
|
GetFullPath(program_id, dir, SaveDataSpaceId::User, type, title_id, user_id, 0);
|
||||||
const auto relative_dir = GetOrCreateDirectoryRelative(dir, path);
|
const auto relative_dir = GetOrCreateDirectoryRelative(dir, path);
|
||||||
|
|
||||||
const auto size_file = relative_dir->GetFile(GetSaveDataSizeFileName());
|
const auto size_file = relative_dir->GetFile(GetSaveDataSizeFileName());
|
||||||
@@ -180,7 +173,8 @@ SaveDataSize SaveDataFactory::ReadSaveDataSize(SaveDataType type, u64 title_id,
|
|||||||
|
|
||||||
void SaveDataFactory::WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id,
|
void SaveDataFactory::WriteSaveDataSize(SaveDataType type, u64 title_id, u128 user_id,
|
||||||
SaveDataSize new_value) const {
|
SaveDataSize new_value) const {
|
||||||
const auto path = GetSaveDataPath(SaveDataSpaceId::User, type, title_id, user_id, 0);
|
const auto path =
|
||||||
|
GetFullPath(program_id, dir, SaveDataSpaceId::User, type, title_id, user_id, 0);
|
||||||
const auto relative_dir = GetOrCreateDirectoryRelative(dir, path);
|
const auto relative_dir = GetOrCreateDirectoryRelative(dir, path);
|
||||||
|
|
||||||
const auto size_file = relative_dir->CreateFile(GetSaveDataSizeFileName());
|
const auto size_file = relative_dir->CreateFile(GetSaveDataSizeFileName());
|
||||||
|
|||||||
@@ -50,7 +50,6 @@ public:
|
|||||||
void SetAutoCreate(bool state);
|
void SetAutoCreate(bool state);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::string GetSaveDataPath(SaveDataSpaceId space, SaveDataType type, u64 title_id, u128 user_id, u64 save_id) const;
|
|
||||||
Core::System& system;
|
Core::System& system;
|
||||||
ProgramId program_id;
|
ProgramId program_id;
|
||||||
VirtualDir dir;
|
VirtualDir dir;
|
||||||
|
|||||||
@@ -29,6 +29,7 @@
|
|||||||
#include "core/hle/service/am/frontend/applet_web_browser.h"
|
#include "core/hle/service/am/frontend/applet_web_browser.h"
|
||||||
#include "core/hle/service/am/frontend/applets.h"
|
#include "core/hle/service/am/frontend/applets.h"
|
||||||
#include "core/hle/service/am/service/storage.h"
|
#include "core/hle/service/am/service/storage.h"
|
||||||
|
#include "core/hle/service/am/window_system.h"
|
||||||
#include "core/hle/service/sm/sm.h"
|
#include "core/hle/service/sm/sm.h"
|
||||||
|
|
||||||
namespace Service::AM::Frontend {
|
namespace Service::AM::Frontend {
|
||||||
@@ -72,10 +73,16 @@ void FrontendApplet::PushInteractiveOutData(std::shared_ptr<IStorage> storage) {
|
|||||||
|
|
||||||
void FrontendApplet::Exit() {
|
void FrontendApplet::Exit() {
|
||||||
auto applet_ = applet.lock();
|
auto applet_ = applet.lock();
|
||||||
|
{
|
||||||
std::scoped_lock lk{applet_->lock};
|
std::scoped_lock lk{applet_->lock};
|
||||||
applet_->is_completed = true;
|
applet_->is_completed = true;
|
||||||
applet_->state_changed_event.Signal(system.Kernel());
|
applet_->state_changed_event.Signal(system.Kernel());
|
||||||
|
}
|
||||||
|
if (auto caller_applet = applet_->caller_applet.lock()) {
|
||||||
|
std::scoped_lock lk{caller_applet->lock};
|
||||||
|
std::erase(caller_applet->child_applets, applet_);
|
||||||
|
}
|
||||||
|
if (auto* window_system = system.GetAppletManager().GetWindowSystem()) window_system->RequestUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
FrontendAppletSet::FrontendAppletSet() = default;
|
FrontendAppletSet::FrontendAppletSet() = default;
|
||||||
|
|||||||
@@ -122,7 +122,10 @@ std::shared_ptr<ILibraryAppletAccessor> CreateGuestApplet(Core::System& system,
|
|||||||
auto broker = std::make_shared<AppletDataBroker>(system);
|
auto broker = std::make_shared<AppletDataBroker>(system);
|
||||||
applet->caller_applet = caller_applet;
|
applet->caller_applet = caller_applet;
|
||||||
applet->caller_applet_broker = broker;
|
applet->caller_applet_broker = broker;
|
||||||
caller_applet->child_applets.push_back(applet);
|
{
|
||||||
|
std::scoped_lock lk{caller_applet->lock};
|
||||||
|
caller_applet->child_applets.push_back(applet);
|
||||||
|
}
|
||||||
window_system.TrackApplet(applet, false);
|
window_system.TrackApplet(applet, false);
|
||||||
return std::make_shared<ILibraryAppletAccessor>(system, broker, applet);
|
return std::make_shared<ILibraryAppletAccessor>(system, broker, applet);
|
||||||
}
|
}
|
||||||
@@ -148,10 +151,10 @@ std::shared_ptr<ILibraryAppletAccessor> CreateFrontendApplet(Core::System& syste
|
|||||||
applet->caller_applet = caller_applet;
|
applet->caller_applet = caller_applet;
|
||||||
applet->caller_applet_broker = storage;
|
applet->caller_applet_broker = storage;
|
||||||
applet->frontend = system.GetFrontendAppletHolder().GetApplet(applet, applet_id, mode);
|
applet->frontend = system.GetFrontendAppletHolder().GetApplet(applet, applet_id, mode);
|
||||||
caller_applet->child_applets.push_back(applet);
|
{
|
||||||
|
std::scoped_lock lk{caller_applet->lock};
|
||||||
window_system.TrackApplet(applet, false);
|
caller_applet->child_applets.push_back(applet);
|
||||||
|
}
|
||||||
return std::make_shared<ILibraryAppletAccessor>(system, storage, applet);
|
return std::make_shared<ILibraryAppletAccessor>(system, storage, applet);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,29 +24,65 @@
|
|||||||
namespace Dynarmic::Backend::Arm64 {
|
namespace Dynarmic::Backend::Arm64 {
|
||||||
|
|
||||||
template<auto mfp, typename T>
|
template<auto mfp, typename T>
|
||||||
static void* EmitCallTrampoline(oaknut::CodeGenerator& code, T* this_) {
|
static void* EmitCallReadTrampoline(oaknut::CodeGenerator& code, T* this_, size_t bitsize) {
|
||||||
using namespace oaknut::util;
|
using namespace oaknut::util;
|
||||||
|
|
||||||
const auto info = Devirtualize<mfp>(this_);
|
const auto info = Devirtualize<mfp>(this_);
|
||||||
|
|
||||||
oaknut::Label l_addr, l_this;
|
oaknut::Label l_addr, l_this;
|
||||||
|
|
||||||
void* target = code.xptr<void*>();
|
void* target = code.xptr<void*>();
|
||||||
|
// params = { this, vaddr, bitsize }
|
||||||
code.LDR(X0, l_this);
|
code.LDR(X0, l_this);
|
||||||
|
// X1 = vaddr
|
||||||
|
code.MOV(X2, bitsize);
|
||||||
code.LDR(Xscratch0, l_addr);
|
code.LDR(Xscratch0, l_addr);
|
||||||
code.BR(Xscratch0);
|
code.BR(Xscratch0);
|
||||||
|
|
||||||
code.align(8);
|
code.align(8);
|
||||||
code.l(l_this);
|
code.l(l_this);
|
||||||
code.dx(info.this_ptr);
|
code.dx(info.this_ptr);
|
||||||
code.l(l_addr);
|
code.l(l_addr);
|
||||||
code.dx(info.fn_ptr);
|
code.dx(info.fn_ptr);
|
||||||
|
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<auto mfp, typename T>
|
template<auto mfp, typename T>
|
||||||
static void* EmitWrappedReadCallTrampoline(oaknut::CodeGenerator& code, T* this_) {
|
static void* EmitCallWriteTrampoline(oaknut::CodeGenerator& code, T* this_, size_t bitsize) {
|
||||||
|
using namespace oaknut::util;
|
||||||
|
const auto info = Devirtualize<mfp>(this_);
|
||||||
|
oaknut::Label l_addr, l_this;
|
||||||
|
void* target = code.xptr<void*>();
|
||||||
|
// params = { this, vaddr, value, bitsize }
|
||||||
|
code.LDR(X0, l_this);
|
||||||
|
// X1 = vaddr
|
||||||
|
// X2 = value
|
||||||
|
code.MOV(X3, bitsize);
|
||||||
|
code.LDR(Xscratch0, l_addr);
|
||||||
|
code.BR(Xscratch0);
|
||||||
|
code.align(8);
|
||||||
|
code.l(l_this);
|
||||||
|
code.dx(info.this_ptr);
|
||||||
|
code.l(l_addr);
|
||||||
|
code.dx(info.fn_ptr);
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<auto mfp, typename T>
|
||||||
|
static void* EmitCallTrampoline(oaknut::CodeGenerator& code, T* this_) {
|
||||||
|
using namespace oaknut::util;
|
||||||
|
const auto info = Devirtualize<mfp>(this_);
|
||||||
|
oaknut::Label l_addr, l_this;
|
||||||
|
void* target = code.xptr<void*>();
|
||||||
|
code.LDR(X0, l_this);
|
||||||
|
code.LDR(Xscratch0, l_addr);
|
||||||
|
code.BR(Xscratch0);
|
||||||
|
code.align(8);
|
||||||
|
code.l(l_this);
|
||||||
|
code.dx(info.this_ptr);
|
||||||
|
code.l(l_addr);
|
||||||
|
code.dx(info.fn_ptr);
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<auto mfp, typename T>
|
||||||
|
static void* EmitWrappedReadCallTrampoline(oaknut::CodeGenerator& code, T* this_, size_t bitsize) {
|
||||||
using namespace oaknut::util;
|
using namespace oaknut::util;
|
||||||
|
|
||||||
const auto info = Devirtualize<mfp>(this_);
|
const auto info = Devirtualize<mfp>(this_);
|
||||||
@@ -59,6 +95,7 @@ static void* EmitWrappedReadCallTrampoline(oaknut::CodeGenerator& code, T* this_
|
|||||||
ABI_PushRegisters(code, save_regs, 0);
|
ABI_PushRegisters(code, save_regs, 0);
|
||||||
code.LDR(X0, l_this);
|
code.LDR(X0, l_this);
|
||||||
code.MOV(X1, Xscratch0);
|
code.MOV(X1, Xscratch0);
|
||||||
|
code.MOV(X2, bitsize);
|
||||||
code.LDR(Xscratch0, l_addr);
|
code.LDR(Xscratch0, l_addr);
|
||||||
code.BLR(Xscratch0);
|
code.BLR(Xscratch0);
|
||||||
code.MOV(Xscratch0, X0);
|
code.MOV(Xscratch0, X0);
|
||||||
@@ -101,7 +138,7 @@ static void* EmitExclusiveReadCallTrampoline(oaknut::CodeGenerator& code, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<auto mfp, typename T>
|
template<auto mfp, typename T>
|
||||||
static void* EmitWrappedWriteCallTrampoline(oaknut::CodeGenerator& code, T* this_) {
|
static void* EmitWrappedWriteCallTrampoline(oaknut::CodeGenerator& code, T* this_, size_t bitsize) {
|
||||||
using namespace oaknut::util;
|
using namespace oaknut::util;
|
||||||
|
|
||||||
const auto info = Devirtualize<mfp>(this_);
|
const auto info = Devirtualize<mfp>(this_);
|
||||||
@@ -115,6 +152,7 @@ static void* EmitWrappedWriteCallTrampoline(oaknut::CodeGenerator& code, T* this
|
|||||||
code.LDR(X0, l_this);
|
code.LDR(X0, l_this);
|
||||||
code.MOV(X1, Xscratch0);
|
code.MOV(X1, Xscratch0);
|
||||||
code.MOV(X2, Xscratch1);
|
code.MOV(X2, Xscratch1);
|
||||||
|
code.MOV(X3, bitsize);
|
||||||
code.LDR(Xscratch0, l_addr);
|
code.LDR(Xscratch0, l_addr);
|
||||||
code.BLR(Xscratch0);
|
code.BLR(Xscratch0);
|
||||||
ABI_PopRegisters(code, save_regs, 0);
|
ABI_PopRegisters(code, save_regs, 0);
|
||||||
@@ -176,14 +214,27 @@ void A32AddressSpace::EmitPrelude() {
|
|||||||
|
|
||||||
UnprotectCodeMemory();
|
UnprotectCodeMemory();
|
||||||
|
|
||||||
prelude_info.read_memory = EmitCallTrampoline<&A32::UserCallbacks::MemoryRead>(code, conf.callbacks);
|
|
||||||
prelude_info.wrapped_read_memory = EmitWrappedReadCallTrampoline<&A32::UserCallbacks::MemoryRead>(code, conf.callbacks);
|
prelude_info.read_memory_8 = EmitCallReadTrampoline<&A32::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u8));
|
||||||
|
prelude_info.read_memory_16 = EmitCallReadTrampoline<&A32::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u16));
|
||||||
|
prelude_info.read_memory_32 = EmitCallReadTrampoline<&A32::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u32));
|
||||||
|
prelude_info.read_memory_64 = EmitCallReadTrampoline<&A32::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u64));
|
||||||
|
prelude_info.wrapped_read_memory_8 = EmitWrappedReadCallTrampoline<&A32::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u8));
|
||||||
|
prelude_info.wrapped_read_memory_16 = EmitWrappedReadCallTrampoline<&A32::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u16));
|
||||||
|
prelude_info.wrapped_read_memory_32 = EmitWrappedReadCallTrampoline<&A32::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u32));
|
||||||
|
prelude_info.wrapped_read_memory_64 = EmitWrappedReadCallTrampoline<&A32::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u64));
|
||||||
prelude_info.exclusive_read_memory_8 = EmitExclusiveReadCallTrampoline<&A32::UserCallbacks::MemoryRead, u8>(code, conf);
|
prelude_info.exclusive_read_memory_8 = EmitExclusiveReadCallTrampoline<&A32::UserCallbacks::MemoryRead, u8>(code, conf);
|
||||||
prelude_info.exclusive_read_memory_16 = EmitExclusiveReadCallTrampoline<&A32::UserCallbacks::MemoryRead, u16>(code, conf);
|
prelude_info.exclusive_read_memory_16 = EmitExclusiveReadCallTrampoline<&A32::UserCallbacks::MemoryRead, u16>(code, conf);
|
||||||
prelude_info.exclusive_read_memory_32 = EmitExclusiveReadCallTrampoline<&A32::UserCallbacks::MemoryRead, u32>(code, conf);
|
prelude_info.exclusive_read_memory_32 = EmitExclusiveReadCallTrampoline<&A32::UserCallbacks::MemoryRead, u32>(code, conf);
|
||||||
prelude_info.exclusive_read_memory_64 = EmitExclusiveReadCallTrampoline<&A32::UserCallbacks::MemoryRead, u64>(code, conf);
|
prelude_info.exclusive_read_memory_64 = EmitExclusiveReadCallTrampoline<&A32::UserCallbacks::MemoryRead, u64>(code, conf);
|
||||||
prelude_info.write_memory = EmitCallTrampoline<&A32::UserCallbacks::MemoryWrite>(code, conf.callbacks);
|
prelude_info.write_memory_8 = EmitCallWriteTrampoline<&A32::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u8));
|
||||||
prelude_info.wrapped_write_memory = EmitWrappedWriteCallTrampoline<&A32::UserCallbacks::MemoryWrite>(code, conf.callbacks);
|
prelude_info.write_memory_16 = EmitCallWriteTrampoline<&A32::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u16));
|
||||||
|
prelude_info.write_memory_32 = EmitCallWriteTrampoline<&A32::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u32));
|
||||||
|
prelude_info.write_memory_64 = EmitCallWriteTrampoline<&A32::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u64));
|
||||||
|
prelude_info.wrapped_write_memory_8 = EmitWrappedWriteCallTrampoline<&A32::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u8));
|
||||||
|
prelude_info.wrapped_write_memory_16 = EmitWrappedWriteCallTrampoline<&A32::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u16));
|
||||||
|
prelude_info.wrapped_write_memory_32 = EmitWrappedWriteCallTrampoline<&A32::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u32));
|
||||||
|
prelude_info.wrapped_write_memory_64 = EmitWrappedWriteCallTrampoline<&A32::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u64));
|
||||||
prelude_info.exclusive_write_memory_8 = EmitExclusiveWriteCallTrampoline<&A32::UserCallbacks::MemoryWriteExclusive8, u8>(code, conf);
|
prelude_info.exclusive_write_memory_8 = EmitExclusiveWriteCallTrampoline<&A32::UserCallbacks::MemoryWriteExclusive8, u8>(code, conf);
|
||||||
prelude_info.exclusive_write_memory_16 = EmitExclusiveWriteCallTrampoline<&A32::UserCallbacks::MemoryWriteExclusive16, u16>(code, conf);
|
prelude_info.exclusive_write_memory_16 = EmitExclusiveWriteCallTrampoline<&A32::UserCallbacks::MemoryWriteExclusive16, u16>(code, conf);
|
||||||
prelude_info.exclusive_write_memory_32 = EmitExclusiveWriteCallTrampoline<&A32::UserCallbacks::MemoryWriteExclusive32, u32>(code, conf);
|
prelude_info.exclusive_write_memory_32 = EmitExclusiveWriteCallTrampoline<&A32::UserCallbacks::MemoryWriteExclusive32, u32>(code, conf);
|
||||||
|
|||||||
@@ -23,29 +23,65 @@
|
|||||||
namespace Dynarmic::Backend::Arm64 {
|
namespace Dynarmic::Backend::Arm64 {
|
||||||
|
|
||||||
template<auto mfp, typename T>
|
template<auto mfp, typename T>
|
||||||
static void* EmitCallTrampoline(oaknut::CodeGenerator& code, T* this_) {
|
static void* EmitCallReadTrampoline(oaknut::CodeGenerator& code, T* this_, size_t bitsize) {
|
||||||
using namespace oaknut::util;
|
using namespace oaknut::util;
|
||||||
|
|
||||||
const auto info = Devirtualize<mfp>(this_);
|
const auto info = Devirtualize<mfp>(this_);
|
||||||
|
|
||||||
oaknut::Label l_addr, l_this;
|
oaknut::Label l_addr, l_this;
|
||||||
|
|
||||||
void* target = code.xptr<void*>();
|
void* target = code.xptr<void*>();
|
||||||
|
// params = { this, vaddr, bitsize }
|
||||||
code.LDR(X0, l_this);
|
code.LDR(X0, l_this);
|
||||||
|
// X1 = vaddr
|
||||||
|
code.MOV(X2, bitsize);
|
||||||
code.LDR(Xscratch0, l_addr);
|
code.LDR(Xscratch0, l_addr);
|
||||||
code.BR(Xscratch0);
|
code.BR(Xscratch0);
|
||||||
|
|
||||||
code.align(8);
|
code.align(8);
|
||||||
code.l(l_this);
|
code.l(l_this);
|
||||||
code.dx(info.this_ptr);
|
code.dx(info.this_ptr);
|
||||||
code.l(l_addr);
|
code.l(l_addr);
|
||||||
code.dx(info.fn_ptr);
|
code.dx(info.fn_ptr);
|
||||||
|
|
||||||
return target;
|
return target;
|
||||||
}
|
}
|
||||||
|
|
||||||
template<auto mfp, typename T>
|
template<auto mfp, typename T>
|
||||||
static void* EmitWrappedReadCallTrampoline(oaknut::CodeGenerator& code, T* this_) {
|
static void* EmitCallWriteTrampoline(oaknut::CodeGenerator& code, T* this_, size_t bitsize) {
|
||||||
|
using namespace oaknut::util;
|
||||||
|
const auto info = Devirtualize<mfp>(this_);
|
||||||
|
oaknut::Label l_addr, l_this;
|
||||||
|
void* target = code.xptr<void*>();
|
||||||
|
// params = { this, vaddr, value, bitsize }
|
||||||
|
code.LDR(X0, l_this);
|
||||||
|
// X1 = vaddr
|
||||||
|
// X2 = value
|
||||||
|
code.MOV(X3, bitsize);
|
||||||
|
code.LDR(Xscratch0, l_addr);
|
||||||
|
code.BR(Xscratch0);
|
||||||
|
code.align(8);
|
||||||
|
code.l(l_this);
|
||||||
|
code.dx(info.this_ptr);
|
||||||
|
code.l(l_addr);
|
||||||
|
code.dx(info.fn_ptr);
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<auto mfp, typename T>
|
||||||
|
static void* EmitCallTrampoline(oaknut::CodeGenerator& code, T* this_) {
|
||||||
|
using namespace oaknut::util;
|
||||||
|
const auto info = Devirtualize<mfp>(this_);
|
||||||
|
oaknut::Label l_addr, l_this;
|
||||||
|
void* target = code.xptr<void*>();
|
||||||
|
code.LDR(X0, l_this);
|
||||||
|
code.LDR(Xscratch0, l_addr);
|
||||||
|
code.BR(Xscratch0);
|
||||||
|
code.align(8);
|
||||||
|
code.l(l_this);
|
||||||
|
code.dx(info.this_ptr);
|
||||||
|
code.l(l_addr);
|
||||||
|
code.dx(info.fn_ptr);
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<auto mfp, typename T>
|
||||||
|
static void* EmitWrappedReadCallTrampoline(oaknut::CodeGenerator& code, T* this_, size_t bitsize) {
|
||||||
using namespace oaknut::util;
|
using namespace oaknut::util;
|
||||||
|
|
||||||
const auto info = Devirtualize<mfp>(this_);
|
const auto info = Devirtualize<mfp>(this_);
|
||||||
@@ -58,6 +94,7 @@ static void* EmitWrappedReadCallTrampoline(oaknut::CodeGenerator& code, T* this_
|
|||||||
ABI_PushRegisters(code, save_regs, 0);
|
ABI_PushRegisters(code, save_regs, 0);
|
||||||
code.LDR(X0, l_this);
|
code.LDR(X0, l_this);
|
||||||
code.MOV(X1, Xscratch0);
|
code.MOV(X1, Xscratch0);
|
||||||
|
code.MOV(X2, bitsize);
|
||||||
code.LDR(Xscratch0, l_addr);
|
code.LDR(Xscratch0, l_addr);
|
||||||
code.BLR(Xscratch0);
|
code.BLR(Xscratch0);
|
||||||
code.MOV(Xscratch0, X0);
|
code.MOV(Xscratch0, X0);
|
||||||
@@ -100,7 +137,7 @@ static void* EmitExclusiveReadCallTrampoline(oaknut::CodeGenerator& code, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<auto mfp, typename T>
|
template<auto mfp, typename T>
|
||||||
static void* EmitWrappedWriteCallTrampoline(oaknut::CodeGenerator& code, T* this_) {
|
static void* EmitWrappedWriteCallTrampoline(oaknut::CodeGenerator& code, T* this_, size_t bitsize) {
|
||||||
using namespace oaknut::util;
|
using namespace oaknut::util;
|
||||||
|
|
||||||
const auto info = Devirtualize<mfp>(this_);
|
const auto info = Devirtualize<mfp>(this_);
|
||||||
@@ -114,6 +151,7 @@ static void* EmitWrappedWriteCallTrampoline(oaknut::CodeGenerator& code, T* this
|
|||||||
code.LDR(X0, l_this);
|
code.LDR(X0, l_this);
|
||||||
code.MOV(X1, Xscratch0);
|
code.MOV(X1, Xscratch0);
|
||||||
code.MOV(X2, Xscratch1);
|
code.MOV(X2, Xscratch1);
|
||||||
|
code.MOV(X3, bitsize);
|
||||||
code.LDR(Xscratch0, l_addr);
|
code.LDR(Xscratch0, l_addr);
|
||||||
code.BLR(Xscratch0);
|
code.BLR(Xscratch0);
|
||||||
ABI_PopRegisters(code, save_regs, 0);
|
ABI_PopRegisters(code, save_regs, 0);
|
||||||
@@ -342,18 +380,30 @@ void A64AddressSpace::EmitPrelude() {
|
|||||||
|
|
||||||
UnprotectCodeMemory();
|
UnprotectCodeMemory();
|
||||||
|
|
||||||
prelude_info.read_memory = EmitCallTrampoline<&A64::UserCallbacks::MemoryRead>(code, conf.callbacks);
|
prelude_info.read_memory_8 = EmitCallReadTrampoline<&A64::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u8));
|
||||||
|
prelude_info.read_memory_16 = EmitCallReadTrampoline<&A64::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u16));
|
||||||
|
prelude_info.read_memory_32 = EmitCallReadTrampoline<&A64::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u32));
|
||||||
|
prelude_info.read_memory_64 = EmitCallReadTrampoline<&A64::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u64));
|
||||||
prelude_info.read_memory_128 = EmitRead128CallTrampoline(code, conf.callbacks);
|
prelude_info.read_memory_128 = EmitRead128CallTrampoline(code, conf.callbacks);
|
||||||
prelude_info.wrapped_read_memory = EmitWrappedReadCallTrampoline<&A64::UserCallbacks::MemoryRead>(code, conf.callbacks);
|
prelude_info.wrapped_read_memory_8 = EmitWrappedReadCallTrampoline<&A64::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u8));
|
||||||
|
prelude_info.wrapped_read_memory_16 = EmitWrappedReadCallTrampoline<&A64::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u16));
|
||||||
|
prelude_info.wrapped_read_memory_32 = EmitWrappedReadCallTrampoline<&A64::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u32));
|
||||||
|
prelude_info.wrapped_read_memory_64 = EmitWrappedReadCallTrampoline<&A64::UserCallbacks::MemoryRead>(code, conf.callbacks, sizeof(u64));
|
||||||
prelude_info.wrapped_read_memory_128 = EmitWrappedRead128CallTrampoline(code, conf.callbacks);
|
prelude_info.wrapped_read_memory_128 = EmitWrappedRead128CallTrampoline(code, conf.callbacks);
|
||||||
prelude_info.exclusive_read_memory_8 = EmitExclusiveReadCallTrampoline<&A64::UserCallbacks::MemoryRead, u8>(code, conf);
|
prelude_info.exclusive_read_memory_8 = EmitExclusiveReadCallTrampoline<&A64::UserCallbacks::MemoryRead, u8>(code, conf);
|
||||||
prelude_info.exclusive_read_memory_16 = EmitExclusiveReadCallTrampoline<&A64::UserCallbacks::MemoryRead, u16>(code, conf);
|
prelude_info.exclusive_read_memory_16 = EmitExclusiveReadCallTrampoline<&A64::UserCallbacks::MemoryRead, u16>(code, conf);
|
||||||
prelude_info.exclusive_read_memory_32 = EmitExclusiveReadCallTrampoline<&A64::UserCallbacks::MemoryRead, u32>(code, conf);
|
prelude_info.exclusive_read_memory_32 = EmitExclusiveReadCallTrampoline<&A64::UserCallbacks::MemoryRead, u32>(code, conf);
|
||||||
prelude_info.exclusive_read_memory_64 = EmitExclusiveReadCallTrampoline<&A64::UserCallbacks::MemoryRead, u64>(code, conf);
|
prelude_info.exclusive_read_memory_64 = EmitExclusiveReadCallTrampoline<&A64::UserCallbacks::MemoryRead, u64>(code, conf);
|
||||||
prelude_info.exclusive_read_memory_128 = EmitExclusiveRead128CallTrampoline(code, conf);
|
prelude_info.exclusive_read_memory_128 = EmitExclusiveRead128CallTrampoline(code, conf);
|
||||||
prelude_info.write_memory = EmitCallTrampoline<&A64::UserCallbacks::MemoryWrite>(code, conf.callbacks);
|
prelude_info.write_memory_8 = EmitCallWriteTrampoline<&A64::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u8));
|
||||||
|
prelude_info.write_memory_16 = EmitCallWriteTrampoline<&A64::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u16));
|
||||||
|
prelude_info.write_memory_32 = EmitCallWriteTrampoline<&A64::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u32));
|
||||||
|
prelude_info.write_memory_64 = EmitCallWriteTrampoline<&A64::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u64));
|
||||||
prelude_info.write_memory_128 = EmitWrite128CallTrampoline(code, conf.callbacks);
|
prelude_info.write_memory_128 = EmitWrite128CallTrampoline(code, conf.callbacks);
|
||||||
prelude_info.wrapped_write_memory = EmitWrappedWriteCallTrampoline<&A64::UserCallbacks::MemoryWrite>(code, conf.callbacks);
|
prelude_info.wrapped_write_memory_8 = EmitWrappedWriteCallTrampoline<&A64::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u8));
|
||||||
|
prelude_info.wrapped_write_memory_16 = EmitWrappedWriteCallTrampoline<&A64::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u16));
|
||||||
|
prelude_info.wrapped_write_memory_32 = EmitWrappedWriteCallTrampoline<&A64::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u32));
|
||||||
|
prelude_info.wrapped_write_memory_64 = EmitWrappedWriteCallTrampoline<&A64::UserCallbacks::MemoryWrite>(code, conf.callbacks, sizeof(u64));
|
||||||
prelude_info.wrapped_write_memory_128 = EmitWrappedWrite128CallTrampoline(code, conf.callbacks);
|
prelude_info.wrapped_write_memory_128 = EmitWrappedWrite128CallTrampoline(code, conf.callbacks);
|
||||||
prelude_info.exclusive_write_memory_8 = EmitExclusiveWriteCallTrampoline<&A64::UserCallbacks::MemoryWriteExclusive8, u8>(code, conf);
|
prelude_info.exclusive_write_memory_8 = EmitExclusiveWriteCallTrampoline<&A64::UserCallbacks::MemoryWriteExclusive8, u8>(code, conf);
|
||||||
prelude_info.exclusive_write_memory_16 = EmitExclusiveWriteCallTrampoline<&A64::UserCallbacks::MemoryWriteExclusive16, u16>(code, conf);
|
prelude_info.exclusive_write_memory_16 = EmitExclusiveWriteCallTrampoline<&A64::UserCallbacks::MemoryWriteExclusive16, u16>(code, conf);
|
||||||
|
|||||||
@@ -147,44 +147,37 @@ void AddressSpace::Link(EmittedBlockInfo& block_info) {
|
|||||||
break;
|
break;
|
||||||
// { this, vaddr, size }
|
// { this, vaddr, size }
|
||||||
case LinkTarget::ReadMemory8:
|
case LinkTarget::ReadMemory8:
|
||||||
c.LDR(X2, 1);
|
c.BL(prelude_info.read_memory_8);
|
||||||
c.BL(prelude_info.read_memory);
|
|
||||||
break;
|
break;
|
||||||
case LinkTarget::ReadMemory16:
|
case LinkTarget::ReadMemory16:
|
||||||
c.LDR(X2, 2);
|
c.BL(prelude_info.read_memory_16);
|
||||||
c.BL(prelude_info.read_memory);
|
|
||||||
break;
|
break;
|
||||||
case LinkTarget::ReadMemory32:
|
case LinkTarget::ReadMemory32:
|
||||||
c.LDR(X2, 4);
|
c.BL(prelude_info.read_memory_32);
|
||||||
c.BL(prelude_info.read_memory);
|
|
||||||
break;
|
break;
|
||||||
case LinkTarget::ReadMemory64:
|
case LinkTarget::ReadMemory64:
|
||||||
c.LDR(X2, 8);
|
c.BL(prelude_info.read_memory_64);
|
||||||
c.BL(prelude_info.read_memory);
|
|
||||||
break;
|
break;
|
||||||
case LinkTarget::ReadMemory128:
|
case LinkTarget::ReadMemory128:
|
||||||
c.BL(prelude_info.read_memory_128);
|
c.BL(prelude_info.read_memory_128);
|
||||||
break;
|
break;
|
||||||
// { this, vaddr, size }
|
// { this, vaddr, size }
|
||||||
case LinkTarget::WrappedReadMemory8:
|
case LinkTarget::WrappedReadMemory8:
|
||||||
c.LDR(X2, 1);
|
c.BL(prelude_info.wrapped_read_memory_8);
|
||||||
c.BL(prelude_info.wrapped_read_memory);
|
|
||||||
break;
|
break;
|
||||||
case LinkTarget::WrappedReadMemory16:
|
case LinkTarget::WrappedReadMemory16:
|
||||||
c.LDR(X2, 2);
|
c.BL(prelude_info.wrapped_read_memory_16);
|
||||||
c.BL(prelude_info.wrapped_read_memory);
|
|
||||||
break;
|
break;
|
||||||
case LinkTarget::WrappedReadMemory32:
|
case LinkTarget::WrappedReadMemory32:
|
||||||
c.LDR(X2, 4);
|
c.BL(prelude_info.wrapped_read_memory_32);
|
||||||
c.BL(prelude_info.wrapped_read_memory);
|
|
||||||
break;
|
break;
|
||||||
case LinkTarget::WrappedReadMemory64:
|
case LinkTarget::WrappedReadMemory64:
|
||||||
c.LDR(X2, 8);
|
c.BL(prelude_info.wrapped_read_memory_64);
|
||||||
c.BL(prelude_info.wrapped_read_memory);
|
|
||||||
break;
|
break;
|
||||||
case LinkTarget::WrappedReadMemory128:
|
case LinkTarget::WrappedReadMemory128:
|
||||||
c.BL(prelude_info.wrapped_read_memory_128);
|
c.BL(prelude_info.wrapped_read_memory_128);
|
||||||
break;
|
break;
|
||||||
|
//
|
||||||
case LinkTarget::ExclusiveReadMemory8:
|
case LinkTarget::ExclusiveReadMemory8:
|
||||||
c.BL(prelude_info.exclusive_read_memory_8);
|
c.BL(prelude_info.exclusive_read_memory_8);
|
||||||
break;
|
break;
|
||||||
@@ -202,43 +195,37 @@ void AddressSpace::Link(EmittedBlockInfo& block_info) {
|
|||||||
break;
|
break;
|
||||||
// { this, vaddr, value, size }
|
// { this, vaddr, value, size }
|
||||||
case LinkTarget::WriteMemory8:
|
case LinkTarget::WriteMemory8:
|
||||||
c.LDR(X3, 1);
|
c.BL(prelude_info.write_memory_8);
|
||||||
c.BL(prelude_info.write_memory);
|
|
||||||
break;
|
break;
|
||||||
case LinkTarget::WriteMemory16:
|
case LinkTarget::WriteMemory16:
|
||||||
c.LDR(X3, 2);
|
c.BL(prelude_info.write_memory_16);
|
||||||
c.BL(prelude_info.write_memory);
|
|
||||||
break;
|
break;
|
||||||
case LinkTarget::WriteMemory32:
|
case LinkTarget::WriteMemory32:
|
||||||
c.LDR(X3, 4);
|
c.BL(prelude_info.write_memory_32);
|
||||||
c.BL(prelude_info.write_memory);
|
|
||||||
break;
|
break;
|
||||||
case LinkTarget::WriteMemory64:
|
case LinkTarget::WriteMemory64:
|
||||||
c.LDR(X3, 8);
|
c.BL(prelude_info.write_memory_64);
|
||||||
c.BL(prelude_info.write_memory);
|
|
||||||
break;
|
break;
|
||||||
case LinkTarget::WriteMemory128:
|
case LinkTarget::WriteMemory128:
|
||||||
c.BL(prelude_info.write_memory_128);
|
c.BL(prelude_info.write_memory_128);
|
||||||
break;
|
break;
|
||||||
|
//
|
||||||
case LinkTarget::WrappedWriteMemory8:
|
case LinkTarget::WrappedWriteMemory8:
|
||||||
c.LDR(X3, 1);
|
c.BL(prelude_info.wrapped_write_memory_8);
|
||||||
c.BL(prelude_info.wrapped_write_memory);
|
|
||||||
break;
|
break;
|
||||||
case LinkTarget::WrappedWriteMemory16:
|
case LinkTarget::WrappedWriteMemory16:
|
||||||
c.LDR(X3, 2);
|
c.BL(prelude_info.wrapped_write_memory_16);
|
||||||
c.BL(prelude_info.wrapped_write_memory);
|
|
||||||
break;
|
break;
|
||||||
case LinkTarget::WrappedWriteMemory32:
|
case LinkTarget::WrappedWriteMemory32:
|
||||||
c.LDR(X3, 4);
|
c.BL(prelude_info.wrapped_write_memory_32);
|
||||||
c.BL(prelude_info.wrapped_write_memory);
|
|
||||||
break;
|
break;
|
||||||
case LinkTarget::WrappedWriteMemory64:
|
case LinkTarget::WrappedWriteMemory64:
|
||||||
c.LDR(X3, 8);
|
c.BL(prelude_info.wrapped_write_memory_64);
|
||||||
c.BL(prelude_info.wrapped_write_memory);
|
|
||||||
break;
|
break;
|
||||||
case LinkTarget::WrappedWriteMemory128:
|
case LinkTarget::WrappedWriteMemory128:
|
||||||
c.BL(prelude_info.wrapped_write_memory_128);
|
c.BL(prelude_info.wrapped_write_memory_128);
|
||||||
break;
|
break;
|
||||||
|
//
|
||||||
case LinkTarget::ExclusiveWriteMemory8:
|
case LinkTarget::ExclusiveWriteMemory8:
|
||||||
c.BL(prelude_info.exclusive_write_memory_8);
|
c.BL(prelude_info.exclusive_write_memory_8);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -93,18 +93,30 @@ protected:
|
|||||||
void* return_to_dispatcher;
|
void* return_to_dispatcher;
|
||||||
void* return_from_run_code;
|
void* return_from_run_code;
|
||||||
|
|
||||||
void* read_memory;
|
void* read_memory_8;
|
||||||
|
void* read_memory_16;
|
||||||
|
void* read_memory_32;
|
||||||
|
void* read_memory_64;
|
||||||
void* read_memory_128;
|
void* read_memory_128;
|
||||||
void* wrapped_read_memory;
|
void* wrapped_read_memory_8;
|
||||||
|
void* wrapped_read_memory_16;
|
||||||
|
void* wrapped_read_memory_32;
|
||||||
|
void* wrapped_read_memory_64;
|
||||||
void* wrapped_read_memory_128;
|
void* wrapped_read_memory_128;
|
||||||
void* exclusive_read_memory_8;
|
void* exclusive_read_memory_8;
|
||||||
void* exclusive_read_memory_16;
|
void* exclusive_read_memory_16;
|
||||||
void* exclusive_read_memory_32;
|
void* exclusive_read_memory_32;
|
||||||
void* exclusive_read_memory_64;
|
void* exclusive_read_memory_64;
|
||||||
void* exclusive_read_memory_128;
|
void* exclusive_read_memory_128;
|
||||||
void* write_memory;
|
void* write_memory_8;
|
||||||
|
void* write_memory_16;
|
||||||
|
void* write_memory_32;
|
||||||
|
void* write_memory_64;
|
||||||
void* write_memory_128;
|
void* write_memory_128;
|
||||||
void* wrapped_write_memory;
|
void* wrapped_write_memory_8;
|
||||||
|
void* wrapped_write_memory_16;
|
||||||
|
void* wrapped_write_memory_32;
|
||||||
|
void* wrapped_write_memory_64;
|
||||||
void* wrapped_write_memory_128;
|
void* wrapped_write_memory_128;
|
||||||
void* exclusive_write_memory_8;
|
void* exclusive_write_memory_8;
|
||||||
void* exclusive_write_memory_16;
|
void* exclusive_write_memory_16;
|
||||||
|
|||||||
Reference in New Issue
Block a user