[build] E: Link libnvx_crt0.a into test ELF for PR-11b compatibility#2
[build] E: Link libnvx_crt0.a into test ELF for PR-11b compatibility#2esaurez wants to merge 8 commits into
Conversation
…sion [ci] Sync zutils v0.10.4
…sion [ci] Sync zutils v0.10.4
…sion [ci] Sync zutils v0.10.4
Validation update — squashed in fixup commitEnd-to-end validation against a locally-built nanvix-dev sysroot with PR-11b surfaced a hard linker error in the original Pushed fixup commit that switches to: With libnvx_crt0.a inside the start-group ahead of libposix.a, the linker resolves the entry-point The Validated by building + running the test ELF via Follow-up upstream issue (not addressed here): the duplicate |
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>
107ff5a to
d6da83b
Compare
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>
|
Superseded by upstream PR nanvix#74, which carries the same compat fix -- rebased onto the corresponding upstream branch (port libs stack on top of the freshly-filed Wave 3 .so PR; posix-tests stacks on nanvix/posix-tests#177), with only the |
Summary
PR-11b (nanvix/nanvix#2453) moves the
_startentry point out oflibposix.ainto a newlibnvx_crt0.a. Consumers that link onlylibposix/libcfall back to newlib's weak default_startand hang at startup with no diagnostic output.This PR adds
libnvx_crt0.ato the test ELF link line in.nanvix/Makefile.nanvix. Uses$(wildcard ...)so the path is only included when the file exists, keeping the Makefile compatible with both:libnvx_crt0.aabsent;_startstill inlibposix.a. Wildcard returns empty, link line unchanged.libnvx_crt0.apresent;libposix.ano longer carries_start. Wildcard expands,_startis provided.Why this matters now
Without this change, the next nanvix release that includes PR-11b will silently break this repo's functional test — it would still build but hang at startup with no diagnostic output.
What's in this PR
Two commits on
.nanvix/Makefile.nanvix(3-line net change):[build] E: Link libnvx_crt0.a into test ELF for PR-11b compatibility— adds$(wildcard $(SYSROOT_PATH)/lib/libnvx_crt0.a)to the TEST_ELF link rule, inside the existing--start-group, ahead of$(NANVIX_LIBS). Initially landed with-Wl,--allow-multiple-definitionas a safety flag to coalesce duplicate strong symbols (__kcall_*,_do_exit_thread,_do_start_thread,_do_start) that appeared in bothlibnvx_crt0.aandlibposix.aonce PR-11b forced them into the same link line.[build] F: Drop -Wl,--allow-multiple-definition (no longer needed)— the safety flag is no longer required after the upstream cleanup chain (sys-ffi crate split forlibposix.a+.weak _do_startfor newlib'scrt0.o) eliminates all 37 duplicate strong symbols at the source. The cleanup chain is a companion to this PR series:sys-fficrate split (resolves 36 of 37 duplicates:__kcall_*×34,_do_exit_thread,_do_start_thread)_do_startweakening (resolves the 37th)How to merge this PR independently of the cleanup chain
If you want to merge this PR before the cleanup chain lands and the toolchain image is republished, revert the
F:fixup commit and keep-Wl,--allow-multiple-definitionin the link line. The flag is purely defensive (silently coalesces byte-identical duplicate strong symbols, which is safe but hides legitimate collisions). Functional behavior of the test ELF is unchanged either way:F:fixup commit + the new toolchain image → cleanest link line, no flag.F:commit (flag retained) → no toolchain dependency, merges immediately.Validation
End-to-end validated against a locally-built nanvix sysroot that includes PR-11b:
nmconfirms the resulting test ELF resolves_startfromlibnvx_crt0.a(not newlib's weak fallback).nanvixd.exetotest_libxml2: PASS.F:fixup commit applied (against a sysroot built from the cleanup chain), the link line drops--allow-multiple-definitionand the resulting binary uses libnvx_crt0's SSE-aligned_do_startat the entry point (verified by disassembly:and $0xfffffff0, %esp; sub $0x8, %esp; ...) — fixing a latent SSE-alignment bug that was previously masked when newlib's 9-byte unaligned_do_startwon the link.Related work (informational)
The same one-line fix is being filed against every port-library repo that builds a test ELF on a Nanvix sysroot (
nanvix/posix-tests,nanvix/libxml2,nanvix/libxslt,nanvix/lxml,nanvix/libffi,nanvix/openssl). Each PR is functionally independent — they can be reviewed and merged in any order.