diff --git a/Makefile b/Makefile index 088dfc24ac..015d0cd419 100644 --- a/Makefile +++ b/Makefile @@ -119,7 +119,10 @@ define BUNDLE_SDK OSDRV_DIR=$(PWD)/general/package/$(BR2_OPENIPC_SOC_VENDOR)-osdrv-$(BR2_OPENIPC_SOC_FAMILY)/files; \ MPP_HEADERS=$(PWD)/general/package/hisilicon-osdrv-hi3516cv100/files/include; \ SDK_TGZ=$$(find $(TARGET)/images -name '*_sdk-buildroot.tar.gz' | head -1); \ - COMPAT_SRC=$(PWD)/general/package/uclibc-compat/src/uclibc-compat.c; \ + UCLIBC_COMPAT_SRC=$(PWD)/general/package/uclibc-compat/src/uclibc-compat.c; \ + UCLIBC_COMPAT_STATIC=$(PWD)/general/package/uclibc-compat/src/uclibc-compat-static.c; \ + GLIBC_COMPAT_SRC=$(PWD)/general/package/glibc-compat/src/glibc-compat.c; \ + GLIBC_COMPAT_STATIC=$(PWD)/general/package/glibc-compat/src/glibc-compat-static.c; \ SDK_CC=$$(ls $(TARGET)/host/bin/*-gcc 2>/dev/null | head -1); \ if [ -d "$$OSDRV_DIR" ] && [ -n "$$SDK_TGZ" ]; then \ SDK_TOP=$$(tar tzf $$SDK_TGZ | head -1 | cut -d/ -f1); \ @@ -129,20 +132,34 @@ define BUNDLE_SDK mkdir -p /tmp/sdk-overlay/$$SDK_TOP/sdk/include; \ cp -a $$MPP_HEADERS/. /tmp/sdk-overlay/$$SDK_TOP/sdk/include/; \ fi; \ - if [ -f "$$COMPAT_SRC" ] && [ -n "$$SDK_CC" ]; then \ - $$SDK_CC -shared -Wall -O2 -fPIC \ - -o /tmp/sdk-overlay/$$SDK_TOP/sdk/lib/libuclibc-compat.so \ - $$COMPAT_SRC; \ - COMPAT_STATIC=$(PWD)/general/package/uclibc-compat/src/uclibc-compat-static.c; \ - if [ -f "$$COMPAT_STATIC" ]; then \ - SDK_AR=$$(echo $$SDK_CC | sed 's/-gcc$$/-ar/'); \ + if [ -n "$$SDK_CC" ]; then \ + SDK_AR=$$(echo $$SDK_CC | sed 's/-gcc$$/-ar/'); \ + if [ -f "$$UCLIBC_COMPAT_SRC" ]; then \ + $$SDK_CC -shared -Wall -O2 -fPIC \ + -o /tmp/sdk-overlay/$$SDK_TOP/sdk/lib/libuclibc-compat.so \ + $$UCLIBC_COMPAT_SRC; \ + fi; \ + if [ -f "$$UCLIBC_COMPAT_STATIC" ]; then \ $$SDK_CC -Wall -O2 -fPIC -c \ -o /tmp/sdk-overlay/$$SDK_TOP/sdk/lib/uclibc-compat-static.o \ - $$COMPAT_STATIC; \ + $$UCLIBC_COMPAT_STATIC; \ $$SDK_AR rcs /tmp/sdk-overlay/$$SDK_TOP/sdk/lib/libuclibc-compat-static.a \ /tmp/sdk-overlay/$$SDK_TOP/sdk/lib/uclibc-compat-static.o; \ rm -f /tmp/sdk-overlay/$$SDK_TOP/sdk/lib/uclibc-compat-static.o; \ fi; \ + if [ -f "$$GLIBC_COMPAT_SRC" ]; then \ + $$SDK_CC -shared -Wall -O2 -fPIC \ + -o /tmp/sdk-overlay/$$SDK_TOP/sdk/lib/libglibc-compat.so \ + $$GLIBC_COMPAT_SRC; \ + fi; \ + if [ -f "$$GLIBC_COMPAT_STATIC" ]; then \ + $$SDK_CC -Wall -O2 -fPIC -c \ + -o /tmp/sdk-overlay/$$SDK_TOP/sdk/lib/glibc-compat-static.o \ + $$GLIBC_COMPAT_STATIC; \ + $$SDK_AR rcs /tmp/sdk-overlay/$$SDK_TOP/sdk/lib/libglibc-compat-static.a \ + /tmp/sdk-overlay/$$SDK_TOP/sdk/lib/glibc-compat-static.o; \ + rm -f /tmp/sdk-overlay/$$SDK_TOP/sdk/lib/glibc-compat-static.o; \ + fi; \ fi; \ gunzip $$SDK_TGZ && \ tar rf $${SDK_TGZ%.tar.gz}.tar -C /tmp/sdk-overlay $$SDK_TOP && \ diff --git a/general/package/glibc-compat/glibc-compat.mk b/general/package/glibc-compat/glibc-compat.mk index cbc9ac0bf7..13cbef4684 100644 --- a/general/package/glibc-compat/glibc-compat.mk +++ b/general/package/glibc-compat/glibc-compat.mk @@ -7,6 +7,7 @@ GLIBC_COMPAT_VERSION = GLIBC_COMPAT_SITE = GLIBC_COMPAT_LICENSE = MIT +GLIBC_COMPAT_INSTALL_STAGING = YES define GLIBC_COMPAT_BUILD_CMDS $(MAKE) $(TARGET_CONFIGURE_OPTS) -C $(GLIBC_COMPAT_PKGDIR)/src all @@ -17,6 +18,11 @@ endef # pointing all four names at it is enough for the loader to satisfy NEEDED # entries; the libglibc-compat.so providing missing symbols is pulled in by # the LD_PRELOAD-equivalent NEEDED added to vendor wrapper scripts. +define GLIBC_COMPAT_INSTALL_STAGING_CMDS + $(INSTALL) -D -m 0644 $(GLIBC_COMPAT_PKGDIR)/src/libglibc-compat-static.a \ + $(STAGING_DIR)/usr/lib/libglibc-compat-static.a +endef + define GLIBC_COMPAT_INSTALL_TARGET_CMDS $(INSTALL) -D -m 0755 $(GLIBC_COMPAT_PKGDIR)/src/libglibc-compat.so \ $(TARGET_DIR)/usr/lib/libglibc-compat.so diff --git a/general/package/glibc-compat/src/Makefile b/general/package/glibc-compat/src/Makefile index b3783a4510..969684ee20 100644 --- a/general/package/glibc-compat/src/Makefile +++ b/general/package/glibc-compat/src/Makefile @@ -1,10 +1,16 @@ CFLAGS ?= -O2 CFLAGS += -Wall -fPIC -all: libglibc-compat.so +all: libglibc-compat.so libglibc-compat-static.a libglibc-compat.so: glibc-compat.c $(CC) $(CFLAGS) -shared -o $@ $^ +libglibc-compat-static.a: glibc-compat-static.o + $(AR) rcs $@ $^ + +glibc-compat-static.o: glibc-compat-static.c + $(CC) $(CFLAGS) -c -o $@ $< + clean: - rm -f *.o *.so + rm -f *.o *.so *.a diff --git a/general/package/glibc-compat/src/glibc-compat-static.c b/general/package/glibc-compat/src/glibc-compat-static.c new file mode 100644 index 0000000000..4177697046 --- /dev/null +++ b/general/package/glibc-compat/src/glibc-compat-static.c @@ -0,0 +1,41 @@ +/* + * glibc-compat-static.c -- ABI wrappers that MUST be statically linked + * + * Vendor glibc binaries built against 32-bit off_t (no _FILE_OFFSET_BITS=64, + * typical of 2014-era SDKs like Hi3520DV200's MPP) call mmap() with a + * single-register 32-bit offset arg. musl's mmap() expects 64-bit off_t — + * when the vendor .so binds against musl, the kernel sees uninitialised + * stack as the high half of pgoff and rejects with EINVAL. Symptom on + * hi3520dv200: VENC CreateChn returns 0xa007800c (EN_ERR_VENC_NOMEM) + * because libmpi can't mmap the model_buf via /dev/venc. + * + * This function MUST be linked statically into the EXECUTABLE + * (-lglibc-compat-static) so it appears in the executable's symbol + * table. The dynamic linker then resolves vendor .so imports from the + * executable BEFORE musl. Putting it in a shared library would override + * musl's mmap process-wide, breaking musl's own internal mmap callers + * (malloc, dlopen, ...). + * + * Pattern mirrors OpenIPC/firmware#2000 (uclibc-compat-static for the + * hi3516cv100 vendor blobs). + */ + +#define _GNU_SOURCE +#include +#include +#include +#include + +#ifndef SYS_mmap2 +#define SYS_mmap2 192 +#endif + +void *mmap(void *addr, size_t len, int prot, int flags, int fd, uint32_t offset) +{ + return (void *)syscall(SYS_mmap2, addr, len, prot, flags, fd, offset >> 12); +} + +void *mmap64(void *addr, size_t len, int prot, int flags, int fd, uint32_t offset) +{ + return (void *)syscall(SYS_mmap2, addr, len, prot, flags, fd, offset >> 12); +}