mlibc icon indicating copy to clipboard operation
mlibc copied to clipboard

RFC: C++-style sysdeps without weak symbols

Open no92 opened this issue 1 month ago • 0 comments

This PR provides a small proof of concept for reworking the sysdep interfaces.

Previously, sysdeps were either made required for absolutely basic functionality (like sys_read), and the rest was made optional by way of having them be weak symbols. This lead to a few problems:

  • Getting the signature wrong changes the (mangled) name of the sysdep, which means that the wrongly-typed sysdep would not get picked up; because of how weak symbols work, this breakage was silent and doesn't necessarily even generate a compiler warning/error
  • Using a struct pointer in the signature and declaring the struct afterwards resulted in similar breakage as above.
  • There was trouble in static libraries, see issue #906.

My proposal is derived from @marv7000's godbolt example that shoved the sysdep interface in a C++ class.

This proposal aims to extend on that, so as to provide mechanisms for required sysdeps, optional sysdeps, a transition plan so that changes can be made incrementally.

The core of the PoC is the struct Sysdeps that each sysdep defines. It contains functions that can be called by implementations.

Required sysdeps are enforced by a concept (concept RequiredSysdeps). The struct Sysdeps is globally instantiated as a constinit variable with a requires clause on RequiredSysdeps, which means that missing or having a sysdep wrongly typed results in a short error message at compile-time.

The struct Sysdeps should derive interface classes like AnsiSysdeps for optional sysdeps for each supported option. These base classes provide an implementation for each optional sysdep that amounts to returning ENOSYS, but allow for the sysdep to provide a proper implementation.

As a compatability thing for transitioning, I provided a AnsiCompatSysdeps class that adapts the old weak-symbol interface to the struct Sysdeps. This allows for gradual replacement of the weak symbol implementations by class functions.

The PR currently implements ANSI sysdeps for Linux and managarm as an example using the compat interface as a basis. Some functions are rewritten to use the new interface, and some call sites have been changed to the new style.

Due to the AnsiSysdeps class providing a ENOSYS implementation, we can avoid using the auto sysdep = MLIBC_CHECK_OR_ENOSYS(mlibc::sys_whatever, -1); line and just directly call sysdeps.whatever() instead.

no92 avatar Nov 24 '25 19:11 no92