Merge remote-tracking branch 'upstream/master'
This commit is contained in:
commit
6d4d80a798
@ -20,7 +20,7 @@ LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib)
|
|||||||
INCLUDE := $(foreach dir,$(LIBDIRS),-I$(dir)/include)
|
INCLUDE := $(foreach dir,$(LIBDIRS),-I$(dir)/include)
|
||||||
|
|
||||||
ASFLAGS := -mcpu=mpcore -mfloat-abi=hard
|
ASFLAGS := -mcpu=mpcore -mfloat-abi=hard
|
||||||
CFLAGS := -Wall -Wextra $(ASFLAGS) -fno-builtin -std=c11 -O2 -flto -ffast-math $(INCLUDE) -DARM11 -D_3DS
|
CFLAGS := -Wall -Wextra $(ASFLAGS) -fno-builtin -std=c11 -O2 -ffast-math $(INCLUDE) -DARM11 -D_3DS
|
||||||
LDFLAGS := -specs=3dsx.specs $(ASFLAGS) -Wl,--section-start,.text=0x14000000
|
LDFLAGS := -specs=3dsx.specs $(ASFLAGS) -Wl,--section-start,.text=0x14000000
|
||||||
|
|
||||||
objects = $(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \
|
objects = $(patsubst $(dir_source)/%.c, $(dir_build)/%.o, \
|
||||||
|
@ -21,7 +21,7 @@ INCLUDE := $(foreach dir,$(LIBDIRS),-I$(dir)/include)
|
|||||||
|
|
||||||
ARCH := -mcpu=mpcore -mfloat-abi=hard
|
ARCH := -mcpu=mpcore -mfloat-abi=hard
|
||||||
ASFLAGS := -g $(ARCH)
|
ASFLAGS := -g $(ARCH)
|
||||||
CFLAGS := -Wall -Wextra -MMD -MP -marm $(ASFLAGS) -mtp=soft -fno-builtin -std=c11 -O2 -flto -ffast-math -mword-relocations \
|
CFLAGS := -Wall -Wextra -MMD -MP -marm $(ASFLAGS) -mtp=soft -fno-builtin -std=c11 -O2 -ffast-math -mword-relocations \
|
||||||
-fomit-frame-pointer -ffunction-sections -fdata-sections $(INCLUDE) -I$(dir_include) -DARM11 -D_3DS
|
-fomit-frame-pointer -ffunction-sections -fdata-sections $(INCLUDE) -I$(dir_include) -DARM11 -D_3DS
|
||||||
LDFLAGS := -specs=3dsx.specs -g $(ARCH) -mtp=soft -Wl,--section-start,.text=0x14000000 -Wl,--gc-sections
|
LDFLAGS := -specs=3dsx.specs -g $(ARCH) -mtp=soft -Wl,--section-start,.text=0x14000000 -Wl,--gc-sections
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@
|
|||||||
GDB_DECLARE_REMOTE_COMMAND_HANDLER(SyncRequestInfo);
|
GDB_DECLARE_REMOTE_COMMAND_HANDLER(SyncRequestInfo);
|
||||||
GDB_DECLARE_REMOTE_COMMAND_HANDLER(TranslateHandle);
|
GDB_DECLARE_REMOTE_COMMAND_HANDLER(TranslateHandle);
|
||||||
GDB_DECLARE_REMOTE_COMMAND_HANDLER(GetMmuConfig);
|
GDB_DECLARE_REMOTE_COMMAND_HANDLER(GetMmuConfig);
|
||||||
|
GDB_DECLARE_REMOTE_COMMAND_HANDLER(GetMemRegions);
|
||||||
GDB_DECLARE_REMOTE_COMMAND_HANDLER(FlushCaches);
|
GDB_DECLARE_REMOTE_COMMAND_HANDLER(FlushCaches);
|
||||||
GDB_DECLARE_REMOTE_COMMAND_HANDLER(ToggleExternalMemoryAccess);
|
GDB_DECLARE_REMOTE_COMMAND_HANDLER(ToggleExternalMemoryAccess);
|
||||||
|
|
||||||
|
@ -26,10 +26,22 @@
|
|||||||
|
|
||||||
#include "MyThread.h"
|
#include "MyThread.h"
|
||||||
#include "memory.h"
|
#include "memory.h"
|
||||||
|
#include <3ds/srv.h>
|
||||||
|
|
||||||
static void _thread_begin(void* arg)
|
static void _thread_begin(void* arg)
|
||||||
{
|
{
|
||||||
MyThread *t = (MyThread *)arg;
|
MyThread *t = (MyThread *)arg;
|
||||||
|
|
||||||
|
// ROSALINA HACKJOB BEGIN
|
||||||
|
// NORMAL APPS SHOULD NOT DO THIS, EVER
|
||||||
|
u32 *tls = (u32 *)getThreadLocalStorage();
|
||||||
|
memset(tls, 0, 0x80);
|
||||||
|
tls[0] = 0x21545624;
|
||||||
|
// ROSALINA HACKJOB END
|
||||||
|
|
||||||
|
// Rosalina specific:
|
||||||
|
srvSetBlockingPolicy(true); // GetServiceHandle nonblocking if service port is full
|
||||||
|
|
||||||
t->ep();
|
t->ep();
|
||||||
MyThread_Exit();
|
MyThread_Exit();
|
||||||
}
|
}
|
||||||
|
@ -39,6 +39,7 @@ struct
|
|||||||
{ "syncrequestinfo" , GDB_REMOTE_COMMAND_HANDLER(SyncRequestInfo) },
|
{ "syncrequestinfo" , GDB_REMOTE_COMMAND_HANDLER(SyncRequestInfo) },
|
||||||
{ "translatehandle" , GDB_REMOTE_COMMAND_HANDLER(TranslateHandle) },
|
{ "translatehandle" , GDB_REMOTE_COMMAND_HANDLER(TranslateHandle) },
|
||||||
{ "getmmuconfig" , GDB_REMOTE_COMMAND_HANDLER(GetMmuConfig) },
|
{ "getmmuconfig" , GDB_REMOTE_COMMAND_HANDLER(GetMmuConfig) },
|
||||||
|
{ "getmemregions" , GDB_REMOTE_COMMAND_HANDLER(GetMemRegions) },
|
||||||
{ "flushcaches" , GDB_REMOTE_COMMAND_HANDLER(FlushCaches) },
|
{ "flushcaches" , GDB_REMOTE_COMMAND_HANDLER(FlushCaches) },
|
||||||
{ "toggleextmemaccess", GDB_REMOTE_COMMAND_HANDLER(ToggleExternalMemoryAccess) },
|
{ "toggleextmemaccess", GDB_REMOTE_COMMAND_HANDLER(ToggleExternalMemoryAccess) },
|
||||||
};
|
};
|
||||||
@ -226,6 +227,84 @@ GDB_DECLARE_REMOTE_COMMAND_HANDLER(GetMmuConfig)
|
|||||||
return GDB_SendHexPacket(ctx, outbuf, n);
|
return GDB_SendHexPacket(ctx, outbuf, n);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *FormatMemPerm(u32 perm)
|
||||||
|
{
|
||||||
|
if (perm == MEMPERM_DONTCARE)
|
||||||
|
return "???";
|
||||||
|
|
||||||
|
static char buf[4] = {0};
|
||||||
|
|
||||||
|
buf[0] = perm & MEMPERM_READ ? 'r' : '-';
|
||||||
|
buf[1] = perm & MEMPERM_WRITE ? 'w' : '-';
|
||||||
|
buf[2] = perm & MEMPERM_EXECUTE ? 'x' : '-';
|
||||||
|
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char *FormatMemState(u32 state)
|
||||||
|
{
|
||||||
|
if (state > 11)
|
||||||
|
return "Unknown";
|
||||||
|
|
||||||
|
static const char *states[12] =
|
||||||
|
{
|
||||||
|
"Free",
|
||||||
|
"Reserved",
|
||||||
|
"IO",
|
||||||
|
"Static",
|
||||||
|
"Code",
|
||||||
|
"Private",
|
||||||
|
"Shared",
|
||||||
|
"Continuous",
|
||||||
|
"Aliased",
|
||||||
|
"Alias",
|
||||||
|
"AliasCode",
|
||||||
|
"Locked"
|
||||||
|
};
|
||||||
|
|
||||||
|
return states[state];
|
||||||
|
}
|
||||||
|
|
||||||
|
GDB_DECLARE_REMOTE_COMMAND_HANDLER(GetMemRegions)
|
||||||
|
{
|
||||||
|
u32 address = 0;
|
||||||
|
u32 posInBuffer = 0;
|
||||||
|
u32 maxPosInBuffer = GDB_BUF_LEN / 2 - 35; ///< 35 is the maximum length of a formatted region
|
||||||
|
Handle handle;
|
||||||
|
MemInfo memi;
|
||||||
|
PageInfo pagei;
|
||||||
|
char outbuf[GDB_BUF_LEN / 2 + 1];
|
||||||
|
|
||||||
|
if(R_FAILED(svcOpenProcess(&handle, ctx->pid)))
|
||||||
|
{
|
||||||
|
posInBuffer = sprintf(outbuf, "Invalid process (wtf?)\n");
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (address < 0x40000000 ///< Limit to check for regions
|
||||||
|
&& posInBuffer < maxPosInBuffer
|
||||||
|
&& R_SUCCEEDED(svcQueryProcessMemory(&memi, &pagei, handle, address)))
|
||||||
|
{
|
||||||
|
// Update the address for next region
|
||||||
|
address = memi.base_addr + memi.size;
|
||||||
|
|
||||||
|
// If region isn't FREE then add it to the list
|
||||||
|
if (memi.state != MEMSTATE_FREE)
|
||||||
|
{
|
||||||
|
const char *perm = FormatMemPerm(memi.perm);
|
||||||
|
const char *state = FormatMemState(memi.state);
|
||||||
|
|
||||||
|
posInBuffer += sprintf(outbuf + posInBuffer, "%08X - %08X %s %s\n",
|
||||||
|
memi.base_addr, address, perm, state);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
svcCloseHandle(handle);
|
||||||
|
|
||||||
|
end:
|
||||||
|
return GDB_SendHexPacket(ctx, outbuf, posInBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
GDB_DECLARE_REMOTE_COMMAND_HANDLER(FlushCaches)
|
GDB_DECLARE_REMOTE_COMMAND_HANDLER(FlushCaches)
|
||||||
{
|
{
|
||||||
if(ctx->commandData[0] != 0)
|
if(ctx->commandData[0] != 0)
|
||||||
|
@ -89,6 +89,16 @@ void initSystem()
|
|||||||
ProcessPatchesMenu_PatchUnpatchFSDirectly();
|
ProcessPatchesMenu_PatchUnpatchFSDirectly();
|
||||||
__sync_init();
|
__sync_init();
|
||||||
__appInit();
|
__appInit();
|
||||||
|
|
||||||
|
// ROSALINA HACKJOB BEGIN
|
||||||
|
// NORMAL APPS SHOULD NOT DO THIS, EVER
|
||||||
|
u32 *tls = (u32 *)getThreadLocalStorage();
|
||||||
|
memset(tls, 0, 0x80);
|
||||||
|
tls[0] = 0x21545624;
|
||||||
|
// ROSALINA HACKJOB END
|
||||||
|
|
||||||
|
// Rosalina specific:
|
||||||
|
srvSetBlockingPolicy(true); // GetServiceHandle nonblocking if service port is full
|
||||||
}
|
}
|
||||||
|
|
||||||
bool terminationRequest = false;
|
bool terminationRequest = false;
|
||||||
|
@ -149,14 +149,23 @@ void menuThreadMain(void)
|
|||||||
else
|
else
|
||||||
N3DSMenu_UpdateStatus();
|
N3DSMenu_UpdateStatus();
|
||||||
|
|
||||||
|
bool isAcURegistered = false;
|
||||||
|
|
||||||
while(!terminationRequest)
|
while(!terminationRequest)
|
||||||
{
|
{
|
||||||
if((HID_PAD & menuCombo) == menuCombo)
|
if((HID_PAD & menuCombo) == menuCombo)
|
||||||
{
|
{
|
||||||
menuEnter();
|
if (!isAcURegistered)
|
||||||
if(isN3DS) N3DSMenu_UpdateStatus();
|
isAcURegistered = R_SUCCEEDED(srvIsServiceRegistered(&isAcURegistered, "ac:u"))
|
||||||
menuShow(&rosalinaMenu);
|
&& isAcURegistered;
|
||||||
menuLeave();
|
|
||||||
|
if (isAcURegistered)
|
||||||
|
{
|
||||||
|
menuEnter();
|
||||||
|
if(isN3DS) N3DSMenu_UpdateStatus();
|
||||||
|
menuShow(&rosalinaMenu);
|
||||||
|
menuLeave();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -200,13 +209,16 @@ static void menuDraw(Menu *menu, u32 selected)
|
|||||||
s64 out;
|
s64 out;
|
||||||
u32 version, commitHash;
|
u32 version, commitHash;
|
||||||
bool isRelease;
|
bool isRelease;
|
||||||
|
bool isMcuHwcRegistered;
|
||||||
|
|
||||||
if(R_SUCCEEDED(mcuHwcInit()))
|
if(R_SUCCEEDED(srvIsServiceRegistered(&isMcuHwcRegistered, "mcu::HWC")) && isMcuHwcRegistered && R_SUCCEEDED(mcuHwcInit()))
|
||||||
{
|
{
|
||||||
if(R_FAILED(MCUHWC_GetBatteryLevel(&batteryLevel)))
|
if(R_FAILED(MCUHWC_GetBatteryLevel(&batteryLevel)))
|
||||||
batteryLevel = 255;
|
batteryLevel = 255;
|
||||||
mcuHwcExit();
|
mcuHwcExit();
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
batteryLevel = 255;
|
||||||
|
|
||||||
svcGetSystemInfo(&out, 0x10000, 0);
|
svcGetSystemInfo(&out, 0x10000, 0);
|
||||||
version = (u32)out;
|
version = (u32)out;
|
||||||
|
@ -69,12 +69,10 @@ void DebuggerMenu_EnableDebugger(void)
|
|||||||
bool done = false, alreadyEnabled = gdbServer.super.running;
|
bool done = false, alreadyEnabled = gdbServer.super.running;
|
||||||
Result res = 0;
|
Result res = 0;
|
||||||
char buf[65];
|
char buf[65];
|
||||||
bool cantStart;
|
bool isSocURegistered;
|
||||||
Handle dummy;
|
|
||||||
|
|
||||||
res = OpenProcessByName("socket", &dummy);
|
res = srvIsServiceRegistered(&isSocURegistered, "soc:U");
|
||||||
cantStart = R_FAILED(res);
|
isSocURegistered = R_SUCCEEDED(res) && isSocURegistered;
|
||||||
svcCloseHandle(dummy);
|
|
||||||
|
|
||||||
Draw_Lock();
|
Draw_Lock();
|
||||||
Draw_ClearFramebuffer();
|
Draw_ClearFramebuffer();
|
||||||
@ -88,7 +86,7 @@ void DebuggerMenu_EnableDebugger(void)
|
|||||||
|
|
||||||
if(alreadyEnabled)
|
if(alreadyEnabled)
|
||||||
Draw_DrawString(10, 30, COLOR_WHITE, "Already enabled!");
|
Draw_DrawString(10, 30, COLOR_WHITE, "Already enabled!");
|
||||||
else if(cantStart)
|
else if(!isSocURegistered)
|
||||||
Draw_DrawString(10, 30, COLOR_WHITE, "Can't start the debugger before the system has fi-\nnished loading.");
|
Draw_DrawString(10, 30, COLOR_WHITE, "Can't start the debugger before the system has fi-\nnished loading.");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -258,19 +258,19 @@ void MiscellaneousMenu_InputRedirection(void)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Handle dummy;
|
s64 dummyInfo;
|
||||||
s64 dummyInfo;
|
bool isN3DS = svcGetSystemInfo(&dummyInfo, 0x10001, 0) == 0;
|
||||||
bool isN3DS = svcGetSystemInfo(&dummyInfo, 0x10001, 0) == 0;
|
bool isSocURegistered;
|
||||||
|
|
||||||
res = OpenProcessByName("socket", &dummy);
|
res = srvIsServiceRegistered(&isSocURegistered, "soc:U");
|
||||||
cantStart = R_FAILED(res);
|
cantStart = R_FAILED(res) || !isSocURegistered;
|
||||||
svcCloseHandle(dummy);
|
|
||||||
|
|
||||||
if(!cantStart && isN3DS)
|
if(!cantStart && isN3DS)
|
||||||
{
|
{
|
||||||
res = OpenProcessByName("ir", &dummy);
|
bool isIrRstRegistered;
|
||||||
cantStart = R_FAILED(res);
|
|
||||||
svcCloseHandle(dummy);
|
res = srvIsServiceRegistered(&isIrRstRegistered, "ir:rst");
|
||||||
|
cantStart = R_FAILED(res) || !isIrRstRegistered;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,7 +285,7 @@ void MiscellaneousMenu_InputRedirection(void)
|
|||||||
Draw_DrawString(10, 10, COLOR_TITLE, "Miscellaneous options menu");
|
Draw_DrawString(10, 10, COLOR_TITLE, "Miscellaneous options menu");
|
||||||
|
|
||||||
if(!wasEnabled && cantStart)
|
if(!wasEnabled && cantStart)
|
||||||
Draw_DrawString(10, 30, COLOR_WHITE, "Can't start the debugger before the system has fi-\nnished loading.");
|
Draw_DrawString(10, 30, COLOR_WHITE, "Can't start the input redirection before the system\nhas finished loading.");
|
||||||
else if(!wasEnabled)
|
else if(!wasEnabled)
|
||||||
{
|
{
|
||||||
Draw_DrawString(10, 30, COLOR_WHITE, "Starting InputRedirection...");
|
Draw_DrawString(10, 30, COLOR_WHITE, "Starting InputRedirection...");
|
||||||
|
@ -80,6 +80,18 @@ Result miniSocInit()
|
|||||||
|
|
||||||
u32 tmp = 0;
|
u32 tmp = 0;
|
||||||
Result ret = 0;
|
Result ret = 0;
|
||||||
|
bool isSocURegistered;
|
||||||
|
|
||||||
|
ret = srvIsServiceRegistered(&isSocURegistered, "soc:U");
|
||||||
|
if(ret != 0) goto cleanup;
|
||||||
|
if(!isSocURegistered)
|
||||||
|
{
|
||||||
|
ret = -1;
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = srvGetServiceHandle(&SOCU_handle, "soc:U");
|
||||||
|
if(ret != 0) goto cleanup;
|
||||||
|
|
||||||
ret = svcControlMemory(&tmp, socContextAddr, 0, socContextSize, MEMOP_ALLOC, MEMPERM_READ | MEMPERM_WRITE);
|
ret = svcControlMemory(&tmp, socContextAddr, 0, socContextSize, MEMOP_ALLOC, MEMPERM_READ | MEMPERM_WRITE);
|
||||||
if(ret != 0) goto cleanup;
|
if(ret != 0) goto cleanup;
|
||||||
@ -89,8 +101,7 @@ Result miniSocInit()
|
|||||||
ret = svcCreateMemoryBlock(&socMemhandle, (u32)socContextAddr, socContextSize, 0, 3);
|
ret = svcCreateMemoryBlock(&socMemhandle, (u32)socContextAddr, socContextSize, 0, 3);
|
||||||
if(ret != 0) goto cleanup;
|
if(ret != 0) goto cleanup;
|
||||||
|
|
||||||
ret = srvGetServiceHandle(&SOCU_handle, "soc:U");
|
|
||||||
if(ret != 0) goto cleanup;
|
|
||||||
|
|
||||||
ret = SOCU_Initialize(socMemhandle, socContextSize);
|
ret = SOCU_Initialize(socMemhandle, socContextSize);
|
||||||
if(ret != 0) goto cleanup;
|
if(ret != 0) goto cleanup;
|
||||||
|
@ -135,33 +135,30 @@ void server_bind(struct sock_server *serv, u16 port)
|
|||||||
server_sockfd = socSocket(AF_INET, SOCK_STREAM, 0);
|
server_sockfd = socSocket(AF_INET, SOCK_STREAM, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(server_sockfd != -1)
|
struct sockaddr_in saddr;
|
||||||
|
saddr.sin_family = AF_INET;
|
||||||
|
saddr.sin_port = htons(port);
|
||||||
|
saddr.sin_addr.s_addr = gethostid();
|
||||||
|
|
||||||
|
res = socBind(server_sockfd, (struct sockaddr*)&saddr, sizeof(struct sockaddr_in));
|
||||||
|
|
||||||
|
if(res == 0)
|
||||||
{
|
{
|
||||||
struct sockaddr_in saddr;
|
res = socListen(server_sockfd, 2);
|
||||||
saddr.sin_family = AF_INET;
|
|
||||||
saddr.sin_port = htons(port);
|
|
||||||
saddr.sin_addr.s_addr = gethostid();
|
|
||||||
|
|
||||||
res = socBind(server_sockfd, (struct sockaddr*)&saddr, sizeof(struct sockaddr_in));
|
|
||||||
|
|
||||||
if(res == 0)
|
if(res == 0)
|
||||||
{
|
{
|
||||||
res = socListen(server_sockfd, 2);
|
int idx = serv->nfds;
|
||||||
if(res == 0)
|
serv->nfds++;
|
||||||
{
|
serv->poll_fds[idx].fd = server_sockfd;
|
||||||
int idx = serv->nfds;
|
serv->poll_fds[idx].events = POLLIN;
|
||||||
serv->nfds++;
|
|
||||||
serv->poll_fds[idx].fd = server_sockfd;
|
|
||||||
serv->poll_fds[idx].events = POLLIN;
|
|
||||||
|
|
||||||
struct sock_ctx *new_ctx = server_alloc_server_ctx(serv);
|
struct sock_ctx *new_ctx = server_alloc_server_ctx(serv);
|
||||||
memcpy(&new_ctx->addr_in, &saddr, sizeof(struct sockaddr_in));
|
memcpy(&new_ctx->addr_in, &saddr, sizeof(struct sockaddr_in));
|
||||||
new_ctx->type = SOCK_SERVER;
|
new_ctx->type = SOCK_SERVER;
|
||||||
new_ctx->sockfd = server_sockfd;
|
new_ctx->sockfd = server_sockfd;
|
||||||
new_ctx->n = 0;
|
new_ctx->n = 0;
|
||||||
new_ctx->i = idx;
|
new_ctx->i = idx;
|
||||||
serv->ctx_ptrs[idx] = new_ctx;
|
serv->ctx_ptrs[idx] = new_ctx;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user