Skip to content

[build] F: Pin newlib to _do_start-weak commit, restore reproducible newlib checkout#14

Draft
esaurez wants to merge 1 commit into
nanvix:mainfrom
esaurez:chore/bump-newlib-for-do_start-weak-upstream
Draft

[build] F: Pin newlib to _do_start-weak commit, restore reproducible newlib checkout#14
esaurez wants to merge 1 commit into
nanvix:mainfrom
esaurez:chore/bump-newlib-for-do_start-weak-upstream

Conversation

@esaurez

@esaurez esaurez commented Jun 9, 2026

Copy link
Copy Markdown

Summary

Two related fixes, both touching the newlib clone step of the toolchain Dockerfile.

1. Bump NEWLIB_COMMIT to the _do_start weakening

Updates ARG NEWLIB_COMMIT to point at the merge commit of nanvix/newlib#17 ("[libc] F: Weaken _do_start so libnvx_crt0.a can override it cleanly"). Once the new toolchain image is republished, consumers linking Nanvix's libnvx_crt0.a will no longer need -Wl,--allow-multiple-definition on their guest test ELF link lines. The SHA in the diff is a placeholder pointing at #17's branch HEAD and must be re-pointed at the upstream merge commit before this PR merges.

2. Restore reproducibility of the newlib checkout

The prior git clone --branch dev --single-branch --depth=1 step silently used the tip of dev regardless of the declared NEWLIB_COMMIT pin, so every toolchain image rebuild could pick up a different newlib commit even when NEWLIB_COMMIT was unchanged. Removing --depth=1 --single-branch and adding an explicit git checkout ${NEWLIB_COMMIT} after the clone restores the pin. The new shape is identical to the binutils and gcc clone steps in the same file.

This is independently useful even if the SHA bump is reverted: it makes the toolchain build reproducible against any pinned newlib commit, not just the one for #17.

Diff

-ARG NEWLIB_COMMIT=e12d84a6789c07f938db4f6440ea0b427914c735
+# Pinned to the merge commit of nanvix/newlib#17 ("[libc] F: Weaken
+# _do_start so libnvx_crt0.a can override it cleanly").  Update this
+# SHA to the upstream merge commit before merging the present PR.
+ARG NEWLIB_COMMIT=881840f880350e6fd929629cef9a5a3d1708bbf4

-# Clone Newlib.
-RUN git clone --branch ${NEWLIB_BRANCH} --single-branch --depth=1 \
-    https://github.com/nanvix/newlib /build/newlib
+# Clone Newlib and pin to ${NEWLIB_COMMIT} (prior versions of this
+# Dockerfile cloned with --depth=1 only and silently used the tip of
+# ${NEWLIB_BRANCH} regardless of the declared pin, which made the
+# build non-reproducible).  Fetching with sufficient depth and then
+# checking out ${NEWLIB_COMMIT} restores the pin.
+RUN git clone --branch ${NEWLIB_BRANCH} \
+    https://github.com/nanvix/newlib /build/newlib && \
+    cd /build/newlib && git checkout ${NEWLIB_COMMIT}

Validation

Reviewers who want to confirm the effect of #17 on the produced toolchain sysroot without waiting for a full toolchain rebuild can use the small local-only Dockerfile below. It starts from the official toolchain image, surgically reassembles crt0.S from a patched newlib tree, overlays the resulting crt0.o onto the sysroot, and asserts that _do_start becomes a weak symbol.

The same companion changes already in flight in the rest of the chain provide the consumer-side proof:

  • nanvix/newlib#17 — the source-side .weak _do_start change.
  • nanvix/nanvix#2487 — splits the other 36 duplicate strong symbols (__kcall_* x 34, _do_exit_thread, _do_start_thread) out of libnvx_crt0.a into a dedicated sys-ffi crate. After both this PR (republished image) and #2487 land, every Nanvix link line can drop -Wl,--allow-multiple-definition.

Local validation Dockerfile (not committed; copy and run from a sibling toolchain-gcc + newlib checkout pair)

