Subject: Re: softfloat fixuns woes
To: Valeriy E. Ushakov <uwe@ptc.spbu.ru>
From: Richard Earnshaw <rearnsha@arm.com>
List: tech-toolchain
Date: 11/10/2003 15:52:18
> [uwe: cc to current-users dropped, as this follow-up concerns toolchain
> technicalities and is not of much interest to current users]
> 
> On Sat, Nov 01, 2003 at 11:19:16 +0000, Richard Earnshaw wrote:
> 
> > 2) It completely breaks when using the new assembler/linker and a FSF 
> > build of gcc-3.4, where libgcc is built with all the support functions 
> > marked as .hidden (libraries are clearly intended to be built 
> > self-contained or linked against the shared libgcc.so).  And the latest 
> > versions of ld enforce this correctly.
> 
> Uh, oh.  Now I'm totally confused.
> 
> When I discussed the sh3 problem documented in toolchain/22452 with
> Kaz Kojima, he mentioned this approach to me, i.e. mark them .hidden,
> link -lgcc{,_pic} everywhere (however I didn't realize that in gcc-3.4
> all symbols in libgcc are marked as .hidden).
> 
> At about the same time we had a PR about C++ exception handling not
> working properly with shared libraries and Nick Hudson fixed it by
> *NOT* linking -lgcc_pic into shared libraries.  However, note, that
> our -lgcc_pic doesn't yet have its symbols .hidden - so may be that's
> causing that PR about exceptions.  [sorry about being unspecific, but
> I don't have the PR number written down and our web interface to gnats
> sucks]
> 
> If marking all libgcc symbols .hidden, including the exception
> handling code &c makes the exceptions work when libgcc_pic is linked
> into every shared library - this will make both PRs (toolchain/22452
> and the one about exceptions) fixed at once and also will save us the
> trouble of doing all these dances with "libgcc0" (as I called the
> library of .hidden symbols that is safe to link into each shared lib
> &c).
> 
> 
> PS: We provide some of the libgcc functions in libc (to make it
> "self-contained"), we will need to move them to libgcc.
> 
> . libc no longer provides an interface it used to provide - a major bump?
> 
> . if we want to keep our implementations for those libgcc functions we
>   will be linking our sources and libgcc sources, so we need to ensure
>   the licenses are compatible (e.g. no ad clause, etc).
> 

Sorry for the delay responding to this, I've been out of the office all 
last week.

We need to be very careful here.  Whether a symbol should be hidden or not 
can depend on what it needs to do and on whether it has persistent static 
data.

I think the general idea in gcc is that a symbol should be hidden if it is 
'pure' in terms of its response (it accesses no writable private static 
data).  Making these symbols hidden avoids any risk of versioning problems 
if the interface needs to change in any way.

However, there are functions in libgcc (specifically those related to 
exception handling) that are definitely NOT pure by this definition.  The 
exception handling code, for example, has to maintain a list of all the 
unwind areas in an application: this code must be registered with a single 
libgcc function into a single list/table/whatever, which is then searched 
when an exception is thrown.  If there are multiple definitions of these 
functions, then they will not create a single list and hence exception 
unwinding will be broken.

Finally, although there a large number of functions that fall into the 
first category, many of these will be highly unlikely to change their 
interface in future versions of gcc (this is speculation on my part, but 
it's based on the fact that they haven't changed in the 10+ years I've 
been working with the compiler).  These functions are good candidates for 
inclusion directly in our libc library because they are stable, and likely 
to be referenced by many if not all applications in the system: 
duplication into each shared library would be a waste of code space 
(though avoiding a PLT trampoline might be a win in performance terms).

Part of the way that gcc handles this is to use symbol versioning -- this 
is a gnu extension that I'm not sure whether or not we support in NetBSD.  
We may do, if it comes for free with LD, but we certainly don't build the 
information into libc -- we use other methods when an interface needs to 
change.

So I think we need to categorize all the routines in libgcc into three 
groups.

- Functions that have very standard interfaces and are (effectively) pure.
- Functions that work as a group and share static data.
- Other functions whose interface might change, but are otherwise pure.

Then functions should be allocated as follows:

pure standard functions should be built into libc{.so,.a,_p.a} etc.
functions sharing static data should be in libgcc.so (this will probably 
only be needed for c++).
The rest should be .hidden and built into libgcc.a, which should be linked 
into every application and every shared library (libgcc_pic.a).

To avoid any linkage problems, we should probably make any definitions in 
libc weak.

R.