kit

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

commit ecd87b418b7a7aa82599b42b633cbdf724c2e25c
parent 7e14bdec70dcc26fe4970524bbc3b36707097be5
Author: Ryan Sepassi <rsepassi@gmail.com>
Date:   Thu, 16 Jul 2026 10:45:10 -0700

link: preserve explicit targets and RISC-V ABI flags

Diffstat:
Mdriver/cmd/ld.c | 2+-
Msrc/obj/elf/emit.c | 18+++++++++++-------
Msrc/obj/elf/reloc_riscv64.c | 15+++++++--------
3 files changed, 19 insertions(+), 16 deletions(-)

diff --git a/driver/cmd/ld.c b/driver/cmd/ld.c @@ -2935,7 +2935,7 @@ static int ld_run_link(LdOptions* o) { * a freestanding (`*-none-elf`, EI_OSABI=STANDALONE) object means a * freestanding link even if a foreign object (e.g. a clang-assembled startup * stub, which stamps EI_OSABI=SysV and so decodes as Linux) appears first. */ - if (initial_nobject_files > 0) { + if (!o->target_explicit && initial_nobject_files > 0) { KitTargetSpec detected; if (kit_detect_target(obj_lf[0].data.data, obj_lf[0].data.size, &detected) == KIT_OK) { diff --git a/src/obj/elf/emit.c b/src/obj/elf/emit.c @@ -720,20 +720,24 @@ void emit_elf(Compiler* c, ObjBuilder* ob, Writer* w) { } } /* e_flags: prefer the value preserved from a prior read (round-trip); - * else synthesize a sensible per-arch default. RV64 kit targets the - * Linux psABI's lp64d soft-relax convention (RVC + double-float ABI). */ + * otherwise derive the RISC-V ABI/features from the resolved target rather + * than the arch descriptor's default profile. */ u32 e_flags; if (!obj_get_elf_e_flags(ob, &e_flags)) { e_flags = elf->e_flags; - /* rv32 (ptr_size 4): ilp32 and ilp32f share KIT_ARCH_RV32, so the static - * descriptor's float-ABI bits (a placeholder SINGLE) cannot be right for - * both. Derive them from -mabi (float_abi); RVC and other descriptor bits - * are kept. rv64 (ptr_size 8) is left untouched, preserving its e_flags. */ + /* Both XLENs expose multiple psABIs through -mabi. The static descriptors + * describe only their default profiles, so replace the float bits and the + * RVC presence bit with the resolved target values. */ if (e_machine == EM_RISCV) { Compiler* ec = obj_compiler(ob); - if (ec && ec->target.ptr_size == 4u) { + if (ec) { u32 fa = elf_riscv_float_abi_to_e_flags(ec->target.float_abi); e_flags = (e_flags & ~(u32)EF_RISCV_FLOAT_ABI_MASK) | fa; + if (ec->target_ref && + kit_target_has_feature(ec->target_ref, KIT_SLICE_LIT("c"))) + e_flags |= EF_RISCV_RVC; + else + e_flags &= ~(u32)EF_RISCV_RVC; } } /* ARM: keep the EABI version (top byte) from the descriptor and override diff --git a/src/obj/elf/reloc_riscv64.c b/src/obj/elf/reloc_riscv64.c @@ -297,14 +297,13 @@ KitFloatAbi elf_riscv_float_abi_from_e_flags(u32 e_flags) { } } -/* Encode the float ABI into RISC-V ELF e_flags (the EF_RISCV_FLOAT_ABI_* bits; - * caller masks them into e_flags with EF_RISCV_FLOAT_ABI_MASK). Inverse of - * elf_riscv_float_abi_from_e_flags, kept here so the format-generic ELF writers - * (emit.c ET_REL, link.c ET_EXEC) don't inline the mapping. - * KIT_FLOAT_ABI_DEFAULT resolves to SINGLE: the rv32 ilp32/ilp32f pair shares - * one KitArchKind, so the static descriptor's float bits are a placeholder and - * -mabi DEFAULT means the rv32 default profile (ilp32f). XLEN-neutral; only the - * rv32 writers call it. */ +/* Encode the resolved float ABI into RISC-V ELF e_flags (the + * EF_RISCV_FLOAT_ABI_* bits; callers mask them into e_flags with + * EF_RISCV_FLOAT_ABI_MASK). Inverse of elf_riscv_float_abi_from_e_flags, kept + * here so the format-generic ELF writers (emit.c ET_REL, link.c ET_EXEC) do not + * inline the mapping. KitTarget construction resolves the ABI for both XLENs; + * DEFAULT retains the historical single-float fallback for a synthetic target + * that bypasses normal construction. */ u32 elf_riscv_float_abi_to_e_flags(KitFloatAbi abi) { switch (abi) { case KIT_FLOAT_ABI_SINGLE: