Hi Denis,
Now I understand. You mean, I can propagate information from the target component through its capability space. For a simple example, I could create an (unbound) IPC gate, store a pointer into the label, and use a capability space slot to reference it. I could take one from the area controlled by core, which will (probably) not be overriden: I could take the last one which is 0x1ff.
I had a pretty simple idea in mind: The PD session could offer an RPC function like this:
Dataspace_capability cap_space_info();
A component can call this function to obtain a RAM dataspace of a predefined size from the PD service.
The component startup code calls this function. If it returns a valid dataspace, it attaches the dataspace to its address space. So now, we have a shared memory block that can be written to by the target and inspected by the monitor (because it is the PD service that handed out the 'cap_space_info' dataspace).
Once the shared memory is in place, the target can record information that might be of interest for the monitor to this dataspace. E.g., it may maintain an array of the following struct:
struct Cap_info { unsigned kcap; addr_t badge_ptr; /* pointer to badge value within cap map */ };
Thereby it tells the monitor all the information that is needed to extract/update the information of the cap map.
This array could be updated initially (when the dataspace is mapped, the cap map already contains a bunch of capabilities), and whenever a capability is inserted/removed into/from the cap map.
Note that since both the target and monitor access the cap_space_info concurrently, you'd need to add some kind of synchronization between both, e.g., by maintaining some bits within the cap-space-info dataspace that act as some kind of spinlock.
Core's version of 'Pd_session::cap_space_info' would return an invalid capability. In this case, the component skips the reporting.
I could do the creation of the IPC gate and the assignment in the startup code of the application. I found a file, where a function initializes the main thread:
base_foc/src/lib/base/thread_bootstrap.cc:30
It is called prepare_init_main_thread. Is it save to use this function, or is there a better one?
Its good as it is specific to Fiasco.OC.
What do you think about my approach? Will it work theoretically with the assumption that the last capability slot will not be used by any Genode/Fiasco.OC library and by no future library/component.
I think that your approach could work well but it adds one IPC call for each cap-map operation. The shared-memory idea as drafted above does not impose this overhead. That said, I would suggest to implement whichever way you find easier. ;-)
Cheers Norman