diff --git a/Macros.h b/Macros.h index 051bedbc24..4da6d2043e 100644 --- a/Macros.h +++ b/Macros.h @@ -118,6 +118,15 @@ in the source distribution for its full text. #define IGNORE_WCASTQUAL_END #endif +#if defined(__clang__) +#define IGNORE_W11EXTENSIONS_BEGIN _Pragma("clang diagnostic push") \ + _Pragma("clang diagnostic ignored \"-Wc11-extensions\"") +#define IGNORE_W11EXTENSIONS_END _Pragma("clang diagnostic pop") +#else +#define IGNORE_W11EXTENSIONS_BEGIN +#define IGNORE_W11EXTENSIONS_END +#endif + /* Cheaper function for checking NaNs. Unlike the standard isnan(), this may throw an FP exception on a "signaling NaN". (ISO/IEC TS 18661-1 and the C23 standard stated that isnan() throws no @@ -142,4 +151,32 @@ static inline unsigned long long saturatingSub(unsigned long long a, unsigned lo return a > b ? a - b : 0; } +#ifdef HAVE_ALIGNAS +#include + +#define ELF_NOTE_DLOPEN_OWNER "FDO" +#define ELF_NOTE_DLOPEN_TYPE UINT32_C(0x407c0c0a) + +#define DECLARE_ELF_NOTE_DLOPEN(content) \ + IGNORE_W11EXTENSIONS_BEGIN \ + __attribute__((used, section(".note.dlopen"))) alignas(sizeof(uint32_t)) static const struct { \ + struct { \ + uint32_t n_namesz, n_descsz, n_type; \ + } nhdr; \ + char name[sizeof(ELF_NOTE_DLOPEN_OWNER)]; \ + alignas(sizeof(uint32_t)) char dlopen_content[sizeof(content)]; \ + } variable_name = { \ + .nhdr = { \ + .n_namesz = sizeof(ELF_NOTE_DLOPEN_OWNER), \ + .n_descsz = sizeof(content), \ + .n_type = ELF_NOTE_DLOPEN_TYPE, \ + }, \ + .name = ELF_NOTE_DLOPEN_OWNER, \ + .dlopen_content = content, \ + }; \ + IGNORE_W11EXTENSIONS_END +#else +#define DECLARE_ELF_NOTE_DLOPEN() #endif + +#endif /* HEADER_Macros */ diff --git a/configure.ac b/configure.ac index 81836e8e72..23fb0f1850 100644 --- a/configure.ac +++ b/configure.ac @@ -273,6 +273,18 @@ AC_LINK_IFELSE([ [AC_MSG_RESULT(no) AC_MSG_ERROR([can not find required macros: NAN, isgreater() and isgreaterequal()])]) +AC_MSG_CHECKING(for alignas support) +AC_COMPILE_IFELSE([ + AC_LANG_SOURCE( + [[ + #include + alignas(128) char buffer[128]; + ]] + )], + AC_DEFINE([HAVE_ALIGNAS], 1, [The alignas C11 feauture is supported.]) + AC_MSG_RESULT(yes), + AC_MSG_RESULT(no)) + # ---------------------------------------------------------------------- diff --git a/linux/LibNl.c b/linux/LibNl.c index ba1359f20c..956c164f11 100644 --- a/linux/LibNl.c +++ b/linux/LibNl.c @@ -75,6 +75,12 @@ static void unload_libnl(void) { } static int load_libnl(void) { + + DECLARE_ELF_NOTE_DLOPEN("[{\"soname\":[\"libnl-3.so\",\"libnl-3.so.200\"],\"feature\":\"delay-accounting\"," \ + "\"description:\":\"Enables delay accounting support\",\"priority\":\"recommended\"},{\"soname\":[" \ + "\"libnl-genl-3.so\",\"libnl-genl-3.so.200\"],\"feature\":\"delay-accounting\",\"description:\":"\ + "\"Enables delay accounting support\",\"priority\":\"recommended\"}]") + if (libnlHandle && libnlGenlHandle) return 0; diff --git a/linux/LibSensors.c b/linux/LibSensors.c index bfc5903ba7..efae7e7c55 100644 --- a/linux/LibSensors.c +++ b/linux/LibSensors.c @@ -56,6 +56,9 @@ int LibSensors_init(void) { #else + DECLARE_ELF_NOTE_DLOPEN("[{\"soname\":[\"libsensors.so\",\"libsensors.so.5\",\"libsensors.so.4\"],\"feature\":"\ + "\"sensors\",\"description:\":\"Enables hardware sensor support\",\"priority\":\"recommended\"}]") + if (!dlopenHandle) { /* Find the unversioned libsensors.so (symlink) and prefer that, but Debian has .so.5 and Fedora .so.4 without matching symlinks (unless people install the -dev packages) */ diff --git a/linux/SystemdMeter.c b/linux/SystemdMeter.c index 039e578dbf..d1b747157b 100644 --- a/linux/SystemdMeter.c +++ b/linux/SystemdMeter.c @@ -98,6 +98,9 @@ static void SystemdMeter_done(ATTR_UNUSED Meter* this) { static int updateViaLib(bool user) { SystemdMeterContext_t* ctx = user ? &ctx_user : &ctx_system; #ifndef BUILD_STATIC + DECLARE_ELF_NOTE_DLOPEN("[{\"soname\":[\"libsystemd.so.0\"],\"feature\":\"systemd\",\"description:\":"\ + "\"Enables systemd support\",\"priority\":\"suggested\"}]") + if (!dlopenHandle) { dlopenHandle = dlopen("libsystemd.so.0", RTLD_LAZY); if (!dlopenHandle)