svc: refactor/rename MemoryInfo fields
This commit is contained in:
@@ -99,10 +99,10 @@ namespace ams::creport {
|
||||
}
|
||||
|
||||
/* Parse module. */
|
||||
if (mi.perm == svc::MemoryPermission_ReadExecute) {
|
||||
if (mi.permission == svc::MemoryPermission_ReadExecute) {
|
||||
auto& module = this->modules[this->num_modules++];
|
||||
module.start_address = mi.addr;
|
||||
module.end_address = mi.addr + mi.size;
|
||||
module.start_address = mi.base_address;
|
||||
module.end_address = mi.base_address + mi.size;
|
||||
GetModuleName(module.name, module.start_address, module.end_address);
|
||||
GetModuleBuildId(module.build_id, module.end_address);
|
||||
/* Some homebrew won't have a name. Add a fake one for readability. */
|
||||
@@ -134,34 +134,34 @@ namespace ams::creport {
|
||||
}
|
||||
|
||||
/* If we fall into a RW region, it may be rwdata. Query the region before it, which may be rodata or text. */
|
||||
if (mi.perm == svc::MemoryPermission_ReadWrite) {
|
||||
if (R_FAILED(svc::QueryDebugProcessMemory(&mi, &pi, debug_handle, mi.addr - 4))) {
|
||||
if (mi.permission == svc::MemoryPermission_ReadWrite) {
|
||||
if (R_FAILED(svc::QueryDebugProcessMemory(&mi, &pi, debug_handle, mi.base_address - 4))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* If we fall into an RO region, it may be rodata. Query the region before it, which should be text. */
|
||||
if (mi.perm == svc::MemoryPermission_Read) {
|
||||
if (R_FAILED(svc::QueryDebugProcessMemory(&mi, &pi, debug_handle, mi.addr - 4))) {
|
||||
if (mi.permission == svc::MemoryPermission_Read) {
|
||||
if (R_FAILED(svc::QueryDebugProcessMemory(&mi, &pi, debug_handle, mi.base_address - 4))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* We should, at this point, be looking at an executable region (text). */
|
||||
if (mi.perm != svc::MemoryPermission_ReadExecute) {
|
||||
if (mi.permission != svc::MemoryPermission_ReadExecute) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Modules are a series of contiguous (text/rodata/rwdata) regions. */
|
||||
/* Iterate backwards until we find unmapped memory, to find the start of the set of modules loaded here. */
|
||||
while (mi.addr > 0) {
|
||||
if (R_FAILED(svc::QueryDebugProcessMemory(&mi, &pi, debug_handle, mi.addr - 4))) {
|
||||
while (mi.base_address > 0) {
|
||||
if (R_FAILED(svc::QueryDebugProcessMemory(&mi, &pi, debug_handle, mi.base_address - 4))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mi.state == svc::MemoryState_Free) {
|
||||
/* We've found unmapped memory, so output the mapped memory afterwards. */
|
||||
*out_address = mi.addr + mi.size;
|
||||
*out_address = mi.base_address + mi.size;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -181,12 +181,12 @@ namespace ams::creport {
|
||||
svc::PageInfo pi;
|
||||
|
||||
/* Verify .rodata is read-only. */
|
||||
if (R_FAILED(svc::QueryDebugProcessMemory(&mi, &pi, this->debug_handle, ro_start_address)) || mi.perm != svc::MemoryPermission_Read) {
|
||||
if (R_FAILED(svc::QueryDebugProcessMemory(&mi, &pi, this->debug_handle, ro_start_address)) || mi.permission != svc::MemoryPermission_Read) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* Calculate start of rwdata. */
|
||||
const u64 rw_start_address = mi.addr + mi.size;
|
||||
const u64 rw_start_address = mi.base_address + mi.size;
|
||||
|
||||
/* Read start of .rodata. */
|
||||
if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast<uintptr_t>(std::addressof(rodata_start)), this->debug_handle, ro_start_address, sizeof(rodata_start)))) {
|
||||
@@ -228,13 +228,13 @@ namespace ams::creport {
|
||||
/* Verify .rodata is read-only. */
|
||||
svc::MemoryInfo mi;
|
||||
svc::PageInfo pi;
|
||||
if (R_FAILED(svc::QueryDebugProcessMemory(&mi, &pi, this->debug_handle, ro_start_address)) || mi.perm != svc::MemoryPermission_Read) {
|
||||
if (R_FAILED(svc::QueryDebugProcessMemory(&mi, &pi, this->debug_handle, ro_start_address)) || mi.permission != svc::MemoryPermission_Read) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* We want to read the last two pages of .rodata. */
|
||||
const size_t read_size = mi.size >= sizeof(g_last_rodata_pages) ? sizeof(g_last_rodata_pages) : (sizeof(g_last_rodata_pages) / 2);
|
||||
if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast<uintptr_t>(g_last_rodata_pages), this->debug_handle, mi.addr + mi.size - read_size, read_size))) {
|
||||
if (R_FAILED(svc::ReadDebugProcessMemory(reinterpret_cast<uintptr_t>(g_last_rodata_pages), this->debug_handle, mi.base_address + mi.size - read_size, read_size))) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -198,14 +198,14 @@ namespace ams::creport {
|
||||
/* Check if sp points into the stack. */
|
||||
if (mi.state != svc::MemoryState_Stack) {
|
||||
/* It's possible that sp is below the stack... */
|
||||
if (R_FAILED(svc::QueryDebugProcessMemory(&mi, &pi, debug_handle, mi.addr + mi.size)) || mi.state != svc::MemoryState_Stack) {
|
||||
if (R_FAILED(svc::QueryDebugProcessMemory(&mi, &pi, debug_handle, mi.base_address + mi.size)) || mi.state != svc::MemoryState_Stack) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Save stack extents. */
|
||||
this->stack_bottom = mi.addr;
|
||||
this->stack_top = mi.addr + mi.size;
|
||||
this->stack_bottom = mi.base_address;
|
||||
this->stack_top = mi.base_address + mi.size;
|
||||
|
||||
/* We always want to dump 0x100 of stack, starting from the lowest 0x10-byte aligned address below the stack pointer. */
|
||||
/* Note: if the stack pointer is below the stack bottom, we will start dumping from the stack bottom. */
|
||||
|
||||
@@ -166,7 +166,7 @@ namespace ams::dmnt {
|
||||
svc::MemoryInfo memory_info;
|
||||
svc::PageInfo page_info;
|
||||
if (R_SUCCEEDED(svc::QueryDebugProcessMemory(std::addressof(memory_info), std::addressof(page_info), m_debug_handle, address))) {
|
||||
if (memory_info.perm == svc::MemoryPermission_ReadExecute && (memory_info.state == svc::MemoryState_Code || memory_info.state == svc::MemoryState_AliasCode)) {
|
||||
if (memory_info.permission == svc::MemoryPermission_ReadExecute && (memory_info.state == svc::MemoryState_Code || memory_info.state == svc::MemoryState_AliasCode)) {
|
||||
/* Check that we can add the module. */
|
||||
AMS_ABORT_UNLESS(m_module_count < ModuleCountMax);
|
||||
|
||||
@@ -174,7 +174,7 @@ namespace ams::dmnt {
|
||||
auto &module = m_module_definitions[m_module_count++];
|
||||
|
||||
/* Set module address/size. */
|
||||
module.SetAddressSize(memory_info.addr, memory_info.size);
|
||||
module.SetAddressSize(memory_info.base_address, memory_info.size);
|
||||
|
||||
/* Get module name buffer. */
|
||||
char *module_name = module.GetNameBuffer();
|
||||
@@ -186,7 +186,7 @@ namespace ams::dmnt {
|
||||
s32 path_length;
|
||||
char path[ModuleDefinition::PathLengthMax];
|
||||
} module_path;
|
||||
if (R_SUCCEEDED(this->ReadMemory(std::addressof(module_path), memory_info.addr + memory_info.size, sizeof(module_path)))) {
|
||||
if (R_SUCCEEDED(this->ReadMemory(std::addressof(module_path), memory_info.base_address + memory_info.size, sizeof(module_path)))) {
|
||||
if (module_path.zero == 0 && module_path.path_length == util::Strnlen(module_path.path, sizeof(module_path.path))) {
|
||||
std::memcpy(module_name, module_path.path, ModuleDefinition::PathLengthMax);
|
||||
}
|
||||
@@ -198,7 +198,7 @@ namespace ams::dmnt {
|
||||
}
|
||||
|
||||
/* Check if we're done. */
|
||||
const uintptr_t next_address = memory_info.addr + memory_info.size;
|
||||
const uintptr_t next_address = memory_info.base_address + memory_info.size;
|
||||
if (memory_info.state == svc::MemoryState_Inaccessible) {
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -360,11 +360,11 @@ namespace ams::dmnt::cheat::impl {
|
||||
break;
|
||||
}
|
||||
|
||||
if (mem_info.perm != svc::MemoryPermission_None) {
|
||||
if (mem_info.permission != svc::MemoryPermission_None) {
|
||||
count++;
|
||||
}
|
||||
|
||||
address = mem_info.addr + mem_info.size;
|
||||
address = mem_info.base_address + mem_info.size;
|
||||
} while (address != 0);
|
||||
|
||||
*out_count = count;
|
||||
@@ -384,14 +384,14 @@ namespace ams::dmnt::cheat::impl {
|
||||
break;
|
||||
}
|
||||
|
||||
if (mem_info.perm != svc::MemoryPermission_None) {
|
||||
if (mem_info.permission != svc::MemoryPermission_None) {
|
||||
if (offset <= total_count && written_count < max_count) {
|
||||
mappings[written_count++] = mem_info;
|
||||
}
|
||||
total_count++;
|
||||
}
|
||||
|
||||
address = mem_info.addr + mem_info.size;
|
||||
address = mem_info.base_address + mem_info.size;
|
||||
} while (address != 0 && written_count < max_count);
|
||||
|
||||
*out_count = written_count;
|
||||
|
||||
@@ -159,23 +159,23 @@ namespace ams::fatal::srv {
|
||||
bool TryGuessBaseAddress(u64 *out_base_address, os::NativeHandle debug_handle, u64 guess) {
|
||||
svc::MemoryInfo mi;
|
||||
svc::PageInfo pi;
|
||||
if (R_FAILED(svc::QueryDebugProcessMemory(&mi, &pi, debug_handle, guess)) || mi.perm != svc::MemoryPermission_ReadExecute) {
|
||||
if (R_FAILED(svc::QueryDebugProcessMemory(&mi, &pi, debug_handle, guess)) || mi.permission != svc::MemoryPermission_ReadExecute) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Iterate backwards until we find the memory before the code region. */
|
||||
while (mi.addr > 0) {
|
||||
while (mi.base_address > 0) {
|
||||
if (R_FAILED(svc::QueryDebugProcessMemory(&mi, &pi, debug_handle, guess))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (mi.state == svc::MemoryState_Free) {
|
||||
/* Code region will be at the end of the unmapped region preceding it. */
|
||||
*out_base_address = mi.addr + mi.size;
|
||||
*out_base_address = mi.base_address + mi.size;
|
||||
return true;
|
||||
}
|
||||
|
||||
guess = mi.addr - 4;
|
||||
guess = mi.base_address - 4;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
||||
@@ -411,17 +411,17 @@ namespace ams::ldr {
|
||||
R_ABORT_UNLESS(svc::QueryMemory(std::addressof(mem_info), std::addressof(page_info), address));
|
||||
|
||||
/* If the memory range is free and big enough, use it. */
|
||||
if (mem_info.state == svc::MemoryState_Free && mapping_size <= ((mem_info.addr + mem_info.size) - address)) {
|
||||
if (mem_info.state == svc::MemoryState_Free && mapping_size <= ((mem_info.base_address + mem_info.size) - address)) {
|
||||
*out = address;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
/* Check that we can advance. */
|
||||
R_UNLESS(address < mem_info.addr + mem_info.size, svc::ResultOutOfMemory());
|
||||
R_UNLESS(mem_info.addr + mem_info.size - 1 < aslr_start + aslr_size - 1, svc::ResultOutOfMemory());
|
||||
R_UNLESS(address < mem_info.base_address + mem_info.size, svc::ResultOutOfMemory());
|
||||
R_UNLESS(mem_info.base_address + mem_info.size - 1 < aslr_start + aslr_size - 1, svc::ResultOutOfMemory());
|
||||
|
||||
/* Advance. */
|
||||
address = mem_info.addr + mem_info.size;
|
||||
address = mem_info.base_address + mem_info.size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -66,17 +66,17 @@ namespace ams::ro::impl {
|
||||
R_ABORT_UNLESS(svc::QueryMemory(std::addressof(mem_info), std::addressof(page_info), address));
|
||||
|
||||
/* If the memory range is free and big enough, use it. */
|
||||
if (mem_info.state == svc::MemoryState_Free && mapping_size <= ((mem_info.addr + mem_info.size) - address)) {
|
||||
if (mem_info.state == svc::MemoryState_Free && mapping_size <= ((mem_info.base_address + mem_info.size) - address)) {
|
||||
*out = address;
|
||||
return ResultSuccess();
|
||||
}
|
||||
|
||||
/* Check that we can advance. */
|
||||
R_UNLESS(address < mem_info.addr + mem_info.size, ro::ResultOutOfAddressSpace());
|
||||
R_UNLESS(mem_info.addr + mem_info.size - 1 < aslr_start + aslr_size - 1, ro::ResultOutOfAddressSpace());
|
||||
R_UNLESS(address < mem_info.base_address + mem_info.size, ro::ResultOutOfAddressSpace());
|
||||
R_UNLESS(mem_info.base_address + mem_info.size - 1 < aslr_start + aslr_size - 1, ro::ResultOutOfAddressSpace());
|
||||
|
||||
/* Advance. */
|
||||
address = mem_info.addr + mem_info.size;
|
||||
address = mem_info.base_address + mem_info.size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -77,13 +77,13 @@ namespace ams::ro::impl {
|
||||
|
||||
/* Check for guard availability before the region. */
|
||||
R_ABORT_UNLESS(svc::QueryProcessMemory(std::addressof(mem_info), std::addressof(page_info), process, address - 1));
|
||||
if (!(mem_info.state == svc::MemoryState_Free && mem_info.addr <= address - StackGuardSize)) {
|
||||
if (!(mem_info.state == svc::MemoryState_Free && mem_info.base_address <= address - StackGuardSize)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check for guard availability after the region. */
|
||||
R_ABORT_UNLESS(svc::QueryProcessMemory(std::addressof(mem_info), std::addressof(page_info), process, address + size));
|
||||
if (!(mem_info.state == svc::MemoryState_Free && address + size + StackGuardSize <= mem_info.addr + mem_info.size)) {
|
||||
if (!(mem_info.state == svc::MemoryState_Free && address + size + StackGuardSize <= mem_info.base_address + mem_info.size)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user