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]

Reply via email to