diff options
| -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 | ||
