Skip to content

Commit 98598e5

Browse files
committed
lk
1 parent 03d5926 commit 98598e5

8 files changed

Lines changed: 83 additions & 13 deletions

File tree

README.md

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -83,9 +83,10 @@
8383
- `R_AARCH64_LD_PREL_LO19`, `R_AARCH64_ADR_PREL_LO21`, `R_AARCH64_ADR_PREL_PG_HI21`, `R_AARCH64_ADR_PREL_PG_HI21_NC`
8484
- `R_AARCH64_ADD_ABS_LO12_NC`, `R_AARCH64_LDST8/16/32/64/128_ABS_LO12_NC`
8585
- MOVW families: `R_AARCH64_MOVW_UABS_*`, `R_AARCH64_MOVW_SABS_*`, `R_AARCH64_MOVW_PREL_*`
86-
- AArch64 TLS starter coverage:
87-
- `TLSGD` / `TLSLD` / `TLSDESC` instruction-form relocations (ADR/ADRP/ADD/LD literal/LD lo12/CALL subset)
88-
- `R_AARCH64_TLS_DTPMOD`, `R_AARCH64_TLS_DTPREL`, `R_AARCH64_TLS_TPREL`
86+
- AArch64 TLS relocation coverage (parse/validate surface):
87+
- `TLSGD` / `TLSLD` / `TLSDESC` instruction-form relocation IDs are recognized by ELF ingest and relocation validation
88+
- `R_AARCH64_TLS_DTPMOD`, `R_AARCH64_TLS_DTPREL`, `R_AARCH64_TLS_TPREL` are recognized as AArch64 TLS data relocation IDs
89+
- relocation application currently returns `ERR_NOT_IMPLEMENTED_YET` for AArch64 TLS-family relocations pending TLS layout/module metadata in the host linker runtime ABI
8990

9091
## CLI Compatibility Surface
9192

@@ -142,7 +143,10 @@ These compatibility no-op paths now emit diagnostics, and become hard failures w
142143
- `--hash-style` now affects ELF dynamic-tag emission (`DT_HASH` / `DT_GNU_HASH`) in Dust runtime host writer output.
143144
- `--print-gc-sections` now prints section-drop diagnostics during GC-aware alloc-section selection.
144145
- Unsupported flag/target failures now emit explicit diagnostics instead of returning only status codes.
145-
- AArch64 ELF relocation coverage now includes instruction bitfield patching (`ADR_PREL_LO21`, MOVW families, `LD/ST` lo12 variants, branch/literal forms) and starter TLS relocation plumbing (`TLSGD`/`TLSLD`/`TLSDESC`, `TLS_DTPMOD`/`TLS_DTPREL`/`TLS_TPREL`).
146+
- AArch64 ELF relocation coverage now includes instruction bitfield patching (`ADR_PREL_LO21`, MOVW families, `LD/ST` lo12 variants, branch/literal forms) and stricter TLS-family handling:
147+
- `TLSDESC_CALL` now validates `BLR` instruction encoding instead of acting as a generic no-op
148+
- AArch64 TLS-family relocation application now fails with `ERR_NOT_IMPLEMENTED_YET` instead of silently patching placeholder values
149+
- Shared-library ingest now propagates shared-object ingest failures directly (no Dust-side `ERR_NOT_IMPLEMENTED_YET` swallow path).
146150

147151
## Build
148152

changelog.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,11 +57,12 @@
5757
- AArch64 ELF relocation parity expansions in Dust linker modules:
5858
- instruction-form bitfield patching for `CALL26`, `JUMP26`, `CONDBR19`, `TSTBR14`, `LD_PREL_LO19`, `ADR_PREL_LO21`, `ADR_PREL_PG_HI21(_NC)`, `ADD_ABS_LO12_NC`, and `LDST*_ABS_LO12_NC` (including `LDST128`)
5959
- MOVW relocation families (`UABS`, `SABS`, `PREL`)
60-
- starter TLS relocation families (`TLSGD`, `TLSLD`, `TLSDESC` instruction forms) and AArch64 TLS data relocs (`TLS_DTPMOD`, `TLS_DTPREL`, `TLS_TPREL`)
60+
- AArch64 TLS relocation ID recognition/validation for starter TLS families (`TLSGD`, `TLSLD`, `TLSDESC` instruction forms) and AArch64 TLS data relocs (`TLS_DTPMOD`, `TLS_DTPREL`, `TLS_TPREL`)
6161
- Additional Dust relocation/math tests for AArch64:
6262
- `ADR_PREL_LO21` patching
6363
- MOVW patching and overflow validation
6464
- AArch64 TLS data relocation value validation
65+
- `TLSDESC_CALL` instruction-shape validation (`BLR` accepted, non-`BLR` rejected)
6566

