fix: emit build-id in arm64-musl cross-compiled binaries#233
Conversation
The musl-cross-make toolchain used for arm64-musl has no specs file injecting -Wl,--build-id, unlike the distro-packaged cross-compilers used for loong64/riscv64 or the native gcc used for x64-musl. As a result, the binary has no .note.gnu.build-id section and no PT_NOTE program header at all, which breaks postject-based SEA tooling that relies on dl_iterate_phdr finding a PT_NOTE segment to extend. Refs: nodejs#200
|
Validated locally end-to-end with a minimal C test (no Node build needed). Compiled a tiny
So the fix in this PR resolves the runtime SEGV on arm64-musl SEA binaries. Still wants a CI run to confirm against an actual Node build, but the mechanism is verified. Side note: postject reporting "Injection done" + exit 0 on a binary it silently failed to modify is itself worth filing on |
|
@sxa whenever it fits into your queue — anything else useful for me to add here (additional validation, alternative approach)? Happy to iterate. |
Summary
The musl-cross-make toolchain used for arm64-musl has no specs file injecting
-Wl,--build-id, unlike the distro-packaged cross-compilers used forloong64/riscv64or the native gcc used forx64-musl. As a result, the resulting binary has no.note.gnu.build-idsection and noPT_NOTEprogram header at all, which breaks postject-based SEA tooling (dl_iterate_phdrfinds no notes →postject_find_resource()returns NULL →BlobDeserializer::ReadArithmeticSEGVs).Adding
LDFLAGS="-Wl,--build-id=sha1"torecipes/arm64-musl/run.shrestores parity with every other recipe's output and unblocks SEA on the unofficial arm64-musl tarball.Why this is the right place to fix it
PT_NOTEtoday?arm64-muslrichfelker/musl-cross-make(commit3635262)loong64g++-14-loongarch64-linux-gnupackageriscv64/riscv64-pointer-compressiong++-14-riscv64-linux-gnupackagemusl(x64-musl)g++Only
arm64-muslis affected. The PR is intentionally a one-line LDFLAGS addition rather than re-configuring the musl-cross-make binutils build, to minimize blast radius.Refs
Closes #200.
Full root-cause analysis in #200 (comment) and #200 (comment).
Test plan
arm64-muslonunofficial-builds.nodejs.orgreadelf -lW node | grep '^\s*NOTE'on the resulting binary should show aNOTEprogram headerreadelf -SW node | grep '\.note'should show.note.gnu.build-idnode --experimental-sea-config ... && cp $(which node) hello && npx postject hello NODE_SEA_BLOB sea-prep.blob --sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2 && ./helloshould print the embedded JS instead of segfaultingI haven't been able to validate locally (musl-cross-make toolchain build ~30 min + Node build ~1–2 hr on my hardware); the fix is well-supported by the diagnosis but needs a CI run on this repo's infrastructure to confirm.