sd-dlopen: add header-only public API for FDO .note.dlopen ELF metadata
Expose ELF note dlopen annotation macros as a public header-only API in sd-dlopen.h. This allows any project to embed .note.dlopen metadata in their ELF binaries by simply including the header - no runtime linkage against libsystemd is required. The header provides SD_ELF_NOTE_DLOPEN() and associated macros/constants implementing the ELF dlopen metadata specification for declaring optional shared library dependencies loaded via dlopen() at runtime. Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
committed by
Luca Boccassi
parent
4c7af7d9d1
commit
e10302b6b6
@@ -6,6 +6,7 @@ _systemd_headers = [
|
||||
'sd-bus-vtable.h',
|
||||
'sd-daemon.h',
|
||||
'sd-device.h',
|
||||
'sd-dlopen.h',
|
||||
'sd-event.h',
|
||||
'sd-gpt.h',
|
||||
'sd-hwdb.h',
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#ifndef foosddlopenhfoo
|
||||
#define foosddlopenhfoo
|
||||
|
||||
/***
|
||||
systemd is free software; you can redistribute it and/or modify it
|
||||
under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation; either version 2.1 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
systemd is distributed in the hope that it will be useful, but
|
||||
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with systemd; If not, see <https://www.gnu.org/licenses/>.
|
||||
***/
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef _SD_PASTE
|
||||
# define _SD_PASTE_INNER(a, b) a##b
|
||||
# define _SD_PASTE(a, b) _SD_PASTE_INNER(a, b)
|
||||
#endif
|
||||
|
||||
#ifndef _SD_UNIQ
|
||||
# ifdef __COUNTER__
|
||||
# define _SD_UNIQ _SD_PASTE(_sd_uniq_, __COUNTER__)
|
||||
# else
|
||||
# define _SD_UNIQ _SD_PASTE(_sd_uniq_, __LINE__)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* ELF note macros implementing the FDO .note.dlopen standard.
|
||||
*
|
||||
* These macros embed metadata in an ELF binary's .note.dlopen section,
|
||||
* declaring optional shared library dependencies that are loaded via
|
||||
* dlopen() at runtime. Package managers and build systems can read
|
||||
* these notes to discover runtime dependencies not visible in ELF
|
||||
* DT_NEEDED entries.
|
||||
*
|
||||
* Usage:
|
||||
*
|
||||
* SD_ELF_NOTE_DLOPEN("myfeature", "Feature description",
|
||||
* SD_ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED,
|
||||
* "libfoo.so.1");
|
||||
*
|
||||
* See SD_ELF_NOTE_DLOPEN(3) for details.
|
||||
*/
|
||||
|
||||
#define SD_ELF_NOTE_DLOPEN_VENDOR "FDO"
|
||||
#define SD_ELF_NOTE_DLOPEN_TYPE UINT32_C(0x407c0c0a)
|
||||
#define SD_ELF_NOTE_DLOPEN_PRIORITY_REQUIRED "required"
|
||||
#define SD_ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED "recommended"
|
||||
#define SD_ELF_NOTE_DLOPEN_PRIORITY_SUGGESTED "suggested"
|
||||
|
||||
#define _SD_ELF_NOTE_DLOPEN(json, variable_name) \
|
||||
__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(SD_ELF_NOTE_DLOPEN_VENDOR)]; \
|
||||
_Alignas(sizeof(uint32_t)) char dlopen_json[sizeof(json)]; \
|
||||
} variable_name = { \
|
||||
.nhdr = { \
|
||||
.n_namesz = sizeof(SD_ELF_NOTE_DLOPEN_VENDOR), \
|
||||
.n_descsz = sizeof(json), \
|
||||
.n_type = SD_ELF_NOTE_DLOPEN_TYPE, \
|
||||
}, \
|
||||
.name = SD_ELF_NOTE_DLOPEN_VENDOR, \
|
||||
.dlopen_json = json, \
|
||||
}
|
||||
|
||||
#define _SD_SONAME_ARRAY1(a) "[\"" a "\"]"
|
||||
#define _SD_SONAME_ARRAY2(a, b) "[\"" a "\",\"" b "\"]"
|
||||
#define _SD_SONAME_ARRAY3(a, b, c) "[\"" a "\",\"" b "\",\"" c "\"]"
|
||||
#define _SD_SONAME_ARRAY4(a, b, c, d) "[\"" a "\",\"" b "\",\"" c "\",\"" d "\"]"
|
||||
#define _SD_SONAME_ARRAY5(a, b, c, d, e) "[\"" a "\",\"" b "\",\"" c "\",\"" d "\",\"" e "\"]"
|
||||
#define _SD_SONAME_ARRAY_GET(_1,_2,_3,_4,_5,NAME,...) NAME
|
||||
#define _SD_SONAME_ARRAY(...) _SD_SONAME_ARRAY_GET(__VA_ARGS__, _SD_SONAME_ARRAY5, _SD_SONAME_ARRAY4, _SD_SONAME_ARRAY3, _SD_SONAME_ARRAY2, _SD_SONAME_ARRAY1)(__VA_ARGS__)
|
||||
|
||||
#define SD_ELF_NOTE_DLOPEN(feature, description, priority, ...) \
|
||||
_SD_ELF_NOTE_DLOPEN("[{\"feature\":\"" feature "\",\"description\":\"" description "\",\"priority\":\"" priority "\",\"soname\":" _SD_SONAME_ARRAY(__VA_ARGS__) "}]", _SD_PASTE(_sd_elf_note_dlopen_, _SD_UNIQ))
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user