tech-toolchain archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: libelf

On Fri, Jan 15, 2010 at 09:20:29PM -0500, der Mouse wrote:
 > >> To really fix it, FILE would have to become truly opaque, without
 > >> accessors/mutators except for stdio-exported interfaces.
 > > That wouldn't fix it either, unless you never tried to make a change
 > > to FILE and provide backwards ABI compatibility.
 > It's difficult to need backwards ABI compatability when (a) stdio is
 > the only ultimate producer or consumer of FILE *s (ie, producer or
 > consumer who doesn't just produce them from elsewhere or consume them
 > only to pass them along) and (b) stdio's API is stable.

Consider this:

#define stdin   (&__sF[0])
#define stdout  (&__sF[1])
#define stderr  (&__sF[2])

That technically meets your criteria but creates a compatibility
problem. :-p

So yeah, so I made the example too simple and it didn't actually need
the compat versions of struct thing or thing_create and thing_destroy.
If all you have is operations on a pointer, you can change the
representation behind the pointer freely.

Nonetheless, that doesn't necessarily mean that after some change you
don't need to distinguish the old and new creation functions. Perhaps
there's a semantic difference, or perhaps you want to make sure that
objects used by old programs continue to maintain invariants
expected/assumed under the old version of the API. Once you have old
and new versions of your object, even if that version is encoded as a
flag rather than different language-level data types, it's probably
not correct for old and new calls to be mixed indiscriminately. If the
version is a flag, doing so might cause an exception or assertion
failure in the library instead of nasal demons. But at the end of the
day, the application is still broken.

It is silly to argue about whether this problem exists. Binary compat
issues do exist, and it's not always something you can blame on poor
ABI design. (And even if it is, in practice one's stuck with the ABI
design one already has, and tools need to work in the real world as
well as the ideal world.) Try grepping for __RENAME in /usr/include.

Suppose we consider the time_t change then? time_t is now 64 bits wide
where it used to be 32 bits wide. A quick grep shows that libpng
reexports time_t as part of its ABI; an application that uses the
function in question will break if libc is updated unless both it and
libpng are recompiled, regardless of how many compat entry points we
add to libc. And it'll break silently; you won't get any warnings or
errors from the shared library infrastructure or dynamic linking
system. The breakage in this particular case is minimal, but that's
not the point.

 > In the case that got us here, libcurses and FILE *, provided libcurses
 > sticks to stdio-exported interfaces - provided it never goes under the
 > hood of a FILE - there is no issue, even if stdio changes, unless (a)
 > the changes make FILE * change passing-convention-incompatibly, (b)
 > some stdio interface curses uses is being removed, or (c) some stdio
 > interface curses uses changes incompatibly.  None of these are
 > plausible, and merely changing the internals of the struct known as
 > FILE causes none of them.

In real life, FILE is not opaque.

David A. Holland

Home | Main Index | Thread Index | Old Index