2018-11-19 20:08:04 +01:00
# pragma once
2018-11-27 08:33:28 +01:00
# include "alloc-util.h"
2018-11-19 20:08:04 +01:00
# include "macro.h"
/* A framework for registering static variables that shall be freed on shutdown of a process. It's a bit like gcc's
* destructor attribute , but allows us to precisely schedule when we want to free the variables . This is supposed to
* feel a bit like the gcc cleanup attribute , but for static variables . Note that this does not work for static
* variables declared in . so ' s , as the list is private to the same linking unit . But maybe that ' s a good thing . */
typedef struct StaticDestructor {
void * data ;
2018-11-27 08:33:28 +01:00
free_func_t destroy ;
2018-11-19 20:08:04 +01:00
} StaticDestructor ;
# define STATIC_DESTRUCTOR_REGISTER(variable, func) \
_STATIC_DESTRUCTOR_REGISTER ( UNIQ , variable , func )
# define _STATIC_DESTRUCTOR_REGISTER(uq, variable, func) \
/* Type-safe destructor */ \
static void UNIQ_T ( static_destructor_wrapper , uq ) ( void * p ) { \
typeof ( variable ) * q = p ; \
func ( q ) ; \
} \
2018-12-03 17:33:28 +01:00
/* The actual destructor structure we place in a special section to find it */ \
sd-bus,static-destruct: clean up how we do our ELF section magic
This cleans up a bit how we set up things for the ELF section magic:
1. Let's always use our gcc macros, instead of __attribute__ directly
2. Align our structures to sizeof(void*), i.e. the pointer size, rather
than a fixed 8 or __BIGGEST_ALIGNMENT__. The former is unnecessarily
high for 32bit systems, the latter too high for 64bit systems. gcc
seems to use ptr alignment for static variables itself, hence this
should be good enough for us too. Moreover, the Linux kernel also
uses pointer alginment for all its ELF section registration magic,
hence this should be good enough for us too.
3. Let's always prefix the sections we create ourself with SYSTEMD_,
just to make clear where they come from.
4. Always align the pointer we start from when iterating through these
lists. This should be unnecessary, but makes things nicely
systematic, as we'll align all pointers we use to access these
sections properly.
2018-12-03 13:22:15 +01:00
_section_ ( " SYSTEMD_STATIC_DESTRUCT " ) \
2018-12-03 17:33:28 +01:00
/* We pick pointer alignment, since that is apparently what gcc does for static variables */ \
sd-bus,static-destruct: clean up how we do our ELF section magic
This cleans up a bit how we set up things for the ELF section magic:
1. Let's always use our gcc macros, instead of __attribute__ directly
2. Align our structures to sizeof(void*), i.e. the pointer size, rather
than a fixed 8 or __BIGGEST_ALIGNMENT__. The former is unnecessarily
high for 32bit systems, the latter too high for 64bit systems. gcc
seems to use ptr alignment for static variables itself, hence this
should be good enough for us too. Moreover, the Linux kernel also
uses pointer alginment for all its ELF section registration magic,
hence this should be good enough for us too.
3. Let's always prefix the sections we create ourself with SYSTEMD_,
just to make clear where they come from.
4. Always align the pointer we start from when iterating through these
lists. This should be unnecessary, but makes things nicely
systematic, as we'll align all pointers we use to access these
sections properly.
2018-12-03 13:22:15 +01:00
_alignptr_ \
2018-12-03 17:33:28 +01:00
/* Make sure this is not dropped from the image because not explicitly referenced */ \
sd-bus,static-destruct: clean up how we do our ELF section magic
This cleans up a bit how we set up things for the ELF section magic:
1. Let's always use our gcc macros, instead of __attribute__ directly
2. Align our structures to sizeof(void*), i.e. the pointer size, rather
than a fixed 8 or __BIGGEST_ALIGNMENT__. The former is unnecessarily
high for 32bit systems, the latter too high for 64bit systems. gcc
seems to use ptr alignment for static variables itself, hence this
should be good enough for us too. Moreover, the Linux kernel also
uses pointer alginment for all its ELF section registration magic,
hence this should be good enough for us too.
3. Let's always prefix the sections we create ourself with SYSTEMD_,
just to make clear where they come from.
4. Always align the pointer we start from when iterating through these
lists. This should be unnecessary, but makes things nicely
systematic, as we'll align all pointers we use to access these
sections properly.
2018-12-03 13:22:15 +01:00
_used_ \
2018-12-03 17:33:28 +01:00
/* Make sure that AddressSanitizer doesn't pad this variable: we want everything in this section packed next to each other so that we can enumerate it. */ \
_variable_no_sanitize_address_ \
2018-11-19 20:08:04 +01:00
static const StaticDestructor UNIQ_T ( static_destructor_entry , uq ) = { \
. data = & ( variable ) , \
. destroy = UNIQ_T ( static_destructor_wrapper , uq ) , \
}
/* Beginning and end of our section listing the destructors. We define these as weak as we want this to work even if
* there ' s not a single destructor is defined in which case the section will be missing . */
2018-12-03 13:08:33 +01:00
extern const struct StaticDestructor _weak_ __start_SYSTEMD_STATIC_DESTRUCT [ ] ;
extern const struct StaticDestructor _weak_ __stop_SYSTEMD_STATIC_DESTRUCT [ ] ;
2018-11-19 20:08:04 +01:00
2019-11-01 11:31:20 +01:00
/* The function to destroy everything. (Note that this must be static inline, as it's key that it remains in
* the same linking unit as the variables we want to destroy . ) */
2018-11-19 20:08:04 +01:00
static inline void static_destruct ( void ) {
const StaticDestructor * d ;
if ( ! __start_SYSTEMD_STATIC_DESTRUCT )
return ;
sd-bus,static-destruct: clean up how we do our ELF section magic
This cleans up a bit how we set up things for the ELF section magic:
1. Let's always use our gcc macros, instead of __attribute__ directly
2. Align our structures to sizeof(void*), i.e. the pointer size, rather
than a fixed 8 or __BIGGEST_ALIGNMENT__. The former is unnecessarily
high for 32bit systems, the latter too high for 64bit systems. gcc
seems to use ptr alignment for static variables itself, hence this
should be good enough for us too. Moreover, the Linux kernel also
uses pointer alginment for all its ELF section registration magic,
hence this should be good enough for us too.
3. Let's always prefix the sections we create ourself with SYSTEMD_,
just to make clear where they come from.
4. Always align the pointer we start from when iterating through these
lists. This should be unnecessary, but makes things nicely
systematic, as we'll align all pointers we use to access these
sections properly.
2018-12-03 13:22:15 +01:00
d = ALIGN_TO_PTR ( __start_SYSTEMD_STATIC_DESTRUCT , sizeof ( void * ) ) ;
2018-11-19 20:08:04 +01:00
while ( d < __stop_SYSTEMD_STATIC_DESTRUCT ) {
d - > destroy ( d - > data ) ;
sd-bus,static-destruct: clean up how we do our ELF section magic
This cleans up a bit how we set up things for the ELF section magic:
1. Let's always use our gcc macros, instead of __attribute__ directly
2. Align our structures to sizeof(void*), i.e. the pointer size, rather
than a fixed 8 or __BIGGEST_ALIGNMENT__. The former is unnecessarily
high for 32bit systems, the latter too high for 64bit systems. gcc
seems to use ptr alignment for static variables itself, hence this
should be good enough for us too. Moreover, the Linux kernel also
uses pointer alginment for all its ELF section registration magic,
hence this should be good enough for us too.
3. Let's always prefix the sections we create ourself with SYSTEMD_,
just to make clear where they come from.
4. Always align the pointer we start from when iterating through these
lists. This should be unnecessary, but makes things nicely
systematic, as we'll align all pointers we use to access these
sections properly.
2018-12-03 13:22:15 +01:00
d = ALIGN_TO_PTR ( d + 1 , sizeof ( void * ) ) ;
2018-11-19 20:08:04 +01:00
}
}