XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet

XFESystem

【Rust】XFE系统,基于Rust和汇编

公开
关注 0 Fork 0 Star 0
UTF-8
#include "../NativePal.h"
#include <stdint.h>
#include <stddef.h>

// API signatures follow the MIT-licensed .NET 10.0.12 System.Native headers.
// These implementations call XFESystem's native services; no Linux syscalls or
// operating-system libraries supply execution or memory for the managed guest.
extern "C" void* malloc(size_t);
extern "C" void free(void*);
extern "C" void* calloc(size_t,size_t);
extern "C" void* realloc(void*,size_t);
extern "C" int* __errno_location();
extern "C" [[noreturn]] void abort();

static const XfeRuntimePal& pal() { auto p=XfeRuntimeGetPal();if(!p)abort();return *p; }
[[noreturn]] static void fatal(const char* text) { pal().fatal(text);abort(); }
static int error(int code) { *__errno_location()=code;return -1; }
extern "C" void* SystemNative_Malloc(uintptr_t n) { return malloc(n); }
extern "C" void SystemNative_Free(void* p) { free(p); }
extern "C" void* SystemNative_Calloc(uintptr_t n,uintptr_t size) { return calloc(n,size); }
extern "C" void* SystemNative_Realloc(void* p,uintptr_t n) { return realloc(p,n); }
extern "C" int32_t SystemNative_GetErrNo() { return *__errno_location(); }
extern "C" void SystemNative_SetErrNo(int32_t value) { *__errno_location()=value; }
extern "C" char* SystemNative_GetEnv(const char*) { return nullptr; }
extern "C" int64_t SystemNative_GetTimestamp() { return (int64_t)pal().monotonic_nanoseconds(); }
extern "C" int64_t SystemNative_GetLowResolutionTimestamp() { return (int64_t)(pal().monotonic_nanoseconds()/1000000); }
extern "C" int32_t SystemNative_SchedGetCpu() { return 0; }
extern "C" uint64_t SystemNative_GetUInt64OSThreadId() { return pal().current_thread_id(); }
extern "C" uint32_t SystemNative_TryGetUInt32OSThreadId() { uint64_t id=pal().current_thread_id();return id && id<=UINT32_MAX?(uint32_t)id:UINT32_MAX; }
extern "C" [[noreturn]] void SystemNative_Abort() { abort(); }
extern "C" [[noreturn]] void SystemNative_Exit(int32_t) { fatal("Managed process requested exit"); }
extern "C" void SystemNative_LogError(uint8_t* text,int32_t length) { if(text && length>0)pal().write((char*)text,(uint32_t)length); }
extern "C" void SystemNative_Log(uint8_t* text,int32_t length) { SystemNative_LogError(text,length); }
extern "C" void SystemNative_SysLog(int32_t, const char* format, const char* argument)
{
    // System.Private.CoreLib's Unix diagnostic ABI; bounded serial output in
    // this kernel, without a host syslog socket or printf format evaluation.
    char text[1024];uint32_t used=0;
    if(format)for(uint32_t i=0;i<4096&&format[i]&&used<sizeof(text);++i) {
        if(format[i]=='%'&&format[i+1]=='s') {
            if(argument)for(uint32_t j=0;j<4096&&argument[j]&&used<sizeof(text);++j)text[used++]=argument[j];
            ++i;
        } else if(format[i]=='%'&&format[i+1]=='%') {text[used++]='%';++i;}
        else text[used++]=format[i];
    }
    if(used)pal().write(text,used);
}

// Only hash-table seeding and other non-security callers use this interface.
// A cryptographic API must use an independently validated strong entropy source.
extern "C" void SystemNative_GetNonCryptographicallySecureRandomBytes(uint8_t* output,int32_t length)
{
    if(!output || length<0)fatal("Invalid non-cryptographic random request");
    static uint64_t sequence;
    uint64_t state=pal().monotonic_nanoseconds()^pal().current_thread_id()^__atomic_add_fetch(&sequence,0x9e3779b97f4a7c15ULL,__ATOMIC_RELAXED);
    if(!state)state=0xd1b54a32d192ed03ULL;
    for(int32_t i=0;i<length;i++){state^=state>>12;state^=state<<25;state^=state>>27;output[i]=(uint8_t)((state*0x2545f4914f6cdd1dULL)>>56);}
}
extern "C" void* SystemNative_MMap(void*,uint64_t length,int32_t prot,int32_t flags,intptr_t fd,int64_t offset)
{
    if(!length || (prot&~7) || (flags!=0x12 && flags!=0x11) || fd!=-1 || offset!=0){error(95);return nullptr;}
    void* address=pal().reserve(length,4096);if(!address){error(12);return nullptr;}
    if(prot && (!pal().commit(address,length) || !pal().protect(address,length,(uint32_t)prot))){pal().release(address,length);error(12);return nullptr;}
    return address;
}
extern "C" int32_t SystemNative_MProtect(void* address,uint64_t length,int32_t prot)
{
    if(!address || !length || (prot&~7))return error(22);
    if(prot && !pal().commit(address,length))return error(12);
    return pal().protect(address,length,(uint32_t)prot)?0:error(13);
}
extern "C" int32_t SystemNative_MUnmap(void* address,uint64_t length) { return pal().release(address,length)?0:error(22); }

