Implement ro:1

This commit is contained in:
Michael Scire 2019-04-22 05:08:12 -07:00 committed by fincs
parent 23bd10f6db
commit 50db74a15b
2 changed files with 119 additions and 52 deletions

View File

@ -12,6 +12,9 @@
Result ldrRoInitialize(void);
void ldrRoExit(void);
Result ro1Initialize(void);
void ro1Exit(void);
Result roDmntInitialize(void);
void roDmntExit(void);
@ -21,4 +24,10 @@ Result ldrRoLoadNrr(u64 nrr_address, u64 nrr_size);
Result ldrRoUnloadNrr(u64 nrr_address);
Result ldrRoLoadNrrEx(u64 nrr_address, u64 nrr_size);
Result ro1LoadNro(u64* out_address, u64 nro_address, u64 nro_size, u64 bss_address, u64 bss_size);
Result ro1UnloadNro(u64 nro_address);
Result ro1LoadNrr(u64 nrr_address, u64 nrr_size);
Result ro1UnloadNrr(u64 nrr_address);
Result ro1LoadNrrEx(u64 nrr_address, u64 nrr_size);
Result roDmntGetModuleInfos(u64 pid, LoaderModuleInfo *out_module_infos, size_t max_out_modules, u32 *num_out);

View File

@ -8,10 +8,14 @@
#include "services/ro.h"
#include "services/sm.h"
static Service g_roSrv, g_dmntSrv;
static u64 g_roRefCnt, g_dmntRefCnt;
static Service g_roSrv, g_ro1Srv, g_dmntSrv;
static u64 g_roRefCnt, g_ro1RefCnt, g_dmntRefCnt;
static Result _ldrRoInitialize(void);
static Result _rosrvInitialize(Service* srv);
static Result _rosrvLoadNro(Service* srv, u64* out_address, u64 nro_address, u64 nro_size, u64 bss_address, u64 bss_size);
static Result _rosrvUnloadNro(Service* srv, u64 nro_address);
static Result _rosrvLoadNrr(Service* srv, u64 cmd_id, u64 nrr_address, u64 nrr_size);
static Result _rosrvUnloadNrr(Service* srv, u64 nrr_address);
Result ldrRoInitialize(void) {
atomicIncrement64(&g_roRefCnt);
@ -22,7 +26,7 @@ Result ldrRoInitialize(void) {
Result rc = smGetService(&g_roSrv, "ldr:ro");
if (R_SUCCEEDED(rc)) {
rc = _ldrRoInitialize();
rc = _rosrvInitialize(&g_roSrv);
}
return rc;
@ -33,6 +37,28 @@ void ldrRoExit(void) {
serviceClose(&g_roSrv);
}
Result ro1Initialize(void) {
if (hosversionBefore(7,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
atomicIncrement64(&g_ro1RefCnt);
if (serviceIsActive(&g_ro1Srv))
return 0;
Result rc = smGetService(&g_ro1Srv, "ro:1");
if (R_SUCCEEDED(rc)) {
rc = _rosrvInitialize(&g_ro1Srv);
}
return rc;
}
void ro1Exit(void) {
if (atomicDecrement64(&g_ro1RefCnt) == 0)
serviceClose(&g_ro1Srv);
}
Result roDmntInitialize(void) {
if (hosversionBefore(3,0,0)) return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
@ -49,7 +75,40 @@ void roDmntExit(void) {
serviceClose(&g_dmntSrv);
}
Result ldrRoLoadNro(u64* out_address, u64 nro_address, u64 nro_size, u64 bss_address, u64 bss_size) {
Result _rosrvInitialize(Service* srv) {
IpcCommand c;
ipcInitialize(&c);
ipcSendHandleCopy(&c, CUR_PROCESS_HANDLE);
struct {
u64 magic;
u64 cmd_id;
} *raw;
raw = serviceIpcPrepareHeader(srv, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 4;
Result rc = serviceIpcDispatch(srv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
struct {
u64 magic;
u64 result;
} *resp;
serviceIpcParse(srv, &r, sizeof(*resp));
resp = r.Raw;
rc = resp->result;
}
return rc;
}
Result _rosrvLoadNro(Service* srv, u64* out_address, u64 nro_address, u64 nro_size, u64 bss_address, u64 bss_size) {
IpcCommand c;
ipcInitialize(&c);
ipcSendPid(&c);
@ -64,7 +123,7 @@ Result ldrRoLoadNro(u64* out_address, u64 nro_address, u64 nro_size, u64 bss_add
u64 bss_size;
} *raw;
raw = serviceIpcPrepareHeader(&g_roSrv, &c, sizeof(*raw));
raw = serviceIpcPrepareHeader(srv, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 0;
@ -74,7 +133,7 @@ Result ldrRoLoadNro(u64* out_address, u64 nro_address, u64 nro_size, u64 bss_add
raw->bss_address = bss_address;
raw->bss_size = bss_size;
Result rc = serviceIpcDispatch(&g_roSrv);
Result rc = serviceIpcDispatch(srv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
@ -84,7 +143,7 @@ Result ldrRoLoadNro(u64* out_address, u64 nro_address, u64 nro_size, u64 bss_add
u64 out_address;
} *resp;
serviceIpcParse(&g_roSrv, &r, sizeof(*resp));
serviceIpcParse(srv, &r, sizeof(*resp));
resp = r.Raw;
rc = resp->result;
@ -97,7 +156,7 @@ Result ldrRoLoadNro(u64* out_address, u64 nro_address, u64 nro_size, u64 bss_add
return rc;
}
Result ldrRoUnloadNro(u64 nro_address) {
Result _rosrvUnloadNro(Service* srv, u64 nro_address) {
IpcCommand c;
ipcInitialize(&c);
ipcSendPid(&c);
@ -109,14 +168,14 @@ Result ldrRoUnloadNro(u64 nro_address) {
u64 nro_address;
} *raw;
raw = serviceIpcPrepareHeader(&g_roSrv, &c, sizeof(*raw));
raw = serviceIpcPrepareHeader(srv, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 1;
raw->pid = 0;
raw->nro_address = nro_address;
Result rc = serviceIpcDispatch(&g_roSrv);
Result rc = serviceIpcDispatch(srv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
@ -125,7 +184,7 @@ Result ldrRoUnloadNro(u64 nro_address) {
u64 result;
} *resp;
serviceIpcParse(&g_roSrv, &r, sizeof(*resp));
serviceIpcParse(srv, &r, sizeof(*resp));
resp = r.Raw;
rc = resp->result;
@ -134,7 +193,7 @@ Result ldrRoUnloadNro(u64 nro_address) {
return rc;
}
static Result _ldrRoLoadNrr(u64 cmd_id, u64 nrr_address, u64 nrr_size) {
Result _rosrvLoadNrr(Service* srv, u64 cmd_id, u64 nrr_address, u64 nrr_size) {
IpcCommand c;
ipcInitialize(&c);
ipcSendPid(&c);
@ -147,7 +206,7 @@ static Result _ldrRoLoadNrr(u64 cmd_id, u64 nrr_address, u64 nrr_size) {
u64 nrr_size;
} *raw;
raw = serviceIpcPrepareHeader(&g_roSrv, &c, sizeof(*raw));
raw = serviceIpcPrepareHeader(srv, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = cmd_id;
@ -155,7 +214,7 @@ static Result _ldrRoLoadNrr(u64 cmd_id, u64 nrr_address, u64 nrr_size) {
raw->nrr_address = nrr_address;
raw->nrr_size = nrr_size;
Result rc = serviceIpcDispatch(&g_roSrv);
Result rc = serviceIpcDispatch(srv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
@ -164,7 +223,7 @@ static Result _ldrRoLoadNrr(u64 cmd_id, u64 nrr_address, u64 nrr_size) {
u64 result;
} *resp;
serviceIpcParse(&g_roSrv, &r, sizeof(*resp));
serviceIpcParse(srv, &r, sizeof(*resp));
resp = r.Raw;
rc = resp->result;
@ -173,11 +232,7 @@ static Result _ldrRoLoadNrr(u64 cmd_id, u64 nrr_address, u64 nrr_size) {
return rc;
}
Result ldrRoLoadNrr(u64 nrr_address, u64 nrr_size) {
return _ldrRoLoadNrr(2, nrr_address, nrr_size);
}
Result ldrRoUnloadNrr(u64 nrr_address) {
Result _rosrvUnloadNrr(Service* srv, u64 nrr_address) {
IpcCommand c;
ipcInitialize(&c);
ipcSendPid(&c);
@ -189,14 +244,14 @@ Result ldrRoUnloadNrr(u64 nrr_address) {
u64 nrr_address;
} *raw;
raw = serviceIpcPrepareHeader(&g_roSrv, &c, sizeof(*raw));
raw = serviceIpcPrepareHeader(srv, &c, sizeof(*raw));
raw->magic = SFCI_MAGIC;
raw->cmd_id = 3;
raw->pid = 0;
raw->nrr_address = nrr_address;
Result rc = serviceIpcDispatch(&g_roSrv);
Result rc = serviceIpcDispatch(srv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
@ -205,7 +260,7 @@ Result ldrRoUnloadNrr(u64 nrr_address) {
u64 result;
} *resp;
serviceIpcParse(&g_roSrv, &r, sizeof(*resp));
serviceIpcParse(srv, &r, sizeof(*resp));
resp = r.Raw;
rc = resp->result;
@ -214,44 +269,47 @@ Result ldrRoUnloadNrr(u64 nrr_address) {
return rc;
}
Result ldrRoLoadNro(u64* out_address, u64 nro_address, u64 nro_size, u64 bss_address, u64 bss_size) {
return _rosrvLoadNro(&g_roSrv, out_address, nro_address, nro_size, bss_address, bss_size);
}
Result ldrRoUnloadNro(u64 nro_address) {
return _rosrvUnloadNro(&g_roSrv, nro_address);
}
Result ldrRoLoadNrr(u64 nrr_address, u64 nrr_size) {
return _rosrvLoadNrr(&g_roSrv, 2, nrr_address, nrr_size);
}
Result ldrRoUnloadNrr(u64 nrr_address) {
return _rosrvUnloadNrr(&g_roSrv, nrr_address);
}
Result ldrRoLoadNrrEx(u64 nrr_address, u64 nrr_size) {
if (hosversionBefore(7,0,0)) {
return MAKERESULT(Module_Libnx, LibnxError_IncompatSysVer);
}
return _ldrRoLoadNrr(10, nrr_address, nrr_size);
return _rosrvLoadNrr(&g_roSrv, 10, nrr_address, nrr_size);
}
Result _ldrRoInitialize(void) {
IpcCommand c;
ipcInitialize(&c);
ipcSendHandleCopy(&c, CUR_PROCESS_HANDLE);
Result ro1LoadNro(u64* out_address, u64 nro_address, u64 nro_size, u64 bss_address, u64 bss_size) {
return _rosrvLoadNro(&g_ro1Srv, out_address, nro_address, nro_size, bss_address, bss_size);
}
struct {
u64 magic;
u64 cmd_id;
} *raw;
Result ro1UnloadNro(u64 nro_address) {
return _rosrvUnloadNro(&g_ro1Srv, nro_address);
}
raw = serviceIpcPrepareHeader(&g_roSrv, &c, sizeof(*raw));
Result ro1LoadNrr(u64 nrr_address, u64 nrr_size) {
return _rosrvLoadNrr(&g_ro1Srv, 2, nrr_address, nrr_size);
}
raw->magic = SFCI_MAGIC;
raw->cmd_id = 4;
Result ro1UnloadNrr(u64 nrr_address) {
return _rosrvUnloadNrr(&g_ro1Srv, nrr_address);
}
Result rc = serviceIpcDispatch(&g_roSrv);
if (R_SUCCEEDED(rc)) {
IpcParsedCommand r;
struct {
u64 magic;
u64 result;
} *resp;
serviceIpcParse(&g_roSrv, &r, sizeof(*resp));
resp = r.Raw;
rc = resp->result;
}
return rc;
Result ro1LoadNrrEx(u64 nrr_address, u64 nrr_size) {
return _rosrvLoadNrr(&g_ro1Srv, 10, nrr_address, nrr_size);
}
Result roDmntGetModuleInfos(u64 pid, LoaderModuleInfo *out_module_infos, size_t max_out_modules, u32 *num_out) {