/*
* This file is part of Luma3DS
* Copyright (C) 2016-2020 Aurora Wright, TuxSH
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*
* Additional Terms 7.b and 7.c of GPLv3 apply to this file:
* * Requiring preservation of specified reasonable legal notices or
* author attributions in that material or in the Appropriate Legal
* Notices displayed by works containing it.
* * Prohibiting misrepresentation of the origin of that material,
* or requiring that modified versions of such material be marked in
* reasonable ways as different from the original version.
*/
#include "utils.h"
#include "csvc.h"
#include
#include
void formatMemoryPermission(char *outbuf, MemPerm perm)
{
if (perm == MEMPERM_DONTCARE)
{
strcpy(outbuf, "???");
return;
}
outbuf[0] = perm & MEMPERM_READ ? 'r' : '-';
outbuf[1] = perm & MEMPERM_WRITE ? 'w' : '-';
outbuf[2] = perm & MEMPERM_EXECUTE ? 'x' : '-';
outbuf[3] = '\0';
}
void formatUserMemoryState(char *outbuf, MemState state)
{
static const char *states[12] =
{
"Free",
"Reserved",
"IO",
"Static",
"Code",
"Private",
"Shared",
"Continuous",
"Aliased",
"Alias",
"AliasCode",
"Locked"
};
strcpy(outbuf, state > 11 ? "Unknown" : states[state]);
}
u32 formatMemoryMapOfProcess(char *outbuf, u32 bufLen, Handle handle)
{
u32 maxLineSize = 35 + (handle == CUR_PROCESS_HANDLE ? 15 : 0);
u32 address = 0;
u32 posInBuffer = 0;
u32 maxPosInBuffer = bufLen - maxLineSize; // 35 is the maximum length of a formatted region
MemInfo memi;
PageInfo pagei;
char pabuf[32];
char permbuf[8];
char statebuf[16];
s64 TTBCR;
svcGetSystemInfo(&TTBCR, 0x10002, 0);
while (address < (1u << (32 - (u32)TTBCR)) // 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)
{
if (handle == CUR_PROCESS_HANDLE)
{
u32 pa = svcConvertVAToPA((void *)memi.base_addr, false);
sprintf(pabuf, " (PA %08lx)", pa);
}
else
pabuf[0] = '\0';
formatMemoryPermission(permbuf, memi.perm);
formatUserMemoryState(statebuf, memi.state);
posInBuffer += sprintf(outbuf + posInBuffer, "%08lx - %08lx%s %s %s\n",
memi.base_addr, address, pabuf, permbuf, statebuf);
}
}
svcCloseHandle(handle);
return posInBuffer;
}