[PATCH] D59264: [Driver] Support compiler-rt crtbegin.o/crtend.o for Linux

Fangrui Song via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Mar 14 02:15:58 PDT 2019

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); }`

  rC Clang



More information about the cfe-commits mailing list