I am sponsoring this fast-track case for myself.
This proposal will time out 05/19/2008

It's not clear that this actually needs PSARC review
since no official interfaces are affected, but it is
a change to the system for old stuff that has been
pervasive in Solaris since Solaris 2.0 and I'd like
to get your opinions.

There are no exported interfaces involved, so there is
no stability level issue.

The proposed release binding (if required) is "minor release"
since no one, certainly not I, wants this to be back-ported
to Solaris 10.

==============================================================
History

Since the dawn of time (that is, since SVR4 came from New Jersey
and became Solaris 2.0), there have been synonym symbols in
the system-supplied libraries, most prevalently in libc.

Synonym symbols come in pairs like this:
        opendir
        _opendir
These two functions are identical.  Not identical contents but
exactly the same location in memory.  This is most commonly
achieved with #pragma weak directives.  (Back in the days of
static system libraries, the notion of 'strong' and 'weak'
symbols had some meaning, but with dynamically linked system
libraries the distinction is lost and the two symbols are just
alternate names for the same function.)

The motivation for synonym symbols is to allow applications
and system libraries to define and use the same symbol names
without hurting with each other.  Standards-conforming applications
are constrained not to define or call functions with leading
underscores in their names.  The system libraries are not so
constrained.

So, for example, libc defines opendir() and it calls opendir()
internally in its implementation of ttyname().  If an application
defines its own version of opendir() (which does something entirely
different from opendir() in libc) and the application also calls
ttyname() in libc, which instance of opendir() will be called by
libc's ttyname()?

The solution to this problem has historically (since the dawn of time)
been synonym symbols.  Internally, libc calls the _opendir() symbol.
This way, the application can define and use its opendir() function
for whatever it chooses and there will be no problem when the
application calls ttyname().

The implementation of this scheme for system libraries involves
special header files, usr/src/lib/libc/inc/synonyms.h for libc and
usr/src/lib/common/inc/c_synonyms.h for all other system libraries.
These header files contain definitions like these:
        #define openat          _openat
        #define opendir         _opendir
        #define openlog         _openlog
        #define open            _open
There are over one thousand definitions in each file.
For the scheme to work, every source file in libc must do this:
        #include "synonyms.h"
before including any other header file.

Neither synonyms.h nor c_synonyms.h are delivered as header files
for Solaris.  They are OS/NET consolidation-private files.

The source code for ttyname() in libc shows a call to opendir(),
but by virtue of including "synonyms.h", the compiled code
actually calls _opendir().

For the scheme to work for all system libraries delivered from
the OS/NET consolidation, all other libraries are required to
include "c_synonyms.h" before any other header file in every
one of their source files.  Some of them do (libnsl, libresolve,
libgen plus a few others) but the vast majority of them do not.

So the synonyms scheme is a failure for most libraries, due to
historical omission.

==============================================================
The better solution

So much for history.  Now for today's situation.

The change for this bug report was recently integrated
into /ws/onnv-gate:

4947191 OSNet should use direct bindings

This causes all OS/NET libraries, including libc, to be built
using direct binding (-B direct).  As a result, all symbols
referenced by a library are bound either to the definition
within itself or to the definition within its direct dependencies.

This solves the problem for which synonyms were invented
in an elegant and global way.  Now all libraries in OS/NET
have the benefit of not damaging or being damaged by an
application's redefinition of a symbol that the library calls.
The application calls its instance and the library calls its
instance, even though both instances have the same name.
(Excepting, of course, symbols in the malloc() family and
other symbols explicitly defined to be interposable symbols
by default.  These have all been marked NODIRECT in the
appropriate mapfiles.  [The devil is in the details.])

This renders the whole synonyms scheme obsolete.

The final stage of this evolution is to expunge the
various synonyms.h files:
        usr/src/cmd/sgs/libelf/common/syn.h
        usr/src/cmd/sgs/rtld/common/_synonyms.h
        usr/src/lib/common/inc/c_synonyms.h
        usr/src/lib/libc/inc/synonyms.h
        usr/src/lib/libcrypt/inc/des_synonyms.h
        usr/src/lib/libgen/inc/gen_synonyms.h
        usr/src/lib/libtsnet/common/synonyms.h
and to fix all of the source files that include them.

Also, most of the leading-underscore symbols involved
in the synonyms scheme are versioned SUNWprivate_1.1
(over 600 of them).  Many others are versioned public,
some because they are defined in the SVID, hence the ABI,
but others because of mistakes made along the way wherein
developers mistakenly thought that the leading-underscore
symbols should be versioned the same as the primary symbols.

In an ideal world, the SUNWprivate symbols could just be
eliminated since nothing outside of OS/NET can legitimately
call them, and they are not part of the ABI.  This would
reduce the number of symbols exported from libc by 25%.
The non-private symbols cannot be eliminated (although
I wish they could).

However, a search of all of the executables and libraries
not delivered from OS/NET and also all the executables and
libraries in /usr/dist reveals that /lib/libm.so.2, some
older versions of the Studio compiler/debugger components,
and some ancient programs in /usr/dist call 55 of the
SUNWprivate symbols.  So these 55 must be retained,
hopefully to be removed in some future update of Solaris.

==============================================================
The proposal

This brings us to the change being proposed by this PSARC case:

1. Delete these header files from the OS/NET consolidation:
        usr/src/cmd/sgs/libelf/common/syn.h
        usr/src/cmd/sgs/rtld/common/_synonyms.h
        usr/src/lib/common/inc/c_synonyms.h
        usr/src/lib/libc/inc/synonyms.h
        usr/src/lib/libcrypt/inc/des_synonyms.h
        usr/src/lib/libgen/inc/gen_synonyms.h
        usr/src/lib/libtsnet/common/synonyms.h
   and fix all of the source files that include them.

2. Eliminate all of the SUNWprivate leading-underscore symbols
   involved in the synonyms scheme except for the 55 that were
   discovered to be used outside of OS/NET.

Roger Faulkner


Reply via email to