struct LowLevelMonitor { uint64_t owner;uint32_t waiters;void* event; };
extern "C" LowLevelMonitor* SystemNative_LowLevelMonitor_Create()
{
    auto m=(LowLevelMonitor*)calloc(1,sizeof(LowLevelMonitor));if(!m)return nullptr;
    m->event=pal().create_event(0,0);if(!m->event){free(m);return nullptr;}return m;
}
extern "C" void SystemNative_LowLevelMonitor_Destroy(LowLevelMonitor* m)
{
    if(!m || __atomic_load_n(&m->owner,__ATOMIC_ACQUIRE) || __atomic_load_n(&m->waiters,__ATOMIC_ACQUIRE))fatal("Destroying an active native monitor");
    if(!pal().close_event(m->event))fatal("Native monitor event close failed");free(m);
}
extern "C" void SystemNative_LowLevelMonitor_Acquire(LowLevelMonitor* m)
{
    if(!m)fatal("Null native monitor");uint64_t id=pal().current_thread_id();if(!id)fatal("Native monitor thread id unavailable");
    for(;;){
        uint64_t old=__atomic_load_n(&m->owner,__ATOMIC_ACQUIRE);if(old==id)fatal("Recursive non-recursive native monitor");
        uint64_t expected=0;if(__atomic_compare_exchange_n(&m->owner,&expected,id,false,__ATOMIC_ACQUIRE,__ATOMIC_RELAXED))return;
        pal().yield();
    }
}
extern "C" void SystemNative_LowLevelMonitor_Release(LowLevelMonitor* m)
{
    if(!m || __atomic_load_n(&m->owner,__ATOMIC_ACQUIRE)!=pal().current_thread_id())fatal("Native monitor release by non-owner");
    __atomic_store_n(&m->owner,0,__ATOMIC_RELEASE);
}
static int32_t monitor_wait(LowLevelMonitor* m,uint32_t milliseconds)
{
    if(!m || __atomic_load_n(&m->owner,__ATOMIC_ACQUIRE)!=pal().current_thread_id())fatal("Native monitor wait by non-owner");
    // Registration occurs while holding the mutex. Signal_Release can only run
    // after this release, and its auto-reset event preserves an early signal.
    __atomic_add_fetch(&m->waiters,1,__ATOMIC_RELEASE);
    SystemNative_LowLevelMonitor_Release(m);
    uint32_t status=pal().wait_event(m->event,milliseconds);
    SystemNative_LowLevelMonitor_Acquire(m);
    __atomic_sub_fetch(&m->waiters,1,__ATOMIC_RELEASE);
    if(status==UINT32_MAX)fatal("Native monitor wait failed");
    return status==0;
}
extern "C" void SystemNative_LowLevelMonitor_Wait(LowLevelMonitor* m) { (void)monitor_wait(m,UINT32_MAX); }
extern "C" int32_t SystemNative_LowLevelMonitor_TimedWait(LowLevelMonitor* m,int32_t milliseconds) { if(milliseconds<0)fatal("Negative native monitor timeout");return monitor_wait(m,(uint32_t)milliseconds); }
extern "C" void SystemNative_LowLevelMonitor_Signal_Release(LowLevelMonitor* m)
{
    if(!m || __atomic_load_n(&m->owner,__ATOMIC_ACQUIRE)!=pal().current_thread_id())fatal("Native monitor signal by non-owner");
    if(__atomic_load_n(&m->waiters,__ATOMIC_ACQUIRE) && !pal().set_event(m->event))fatal("Native monitor signal failed");
    SystemNative_LowLevelMonitor_Release(m);
}
struct ThreadStart { void*(*entry)(void*);void* argument; };
static uint32_t native_thread_start(void* context)
{
    auto start=*(ThreadStart*)context;free(context);(void)start.entry(start.argument);return 0;
}
extern "C" int32_t SystemNative_CreateThread(uintptr_t stack,void*(*entry)(void*),void* argument)
{
    if(!entry)return 0;
    auto p=(ThreadStart*)malloc(sizeof(ThreadStart));if(!p)return 0;*p={entry,argument};
    if(stack<64*1024)stack=8*1024*1024;
    if(!pal().start_thread(native_thread_start,p,stack)){free(p);return 0;}return 1;
}