diff options
Diffstat (limited to 'meta')
-rw-r--r-- | meta/recipes-core/systemd/dlopen-deps.inc | 73 | ||||
-rw-r--r-- | meta/recipes-core/systemd/systemd_256.7.bb | 4 |
2 files changed, 75 insertions, 2 deletions
diff --git a/meta/recipes-core/systemd/dlopen-deps.inc b/meta/recipes-core/systemd/dlopen-deps.inc new file mode 100644 index 0000000000..eaf6ca1f79 --- /dev/null +++ b/meta/recipes-core/systemd/dlopen-deps.inc | |||
@@ -0,0 +1,73 @@ | |||
1 | PACKAGEFUNCS =+ "package_generate_dlopen_deps" | ||
2 | |||
3 | python package_generate_dlopen_deps() { | ||
4 | # https://systemd.io/ELF_DLOPEN_METADATA/ | ||
5 | |||
6 | import struct, json | ||
7 | |||
8 | def extract_segment(filename, segment): | ||
9 | """ | ||
10 | Return the named segment from the ELF. | ||
11 | """ | ||
12 | import tempfile, subprocess | ||
13 | |||
14 | with tempfile.NamedTemporaryFile() as f: | ||
15 | cmd = [d.getVar("OBJCOPY"), "--dump-section", f"{segment}={f.name}", filename] | ||
16 | subprocess.run(cmd, check=True) | ||
17 | return f.read() | ||
18 | |||
19 | def parse(buffer, is_little): | ||
20 | deps = [] | ||
21 | offset = 0 | ||
22 | while offset < len(buffer): | ||
23 | format = f"{'<' if is_little else '>'}iii" | ||
24 | name_size, desc_size, note_type = struct.unpack_from(format, buffer, offset) | ||
25 | offset += struct.calcsize(format) | ||
26 | |||
27 | format = f"{name_size}s0i{desc_size}s0i" | ||
28 | if note_type == 0x407c0c0a: | ||
29 | name_b, desc_b = struct.unpack_from(format, buffer, offset) | ||
30 | name = name_b.strip(b"\x00").decode("ascii") | ||
31 | if name == "FDO": | ||
32 | desc = desc_b.strip(b"\x00").decode("utf-8") | ||
33 | deps.append(*json.loads(desc)) | ||
34 | offset += struct.calcsize(format) | ||
35 | return deps | ||
36 | |||
37 | dep_map = { | ||
38 | "required": "RDEPENDS", | ||
39 | "recommended": "RRECOMMENDS", | ||
40 | "suggested": "RSUGGESTS" | ||
41 | } | ||
42 | |||
43 | shlibs = oe.package.read_shlib_providers(d) | ||
44 | |||
45 | for pkg, files in pkgfiles.items(): | ||
46 | # Skip -dbg packages as we won't need to generate dependencies for those | ||
47 | # but scanning can take time | ||
48 | if pkg.endswith("-dbg"): | ||
49 | continue | ||
50 | |||
51 | for f in files: | ||
52 | # Skip symlinks, just look for real libraries | ||
53 | if cpath.islink(f): | ||
54 | continue | ||
55 | |||
56 | if ".so." in f or f.endswith(".so"): | ||
57 | try: | ||
58 | elf = oe.qa.ELFFile(f) | ||
59 | elf.open() | ||
60 | for dep in parse(extract_segment(f, ".note.dlopen"), elf.isLittleEndian()): | ||
61 | for soname in dep["soname"]: | ||
62 | if soname in shlibs: | ||
63 | # TODO assumes the first match is good | ||
64 | package, version = list(shlibs[soname].values())[0] | ||
65 | dependency = dep_map[dep["priority"]] | ||
66 | bb.note(f"{pkg}: adding {dependency} on {package} via .note.dlopen") | ||
67 | d.appendVar(f"{dependency}:{pkg}", f" {package} (>= {version})") | ||
68 | else: | ||
69 | bb.warn(f"cannot find {soname}") | ||
70 | except oe.qa.NotELFFileError as e: | ||
71 | bb.note(f"Cannot extract ELF notes: {e}") | ||
72 | pass | ||
73 | } | ||
diff --git a/meta/recipes-core/systemd/systemd_256.7.bb b/meta/recipes-core/systemd/systemd_256.7.bb index 8b7ed2efe2..97537d09ba 100644 --- a/meta/recipes-core/systemd/systemd_256.7.bb +++ b/meta/recipes-core/systemd/systemd_256.7.bb | |||
@@ -742,8 +742,6 @@ INSANE_SKIP:libsystemd-shared += "libdir" | |||
742 | FILES:libsystemd-shared = "${rootlibdir}/systemd/libsystemd-shared*.so" | 742 | FILES:libsystemd-shared = "${rootlibdir}/systemd/libsystemd-shared*.so" |
743 | 743 | ||
744 | RPROVIDES:udev = "hotplug" | 744 | RPROVIDES:udev = "hotplug" |
745 | # This can be removed when we parse .note.dlopen in the ELF | ||
746 | RDEPENDS:udev += "libkmod" | ||
747 | 745 | ||
748 | RDEPENDS:udev-bash-completion += "bash-completion" | 746 | RDEPENDS:udev-bash-completion += "bash-completion" |
749 | RDEPENDS:udev-hwdb += "udev" | 747 | RDEPENDS:udev-hwdb += "udev" |
@@ -915,3 +913,5 @@ pkg_postinst:udev-hwdb () { | |||
915 | pkg_prerm:udev-hwdb () { | 913 | pkg_prerm:udev-hwdb () { |
916 | rm -f $D${sysconfdir}/udev/hwdb.bin | 914 | rm -f $D${sysconfdir}/udev/hwdb.bin |
917 | } | 915 | } |
916 | |||
917 | require dlopen-deps.inc | ||