#include "bitfield.h"
#include "compress.h"
#include "dlfcn-util.h"
-#include "dlopen-note.h"
#include "io-util.h"
#include "log.h"
#include "string-table.h"
#pragma once
#include "basic-forward.h"
+#include "dlopen-note.h"
typedef enum Compression {
COMPRESSION_NONE,
int decompress_stream(Compression type, int fdf, int fdt, uint64_t max_bytes);
int decompress_stream_by_filename(const char *filename, int fdf, int fdt, uint64_t max_bytes);
-int dlopen_xz(int log_level);
-int dlopen_lz4(int log_level);
-int dlopen_zstd(int log_level);
-int dlopen_zlib(int log_level);
-int dlopen_bzip2(int log_level);
+int dlopen_xz(int log_level) _dlopen_loader_;
+int dlopen_lz4(int log_level) _dlopen_loader_;
+int dlopen_zstd(int log_level) _dlopen_loader_;
+int dlopen_zlib(int log_level) _dlopen_loader_;
+int dlopen_bzip2(int log_level) _dlopen_loader_;
static inline const char* default_compression_extension(void) {
return compression_extension_to_string(DEFAULT_COMPRESSION) ?: "";
#include "basic-forward.h"
#include "strv.h"
+/* Prevent dlopen helper functions (e.g., dlopen_libfoo()) from being inlined or cloned by the compiler/LTO.
+ * This ensures that their specific symbols remain intact in the final executable, allowing the developer
+ * test utility to verify that the functions corresponding to the dlopen ELF notes are actually invoked.
+ * This is restricted to BUILD_MODE_DEVELOPER to avoid degrading production performance. */
+#if BUILD_MODE_DEVELOPER
+# define _dlopen_loader_ _noclone_ _noinline_
+#else
+# define _dlopen_loader_
+#endif
+
/* Avoid invalid priority. */
#define _DLOPEN_CHECK_PRIORITY_required 1
#define _DLOPEN_CHECK_PRIORITY_recommended 1
#define _hidden_ __attribute__((__visibility__("hidden")))
#define _likely_(x) (__builtin_expect(!!(x), 1))
#define _malloc_ __attribute__((__malloc__))
+#ifdef __clang__
+# define _noclone_
+#else
+# define _noclone_ __attribute__((noclone))
+#endif
#define _noinline_ __attribute__((noinline))
#define _noreturn_ _Noreturn
#define _packed_ __attribute__((__packed__))
DLSYM_PROTOTYPE(xkb_keymap_new_from_names) = NULL;
DLSYM_PROTOTYPE(xkb_keymap_unref) = NULL;
+_dlopen_loader_
static int dlopen_xkbcommon(int log_level) {
static void *xkbcommon_dl = NULL;
}
#endif
-int dlopen_libacl(int log_level);
+int dlopen_libacl(int log_level) _dlopen_loader_;
#define DLOPEN_LIBACL(log_level, priority) \
({ \
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "apparmor-util.h"
-#include "dlopen-note.h"
#include "log.h"
#if HAVE_APPARMOR
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
+#include "dlopen-note.h"
#include "shared-forward.h"
#if HAVE_APPARMOR
}
#endif
-int dlopen_libapparmor(int log_level);
+int dlopen_libapparmor(int log_level) _dlopen_loader_;
int blkid_probe_lookup_value_u64(blkid_probe b, const char *field, uint64_t *ret);
#endif
-int dlopen_libblkid(int log_level);
+int dlopen_libblkid(int log_level) _dlopen_loader_;
#define DLOPEN_LIBBLKID(log_level, priority) \
({ \
int bpf_get_error_translated(const void *ptr);
#endif
-int dlopen_bpf(int log_level);
+int dlopen_bpf(int log_level) _dlopen_loader_;
#define DLOPEN_BPF(log_level, priority) \
({ \
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(OpenSSLAskPasswordUI*, openssl_ask_password_ui_free, NULL);
#endif
-int dlopen_libcrypto(int log_level);
+int dlopen_libcrypto(int log_level) _dlopen_loader_;
#define DLOPEN_LIBCRYPTO(log_level, priority) \
({ \
size_t volume_key_size, char **ret);
#endif
-int dlopen_cryptsetup(int log_level);
+int dlopen_cryptsetup(int log_level) _dlopen_loader_;
#define DLOPEN_CRYPTSETUP(log_level, priority) \
({ \
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(struct curl_slist*, sym_curl_slist_free_all, curl_slist_free_allp, NULL);
#endif
-int dlopen_curl(int log_level);
+int dlopen_curl(int log_level) _dlopen_loader_;
#define DLOPEN_CURL(log_level, priority) \
({ \
#include "alloc-util.h"
#include "coredump-util.h"
#include "dlfcn-util.h"
-#include "dlopen-note.h"
#include "elf-util.h"
#include "errno-util.h"
#include "escape.h"
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
+#include "dlopen-note.h"
#include "shared-forward.h"
-int dlopen_dw(int log_level);
-int dlopen_elf(int log_level);
+int dlopen_dw(int log_level) _dlopen_loader_;
+int dlopen_elf(int log_level) _dlopen_loader_;
bool dlopen_dw_has_dwfl_set_sysroot(void);
int fdisk_partition_set_attrs_as_uint64(struct fdisk_partition *pa, uint64_t flags);
#endif
-int dlopen_fdisk(int log_level);
+int dlopen_fdisk(int log_level) _dlopen_loader_;
#define DLOPEN_FDISK(log_level, priority) \
({ \
/* SPDX-License-Identifier: LGPL-2.1-or-later */
-#include "dlopen-note.h"
#include "gnutls-util.h"
#include "log.h" /* IWYU pragma: keep */
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
+#include "dlopen-note.h"
#include "shared-forward.h"
-int dlopen_gnutls(int log_level);
+int dlopen_gnutls(int log_level) _dlopen_loader_;
#if HAVE_GNUTLS
# ifndef SYSTEMD_CFLAGS_MARKER_LIBGNUTLS
extern DLSYM_PROTOTYPE(idn2_to_unicode_8z8z);
#endif
-int dlopen_idn(int log_level);
+int dlopen_idn(int log_level) _dlopen_loader_;
#define DLOPEN_IDN(log_level, priority) \
({ \
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(struct archive*, sym_archive_read_free, archive_read_freep, NULL);
#endif
-int dlopen_libarchive(int log_level);
+int dlopen_libarchive(int log_level) _dlopen_loader_;
#define DLOPEN_LIBARCHIVE(log_level, priority) \
({ \
#include <linux/netlink.h>
#include <sys/socket.h>
-#include "dlopen-note.h"
#include "errno-util.h"
#include "fd-util.h"
#include "iovec-util.h"
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
+#include "dlopen-note.h"
#include "shared-forward.h"
-int dlopen_libaudit(int log_level);
+int dlopen_libaudit(int log_level) _dlopen_loader_;
#if HAVE_AUDIT
# ifndef SYSTEMD_CFLAGS_MARKER_LIBAUDIT
#include "alloc-util.h"
#include "dlfcn-util.h"
-#include "dlopen-note.h"
#include "errno-util.h"
#include "libcrypt-util.h"
#include "log.h"
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
+#include "dlopen-note.h"
#include "shared-forward.h"
#if HAVE_LIBCRYPT
}
#endif
-int dlopen_libcrypt(int log_level);
+int dlopen_libcrypt(int log_level) _dlopen_loader_;
bool looks_like_hashed_password(const char *s);
/* SPDX-License-Identifier: LGPL-2.1-or-later */
-#include "dlopen-note.h"
#include "libfido2-util.h"
#include "log.h"
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
+#include "dlopen-note.h"
#include "shared-forward.h"
#define FIDO2_SALT_SIZE 32U
_FIDO2ENROLL_TYPE_INVALID = -EINVAL,
} Fido2EnrollFlags;
-int dlopen_libfido2(int log_level);
+int dlopen_libfido2(int log_level) _dlopen_loader_;
#if HAVE_LIBFIDO2
#ifndef SYSTEMD_CFLAGS_MARKER_LIBFIDO2
#endif
-int dlopen_libmount(int log_level);
+int dlopen_libmount(int log_level) _dlopen_loader_;
#define DLOPEN_LIBMOUNT(log_level, priority) \
({ \
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(struct MHD_Response*, sym_MHD_destroy_response, MHD_destroy_responsep, NULL);
#endif
-int dlopen_microhttpd(int log_level);
+int dlopen_microhttpd(int log_level) _dlopen_loader_;
#define DLOPEN_MICROHTTPD(log_level, priority) \
({ \
#endif
-int dlopen_libkmod(int log_level);
+int dlopen_libkmod(int log_level) _dlopen_loader_;
#define DLOPEN_LIBKMOD(log_level, priority) \
({ \
int pam_putenv_assign(pam_handle_t *pamh, const char *name, const char *value);
#endif
-int dlopen_libpam(int log_level);
+int dlopen_libpam(int log_level) _dlopen_loader_;
#define DLOPEN_LIBPAM(log_level, priority) \
({ \
/* SPDX-License-Identifier: LGPL-2.1-or-later */
-#include "dlopen-note.h"
#include "errno-util.h" /* IWYU pragma: keep */
#include "log.h" /* IWYU pragma: keep */
#include "password-quality-util-passwdqc.h"
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
+#include "dlopen-note.h"
#include "shared-forward.h"
#if HAVE_PASSWDQC
int check_password_quality(const char *password, const char *old, const char *username, char **ret_error);
#endif
-int dlopen_passwdqc(int log_level);
+int dlopen_passwdqc(int log_level) _dlopen_loader_;
/* SPDX-License-Identifier: LGPL-2.1-or-later */
-#include "dlopen-note.h"
#include "errno-util.h"
#include "log.h"
#include "password-quality-util-pwquality.h"
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
+#include "dlopen-note.h"
#include "shared-forward.h"
#if HAVE_PWQUALITY
int check_password_quality(const char *password, const char *old, const char *username, char **ret_error);
#endif
-int dlopen_pwquality(int log_level);
+int dlopen_pwquality(int log_level) _dlopen_loader_;
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include "dlfcn-util.h"
-#include "dlopen-note.h"
#include "hash-funcs.h"
#include "log.h"
#include "pcre2-util.h"
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
+#include "dlopen-note.h"
#include "shared-forward.h"
#if HAVE_PCRE2
int pattern_compile_and_log(const char *pattern, PatternCompileCase case_, pcre2_code **ret);
int pattern_matches_and_log(pcre2_code *compiled_pattern, const char *message, size_t size, size_t *ret_ovec);
-int dlopen_pcre2(int log_level);
+int dlopen_pcre2(int log_level) _dlopen_loader_;
#include "ask-password-api.h"
#include "crypto-util.h"
#include "dlfcn-util.h"
-#include "dlopen-note.h"
#include "env-util.h"
#include "escape.h"
#include "format-table.h"
#include "ask-password-api.h"
#include "dlfcn-util.h"
+#include "dlopen-note.h"
#include "pkcs11-padding.h"
#include "shared-forward.h"
#endif
-int dlopen_p11kit(int log_level);
+int dlopen_p11kit(int log_level) _dlopen_loader_;
typedef struct {
const char *friendly_name;
#include "ansi-color.h"
#include "dlfcn-util.h"
-#include "dlopen-note.h"
#include "locale-util.h"
#include "log.h"
#include "strv.h"
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
+#include "dlopen-note.h"
#include "shared-forward.h"
int print_qrcode_full(
unsigned tty_height,
bool check_tty);
-int dlopen_qrencode(int log_level);
+int dlopen_qrencode(int log_level) _dlopen_loader_;
static inline int print_qrcode(FILE *out, const char *header, const char *string) {
return print_qrcode_full(out, header, string, UINT_MAX, UINT_MAX, UINT_MAX, UINT_MAX, true);
#endif
-int dlopen_libseccomp(int log_level);
+int dlopen_libseccomp(int log_level) _dlopen_loader_;
#define DLOPEN_LIBSECCOMP(log_level, priority) \
({ \
#endif
-int dlopen_libselinux(int log_level);
+int dlopen_libselinux(int log_level) _dlopen_loader_;
#define DLOPEN_LIBSELINUX(log_level, priority) \
({ \
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(SSL_CTX*, sym_SSL_CTX_free, SSL_CTX_freep, NULL);
#endif
-int dlopen_libssl(int log_level);
+int dlopen_libssl(int log_level) _dlopen_loader_;
#define DLOPEN_LIBSSL(log_level, priority) \
({ \
static DLSYM_PROTOTYPE(Tss2_RC_Decode) = NULL;
+_dlopen_loader_
static int dlopen_tpm2_esys(int log_level) {
static void *libtss2_esys_dl = NULL;
int r;
return 0;
}
+_dlopen_loader_
static int dlopen_tpm2_rc(int log_level) {
static void *libtss2_rc_dl = NULL;
DLSYM_ARG(Tss2_RC_Decode));
}
+_dlopen_loader_
static int dlopen_tpm2_mu(int log_level) {
static void *libtss2_mu_dl = NULL;
DLSYM_ARG(Tss2_MU_UINT32_Marshal));
}
+_dlopen_loader_
static int dlopen_tpm2_tcti_device(int log_level) {
static void *libtss2_tcti_device_dl = NULL;
#define TPM2_N_HASH_ALGORITHMS 4U
-int dlopen_tpm2(int log_level);
+int dlopen_tpm2(int log_level) _dlopen_loader_;
/* tpm2_unseal() returns a bunch of different errors for various flavours of PCR issues, let's group them.
* Kept outside the HAVE_TPM2 guard as callers switch on these errnos even in builds without TPM2. */