-
-
Notifications
You must be signed in to change notification settings - Fork 439
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Embed ELF metadata about dynamic runtime dependencies #1482
base: main
Are you sure you want to change the base?
Conversation
See https://salsa.debian.org/debian/htop/-/merge_requests/5 for the packaging update. |
Embed metadata about runtime dependencies of dynamic libraries used via dlopen(3) in the binary so that distributions can automatically generate package dependencies. Specification: https://systemd.io/ELF_DLOPEN_METADATA/ (TODO: link not yet available) Inspired-by: systemd/systemd#32234
}; \ | ||
IGNORE_W11EXTENSIONS_END | ||
#else | ||
#define DECLARE_ELF_NOTE_DLOPEN() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should name the content
parameter for consistency.
|
||
#define DECLARE_ELF_NOTE_DLOPEN(content) \ | ||
IGNORE_W11EXTENSIONS_BEGIN \ | ||
__attribute__((used, section(".note.dlopen"))) alignas(sizeof(uint32_t)) static const struct { \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
__attribute__((used, section(".note.dlopen"))) alignas(sizeof(uint32_t)) static const struct { \ | |
__attribute__((packed, used, section(".note.dlopen"))) static const struct { \ |
Just byte-align ourselves and round up with some little magic later
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another problem: C99 doesn't support anonymous struct yet.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another problem: C99 doesn't support anonymous struct yet.
The workaround for that is kinda easy though, too …
struct { \ | ||
uint32_t n_namesz, n_descsz, n_type; \ | ||
} nhdr; \ | ||
char name[sizeof(ELF_NOTE_DLOPEN_OWNER)]; \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
char name[sizeof(ELF_NOTE_DLOPEN_OWNER)]; \ | |
char name[(sizeof(ELF_NOTE_DLOPEN_OWNER)+3)&(~3)]; \ |
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)]; \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
alignas(sizeof(uint32_t)) char dlopen_content[sizeof(content)]; \ | |
char dlopen_content[(sizeof(content)+3)&(~3)]; \ |
Although one could argue if this last expansion is still required at the end of the attribute section.
AC_MSG_CHECKING(for alignas support) | ||
AC_COMPILE_IFELSE([ | ||
AC_LANG_SOURCE( | ||
[[ | ||
#include <stdalign.h> | ||
alignas(128) char buffer[128]; | ||
]] | ||
)], | ||
AC_DEFINE([HAVE_ALIGNAS], 1, [The alignas C11 feature is supported.]) | ||
AC_MSG_RESULT(yes), | ||
AC_MSG_RESULT(no)) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cf. Macros.h
for a way on how to do this without C11 support. If we throw around GCC/Clang compiler extensions, we also could just use packed
, which at least is even kinda portable to other compilers too …
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\"}]") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any objections to have this literal span multiple lines for better maintainability?
Please add proper meta-commands for astyle
to leave this block alone afterwards.
Also, this note probably should only contain the optional dependencies we actually have enabled; i.e. if configured without delay accounting, there's no need to declare this as an optional runtime dependency if we would never try to load that library anyway.
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\"}]") | |
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\""\ | |
"}"\ | |
"]" ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a fan of having a full JSON syntax in a macro caller. Can we rework the macros so that only important fields will be used as parameters?
I expect the usage would ideally work like this:
#define ELF_NOTE_DLOPEN_DEP(sonames, feature_tag, priority) ...
// Example
ELF_NOTE_DLOPEN_DEP(
"[\"libnl-3.so\",\"libnl-3.so.200\"]", "delay-accounting", "recommended")
ELF_NOTE_DLOPEN_DEP(
"[\"libnl-genl-3.so\",\"libnl-genl-3.so.200\"]", "delay-accounting", "recommended")
How do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While I also thought about this, including making generating the JSON be split into different macro calls (definitively possible AFAICS), there's one minor issue with the pre-processor IMHO, that prevents this from being really nice syntax. The issue is, that you can't properly auto-terminate lists of arguments to insert the semicolon in list contexts, thus you'd most likely have to resort to something like "[" ELF_NOTE_DEP(foo…) "," ELF_NOTE_DEP(bar…) "]"
; which doesn't look too terrible, but in a really great world could work without the explicit "," token in between.
Also from a practcal PoV, I'd prefer such macros to go ELF_NOTE_DLOPEN_DEP(freature, level, description, solist)`, but comparibly that's a minor change to implement.
} nhdr; \ | ||
char name[sizeof(ELF_NOTE_DLOPEN_OWNER)]; \ | ||
alignas(sizeof(uint32_t)) char dlopen_content[sizeof(content)]; \ | ||
} variable_name = { \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't be variable_name
be dynamic?
DECLARE_ELF_NOTE_DLOPEN("[{\"soname\":[\"libsensors.so\",\"libsensors.so.5\",\"libsensors.so.4\"],\"feature\":"\ | ||
"\"sensors\",\"description:\":\"Enables hardware sensor support\",\"priority\":\"recommended\"}]") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Multiple lines, example above …
DECLARE_ELF_NOTE_DLOPEN("[{\"soname\":[\"libsystemd.so.0\"],\"feature\":\"systemd\",\"description:\":"\ | ||
"\"Enables systemd support\",\"priority\":\"suggested\"}]") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Multiple lines, example above …
Any objections to having the code for generating these annotations be its own source code file? NB: There's also |
Just my general comments: Besides, this information is ELF-specific, which could potentially discriminate other OSes such as BSDs. |
Embed metadata about runtime dependencies of dynamic libraries used via dlopen(3) in the binary so that distributions can automatically generate package dependencies.
Specification: https://systemd.io/ELF_DLOPEN_METADATA/ (TODO: link not yet available)
Alternative link: https://github.com/systemd/systemd/blob/main/docs/ELF_DLOPEN_METADATA.md
Inspired-by: systemd/systemd#32234