File genode-haiku/haiku-on-genode/system/README.md from the latest check-in
Launching executable programs
with fork/exec
fork() and exec() are provided by Genode's libc.
load_image() implementation
We also supply load_image() (as per Be-style API). The implementation within this directory in api-public_main.cpp is not self-contained, but instead interacts (depends on) the registrar (hai-src/server/registrar).
UPD: the implementation has been moved to sys-libroot/os/image.cpp (but that hierarchy should really be located here in system/ anyway)
Here's an outline of the call chain ; load_image() (or BRoster.Launch(), which amounts to the same) sends a BMessage to the registrar component, which then generate an XML report for the init/dyn component to make it launch the specified program:
arrow "App" "" box "BRoster:" "Launch()" "_LaunchApp()" fit arrow down from last box.s box "load_image()" "rosterPrivate.RemoteLaunchInRegistrar()" fit arrow right from last box.e box "BRoster" fit arrow right 200% from last box.e "BMessage/RPC" "call" oval "registrar:" "_HandleLaunch" "DynRunRoster class" fit arrow right 200% "Report" "to ROM" oval "init (dyn)" move left from 2nd box.w arrow right "App" ""→ /pikchrshow
As to init/Dynit, it ultimately makes Genode's 'ldso' load the executable and its .so dependencies
either from boot-module ROMs,
or via fs_rom which creates virtual ROMs from a file system.
Finally, ldso performs the loading in 'struct Linker::Elf_file' with a
rom_connection.construct() call.
As far as Depot packages are concerned, the ROMs for the libraries (e.g. qt5.lib.so) are located deep within folder hierarchies. To avoid having to relocate or symlink them at the top of the volume, Genode changes the ROM label to the full path to the library (e.g. /depot/genodelabs/bin/x86_64/qt5/2023-04-25/qt5.lib.so) so that cached_fs_rom will find them -- this is done at the end of depot_deploy's gen_routes().
There are unresolved issues though, with an old Be-style API.
Issues with load_image()
The (historical Be API) load_image() is supposed to return a suspended (paused) thread, and indeed the Be applications that rely on it do call resume_thread() on the heels of load_image().
The issue with our implementation of load_image is
- the process we create is not suspended, and
- we do not return a valid thread_id
Since our current implementation does not provide 1) and 2), a subsequent resume_thread() call fails/errors out. It's easy to 'patch' the code to work around that (e.g. Roster::Launch()) but this should be looked into.