mirror of
https://github.com/wiiu-env/gdbstub_plugin.git
synced 2024-11-22 03:39:15 +01:00
WIP
This commit is contained in:
parent
60a0679699
commit
cda1a77ec8
@ -1,6 +1,7 @@
|
|||||||
FROM wiiuenv/devkitppc:20211229
|
FROM wiiuenv/devkitppc:20220724
|
||||||
|
|
||||||
COPY --from=wiiuenv/wiiupluginsystem:20220123 /artifacts $DEVKITPRO
|
COPY --from=wiiuenv/wiiupluginsystem:20220724 /artifacts $DEVKITPRO
|
||||||
COPY --from=wiiuenv/libiosuhax:20220129 /artifacts $DEVKITPRO
|
COPY --from=wiiuenv/libkernel:20220724 /artifacts $DEVKITPRO
|
||||||
|
COPY --from=wiiuenv/libmappedmemory:20220724 /artifacts $DEVKITPRO
|
||||||
|
|
||||||
WORKDIR project
|
WORKDIR project
|
6
Makefile
6
Makefile
@ -39,10 +39,10 @@ CXXFLAGS := $(CFLAGS)
|
|||||||
ASFLAGS := -g $(ARCH)
|
ASFLAGS := -g $(ARCH)
|
||||||
LDFLAGS = -g $(ARCH) $(RPXSPECS) -Wl,-Map,$(notdir $*.map) -T$(WUMS_ROOT)/share/libmappedmemory.ld -T$(WUMS_ROOT)/share/libkernel.ld $(WUPSSPECS)
|
LDFLAGS = -g $(ARCH) $(RPXSPECS) -Wl,-Map,$(notdir $*.map) -T$(WUMS_ROOT)/share/libmappedmemory.ld -T$(WUMS_ROOT)/share/libkernel.ld $(WUPSSPECS)
|
||||||
|
|
||||||
ifeq ($(DEBUG),1)
|
|
||||||
CXXFLAGS += -DDEBUG -g
|
CXXFLAGS += -DDEBUG -g
|
||||||
CFLAGS += -DDEBUG -g
|
CFLAGS += -DDEBUG -g
|
||||||
endif
|
|
||||||
|
|
||||||
LIBS := -lwups -lwut -lkernel -lmappedmemory
|
LIBS := -lwups -lwut -lkernel -lmappedmemory
|
||||||
|
|
||||||
@ -103,7 +103,7 @@ export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
|||||||
all: $(BUILD)
|
all: $(BUILD)
|
||||||
|
|
||||||
$(BUILD):
|
$(BUILD):
|
||||||
@[ -d $@ ] || mkdir -p $@
|
@$(shell [ ! -d $(BUILD) ] && mkdir -p $(BUILD))
|
||||||
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
|
||||||
|
|
||||||
#-------------------------------------------------------------------------------
|
#-------------------------------------------------------------------------------
|
||||||
|
133
src/debugger.cpp
133
src/debugger.cpp
@ -9,17 +9,14 @@
|
|||||||
#include <coreinit/exception.h>
|
#include <coreinit/exception.h>
|
||||||
#include <coreinit/interrupts.h>
|
#include <coreinit/interrupts.h>
|
||||||
#include <coreinit/memory.h>
|
#include <coreinit/memory.h>
|
||||||
|
#include <coreinit/memorymap.h>
|
||||||
#include <coreinit/scheduler.h>
|
#include <coreinit/scheduler.h>
|
||||||
|
#include <cstdarg>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <gx2/context.h>
|
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <sysapp/switch.h>
|
|
||||||
#include <vpad/input.h>
|
|
||||||
|
|
||||||
#include <stdarg.h>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <vpad/input.h>
|
||||||
|
|
||||||
Debugger *debugger;
|
Debugger *debugger;
|
||||||
bool initDebugState = false;
|
bool initDebugState = false;
|
||||||
@ -604,10 +601,11 @@ void Debugger::handleCrash(ExceptionState *state) {
|
|||||||
|
|
||||||
void Debugger::handleFatalCrash(OSContext *context, ExceptionState::Type type) {
|
void Debugger::handleFatalCrash(OSContext *context, ExceptionState::Type type) {
|
||||||
const char *name;
|
const char *name;
|
||||||
if (type == ExceptionState::DSI) name = "A DSI";
|
if (type == ExceptionState::DSI) {
|
||||||
else if (type == ExceptionState::ISI)
|
name = "A DSI";
|
||||||
|
} else if (type == ExceptionState::ISI) {
|
||||||
name = "An ISI";
|
name = "An ISI";
|
||||||
else {
|
} else {
|
||||||
name = "A program";
|
name = "A program";
|
||||||
}
|
}
|
||||||
DumpContext(context, name);
|
DumpContext(context, name);
|
||||||
@ -638,7 +636,7 @@ void Debugger::exceptionHandler(OSContext *context, ExceptionState::Type type) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
BOOL Debugger::dsiHandler(OSContext *context) {
|
BOOL Debugger::dsiHandler(OSContext *context) {
|
||||||
OSContext *info = new OSContext();
|
auto *info = new OSContext();
|
||||||
memcpy(info, context, sizeof(OSContext));
|
memcpy(info, context, sizeof(OSContext));
|
||||||
context->srr0 = (uint32_t) exceptionHandler;
|
context->srr0 = (uint32_t) exceptionHandler;
|
||||||
context->gpr[3] = (uint32_t) info;
|
context->gpr[3] = (uint32_t) info;
|
||||||
@ -673,64 +671,41 @@ void Debugger::cleanup() {
|
|||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static const char **commandNames = (const char *[]){
|
|
||||||
"COMMAND_CLOSE",
|
|
||||||
"COMMAND_READ",
|
|
||||||
"COMMAND_WRITE",
|
|
||||||
"COMMAND_WRITE_CODE",
|
|
||||||
"COMMAND_GET_MODULE_NAME",
|
|
||||||
"COMMAND_GET_MODULE_LIST",
|
|
||||||
"COMMAND_GET_THREAD_LIST",
|
|
||||||
"COMMAND_GET_STACK_TRACE",
|
|
||||||
"COMMAND_TOGGLE_BREAKPOINT",
|
|
||||||
"COMMAND_POKE_REGISTERS",
|
|
||||||
"COMMAND_RECEIVE_MESSAGES",
|
|
||||||
"COMMAND_SEND_MESSAGE",
|
|
||||||
"COMMAND_DISASM"};
|
|
||||||
|
|
||||||
|
|
||||||
#define LOG_DISASSEMBLY_SIZE (4096)
|
#define LOG_DISASSEMBLY_SIZE (4096)
|
||||||
|
|
||||||
static char
|
static char sDisassemblyBuffer[LOG_DISASSEMBLY_SIZE];
|
||||||
sDisassemblyBuffer[LOG_DISASSEMBLY_SIZE];
|
|
||||||
|
|
||||||
static uint32_t
|
static uint32_t sDisassemblyLength = 0;
|
||||||
sDisassemblyLength = 0;
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
disassemblyPrintCallback(const char *fmt, ...) {
|
disassemblyPrintCallback(const char *fmt, ...) {
|
||||||
va_list args;
|
va_list args;
|
||||||
va_start(args, fmt);
|
va_start(args, fmt);
|
||||||
sDisassemblyLength += vsprintf(sDisassemblyBuffer + sDisassemblyLength,
|
sDisassemblyLength += vsprintf(sDisassemblyBuffer + sDisassemblyLength, fmt, args);
|
||||||
fmt, args);
|
|
||||||
sDisassemblyBuffer[sDisassemblyLength] = 0;
|
sDisassemblyBuffer[sDisassemblyLength] = 0;
|
||||||
va_end(args);
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
void eraseAllSubStr(std::string & mainStr, const std::string & toErase)
|
void eraseAllSubStr(std::string &mainStr, const std::string &toErase) {
|
||||||
{
|
|
||||||
size_t pos = std::string::npos;
|
size_t pos = std::string::npos;
|
||||||
// Search for the substring in string in a loop untill nothing is found
|
// Search for the substring in string in a loop until nothing is found
|
||||||
while ((pos = mainStr.find(toErase) )!= std::string::npos)
|
while ((pos = mainStr.find(toErase)) != std::string::npos) {
|
||||||
{
|
|
||||||
// If found then erase it from string
|
// If found then erase it from string
|
||||||
mainStr.erase(pos, toErase.length());
|
mainStr.erase(pos, toErase.length());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//#define OSIopShell_Command_Disassemble ((void (*)(void*, uint32_t))(0x101C400 + 0x173e0))
|
//#define OSIopShell_Command_Disassemble ((void (*)(void*, uint32_t))(0x101C400 + 0x173e0))
|
||||||
#define __os_printf ((void (*)(char*, ...))(0x101C400 + 0x012e88))
|
#define __os_printf ((void (*)(char *, ...))(0x101C400 + 0x012e88))
|
||||||
|
|
||||||
void Debugger::mainLoop(Client *client) {
|
void Debugger::mainLoop(Client *client) {
|
||||||
while (!stopRunning) {
|
while (!stopRunning) {
|
||||||
uint8_t cmd;
|
uint8_t cmd;
|
||||||
if (!client->recvall(&cmd, 1)) return;
|
if (!client->recvall(&cmd, 1)) {
|
||||||
|
return;
|
||||||
if (cmd <= 12 && cmd != 10) {
|
|
||||||
DEBUG_FUNCTION_LINE("Recieved command %s %d", commandNames[cmd], cmd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cmd == COMMAND_CLOSE) {
|
if (cmd == COMMAND_CLOSE) {
|
||||||
return;
|
return;
|
||||||
} else if (cmd == COMMAND_READ) {
|
} else if (cmd == COMMAND_READ) {
|
||||||
@ -755,36 +730,25 @@ void Debugger::mainLoop(Client *client) {
|
|||||||
|
|
||||||
auto addrAsPtr = (uint32_t *) (addr & 0xfffffffc);
|
auto addrAsPtr = (uint32_t *) (addr & 0xfffffffc);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
DisassemblePPCRange(reinterpret_cast<void *>(addr + 0x20), reinterpret_cast<void *>(addr + length), reinterpret_cast<DisassemblyPrintFn>(__os_printf),OSGetSymbolName,
|
|
||||||
static_cast<DisassemblePPCFlags>(0x121));
|
|
||||||
|
|
||||||
|
|
||||||
for (int i = 0; i < length / 4; i++) {
|
for (int i = 0; i < length / 4; i++) {
|
||||||
DisassemblePPCOpcode(&addrAsPtr[i],
|
if (OSIsAddressValid(reinterpret_cast<uint32_t>(&addrAsPtr[i]))) {
|
||||||
buffer,
|
DisassemblePPCOpcode(&addrAsPtr[i], buffer, 0x40, OSGetSymbolName, static_cast<DisassemblePPCFlags>(0x121));
|
||||||
0x40,
|
disassemblyPrintCallback("0x%08x 0x%08x %s\n", &addrAsPtr[i], addrAsPtr[i], buffer);
|
||||||
OSGetSymbolName,
|
} else {
|
||||||
static_cast<DisassemblePPCFlags>(0x121));
|
disassemblyPrintCallback("0x%08x ?????????? ???\n", &addrAsPtr[i]);
|
||||||
disassemblyPrintCallback("0x%08x 0x%08x %s\n",&addrAsPtr[i],addrAsPtr[i],buffer);
|
}
|
||||||
}
|
}
|
||||||
delete[] buffer;
|
delete[] buffer;
|
||||||
|
|
||||||
|
std::string tmpString(sDisassemblyBuffer);
|
||||||
|
eraseAllSubStr(tmpString, "(null)");
|
||||||
|
|
||||||
std::string shit(sDisassemblyBuffer);
|
auto length_ = tmpString.length() + 1;
|
||||||
eraseAllSubStr(shit, "(null)");
|
|
||||||
|
|
||||||
|
|
||||||
DEBUG_FUNCTION_LINE("done");
|
|
||||||
|
|
||||||
auto length_ = shit.length() + 1;
|
|
||||||
if (!client->sendall(&length_, 4)) {
|
if (!client->sendall(&length_, 4)) {
|
||||||
sDisassemblyLength = 0;
|
sDisassemblyLength = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!client->sendall(shit.c_str(), length_)) {
|
if (!client->sendall(tmpString.c_str(), length_)) {
|
||||||
sDisassemblyLength = 0;
|
sDisassemblyLength = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -809,36 +773,44 @@ void Debugger::mainLoop(Client *client) {
|
|||||||
} else if (cmd == COMMAND_GET_MODULE_NAME) {
|
} else if (cmd == COMMAND_GET_MODULE_NAME) {
|
||||||
char name[0x40];
|
char name[0x40];
|
||||||
int length = 0x40;
|
int length = 0x40;
|
||||||
if(OSDynLoad_GetModuleName(reinterpret_cast<OSDynLoad_Module>(-1), name, &length) != OS_DYNLOAD_OK){
|
if (OSDynLoad_GetModuleName(reinterpret_cast<OSDynLoad_Module>(-1), name, &length) != OS_DYNLOAD_OK) {
|
||||||
strncat(name, "ERROR", sizeof(name) -1);
|
strncat(name, "ERROR", sizeof(name) - 1);
|
||||||
}
|
}
|
||||||
length = strlen(name);
|
length = strlen(name);
|
||||||
|
|
||||||
if (!client->sendall(&length, 4)) return;
|
if (!client->sendall(&length, 4)) return;
|
||||||
if (!client->sendall(name, length)) return;
|
if (!client->sendall(name, length)) return;
|
||||||
} else if (cmd == COMMAND_GET_MODULE_LIST) {
|
} else if (cmd == COMMAND_GET_MODULE_LIST) {
|
||||||
|
|
||||||
int num_rpls = OSDynLoad_GetNumberOfRPLs();
|
int num_rpls = OSDynLoad_GetNumberOfRPLs();
|
||||||
if (num_rpls == 0) {
|
if (num_rpls == 0) {
|
||||||
|
DEBUG_FUNCTION_LINE_ERR("Failed to get OSDynLoad_GetNumberOfRPLs");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<OSDynLoad_NotifyData> rpls;
|
std::vector<OSDynLoad_NotifyData> rpls;
|
||||||
rpls.resize(num_rpls);
|
rpls.resize(num_rpls);
|
||||||
|
|
||||||
bool ret = OSDynLoad_GetRPLInfo(0, num_rpls, rpls.data());
|
bool ret = OSDynLoad_GetRPLInfo(0, num_rpls, rpls.data());
|
||||||
if (!ret) {
|
if (!ret) {
|
||||||
|
DEBUG_FUNCTION_LINE_ERR("Failed to get OSDynLoad_GetRPLInfo");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
auto BUFFER_SIZE = 0x1000; //This should be enough
|
||||||
|
|
||||||
|
char buffer[BUFFER_SIZE];
|
||||||
|
|
||||||
char buffer[0x1000]; //This should be enough
|
|
||||||
uint32_t offset = 0;
|
uint32_t offset = 0;
|
||||||
|
|
||||||
|
|
||||||
for (auto &info : rpls) {
|
for (auto &info : rpls) {
|
||||||
uint32_t namelen = strlen(info.name);
|
uint32_t namelen = 0;
|
||||||
if (offset + 0x18 + namelen > 0x1000) {
|
if (info.name != nullptr) {
|
||||||
|
namelen = strlen(info.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (offset + 0x18 + namelen > BUFFER_SIZE) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto *infobuf = (uint32_t *) (buffer + offset);
|
auto *infobuf = (uint32_t *) (buffer + offset);
|
||||||
infobuf[0] = info.textAddr;
|
infobuf[0] = info.textAddr;
|
||||||
infobuf[1] = info.textSize;
|
infobuf[1] = info.textSize;
|
||||||
@ -846,31 +818,32 @@ void Debugger::mainLoop(Client *client) {
|
|||||||
infobuf[3] = info.dataSize;
|
infobuf[3] = info.dataSize;
|
||||||
infobuf[4] = (uint32_t) 0; // TODO: missing
|
infobuf[4] = (uint32_t) 0; // TODO: missing
|
||||||
infobuf[5] = namelen;
|
infobuf[5] = namelen;
|
||||||
memcpy(&infobuf[6], info.name, namelen);
|
if (namelen > 0) {
|
||||||
offset += 0x18 + strlen(info.name);
|
memcpy(&infobuf[6], info.name, namelen);
|
||||||
|
offset += 0x18 + strlen(info.name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//OSUnlockMutex(OSDynLoad_gLoaderLock);
|
|
||||||
|
|
||||||
if (!client->sendall(&offset, 4)) return;
|
if (!client->sendall(&offset, 4)) return;
|
||||||
if (!client->sendall(buffer, offset)) return;
|
if (!client->sendall(buffer, offset)) return;
|
||||||
} else if (cmd == COMMAND_GET_THREAD_LIST) {
|
} else if (cmd == COMMAND_GET_THREAD_LIST) {
|
||||||
int state = OSDisableInterrupts();
|
int state = OSDisableInterrupts();
|
||||||
__OSLockScheduler(this);
|
__OSLockScheduler(this);
|
||||||
|
|
||||||
char buffer[0x1000]; //This should be enough
|
auto BUFFER_SIZE = 0x1000; //This should be enough
|
||||||
|
|
||||||
|
char buffer[BUFFER_SIZE]; //This should be enough
|
||||||
uint32_t offset = 0;
|
uint32_t offset = 0;
|
||||||
OSThread *current = ThreadList;
|
OSThread *current = ThreadList;
|
||||||
while (current) {
|
while (current) {
|
||||||
const char *name = OSGetThreadName(current);
|
const char *name = OSGetThreadName(current);
|
||||||
OSReport("name %s", name);
|
|
||||||
|
|
||||||
uint32_t namelen = 0;
|
uint32_t namelen = 0;
|
||||||
if (name) {
|
if (name) {
|
||||||
namelen = strlen(name);
|
namelen = strlen(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (offset + 0x1C + namelen > 0x1000) {
|
if (offset + 0x1C + namelen > BUFFER_SIZE) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -978,7 +951,7 @@ void Debugger::mainLoop(Client *client) {
|
|||||||
}
|
}
|
||||||
exceptions.unlock();
|
exceptions.unlock();
|
||||||
} else {
|
} else {
|
||||||
DEBUG_FUNCTION_LINE("Recieved unknown command %d", cmd);
|
DEBUG_FUNCTION_LINE_ERR("Recieved unknown command %d", cmd);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1027,7 +1000,7 @@ void Debugger::start() {
|
|||||||
serverStack = (char *) memalign(0x20, STACK_SIZE);
|
serverStack = (char *) memalign(0x20, STACK_SIZE);
|
||||||
|
|
||||||
OSCreateThread(
|
OSCreateThread(
|
||||||
serverThread, threadEntry, 0, 0,
|
serverThread, threadEntry, 0, nullptr,
|
||||||
serverStack + STACK_SIZE, STACK_SIZE,
|
serverStack + STACK_SIZE, STACK_SIZE,
|
||||||
0, OS_THREAD_ATTRIB_AFFINITY_CPU2 | OS_THREAD_ATTRIB_DETACHED);
|
0, OS_THREAD_ATTRIB_AFFINITY_CPU2 | OS_THREAD_ATTRIB_DETACHED);
|
||||||
OSSetThreadName(serverThread, "Debug Server");
|
OSSetThreadName(serverThread, "Debug Server");
|
||||||
|
@ -222,7 +222,7 @@ public:
|
|||||||
~Debugger();
|
~Debugger();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
enum Command {
|
typedef enum Command {
|
||||||
COMMAND_CLOSE,
|
COMMAND_CLOSE,
|
||||||
COMMAND_READ,
|
COMMAND_READ,
|
||||||
COMMAND_WRITE,
|
COMMAND_WRITE,
|
||||||
@ -236,7 +236,7 @@ private:
|
|||||||
COMMAND_RECEIVE_MESSAGES,
|
COMMAND_RECEIVE_MESSAGES,
|
||||||
COMMAND_SEND_MESSAGE,
|
COMMAND_SEND_MESSAGE,
|
||||||
COMMAND_DISASM
|
COMMAND_DISASM
|
||||||
};
|
} Command;
|
||||||
|
|
||||||
static int threadEntry(int argc, const char **argv);
|
static int threadEntry(int argc, const char **argv);
|
||||||
static BOOL dsiHandler(OSContext *context);
|
static BOOL dsiHandler(OSContext *context);
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#include <coreinit/cache.h>
|
#include <coreinit/cache.h>
|
||||||
#include <coreinit/memorymap.h>
|
#include <coreinit/memorymap.h>
|
||||||
#include <cstdint>
|
|
||||||
#include <kernel/kernel.h>
|
#include <kernel/kernel.h>
|
||||||
|
|
||||||
void KernelWrite(uint32_t addr, const void *data, uint32_t length) {
|
void KernelWrite(uint32_t addr, const void *data, uint32_t length) {
|
||||||
|
51
src/logger.h
51
src/logger.h
@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <coreinit/debug.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <whb/log.h>
|
#include <whb/log.h>
|
||||||
|
|
||||||
@ -7,30 +8,52 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define LOG_APP_TYPE "P"
|
||||||
|
#define LOG_APP_NAME "debugger_plugin"
|
||||||
|
|
||||||
|
#define __FILENAME_X__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
|
||||||
|
#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILENAME_X__)
|
||||||
|
|
||||||
|
#define LOG(LOG_FUNC, FMT, ARGS...) LOG_EX_DEFAULT(LOG_FUNC, "", "", FMT, ##ARGS)
|
||||||
|
|
||||||
|
#define LOG_EX_DEFAULT(LOG_FUNC, LOG_LEVEL, LINE_END, FMT, ARGS...) LOG_EX(__FILENAME__, __FUNCTION__, __LINE__, LOG_FUNC, LOG_LEVEL, LINE_END, FMT, ##ARGS)
|
||||||
|
|
||||||
|
#define LOG_EX(FILENAME, FUNCTION, LINE, LOG_FUNC, LOG_LEVEL, LINE_END, FMT, ARGS...) \
|
||||||
|
do { \
|
||||||
|
LOG_FUNC("[(%s)%18s][%23s]%30s@L%04d: " LOG_LEVEL "" FMT "" LINE_END, LOG_APP_TYPE, LOG_APP_NAME, FILENAME, FUNCTION, LINE, ##ARGS); \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
||||||
#define __FILENAME_X__ (strrchr(__FILE__, '\\') ? strrchr(__FILE__, '\\') + 1 : __FILE__)
|
#ifdef VERBOSE_DEBUG
|
||||||
#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILENAME_X__)
|
#define DEBUG_FUNCTION_LINE_VERBOSE(FMT, ARGS...) LOG(WHBLogPrintf, FMT, ##ARGS)
|
||||||
|
#define DEBUG_FUNCTION_LINE_VERBOSE_EX(FILENAME, FUNCTION, LINE, FMT, ARGS...) LOG_EX(FILENAME, FUNCTION, LINE, WHBLogPrintf, "", "", FMT, ##ARGS);
|
||||||
|
#else
|
||||||
|
#define DEBUG_FUNCTION_LINE_VERBOSE(FMT, ARGS...) while (0)
|
||||||
|
#define DEBUG_FUNCTION_LINE_VERBOSE_EX(FMT, ARGS...) while (0)
|
||||||
|
#endif
|
||||||
|
|
||||||
#define DEBUG_FUNCTION_LINE_VERBOSE(FMT, ARGS...) while (0)
|
#define DEBUG_FUNCTION_LINE(FMT, ARGS...) LOG(WHBLogPrintf, FMT, ##ARGS)
|
||||||
|
|
||||||
#define DEBUG_FUNCTION_LINE(FMT, ARGS...) \
|
#define DEBUG_FUNCTION_LINE_WRITE(FMT, ARGS...) LOG(WHBLogWritef, FMT, ##ARGS)
|
||||||
do { \
|
|
||||||
WHBLogPrintf("[%23s]%30s@L%04d: " FMT "", __FILENAME__, __FUNCTION__, __LINE__, ##ARGS); \
|
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#define DEBUG_FUNCTION_LINE_WRITE(FMT, ARGS...) \
|
#define DEBUG_FUNCTION_LINE_ERR(FMT, ARGS...) LOG_EX_DEFAULT(WHBLogPrintf, "##ERROR## ", "", FMT, ##ARGS)
|
||||||
do { \
|
|
||||||
WHBLogWritef("[%23s]%30s@L%04d: " FMT "", __FILENAME__, __FUNCTION__, __LINE__, ##ARGS); \
|
#define DEBUG_FUNCTION_LINE_ERR_LAMBDA(FILENAME, FUNCTION, LINE, FMT, ARGS...) LOG_EX(FILENAME, FUNCTION, LINE, WHBLogPrintf, "##ERROR## ", "", FMT, ##ARGS);
|
||||||
} while (0)
|
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
#define DEBUG_FUNCTION_LINE_VERBOSE(FMT, ARGS...) while (0)
|
#define DEBUG_FUNCTION_LINE_VERBOSE_EX(FMT, ARGS...) while (0)
|
||||||
|
|
||||||
#define DEBUG_FUNCTION_LINE(FMT, ARGS...) while (0)
|
#define DEBUG_FUNCTION_LINE_VERBOSE(FMT, ARGS...) while (0)
|
||||||
|
|
||||||
#define DEBUG_FUNCTION_LINE_WRITE(FMT, ARGS...) while (0)
|
#define DEBUG_FUNCTION_LINE(FMT, ARGS...) while (0)
|
||||||
|
|
||||||
|
#define DEBUG_FUNCTION_LINE_WRITE(FMT, ARGS...) while (0)
|
||||||
|
|
||||||
|
#define DEBUG_FUNCTION_LINE_ERR(FMT, ARGS...) LOG_EX_DEFAULT(OSReport, "##ERROR## ", "\n", FMT, ##ARGS)
|
||||||
|
|
||||||
|
#define DEBUG_FUNCTION_LINE_ERR_LAMBDA(FILENAME, FUNCTION, LINE, FMT, ARGS...) LOG_EX(FILENAME, FUNCTION, LINE, OSReport, "##ERROR## ", "\n", FMT, ##ARGS);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
18
src/main.cpp
18
src/main.cpp
@ -21,15 +21,15 @@ WUPS_USE_WUT_DEVOPTAB();
|
|||||||
/* https://github.com/QuarkTheAwesome/CafeBinPatch/blob/main/src/runtime-patcher.cpp#L58 */
|
/* https://github.com/QuarkTheAwesome/CafeBinPatch/blob/main/src/runtime-patcher.cpp#L58 */
|
||||||
bool PatchInstruction(void *instr, uint32_t original, uint32_t replacement) {
|
bool PatchInstruction(void *instr, uint32_t original, uint32_t replacement) {
|
||||||
uint32_t current = *(uint32_t *) instr;
|
uint32_t current = *(uint32_t *) instr;
|
||||||
if (current != original) return current == replacement;
|
if (current != original) {
|
||||||
|
return current == replacement;
|
||||||
|
}
|
||||||
|
|
||||||
KernelCopyData(OSEffectiveToPhysical((uint32_t) instr), OSEffectiveToPhysical((uint32_t) &replacement), sizeof(replacement));
|
KernelCopyData(OSEffectiveToPhysical((uint32_t) instr), OSEffectiveToPhysical((uint32_t) &replacement), sizeof(replacement));
|
||||||
//Only works on AROMA! WUPS 0.1's KernelCopyData is uncached, needs DCInvalidate here instead
|
//Only works on AROMA! WUPS 0.1's KernelCopyData is uncached, needs DCInvalidate here instead
|
||||||
DCFlushRange(instr, 4);
|
DCFlushRange(instr, 4);
|
||||||
ICInvalidateRange(instr, 4);
|
ICInvalidateRange(instr, 4);
|
||||||
|
|
||||||
current = *(uint32_t *) instr;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,20 +55,20 @@ INITIALIZE_PLUGIN() {
|
|||||||
|
|
||||||
ON_APPLICATION_START() {
|
ON_APPLICATION_START() {
|
||||||
initLogging();
|
initLogging();
|
||||||
|
|
||||||
DEBUG_FUNCTION_LINE("Hello from Debugger plugin");
|
DEBUG_FUNCTION_LINE("Hello from Debugger plugin");
|
||||||
pThreadList = (OSThread **) 0x100567F8; // 100567f8
|
pThreadList = (OSThread **) 0x100567F8; // 100567f8
|
||||||
debugger = new Debugger();
|
debugger = new Debugger();
|
||||||
DCFlushRange(&debugger, 4);
|
OSMemoryBarrier();
|
||||||
DCFlushRange(debugger, sizeof(Debugger));
|
DEBUG_FUNCTION_LINE_VERBOSE("Created Debugger");
|
||||||
DEBUG_FUNCTION_LINE("Created Debugger");
|
|
||||||
debugger->start();
|
debugger->start();
|
||||||
DEBUG_FUNCTION_LINE("Started Debugger thread");
|
DEBUG_FUNCTION_LINE_VERBOSE("Started Debugger thread");
|
||||||
}
|
}
|
||||||
|
|
||||||
ON_APPLICATION_REQUESTS_EXIT() {
|
ON_APPLICATION_REQUESTS_EXIT() {
|
||||||
DEBUG_FUNCTION_LINE("Deleting Debugger thread");
|
DEBUG_FUNCTION_LINE_VERBOSE("Deleting Debugger thread");
|
||||||
delete debugger;
|
delete debugger;
|
||||||
DEBUG_FUNCTION_LINE("Deleted Debugger thread");
|
DEBUG_FUNCTION_LINE_VERBOSE("Deleted Debugger thread");
|
||||||
deinitLogging();
|
deinitLogging();
|
||||||
}
|
}
|
||||||
ON_APPLICATION_ENDS() {
|
ON_APPLICATION_ENDS() {
|
||||||
|
42
src/menu.cpp
42
src/menu.cpp
@ -1,42 +0,0 @@
|
|||||||
|
|
||||||
#include "menu.h"
|
|
||||||
#include "color.h"
|
|
||||||
#include "input.h"
|
|
||||||
#include <vpad/input.h>
|
|
||||||
|
|
||||||
Menu::Menu(Screen *screen) : screen(screen) {
|
|
||||||
currentOption = LaunchDisk;
|
|
||||||
message = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
Menu::Option Menu::show() {
|
|
||||||
while (true) {
|
|
||||||
redraw();
|
|
||||||
uint32_t buttons = WaitInput(VPAD_BUTTON_A | VPAD_BUTTON_DOWN | VPAD_BUTTON_UP);
|
|
||||||
if (buttons & VPAD_BUTTON_A) return (Option) currentOption;
|
|
||||||
else if (buttons & VPAD_BUTTON_DOWN) {
|
|
||||||
if (currentOption < 2) currentOption++;
|
|
||||||
} else if (buttons & VPAD_BUTTON_UP) {
|
|
||||||
if (currentOption > 0) currentOption--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void Menu::setMessage(const char *message) {
|
|
||||||
this->message = message;
|
|
||||||
redraw();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Menu::redraw() {
|
|
||||||
screen->clear(COLOR_BLUE);
|
|
||||||
Screen::drawText(5, 5, "Wii U Debugger");
|
|
||||||
Screen::drawText(5, 7, "Choose an option:");
|
|
||||||
Screen::drawText(8, 9, "Install and launch disc");
|
|
||||||
Screen::drawText(8, 10, "Install and return to system menu");
|
|
||||||
Screen::drawText(8, 11, "Exit without installing");
|
|
||||||
Screen::drawText(5, 9 + currentOption, ">");
|
|
||||||
if (message) {
|
|
||||||
Screen::drawText(5, 13, message);
|
|
||||||
}
|
|
||||||
Screen::flip();
|
|
||||||
}
|
|
22
src/menu.h
22
src/menu.h
@ -1,22 +0,0 @@
|
|||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "screen.h"
|
|
||||||
|
|
||||||
class Menu {
|
|
||||||
public:
|
|
||||||
enum Option { LaunchDisk,
|
|
||||||
ReturnToMenu,
|
|
||||||
Exit };
|
|
||||||
|
|
||||||
Menu(Screen *screen);
|
|
||||||
Option show();
|
|
||||||
void setMessage(const char *message);
|
|
||||||
void redraw();
|
|
||||||
|
|
||||||
private:
|
|
||||||
Screen *screen;
|
|
||||||
int currentOption;
|
|
||||||
|
|
||||||
const char *message;
|
|
||||||
};
|
|
@ -19,9 +19,11 @@ void Screen::init() {
|
|||||||
uint32_t bufferSize0 = OSScreenGetBufferSizeEx(SCREEN_TV);
|
uint32_t bufferSize0 = OSScreenGetBufferSizeEx(SCREEN_TV);
|
||||||
uint32_t bufferSize1 = OSScreenGetBufferSizeEx(SCREEN_DRC);
|
uint32_t bufferSize1 = OSScreenGetBufferSizeEx(SCREEN_DRC);
|
||||||
screenBuffer = MEMAllocFromMappedMemoryForGX2Ex(bufferSize0 + bufferSize1, 0x100);
|
screenBuffer = MEMAllocFromMappedMemoryForGX2Ex(bufferSize0 + bufferSize1, 0x100);
|
||||||
|
|
||||||
if (screenBuffer == nullptr) {
|
if (screenBuffer == nullptr) {
|
||||||
OSFatal("Failed to allocate screenbuffer");
|
OSFatal("Failed to allocate screenbuffer");
|
||||||
}
|
}
|
||||||
|
memset(screenBuffer, 0, bufferSize0 + bufferSize1);
|
||||||
OSScreenSetBufferEx(SCREEN_TV, screenBuffer);
|
OSScreenSetBufferEx(SCREEN_TV, screenBuffer);
|
||||||
OSScreenSetBufferEx(SCREEN_DRC, (char *) screenBuffer + bufferSize0);
|
OSScreenSetBufferEx(SCREEN_DRC, (char *) screenBuffer + bufferSize0);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user