- C 94.8%
- Makefile 5.2%
| assets | ADD: New logo and update README.md | |
| examples | ADD: .text, .rodata, .data and .bss support + relocations implemantation | |
| src | ADD: New flags options for compiler driver linking with cc | |
| .gitignore | Initial commit | |
| LICENSE | Add MIT License | |
| Makefile | Initial commit | |
| README.md | FIX: fix the honorable mention again </3 | |
xld
xld is a static linker for ELF64 x86-64 on Linux. It links GCC-generated object files into standalone executables without relying on the system linker. This project emphasizes clarity, low-level control, and a deep understanding of the ELF format and program loading process.
Features
- Static linking for ELF64 x86-64 object files
- Fully independent of the system linker
- Reads ELF headers, section headers, symbol tables, and relocations manually
- Supports
.text,.rodata,.dataand.bsssections - Generates standalone executables with custom memory layout
Memory Layout
xld sets a static memory layout for the executable:
- BASE_ADDR: 0x400000
- PAGE_SIZE: 0x1000
- TEXT_ADDR: BASE_ADDR + PAGE_SIZE
Sections are mapped as:
| Section | Runtime Address |
|---|---|
| .text | TEXT_ADDR |
| .rodata | Immediately after .text |
| .data | Aligned to PAGE_SIZE after .rodata |
| .bss | Immediately after .data |
The linker calculates addresses using align_up() to ensure proper page alignment.
ELF Parsing
xld reads ELF files manually:
- Reads the ELF header (Elf64_Ehdr) to determine section table offsets and number of sections.
- Reads section headers (Elf64_Shdr) to identify
.text,.rodata,.data,.bss. - Reads symbol tables (SHT_SYMTAB) to locate the entry symbol or other symbols needed for relocations.
- Reads relocation sections (SHT_RELA) and applies them manually to the .text section.
- Functions like find_sections(), find_entry_symbol(), and apply_relocations() handle these tasks.
Relocation Handling
- Currently supports only R_X86_64_PC32 relocations.
- For each relocation:
- Compute S, the runtime address of the target symbol.
- Compute P, the runtime address of the relocation location.
- Compute A, the addend from the relocation entry.
- Write the 32-bit value
(S + A - P)into the.textbuffer. This ensures that all relative calls and jumps point to the correct runtime addresses.
Program Headers
xld generates two program headers:
- LOAD 1 (RX) – Includes headers,
.textand.rodata. - LOAD 2 (RW) – Includes
.dataand.bss
Each header specifies:
- Virtual and physical addresses (p_vaddr and p_paddr)
- File size (p_filesz) and memory size (p_memsz)
- Permissions (PF_R | PF_X for code, PF_R | PF_W for data)
- Alignment (PAGE_SIZE)
Installation
Clone and build:
git clone https://codeberg.org/grassleaff/xld
cd xld
make # or sudo make install (system-wide installation)
Makefile Options
| Command | Description |
|---|---|
| make or make all | Build xld (same as make build) |
| make build | Compile the xld executable from src/ |
| make install | Install xld to /usr/local/bin |
| make uninstall | Remove the installed executable |
| make examples | Build example .S files located on examples/ into .out executables |
| make run-examples | Build and run all examples sequentially |
| make clean Remove | xld binary, object files, and compiled examples |
Usage
Link object files:
xld input1.o input2.o -o my_program
Run examples:
make run-examples
Honorable mention
1 - 0xdd / eighty_twenty
xld is used in this project as the linker for the minimalist C toolchain that supports the et language ecosystem. It has been adapted to work with the etstd library, allowing it to be compiled and executed in an extremely minimal environment, without dependencies such as libc or complex toolchains.
In this context, xld is responsible for linking the generated binaries (including the compiler itself, etc.), supporting specific relocations required for this simplified environment and enabling the construction of fully static executables in a nearly self-contained system.
© 2026 grassleaff. All rights reserved.
Licensed under the MIT License.