diff options
author | Ben Gamari <ben@smart-cactus.org> | 2022-07-14 15:54:56 -0400 |
---|---|---|
committer | Ben Gamari <ben@smart-cactus.org> | 2022-07-16 08:41:20 -0400 |
commit | 4c5248788feccbdd683681e40a93dc1fe6b3461b (patch) | |
tree | e7f98ca21903ed616a112304a55bc6fc8c282c6a | |
parent | 70568834a0093b87cc1a8b3b8ede19af427c6377 (diff) | |
download | haskell-wip/T21618.tar.gz |
rts/linker: Ensure that __cxa_finalize is called on code unloadwip/T21618
-rw-r--r-- | rts/Linker.c | 18 | ||||
-rw-r--r-- | rts/LinkerInternals.h | 7 |
2 files changed, 25 insertions, 0 deletions
diff --git a/rts/Linker.c b/rts/Linker.c index 0672873a2d..1faff3b371 100644 --- a/rts/Linker.c +++ b/rts/Linker.c @@ -855,6 +855,12 @@ SymbolAddr* lookupDependentSymbol (SymbolName* lbl, ObjectCode *dependent, SymTy return &lookupDependentSymbol; } } + if (strcmp(lbl, MAYBE_LEADING_UNDERSCORE_STR("__cxa_atexit")) == 0 && dependent) { + dependent->cxa_finalize = (cxa_finalize_fn) lookupDependentSymbol( + MAYBE_LEADING_UNDERSCORE_STR("__cxa_finalize"), + dependent, + NULL); + } if (!ghciLookupSymbolInfo(symhash, lbl, &pinfo)) { IF_DEBUG(linker_verbose, debugBelch("lookupSymbol: symbol '%s' not found, trying dlsym\n", lbl)); @@ -937,7 +943,13 @@ SymbolAddr* lookupDependentSymbol (SymbolName* lbl, ObjectCode *dependent, SymTy * relocations of bounded displacement and therefore __dso_handle must not be * too far from the loaded object's code (hence using its start address). * + * Finally, when we see a reference to __cxa_atexit in an object we take care + * to lookup and record the address of __cxa_finalize (largely to ensure that + * the symbol dependency is recorded) and call it with the appropriate handle + * when the object is unloaded. + * * See #20493. + * See section 3.3.5 of the Itanium C++ ABI, version 1.83. */ /* @@ -1150,6 +1162,11 @@ void freeObjectCode (ObjectCode *oc) #endif } + // See Note [Resolving __dso_handle] + if (oc->cxa_finalize) { + oc->cxa_finalize(oc->image); + } + if (oc->type == DYNAMIC_OBJECT) { #if defined(OBJFORMAT_ELF) ACQUIRE_LOCK(&dl_mutex); @@ -1300,6 +1317,7 @@ mkOc( ObjectType type, pathchar *path, char *image, int imageSize, oc->imageMapped = mapped; oc->misalignment = misalignment; + oc->cxa_finalize = NULL; oc->extraInfos = NULL; /* chain it onto the list of objects */ diff --git a/rts/LinkerInternals.h b/rts/LinkerInternals.h index 5370c86357..bafd7f0543 100644 --- a/rts/LinkerInternals.h +++ b/rts/LinkerInternals.h @@ -239,6 +239,8 @@ typedef enum { DYNAMIC_OBJECT, } ObjectType; +typedef void (*cxa_finalize_fn)(void *); + /* Top-level structure for an object module. One of these is allocated * for each object file in use. */ @@ -276,6 +278,11 @@ struct _ObjectCode { after allocation, so that we can use realloc */ int misalignment; + /* The address of __cxa_finalize; set when at least one finalizer was + * register and therefore we must call __cxa_finalize before unloading. + * See Note [Resolving __dso_handle]. */ + cxa_finalize_fn cxa_finalize; + /* The section-kind entries for this object module. An array. */ int n_sections; Section* sections; |