Blog

plugin.fedem.eu is live

Posted on 2026-09-08

plugin has its own site starting today, at plugin.fedem.eu. Like its siblings cparse, callonce and fson, it is a small C++ library that has so far lived only as an internal dependency — inside FFS, where it loads the .ffs plugins. Giving it a public home is a step towards treating it as a component other people can pick up.

What plugin is

Three pieces that work together, or on their own:

#include <dso/DSOLoader.hh>
#include <plugin/Plugin.hh>

// 1. The loader — dlopen with a mutex and lifetime management
fedem::dso::DSOLoader::load( "./libCircle.so" );

// 2. The catalog — the DSO's REGISTER(Circle, Shape) line put a factory here
auto shape = Shape::create( "Circle", Circle::Config{ 42 } );
shape->printOn( std::cout );            // Circle r:42

DSOLoader wraps dlopen with RTLD_GLOBAL | RTLD_LAZY, keeps every handle for the process lifetime, and serialises access with a mutex. It can load one file, every file in a directory with a given extension, or every entry on LD_LIBRARY_PATH.

The plugin:: templates are the part that lets a host create a type it never linked against. A plugin translation unit adds one line — REGISTER(Circle, Shape), or REGISTER_WITH_CONFIG(Circle, Shape, Circle::Config) — and when its DSO loads, a factory for "Circle" appears in Shape's catalog. Shape::create("Circle") returns a std::unique_ptr<Shape>.

The third piece, plugin-sign, is for when "load any .so on the path" is too much trust. dso-sign embeds a JSON manifest and a 64-byte Ed25519 signature as ELF sections; at load time DSOLoader::loadVerified checks them against a trusted-keys directory and throws SignatureRejected if the add-on is not TRUSTED. The verification is mmap plus a manual section-table walk — no libelf.

What is here today

What is next

  • Binary packages.deb / .rpm once there is an APT/YUM repository to host them.
  • A worked non-ELF note — the loader is portable dlopen; the signer assumes ELF. Mach-O / PE section embedding is a possible follow-up.
  • ABI-version enforcement in the loader — the manifest already carries abiMajor / abiMinor; wiring a host-declared floor into loadVerified is the obvious next step.

If you use plugin, or the self-registering-catalog pattern it captures, in a project of your own, say hello via the contact page.