design choices for a loadable module interface

Nicolas Williams Nicolas.Williams at
Tue Jun 29 18:12:26 EDT 2010

On Tue, Jun 29, 2010 at 02:55:08PM -0700, Russ Allbery wrote:
> Nicolas Williams <Nicolas.Williams at> writes:
> > On Tue, Jun 29, 2010 at 02:07:11PM -0700, Russ Allbery wrote:

> > Please explain how (1) doesn't allow that?
> Perhaps I was misled by "the names are the same across all plugin
> implementations of an interface."

That just means that all plugins export functions with the same names,
as opposed to having to prefix each plugin's exported functions' names
with a disambiguator, such as the plugin's name.  (If all plugins are
statically linked in then exported name conflicts become a problem.
With a v-table approach you can keep the same names, except for the one
symbol used to get at the v-table.)

>                                    I took that to mean that if we changed,
> say, the function signature, we'd keep the same symbol for the function,
> which would preclude supporting multiple versions in the same plugin.  But
> maybe something different was meant by that?

If we wanted to change the signature of some function we'd not do that
-- we'd introduce a new function instead and deprecate the old one.

> > I especially dislike manually doing what the linker/loader already does.
> The problem that I have with your proposal is precisely that the
> linker/loader *cannot* check the ABI fully.  All it can check is whether

This is true.  It's true only because we don't have versioning in
dlopen() (I believe we should have a versioned variant of dlopen()).

HOWEVER, just because there is one thing that the linker/loader will not
do for us does not mean we should throw the baby out with the bath water
and effectively duplicate other linker/loader functionality.

> there's a symbol with the appropriate name, but that function may be
> expecting a completely different set of arguments if that changed over
> time.  When you call that function, you can then get segfaults or memory
> clobbers or other nastiness.  I'm therefore skeptical of relying only on
> the linker/loader.

Plugin versioning in a framework using dlopen() must be done by the
framework.  This is true in _both_ (1) and (2).  Both require versioning
to be done by the dlopen() caller; both allow you to have implicit or
explicit version identifiers, whichever is preferred.

> With either the vtable or the function approach, you have to rename the
> symbols whenever the signature changes.  With the vtable approach, you

Not so.  You can deprecate old ones and add new ones.  No renames

> encapsulate defined versions of the API in a single struct and know in the
> plugin exactly which set of functions will be called together.  With the
> function approach, you are essentially keeping track of that separately,

If you decide to never make backwards-incompatible changes to function
signatures and semantics then you there is no need to keep track of
anything more with one scheme or the other.

(1) and (2) really are equivalent, except that (2) requires more work on
the part of plugin authors than (1).

> even if you rename functions when the API changes, and you potentially
> open yourself to confusions that happen only if people mix old and new API
> calls.
> > Data symbols tend to have more issues than function symbols.  There's no
> > GOT when it comes to data symbols, for example.  I once again left my
> > copy of the linkers and loaders book at home.  I strongly recommend
> > against using exported data symbols as part of any ABIs.
> Given that both MIT and Heimdal are already successfully using exported
> data symbols as part of their ABIs, I'd like to hear more concrete details
> of what problems this is currently causing in practice before ruling this
> out.  I assume that you're proposing moving away from this to solve some
> set of problems that are currently affecting both major Kerberos
> implementations?

I distinctly remember issues on Windows; I just don't remember the


More information about the krbdev mailing list