aboutsummaryrefslogtreecommitdiff
path: root/src/core/hle/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel')
-rw-r--r--src/core/hle/kernel/address_arbiter.cpp2
-rw-r--r--src/core/hle/kernel/process.cpp10
-rw-r--r--src/core/hle/kernel/process.h21
-rw-r--r--src/core/hle/kernel/svc.cpp54
-rw-r--r--src/core/hle/kernel/svc.h4
-rw-r--r--src/core/hle/kernel/svc_wrap.h8
-rw-r--r--src/core/hle/kernel/thread.cpp16
-rw-r--r--src/core/hle/kernel/vm_manager.cpp35
-rw-r--r--src/core/hle/kernel/vm_manager.h12
9 files changed, 115 insertions, 47 deletions
diff --git a/src/core/hle/kernel/address_arbiter.cpp b/src/core/hle/kernel/address_arbiter.cpp
index ebf193930..57157beb4 100644
--- a/src/core/hle/kernel/address_arbiter.cpp
+++ b/src/core/hle/kernel/address_arbiter.cpp
@@ -39,7 +39,7 @@ static std::vector<SharedPtr<Thread>> GetThreadsWaitingOnAddress(VAddr address)
std::vector<SharedPtr<Thread>>& waiting_threads,
VAddr arb_addr) {
const auto& scheduler = Core::System::GetInstance().Scheduler(core_index);
- const auto& thread_list = scheduler->GetThreadList();
+ const auto& thread_list = scheduler.GetThreadList();
for (const auto& thread : thread_list) {
if (thread->GetArbiterWaitAddress() == arb_addr)
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp
index c80b2c507..073dd5a7d 100644
--- a/src/core/hle/kernel/process.cpp
+++ b/src/core/hle/kernel/process.cpp
@@ -153,11 +153,11 @@ void Process::PrepareForTermination() {
}
};
- auto& system = Core::System::GetInstance();
- stop_threads(system.Scheduler(0)->GetThreadList());
- stop_threads(system.Scheduler(1)->GetThreadList());
- stop_threads(system.Scheduler(2)->GetThreadList());
- stop_threads(system.Scheduler(3)->GetThreadList());
+ const auto& system = Core::System::GetInstance();
+ stop_threads(system.Scheduler(0).GetThreadList());
+ stop_threads(system.Scheduler(1).GetThreadList());
+ stop_threads(system.Scheduler(2).GetThreadList());
+ stop_threads(system.Scheduler(3).GetThreadList());
}
/**
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h
index 73ec01e11..f2816943a 100644
--- a/src/core/hle/kernel/process.h
+++ b/src/core/hle/kernel/process.h
@@ -24,6 +24,7 @@ class ProgramMetadata;
namespace Kernel {
class KernelCore;
+class ResourceLimit;
struct AddressMapping {
// Address and size must be page-aligned
@@ -57,9 +58,23 @@ union ProcessFlags {
BitField<12, 1, u16> loaded_high; ///< Application loaded high (not at 0x00100000).
};
-enum class ProcessStatus { Created, Running, Exited };
-
-class ResourceLimit;
+/**
+ * Indicates the status of a Process instance.
+ *
+ * @note These match the values as used by kernel,
+ * so new entries should only be added if RE
+ * shows that a new value has been introduced.
+ */
+enum class ProcessStatus {
+ Created,
+ CreatedWithDebuggerAttached,
+ Running,
+ WaitingForDebuggerToAttach,
+ DebuggerAttached,
+ Exiting,
+ Exited,
+ DebugBreak,
+};
struct CodeSet final {
struct Segment {
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index e406df829..d08b84bde 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -389,6 +389,12 @@ static void Break(u32 reason, u64 info1, u64 info2) {
"Emulated program broke execution! reason=0x{:016X}, info1=0x{:016X}, info2=0x{:016X}",
reason, info1, info2);
ASSERT(false);
+
+ Core::CurrentProcess()->PrepareForTermination();
+
+ // Kill the current thread
+ GetCurrentThread()->Stop();
+ Core::System::GetInstance().PrepareReschedule();
}
}
@@ -442,25 +448,12 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
case GetInfoType::RandomEntropy:
*result = 0;
break;
- case GetInfoType::AddressSpaceBaseAddr:
- *result = vm_manager.GetCodeRegionBaseAddress();
+ case GetInfoType::ASLRRegionBaseAddr:
+ *result = vm_manager.GetASLRRegionBaseAddress();
break;
- case GetInfoType::AddressSpaceSize: {
- const u64 width = vm_manager.GetAddressSpaceWidth();
-
- switch (width) {
- case 32:
- *result = 0xFFE00000;
- break;
- case 36:
- *result = 0xFF8000000;
- break;
- case 39:
- *result = 0x7FF8000000;
- break;
- }
+ case GetInfoType::ASLRRegionSize:
+ *result = vm_manager.GetASLRRegionSize();
break;
- }
case GetInfoType::NewMapRegionBaseAddr:
*result = vm_manager.GetNewMapRegionBaseAddress();
break;
@@ -803,7 +796,7 @@ static ResultCode SignalProcessWideKey(VAddr condition_variable_addr, s32 target
std::vector<SharedPtr<Thread>>& waiting_threads,
VAddr condvar_addr) {
const auto& scheduler = Core::System::GetInstance().Scheduler(core_index);
- const auto& thread_list = scheduler->GetThreadList();
+ const auto& thread_list = scheduler.GetThreadList();
for (const auto& thread : thread_list) {
if (thread->GetCondVarWaitAddress() == condvar_addr)
@@ -1092,6 +1085,29 @@ static ResultCode ClearEvent(Handle handle) {
return RESULT_SUCCESS;
}
+static ResultCode GetProcessInfo(u64* out, Handle process_handle, u32 type) {
+ LOG_DEBUG(Kernel_SVC, "called, handle=0x{:08X}, type=0x{:X}", process_handle, type);
+
+ // This function currently only allows retrieving a process' status.
+ enum class InfoType {
+ Status,
+ };
+
+ const auto& kernel = Core::System::GetInstance().Kernel();
+ const auto process = kernel.HandleTable().Get<Process>(process_handle);
+ if (!process) {
+ return ERR_INVALID_HANDLE;
+ }
+
+ const auto info_type = static_cast<InfoType>(type);
+ if (info_type != InfoType::Status) {
+ return ERR_INVALID_ENUM_VALUE;
+ }
+
+ *out = static_cast<u64>(process->GetStatus());
+ return RESULT_SUCCESS;
+}
+
namespace {
struct FunctionDef {
using Func = void();
@@ -1227,7 +1243,7 @@ static const FunctionDef SVC_Table[] = {
{0x79, nullptr, "CreateProcess"},
{0x7A, nullptr, "StartProcess"},
{0x7B, nullptr, "TerminateProcess"},
- {0x7C, nullptr, "GetProcessInfo"},
+ {0x7C, SvcWrap<GetProcessInfo>, "GetProcessInfo"},
{0x7D, nullptr, "CreateResourceLimit"},
{0x7E, nullptr, "SetResourceLimitLimitValue"},
{0x7F, nullptr, "CallSecureMonitor"},
diff --git a/src/core/hle/kernel/svc.h b/src/core/hle/kernel/svc.h
index 70148c4fe..554a5e328 100644
--- a/src/core/hle/kernel/svc.h
+++ b/src/core/hle/kernel/svc.h
@@ -41,8 +41,8 @@ enum class GetInfoType : u64 {
RandomEntropy = 11,
PerformanceCounter = 0xF0000002,
// 2.0.0+
- AddressSpaceBaseAddr = 12,
- AddressSpaceSize = 13,
+ ASLRRegionBaseAddr = 12,
+ ASLRRegionSize = 13,
NewMapRegionBaseAddr = 14,
NewMapRegionSize = 15,
// 3.0.0+
diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h
index cbb80c3c4..b09753c80 100644
--- a/src/core/hle/kernel/svc_wrap.h
+++ b/src/core/hle/kernel/svc_wrap.h
@@ -77,6 +77,14 @@ void SvcWrap() {
FuncReturn(retval);
}
+template <ResultCode func(u64*, u32, u32)>
+void SvcWrap() {
+ u64 param_1 = 0;
+ u32 retval = func(&param_1, static_cast<u32>(Param(1)), static_cast<u32>(Param(2))).raw;
+ Core::CurrentArmInterface().SetReg(1, param_1);
+ FuncReturn(retval);
+}
+
template <ResultCode func(u32, u64)>
void SvcWrap() {
FuncReturn(func(static_cast<u32>(Param(0)), Param(1)).raw);
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index 352ce1725..35ec98c1a 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -97,7 +97,7 @@ void Thread::CancelWakeupTimer() {
static boost::optional<s32> GetNextProcessorId(u64 mask) {
for (s32 index = 0; index < Core::NUM_CPU_CORES; ++index) {
if (mask & (1ULL << index)) {
- if (!Core::System::GetInstance().Scheduler(index)->GetCurrentThread()) {
+ if (!Core::System::GetInstance().Scheduler(index).GetCurrentThread()) {
// Core is enabled and not running any threads, use this one
return index;
}
@@ -147,14 +147,14 @@ void Thread::ResumeFromWait() {
new_processor_id = processor_id;
}
if (ideal_core != -1 &&
- Core::System::GetInstance().Scheduler(ideal_core)->GetCurrentThread() == nullptr) {
+ Core::System::GetInstance().Scheduler(ideal_core).GetCurrentThread() == nullptr) {
new_processor_id = ideal_core;
}
ASSERT(*new_processor_id < 4);
// Add thread to new core's scheduler
- auto& next_scheduler = Core::System::GetInstance().Scheduler(*new_processor_id);
+ auto* next_scheduler = &Core::System::GetInstance().Scheduler(*new_processor_id);
if (*new_processor_id != processor_id) {
// Remove thread from previous core's scheduler
@@ -169,7 +169,7 @@ void Thread::ResumeFromWait() {
next_scheduler->ScheduleThread(this, current_priority);
// Change thread's scheduler
- scheduler = next_scheduler.get();
+ scheduler = next_scheduler;
Core::System::GetInstance().CpuCore(processor_id).PrepareReschedule();
}
@@ -230,7 +230,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(KernelCore& kernel, std::string name
thread->name = std::move(name);
thread->callback_handle = kernel.ThreadWakeupCallbackHandleTable().Create(thread).Unwrap();
thread->owner_process = &owner_process;
- thread->scheduler = Core::System::GetInstance().Scheduler(processor_id).get();
+ thread->scheduler = &Core::System::GetInstance().Scheduler(processor_id);
thread->scheduler->AddThread(thread, priority);
thread->tls_address = thread->owner_process->MarkNextAvailableTLSSlotAsUsed(*thread);
@@ -375,14 +375,14 @@ void Thread::ChangeCore(u32 core, u64 mask) {
new_processor_id = processor_id;
}
if (ideal_core != -1 &&
- Core::System::GetInstance().Scheduler(ideal_core)->GetCurrentThread() == nullptr) {
+ Core::System::GetInstance().Scheduler(ideal_core).GetCurrentThread() == nullptr) {
new_processor_id = ideal_core;
}
ASSERT(*new_processor_id < 4);
// Add thread to new core's scheduler
- auto& next_scheduler = Core::System::GetInstance().Scheduler(*new_processor_id);
+ auto* next_scheduler = &Core::System::GetInstance().Scheduler(*new_processor_id);
if (*new_processor_id != processor_id) {
// Remove thread from previous core's scheduler
@@ -397,7 +397,7 @@ void Thread::ChangeCore(u32 core, u64 mask) {
next_scheduler->ScheduleThread(this, current_priority);
// Change thread's scheduler
- scheduler = next_scheduler.get();
+ scheduler = next_scheduler;
Core::System::GetInstance().CpuCore(processor_id).PrepareReschedule();
}
diff --git a/src/core/hle/kernel/vm_manager.cpp b/src/core/hle/kernel/vm_manager.cpp
index e412309fd..1e28ccbda 100644
--- a/src/core/hle/kernel/vm_manager.cpp
+++ b/src/core/hle/kernel/vm_manager.cpp
@@ -393,30 +393,35 @@ void VMManager::InitializeMemoryRegionRanges(FileSys::ProgramAddressSpaceType ty
switch (type) {
case FileSys::ProgramAddressSpaceType::Is32Bit:
+ case FileSys::ProgramAddressSpaceType::Is32BitNoMap:
address_space_width = 32;
code_region_base = 0x200000;
code_region_end = code_region_base + 0x3FE00000;
- map_region_size = 0x40000000;
- heap_region_size = 0x40000000;
+ aslr_region_base = 0x200000;
+ aslr_region_end = aslr_region_base + 0xFFE00000;
+ if (type == FileSys::ProgramAddressSpaceType::Is32Bit) {
+ map_region_size = 0x40000000;
+ heap_region_size = 0x40000000;
+ } else {
+ map_region_size = 0;
+ heap_region_size = 0x80000000;
+ }
break;
case FileSys::ProgramAddressSpaceType::Is36Bit:
address_space_width = 36;
code_region_base = 0x8000000;
code_region_end = code_region_base + 0x78000000;
+ aslr_region_base = 0x8000000;
+ aslr_region_end = aslr_region_base + 0xFF8000000;
map_region_size = 0x180000000;
heap_region_size = 0x180000000;
break;
- case FileSys::ProgramAddressSpaceType::Is32BitNoMap:
- address_space_width = 32;
- code_region_base = 0x200000;
- code_region_end = code_region_base + 0x3FE00000;
- map_region_size = 0;
- heap_region_size = 0x80000000;
- break;
case FileSys::ProgramAddressSpaceType::Is39Bit:
address_space_width = 39;
code_region_base = 0x8000000;
code_region_end = code_region_base + 0x80000000;
+ aslr_region_base = 0x8000000;
+ aslr_region_end = aslr_region_base + 0x7FF8000000;
map_region_size = 0x1000000000;
heap_region_size = 0x180000000;
new_map_region_size = 0x80000000;
@@ -490,6 +495,18 @@ u64 VMManager::GetAddressSpaceWidth() const {
return address_space_width;
}
+VAddr VMManager::GetASLRRegionBaseAddress() const {
+ return aslr_region_base;
+}
+
+VAddr VMManager::GetASLRRegionEndAddress() const {
+ return aslr_region_end;
+}
+
+u64 VMManager::GetASLRRegionSize() const {
+ return aslr_region_end - aslr_region_base;
+}
+
VAddr VMManager::GetCodeRegionBaseAddress() const {
return code_region_base;
}
diff --git a/src/core/hle/kernel/vm_manager.h b/src/core/hle/kernel/vm_manager.h
index 015559a64..4accde6b3 100644
--- a/src/core/hle/kernel/vm_manager.h
+++ b/src/core/hle/kernel/vm_manager.h
@@ -205,6 +205,15 @@ public:
/// Gets the address space width in bits.
u64 GetAddressSpaceWidth() const;
+ /// Gets the base address of the ASLR region.
+ VAddr GetASLRRegionBaseAddress() const;
+
+ /// Gets the end address of the ASLR region.
+ VAddr GetASLRRegionEndAddress() const;
+
+ /// Gets the size of the ASLR region
+ u64 GetASLRRegionSize() const;
+
/// Gets the base address of the code region.
VAddr GetCodeRegionBaseAddress() const;
@@ -306,6 +315,9 @@ private:
VAddr address_space_base = 0;
VAddr address_space_end = 0;
+ VAddr aslr_region_base = 0;
+ VAddr aslr_region_end = 0;
+
VAddr code_region_base = 0;
VAddr code_region_end = 0;