This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Darwin assert.h / shared libgcc mess


I sat down to look into the problems with <assert.h> on Darwin, which
were exposed by Andrew Pinski's patch on Nov 3

        * config/darwin.h (REAL_LIBGCC_SPEC): Define to use shared
        libgcc for shared libraries.

As I suspected, the apparent problem is just the tip of a very large
iceberg.  I have traced it pretty far back, and would now like to
discuss a solution, before I go off and implement it.

1) /usr/include/assert.h on Darwin depends on __eprintf being provided
   by libgcc.  This is not terribly surprising, considering that GCC
   has been the system compiler for Darwin since NeXT days.

i) It is also seriously non-ISO-C compliant.  This is because someone
   blindly copied the results of a buggy fixincludes edit into
   Darwin's CVS tree.  [The fixincludes edits broken_assert_stdio and
   broken_assert_stdlib both produce an <assert.h> which is
   idempotent.  This is wrong.]

Given (1), IMO the correct thing to do is put __eprintf into
libgcc.dylib on Darwin; Andrew's proposed fix isn't ISO compliant
either (assert() is required to write to stderr, but <assert.h> is
required not to declare "stderr", or "fprintf" or "abort" for that
matter).  However, when one attempts to fix that, one encounters
another set of problems:

2) There is no way to tell mklibgcc.in to add something from libgcc2.c
   to both libgcc.a and libgcc.so.  Even if there were, by itself that
   wouldn't work, because

3) ... the version script would knock it out again.  However, there
   *is* a facility for adding target-specific version map entries.

2i) ... but this doesn't matter, because as far as I can tell
    t-slibgcc-darwin is not actually *using* the generated version map

3i) ... and that is fortunate, because (a) as far as I can tell,
    Darwin ld does not support full-fledged symbol versioning (it does
    support flat export lists), and (b) libgcc-darwin.ver is out of
    sync with libgcc-std.ver.  [And the same is true for
    config/sh/libgcc-std.ver, incidentally.]

---

My proposed fix for all this is as follows.

1) Ship a *correct* assert.h, as a replace-entire-file fixincludes
   edit, which recognizes the broken Darwin /usr/include/assert.h.  If
   I can swing it, it will also subsume the buggy
   broken_assert_{stdio,stdlib} fixes.  This corrected assert.h will
   continue to use __eprintf.  Alternatively, if people prefer, it
   could use the more recent convention of __assert, per, eg. FreeBSD
   /usr/include/assert.h.  (The advantage of this is there aren't
   copies of the "%s:%d:%s: assertion failed: %s" string constant
   everywhere that uses assert.)

2) Put __eprintf back into the shared libgcc, as an exported symbol,
   for all !inhibit_libc targets, so that fixincludes can rely on its
   being there.  (If we instead use __assert, then __eprintf will
   remain a static-library-only backward compatibility symbol.)

3) For the sake of future flexibility, move the hardwired list of
   static-and-shared functions from mklibgcc.in to the Makefile so
   that it can be adjusted in t-fragments.

4) Add the ability to add a leading underscore to all symbol names to
   mkmap-flat.awk and mkmap-symver.awk.  Also add the ability to
   delete symbols from the list, in a target-specific .ver file.
   Update Darwin and SH target configuration to match, and delete the
   out-of-sync libgcc-darwin.ver and config/sh/libgcc-std.ver.

5) Determine for certain whether or not Darwin ld supports symbol
   versioning.  Correct t-slibgcc-darwin to use the appropriate mkmap
   file and to actually apply the map to the generated libgcc.dylib.

i) Nudzh the Darwin developers to put __assert in libSystem and
   provide a correct /usr/include/assert.h (y'all can just copy it
   from FreeBSD!  Only with attribute noreturn, please).

Thoughts?

zw


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]