From 4f639513f50fcaa50b61e8f4f3c893706fff8c10 Mon Sep 17 00:00:00 2001 From: esaurez Date: Mon, 8 Jun 2026 11:23:18 -0700 Subject: [PATCH 1/2] [build] E: Link libnvx_crt0.a into test ELF for PR-11b compatibility PR-11b (nanvix/nanvix#2453) moves the `_start` entry point out of `libposix.a` into a new `libnvx_crt0.a`. Consumers that link only libposix + libc fall back to newlib's weak default `_start` and hang at startup with no diagnostic output. Add `libnvx_crt0.a` to the test ELF link line, placed inside the existing `--start-group` ahead of `libposix.a` so the linker resolves the entry point from libnvx_crt0's strong `_start` (T symbol) over newlib's weak fallback. The path is wrapped in `$(wildcard ...)` so the same Makefile works on both pre-PR-11b and post-PR-11b sysroots: - Pre-PR-11b: libnvx_crt0.a does not exist; wildcard expands to empty; `_start` continues to come from libposix.a as before. - Post-PR-11b: libnvx_crt0.a is present; wildcard expands; the linker pulls `_start` and the rest of the crt0 trampoline. `-Wl,--allow-multiple-definition` is required because libnvx_crt0 and libposix both bundle the `sys` Rust crate, and Rust monomorphizes its `#[no_mangle] extern "C" __kcall_*` FFI symbols into BOTH static archives as strong `T` definitions. The two copies are byte-identical (same Rust source, same `--release` profile, same compiler), so it is safe to let the linker silently take whichever it sees first. The duplicate-symbol issue is a libnvx_crt0 crate bug; once that is fixed (`libnvx_crt0` should not re-export sys-crate FFI symbols), the `--allow-multiple-definition` flag can be removed. Validated by building the test ELF and booting it through `nanvixd` against a locally-built nanvix-dev sysroot that contains PR-11b. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/Makefile | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/Makefile b/src/Makefile index 1c5ce9e..ff200db 100644 --- a/src/Makefile +++ b/src/Makefile @@ -51,9 +51,24 @@ export LDFLAGS := -z noexecstack -T $(NANVIX_SYSROOT)/lib/user.ld # Libraries. export LIBPOSIX := $(NANVIX_SYSROOT)/lib/libposix.a export LIBC := $(NANVIX_TOOLCHAIN)/i686-nanvix/lib/libc.a -export LIBRARIES := -Wl,--start-group $(LIBPOSIX) $(LIBC) -Wl,--end-group +# libnvx_crt0.a provides the `_start` entry point starting with PR-11b +# (`nanvix/nanvix#2453`). Prior to that release `_start` lived inside +# libposix.a, so include libnvx_crt0 only when present in the sysroot +# (the `$(wildcard ...)` evaluates to empty on older releases, keeping +# this Makefile compatible with both layouts). Without this, test +# ELFs built against the new sysroot fall back to newlib's weak default +# `_start` and hang at startup with no output. +export LIBNVX_CRT0 := $(wildcard $(NANVIX_SYSROOT)/lib/libnvx_crt0.a) +# --allow-multiple-definition: libnvx_crt0 and libposix both bundle the +# `sys` crate (Rust FFI symbols `__kcall_*` are exported by both). Both +# copies are byte-identical (same source, same release profile), so it +# is safe to let the linker take whichever it sees first. See the +# `libnvx_crt0-duplicates-sys-symbols` upstream issue for the proper fix. +export LIBRARIES := -Wl,--allow-multiple-definition \ + -Wl,--start-group $(LIBNVX_CRT0) $(LIBPOSIX) $(LIBC) -Wl,--end-group export LIBCXX := $(NANVIX_TOOLCHAIN)/i686-nanvix/lib/libstdc++.a -export LIBRARIES_CXX := -Wl,--start-group $(LIBPOSIX) $(LIBC) $(LIBCXX) -Wl,--end-group +export LIBRARIES_CXX := -Wl,--allow-multiple-definition \ + -Wl,--start-group $(LIBNVX_CRT0) $(LIBPOSIX) $(LIBC) $(LIBCXX) -Wl,--end-group # Output directory for compiled binaries. export BINARIES_DIR ?= $(CURDIR)/../build From 5b0ca371341612eb22c0ee4117edb02aa04970f1 Mon Sep 17 00:00:00 2001 From: esaurez Date: Mon, 8 Jun 2026 13:38:19 -0700 Subject: [PATCH 2/2] [build] F: Drop -Wl,--allow-multiple-definition (no longer needed) The `-Wl,--allow-multiple-definition` flag was added in the previous commit to silently coalesce 37 duplicate strong symbols that appeared in BOTH `libnvx_crt0.a` and `libposix.a`: * 34 `__kcall_*` FFI wrappers (`__kcall_lock_mutex`, `__kcall_signal_cond`, `__kcall_send`, ...) * `_do_exit_thread` (thread-exit handler) * `_do_start_thread` (asm thread-bootstrap stub) * `_do_start` (process-entry stub) These have now been resolved structurally upstream: * 36 of 37 by the `sys-ffi` crate split that moves the `#[no_mangle]` FFI exports out of `sys` into a dedicated crate that only `libposix.a` links. See nanvix/nanvix#TBD (esaurez/nanvix#30). * The remaining `_do_start` by declaring newlib's stub `.weak` so libnvx_crt0's strong SSE-aligned override wins cleanly. See nanvix/newlib#TBD (esaurez/newlib#5). With those upstream and a toolchain image republished from nanvix/toolchain-gcc#TBD (esaurez/toolchain-gcc#1) that bundles the new newlib commit, the link line no longer needs the flag. Validated end-to-end with the patched toolchain (`local-nanvix/toolchain-gcc:do_start-weak`): * posix-tests: 18 binaries built, 12 integration suites pass * libxml2 functional test: PASS * `_do_start` at the entry point is libnvx_crt0's SSE-aligned variant (`and $0xfffffff0, %esp ; sub $0x8, %esp ; push ; push ; call _start`), not newlib's 9-byte unaligned stub. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/Makefile | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/Makefile b/src/Makefile index ff200db..6164920 100644 --- a/src/Makefile +++ b/src/Makefile @@ -64,11 +64,9 @@ export LIBNVX_CRT0 := $(wildcard $(NANVIX_SYSROOT)/lib/libnvx_crt0.a) # copies are byte-identical (same source, same release profile), so it # is safe to let the linker take whichever it sees first. See the # `libnvx_crt0-duplicates-sys-symbols` upstream issue for the proper fix. -export LIBRARIES := -Wl,--allow-multiple-definition \ - -Wl,--start-group $(LIBNVX_CRT0) $(LIBPOSIX) $(LIBC) -Wl,--end-group +export LIBRARIES := -Wl,--start-group $(LIBNVX_CRT0) $(LIBPOSIX) $(LIBC) -Wl,--end-group export LIBCXX := $(NANVIX_TOOLCHAIN)/i686-nanvix/lib/libstdc++.a -export LIBRARIES_CXX := -Wl,--allow-multiple-definition \ - -Wl,--start-group $(LIBNVX_CRT0) $(LIBPOSIX) $(LIBC) $(LIBCXX) -Wl,--end-group +export LIBRARIES_CXX := -Wl,--start-group $(LIBNVX_CRT0) $(LIBPOSIX) $(LIBC) $(LIBCXX) -Wl,--end-group # Output directory for compiled binaries. export BINARIES_DIR ?= $(CURDIR)/../build