# Local-only Dockerfile to validate the nanvix/newlib `_do_start` weakening
# fix WITHOUT a full toolchain rebuild.  Starts from the official base image
# and surgically rebuilds the `crt0.S` source from a patched newlib tree,
# then overlays the resulting `crt0.o` onto the toolchain sysroot.
#
# After this patch:
#   * `/opt/nanvix/i686-nanvix/lib/crt0.o` defines `_do_start` as a WEAK
#     (`W`) symbol instead of STRONG (`T`).
#   * `libnvx_crt0.a`'s strong `_do_start` override now wins at link time
#     without `-Wl,--allow-multiple-definition`.
#
# Usage (run from a toolchain-gcc working tree with a sibling newlib
# checkout that has nanvix/newlib#17 applied; `<newlib-path>` is the
# absolute path to that newlib checkout):
#   docker build --build-context newlib=<newlib-path> \
#       -f Dockerfile.localpatch-do_start \
#       -t local-nanvix/toolchain-gcc:do_start-weak .
#
# Verification:
#   docker run --rm local-nanvix/toolchain-gcc:do_start-weak \
#       i686-nanvix-nm /opt/nanvix/i686-nanvix/lib/crt0.o
#   Expected: `00000000 W _do_start` (weak, not strong T).

FROM ghcr.io/nanvix/toolchain-gcc:sha-34a3641

# DO NOT set `ENV TARGET=` or `ENV PREFIX=` here.  The published
# toolchain-gcc runtime image deliberately drops those build-time
# variables; setting them again leaks into autotools-based downstream
# builds.  In particular, libffi's `AX_ENABLE_BUILDDIR` macro
# (m4/ax_enable_builddir.m4) computes its build subdir from `$TARGET`
# if the variable is set, defeating config.sub's canonicalization of
# `i686-nanvix` -> `i686-pc-nanvix`.  The result is that the build
# lands in `./i686-nanvix/` while downstream Makefiles look in
# `./i686-pc-nanvix/`, breaking the link step.
#
# The `PATH` extension is the only inherited env override that is
# safe and necessary.

# Copy just the patched crt0.S source.
COPY --from=newlib newlib/libc/sys/nanvix/crt0.S /build/patch/crt0.S

# Normalize line endings -- Windows checkouts may carry CRLF.
RUN sed -i 's/\r$//' /build/patch/crt0.S

# Reassemble crt0.S into crt0.o.
RUN /opt/nanvix/bin/i686-nanvix-as \
        /build/patch/crt0.S \
        -o /build/patch/crt0.o

# Replace the toolchain sysroot's crt0.o.
RUN cp /build/patch/crt0.o /opt/nanvix/i686-nanvix/lib/crt0.o

# Verify: _do_start must now be WEAK, not STRONG.
RUN result=$(/opt/nanvix/bin/i686-nanvix-nm /opt/nanvix/i686-nanvix/lib/crt0.o); \
    echo "$result"; \
    echo "$result" | grep -qE '^[0-9a-f]+ W _do_start$' \
        || (echo "VERIFY FAILED: _do_start is not WEAK in patched crt0.o" && exit 1) \
    && echo "VERIFY OK: _do_start is now WEAK in crt0.o"

End-to-end with this local patch in place, posix-tests integration suites and libxml2 functional tests link cleanly without -Wl,--allow-multiple-definition, and the SSE-aligned _do_start from libnvx_crt0.a shows up at the entry point in the produced ELFs.

Merge ordering

This PR depends on nanvix/newlib#17 merging first so the NEWLIB_COMMIT SHA above can be re-pointed at the upstream merge commit. Once both land and CI republishes the toolchain image, consumer-side follow-up PRs in nanvix/nanvix and the port-library repositories will drop -Wl,--allow-multiple-definition from every link line. Those follow-up PRs are in progress.

…newlib checkout

Two related fixes, both touching the newlib clone step of the
toolchain Dockerfile:

