svc: populate namespace

This commit is contained in:
Michael Scire
2020-01-17 20:11:03 -08:00
parent 7806766a59
commit 3a91a6b786
23 changed files with 1258 additions and 273 deletions

View File

@@ -125,12 +125,10 @@ namespace ams::boot {
std::memset(g_frame_buffer, 0x00, FrameBufferSize);
armDCacheFlush(g_frame_buffer, FrameBufferSize);
constexpr u64 DeviceName_DC = 2;
/* Create Address Space. */
R_ASSERT(svcCreateDeviceAddressSpace(&g_dc_das_hnd, 0, (1ul << 32)));
/* Attach it to the DC. */
R_ASSERT(svcAttachDeviceAddressSpace(DeviceName_DC, g_dc_das_hnd));
R_ASSERT(svcAttachDeviceAddressSpace(svc::DeviceName_Dc, g_dc_das_hnd));
/* Map the framebuffer for the DC as read-only. */
R_ASSERT(svcMapDeviceAddressSpaceAligned(g_dc_das_hnd, dd::GetCurrentProcessHandle(), frame_buffer_aligned, FrameBufferSize, FrameBufferPaddr, 1));
@@ -140,12 +138,11 @@ namespace ams::boot {
void FinalizeFrameBuffer() {
if (g_frame_buffer != nullptr) {
const uintptr_t frame_buffer_aligned = reinterpret_cast<uintptr_t>(g_frame_buffer);
constexpr u64 DeviceName_DC = 2;
/* Unmap the framebuffer from the DC. */
R_ASSERT(svcUnmapDeviceAddressSpace(g_dc_das_hnd, dd::GetCurrentProcessHandle(), frame_buffer_aligned, FrameBufferSize, FrameBufferPaddr));
/* Detach address space from the DC. */
R_ASSERT(svcDetachDeviceAddressSpace(DeviceName_DC, g_dc_das_hnd));
R_ASSERT(svcDetachDeviceAddressSpace(svc::DeviceName_Dc, g_dc_das_hnd));
/* Close the address space. */
R_ASSERT(svcCloseHandle(g_dc_das_hnd));
g_dc_das_hnd = INVALID_HANDLE;

View File

@@ -24,6 +24,8 @@ namespace ams::creport {
/* Convenience definitions. */
constexpr size_t DyingMessageAddressOffset = 0x1C0;
static_assert(DyingMessageAddressOffset == OFFSETOF(ams::svc::aarch64::ProcessLocalRegion, dying_message_region_address));
static_assert(DyingMessageAddressOffset == OFFSETOF(ams::svc::aarch32::ProcessLocalRegion, dying_message_region_address));
/* Helper functions. */
bool TryGetCurrentTimestamp(u64 *out) {
@@ -53,27 +55,27 @@ namespace ams::creport {
mkdir("sdmc:/atmosphere/fatal_reports/dumps", S_IRWXU);
}
constexpr const char *GetDebugExceptionTypeString(const svc::DebugExceptionType type) {
constexpr const char *GetDebugExceptionString(const svc::DebugException type) {
switch (type) {
case svc::DebugExceptionType::UndefinedInstruction:
case svc::DebugException_UndefinedInstruction:
return "Undefined Instruction";
case svc::DebugExceptionType::InstructionAbort:
case svc::DebugException_InstructionAbort:
return "Instruction Abort";
case svc::DebugExceptionType::DataAbort:
case svc::DebugException_DataAbort:
return "Data Abort";
case svc::DebugExceptionType::AlignmentFault:
case svc::DebugException_AlignmentFault:
return "Alignment Fault";
case svc::DebugExceptionType::DebuggerAttached:
case svc::DebugException_DebuggerAttached:
return "Debugger Attached";
case svc::DebugExceptionType::BreakPoint:
case svc::DebugException_BreakPoint:
return "Break Point";
case svc::DebugExceptionType::UserBreak:
case svc::DebugException_UserBreak:
return "User Break";
case svc::DebugExceptionType::DebuggerBreak:
case svc::DebugException_DebuggerBreak:
return "Debugger Break";
case svc::DebugExceptionType::UndefinedSystemCall:
case svc::DebugException_UndefinedSystemCall:
return "Undefined System Call";
case svc::DebugExceptionType::SystemMemoryError:
case svc::DebugException_MemorySystemError:
return "System Memory Error";
default:
return "Unknown";
@@ -147,17 +149,17 @@ namespace ams::creport {
svc::DebugEventInfo d;
while (R_SUCCEEDED(svcGetDebugEvent(reinterpret_cast<u8 *>(&d), this->debug_handle))) {
switch (d.type) {
case svc::DebugEventType::AttachProcess:
case svc::DebugEvent_AttachProcess:
this->HandleDebugEventInfoAttachProcess(d);
break;
case svc::DebugEventType::AttachThread:
case svc::DebugEvent_AttachThread:
this->HandleDebugEventInfoAttachThread(d);
break;
case svc::DebugEventType::Exception:
case svc::DebugEvent_Exception:
this->HandleDebugEventInfoException(d);
break;
case svc::DebugEventType::ExitProcess:
case svc::DebugEventType::ExitThread:
case svc::DebugEvent_ExitProcess:
case svc::DebugEvent_ExitThread:
break;
}
}
@@ -208,34 +210,34 @@ namespace ams::creport {
void CrashReport::HandleDebugEventInfoException(const svc::DebugEventInfo &d) {
switch (d.info.exception.type) {
case svc::DebugExceptionType::UndefinedInstruction:
case svc::DebugException_UndefinedInstruction:
this->result = ResultUndefinedInstruction();
break;
case svc::DebugExceptionType::InstructionAbort:
case svc::DebugException_InstructionAbort:
this->result = ResultInstructionAbort();
break;
case svc::DebugExceptionType::DataAbort:
case svc::DebugException_DataAbort:
this->result = ResultDataAbort();
break;
case svc::DebugExceptionType::AlignmentFault:
case svc::DebugException_AlignmentFault:
this->result = ResultAlignmentFault();
break;
case svc::DebugExceptionType::UserBreak:
case svc::DebugException_UserBreak:
this->result = ResultUserBreak();
/* Try to parse out the user break result. */
if (hos::GetVersion() >= hos::Version_500) {
svcReadDebugProcessMemory(&this->result, this->debug_handle, d.info.exception.specific.user_break.address, sizeof(this->result));
}
break;
case svc::DebugExceptionType::UndefinedSystemCall:
case svc::DebugException_UndefinedSystemCall:
this->result = ResultUndefinedSystemCall();
break;
case svc::DebugExceptionType::SystemMemoryError:
this->result = ResultSystemMemoryError();
case svc::DebugException_MemorySystemError:
this->result = ResultMemorySystemError();
break;
case svc::DebugExceptionType::DebuggerAttached:
case svc::DebugExceptionType::BreakPoint:
case svc::DebugExceptionType::DebuggerBreak:
case svc::DebugException_DebuggerAttached:
case svc::DebugException_BreakPoint:
case svc::DebugException_DebuggerBreak:
return;
}
@@ -320,22 +322,22 @@ namespace ams::creport {
/* Exception Info. */
fprintf(f_report, "Exception Info:\n");
fprintf(f_report, " Type: %s\n", GetDebugExceptionTypeString(this->exception_info.type));
fprintf(f_report, " Type: %s\n", GetDebugExceptionString(this->exception_info.type));
fprintf(f_report, " Address: %s\n", this->module_list.GetFormattedAddressString(this->exception_info.address));
switch (this->exception_info.type) {
case svc::DebugExceptionType::UndefinedInstruction:
case svc::DebugException_UndefinedInstruction:
fprintf(f_report, " Opcode: %08x\n", this->exception_info.specific.undefined_instruction.insn);
break;
case svc::DebugExceptionType::DataAbort:
case svc::DebugExceptionType::AlignmentFault:
case svc::DebugException_DataAbort:
case svc::DebugException_AlignmentFault:
if (this->exception_info.specific.raw != this->exception_info.address) {
fprintf(f_report, " Fault Address: %s\n", this->module_list.GetFormattedAddressString(this->exception_info.specific.raw));
}
break;
case svc::DebugExceptionType::UndefinedSystemCall:
case svc::DebugException_UndefinedSystemCall:
fprintf(f_report, " Svc Id: 0x%02x\n", this->exception_info.specific.undefined_system_call.id);
break;
case svc::DebugExceptionType::UserBreak:
case svc::DebugException_UserBreak:
fprintf(f_report, " Break Reason: 0x%x\n", this->exception_info.specific.user_break.break_reason);
fprintf(f_report, " Break Address: %s\n", this->module_list.GetFormattedAddressString(this->exception_info.specific.user_break.address));
fprintf(f_report, " Break Size: 0x%lx\n", this->exception_info.specific.user_break.size);

View File

@@ -66,7 +66,7 @@ namespace ams::creport {
}
bool IsUserBreak() const {
return this->exception_info.type == svc::DebugExceptionType::UserBreak;
return this->exception_info.type == svc::DebugException_UserBreak;
}
bool OpenProcess(os::ProcessId process_id) {

View File

@@ -125,7 +125,7 @@ namespace ams::creport {
}
const svc::ThreadState thread_state = static_cast<svc::ThreadState>(_thread_state);
if (thread_state != svc::ThreadState::Waiting && thread_state != svc::ThreadState::Running) {
if (thread_state != svc::ThreadState_Waiting && thread_state != svc::ThreadState_Running) {
return false;
}
}

View File

@@ -54,7 +54,7 @@ namespace ams::dmnt::cheat::impl {
size_t target_core = NumCores - 1;
/* Retrieve correct core for new thread event. */
if (dbg_event.type == svc::DebugEventType::AttachThread) {
if (dbg_event.type == svc::DebugEvent_AttachThread) {
u64 out64 = 0;
u32 out32 = 0;
R_ASSERT(svcGetDebugThreadParam(&out64, &out32, debug_handle, dbg_event.info.attach_thread.thread_id, DebugThreadParam_CurrentCore));
@@ -109,7 +109,7 @@ namespace ams::dmnt::cheat::impl {
svc::DebugEventInfo d;
size_t target_core = NumCores - 1;
while (R_SUCCEEDED(svcGetDebugEvent(reinterpret_cast<u8 *>(&d), cheat_dbg_hnd))) {
if (d.type == svc::DebugEventType::AttachThread) {
if (d.type == svc::DebugEvent_AttachThread) {
target_core = GetTargetCore(d, cheat_dbg_hnd);
}
}

View File

@@ -37,7 +37,7 @@ namespace ams::fatal::srv {
}
const svc::ThreadState thread_state = static_cast<svc::ThreadState>(_thread_state);
if (thread_state != svc::ThreadState::Waiting && thread_state != svc::ThreadState::Running) {
if (thread_state != svc::ThreadState_Waiting && thread_state != svc::ThreadState_Running) {
return false;
}
}
@@ -181,17 +181,17 @@ namespace ams::fatal::srv {
svc::DebugEventInfo d;
while (R_SUCCEEDED(svcGetDebugEvent(reinterpret_cast<u8 *>(&d), debug_handle.Get()))) {
switch (d.type) {
case svc::DebugEventType::AttachProcess:
case svc::DebugEvent_AttachProcess:
ctx->cpu_ctx.architecture = (d.info.attach_process.flags & 1) ? CpuContext::Architecture_Aarch64 : CpuContext::Architecture_Aarch32;
std::memcpy(ctx->proc_name, d.info.attach_process.name, sizeof(d.info.attach_process.name));
got_attach_process = true;
break;
case svc::DebugEventType::AttachThread:
case svc::DebugEvent_AttachThread:
thread_id_to_tls[d.info.attach_thread.thread_id] = d.info.attach_thread.tls_address;
break;
case svc::DebugEventType::Exception:
case svc::DebugEventType::ExitProcess:
case svc::DebugEventType::ExitThread:
case svc::DebugEvent_Exception:
case svc::DebugEvent_ExitProcess:
case svc::DebugEvent_ExitThread:
break;
}
}

View File

@@ -68,18 +68,6 @@ namespace ams::ldr {
return NsoNames[idx];
}
struct CreateProcessInfo {
char name[12];
u32 version;
ncm::ProgramId program_id;
u64 code_address;
u32 code_num_pages;
u32 flags;
Handle reslimit;
u32 system_resource_num_pages;
};
static_assert(sizeof(CreateProcessInfo) == 0x30, "CreateProcessInfo definition!");
struct ProcessInfo {
os::ManagedHandle process_handle;
uintptr_t args_address;
@@ -310,14 +298,14 @@ namespace ams::ldr {
return ResultSuccess();
}
Result GetCreateProcessInfo(CreateProcessInfo *out, const Meta *meta, u32 flags, Handle reslimit_h) {
Result GetCreateProcessParameter(svc::CreateProcessParameter *out, const Meta *meta, u32 flags, Handle reslimit_h) {
/* Clear output. */
std::memset(out, 0, sizeof(*out));
/* Set name, version, program id, resource limit handle. */
std::memcpy(out->name, meta->npdm->program_name, sizeof(out->name) - 1);
out->version = meta->npdm->version;
out->program_id = meta->aci->program_id;
out->program_id = static_cast<u64>(meta->aci->program_id);
out->reslimit = reslimit_h;
/* Set flags. */
@@ -345,7 +333,7 @@ namespace ams::ldr {
return ResultSuccess();
}
Result DecideAddressSpaceLayout(ProcessInfo *out, CreateProcessInfo *out_cpi, const NsoHeader *nso_headers, const bool *has_nso, const args::ArgumentInfo *arg_info) {
Result DecideAddressSpaceLayout(ProcessInfo *out, svc::CreateProcessParameter *out_param, const NsoHeader *nso_headers, const bool *has_nso, const args::ArgumentInfo *arg_info) {
/* Clear output. */
out->args_address = 0;
out->args_size = 0;
@@ -381,7 +369,7 @@ namespace ams::ldr {
uintptr_t aslr_start = 0;
uintptr_t aslr_size = 0;
if (hos::GetVersion() >= hos::Version_200) {
switch (out_cpi->flags & svc::CreateProcessFlag_AddressSpaceMask) {
switch (out_param->flags & svc::CreateProcessFlag_AddressSpaceMask) {
case svc::CreateProcessFlag_AddressSpace32Bit:
case svc::CreateProcessFlag_AddressSpace32BitWithoutAlias:
aslr_start = map::AslrBase32Bit;
@@ -399,7 +387,7 @@ namespace ams::ldr {
}
} else {
/* On 1.0.0, only 2 address space types existed. */
if (out_cpi->flags & svc::CreateProcessFlag_AddressSpace64BitDeprecated) {
if (out_param->flags & svc::CreateProcessFlag_AddressSpace64BitDeprecated) {
aslr_start = map::AslrBase64BitDeprecated;
aslr_size = map::AslrSize64BitDeprecated;
} else {
@@ -412,7 +400,7 @@ namespace ams::ldr {
/* Set Create Process output. */
uintptr_t aslr_slide = 0;
uintptr_t free_size = (aslr_size - total_size);
if (out_cpi->flags & svc::CreateProcessFlag_EnableAslr) {
if (out_param->flags & svc::CreateProcessFlag_EnableAslr) {
/* Nintendo uses MT19937 (not os::GenerateRandomBytes), but we'll just use TinyMT for now. */
aslr_slide = os::GenerateRandomU64(free_size / os::MemoryBlockUnitSize) * os::MemoryBlockUnitSize;
}
@@ -428,22 +416,22 @@ namespace ams::ldr {
out->args_address += aslr_start;
}
out_cpi->code_address = aslr_start;
out_cpi->code_num_pages = total_size >> 12;
out_param->code_address = aslr_start;
out_param->code_num_pages = total_size >> 12;
return ResultSuccess();
}
Result CreateProcessImpl(ProcessInfo *out, const Meta *meta, const NsoHeader *nso_headers, const bool *has_nso, const args::ArgumentInfo *arg_info, u32 flags, Handle reslimit_h) {
/* Get CreateProcessInfo. */
CreateProcessInfo cpi;
R_TRY(GetCreateProcessInfo(&cpi, meta, flags, reslimit_h));
/* Get CreateProcessParameter. */
svc::CreateProcessParameter param;
R_TRY(GetCreateProcessParameter(&param, meta, flags, reslimit_h));
/* Decide on an NSO layout. */
R_TRY(DecideAddressSpaceLayout(out, &cpi, nso_headers, has_nso, arg_info));
R_TRY(DecideAddressSpaceLayout(out, &param, nso_headers, has_nso, arg_info));
/* Actually create process. const_cast necessary because libnx doesn't declare svcCreateProcess with const u32*. */
return svcCreateProcess(out->process_handle.GetPointer(), &cpi, reinterpret_cast<const u32 *>(meta->aci_kac), meta->aci->kac_size / sizeof(u32));
return svcCreateProcess(out->process_handle.GetPointer(), &param, reinterpret_cast<const u32 *>(meta->aci_kac), meta->aci->kac_size / sizeof(u32));
}
Result LoadNsoSegment(FILE *f, const NsoHeader::SegmentInfo *segment, size_t file_size, const u8 *file_hash, bool is_compressed, bool check_hash, uintptr_t map_base, uintptr_t map_end) {

View File

@@ -93,7 +93,7 @@ namespace {
svc::DebugEventInfo d;
while (true) {
R_ASSERT(svcGetDebugEvent(reinterpret_cast<u8 *>(&d), debug_handle.Get()));
if (d.type == svc::DebugEventType::AttachProcess) {
if (d.type == svc::DebugEvent_AttachProcess) {
return ncm::ProgramId{d.info.attach_process.program_id};
}
}

View File

@@ -137,13 +137,12 @@ namespace ams::spl::impl {
}
void InitializeDeviceAddressSpace() {
constexpr u64 DeviceName_SE = 29;
/* Create Address Space. */
R_ASSERT(svcCreateDeviceAddressSpace(&g_se_das_hnd, 0, (1ul << 32)));
/* Attach it to the SE. */
R_ASSERT(svcAttachDeviceAddressSpace(DeviceName_SE, g_se_das_hnd));
R_ASSERT(svcAttachDeviceAddressSpace(svc::DeviceName_Se, g_se_das_hnd));
const u64 work_buffer_addr = reinterpret_cast<u64>(g_work_buffer);
g_se_mapped_work_buffer_addr = WorkBufferMapBase + (work_buffer_addr % DeviceAddressSpaceAlign);