Skip to content

uclibc-compat: split .so and .a to fix segfault from symbol interposition - #2000

Merged
widgetii merged 1 commit into
masterfrom
fix-uclibc-compat-so-interpose
Apr 13, 2026
Merged

uclibc-compat: split .so and .a to fix segfault from symbol interposition#2000
widgetii merged 1 commit into
masterfrom
fix-uclibc-compat-so-interpose

Conversation

@widgetii

Copy link
Copy Markdown
Member

Problem

libuclibc-compat.so exported stat/mmap which overrode musl's implementations process-wide, causing segfaults. musl expects 64-bit off_t for mmap but the shim's version takes uint32_t — when musl's own internal code called mmap, it hit the wrong implementation.

Confirmed crash: majestic segfaults at hisi_free_mem_ex (MMZ memory allocation via mmap) on hi3516cv100 nightly build.

Fix

Split into two libraries:

  • libuclibc-compat.so: only symbols MISSING from musl (__ctype_b, __assert, __fgetc_unlocked, memcpy_s, etc). Safe as shared lib — no conflict.
  • libuclibc-compat-static.a: stat/mmap wrappers. Must be statically linked into the executable, so overrides only affect vendor .so lookups through the executable's symbol scope, not musl internally.

BUNDLE_SDK updated to build and include both in the toolchain tarball.

Test plan

  • Rebuild cv100 toolchain, verify .so has no stat/mmap, .a has them
  • Build majestic linking -luclibc-compat (dynamic) + -luclibc-compat-static (static)
  • Hardware test on hi3516cv100 — no segfault at hisi_free_mem_ex

Ref: #1992

libuclibc-compat.so was exporting stat/mmap which overrode musl's
implementations for ALL code in the process, including musl's own
internal calls.  This caused segfaults because musl expects 64-bit
off_t but the shim's mmap takes uint32_t.

Split into two libraries:
- libuclibc-compat.so: only symbols MISSING from musl (__ctype_b,
  __assert, __fgetc_unlocked, memcpy_s, etc).  Safe as shared lib.
- libuclibc-compat-static.a: stat/mmap wrappers with uclibc-compatible
  ABI.  Must be statically linked into the executable so overrides
  only affect vendor .so lookups through the executable's symbol scope.

BUNDLE_SDK now builds and includes both in the toolchain tarball.

Fixes: segfault in majestic on hi3516cv100 at hisi_free_mem_ex (mmap)
Ref: #1992

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@widgetii

Copy link
Copy Markdown
Member Author

/rerun

@widgetii
widgetii merged commit d1b2c87 into master Apr 13, 2026
88 of 176 checks passed
@widgetii
widgetii deleted the fix-uclibc-compat-so-interpose branch April 14, 2026 05:13
widgetii added a commit that referenced this pull request May 18, 2026
Vendor glibc binaries from the V2 era (e.g. hi3520dv200's libmpi.so)
were built without _FILE_OFFSET_BITS=64 so their mmap() takes a 32-bit
off_t. musl's mmap() exports 64-bit off_t — when libmpi dynamic-links
against musl on a modern rootfs, the high 32 bits of the offset arg
come from uninitialised stack and the kernel sees a garbage pgoff,
rejecting with EINVAL.

Symptom on hi3520dv200: every HI_MPI_VENC_CreateChn returns 0xa007800c
(EN_ERR_VENC_NOMEM) because libmpi can't mmap the model_buf via
/dev/venc. Confirmed via LD_PRELOAD trace shim that wraps mmap():
the syscall reaches the kernel with off=0x402b65d8 — a userspace VA
(varies between runs with ASLR), clearly stack garbage.

Fix: add glibc-compat-static.c with a 32-bit off_t mmap()/mmap64()
wrapper that goes straight to SYS_mmap2 bypassing musl's libc wrapper.
Same pattern as #2000 (uclibc-compat-static for hi3516cv100). The
function must be statically linked into the consumer executable (not
in a .so) so the dynamic linker resolves vendor .so imports of mmap
to the executable's symbol table BEFORE musl — putting it in a .so
would override musl process-wide and break musl's own internal mmap
callers (malloc, dlopen, etc.).

- glibc-compat/src/glibc-compat-static.c: new file, mmap()/mmap64()
  wrappers calling SYS_mmap2 with pgoff
- glibc-compat/src/Makefile: build both libglibc-compat.so and
  libglibc-compat-static.a
- glibc-compat/glibc-compat.mk: INSTALL_STAGING=YES, install .a to
  STAGING_DIR so dependent packages can link -lglibc-compat-static
- Makefile (BUNDLE_SDK): produce libglibc-compat.so and
  libglibc-compat-static.a in the published toolchain SDK tarball,
  mirroring the existing uclibc-compat handling

Verified on lab DVR (openipc-hi3520dv200.dlab.torturelabs.com):
linking dvr_home with the mmap shim makes HI_MPI_VENC_CreateChn
succeed on all 4 channels.

Refs: #1992 (toolchain ABI audit), #1993 (cv100 stat shim),
      #2000 (cv100 static-link split)
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