6667
### Changed
6768

@@ -83,13 +84,16 @@
8384
- `--print-gc-sections` now emits drop diagnostics during GC-based section pruning.
8485
- COFF and Mach-O object ingest relocation mapping is now machine-aware/refined instead of coarse fallback-only classification.
8586
- ELF relocation ingest validation and linker relocation pipeline now accept/process a broader AArch64 relocation surface (including MOVW and TLS starter forms) instead of rejecting them as unsupported.
87+
- Shared-library ingest in `linker_archive.ds` now propagates shared-object ingest errors directly instead of swallowing `ERR_NOT_IMPLEMENTED_YET`.
8688

8789
### Fixed
8890

8991
- Unsupported flag/target failures now print explicit diagnostics instead of returning a status code with no CLI context.
9092
- Linker script parser no longer silently accepts unknown directive heads.
9193
- Linker script `OUTPUT_FORMAT`, `TARGET`, and `OUTPUT_ARCH` invalid values now fail with explicit invalid/unsupported statuses instead of silently succeeding.
9294
- AArch64 64-bit TLS data relocations no longer fall through 32-bit relocation validation constraints in the Dust relocation validator.
95+
- AArch64 TLS-family relocation application no longer silently patches placeholder values; it now returns `ERR_NOT_IMPLEMENTED_YET` until TLS layout/module metadata is exposed to the Dust relocation pipeline.
96+
- `R_AARCH64_TLSDESC_CALL` patch helper no longer accepts arbitrary non-zero instructions; it now validates `BLR`-class encoding.
9397

9498
## 2026-02-21
9599

docs/README.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ This directory contains complete Markdown documentation for `dustlink`.
6161
- Compatibility no-op families now emit diagnostics and can hard-fail under `--fatal-warnings` / `/WX`.
6262
- `--dependency-file` and `--emit-relocs` are state-wired (depfile output + relocation map-row reporting).
6363
- ELF writer now consumes `--hash-style` state for dynamic hash-tag emission and host runtime consumes `--print-gc-sections` for GC drop diagnostics.
64-
- AArch64 ELF relocation coverage now includes instruction bitfield patching (branches/literals/ADR/ADRP/ADD/LDST, including `LDST128`), MOVW relocation families, and starter TLS relocation plumbing (`TLSGD`/`TLSLD`/`TLSDESC`, `TLS_DTPMOD`/`TLS_DTPREL`/`TLS_TPREL`).
64+
- AArch64 ELF relocation coverage now includes instruction bitfield patching (branches/literals/ADR/ADRP/ADD/LDST, including `LDST128`) and MOVW relocation families.
65+
- AArch64 TLS-family relocation IDs (`TLSGD`/`TLSLD`/`TLSDESC`, `TLS_DTPMOD`/`TLS_DTPREL`/`TLS_TPREL`) are recognized/validated, but relocation application is currently strict `ERR_NOT_IMPLEMENTED_YET` pending TLS layout/module metadata in the host linker runtime ABI.
66+
- Shared-library ingest now propagates shared-object ingest failures directly (no Dust-side `ERR_NOT_IMPLEMENTED_YET` swallow).
6567
- `lld-link` spellings: `/OUT`, `/ENTRY`, `/MACHINE`, `/LIBPATH`, `/DEFAULTLIB`, `/MAP`, `/DLL`, `/SUBSYSTEM`, `/OPT`, `/WX`, `/NOENTRY`, `/DYNAMICBASE`, `/NXCOMPAT`, `/LARGEADDRESSAWARE`.
6668
- soft-compatibility flag-family acceptance for broader ld/lld/lld-link compatibility while preserving deterministic internal link behavior.

