FreeBSD Bugzilla – Attachment 153231 Details for
Bug 115631
[libc] [request] make dlclose(3) atexit-aware
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
atexit-dclose.diff (text/plain), 4.37 KB, created by
Pedro F. Giffuni
on 2015-02-20 18:45:37 UTC
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Pedro F. Giffuni
Created:
2015-02-20 18:45:37 UTC
Size:
4.37 KB
patch
obsolete
>Index: lib/libc/stdlib/atexit.h >=================================================================== >--- lib/libc/stdlib/atexit.h (revision 279068) >+++ lib/libc/stdlib/atexit.h (working copy) >@@ -34,3 +34,23 @@ > #define ATEXIT_SIZE 32 > > void __cxa_finalize(void *dso); >+ >+#define ATEXIT_FN_EMPTY 0 >+#define ATEXIT_FN_STD 1 >+#define ATEXIT_FN_CXA 2 >+ >+struct atexit { >+ struct atexit *next; /* next in list */ >+ int ind; /* next index in this table */ >+ struct atexit_fn { >+ int fn_type; /* ATEXIT_? from above */ >+ union { >+ void (*std_func)(void); >+ void (*cxa_func)(void *); >+ } fn_ptr; /* function pointer */ >+ void *fn_arg; /* argument for CXA callback */ >+ void *fn_dso; /* shared module handle */ >+ } fns[ATEXIT_SIZE]; /* the table itself */ >+}; >+ >+extern struct atexit *__atexit; /* points to head of LIFO stack */ >Index: libexec/rtld-elf/Makefile >=================================================================== >--- libexec/rtld-elf/Makefile (revision 279068) >+++ libexec/rtld-elf/Makefile (working copy) >@@ -8,6 +8,7 @@ > MK_SSP= no > > PROG?= ld-elf.so.1 >+CFLAGS+= -I${.CURDIR:H:H}/lib/libc/stdlib # atexit.h > SRCS= rtld_start.S \ > reloc.c rtld.c rtld_lock.c rtld_printf.c map_object.c \ > malloc.c xmalloc.c debug.c libmap.c >Index: libexec/rtld-elf/rtld.c >=================================================================== >--- libexec/rtld-elf/rtld.c (revision 279068) >+++ libexec/rtld-elf/rtld.c (working copy) >@@ -57,6 +57,7 @@ > #include <string.h> > #include <unistd.h> > >+#include "atexit.h" /* Not a centrally installed header. Yet? */ > #include "debug.h" > #include "rtld.h" > #include "libmap.h" >@@ -123,6 +124,7 @@ > Obj_Entry *rtldobj, int flags, RtldLockState *lockstate); > static int relocate_object(Obj_Entry *obj, bool bind_now, Obj_Entry *rtldobj, > int flags, RtldLockState *lockstate); >+static const char *addr_to_name(const Obj_Entry *, const void *); > static int relocate_objects(Obj_Entry *, bool, Obj_Entry *, int, > RtldLockState *); > static int resolve_objects_ifunc(Obj_Entry *first, bool bind_now, >@@ -2706,6 +2708,54 @@ > return (p); > } > >+/* >+ * Check if the object being dlclose-d holds a function registered >+ * via atexit() or __cxa_atexit(). If it does, formulate a descriptive >+ * error message and return 1. Otherwise return 0 to allow the object >+ * to be closed/unloaded. >+ */ >+static int >+check_atexit(const Obj_Entry *root) >+{ >+ static const struct atexit *__atexit; >+ const struct atexit *p; >+ int n; >+ >+ if (__atexit == NULL) >+ __atexit = (struct atexit *)get_program_var_addr("__atexit"); >+ >+ for (p = __atexit; p; p = p->next) { >+ for (n = p->ind; --n >= 0;) { >+ void *addr; >+ switch (p->fns[n].fn_type) { >+ case ATEXIT_FN_CXA: >+ if (p->fns[n].fn_dso == root) >+ continue; >+ addr = p->fns[n].fn_ptr.cxa_func; >+ break; >+ case ATEXIT_FN_STD: >+ addr = p->fns[n].fn_ptr.std_func; >+ break; >+ default: >+ continue; >+ } >+ if (addr > (void *)root->mapbase && >+ addr < (void *)root->mapbase + root->mapsize) { >+ const char *name = addr_to_name(root, addr); >+ >+ _rtld_error("shared object %s provides " >+ "%satexit-registered function %p (%s)", >+ root->path, >+ p->fns[n].fn_type == ATEXIT_FN_STD ? >+ "an " : "a __cxa_", >+ addr, name ? name : "static?"); >+ return 1; >+ } >+ } >+ } >+ return 0; >+} >+ > int > dlclose(void *handle) > { >@@ -2714,7 +2764,7 @@ > > wlock_acquire(rtld_bind_lock, &lockstate); > root = dlcheck(handle); >- if (root == NULL) { >+ if (root == NULL || check_atexit(root)) { > lock_release(rtld_bind_lock, &lockstate); > return -1; > } >@@ -3986,6 +4036,34 @@ > return (ESRCH); > } > >+/* >+ * If the addr-specified symbol exists in obj's symbol-table, >+ * return its name. Otherwise, return NULL. Searches through >+ * the entire symbol table, but we don't care, because it is >+ * not called often. >+ */ >+static const char * >+addr_to_name(const Obj_Entry *obj, const void *addr) >+{ >+ unsigned long symnum, bucket; >+ if (obj->buckets == NULL) >+ return NULL; >+ >+ for (bucket = 0; bucket < obj->nbuckets; bucket++) { >+ for (symnum = obj->buckets[bucket]; >+ symnum != STN_UNDEF && symnum < obj->nchains; >+ symnum = obj->chains[symnum]) { >+ const Elf_Sym *symp; >+ >+ symp = obj->symtab + symnum; >+ if (symp->st_value + obj->relocbase == addr) >+ return obj->strtab + symp->st_name; >+ } >+ } >+ >+ return NULL; >+} >+ > static void > trace_loaded_objects(Obj_Entry *obj) > {
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 115631
: 153231