This is the mail archive of the libc-hacker@sources.redhat.com mailing list for the glibc project.

Note that libc-hacker is a closed list. You may look at the archives of this list, but subscription and posting are not open.


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

What to put in a shared libgcc


[Sorry folks, tried to send this to gcc@gnu.org instead of
gcc@gcc.gnu.org :-(]

Here's an analysis of the modules in libgcc.a for GCC 2.95.2 on
i586-pc-linux-gnu.  Feel free to put this up on the gcc web pages if
you like (linked to the libgcc.so discussion page or so).

Based on this analysis, I think the only stuff that should be moved
into a shared libgcc on Linux/x86 is the frame registration stuff
(frame.o) and probably parts of the language-independent exception
handling stuff (libgcc.2[L_eh], i.e. the stuff that ends up in _eh.o).

I left out the arithmetic support functions (such as __ashldi3,
__floatdixf, etc.).  These can go anywhere we like.  That probably
means keeping them in the libgcc archive, provided we can address the
problem of reexporting themfrom shared libraries created with GCC,
which at least on Linux, I think we can.

The reason for putting as little stuff in the shared libgcc as
possible, is simple.  It's much easier to control a small ABI than a
large one.  And one can only add stuff, not remove.

OK here we go.  For some modules I provide the list of global symbols
as reported by nm:

__dummy.o:
00000000 T __dummy

Could this be, eh..., a dummy function?  We can put this wherever we
want.

__gcc_bcmp.o:
0000003b t Letext
00000000 T __gcc_bcmp

Multiple copies don't matter, we can put this obe weherever we want.

_bb.o: 

Functions for basic block profiling.  I don't think these
belong in the shared libgcc.  Profiling isn't something that is
supposed to be done on installed/distributed binaries, so binary
compatibility isn't a problem.

_eh.o:

Functions for exception handling.  I'm not sure about these.  If there
isn't a stable interface for this stuff it shouldn't be added to the
shared libgcc.  If the interface is stable, and the ABI is considered
fixed, this might be added to the shared libgcc.  That might even be
essential to prevent problems from a mismatch with the frame
registration functions.  The presence of __terminate_func also suggests
it might be a good idea.  Otherwise set_terminate() might suffer from
amnesia if additional shared libraries are being dlopen()'ed.

There are plans to use some of this stuff in glibc to implement
pthreads cleanup handlers, in order to let them do the right thing for
multithreaded C++ programs.  In that case the interaction with glibc's
libpthread.so is important too.  Putting things in the shared libgcc
probably avoids any problems.

Is there any reason to put setjmp/longjmp exception handling in the
shared libgcc when DWARF2 unwind info is available?  I don't think
so since it's non-standard.  The sj stuff doesn't need the frame stuff

By the way, is there any reason why __default_terminate() isn't
static?  Or empty() for that matter.  It looks like it isn't
referenced anywhere in the GCC tree, except in the libgcc2.c [L_eh]
itself.  Is this part of an undocumented interface of some sorts or
just an oversight?

_eprintf.o:
00000000 T __eprintf
         U abort
         U fflush
         U fprintf
         U stderr

Better left in the archive.  It's certainly not essential that a
single copy of __eprintf() is used.  This function references abort(),
fflush(), fprintf() and stderr.  The interface of these is dictated by
ISO C, and only depends on the sizeof (int) and sizeof (FILE *).  If
this ends up in a shared library the references will be bound to a
specific version if we link with libc, or to the base version.

_pure.o:
00000000 T __pure_virtial
         U __terminate

The same argument as fot _eprintf.o applies.

_shtab.o:
00000000 D __shtab

Multiple copies may be used.  Doesn't matter where this ends up.

_varargs.o:
00000000 T __builtin_saveregs
         U abort

Multiple copies may be used.  Doesn't really matter where this ends
up, although the argument used with _eprintf.o may be applied to
prefer leaving it in the archive.

exception.o:

Depends on the C++ ABI.  Should therefore not end up in the shared
libgcc.  Probably (parts of) it should be moved into a C++-specific
runtime library.

frame.o:

00000cbc T __deregister_frame
00000c04 T __deregister_frame_info
00000cec T __frame_state_for
00000b20 T __register_frame
00000aa0 T __register_frame_info
00000b54 T __register_frame_info_table
00000bd0 T __register_frame_table
         U abort
         U free
         U malloc
         w pthread_create
         w pthread_getspecific
         w pthread_key_create
         w pthread_key_delete
         w pthread_mutex_lock
         w pthread_mutex_trylock
         w pthread_mutex_unlock
         w pthread_once
         w pthread_setspecific

Functions for EH frame info registration.  This is the module that
started all the trouble.  There has to be a single copy of this module
in the entire process.  The module may be completely absent in
programs that don't use exception handling, i.e. programs that never
call __frame_state_for.  That's why GCC's crtstuff.c goes to some
trouble with weak references to __register_frame_info and
__register_frame_table, although I'm not sure if that has the desired
effect right now.

I think the consensus is that the only chance of having exception
handling work correctly on systems with shared libraries is to put
this module in a shared libgcc.

I'm a bit worried though about the fact that this program references
pthreads functions.  This means that changing the ABI for these
functions in libc might have disastrous consequences.  And since
pthread_mutex_t isn't an opaque type, and might need to be extended to
support new mutex attributes, changing the ABI may become necessary.
Perhaps we should formalize an alternative interface for a basic mutex
type in glibc such that libgcc can use that instead?

Note that __deregister_frame, __register_frame and
__register_frame_table are present for backward compatibility only.
In principle they could be left out from the shared libgcc, which has
the additional advantage that this drops the dependency on malloc()
and free().  They're part glibc right now, but since they can be
easily implemented in terms of the new functions we can provide
an implementation in glibc for them.

new.o:
opdel.o:
opdelnt.o:
opnew.o:
opnewnt.o:
opvdel.o:
opvdelnt.o:
opvnew.o:
opvnewnt.o:
tinfo.o:
tinfo2.o:

These modules depend on the C++ ABI.  Should therefore not end up in
the shared libgcc.  Probably should be moved into a C++-specific
runtime library.

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