docs/linker_reloc.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ Source: `src/linker_reloc.ds`
2727
- branch/literal/ADR forms: `R_AARCH64_CALL26`, `R_AARCH64_JUMP26`, `R_AARCH64_CONDBR19`, `R_AARCH64_TSTBR14`, `R_AARCH64_LD_PREL_LO19`, `R_AARCH64_ADR_PREL_LO21`, `R_AARCH64_ADR_PREL_PG_HI21`, `R_AARCH64_ADR_PREL_PG_HI21_NC`
2828
- lo12 forms: `R_AARCH64_ADD_ABS_LO12_NC`, `R_AARCH64_LDST8/16/32/64/128_ABS_LO12_NC`
2929
- MOVW families: `R_AARCH64_MOVW_UABS_*`, `R_AARCH64_MOVW_SABS_*`, `R_AARCH64_MOVW_PREL_*`
30-
- starter TLS forms: `TLSGD`, `TLSLD`, `TLSDESC` instruction relocations plus `R_AARCH64_TLS_DTPMOD`, `R_AARCH64_TLS_DTPREL`, `R_AARCH64_TLS_TPREL`
30+
- TLS families: `TLSGD`, `TLSLD`, `TLSDESC` instruction relocations plus `R_AARCH64_TLS_DTPMOD`, `R_AARCH64_TLS_DTPREL`, `R_AARCH64_TLS_TPREL`
3131

3232
## `K` Domain Procedures
3333

@@ -45,7 +45,9 @@ Source: `src/linker_reloc.ds`
4545
- `resolve_reloc_address(reloc, sym_addr, base_addr) -> UInt64`
4646

4747
`K` domain validates relocation records, computes relocation values, and applies patch operations through host runtime patch intrinsics (`host_linker_patch_u32`/`host_linker_patch_u64`).
48-
Current AArch64 support includes instruction bitfield patching for branch/literal/ADR/ADRP/ADD/LDST relocations, MOVW family relocations, and starter TLS relocation plumbing.
48+
Current AArch64 support includes instruction bitfield patching for branch/literal/ADR/ADRP/ADD/LDST relocations and MOVW family relocations.
49+
AArch64 TLS-family relocations are recognized/validated in this module, but application currently returns `ERR_NOT_IMPLEMENTED_YET` until TLS layout/module metadata is exposed by the host linker runtime ABI.
50+
`R_AARCH64_TLSDESC_CALL` helper now validates `BLR` instruction encoding before preserving the instruction word.
4951

5052
## `Q` and `Phi`
5153

docs/testing.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ Both files define forge-based test procedures with this pattern:
4747
- `LDST128` scaling/alignment behavior
4848
- `ADR_PREL_LO21` and MOVW patch/validation paths
4949
- starter AArch64 TLS data relocation value validation (`TLS_DTPMOD`, `TLS_TPREL`)
50+
- `TLSDESC_CALL` instruction-shape validation (`BLR` accepted, `BR` rejected)
5051

5152
## Recent Integration Checks
5253

@@ -72,6 +73,7 @@ Both files define forge-based test procedures with this pattern:
7273
- Linker core tests include AArch64 target acceptance in internal target validation.
7374
- `dust check src` passes for current Dust-source linker modules (host CLI + runtime parity changes).
7475
- `dust check src` passes after AArch64 relocation parity expansions (MOVW, `ADR_PREL_LO21`, and starter TLS relocation plumbing).
76+
- `dust check src` passes after stricter AArch64 TLS-family relocation handling (explicit `ERR_NOT_IMPLEMENTED_YET` apply path until TLS metadata support) and shared-ingest error propagation tightening.
7577

7678
## Current Limitations
7779

