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

XFESystem

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

公开
关注 0 Fork 0 Star 0
UTF-8
/* XFESystem-owned single-image loader metadata for the Microsoft unwinder.
 * Limine's documented executable-file ABI supplies the actual loaded ELF.
 * Protocol constants/field layouts: Limine protocol (Mintsuki/contributors, 0BSD).
 */
#include <stdint.h>
#include <stddef.h>
struct xfe_file {uint64_t revision;void *address;uint64_t size;};
struct image_response {uint64_t revision;struct xfe_file *file;};
struct image_request {uint64_t id[4],revision;volatile struct image_response *response;};
__attribute__((used,section(".limine_requests"))) static volatile struct image_request executable_file={
    {0xc7b1dd30df4c8b88ULL,0x0a82e883a194f07bULL,0xad97e90e83f1ed67ULL,0x31eb5d1c5ff23b69ULL},0,0};
struct elf_header {
    unsigned char ident[16];uint16_t type,machine;uint32_t version;
    uint64_t entry,phoff,shoff;uint32_t flags;
    uint16_t header_size,phsize,phcount,shsize,shcount,shstrings;
};
struct elf_phdr {uint32_t type,flags;uint64_t offset,vaddr,paddr,file_size,memory_size,alignment;};
struct dl_phdr_info {
    uintptr_t dlpi_addr;const char *dlpi_name;const struct elf_phdr *dlpi_phdr;uint16_t dlpi_phnum;
    uint64_t dlpi_adds,dlpi_subs;size_t dlpi_tls_modid;void *dlpi_tls_data;
};
struct dl_info {const char *dli_fname;void *dli_fbase;const char *dli_sname;void *dli_saddr;};
extern char __xfe_kernel_start[],__xfe_kernel_end[];
static const char image_name[]="XFESystem.Kernel.elf";

static const struct elf_header *header(void){
    const volatile struct image_response *response=executable_file.response;
    if(!response||!response->file||!response->file->address||response->file->size<sizeof(struct elf_header))return 0;
    const struct elf_header *elf=response->file->address;
    if(elf->ident[0]!=127||elf->ident[1]!='E'||elf->ident[2]!='L'||elf->ident[3]!='F'||
       elf->ident[4]!=2||elf->ident[5]!=1||elf->type!=2||elf->machine!=62||elf->version!=1||
       elf->header_size!=sizeof(*elf)||elf->phsize!=sizeof(struct elf_phdr)||!elf->phcount||elf->phcount>1024||
       elf->phoff>response->file->size||elf->phcount>(response->file->size-elf->phoff)/elf->phsize)return 0;
    if((uintptr_t)elf>UINTPTR_MAX-response->file->size)return 0;
    return elf;
}
int dl_iterate_phdr(int (*callback)(struct dl_phdr_info*,size_t,void*),void *context){
    const struct elf_header *elf=header();if(!elf||!callback)return -1;
    // This is ET_EXEC, so p_vaddr already contains the final runtime addresses.
    // No dynamic module loader or fabricated set of libc/shared objects exists.
    struct dl_phdr_info info={0,image_name,(const struct elf_phdr*)((const char*)elf+elf->phoff),elf->phcount,1,0,1,0};
    return callback(&info,sizeof(info),context);
}
int dladdr(const void *address,struct dl_info *info){
    const struct elf_header *elf=header();if(!elf||!info)return 0;
    const struct elf_phdr *phdr=(const struct elf_phdr*)((const char*)elf+elf->phoff);
    uintptr_t pointer=(uintptr_t)address;
    for(unsigned i=0;i<elf->phcount;i++){
        if(phdr[i].type!=1||!phdr[i].memory_size||phdr[i].memory_size>UINT64_MAX-phdr[i].vaddr)continue;
        if(pointer>=phdr[i].vaddr&&pointer-phdr[i].vaddr<phdr[i].memory_size){
            *info=(struct dl_info){image_name,__xfe_kernel_start,0,0};return 1;
        }
    }
    return 0;
}
static int count_segments(struct dl_phdr_info *info,size_t bytes,void *context){
    if(bytes<sizeof(*info))return -1;unsigned *counts=context;
    for(unsigned i=0;i<info->dlpi_phnum;i++){
        const struct elf_phdr *p=info->dlpi_phdr+i;
        if(p->type==1){counts[0]++;if((p->flags&3)==3)return -1;}
        if(p->type==0x6474e550&&p->memory_size)counts[1]++;
    }
    return 0;
}
int xfe_loaded_elf_selftest(void){
    const struct elf_header *elf=header();if(!elf)return 0;
    unsigned counts[2]={0,0};if(dl_iterate_phdr(count_segments,counts)||counts[0]<3||counts[1]!=1)return 0;
    struct dl_info info;if(!dladdr((void*)&xfe_loaded_elf_selftest,&info)||info.dli_fbase!=__xfe_kernel_start)return 0;
    if(dladdr((void*)0,&info)||elf->entry<(uintptr_t)__xfe_kernel_start||elf->entry>=(uintptr_t)__xfe_kernel_end)return 0;
    return 1;
}