nuttx/include
Marco Casaroli 43694933ce libc, sched: Resolve FDPIC descriptors at module callback entry points.
The base firmware and an FDPIC module disagree about what a function
pointer is.  Firmware is not built FDPIC, so to it a pointer is a code
address and it branches there.  A module passes the address of a two word
descriptor instead, because its code and data are placed independently and
a bare code address would leave the callee unable to find its own data.  A
firmware routine that takes a callback therefore branches into the
module's data segment and faults.

So the ten entry points that can be handed a callback by a module resolve
the descriptor before storing or branching to it: qsort, bsearch,
pthread_create, signal, sigaction, task_create and task_create_with_stack,
task_spawn, pthread_once, scandir, and mq_notify and timer_create with
SIGEV_THREAD.

Which one resolves matters as much as that one does.  Resolving twice would
take an already resolved code address for a descriptor and read two words
from the instruction stream, so each pointer is resolved exactly once, at
the outermost point that sees it.  signal() passes its argument through
untouched because sigaction() and then nxsig_action() will resolve it,
which covers a module calling sigaction() directly as well.  qsort() is
split so that the public entry resolves and the recursive implementation
does not.  scandir() resolves its filter but not its comparison function,
which it hands to qsort().

Whether a caller is a module at all is asked of the PIC base register,
which up_initial_state() sets only for a task that has a D-Space.  A plain
kernel task therefore reads zero and is left alone.

SIGEV_THREAD is the case the register cannot answer, because the callback
runs later on a work queue worker that carries no module's base at all.
The base is captured instead when the notification is registered, in the
module's own context, and installed around the call.

All of it is behind CONFIG_FDPIC, which defaults off.  Built for
mps3-an547:picostest both ways; with it off the entry points compile to
what they were.

Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
2026-09-25 10:46:48 -03:00
..
android
arpa
crypto crypto: add CRYPTO_AES_CTR_SSH variant (128-bit big-endian counter) 2026-07-16 15:42:10 +08:00
cxx include/cxx/{cstdlib,cmath}: Provide std::abs overloads 2026-08-24 12:04:30 +08:00
net arch/arm/src/imxrt: Unify FlexCAN TX work and add SIOCGCANERRORS. 2026-09-01 17:40:47 +08:00
netinet arch/arm/stm32h7: do not log the frames of packet sockets as unknown. 2026-09-23 08:21:59 +02:00
netpacket
nuttx libc, sched: Resolve FDPIC descriptors at module callback entry points. 2026-09-25 10:46:48 -03:00
ssp
sys include/sys/socket.h: add SCM_TIMESTAMPNS and SCM_TIMESTAMPING macros 2026-09-18 20:00:49 +08:00
.gitignore ci: add stdbit.h test 2026-06-29 14:44:17 +02:00
aio.h aio: make the lio_listio() prototype match POSIX 2026-09-14 17:12:49 -03:00
alloca.h
assert.h
byteswap.h
ctype.h
debug.h style: fix checkpatch issues after debug.h move 2026-04-07 07:50:06 -03:00
dirent.h fs/dirent: add d_ino member to struct dirent 2026-06-26 10:45:33 -04:00
dlfcn.h
dsp.h libs/libdsp: Add Matrix operations 2026-07-11 14:55:59 -03:00
dspb16.h
elf.h libs/libc/elf: Read the dynamic tags an FDPIC object needs. 2026-09-08 16:31:16 -03:00
elf32.h
elf64.h
endian.h
err.h
errno.h include/errno.h: skip set_errno in interrupt context 2026-05-03 17:23:40 -03:00
execinfo.h
fcntl.h !include/fcntl.h: align open flags with Linux values 2026-06-30 13:43:44 +08:00
fixedmath.h !compiler: drop CONFIG_HAVE_LONG_LONG and require long long support 2026-05-19 16:21:28 +08:00
fnmatch.h
ftw.h
gcov.h
getopt.h
glob.h
grp.h libc/grp: add getgrouplist() 2026-06-23 23:09:22 +08:00
hex2bin.h
iconv.h
ifaddrs.h
imx_container.h
inttypes.h !sched/clock: remove CONFIG_SYSTEM_TIME64 and always use 64-bit time 2026-05-19 16:21:28 +08:00
iso646.h
langinfo.h
libgen.h
libintl.h
limits.h fs/aio: add configurable AIO_LISTIO_MAX limit 2026-09-14 17:12:49 -03:00
locale.h
lzf.h lzf: prevent lzf header struct optimization 2026-02-13 11:58:50 +01:00
malloc.h
mqueue.h
netdb.h
nl_types.h
nxflat.h !arch/arm: Use r9 as the PIC base register. 2026-08-06 01:38:23 +08:00
obstack.h
paths.h libc: add paths.h, sys/ttydefaults.h and termios IUTF8 2026-09-15 14:51:15 +02:00
poll.h
pthread.h include/pthread : initialize wait_count in PTHREAD_COND_INITIALIZER 2026-06-16 19:12:30 -03:00
pty.h
pwd.h
regex.h
resolv.h
sched.h
search.h LICENSE: update NuttX-PublicDomain SPDX identifier 2025-12-26 19:46:12 +08:00
semaphore.h
shadow.h
signal.h sched/pthread: Implement pthread_sigqueue 2026-09-21 14:53:26 +08:00
spawn.h sched/spawn: Fix MISRA C 2012 Rule 10.4 violations 2026-02-02 20:39:36 +08:00
stdbool.h
stddef.h !compiler: drop CONFIG_HAVE_LONG_LONG and require long long support 2026-05-19 16:21:28 +08:00
stdint.h arm64_head.S: fix the asm code build error 2026-01-13 21:20:52 +08:00
stdio.h stdio.h: Update TMP_MAX definition to match Linux. 2026-01-14 17:28:30 -08:00
stdlib.h fs/binfmt: close symlink TOCTOU and harden setuid/setgid exec hygiene 2026-08-01 15:32:03 -03:00
stdnoreturn.h
string.h include/string.h: mark memset and memcpy as used_code 2026-02-12 13:19:06 -05:00
strings.h !compiler: drop CONFIG_HAVE_LONG_LONG and require long long support 2026-05-19 16:21:28 +08:00
syscall.h
syslog.h
termios.h libc: add paths.h, sys/ttydefaults.h and termios IUTF8 2026-09-15 14:51:15 +02:00
threads.h
time.h
ulimit.h ulimit: add ulimit implementation 2026-01-16 10:03:53 +08:00
unistd.h fs: add chroot() syscall 2026-09-20 22:27:38 +08:00
utime.h
uuid.h
wait.h
wchar.h
wctype.h