src/linker_archive.ds

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ forge LinkerArchive {
55
const ERR_FILE_NOT_FOUND: UInt32 = 1;
66
const ERR_INVALID_FORMAT: UInt32 = 2;
77
const ERR_CONFLICTING_OPTIONS: UInt32 = 16;
8-
const ERR_NOT_IMPLEMENTED_YET: UInt32 = 17;
98

109
const TARGET_NONE: UInt32 = 0;
1110
const TARGET_X86_64_LINUX: UInt32 = 1;
@@ -684,9 +683,7 @@ forge LinkerArchive {
684683
let unresolved_before = host_linker_unresolved_symbol_count();
685684
let shared_status = host_linker_ingest_shared_object(path);
686685
if shared_status ! ERR_OK {
687-
if shared_status ! ERR_NOT_IMPLEMENTED_YET {
688-
return shared_status;
689-
}
686+
return shared_status;
690687
}
691688
let unresolved_after = host_linker_unresolved_symbol_count();
692689
let contributed = shared_contribution(unresolved_before, unresolved_after);

src/linker_math_tests.ds

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ forge LinkerMathTests {
2525
const R_AARCH64_LDST32_ABS_LO12_NC: UInt32 = 285;
2626
const R_AARCH64_LDST64_ABS_LO12_NC: UInt32 = 286;
2727
const R_AARCH64_LDST128_ABS_LO12_NC: UInt32 = 299;
28+
const R_AARCH64_TLSDESC_CALL: UInt32 = 569;
2829
const R_AARCH64_TLS_DTPMOD: UInt32 = 1028;
2930
const R_AARCH64_TLS_TPREL: UInt32 = 1030;
3031

@@ -190,6 +191,18 @@ forge LinkerMathTests {
190191
return expect_u64(patched, 0);
191192
}
192193

194+
proc K::test_aarch64_tlsdesc_call_patch_word_accepts_blr() -> UInt32 {
195+
let blr_x17 = 3594453536;
196+
let patched = LinkerReloc::K::aarch64_tlsdesc_call_patch_word(blr_x17);
197+
return expect_u64(patched, blr_x17);
198+
}
199+
200+
proc K::test_aarch64_tlsdesc_call_patch_word_rejects_br() -> UInt32 {
201+
let br_x17 = 3592356384;
202+
let patched = LinkerReloc::K::aarch64_tlsdesc_call_patch_word(br_x17);
203+
return expect_u64(patched, 0);
204+
}
205+
193206
proc K::test_aarch64_tls_dtpmod_accepts_64bit_value() -> UInt32 {
194207
let status = LinkerReloc::K::validate_relocation_value(R_AARCH64_TLS_DTPMOD, EM_AARCH64, 4294967296);
195208
return expect_u32(status, ERR_OK);
@@ -228,6 +241,8 @@ forge LinkerMathTests {
228241
+ test_aarch64_ldst128_lo12_patch_word_scaled()
229242
+ test_aarch64_ldst_lo12_patch_word_alignment_rejects()
230243
+ test_aarch64_ldst128_lo12_patch_word_alignment_rejects()
244+
+ test_aarch64_tlsdesc_call_patch_word_accepts_blr()
245+
+ test_aarch64_tlsdesc_call_patch_word_rejects_br()
231246
+ test_aarch64_tls_dtpmod_accepts_64bit_value()
232247
+ test_aarch64_tls_tprel_accepts_64bit_value();
233248
return passed;

src/linker_reloc.ds

Lines changed: 45 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ forge LinkerReloc {
8787
const ERR_INVALID_SECTION: UInt32 = 3;
8888
const ERR_UNDEFINED_SYMBOL: UInt32 = 4;
8989
const ERR_INVALID_RELOCATION: UInt32 = 6;
90+
const ERR_NOT_IMPLEMENTED_YET: UInt32 = 17;
9091

9192
proc K::is_supported_reloc_x86_64(reloc_type: UInt32) -> UInt32 {
9293
if reloc_type == R_X86_64_NONE { return 1; }
@@ -464,6 +465,36 @@ forge LinkerReloc {
464465
return 0;
465466
}
466467

468+
proc K::aarch64_is_tls_family_reloc(reloc_type: UInt32) -> UInt32 {
469+
if reloc_type == R_AARCH64_TLSGD_ADR_PREL21 { return 1; }
470+
if reloc_type == R_AARCH64_TLSGD_ADR_PAGE21 { return 1; }
471+
if reloc_type == R_AARCH64_TLSGD_ADD_LO12_NC { return 1; }
472+
if reloc_type == R_AARCH64_TLSGD_MOVW_G1 { return 1; }
473+
if reloc_type == R_AARCH64_TLSGD_MOVW_G0_NC { return 1; }
474+
if reloc_type == R_AARCH64_TLSLD_ADR_PREL21 { return 1; }
475+
if reloc_type == R_AARCH64_TLSLD_ADR_PAGE21 { return 1; }
476+
if reloc_type == R_AARCH64_TLSLD_ADD_LO12_NC { return 1; }
477+
if reloc_type == R_AARCH64_TLSLD_MOVW_G1 { return 1; }
478+
if reloc_type == R_AARCH64_TLSLD_MOVW_G0_NC { return 1; }
479+
if reloc_type == R_AARCH64_TLSLD_LD_PREL19 { return 1; }
480+
if reloc_type == R_AARCH64_TLSLD_ADD_DTPREL_LO12_NC { return 1; }
481+
if reloc_type == R_AARCH64_TLSLD_LDST64_DTPREL_LO12_NC { return 1; }
482+
if reloc_type == R_AARCH64_TLSLD_LDST128_DTPREL_LO12_NC { return 1; }
483+
if reloc_type == R_AARCH64_TLSLE_ADD_TPREL_LO12_NC { return 1; }
484+
if reloc_type == R_AARCH64_TLSLE_LDST64_TPREL_LO12_NC { return 1; }
485+
if reloc_type == R_AARCH64_TLSLE_LDST128_TPREL_LO12_NC { return 1; }
486+
if reloc_type == R_AARCH64_TLSDESC_LD_PREL19 { return 1; }
487+
if reloc_type == R_AARCH64_TLSDESC_ADR_PREL21 { return 1; }
488+
if reloc_type == R_AARCH64_TLSDESC_ADR_PAGE21 { return 1; }
489+
if reloc_type == R_AARCH64_TLSDESC_LD64_LO12 { return 1; }
490+
if reloc_type == R_AARCH64_TLSDESC_ADD_LO12 { return 1; }
491+
if reloc_type == R_AARCH64_TLSDESC_CALL { return 1; }
492+
if reloc_type == R_AARCH64_TLS_DTPMOD { return 1; }
493+
if reloc_type == R_AARCH64_TLS_DTPREL { return 1; }
494+
if reloc_type == R_AARCH64_TLS_TPREL { return 1; }
495+
return 0;
496+
}
497+
467498
proc K::aarch64_page_delta_bytes(symbol_plus_addend: UInt64, place_addr: UInt64) -> UInt64 {
468499
let page_mask = 0 - 4096;
469500
let sym_page = symbol_plus_addend & page_mask;
@@ -677,10 +708,16 @@ forge LinkerReloc {
677708
}
678709

679710
proc K::aarch64_tlsdesc_call_patch_word(instr: UInt64) -> UInt64 {
711+
let blr_mask = 4294966303;
712+
let blr_opcode = 3594452992;
680713
if instr == 0 {
681714
return 0;
682715
} else {
683-
return instr;
716+
if (instr & blr_mask) ! blr_opcode {
717+
return 0;
718+
} else {
719+
return instr;
720+
}
684721
}
685722
}
686723

@@ -1499,6 +1536,13 @@ forge LinkerReloc {
14991536
} else {
15001537
let symbol_defined = host_linker_object_symbol_defined(object_index, sym_index);
15011538
let symbol_addr = host_linker_resolved_symbol_address(object_index, sym_index);
1539+
if machine == EM_AARCH64 {
1540+
if aarch64_is_tls_family_reloc(reloc_type) == 1 {
1541+
// AArch64 TLS relocations require TLS block/layout/module metadata not yet surfaced
1542+
// through the current Dust host linker runtime ABI.
1543+
return ERR_NOT_IMPLEMENTED_YET;
1544+
}
1545+
}
15021546
if symbol_defined == 0 {
15031547
if symbol_addr == 0 {
15041548
if is_dynamic_placeholder_reloc(reloc_type, machine) == 1 {

0 commit comments

Comments
 (0)