HLE_OS: Avoid ppcState global.

This commit is contained in:
Admiral H. Curtiss 2023-01-10 06:19:05 +01:00
parent 7fd552081f
commit b52e8fd295
No known key found for this signature in database
GPG Key ID: F051B4C4044F33FB
3 changed files with 70 additions and 42 deletions

View File

@ -13,6 +13,7 @@
#include "Core/HLE/HLE_VarArgs.h"
#include "Core/PowerPC/MMU.h"
#include "Core/PowerPC/PowerPC.h"
#include "Core/System.h"
namespace HLE_OS
{
@ -22,7 +23,7 @@ enum class ParameterType : bool
VariableArgumentList = true
};
std::string GetStringVA(u32 str_reg = 3,
std::string GetStringVA(Core::System& system, u32 str_reg = 3,
ParameterType parameter_type = ParameterType::ParameterList);
void HLE_GeneralDebugPrint(ParameterType parameter_type);
void HLE_LogDPrint(ParameterType parameter_type);
@ -30,57 +31,63 @@ void HLE_LogFPrint(ParameterType parameter_type);
void HLE_OSPanic()
{
std::string error = GetStringVA();
std::string msg = GetStringVA(5);
auto& system = Core::System::GetInstance();
auto& ppc_state = system.GetPPCState();
std::string error = GetStringVA(system);
std::string msg = GetStringVA(system, 5);
StringPopBackIf(&error, '\n');
StringPopBackIf(&msg, '\n');
PanicAlertFmt("OSPanic: {}: {}", error, msg);
ERROR_LOG_FMT(OSREPORT_HLE, "{:08x}->{:08x}| OSPanic: {}: {}", LR(PowerPC::ppcState),
PowerPC::ppcState.pc, error, msg);
ERROR_LOG_FMT(OSREPORT_HLE, "{:08x}->{:08x}| OSPanic: {}: {}", LR(ppc_state), ppc_state.pc, error,
msg);
PowerPC::ppcState.npc = LR(PowerPC::ppcState);
ppc_state.npc = LR(ppc_state);
}
// Generalized function for printing formatted string.
void HLE_GeneralDebugPrint(ParameterType parameter_type)
{
auto& system = Core::System::GetInstance();
auto& ppc_state = system.GetPPCState();
std::string report_message;
// Is gpr3 pointing to a pointer (including nullptr) rather than an ASCII string
if (PowerPC::HostIsRAMAddress(PowerPC::ppcState.gpr[3]) &&
(PowerPC::HostIsRAMAddress(PowerPC::HostRead_U32(PowerPC::ppcState.gpr[3])) ||
PowerPC::HostRead_U32(PowerPC::ppcState.gpr[3]) == 0))
if (PowerPC::HostIsRAMAddress(ppc_state.gpr[3]) &&
(PowerPC::HostIsRAMAddress(PowerPC::HostRead_U32(ppc_state.gpr[3])) ||
PowerPC::HostRead_U32(ppc_state.gpr[3]) == 0))
{
if (PowerPC::HostIsRAMAddress(PowerPC::ppcState.gpr[4]))
if (PowerPC::HostIsRAMAddress(ppc_state.gpr[4]))
{
// ___blank(void* this, const char* fmt, ...);
report_message = GetStringVA(4, parameter_type);
report_message = GetStringVA(system, 4, parameter_type);
}
else
{
// ___blank(void* this, int log_type, const char* fmt, ...);
report_message = GetStringVA(5, parameter_type);
report_message = GetStringVA(system, 5, parameter_type);
}
}
else
{
if (PowerPC::HostIsRAMAddress(PowerPC::ppcState.gpr[3]))
if (PowerPC::HostIsRAMAddress(ppc_state.gpr[3]))
{
// ___blank(const char* fmt, ...);
report_message = GetStringVA(3, parameter_type);
report_message = GetStringVA(system, 3, parameter_type);
}
else
{
// ___blank(int log_type, const char* fmt, ...);
report_message = GetStringVA(4, parameter_type);
report_message = GetStringVA(system, 4, parameter_type);
}
}
StringPopBackIf(&report_message, '\n');
NOTICE_LOG_FMT(OSREPORT_HLE, "{:08x}->{:08x}| {}", LR(PowerPC::ppcState), PowerPC::ppcState.pc,
NOTICE_LOG_FMT(OSREPORT_HLE, "{:08x}->{:08x}| {}", LR(ppc_state), ppc_state.pc,
SHIFTJISToUTF8(report_message));
}
@ -99,10 +106,13 @@ void HLE_GeneralDebugVPrint()
// __write_console(int fd, const void* buffer, const u32* size)
void HLE_write_console()
{
std::string report_message = GetStringVA(4);
if (PowerPC::HostIsRAMAddress(PowerPC::ppcState.gpr[5]))
auto& system = Core::System::GetInstance();
auto& ppc_state = system.GetPPCState();
std::string report_message = GetStringVA(system, 4);
if (PowerPC::HostIsRAMAddress(ppc_state.gpr[5]))
{
const u32 size = PowerPC::Read_U32(PowerPC::ppcState.gpr[5]);
const u32 size = PowerPC::Read_U32(ppc_state.gpr[5]);
if (size > report_message.size())
WARN_LOG_FMT(OSREPORT_HLE, "__write_console uses an invalid size of {:#010x}", size);
else if (size == 0)
@ -117,19 +127,22 @@ void HLE_write_console()
StringPopBackIf(&report_message, '\n');
NOTICE_LOG_FMT(OSREPORT_HLE, "{:08x}->{:08x}| {}", LR(PowerPC::ppcState), PowerPC::ppcState.pc,
NOTICE_LOG_FMT(OSREPORT_HLE, "{:08x}->{:08x}| {}", LR(ppc_state), ppc_state.pc,
SHIFTJISToUTF8(report_message));
}
// Log (v)dprintf message if fd is 1 (stdout) or 2 (stderr)
void HLE_LogDPrint(ParameterType parameter_type)
{
if (PowerPC::ppcState.gpr[3] != 1 && PowerPC::ppcState.gpr[3] != 2)
auto& system = Core::System::GetInstance();
auto& ppc_state = system.GetPPCState();
if (ppc_state.gpr[3] != 1 && ppc_state.gpr[3] != 2)
return;
std::string report_message = GetStringVA(4, parameter_type);
std::string report_message = GetStringVA(system, 4, parameter_type);
StringPopBackIf(&report_message, '\n');
NOTICE_LOG_FMT(OSREPORT_HLE, "{:08x}->{:08x}| {}", LR(PowerPC::ppcState), PowerPC::ppcState.pc,
NOTICE_LOG_FMT(OSREPORT_HLE, "{:08x}->{:08x}| {}", LR(ppc_state), ppc_state.pc,
SHIFTJISToUTF8(report_message));
}
@ -150,26 +163,29 @@ void HLE_LogVDPrint()
// Log (v)fprintf message if FILE is stdout or stderr
void HLE_LogFPrint(ParameterType parameter_type)
{
auto& system = Core::System::GetInstance();
auto& ppc_state = system.GetPPCState();
// The structure FILE is implementation defined.
// Both libogc and Dolphin SDK seem to store the fd at the same address.
int fd = -1;
if (PowerPC::HostIsRAMAddress(PowerPC::ppcState.gpr[3]) &&
PowerPC::HostIsRAMAddress(PowerPC::ppcState.gpr[3] + 0xF))
if (PowerPC::HostIsRAMAddress(ppc_state.gpr[3]) &&
PowerPC::HostIsRAMAddress(ppc_state.gpr[3] + 0xF))
{
// The fd is stored as a short at FILE+0xE.
fd = static_cast<short>(PowerPC::HostRead_U16(PowerPC::ppcState.gpr[3] + 0xE));
fd = static_cast<short>(PowerPC::HostRead_U16(ppc_state.gpr[3] + 0xE));
}
if (fd != 1 && fd != 2)
{
// On RVL SDK it seems stored at FILE+0x2.
fd = static_cast<short>(PowerPC::HostRead_U16(PowerPC::ppcState.gpr[3] + 0x2));
fd = static_cast<short>(PowerPC::HostRead_U16(ppc_state.gpr[3] + 0x2));
}
if (fd != 1 && fd != 2)
return;
std::string report_message = GetStringVA(4, parameter_type);
std::string report_message = GetStringVA(system, 4, parameter_type);
StringPopBackIf(&report_message, '\n');
NOTICE_LOG_FMT(OSREPORT_HLE, "{:08x}->{:08x}| {}", LR(PowerPC::ppcState), PowerPC::ppcState.pc,
NOTICE_LOG_FMT(OSREPORT_HLE, "{:08x}->{:08x}| {}", LR(ppc_state), ppc_state.pc,
SHIFTJISToUTF8(report_message));
}
@ -187,15 +203,17 @@ void HLE_LogVFPrint()
HLE_LogFPrint(ParameterType::VariableArgumentList);
}
std::string GetStringVA(u32 str_reg, ParameterType parameter_type)
std::string GetStringVA(Core::System& system, u32 str_reg, ParameterType parameter_type)
{
auto& ppc_state = system.GetPPCState();
std::string ArgumentBuffer;
std::string result;
std::string string = PowerPC::HostGetString(PowerPC::ppcState.gpr[str_reg]);
std::string string = PowerPC::HostGetString(ppc_state.gpr[str_reg]);
auto ap =
parameter_type == ParameterType::VariableArgumentList ?
std::make_unique<HLE::SystemVABI::VAListStruct>(PowerPC::ppcState.gpr[str_reg + 1]) :
std::make_unique<HLE::SystemVABI::VAList>(PowerPC::ppcState.gpr[1] + 0x8, str_reg + 1);
std::make_unique<HLE::SystemVABI::VAListStruct>(system, ppc_state.gpr[str_reg + 1]) :
std::make_unique<HLE::SystemVABI::VAList>(system, ppc_state.gpr[1] + 0x8, str_reg + 1);
for (size_t i = 0; i < string.size(); i++)
{

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include "Core/HLE/HLE_VarArgs.h"
#include "Core/System.h"
#include "Common/Logging/Log.h"
@ -9,18 +10,19 @@ HLE::SystemVABI::VAList::~VAList() = default;
u32 HLE::SystemVABI::VAList::GetGPR(u32 gpr) const
{
return PowerPC::ppcState.gpr[gpr];
return m_system.GetPPCState().gpr[gpr];
}
double HLE::SystemVABI::VAList::GetFPR(u32 fpr) const
{
return PowerPC::ppcState.ps[fpr].PS0AsDouble();
return m_system.GetPPCState().ps[fpr].PS0AsDouble();
}
HLE::SystemVABI::VAListStruct::VAListStruct(u32 address)
: VAList(0), m_va_list{PowerPC::HostRead_U8(address), PowerPC::HostRead_U8(address + 1),
PowerPC::HostRead_U32(address + 4), PowerPC::HostRead_U32(address + 8)},
m_address(address), m_has_fpr_area(PowerPC::ppcState.cr.GetBit(6) == 1)
HLE::SystemVABI::VAListStruct::VAListStruct(Core::System& system, u32 address)
: VAList(system, 0), m_va_list{PowerPC::HostRead_U8(address), PowerPC::HostRead_U8(address + 1),
PowerPC::HostRead_U32(address + 4),
PowerPC::HostRead_U32(address + 8)},
m_address(address), m_has_fpr_area(system.GetPPCState().cr.GetBit(6) == 1)
{
m_stack = m_va_list.overflow_arg_area;
m_gpr += m_va_list.gpr;

View File

@ -11,6 +11,11 @@
#include <type_traits>
namespace Core
{
class System;
}
namespace HLE::SystemVABI
{
// SFINAE
@ -32,8 +37,10 @@ constexpr bool IS_ARG_REAL = std::is_floating_point<T>();
class VAList
{
public:
explicit VAList(u32 stack, u32 gpr = 3, u32 fpr = 1, u32 gpr_max = 10, u32 fpr_max = 8)
: m_gpr(gpr), m_fpr(fpr), m_gpr_max(gpr_max), m_fpr_max(fpr_max), m_stack(stack)
explicit VAList(Core::System& system, u32 stack, u32 gpr = 3, u32 fpr = 1, u32 gpr_max = 10,
u32 fpr_max = 8)
: m_system(system), m_gpr(gpr), m_fpr(fpr), m_gpr_max(gpr_max), m_fpr_max(fpr_max),
m_stack(stack)
{
}
virtual ~VAList();
@ -127,6 +134,7 @@ public:
}
protected:
Core::System& m_system;
u32 m_gpr = 3;
u32 m_fpr = 1;
const u32 m_gpr_max = 10;
@ -147,7 +155,7 @@ private:
class VAListStruct : public VAList
{
public:
explicit VAListStruct(u32 address);
explicit VAListStruct(Core::System& system, u32 address);
~VAListStruct() = default;
private: