nuttx/libs/libc/stdlib
Marco Casaroli ea78802f8d binfmt/fdpic: Add an FDPIC ELF module loader.
Lets a NOMMU target execute downloadable modules in place from
memory-mapped NOR flash, so a module's text and rodata never consume
RAM.  It is the consumer of xipfs: the loader maps a module's read-only
segment with MAP_XIP_STRICT, which resolves to a direct flash pointer or
fails with -ENXIO rather than falling back to a RAM copy, and pins the
extent for as long as the module is loaded so the defragmenter cannot
relocate code that is executing.

Only the writable segment is copied to RAM, once per running instance.
The loader follows DT_NEEDED so a module can use shared libraries, each
object getting its own GOT and its own data.

FDPIC is what makes this possible: text is position-independent and each
LOAD segment is placed independently, with the text-to-data offset
communicated at load time through function descriptors and the GOT.  A
descriptor is a pair -- entry pointer plus data base -- so a module
function handed back to the firmware carries the data base it needs.
r9 holds that base at runtime, per the ARM FDPIC ABI.

Reserving r9 across the base firmware is what allows a firmware routine
to call back into module code and still arrive with the module's data
base intact.  Toolchain.defs puts --fixed-r9 in ARCHCPUFLAGS rather than
CFLAGS, because almost every board Make.defs assigns CFLAGS with ':='
after including it, which would discard the flag; ARCHCPUFLAGS is
re-expanded by that same assignment and so survives it.  The CONFIG_PIC
--fixed-r10 case is skipped under FDPIC, since reserving both registers
would cost one for nothing.

The DT_NEEDED walk is depth capped.  fdpic_loaddepends() recursed once per
link of a dependency chain with a path buffer on each frame and nothing to
stop it, so a malformed module set overflowed the stack of whichever task
called the loader instead of being rejected.  A dependency *cycle* was never
the hazard -- an object joins the load's list before its own dependencies are
walked, so a library naming something already loaded finds it there and stops
-- what was unbounded is a chain of distinct names, which the list cannot
bound, hence an explicit cap rather than cycle detection.