1. Bump NEWLIB_COMMIT to the merge commit of nanvix/newlib#17
   ("[libc] F: Weaken _do_start so libnvx_crt0.a can override it
   cleanly").  After the new image is republished, consumers
   linking Nanvix's libnvx_crt0.a no longer need
   `-Wl,--allow-multiple-definition` on their guest test ELF link
   lines.  The SHA above is a placeholder for #17's branch HEAD
   and must be re-pointed at the upstream merge commit before
   this PR merges.

2. Restore reproducibility of the newlib checkout.  The prior
   `git clone --branch dev --single-branch --depth=1` step silently
   used the tip of `dev` regardless of the declared NEWLIB_COMMIT
   pin, so every toolchain image rebuild could pick up a different
   newlib commit even when NEWLIB_COMMIT was unchanged.  Removing
   `--depth=1 --single-branch` and adding an explicit
   `git checkout ${NEWLIB_COMMIT}` after the clone restores the
   pin.  This is the same shape already used by the binutils and
   gcc clone steps in this file.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This was referenced Jun 9, 2026
esaurez added a commit to esaurez/libxml2 that referenced this pull request Jun 9, 2026
… working

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-cutover and post-cutover sysroots:

  - Pre-cutover (sysroot built before nanvix/nanvix#2453):
    libnvx_crt0.a does not exist; wildcard expands to empty;
    `_start` continues to come from libposix.a as before.
  - Post-cutover (sysroot built after nanvix/nanvix#2453):
    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 today both contain duplicate strong definitions of
the sys-crate `__kcall_*` FFI symbols, `_do_exit_thread`, and
`_do_start_thread`.  All 36 of those duplicates are addressed by
nanvix/nanvix#2487 (sys-ffi crate split), which moves the
`#[no_mangle]` exports out of `sys` into a dedicated crate that
only `libposix.a` links.  The remaining 37th duplicate (`_do_start`
colliding between libnvx_crt0 and newlib's prebuilt `crt0.o`) is
addressed by nanvix/newlib#17 (`.weak _do_start` so libnvx_crt0's
strong SSE-aligned override wins cleanly).  Once both have landed
and the toolchain image republished from nanvix/toolchain-gcc#14,
`--allow-multiple-definition` can be dropped in a follow-up commit.

Validated by building the test ELF and booting it through `nanvixd`
against a locally-built nanvix sysroot that contains the cutover.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
esaurez added a commit to esaurez/libxml2 that referenced this pull request Jun 9, 2026
… `-Wl,--allow-multiple-definition` flag was added in the previouscommit to silently coalesce 37 duplicate strong symbols that appearedin 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: nanvix/nanvix#2487.  * The remaining `_do_start` by declaring newlib's stub `.weak` so    libnvx_crt0's strong SSE-aligned override wins cleanly:    nanvix/newlib#17, plus the toolchain image republish in    nanvix/toolchain-gcc#14.Once all three of the above have merged and the toolchain image isrepublished with the new newlib commit, the link line no longerneeds `--allow-multiple-definition`.MERGE ORDER: do NOT merge this PR until ALL of the following havelanded:  1. nanvix/nanvix#2487 (sys-ffi crate split) -- already filed.  2. nanvix/newlib#17   (.weak _do_start)    -- already filed.  3. nanvix/toolchain-gcc#14 (republish image with new newlib)     -- already filed; draft until newlib#17 merges.  4. The toolchain image at ghcr.io/nanvix/toolchain-gcc has been     republished from nanvix#14 with the new newlib commit.  5. The parent E: PR adding the libnvx_crt0.a wildcard link     entry, which this PR is stacked on top of.If merged early, the .so / test ELF link step will fail with"multiple definition of __kcall_*" errors.Validated end-to-end against a locally-rebuilt toolchain imagecarrying the newlib nanvix#17 change: the resulting ELF's `_do_start`entry point is libnvx_crt0's SSE-aligned variant (`and $0xfffffff0,%esp ; sub $0x8, %esp ; push ; push ; call _start`) -- the latentSSE-alignment bug present in shipping binaries today is fixed.Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
esaurez added a commit to esaurez/libxslt that referenced this pull request Jun 9, 2026
… working

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-cutover and post-cutover sysroots:

  - Pre-cutover (sysroot built before nanvix/nanvix#2453):
    libnvx_crt0.a does not exist; wildcard expands to empty;
    `_start` continues to come from libposix.a as before.
  - Post-cutover (sysroot built after nanvix/nanvix#2453):
    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 today both contain duplicate strong definitions of
the sys-crate `__kcall_*` FFI symbols, `_do_exit_thread`, and
`_do_start_thread`.  All 36 of those duplicates are addressed by
nanvix/nanvix#2487 (sys-ffi crate split), which moves the
`#[no_mangle]` exports out of `sys` into a dedicated crate that
only `libposix.a` links.  The remaining 37th duplicate (`_do_start`
colliding between libnvx_crt0 and newlib's prebuilt `crt0.o`) is
addressed by nanvix/newlib#17 (`.weak _do_start` so libnvx_crt0's
strong SSE-aligned override wins cleanly).  Once both have landed
and the toolchain image republished from nanvix/toolchain-gcc#14,
`--allow-multiple-definition` can be dropped in a follow-up commit.

Validated by building the test ELF and booting it through `nanvixd`
against a locally-built nanvix sysroot that contains the cutover.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
esaurez added a commit to esaurez/libxslt that referenced this pull request Jun 9, 2026
… `-Wl,--allow-multiple-definition` flag was added in the previouscommit to silently coalesce 37 duplicate strong symbols that appearedin 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: nanvix/nanvix#2487.  * The remaining `_do_start` by declaring newlib's stub `.weak` so    libnvx_crt0's strong SSE-aligned override wins cleanly:    nanvix/newlib#17, plus the toolchain image republish in    nanvix/toolchain-gcc#14.Once all three of the above have merged and the toolchain image isrepublished with the new newlib commit, the link line no longerneeds `--allow-multiple-definition`.MERGE ORDER: do NOT merge this PR until ALL of the following havelanded:  1. nanvix/nanvix#2487 (sys-ffi crate split) -- already filed.  2. nanvix/newlib#17   (.weak _do_start)    -- already filed.  3. nanvix/toolchain-gcc#14 (republish image with new newlib)     -- already filed; draft until newlib#17 merges.  4. The toolchain image at ghcr.io/nanvix/toolchain-gcc has been     republished from nanvix#14 with the new newlib commit.  5. The parent E: PR adding the libnvx_crt0.a wildcard link     entry, which this PR is stacked on top of.If merged early, the .so / test ELF link step will fail with"multiple definition of __kcall_*" errors.Validated end-to-end against a locally-rebuilt toolchain imagecarrying the newlib nanvix#17 change: the resulting ELF's `_do_start`entry point is libnvx_crt0's SSE-aligned variant (`and $0xfffffff0,%esp ; sub $0x8, %esp ; push ; push ; call _start`) -- the latentSSE-alignment bug present in shipping binaries today is fixed.Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
esaurez added a commit to esaurez/lxml that referenced this pull request Jun 9, 2026
… working

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-cutover and post-cutover sysroots:

  - Pre-cutover (sysroot built before nanvix/nanvix#2453):
    libnvx_crt0.a does not exist; wildcard expands to empty;
    `_start` continues to come from libposix.a as before.
  - Post-cutover (sysroot built after nanvix/nanvix#2453):
    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 today both contain duplicate strong definitions of
the sys-crate `__kcall_*` FFI symbols, `_do_exit_thread`, and
`_do_start_thread`.  All 36 of those duplicates are addressed by
nanvix/nanvix#2487 (sys-ffi crate split), which moves the
`#[no_mangle]` exports out of `sys` into a dedicated crate that
only `libposix.a` links.  The remaining 37th duplicate (`_do_start`
colliding between libnvx_crt0 and newlib's prebuilt `crt0.o`) is
addressed by nanvix/newlib#17 (`.weak _do_start` so libnvx_crt0's
strong SSE-aligned override wins cleanly).  Once both have landed
and the toolchain image republished from nanvix/toolchain-gcc#14,
`--allow-multiple-definition` can be dropped in a follow-up commit.

Validated by building the test ELF and booting it through `nanvixd`
against a locally-built nanvix sysroot that contains the cutover.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
esaurez added a commit to esaurez/lxml that referenced this pull request Jun 9, 2026
… `-Wl,--allow-multiple-definition` flag was added in the previouscommit to silently coalesce 37 duplicate strong symbols that appearedin 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: nanvix/nanvix#2487.  * The remaining `_do_start` by declaring newlib's stub `.weak` so    libnvx_crt0's strong SSE-aligned override wins cleanly:    nanvix/newlib#17, plus the toolchain image republish in    nanvix/toolchain-gcc#14.Once all three of the above have merged and the toolchain image isrepublished with the new newlib commit, the link line no longerneeds `--allow-multiple-definition`.MERGE ORDER: do NOT merge this PR until ALL of the following havelanded:  1. nanvix/nanvix#2487 (sys-ffi crate split) -- already filed.  2. nanvix/newlib#17   (.weak _do_start)    -- already filed.  3. nanvix/toolchain-gcc#14 (republish image with new newlib)     -- already filed; draft until newlib#17 merges.  4. The toolchain image at ghcr.io/nanvix/toolchain-gcc has been     republished from nanvix#14 with the new newlib commit.  5. The parent E: PR adding the libnvx_crt0.a wildcard link     entry, which this PR is stacked on top of.If merged early, the .so / test ELF link step will fail with"multiple definition of __kcall_*" errors.Validated end-to-end against a locally-rebuilt toolchain imagecarrying the newlib nanvix#17 change: the resulting ELF's `_do_start`entry point is libnvx_crt0's SSE-aligned variant (`and $0xfffffff0,%esp ; sub $0x8, %esp ; push ; push ; call _start`) -- the latentSSE-alignment bug present in shipping binaries today is fixed.Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
esaurez added a commit to esaurez/libffi that referenced this pull request Jun 9, 2026
… working

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-cutover and post-cutover sysroots:

  - Pre-cutover (sysroot built before nanvix/nanvix#2453):
    libnvx_crt0.a does not exist; wildcard expands to empty;
    `_start` continues to come from libposix.a as before.
  - Post-cutover (sysroot built after nanvix/nanvix#2453):
    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 today both contain duplicate strong definitions of
the sys-crate `__kcall_*` FFI symbols, `_do_exit_thread`, and
`_do_start_thread`.  All 36 of those duplicates are addressed by
nanvix/nanvix#2487 (sys-ffi crate split), which moves the
`#[no_mangle]` exports out of `sys` into a dedicated crate that
only `libposix.a` links.  The remaining 37th duplicate (`_do_start`
colliding between libnvx_crt0 and newlib's prebuilt `crt0.o`) is
addressed by nanvix/newlib#17 (`.weak _do_start` so libnvx_crt0's
strong SSE-aligned override wins cleanly).  Once both have landed
and the toolchain image republished from nanvix/toolchain-gcc#14,
`--allow-multiple-definition` can be dropped in a follow-up commit.

Validated by building the test ELF and booting it through `nanvixd`
against a locally-built nanvix sysroot that contains the cutover.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
esaurez added a commit to esaurez/libffi that referenced this pull request Jun 9, 2026
… `-Wl,--allow-multiple-definition` flag was added in the previouscommit to silently coalesce 37 duplicate strong symbols that appearedin 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: nanvix/nanvix#2487.  * The remaining `_do_start` by declaring newlib's stub `.weak` so    libnvx_crt0's strong SSE-aligned override wins cleanly:    nanvix/newlib#17, plus the toolchain image republish in    nanvix/toolchain-gcc#14.Once all three of the above have merged and the toolchain image isrepublished with the new newlib commit, the link line no longerneeds `--allow-multiple-definition`.MERGE ORDER: do NOT merge this PR until ALL of the following havelanded:  1. nanvix/nanvix#2487 (sys-ffi crate split) -- already filed.  2. nanvix/newlib#17   (.weak _do_start)    -- already filed.  3. nanvix/toolchain-gcc#14 (republish image with new newlib)     -- already filed; draft until newlib#17 merges.  4. The toolchain image at ghcr.io/nanvix/toolchain-gcc has been     republished from nanvix#14 with the new newlib commit.  5. The parent E: PR adding the libnvx_crt0.a wildcard link     entry, which this PR is stacked on top of.If merged early, the .so / test ELF link step will fail with"multiple definition of __kcall_*" errors.Validated end-to-end against a locally-rebuilt toolchain imagecarrying the newlib nanvix#17 change: the resulting ELF's `_do_start`entry point is libnvx_crt0's SSE-aligned variant (`and $0xfffffff0,%esp ; sub $0x8, %esp ; push ; push ; call _start`) -- the latentSSE-alignment bug present in shipping binaries today is fixed.Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
esaurez added a commit to esaurez/openssl that referenced this pull request Jun 9, 2026
… working

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-cutover and post-cutover sysroots:

  - Pre-cutover (sysroot built before nanvix/nanvix#2453):
    libnvx_crt0.a does not exist; wildcard expands to empty;
    `_start` continues to come from libposix.a as before.
  - Post-cutover (sysroot built after nanvix/nanvix#2453):
    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 today both contain duplicate strong definitions of
the sys-crate `__kcall_*` FFI symbols, `_do_exit_thread`, and
`_do_start_thread`.  All 36 of those duplicates are addressed by
nanvix/nanvix#2487 (sys-ffi crate split), which moves the
`#[no_mangle]` exports out of `sys` into a dedicated crate that
only `libposix.a` links.  The remaining 37th duplicate (`_do_start`
colliding between libnvx_crt0 and newlib's prebuilt `crt0.o`) is
addressed by nanvix/newlib#17 (`.weak _do_start` so libnvx_crt0's
strong SSE-aligned override wins cleanly).  Once both have landed
and the toolchain image republished from nanvix/toolchain-gcc#14,
`--allow-multiple-definition` can be dropped in a follow-up commit.

Validated by building the test ELF and booting it through `nanvixd`
against a locally-built nanvix sysroot that contains the cutover.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
esaurez added a commit to esaurez/openssl that referenced this pull request Jun 9, 2026
… `-Wl,--allow-multiple-definition` flag was added in the previouscommit to silently coalesce 37 duplicate strong symbols that appearedin 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: nanvix/nanvix#2487.  * The remaining `_do_start` by declaring newlib's stub `.weak` so    libnvx_crt0's strong SSE-aligned override wins cleanly:    nanvix/newlib#17, plus the toolchain image republish in    nanvix/toolchain-gcc#14.Once all three of the above have merged and the toolchain image isrepublished with the new newlib commit, the link line no longerneeds `--allow-multiple-definition`.MERGE ORDER: do NOT merge this PR until ALL of the following havelanded:  1. nanvix/nanvix#2487 (sys-ffi crate split) -- already filed.  2. nanvix/newlib#17   (.weak _do_start)    -- already filed.  3. nanvix/toolchain-gcc#14 (republish image with new newlib)     -- already filed; draft until newlib#17 merges.  4. The toolchain image at ghcr.io/nanvix/toolchain-gcc has been     republished from nanvix#14 with the new newlib commit.  5. The parent E: PR adding the libnvx_crt0.a wildcard link     entry, which this PR is stacked on top of.If merged early, the .so / test ELF link step will fail with"multiple definition of __kcall_*" errors.Validated end-to-end against a locally-rebuilt toolchain imagecarrying the newlib nanvix#17 change: the resulting ELF's `_do_start`entry point is libnvx_crt0's SSE-aligned variant (`and $0xfffffff0,%esp ; sub $0x8, %esp ; push ; push ; call _start`) -- the latentSSE-alignment bug present in shipping binaries today is fixed.Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
esaurez pushed a commit to esaurez/libffi that referenced this pull request Jun 9, 2026
…finition

nanvix/nanvix#2453 moved the `_start` entry point out of
`libposix.a` into a new `libnvx_crt0.a`.  Add `libnvx_crt0.a` to
the test ELF link line so `_start` is found at link time;
otherwise the linker silently picks newlib's weak fallback and
the test hangs at startup.

Also drop `-Wl,--allow-multiple-definition` from the link line.
The flag was previously needed to coalesce duplicate strong
symbols (`__kcall_*`, `_do_exit_thread`, `_do_start_thread`,
`_do_start`) that appeared in both `libnvx_crt0.a` and
`libposix.a`.  All of those duplicates are now resolved upstream:

  * nanvix/nanvix#2487 -- sys-ffi crate split that removes the
    `__kcall_*` / `_do_exit_thread` / `_do_start_thread`
    duplicates from `libnvx_crt0.a`.
  * nanvix/newlib#17 -- declares newlib's `_do_start` as `.weak`
    so libnvx_crt0's strong SSE-aligned override wins cleanly.
  * nanvix/toolchain-gcc#14 -- pins the new newlib commit and
    triggers a republish of the toolchain image.

This PR depends on all three above having merged AND the
toolchain image at `ghcr.io/nanvix/toolchain-gcc` having been
republished with the new newlib bundled in.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant