Buildroot Archive on lore.kernel.org
 help / color / mirror / Atom feed
From: Waldemar Brodkorb <wbx@openadk.org>
To: buildroot@buildroot.org
Subject: [Buildroot] [PATCH] package/uclibc: fix for noMMU targets using FLAT binaries
Date: Sun, 14 Jun 2026 15:29:24 +0200	[thread overview]
Message-ID: <ai6stJaA2hWFBHDW@waldemar-brodkorb.de> (raw)

Signed-off-by: Waldemar Brodkorb <wbx@openadk.org>
---
 ...-PAGE_SHIFT-fallback-for-binfmt_flat.patch | 169 ++++++++++++++++++
 1 file changed, 169 insertions(+)
 create mode 100644 package/uclibc/0001-pagesize-restore-PAGE_SHIFT-fallback-for-binfmt_flat.patch

diff --git a/package/uclibc/0001-pagesize-restore-PAGE_SHIFT-fallback-for-binfmt_flat.patch b/package/uclibc/0001-pagesize-restore-PAGE_SHIFT-fallback-for-binfmt_flat.patch
new file mode 100644
index 0000000000..fdfd286042
--- /dev/null
+++ b/package/uclibc/0001-pagesize-restore-PAGE_SHIFT-fallback-for-binfmt_flat.patch
@@ -0,0 +1,169 @@
+From 7730f0d05a51cd89a7123bd696e4638c3c035d7b Mon Sep 17 00:00:00 2001
+From: Ramin Moussavi <ramin.moussavi@yacoub.de>
+Date: Fri, 29 May 2026 19:47:34 +0200
+Subject: [PATCH] pagesize: restore PAGE_SHIFT fallback for binfmt_flat (no
+ auxv)
+
+binfmt_flat builds the initial process stack from only argc/argv/envp;
+it does not place an auxiliary vector. Commit 487af1498 ("drop
+__pagesize, make _dl_pagesize the single source of truth") assumed
+AT_PAGESZ is always supplied by the kernel and changed the _dl_pagesize
+fallback from PAGE_SIZE to 0. On noMMU/FLAT targets that leaves
+_dl_pagesize == 0, so every mmap-based malloc rounds its length to 0,
+mmap() fails with EINVAL and the first allocation aborts -- busybox dies
+with "init: out of memory" before it can run anything.
+
+Restore the fallback that arc/nds32 bits/uClibc_page.h have always
+documented ("_dl_pagesize = auxvt[AT_PAGESZ].a_un.a_val ? : PAGE_SIZE"),
+expressed as (1UL << PAGE_SHIFT) so it keeps working now that PAGE_SIZE
+is no longer defined in <bits/uClibc_page.h>:
+
+  - Seed _dl_pagesize with (1UL << PAGE_SHIFT) at its definition in the
+    two translation units that own the symbol: the dynamic linker
+    (ldso.c, used by ld.so) and the static-libc support (dl-support.c).
+  - Override it from AT_PAGESZ only when that entry is actually present
+    (a_type == AT_PAGESZ) and non-zero, instead of unconditionally
+    resetting it to 0.
+
+libdl.c (!SHARED) previously also defined _dl_pagesize. That was
+harmless while dl-support.c's definition was tentative (the two merged),
+but giving both a non-zero initializer makes them two strong .data
+definitions, which collide as "multiple definition of `_dl_pagesize'"
+when a static link pulls both objects out of libc.a (e.g. NPTL builds
+that drag in libdl). Drop the redundant libdl.c definition: dl-support.c
+is always co-linked from libc.a and provides the symbol.
+
+For FLAT, skip the aux-vector scan in __uClibc_main() altogether: there
+is nothing valid past the envp NULL, so _dl_aux_init() is not called and
+_dl_auxv_start stays NULL. Guard getauxval()'s slow-path loop against
+that NULL so a lookup of an uncached (>= AUX_MAX_AT_ID) tag returns
+ENOENT instead of dereferencing NULL.
+
+Verified on riscv32 noMMU/FLAT (gcc 15.2.0, linux 6.18.33): busybox
+boots as init and the testsuite runs (was "init: out of memory"
+before). Dynamic + NPTL links are unaffected -- x86_64 NPTL static
+busybox links cleanly and ld-uClibc loads the testsuite.
+
+Upstream: https://gogs.waldemar-brodkorb.de/oss/uclibc-ng/commit/7730f0d05a51cd89a7123bd696e4638c3c035d7b
+Signed-off-by: Ramin Moussavi <ramin.moussavi@yacoub.de>
+Signed-off-by: Waldemar Brodkorb <wbx@openadk.org>
+---
+ ldso/ldso/ldso.c                    | 7 ++++---
+ ldso/libdl/libdl.c                  | 2 +-
+ libc/misc/auxvt/getauxval.c         | 3 ++-
+ libc/misc/elf/dl-support.c          | 7 ++++---
+ libc/misc/internals/__uClibc_main.c | 7 +++++--
+ 5 files changed, 16 insertions(+), 10 deletions(-)
+
+diff --git a/ldso/ldso/ldso.c b/ldso/ldso/ldso.c
+index 9c00e4a61..55f7d7e45 100755
+--- a/ldso/ldso/ldso.c
++++ b/ldso/ldso/ldso.c
+@@ -52,7 +52,7 @@ char *_dl_library_path         = NULL;	/* Where we look for libraries */
+ char *_dl_preload              = NULL;	/* Things to be loaded before the libs */
+ #endif
+ int _dl_errno                  = 0;	/* We can't use the real errno in ldso */
+-size_t _dl_pagesize            = 0;	/* Store the page size for use later */
++size_t _dl_pagesize            = (1UL << PAGE_SHIFT);	/* fallback; overridden from AT_PAGESZ if present */
+ struct r_debug *_dl_debug_addr = NULL;	/* Used to communicate with the gdb debugger */
+ void *(*_dl_malloc_function) (size_t size) = NULL;
+ void (*_dl_free_function) (void *p) = NULL;
+@@ -460,8 +460,9 @@ void *_dl_get_ready_to_run(struct elf_resolve *tpnt, DL_LOADADDR_TYPE load_addr,
+ 
+ 	_dl_memset(app_tpnt, 0, sizeof(*app_tpnt));
+ 
+-	/* Store the page size for later use */
+-	_dl_pagesize = (_dl_auxvt[AT_PAGESZ].a_un.a_val) ? (size_t) _dl_auxvt[AT_PAGESZ].a_un.a_val : 0;
++	/* Override the fallback only if AT_PAGESZ is present and non-zero */
++	if (_dl_auxvt[AT_PAGESZ].a_type == AT_PAGESZ && _dl_auxvt[AT_PAGESZ].a_un.a_val)
++		_dl_pagesize = (size_t) _dl_auxvt[AT_PAGESZ].a_un.a_val;
+ 	/* Make it so _dl_malloc can use the page of memory we have already
+ 	 * allocated.  We shouldn't need to grab any more memory.  This must
+ 	 * be first since things like _dl_dprintf() use _dl_malloc()...
+diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c
+index b78d6d9a3..f28801d7b 100644
+--- a/ldso/libdl/libdl.c
++++ b/ldso/libdl/libdl.c
+@@ -109,7 +109,7 @@ void (*_dl_free_function) (void *p);
+ char *_dl_library_path         = NULL;         /* Where we look for libraries */
+ #endif
+ int _dl_errno                  = 0;         /* We can't use the real errno in ldso */
+-size_t _dl_pagesize            = 0; /* Store the page size for use later */
++/* _dl_pagesize is provided by dl-support.c (always co-linked from libc.a) */
+ /* This global variable is also to communicate with debuggers such as gdb. */
+ struct r_debug *_dl_debug_addr = NULL;
+ 
+diff --git a/libc/misc/auxvt/getauxval.c b/libc/misc/auxvt/getauxval.c
+index 7610b7e5c..4af637071 100755
+--- a/libc/misc/auxvt/getauxval.c
++++ b/libc/misc/auxvt/getauxval.c
+@@ -33,7 +33,8 @@ unsigned long int __getauxval (unsigned long int __type)
+ 	}
+ 
+ 	// Otherwise we have to iterate the auxiliary vector.
+-	for (ElfW(auxv_t) *entry = _dl_auxv_start; entry->a_type != AT_NULL; entry++)
++	// _dl_auxv_start is NULL when there is no aux vector (e.g. FLAT).
++	for (ElfW(auxv_t) *entry = _dl_auxv_start; entry && entry->a_type != AT_NULL; entry++)
+ 		if (entry->a_type == __type)
+ 			return entry->a_un.a_val;
+ 
+diff --git a/libc/misc/elf/dl-support.c b/libc/misc/elf/dl-support.c
+index 738f0ed3a..7ad57c090 100644
+--- a/libc/misc/elf/dl-support.c
++++ b/libc/misc/elf/dl-support.c
+@@ -30,7 +30,7 @@ void (*_dl_init_static_tls) (struct link_map *) = &_dl_nothread_init_static_tls;
+ 
+ ElfW(Phdr) *_dl_phdr;
+ size_t _dl_phnum;
+-size_t _dl_pagesize;
++size_t _dl_pagesize = (1UL << PAGE_SHIFT);	/* fallback; overridden from AT_PAGESZ if present */
+ 
+ ElfW(auxv_t) _dl_auxvt[AUX_MAX_AT_ID];
+ ElfW(auxv_t) *_dl_auxv_start;
+@@ -52,8 +52,9 @@ void internal_function _dl_aux_init (ElfW(auxv_t) *av)
+    /* Get the number of program headers from the aux vect */
+    _dl_phnum = (size_t) _dl_auxvt[AT_PHNUM].a_un.a_val;
+ 
+-   /* Get the pagesize from the aux vect */
+-   _dl_pagesize = (_dl_auxvt[AT_PAGESZ].a_un.a_val) ? (size_t) _dl_auxvt[AT_PAGESZ].a_un.a_val : 0;
++   /* Override the fallback only if AT_PAGESZ is present and non-zero */
++   if (_dl_auxvt[AT_PAGESZ].a_type == AT_PAGESZ && _dl_auxvt[AT_PAGESZ].a_un.a_val)
++      _dl_pagesize = (size_t) _dl_auxvt[AT_PAGESZ].a_un.a_val;
+ }
+ 
+ #if defined(USE_TLS) && USE_TLS
+diff --git a/libc/misc/internals/__uClibc_main.c b/libc/misc/internals/__uClibc_main.c
+index 35cb73fcc..549606505 100644
+--- a/libc/misc/internals/__uClibc_main.c
++++ b/libc/misc/internals/__uClibc_main.c
+@@ -369,7 +369,7 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc,
+ 		    char **argv, void (*app_init)(void), void (*app_fini)(void),
+ 		    void (*rtld_fini)(void), void *stack_end attribute_unused)
+ {
+-#ifndef SHARED
++#if !defined(SHARED) && !defined(__UCLIBC_FORMAT_FLAT__)
+     unsigned long *aux_dat;
+ #endif
+ 
+@@ -395,7 +395,9 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc,
+     }
+ 
+ #ifndef SHARED
+-    /* Pull stuff from the ELF header when possible */
++# ifndef __UCLIBC_FORMAT_FLAT__
++    /* Pull stuff from the ELF header when possible. binfmt_flat passes no
++       aux vector, so skip this for FLAT. */
+     aux_dat = (unsigned long*)__environ;
+     while (*aux_dat) {
+ 	aux_dat++;
+@@ -404,6 +406,7 @@ void __uClibc_main(int (*main)(int, char **, char **), int argc,
+     /* Get the program headers (_dl_phdr) from the aux vector
+        It will be used into __libc_setup_tls. */
+     _dl_aux_init ((ElfW(auxv_t) *)aux_dat);
++# endif
+ #endif
+ 
+     /* We need to initialize uClibc.  If we are dynamically linked this
+-- 
+2.47.3
+
-- 
2.47.3

_______________________________________________
buildroot mailing list
buildroot@buildroot.org
https://lists.buildroot.org/mailman/listinfo/buildroot

                 reply	other threads:[~2026-06-14 13:29 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=ai6stJaA2hWFBHDW@waldemar-brodkorb.de \
    --to=wbx@openadk.org \
    --cc=buildroot@buildroot.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox