casaroli opened a new pull request, #20130: URL: https://github.com/apache/nuttx/pull/20130
depends-on: [apache/nuttx/pull/20089] ## Summary `[5/10]` #19942 and `[5.5/10]` #19940 are merged; `[6/10]` #20089 relocates an FDPIC object. This makes the firmware callable *from* one. 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 handed a module's callback therefore branches into the module's data segment and faults. So the ten entry points that can be handed a callback 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 also covers a module calling `sigaction()` directly. `qsort()` is split so 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 the 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, so a plain kernel task 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 carrying no module's base. The base is captured when the notification is registered, in the module's own context, and installed around the call. ## Impact All of it is behind `CONFIG_FDPIC`, which defaults off and is only selectable where `ARCH_HAVE_ELF_FDPIC` is set. `qsort()` gains an internal split and `scandir()` a blank line; everything else is `#ifdef`'d. With the option off the entry points are what they were. ## Testing `mps3-an547:picostest` builds with `CONFIG_FDPIC` off and on. `tools/checkpatch.sh -c -u -m -g` passes. The run time evidence for the descriptors themselves is in `[10/10]`, whose `pimoroni-pico-2-plus:xipfs-fdpic` carries `apps/testing/fs/xipfs`: it exercises `qsort` and `SIGEV_THREAD` callbacks from a loaded module, which is what this patch exists to make work. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
