From af2d0efcac11723f9be52a3dae22dec31d157e24 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Sun, 20 Mar 2016 10:09:18 +0100 Subject: [PATCH] lib: deregister memtypes on exit/unload This is useful for DSO modules in order to get support for unloading them dynamically. It also runs on exit, which doesn't matter much. At some future point, the code could be extended to check that allocation counts are 0 on unloading a module. Signed-off-by: David Lamparter --- lib/memory.h | 31 +++++++++++++++++++++++++------ 1 file changed, 25 insertions(+), 6 deletions(-) diff --git a/lib/memory.h b/lib/memory.h index 8f7d85a983..d287f229f7 100644 --- a/lib/memory.h +++ b/lib/memory.h @@ -30,7 +30,7 @@ #define SIZE_VAR ~0UL struct memtype { - struct memtype *next; + struct memtype *next, **ref; const char *name; size_t n_alloc; size_t size; @@ -38,7 +38,7 @@ struct memtype struct memgroup { - struct memgroup *next; + struct memgroup *next, **ref; struct memtype *types, **insert; const char *name; }; @@ -54,6 +54,7 @@ struct memgroup # endif # if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3) # define _CONSTRUCTOR(x) constructor(x) +# define _DESTRUCTOR(x) destructor(x) # define _ALLOC_SIZE(x) alloc_size(x) # endif #endif @@ -61,6 +62,7 @@ struct memgroup #ifdef __sun /* Solaris doesn't do constructor priorities due to linker restrictions */ # undef _CONSTRUCTOR +# undef _DESTRUCTOR #endif #ifndef _RET_NONNULL @@ -69,6 +71,9 @@ struct memgroup #ifndef _CONSTRUCTOR # define _CONSTRUCTOR(x) constructor #endif +#ifndef _DESTRUCTOR +# define _DESTRUCTOR(x) destructor +#endif #ifndef _ALLOC_SIZE # define _ALLOC_SIZE(x) #endif @@ -104,14 +109,21 @@ struct memgroup struct memgroup _mg_##mname \ __attribute__ ((section (".data.mgroups"))) = { \ .name = desc, \ - .types = NULL, .next = NULL, .insert = NULL, \ + .types = NULL, .next = NULL, .insert = NULL, .ref = NULL, \ }; \ static void _mginit_##mname (void) \ __attribute__ ((_CONSTRUCTOR (1000))); \ static void _mginit_##mname (void) \ { extern struct memgroup **mg_insert; \ + _mg_##mname.ref = mg_insert; \ *mg_insert = &_mg_##mname; \ - mg_insert = &_mg_##mname.next; } + mg_insert = &_mg_##mname.next; } \ + static void _mgfini_##mname (void) \ + __attribute__ ((_DESTRUCTOR (1000))); \ + static void _mgfini_##mname (void) \ + { if (_mg_##mname.next) \ + _mg_##mname.next->ref = _mg_##mname.ref; \ + *_mg_##mname.ref = _mg_##mname.next; } #define DECLARE_MTYPE(name) \ @@ -122,15 +134,22 @@ struct memgroup attr struct memtype _mt_##mname \ __attribute__ ((section (".data.mtypes"))) = { \ .name = desc, \ - .next = NULL, .n_alloc = 0, .size = 0, \ + .next = NULL, .n_alloc = 0, .size = 0, .ref = NULL, \ }; \ static void _mtinit_##mname (void) \ __attribute__ ((_CONSTRUCTOR (1001))); \ static void _mtinit_##mname (void) \ { if (_mg_##group.insert == NULL) \ _mg_##group.insert = &_mg_##group.types; \ + _mt_##mname.ref = _mg_##group.insert; \ *_mg_##group.insert = &_mt_##mname; \ - _mg_##group.insert = &_mt_##mname.next; } + _mg_##group.insert = &_mt_##mname.next; } \ + static void _mtfini_##mname (void) \ + __attribute__ ((_DESTRUCTOR (1001))); \ + static void _mtfini_##mname (void) \ + { if (_mt_##mname.next) \ + _mt_##mname.next->ref = _mt_##mname.ref; \ + *_mt_##mname.ref = _mt_##mname.next; } #define DEFINE_MTYPE(group, name, desc) \ DEFINE_MTYPE_ATTR(group, name, , desc)