@ -2020,6 +2020,46 @@ static ResultCode GetProcessList(u32* out_num_processes, VAddr out_process_ids,
return RESULT_SUCCESS ;
}
ResultCode GetThreadList ( u32 * out_num_threads , VAddr out_thread_ids , u32 out_thread_ids_size ,
Handle debug_handle ) {
// TODO: Handle this case when debug events are supported.
UNIMPLEMENTED_IF ( debug_handle ! = InvalidHandle ) ;
LOG_DEBUG ( Kernel_SVC , " called. out_thread_ids=0x{:016X}, out_thread_ids_size={} " ,
out_thread_ids , out_thread_ids_size ) ;
// If the size is negative or larger than INT32_MAX / sizeof(u64)
if ( ( out_thread_ids_size & 0xF0000000 ) ! = 0 ) {
LOG_ERROR ( Kernel_SVC , " Supplied size outside [0, 0x0FFFFFFF] range. size={} " ,
out_thread_ids_size ) ;
return ERR_OUT_OF_RANGE ;
}
const auto * const current_process = Core : : System : : GetInstance ( ) . Kernel ( ) . CurrentProcess ( ) ;
const auto & vm_manager = current_process - > VMManager ( ) ;
const auto total_copy_size = out_thread_ids_size * sizeof ( u64 ) ;
if ( out_thread_ids_size > 0 & &
! vm_manager . IsWithinAddressSpace ( out_thread_ids , total_copy_size ) ) {
LOG_ERROR ( Kernel_SVC , " Address range outside address space. begin=0x{:016X}, end=0x{:016X} " ,
out_thread_ids , out_thread_ids + total_copy_size ) ;
return ERR_INVALID_ADDRESS_STATE ;
}
const auto & thread_list = current_process - > GetThreadList ( ) ;
const auto num_threads = thread_list . size ( ) ;
const auto copy_amount = std : : min ( std : : size_t { out_thread_ids_size } , num_threads ) ;
auto list_iter = thread_list . cbegin ( ) ;
for ( std : : size_t i = 0 ; i < copy_amount ; + + i , + + list_iter ) {
Memory : : Write64 ( out_thread_ids , ( * list_iter ) - > GetThreadID ( ) ) ;
out_thread_ids + = sizeof ( u64 ) ;
}
* out_num_threads = static_cast < u32 > ( num_threads ) ;
return RESULT_SUCCESS ;
}
namespace {
struct FunctionDef {
using Func = void ( ) ;
@ -2133,7 +2173,7 @@ static const FunctionDef SVC_Table[] = {
{ 0x63 , nullptr , " GetDebugEvent " } ,
{ 0x64 , nullptr , " ContinueDebugEvent " } ,
{ 0x65 , SvcWrap < GetProcessList > , " GetProcessList " } ,
{ 0x66 , nullptr , " GetThreadList " } ,
{ 0x66 , SvcWrap < GetThreadList > , " GetThreadList " } ,
{ 0x67 , nullptr , " GetDebugThreadContext " } ,
{ 0x68 , nullptr , " SetDebugThreadContext " } ,
{ 0x69 , nullptr , " QueryDebugProcessMemory " } ,