Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date: Wed, 22 Apr 2020 13:38:25 -0400
From: Rich Felker <dalias@...c.org>
To: libc-coord@...ts.openwall.com
Subject: Macro-based advertisement of libc extensions

This is proposal I've mentioned in various settings for a while, but
that should be discussed more thoroughly in a proper setting, and
libc-coord is the setting I'd been looking to do it in.


Proposal:

I want to establish a common convention, with participation by
multiple (Linux and non-Linux, ideally BSDs and others too) libc
implementations, for macros defined by the implementation to advertise
nonstandard extensions offered for use by applications.

These should be modeled on the POSIX macros defined in unistd.h, like
_POSIX_MONOTONIC_CLOCK, _POSIX_TIMERS, _POSIX_SEMAPHORES, etc. and
should use a dedicated part of the reserved namespace like _EXT_* or
similar. Possibly this should include the semantics for definition
with a value of 0 ("supported for compilation and might or might not
be supported at runtime"), which may make sense for implementations
with different profiles or that only offer certain functionality
contingent on a kernel that supports it, etc. If that option is taken,
there could be corresponding sysconf (e.g. _SC_EXT_*) macros to query
availability at runtime, or a separate interface so as not to overload
sysconf.


Motivation:

Some extension functionality is "reasonably" detectable just with
autoconf style compile/link tests, but these tests can still produce
wrong results if an implementation has a symbol by the same name but
without the same semantics. This has come up with various extensions
people asked to have added to musl, where existence of multiple vendor
versions with same name but different signature or semantics was
deemed a reason not to implement. Moreover, increasingly many
programmers seem to be using non-autoconf build systems and asking for
ways to detect features without any "configure-time" test.

Other extension functionality is completely undetectable without
executing code with undefined behavior and "assuming" the desired
extension is present and supported if the desired result occurs. This
is incompatible with cross-compiling and fundamentally a buggy test
design. For example, since printf with invalid format specifiers has
undefined behavior, there is no way to detect the presence of support
for extensions like %m.

Frequently programmers ask for a libc identity/version macro to solve
these problems, but using that requires hard-coding assumptions about
each known libc, which version functionality was added in, and that
functionality won't be withdrawn. It's also incompatible with
backporting of new features, which distros or systems integrators
often do, and with building custom reduced-functionality versions of a
libc for restrictive environments that might not support some
features.


Implementation:

I'm not particular about how this is done, but my leaning would be
either putting the macros in an existing standard header (preference:
unistd.h) or defining a single macro via a standard header that
advertises the presence of a second header they're all provided by.
Another option might be grouping them by functionality (i.e. stdio
extensions are advertised in stdio.h).

Everything should be in the reserved namespace, with names chosen not
to clash with any known usage by existing implementations, but also
not to be overly verbose.

Extension names should be generic and avoid including the name of a
particular implementation *unless* there are historically clashing
versions of the same extension and there's a need to indicate which
one is implemented (in which case inclusion of an implementation name
X simply means "compatible with the version from X", not "is the
version from X").


Open questons:

What degree of compatibility do "equivalent" extensions need to be
advertised as the same? While I'd like part of the outcome of this
effort to be standardization of common extensions that are deemed to
be worth standardization (upstreaming in C or POSIX), I'm not
proposing running a parallel extra-standard standards organization.

For extensions which already have multiple implementations, I think
the baseline macro should roughly mean "whatever is common between
historical implementations". If some implementations have additional
features (for example, accepting a null pointer) they can define in
addition to _EXT_FOO macros that advertise these additional properties
(in that example, _EXT_FOO_ACCEPTS_NULL).

Where should common names be published? This probably requires some
sort of registry. A minimal version of that would just be posting
intent to this list and not having sustained well-motivated objection
to it. But maybe something more official/searchable/etc. makes sense.

And of course bikeshed stuff: What should the naming pattern be? Etc.

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.