diff --git a/libc/ElfInterpreter/ld.c b/libc/ElfInterpreter/ld.c index 5fd0d97..914206b 100644 --- a/libc/ElfInterpreter/ld.c +++ b/libc/ElfInterpreter/ld.c @@ -12,8 +12,29 @@ enum KCtl KCTL_GET_UID, KCTL_GET_GID, KCTL_GET_PAGE_SIZE, + KCTL_IS_CRITICAL, }; +uintptr_t RequestPages(size_t Count) +{ + return syscall1(_RequestPages, Count); +} + +int FreePages(uintptr_t Address, size_t Count) +{ + return syscall2(_FreePages, Address, Count); +} + +int IPC(enum IPCCommand Command, enum IPCType Type, int ID, int Flags, void *Buffer, size_t Size) +{ + return syscall6(_IPC, Command, Type, ID, Flags, Buffer, Size); +} + +uintptr_t KernelCTL(enum KCtl Command, uint64_t Arg1, uint64_t Arg2, uint64_t Arg3, uint64_t Arg4) +{ + return syscall5(_KernelCTL, Command, Arg1, Arg2, Arg3, Arg4); +} + // bool ELFAddLazyResolverToGOT(void *ElfFile, void *MemoryImage, LibAddressCollection *Libs) // { // struct Elf64_Dyn *Dyn = (struct Elf64_Dyn *)ELFGetDynamicTag(ElfFile, DT_PLTGOT); @@ -284,34 +305,25 @@ bool ELFDynamicReallocation(void *ElfFile, void *MemoryImage) */ /* Preload */ -void ld_main() +int ld_main() { + /* Prevent race condition. */ + uintptr_t KCTL_ret = 0xdead; + do + { + KCTL_ret = KernelCTL(KCTL_IS_CRITICAL, 0, 0, 0, 0); + } while (KCTL_ret == SYSCALL_ACCESS_DENIED); + + if (KCTL_ret == false) + return -4; + + /* --------------------------------------------------- */ + __asm__ __volatile__("syscall" : : "a"(1), "D"('H'), "S"(0) : "rcx", "r11", "memory"); - - return; -} - -uintptr_t RequestPages(size_t Count) -{ - return syscall1(_RequestPages, Count); -} - -int FreePages(uintptr_t Address, size_t Count) -{ - return syscall2(_FreePages, Address, Count); -} - -int IPC(enum IPCCommand Command, enum IPCType Type, int ID, int Flags, void *Buffer, size_t Size) -{ - return syscall6(_IPC, Command, Type, ID, Flags, Buffer, Size); -} - -uintptr_t KernelCTL(enum KCtl Command, uint64_t Arg1, uint64_t Arg2, uint64_t Arg3, uint64_t Arg4) -{ - return syscall5(_KernelCTL, Command, Arg1, Arg2, Arg3, Arg4); + return 0; } /* Actual load */ diff --git a/libc/ElfInterpreter/ldstart.c b/libc/ElfInterpreter/ldstart.c index b1fe472..490f2fa 100644 --- a/libc/ElfInterpreter/ldstart.c +++ b/libc/ElfInterpreter/ldstart.c @@ -11,6 +11,9 @@ void __attribute__((naked, used, no_stack_protector)) _ld_start() "pushq %rdi\n" "call ld_main\n" + "movl %eax, %edi\n" // Move return value to edi + "cmp $0, %edi\n" // Check if return value is 0 + "jne _exit\n" // If not, jump to _exit "popq %rdi\n" "popq %rsi\n" @@ -18,8 +21,8 @@ void __attribute__((naked, used, no_stack_protector)) _ld_start() "popq %rcx\n" "call ld_load\n" - "movl %eax, %edi\n" - "call _exit"); + "movl %eax, %edi\n" // Move return value to edi + "call _exit"); // Call _exit } void _exit(int Code) diff --git a/libs/include/sysbase.h b/libs/include/sysbase.h index a63639b..e4bb247 100644 --- a/libs/include/sysbase.h +++ b/libs/include/sysbase.h @@ -11,6 +11,7 @@ enum KCtl KCTL_GET_UID, KCTL_GET_GID, KCTL_GET_PAGE_SIZE, + KCTL_IS_CRITICAL, }; long DoCtl(uint64_t Command, uint64_t Arg1, uint64_t Arg2, uint64_t Arg3, uint64_t Arg4);