kit

kit
git clone https://git.ryansepassi.com/git/kit.git
Log | Files | Refs | README

commit 034c337916199487593e4e99dfddfed77e66cc6d
parent a607d9e0169a971697a9073770e075477e079853
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Tue, 16 Jun 2026 17:26:19 -0700

arm32 Phase 2: canonical branch/call placeholders (clang -4 in-field form)

kit emitted BL/B.W/Bcond.W with all-zero immediate fields (f000 d000 etc.),
which for ARM ELF REL relocations decode (via I1=NOT(J1^S)) to a bogus
+0xC00000 in-field addend that stock ARM linkers (ld.lld, gas ld) apply.
Emit the canonical clang/gas 'branch to self' placeholders (encoded -4), which
those linkers read as the correct addend. kit's own linker overwrites the
field, so this is inert for kit ld (still byte-correct). Prerequisite for ARM
REL reloc emission (external-linker compatibility).

Diffstat:
Msrc/arch/arm32/isa.h | 15+++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/src/arch/arm32/isa.h b/src/arch/arm32/isa.h @@ -225,12 +225,19 @@ static inline u16 arm_mov_hi(u32 rd, u32 rm) { return (u16)(0x4600u | ((rd >> 3) << 7) | (rm << 3) | (rd & 7u)); } -/* --------- branches (placeholders; immediate filled by reloc/label-fixup) --- */ -static inline u32 arm_b_w(void) { return arm_t32(0xf000u, 0x9000u); } /* B.W (T4) */ +/* --------- branches (placeholders; immediate filled by reloc/label-fixup) --- + * The immediate fields use the canonical clang/gas "branch to self" pattern + * (encoded displacement -4). For ARM ELF the branch relocs are REL, so the + * in-field bits ARE the addend an external linker (ld.lld, gas's ld) reads; an + * all-zero field decodes (via I1=NOT(J1^S)) to a bogus +0xC00000, which those + * linkers then apply. kit's OWN linker overwrites the field (mask 0xf800d000 / + * the JUMP19 imm mask), so the placeholder is inert for kit ld — these values + * exist purely to keep kit objects linkable by stock ARM linkers. */ +static inline u32 arm_b_w(void) { return arm_t32(0xf7ffu, 0xbffeu); } /* B.W (T4) */ static inline u32 arm_b_cond_w(u32 cond) { /* B<cond>.W (T3) */ - return arm_t32(0xf000u | (cond << 6), 0x8000u); + return arm_t32(0xf43fu | (cond << 6), 0xaffeu); } -static inline u32 arm_bl(void) { return arm_t32(0xf000u, 0xd000u); } /* BL (T1) */ +static inline u32 arm_bl(void) { return arm_t32(0xf7ffu, 0xfffeu); } /* BL (T1) */ /* --------- 16-bit instructions --------- */ static inline u16 arm_bx(u32 rm) { return (u16)(0x4700u | (rm << 3)); }