XELoader ( Xeneva dynamic linker and loader )
October 18, 2025 ยท View on GitHub
XELoader is crucial component in XenevaOS, playing vital role in the process of running programs. XELoader is responsible for loading an executable file into process's memory, preparing it for execution by loading all the necessary resources for it. XELoader supports dynamic linking by loading only the required libraries and linking it to the executable during runtime. This involves finding the required libraries, mapping them into memory and resolving addresses of executable and the library. Some commonly used libraries are XEClib - 'The Xeneva C Library', Chitralekha - ' The Xeneva Graphics, Widget and Audio library.
What is Dynamic Linker and Loader?
The dynamic linker and loader are components of modern operating systems that handle the process of preparing and executing dynamically linked executables - executables that depend on shared libraries. It does -
- Resolves external symbols used by the program at runtime.
- Links the required shared libraries with the executable after it's loaded into memory.
- Loads the program and shared libraries into memory before linking.
- Maps each segment(code, data) of the binary into the process's address space.
Initialization
Initialization of dynamically linked program consist two steps. Whenever a new process slot is created and an executable is loaded into the process slot, the Kernel verifies if the executable is statically linked or dynamically linked. Statically linked programs are directly executed by Kernel bypassing the XELoader and dynamically linked programs are passed to XELoader. XELoader is statically linked program. If Kernel finds dynamically linked program during loading the program, immediately it dismisses the loading process and start loading XELoader. Kernel passes the name of dynamically linked program as an argument followed by other arguments for the the program to the XELoader. Once XELoader gains control, it start loading the program in User mode, during runtime.
Loading and Linking
Everything inside XELoader is an object. Objects are of two type : Main Executable and Libraries. Objects holds the information about the binary and dependencies. XELoader first loads the main executable and gets the name of required library. It loads all the required library as an object and store it in the object list. During library loading stage two steps are performed :
- Symbol resolution is performed by binding symbol reference of one library from another library. Practical example involves the Chitralekha library has many symbol reference to XEClib which needs symbol binding to be performed efficiently.
- Relocation : After loading, XELoader updates addresses of each library to the loaded memory address, so that symbol references point to the correct memory location. By default every executable has base address of 0x600000 for x86 and 0x600000000 for ARM64 in XenevaOS.
XELoader at last links all the loaded libraries to the main executable by performing similar steps performed during library loading stage. The main object holds the main executable. At this stage the main entry point is extracted from the main executable and stored in main object list.
Control Transfer
Transferring the control to the main executable is only performed after loading and linking of the main program and libraries are done efficiently. Failure of loading and linking results in program crash. Before transferring control to the program, XELoader updates the signal table of the current process with Default Signal Handler. Finally XELoader transfers the control to the program by calling the Main Entry Point from the main object list.
Technical Overview
XELoader uses PE image format for executable and libraries, i.e it is only limited to loading of PE image format. Elf format can also be added for supporting Elf binaries. XELoader itself is a statically linked binary means it doesn't depend on shared library, everything is build statically inside XELoader.
There are two-level of loader built into Xeneva :
- The Kernel level loader (Kernel space static executable loader)
- The XELoader (Userspace dynamic linker and loader)
Whenever Xeneva encounters system call _KeProcessLoadExec with the executable file path and name, it immediately loads the executable from the path and verifies if it's PE formatted executable, and not a library. Kernel level loader is only limited to load statically linked executable files not dynamically linked executable nor library. If it's a executable file, then it further check if it's dynamically linked or statically. Static executable files can be directly executed from Kernel level loader, which means it'll map each section of the executable to process's address space and transfer the control to the executable entry point. For dynamically linked executable file, an extra layer is placed in between. Kernel level loader load XELoader (which is a statically linked loader) and put the desired filename and its path into XELoader argument list and transfer the control to XELoader. XELoader then get executed into user space and start the process of loading the executable file that kernel level loader provided. XELoader then further resolve external symbols by loading and linking required shared libraries.
For example here are the steps how it works:
| Steps | Description |
|---|---|
(a) _KeProcessLoadExec(proc, "/calc.exe",0,NULL); | The _KeProcessLoadExec system calls carries a pointer to newly created process slot and the executable file name that needs to be loaded into newly created process slot. |
(b) AuLoadExecToProcess(proc,"/calc.exe",0,NULL); | Get called in Kernel space and it receives the parameters from _KeProcessLoadExec. |
(c) strcmp(filename,"exe") == 0 | Check the extension of the given filename if it's ended with '.exe', because Kernel level loader is limited to loading static executables only. |
(d) AuVFSNodeReadBlock(fsys,filename,(uint64_t*)V2P((uint64_t)buffer)) | If the filename ends with '.exe' then load the file into current process address space. |
(e)if(AuPEFileIsDynamicallyLinked(buffer)); | Check if the executable is dynamically linked or statically, if dynamically linked, the loading of this executable is discarded and XELoader is loaded. |
(f) AuCreateKthread(AuProcessEntUser,...) | Create a kernel thread with entry point to AuProcessEntUser which is a helper function that help jump to mapped user thread, i.e XELoader in this case, if executable was dynamically linked. |
After above step is executed successfully, XELoader will have the name of executable ("/calc.exe", in this case ) in its argument list. XELoader can load the executable, resolve external symbols, link required libraries during runtime,..etc and start executing the executable file.
Binary Alignment
Binary Alignment defines how sections of a binary are organized both in memory and on a disk. Xeneva uses Portable Executable (PE) format as binary format. There are two key alignment considered in Xeneva: SectionAlignment and FileAlignment.
SectionAlignment specifies how sections are aligned in memory once the binary is loaded--typically Xeneva supports 4096 bytes (4 KiB) on ARM64 and 512-4096 bytes on x86 systems. FileAlignment, on the other hand, determines how sections are aligned within the file on disk- commonly 512 bytes or 4096 bytes. When a PE file is loaded, each section's VirtualAddress is rounded up to the nearest multiple of SectionAlignment, while its PointerToRawData is aligned according to FileAlignment. Proper alignment ensures that sections do not overlap and that the loader can efficiently map them into memory with correct page boundaries.
Memory Mapping
All Xeneva binaries are loaded to base address of 0x600000 for x86 and 0x600000000 for ARM64,though this rule applies only to statically linked binaries. For dynamically linked binaries or libraries, XELoader modifies the base address to meet the proper runtime memory map. The system call KeMemMap is used to allocate and map each section of the binary to memory from user area. XELoader maps sections by considering the binary's SectionAlignment and FileAlignment values as key factors to ensure proper alignment and access.