d8deb39b83
Moves the memory writes directly into QueryProcessMemory instead of letting the wrapper function do it. It would be inaccurate to allow the handler to do it because there's cases where memory shouldn't even be written to. For example, if the given process handle is invalid. HOWEVER, if the memory writing is within the wrapper, then we have no control over if these memory writes occur, meaning in an error case, 68 bytes of memory randomly get trashed with zeroes, 64 of those being written to wherever the memory info address points to, and the remaining 4 being written wherever the page info address points to. One solution in this case would be to just conditionally check within the handler itself, but this is kind of smelly, given the handler shouldn't be performing conditional behavior itself, it's a behavior of the managed function. In other words, if you remove the handler from the equation entirely, does the function still retain its proper behavior? In this case, no. Now, we don't potentially trash memory from this function if an invalid query is performed.
267 lines
7 KiB
C++
267 lines
7 KiB
C++
// Copyright 2018 yuzu emulator team
|
|
// Licensed under GPLv2 or any later version
|
|
// Refer to the license.txt file included.
|
|
|
|
#pragma once
|
|
|
|
#include "common/common_types.h"
|
|
#include "core/arm/arm_interface.h"
|
|
#include "core/core.h"
|
|
#include "core/hle/result.h"
|
|
|
|
namespace Kernel {
|
|
|
|
static inline u64 Param(int n) {
|
|
return Core::CurrentArmInterface().GetReg(n);
|
|
}
|
|
|
|
/**
|
|
* HLE a function return from the current ARM userland process
|
|
* @param res Result to return
|
|
*/
|
|
static inline void FuncReturn(u64 res) {
|
|
Core::CurrentArmInterface().SetReg(0, res);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Function wrappers that return type ResultCode
|
|
|
|
template <ResultCode func(u64)>
|
|
void SvcWrap() {
|
|
FuncReturn(func(Param(0)).raw);
|
|
}
|
|
|
|
template <ResultCode func(u32)>
|
|
void SvcWrap() {
|
|
FuncReturn(func(static_cast<u32>(Param(0))).raw);
|
|
}
|
|
|
|
template <ResultCode func(u32, u32)>
|
|
void SvcWrap() {
|
|
FuncReturn(func(static_cast<u32>(Param(0)), static_cast<u32>(Param(1))).raw);
|
|
}
|
|
|
|
template <ResultCode func(u32*)>
|
|
void SvcWrap() {
|
|
u32 param = 0;
|
|
const u32 retval = func(¶m).raw;
|
|
Core::CurrentArmInterface().SetReg(1, param);
|
|
FuncReturn(retval);
|
|
}
|
|
|
|
template <ResultCode func(u32*, u32)>
|
|
void SvcWrap() {
|
|
u32 param_1 = 0;
|
|
u32 retval = func(¶m_1, static_cast<u32>(Param(1))).raw;
|
|
Core::CurrentArmInterface().SetReg(1, param_1);
|
|
FuncReturn(retval);
|
|
}
|
|
|
|
template <ResultCode func(u32*, u32*)>
|
|
void SvcWrap() {
|
|
u32 param_1 = 0;
|
|
u32 param_2 = 0;
|
|
const u32 retval = func(¶m_1, ¶m_2).raw;
|
|
|
|
auto& arm_interface = Core::CurrentArmInterface();
|
|
arm_interface.SetReg(1, param_1);
|
|
arm_interface.SetReg(2, param_2);
|
|
|
|
FuncReturn(retval);
|
|
}
|
|
|
|
template <ResultCode func(u32*, u64)>
|
|
void SvcWrap() {
|
|
u32 param_1 = 0;
|
|
u32 retval = func(¶m_1, Param(1)).raw;
|
|
Core::CurrentArmInterface().SetReg(1, param_1);
|
|
FuncReturn(retval);
|
|
}
|
|
|
|
template <ResultCode func(u64, s32)>
|
|
void SvcWrap() {
|
|
FuncReturn(func(Param(0), static_cast<s32>(Param(1))).raw);
|
|
}
|
|
|
|
template <ResultCode func(u64, u32)>
|
|
void SvcWrap() {
|
|
FuncReturn(func(Param(0), static_cast<u32>(Param(1))).raw);
|
|
}
|
|
|
|
template <ResultCode func(u64*, u64)>
|
|
void SvcWrap() {
|
|
u64 param_1 = 0;
|
|
u32 retval = func(¶m_1, Param(1)).raw;
|
|
Core::CurrentArmInterface().SetReg(1, param_1);
|
|
FuncReturn(retval);
|
|
}
|
|
|
|
template <ResultCode func(u64*, u32, u32)>
|
|
void SvcWrap() {
|
|
u64 param_1 = 0;
|
|
u32 retval = func(¶m_1, static_cast<u32>(Param(1)), static_cast<u32>(Param(2))).raw;
|
|
Core::CurrentArmInterface().SetReg(1, param_1);
|
|
FuncReturn(retval);
|
|
}
|
|
|
|
template <ResultCode func(u32, u64)>
|
|
void SvcWrap() {
|
|
FuncReturn(func(static_cast<u32>(Param(0)), Param(1)).raw);
|
|
}
|
|
|
|
template <ResultCode func(u32, u32, u64)>
|
|
void SvcWrap() {
|
|
FuncReturn(func(static_cast<u32>(Param(0)), static_cast<u32>(Param(1)), Param(2)).raw);
|
|
}
|
|
|
|
template <ResultCode func(u32, u32*, u64*)>
|
|
void SvcWrap() {
|
|
u32 param_1 = 0;
|
|
u64 param_2 = 0;
|
|
ResultCode retval = func(static_cast<u32>(Param(2)), ¶m_1, ¶m_2);
|
|
Core::CurrentArmInterface().SetReg(1, param_1);
|
|
Core::CurrentArmInterface().SetReg(2, param_2);
|
|
FuncReturn(retval.raw);
|
|
}
|
|
|
|
template <ResultCode func(u64, u64, u32, u32)>
|
|
void SvcWrap() {
|
|
FuncReturn(
|
|
func(Param(0), Param(1), static_cast<u32>(Param(3)), static_cast<u32>(Param(3))).raw);
|
|
}
|
|
|
|
template <ResultCode func(u32, u64, u32)>
|
|
void SvcWrap() {
|
|
FuncReturn(func(static_cast<u32>(Param(0)), Param(1), static_cast<u32>(Param(2))).raw);
|
|
}
|
|
|
|
template <ResultCode func(u64, u64, u64)>
|
|
void SvcWrap() {
|
|
FuncReturn(func(Param(0), Param(1), Param(2)).raw);
|
|
}
|
|
|
|
template <ResultCode func(u64, u64, u32)>
|
|
void SvcWrap() {
|
|
FuncReturn(func(Param(0), Param(1), static_cast<u32>(Param(2))).raw);
|
|
}
|
|
|
|
template <ResultCode func(u32, u64, u64, u32)>
|
|
void SvcWrap() {
|
|
FuncReturn(
|
|
func(static_cast<u32>(Param(0)), Param(1), Param(2), static_cast<u32>(Param(3))).raw);
|
|
}
|
|
|
|
template <ResultCode func(u32, u64, u64)>
|
|
void SvcWrap() {
|
|
FuncReturn(func(static_cast<u32>(Param(0)), Param(1), Param(2)).raw);
|
|
}
|
|
|
|
template <ResultCode func(u32*, u64, u64, s64)>
|
|
void SvcWrap() {
|
|
u32 param_1 = 0;
|
|
ResultCode retval =
|
|
func(¶m_1, Param(1), static_cast<u32>(Param(2)), static_cast<s64>(Param(3)));
|
|
Core::CurrentArmInterface().SetReg(1, param_1);
|
|
FuncReturn(retval.raw);
|
|
}
|
|
|
|
template <ResultCode func(u64, u64, u32, s64)>
|
|
void SvcWrap() {
|
|
FuncReturn(
|
|
func(Param(0), Param(1), static_cast<u32>(Param(2)), static_cast<s64>(Param(3))).raw);
|
|
}
|
|
|
|
template <ResultCode func(u64*, u64, u64, u64)>
|
|
void SvcWrap() {
|
|
u64 param_1 = 0;
|
|
u32 retval = func(¶m_1, Param(1), Param(2), Param(3)).raw;
|
|
Core::CurrentArmInterface().SetReg(1, param_1);
|
|
FuncReturn(retval);
|
|
}
|
|
|
|
template <ResultCode func(u32*, u64, u64, u64, u32, s32)>
|
|
void SvcWrap() {
|
|
u32 param_1 = 0;
|
|
u32 retval = func(¶m_1, Param(1), Param(2), Param(3), static_cast<u32>(Param(4)),
|
|
static_cast<s32>(Param(5)))
|
|
.raw;
|
|
Core::CurrentArmInterface().SetReg(1, param_1);
|
|
FuncReturn(retval);
|
|
}
|
|
|
|
template <ResultCode func(u32*, u64, u64, u32)>
|
|
void SvcWrap() {
|
|
u32 param_1 = 0;
|
|
u32 retval = func(¶m_1, Param(1), Param(2), static_cast<u32>(Param(3))).raw;
|
|
Core::CurrentArmInterface().SetReg(1, param_1);
|
|
FuncReturn(retval);
|
|
}
|
|
|
|
template <ResultCode func(Handle*, u64, u32, u32)>
|
|
void SvcWrap() {
|
|
u32 param_1 = 0;
|
|
u32 retval =
|
|
func(¶m_1, Param(1), static_cast<u32>(Param(2)), static_cast<u32>(Param(3))).raw;
|
|
Core::CurrentArmInterface().SetReg(1, param_1);
|
|
FuncReturn(retval);
|
|
}
|
|
|
|
template <ResultCode func(u64, u32, s32, s64)>
|
|
void SvcWrap() {
|
|
FuncReturn(func(Param(0), static_cast<u32>(Param(1)), static_cast<s32>(Param(2)),
|
|
static_cast<s64>(Param(3)))
|
|
.raw);
|
|
}
|
|
|
|
template <ResultCode func(u64, u32, s32, s32)>
|
|
void SvcWrap() {
|
|
FuncReturn(func(Param(0), static_cast<u32>(Param(1)), static_cast<s32>(Param(2)),
|
|
static_cast<s32>(Param(3)))
|
|
.raw);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Function wrappers that return type u32
|
|
|
|
template <u32 func()>
|
|
void SvcWrap() {
|
|
FuncReturn(func());
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Function wrappers that return type u64
|
|
|
|
template <u64 func()>
|
|
void SvcWrap() {
|
|
FuncReturn(func());
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
/// Function wrappers that return type void
|
|
|
|
template <void func()>
|
|
void SvcWrap() {
|
|
func();
|
|
}
|
|
|
|
template <void func(s64)>
|
|
void SvcWrap() {
|
|
func(static_cast<s64>(Param(0)));
|
|
}
|
|
|
|
template <void func(u64, u64 len)>
|
|
void SvcWrap() {
|
|
func(Param(0), Param(1));
|
|
}
|
|
|
|
template <void func(u64, u64, u64)>
|
|
void SvcWrap() {
|
|
func(Param(0), Param(1), Param(2));
|
|
}
|
|
|
|
template <void func(u32, u64, u64)>
|
|
void SvcWrap() {
|
|
func(static_cast<u32>(Param(0)), Param(1), Param(2));
|
|
}
|
|
|
|
} // namespace Kernel
|