This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: __cxa_finalize/__dso_handle contract
- From: Rich Felker <dalias at libc dot org>
- To: Petr Hosek <phosek at google dot com>
- Cc: libc-alpha at sourceware dot org, Roland McGrath <mcgrathr at google dot com>
- Date: Tue, 2 Apr 2019 11:01:57 -0400
- Subject: Re: __cxa_finalize/__dso_handle contract
- References: <CABBv4TZpjyyBAX_NPjMG74hLYJSbgtPRa-uJJ8BJ7di2o73s8A@mail.gmail.com>
On Mon, Apr 01, 2019 at 01:04:14PM -0700, Petr Hosek wrote:
> I'm working on crtbegin.o/crtend.o implementation for compiler-rt as
> part of the LLVM project (see https://reviews.llvm.org/D28791 for more
> details).
>
> One suggestions that was raised in the review
> (https://reviews.llvm.org/D59264#1428785) is to stop differentiating
> between the shared and non-shared case (i.e. no crtbeginS.o) and
> instead use the same object for both cases. The implication of this
> change is that we would use
>
> void *__dso_handle = &__dso_handle;
>
> instead of
>
> void *__dso_handle = (void *)0;
>
> for the non-shared case. I've checked different libc implementations,
> and AFAICT glibc is the only one that differentiates between the two
> cases in its __cxa_finalize implementation.
>
> In glibc's __cxa_finalize(void *d), a nonzero d has to match the value
> passed to __cxa_atexit but a zero d matches every function registered.
> So it matters that DSO fini calls use &__dso_handle to match their
> registrations for the dlclose case, but it also matters that the main
> executable fini call (i.e. exit itself, and resp. for quick_exit) use
> zero to run all the dtors at exit time.
>
> However, it's not clear whether it needs to be that way, because DSO
> fini should run at exit time too, but it would be a change of how the
> dtors get run that might affect dtor order in some cases.
>
> So my question is whether the dtor order is something that glibc users
> should rely on or whether this is considered (an unsupported) corner
> case and whether the suggested change to always use nonzero d even for
> main executable would break the existing contract between __dso_handle
> and __cxa_finalize for glibc?
There's no reason fixing this needs to result in any change in
behavior. Instead of just special-casing a null pointer, glibc could
special-case "null pointer or address in the range of the main
program's mapping".
There may however be versioning issues fixing this with respect to
version mismatch between components.
Rich