MaskRay added a comment.

> A nonzero __dso_handle has to match the value passed to __cxa_atexit but a 
> zero __dso_handle matches every function registered. So it matters that DSO 
> fini calls use &__dso_handle to match their registrations for the dlclose case

Yes, but this won't matter if we change `void *__dso_handle = 0;` to `void 
*__dso_handle = &__dso_handle;`.

  static void __do_global_dtors_aux() { // static void __do_fini() in D28791
    if (__cxa_finalize)
      __cxa_finalize(__dso_handle); // what happens if we change `void 
*__dso_handle = 0;` to `void *__dso_handle = &__dso_handle;`.
    ...
  }

exit calls `__run_exit_handlers` which goes through `__exit_funcs`.
`__cxa_atexit(_dl_fini,0,__dso_handle)` runs before other atexit registered 
functions after main() is executed.[1]

`__do_global_dtors_aux` is called by `_dl_fini`. When it gets called and it 
calls `__cxa_finalize(0)`, other atexit registered functions have run, thus 
__cxa_finalize(0) will do nothing.

The differentiation of `crtbegin.o crtbeginS.o` is unnecessary. It adds 
complexity for little size benefit (crtbegin.o is a bit smaller than 
crtbeginS.o).
While we are adding support for crtbegin.o, it'd be really good to get this 
fixed.

[1]: If a shared object has a constructor that calls `__cxa_atexit`, 
`__cxa_atexit(_dl_fini,...)` will not be the first.

  If you try really hard you can break that in glibc (but not in FreeBSD libc), 
but I'll call that an unsupported land as functions in the main executable 
(`register_in_exe`) shouldn't be called before it is initialized.
  `__attribute__((constructor)) void init_in_dso() { register_in_exe(); 
atexit(fini_in_dso); }`


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D59264/new/

https://reviews.llvm.org/D59264



_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to