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

XFESystem

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

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

// ELF x86_64 TLS variant II. This is kernel code (ring 0), not a host libc.
// A scheduler must save/restore IA32_FS_BASE on every thread switch. No managed
// object is stored in this allocation; the Microsoft runtime owns its TLS roots.
extern unsigned char __tls_start[], __tls_init_end[], __tls_end[];
extern unsigned char __tls_align[];
extern void* xfe_runtime_alloc_pages(uint64_t pages);
extern int xfe_runtime_free_pages(void* address, uint64_t pages);
extern void xfe_runtime_halt(const char* reason);

static __thread int xfe_thread_errno;
static int xfe_boot_errno;
struct XfeTlsControl {
    void* self;
    void* dynamic_vector;
    void* tls_base;
    uint64_t tls_bytes;
    void* allocation;
    uint64_t allocation_pages;
    uint64_t signature;
};
static uint64_t get_fs_base(void)
{
    uint32_t low,high;
    __asm__ volatile("rdmsr" : "=a"(low),"=d"(high) : "c"(0xc0000100));
    return ((uint64_t)high<<32)|low;
}
static void set_fs_base(uint64_t address)
{
    __asm__ volatile("wrmsr" :: "c"(0xc0000100),"a"((uint32_t)address),"d"((uint32_t)(address>>32)) : "memory");
}

void* XfeRuntimeTlsCreate(void)
{
    uint64_t initialized=(uintptr_t)__tls_init_end-(uintptr_t)__tls_start;
    uint64_t bytes=(uintptr_t)__tls_end-(uintptr_t)__tls_start;
    uint64_t alignment=(uintptr_t)__tls_align;
    if(alignment<16)alignment=16;
    if(initialized>bytes || bytes>16*1024*1024 || (alignment&(alignment-1)) || alignment>4096)return NULL;
    bytes=(bytes+alignment-1)&~(alignment-1);
    uint64_t total=bytes+sizeof(struct XfeTlsControl)+alignment;
    uint64_t pages=(total+4095)/4096;
    unsigned char* raw=xfe_runtime_alloc_pages(pages);
    if(!raw)return NULL;
    unsigned char* base=(unsigned char*)(((uintptr_t)raw+alignment-1)&~(alignment-1));
    for(uint64_t i=0;i<bytes;i++)base[i]=i<initialized?__tls_start[i]:0;
    struct XfeTlsControl* control=(struct XfeTlsControl*)(base+bytes);
    *control=(struct XfeTlsControl){control,NULL,base,bytes,raw,pages,0x584645544c533031ULL};
    return control;
}
int XfeRuntimeTlsSet(void* base)
{
    struct XfeTlsControl* control=(struct XfeTlsControl*)base;
    if(!control || control->self!=control || control->signature!=0x584645544c533031ULL)return 0;
    set_fs_base((uintptr_t)base);
    return 1;
}
void* XfeRuntimeTlsCurrent(void) { return (void*)get_fs_base(); }
int XfeRuntimeTlsRelease(void* base)
{
    struct XfeTlsControl* control=(struct XfeTlsControl*)base;
    if(!control || (void*)get_fs_base()==base || control->signature!=0x584645544c533031ULL)return 0;
    return xfe_runtime_free_pages(control->allocation,control->allocation_pages);
}
int XfeRuntimeTlsInitialize(void)
{
    if(get_fs_base())return 0; // Never silently replace firmware or another thread's TLS.
    void* control=XfeRuntimeTlsCreate();
    return control?XfeRuntimeTlsSet(control):0;
}
__attribute__((noinline)) static int* runtime_errno_address(void)
{
    // Keep this load behind the bootstrap check. A ternary address expression
    // can otherwise be lowered to an unconditional FS:0 read plus cmov.
    __asm__ volatile("" ::: "memory");
    return &xfe_thread_errno;
}
int* __errno_location(void)
{
    // During the pre-runtime kernel selftest no threads exist and FS is zero.
    // Once a runtime thread is installed the address follows that thread's TLS.
    if(!get_fs_base())return &xfe_boot_errno;
    return runtime_errno_address();
}
struct XfeTlsIndex { uint64_t module,offset; };
void* __tls_get_addr(struct XfeTlsIndex* index)
{
    struct XfeTlsControl* control=(struct XfeTlsControl*)get_fs_base();
    if(!control || !index || index->module!=1 || index->offset>=control->tls_bytes || control->signature!=0x584645544c533031ULL) {
        xfe_runtime_halt("Invalid NativeAOT TLS access");
        for(;;)__asm__ volatile("cli; hlt");
    }
    return (unsigned char*)control->tls_base+index->offset;
}