dustlink is the Dust Programming Language internal linker project.
- Platform-agnostic linker architecture (not XDV-specific).
- Dust source (
.ds) linker pipeline. - Host runtime implementation for object ingestion and file emission.
- Compatibility-oriented CLI surface for gcc/ld/lld workflows.
dustlink is not a backend pass-through wrapper.
src/main.ds routes directly into Dust linker modules.
- Object ingestion:
- ELF64 relocatable objects
- COFF 64-bit objects (
x86_64andarm64machine IDs) - Mach-O 64-bit objects (
x86_64andarm64CPU IDs)
- Archive ingestion:
.aand.libsearch/ingest via-L/-land--library-path/--library- deterministic search order: explicit
-Lpaths, then-rpath-link(dynamic mode), then target/sysroot default library roots - dynamic-mode
-lresolution prefers shared objects (.so/.dylib/.dll) before static archives - static-mode
-lresolution uses static archives only - exact-name
-l:<file>token support
- Output writers:
- ELF executable
- flat binary
- MBR image
- PE executable (multi-section, section-per-chunk emission)
- Mach-O executable (multi-section segment/section emission)
- machine/cpu selection follows resolved target architecture (
x86_64vsaarch64/arm64) - PE compatibility-state toggles (
/NOENTRY,/DYNAMICBASE,/NXCOMPAT,/LARGEADDRESSAWARE) are emitted into real PE header fields
- Script application:
-T <script>/--script <script>- directive support:
ENTRY,OUTPUT,OUTPUT_FORMAT,OUTPUT_ARCH,TARGET,SEARCH_DIR,INPUT,GROUP,AS_NEEDED,NO_AS_NEEDED,EXTERN,PROVIDE,PROVIDE_HIDDEN,INCLUDE,ASSERT - compatibility blocks:
PHDRS,VERSION(block-shape validated) - script expression coverage for
ORIGIN(...),LENGTH(...),ADDR(...),LOADADDR(...),SIZEOF(...),ALIGN(...), plus additive/subtractive arithmetic - script expression coverage also includes unary,
*,/,%, shifts, and bitwise operators - direct script symbol assignments (
SYMBOL = <expr>) are supported - unknown script directive heads are rejected (no silent acceptance)
SECTIONScoverage: location-counter assignment (. = <expr>), output-address forms (.text <expr> : { ... }), andAT(<expr>)load-address captureSEARCH_DIR(=...)resolves through configured--sysrootwhen presentINPUTfamily token handling recognizes-Land-lforms- block-aware script statement splitting for multi-line
MEMORY/SECTIONSblocks ENTRY(symbol)now registers required-symbol intent when symbol resolution is deferred
- Link-mode controls:
--gc-sections/--no-gc-sections(GC-aware alloc section selection)--allow-multiple-definition--defsym name=value--target=<triple>/-m<emulation>target selection--sysroot,-rpath/--rpath, and-rpath-link/--rpath-link- dynamic-unresolved policy controls:
--no-undefined,--error-unresolved-symbols,--allow-shlib-undefined,--no-allow-shlib-undefined - dynamic-tag controls:
--enable-new-dtags/--disable-new-dtags - transitive
DT_NEEDEDpolicy controls:--copy-dt-needed-entries/--no-copy-dt-needed-entries - compatibility-state controls:
--hash-style,--threads,--thread-count,--eh-frame-hdr,--fatal-warnings,--color-diagnostics,--print-gc-sections,--icf=* - broader compatibility controls:
--version-script,--dynamic-list,--trace-symbol,--print-map,--start-lib,--end-lib,--emit-relocs,--strip-all lld-linkcompatibility controls:/OUT:,/ENTRY:,/MACHINE:,/LIBPATH:,/DEFAULTLIB:,/MAP[:file],/DLL,/SUBSYSTEM:,/OPT:,/WX,/NOENTRY,/DYNAMICBASE,/NXCOMPAT,/LARGEADDRESSAWARE- shared-object symbol ingestion for exported symbol resolution across ELF, PE, COFF, and Mach-O metadata paths
- Target IDs are architecture-aware:
nonex86_64-linux,x86_64-windows,x86_64-macosaarch64-linux,aarch64-windows,aarch64-macos
- CLI target parsing preserves architecture for both
x86_64andaarch64/arm64aliases. - CLI target parsing also accepts musl triples, Windows GNU triples, and bare-metal
*-none[-elf]aliases. - ELF object validator machine coverage includes
EM_X86_64andEM_AARCH64. - relocation application is machine-aware per ingested object via runtime
object.machine. - COFF and Mach-O object ingestion now use refined machine-aware relocation-kind mapping during relocation record ingest.
- Core relocation set includes:
R_X86_64_NONE,R_X86_64_64,R_X86_64_PC32,R_X86_64_PLT32R_X86_64_GLOB_DAT,R_X86_64_JUMP_SLOT,R_X86_64_RELATIVER_X86_64_GOTPCREL,R_X86_64_32,R_X86_64_32SR_X86_64_GOTPCRELX,R_X86_64_REX_GOTPCRELX- AArch64 core + instruction forms:
R_AARCH64_NONE,R_AARCH64_ABS64,R_AARCH64_ABS32,R_AARCH64_PREL64,R_AARCH64_PREL32R_AARCH64_CALL26,R_AARCH64_JUMP26,R_AARCH64_CONDBR19,R_AARCH64_TSTBR14R_AARCH64_LD_PREL_LO19,R_AARCH64_ADR_PREL_LO21,R_AARCH64_ADR_PREL_PG_HI21,R_AARCH64_ADR_PREL_PG_HI21_NCR_AARCH64_ADD_ABS_LO12_NC,R_AARCH64_LDST8/16/32/64/128_ABS_LO12_NC- MOVW families:
R_AARCH64_MOVW_UABS_*,R_AARCH64_MOVW_SABS_*,R_AARCH64_MOVW_PREL_*
- AArch64 TLS relocation coverage:
TLSGD/TLSLD/TLSDESCinstruction-form relocation IDs are recognized by ELF ingest and relocation validationR_AARCH64_TLS_DTPMOD,R_AARCH64_TLS_DTPREL,R_AARCH64_TLS_TPRELare applied for non-shared links using host-runtime TLS layout metadata helpers- shared-link AArch64 TLS data reloc handling is partially differentiated:
TLS_DTPRELresolves from TLS layout metadata, shared-linkTLS_TPRELis rejected as invalid, and shared-linkTLS_DTPMODremains unsupported - TLSLE/TLSLD low12 offset instruction forms (
*_ADD_*_LO12_NC,*_LDST64_*_LO12_NC,*_LDST128_*_LO12_NC) are applied in non-shared links using host-runtime TLS offset helpers R_AARCH64_TLSDESC_CALLis applied as a validatedBLRpreserve relocation- host TLS synthetic descriptor/GOT planning ABI is available and now used in relocation application (
reserve,count,slot address,reloc-value) for stagedTLSGD/TLSLD/TLSDESCdescriptor-sequence implementation - descriptor-sequence instruction relocations (
TLSGD/TLSLD/TLSDESC) now patch against host-planned synthetic slot addresses in the emitted load image (staged semantics; full TLSDESC runtime parity still incomplete) - ELF host writer now materializes a synthetic AArch64 TLS descriptor/GOT-like slot region and emits minimal synthetic
.rela.dynmetadata (DT_SYMTAB,DT_SYMENT,DT_RELA*) for reserved descriptor-sequence slots - initial descriptor-sequence relaxation scope is limited to deterministic synthetic-slot reuse/coalescing (including TLSLD module-slot coalescing); full instruction-sequence rewrite relaxations remain pending
Primary options:
-o,--output-e,--entry,--entry-point--image-base-Ttext-T,--script--oformat(elf64,binary,mbr,pe,macho64plus aliases)-L,--library-path-l,--library--sysroot-rpath,--rpath-rpath-link,--rpath-link-Map,--Map,--map-file-s,--strip-debug--gc-sections--no-gc-sections--allow-multiple-definition--defsym/--defsym=<name=value>--build-id/--build-id=<none|fast|md5|sha1|uuid|0x...>--target/--target=<triple>-m/-m<emulation>-z/-z<...>(relro,norelro,now,lazy,execstack,noexecstack,defs,undefs, plus accepted compatibility tokenstext,notext,origin)-u,--undefined,--require-defined--no-undefined,--error-unresolved-symbols--allow-shlib-undefined--no-allow-shlib-undefined--enable-new-dtags,--disable-new-dtags--copy-dt-needed-entries,--no-copy-dt-needed-entries--start-group,--end-group--version-script,--dynamic-list,--trace-symbol--print-map,--start-lib,--end-lib--emit-relocs,--strip-alllld-linkcompatibility spellings:/OUT:<path>,/ENTRY:<symbol|addr>,/MACHINE:<arch>/LIBPATH:<dir>,/DEFAULTLIB:<name>,/MAPor/MAP:<path>/DLL,/SUBSYSTEM:<kind>,/OPT:<token>,/WX,/WX:NO/NOENTRY,/DYNAMICBASE,/NXCOMPAT,/LARGEADDRESSAWARE
--help,--version
Compatibility spellings for common ld/lld flags are accepted.
Core linker-affecting paths (--target/-m, --defsym, --build-id, -z, required-symbol flags, sysroot/rpath/rpath-link, dynamic policy flags, group/static/shared toggles, and hash/thread/icf-related compatibility controls) are wired to internal linker state.
lld-link compatibility controls /NOENTRY, /DYNAMICBASE, /NXCOMPAT, and /LARGEADDRESSAWARE are now state-wired into PE writer behavior.
Additional soft-compatibility families (--warn-*, --time-trace*, --lto-*, and /GUARD:*-style slash families) are accepted to reduce false hard-fail paths during lld-profile migrations.
These compatibility no-op paths now emit diagnostics, and become hard failures when --fatal-warnings (or /WX) is enabled.
--dependency-fileis now state-wired and emits a depfile after successful links.--emit-relocsis now state-wired and expands map-row output with relocation rows.--hash-stylenow affects ELF dynamic-tag emission (DT_HASH/DT_GNU_HASH) in Dust runtime host writer output.--print-gc-sectionsnow prints section-drop diagnostics during GC-aware alloc-section selection.- Unsupported flag/target failures now emit explicit diagnostics instead of returning only status codes.
- AArch64 ELF relocation coverage now includes instruction bitfield patching (
ADR_PREL_LO21, MOVW families,LD/STlo12 variants, branch/literal forms) and stricter TLS-family handling:TLSDESC_CALLnow validatesBLRinstruction encoding instead of acting as a generic no-op- AArch64 TLS data relocs (
TLS_DTPMOD/TLS_DTPREL/TLS_TPREL) now use host-runtime TLS layout metadata for non-shared links - TLS descriptor-sequence instruction relocations now route through the host synthetic-slot reloc-value helper and patch against materialized synthetic slot addresses (staged semantics)
- reserved TLS descriptor-sequence synthetic slots are now materialized in ELF load images and emit minimal synthetic
.rela.dynmetadata (DT_SYMTAB,DT_SYMENT,DT_RELA*) - descriptor-sequence staged relaxation behavior now includes deterministic synthetic-slot reuse/coalescing (including TLSLD module-slot coalescing); full instruction rewrite relaxations remain pending
- Shared-library ingest now propagates shared-object ingest failures directly (no Dust-side
ERR_NOT_IMPLEMENTED_YETswallow path). - Host shared-object ingest now treats unknown/unsupported payload formats as
ERR_INVALID_FORMATinstead of silently succeeding. - Host shared-object ingest now also rejects cross-target / wrong-ABI / wrong-kind shared inputs before symbol ingest (ELF requires target machine +
ET_DYN; PE requires Windows target + DLL + matching machine; Mach-O requires macOS target + matching CPU + dylib file type). - Host shared-object ingest now filters non-exported metadata entries during symbol ingestion (ELF hidden/internal dynsyms and Mach-O private extern/debug symbols are skipped).
- Needed-library recording now prefers embedded shared-library names when available (
DT_SONAME, PE export DLL name, Mach-O install name) instead of filename-only normalization. dustlinknow patches AArch64 TLS descriptor-sequence instruction relocs through host synthetic-slot helpers and emits staged synthetic slot/dynamic metadata in ELF outputs, preserving future parity work without changing relocation discovery flow.
Check:
dust check src/Build:
dust build src --out target/dust/dustlinkdustlink has advanced beyond initial ELF-only behavior, but it is not yet full lld parity across every flag/script/cross-format semantic.
See changelog.md for detailed change history.