__cxa_atexit and __cxa_finalize implementation

Stephen Warren swarren at wwwdotorg.org
Wed Sep 14 16:10:30 UTC 2005


Peter S. Mazinger wrote:
> On Tue, 13 Sep 2005, Stephen Warren wrote:
>>glibc stores atexit.o (and hence the atexit function) into
>>libc_nonshared.a, so a copy of atexit() is included directly into each
>>DSO/app at link time, rather than atexit() being placed into libc.so and
>>dynamically resolved.
>>
>>I guess my patch doesn't do this to atexit() in uClibc.
> 
> your patch adds it to libc.so.0 (nm -D libc.so.0 shows that), so it should 
> be correct. glibc seems to use libc_nonshared.a to:
> 1. hide some symbols (attribute_hidden) to avoid PIC problems
> 2. add these hiddens to each binary by linking libc_nonshared.a into each 
> of them
> 
>>My built copy of uClibc (0.9.27 at least) doesn't seem to have an
>>equivalent to libc_nonshared.a :-( I wonder how to get equivalent
>>functionality...
> 
> you should probably remove #ifdef HAVE_DOT_HIDDEN\nasm....\#endif from 
> your code completely, so that none of the archs makes use of it (frv, 
> sh[64])
> I do not know what is involved to have PIC correctness. Maybe you could 
> ask on glibc list, why they decided to make it hidden and put it into 
> libc_nonshared.

Well, the underlying issue it that each app/DSO needs a different copy
of atexit(), since it references the __dso_handle variable, which must
be different in each app/DSO.

This is the reason atexit is in libc_nonshared.a in glibc, and the
reason that the symbol is hidden (so each app/DSO uses its own copy of
atexit, and doesn't export it to other app/DSOs)

The background:

Code in any app/DSO can call atexit(). The registered function must run
when that specific app/DSO is unloaded. This is because DSOs can be
unloaded much earlier than the app in the case where dlopen/dlclose are
used. In that case, we must run the atexit routines of the DSO being
unloaded when that DSO is unloaded, not when the app exits, because the
code from the DSO won't necessarily be mapped when the app exits.

To make this work, each app/DSO defines a hidden symbol __dso_handle,
which is unique to each app/DSO. Each atexit routine is tagged with the
value of this symbol upon registration. When app/DSO finalization is
run, only atexit routines with a tag matching the app/DSO being
finalized are executed, so e.g. 10 DSOs could be loaded, then 1
unloaded, and only the atexit routines from the being-unloaded DSO get run.

To make this registration work, the implementation of atexit must be
unique to each app/DSO, so that the app/DSO-specific value of
__dso_handle is used to tag the registered atexit routine. Hence, the
need for it to be in a static lib, and be hidden within each app/DSO.

glibc may also use libc_nonshared.a for other things too, but the above
is what's relevant for ctors/dtors.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 254 bytes
Desc: OpenPGP digital signature
Url : http://lists.busybox.net/pipermail/uclibc/attachments/20050914/7c06eb79/attachment.pgp 


More information about the uClibc mailing list