Support 64-bit args/return in new HLE logging.

Pulls in a new header, unfortunately, but this is a mostly clean way to do
it.
This commit is contained in:
Unknown W. Brackets 2016-01-24 22:22:23 -08:00
parent 0550cd306d
commit 3a64388eee
2 changed files with 47 additions and 30 deletions

View File

@ -596,6 +596,14 @@ size_t hleFormatLogArgs(char *message, size_t sz, const char *argmask) {
}
break;
case 'P':
if (Memory::IsValidAddress(regval)) {
APPEND_FMT("%08x[%016llx]", regval, Memory::Read_U64(regval));
} else {
APPEND_FMT("%08x[invalid]", regval);
}
break;
case 's':
if (Memory::IsValidAddress(regval)) {
APPEND_FMT("%s", Memory::GetCharPointer(regval));
@ -649,22 +657,7 @@ size_t hleFormatLogArgs(char *message, size_t sz, const char *argmask) {
return used;
}
u32 hleDoLog(LogTypes::LOG_TYPE t, LogTypes::LOG_LEVELS level, u32 res, const char *file, int line, const char *reportTag, char retmask, const char *reason, ...) {
if (level > MAX_LOGLEVEL || !GenericLogEnabled(level, t)) {
return res;
}
char formatted_reason[4096] = {0};
if (reason != nullptr) {
va_list args;
va_start(args, reason);
formatted_reason[0] = ':';
formatted_reason[1] = ' ';
vsnprintf(formatted_reason + 2, sizeof(formatted_reason) - 3, reason, args);
formatted_reason[sizeof(formatted_reason) - 1] = '\0';
va_end(args);
}
void hleDoLogInternal(LogTypes::LOG_TYPE t, LogTypes::LOG_LEVELS level, u64 res, const char *file, int line, const char *reportTag, char retmask, const char *reason, const char *formatted_reason) {
char formatted_args[4096];
hleFormatLogArgs(formatted_args, sizeof(formatted_args), latestSyscall->argmask);
@ -675,12 +668,12 @@ u32 hleDoLog(LogTypes::LOG_TYPE t, LogTypes::LOG_LEVELS level, u32 res, const ch
const char *fmt;
// TODO: Floats and other types... move to another func (for return type?) Hmm.
if (retmask == 'x') {
fmt = "%08x=%s(%s)%s";
} else if (retmask == 'i') {
fmt = "%d=%s(%s)%s";
fmt = "%08llx=%s(%s)%s";
} else if (retmask == 'i' || retmask == 'I') {
fmt = "%lld=%s(%s)%s";
} else {
_assert_msg_(HLE, false, "Invalid return format: %c", retmask);
fmt = "%08x=%s(%s)%s";
fmt = "%08llx=%s(%s)%s";
}
GenericLog(level, t, file, line, fmt, res, latestSyscall->name, formatted_args, formatted_reason);
@ -698,10 +691,4 @@ u32 hleDoLog(LogTypes::LOG_TYPE t, LogTypes::LOG_LEVELS level, u32 res, const ch
Reporting::ReportMessageFormatted(key.c_str(), formatted_message);
}
}
return res;
}
u32 hleDoLog(LogTypes::LOG_TYPE t, LogTypes::LOG_LEVELS level, u32 res, const char *file, int line, const char *reportTag, char retmask) {
return hleDoLog(t, level, res, file, line, reportTag, retmask, nullptr);
}

View File

@ -17,6 +17,7 @@
#pragma once
#include <cstdarg>
#include "Common/CommonTypes.h"
#include "Common/Log.h"
#include "Core/MIPS/MIPS.h"
@ -146,8 +147,38 @@ const HLEFunction *GetSyscallInfo(MIPSOpcode op);
// For jit, takes arg: const HLEFunction *
void *GetQuickSyscallFunc(MIPSOpcode op);
u32 hleDoLog(LogTypes::LOG_TYPE t, LogTypes::LOG_LEVELS level, u32 res, const char *file, int line, const char *reportTag, char retmask, const char *reason, ...);
u32 hleDoLog(LogTypes::LOG_TYPE t, LogTypes::LOG_LEVELS level, u32 res, const char *file, int line, const char *reportTag, char retmask);
void hleDoLogInternal(LogTypes::LOG_TYPE t, LogTypes::LOG_LEVELS level, u64 res, const char *file, int line, const char *reportTag, char retmask, const char *reason, const char *formatted_reason);
template <typename T>
T hleDoLog(LogTypes::LOG_TYPE t, LogTypes::LOG_LEVELS level, T res, const char *file, int line, const char *reportTag, char retmask, const char *reason, ...) {
if (level > MAX_LOGLEVEL || !GenericLogEnabled(level, t)) {
return res;
}
char formatted_reason[4096] = {0};
if (reason != nullptr) {
va_list args;
va_start(args, reason);
formatted_reason[0] = ':';
formatted_reason[1] = ' ';
vsnprintf(formatted_reason + 2, sizeof(formatted_reason) - 3, reason, args);
formatted_reason[sizeof(formatted_reason) - 1] = '\0';
va_end(args);
}
hleDoLogInternal(t, level, res, file, line, reportTag, retmask, reason, formatted_reason);
return res;
}
template <typename T>
T hleDoLog(LogTypes::LOG_TYPE t, LogTypes::LOG_LEVELS level, T res, const char *file, int line, const char *reportTag, char retmask) {
if (level > MAX_LOGLEVEL || !GenericLogEnabled(level, t)) {
return res;
}
hleDoLogInternal(t, level, res, file, line, reportTag, retmask, nullptr, "");
return res;
}
// This is just a quick way to force logging to be more visible for one file.
#ifdef HLE_LOG_FORCE
@ -163,8 +194,7 @@ u32 hleDoLog(LogTypes::LOG_TYPE t, LogTypes::LOG_LEVELS level, u32 res, const ch
#define HLE_LOG_LVERBOSE LVERBOSE
#endif
// Only one side of the ?: is evaluated (per c++ standard), so this should be safe.
#define hleLogHelper(t, level, res, retmask, ...) (LogTypes::level > MAX_LOGLEVEL ? res : hleDoLog(LogTypes::t, LogTypes::level, res, __FILE__, __LINE__, nullptr, retmask, ##__VA_ARGS__))
#define hleLogHelper(t, level, res, retmask, ...) hleDoLog(LogTypes::t, LogTypes::level, res, __FILE__, __LINE__, nullptr, retmask, ##__VA_ARGS__)
#define hleLogError(t, res, ...) hleLogHelper(t, LERROR, res, 'x', ##__VA_ARGS__)
#define hleLogWarning(t, res, ...) hleLogHelper(t, LWARNING, res, 'x', ##__VA_ARGS__)
#define hleLogDebug(t, res, ...) hleLogHelper(t, HLE_LOG_LDEBUG, res, 'x', ##__VA_ARGS__)