A module's .rofixup section is skipped, and the file header records why.
.rofixup is the FDPIC self-relocation list a static executable's crt0 walks
to derive its own GOT when no loader is present.  A module links -shared
-nostartfiles, so no crt0 runs, and the built objects hold exactly one entry
there -- the address of the GOT itself, which this loader computes and
installs at every entry into module code anyway.

Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-08-01 12:23:27 +02:00
..
CMakeLists.txt libc: improve libc dependencies in case of LIBM_NONE 2025-12-14 17:57:27 -03:00
Kconfig stdlib/rand: replace weak LCG with xorshift32 PRNG 2026-07-03 15:08:12 +08:00
lib_abort.c libs/libc: migrate to SPDX identifier 2024-10-01 12:25:52 +08:00
lib_abs.c libs/libc: migrate to SPDX identifier 2024-10-01 12:25:52 +08:00
lib_aligned_alloc.c libc: remove reference to non-existent readme 2025-10-11 17:07:51 -04:00
lib_arc4random.c libc: Fix lib_arc4random.c:111:(.text.arc4random_buf+0x26): undefined reference to `clock_systime_ticks' 2024-10-28 09:23:19 +01:00
lib_atexit.c libs/libc: migrate to SPDX identifier 2024-10-01 12:25:52 +08:00
lib_atof.c libs/libc: migrate to SPDX identifier 2024-10-01 12:25:52 +08:00
lib_atoi.c libc: remove reference to non-existent readme 2025-10-11 17:07:51 -04:00
lib_atol.c libc: remove reference to non-existent readme 2025-10-11 17:07:51 -04:00
lib_atoll.c !compiler: drop CONFIG_HAVE_LONG_LONG and require long long support 2026-05-19 16:21:28 +08:00
lib_bsearch.c binfmt/fdpic: Add an FDPIC ELF module loader. 2026-08-01 12:23:27 +02:00
lib_checkbase.c libs/libc: migrate to SPDX identifier 2024-10-01 12:25:52 +08:00
lib_div.c libs/libc: migrate to SPDX identifier 2024-10-01 12:25:52 +08:00
lib_exit.c Revert "libs/libc/stdlib/lib_exit.c: fix multiple definition of __dso_handle in msys2" 2025-07-31 22:10:36 +08:00
lib_getprogname.c libs/libc: migrate to SPDX identifier 2024-10-01 12:25:52 +08:00
lib_itoa.c libs/libc: migrate to SPDX identifier 2024-10-01 12:25:52 +08:00
lib_labs.c libs/libc: migrate to SPDX identifier 2024-10-01 12:25:52 +08:00
lib_ldiv.c libs/libc: migrate to SPDX identifier 2024-10-01 12:25:52 +08:00
lib_llabs.c !compiler: drop CONFIG_HAVE_LONG_LONG and require long long support 2026-05-19 16:21:28 +08:00
lib_lldiv.c !compiler: drop CONFIG_HAVE_LONG_LONG and require long long support 2026-05-19 16:21:28 +08:00
lib_mblen.c libs/libc: migrate to SPDX identifier 2024-10-01 12:25:52 +08:00
lib_mbstowcs.c libs/libc: migrate to SPDX identifier 2024-10-01 12:25:52 +08:00
lib_mbtowc.c libs/libc: migrate to SPDX identifier 2024-10-01 12:25:52 +08:00
lib_mkdtemp.c libs/libc: migrate to SPDX identifier 2024-10-01 12:25:52 +08:00
lib_mkstemp.c libs/libc: migrate to SPDX identifier 2024-10-01 12:25:52 +08:00
lib_mktemp.c libs/libc: migrate to SPDX identifier 2024-10-01 12:25:52 +08:00
lib_openpty.c libs/libc: migrate to SPDX identifier 2024-10-01 12:25:52 +08:00
lib_posix_memalign.c libc: remove reference to non-existent readme 2025-10-11 17:07:51 -04:00
lib_ptsname.c libs/libc: migrate to SPDX identifier 2024-10-01 12:25:52 +08:00
lib_ptsnamer.c libs/libc: migrate to SPDX identifier 2024-10-01 12:25:52 +08:00
lib_qsort.c binfmt/fdpic: Add an FDPIC ELF module loader. 2026-08-01 12:23:27 +02:00
lib_rand.c libs/libc: migrate to SPDX identifier 2024-10-01 12:25:52 +08:00
lib_rand48.c !compiler: drop CONFIG_HAVE_LONG_LONG and require long long support 2026-05-19 16:21:28 +08:00
lib_reallocarray.c style: fix spelling in code comments and strings 2025-05-23 10:48:41 +08:00
lib_realpath.c libs/libc: migrate to SPDX identifier 2024-10-01 12:25:52 +08:00
lib_srand.c stdlib/rand: replace weak LCG with xorshift32 PRNG 2026-07-03 15:08:12 +08:00
lib_strtol.c libs/libc: migrate to SPDX identifier 2024-10-01 12:25:52 +08:00
lib_strtold.c !compiler: drop CONFIG_HAVE_LONG_LONG and require long long support 2026-05-19 16:21:28 +08:00
lib_strtoll.c !compiler: drop CONFIG_HAVE_LONG_LONG and require long long support 2026-05-19 16:21:28 +08:00
lib_strtoul.c libs/libc: migrate to SPDX identifier 2024-10-01 12:25:52 +08:00
lib_strtoull.c !compiler: drop CONFIG_HAVE_LONG_LONG and require long long support 2026-05-19 16:21:28 +08:00
lib_unlockpt.c libs/libc: migrate to SPDX identifier 2024-10-01 12:25:52 +08:00
lib_valloc.c libc: remove reference to non-existent readme 2025-10-11 17:07:51 -04:00
lib_wcstombs.c libs/libc: migrate to SPDX identifier 2024-10-01 12:25:52 +08:00
lib_wctomb.c libs/libc: migrate to SPDX identifier 2024-10-01 12:25:52 +08:00
Make.defs libc: improve libc dependencies in case of LIBM_NONE 2025-12-14 17:57:27 -03:00