public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* Darwin assert.h / shared libgcc mess
@ 2004-11-15 21:43 Zack Weinberg
  2004-11-15 22:42 ` Geoffrey Keating
  0 siblings, 1 reply; 5+ messages in thread
From: Zack Weinberg @ 2004-11-15 21:43 UTC (permalink / raw)
  To: gcc, Stan Shebs, Andrew Pinski, Richard Henderson


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

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Darwin assert.h / shared libgcc mess
  2004-11-15 21:43 Darwin assert.h / shared libgcc mess Zack Weinberg
@ 2004-11-15 22:42 ` Geoffrey Keating
  2004-11-16  3:49   ` Zack Weinberg
  0 siblings, 1 reply; 5+ messages in thread
From: Geoffrey Keating @ 2004-11-15 22:42 UTC (permalink / raw)
  To: Zack Weinberg; +Cc: gcc

Zack Weinberg <zack@codesourcery.com> writes:

> 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.)

This sounds like a good idea.  Be sure that the fixincludes only
triggers on the broken assert.h (looking for __eprintf is good enough
on Darwin; or for the absence of __func__).

> 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.)

Is this really necessary?  I'd rather have __eprintf linked into only
those apps that need it.

> 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.

The Darwin ld does not support symbol versioning.  You can safely delete
any versioning files for Darwin (so long as it doesn't break the makefiles).

> 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).

In Tiger, /usr/include/assert.h will be provided by Libc, not the
compiler, and it will use __assert.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Darwin assert.h / shared libgcc mess
  2004-11-15 22:42 ` Geoffrey Keating
@ 2004-11-16  3:49   ` Zack Weinberg
  2004-11-22 22:50     ` Geoff Keating
  0 siblings, 1 reply; 5+ messages in thread
From: Zack Weinberg @ 2004-11-16  3:49 UTC (permalink / raw)
  To: Geoffrey Keating; +Cc: gcc

Geoffrey Keating <geoffk@geoffk.org> writes:

>> 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.)
>
> Is this really necessary?  I'd rather have __eprintf linked into only
> those apps that need it.

Right now, any shared library that uses assert will fail to link.
_Something_ has to be done.  I'm open to alternative suggestions.

>> 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.
>
> The Darwin ld does not support symbol versioning.  You can safely delete
> any versioning files for Darwin (so long as it doesn't break the makefiles).

Okay, so t-slibgcc-darwin ought to be using mkmap-flat.awk and
-exported_symbols_list.  Thanks for the clarification.

>> 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).
>
> In Tiger, /usr/include/assert.h will be provided by Libc, not the
> compiler, and it will use __assert.

Good.

zw

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Darwin assert.h / shared libgcc mess
  2004-11-16  3:49   ` Zack Weinberg
@ 2004-11-22 22:50     ` Geoff Keating
  2004-11-22 23:57       ` Zack Weinberg
  0 siblings, 1 reply; 5+ messages in thread
From: Geoff Keating @ 2004-11-22 22:50 UTC (permalink / raw)
  To: Zack Weinberg; +Cc: gcc

[-- Attachment #1: Type: text/plain, Size: 763 bytes --]


On 15/11/2004, at 3:39 PM, Zack Weinberg wrote:

> Geoffrey Keating <geoffk@geoffk.org> writes:
>
>>> 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.)
>>
>> Is this really necessary?  I'd rather have __eprintf linked into only
>> those apps that need it.
>
> Right now, any shared library that uses assert will fail to link.
> _Something_ has to be done.  I'm open to alternative suggestions.

What I would do is put __eprintf in the static libgcc.a, and mark it as 
hidden visibility so that it's private to each shared library.

[-- Attachment #2: smime.p7s --]
[-- Type: application/pkcs7-signature, Size: 2410 bytes --]

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: Darwin assert.h / shared libgcc mess
  2004-11-22 22:50     ` Geoff Keating
@ 2004-11-22 23:57       ` Zack Weinberg
  0 siblings, 0 replies; 5+ messages in thread
From: Zack Weinberg @ 2004-11-22 23:57 UTC (permalink / raw)
  To: Geoff Keating; +Cc: gcc

Geoff Keating <geoffk@geoffk.org> writes:

> On 15/11/2004, at 3:39 PM, Zack Weinberg wrote:
>
>> Geoffrey Keating <geoffk@geoffk.org> writes:
>>
>>>> 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.)
>>>
>>> Is this really necessary?  I'd rather have __eprintf linked into only
>>> those apps that need it.
>>
>> Right now, any shared library that uses assert will fail to link.
>> _Something_ has to be done.  I'm open to alternative suggestions.
>
> What I would do is put __eprintf in the static libgcc.a, and mark it as 
> hidden visibility so that it's private to each shared library.

Indeed, right now I am pursuing just such an idea.  It's not done
mainly because mklibgcc.in is very hard to modify.

zw

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2004-11-22 22:33 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2004-11-15 21:43 Darwin assert.h / shared libgcc mess Zack Weinberg
2004-11-15 22:42 ` Geoffrey Keating
2004-11-16  3:49   ` Zack Weinberg
2004-11-22 22:50     ` Geoff Keating
2004-11-22 23:57       ` Zack Weinberg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).