diff options
author | Luca Boccassi <bluca@debian.org> | 2022-12-22 22:19:05 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-12-22 22:19:05 +0100 |
commit | 21c8d750cd72dd847e2b5051395560629fbdecbb (patch) | |
tree | 1986dde70661868227d4be8ff69ec596fcdb6059 | |
parent | 27ce258c54a6ea1b999375e5c7e09b5970607dac (diff) | |
parent | 3fc1ae89e756d1624f5135aec5510a939ed01317 (diff) | |
download | systemd-21c8d750cd72dd847e2b5051395560629fbdecbb.tar.gz |
Merge pull request #25814 from DaanDeMeyer/ukify
ukify: Prefer using llvm-objcopy instead of objcopy
-rw-r--r-- | man/ukify.xml | 8 | ||||
-rwxr-xr-x | src/ukify/ukify.py | 45 |
2 files changed, 35 insertions, 18 deletions
diff --git a/man/ukify.xml b/man/ukify.xml index 17546d543d..c5bf91de02 100644 --- a/man/ukify.xml +++ b/man/ukify.xml @@ -221,11 +221,11 @@ </varlistentry> <varlistentry> - <term><option>--tools=<replaceable>DIR</replaceable></option></term> + <term><option>--tools=<replaceable>DIRS</replaceable></option></term> - <listitem><para>Specify a directory with helper tools. <command>ukify</command> will look for helper - tools in that directory first, and if not found, try to load them from <varname>$PATH</varname> in - the usual fashion.</para></listitem> + <listitem><para>Specify one or more directories with helper tools. <command>ukify</command> will look + for helper tools in those directories first, and if not found, try to load them from + <varname>$PATH</varname> in the usual fashion.</para></listitem> </varlistentry> <varlistentry> diff --git a/src/ukify/ukify.py b/src/ukify/ukify.py index 0c4461c9a9..ad2f8a2c71 100755 --- a/src/ukify/ukify.py +++ b/src/ukify/ukify.py @@ -212,12 +212,12 @@ class Section: name: str content: pathlib.Path tmpfile: typing.IO | None = None - flags: list[str] | None = dataclasses.field(default=None) + flags: list[str] = dataclasses.field(default_factory=lambda: ['data', 'readonly']) offset: int | None = None measure: bool = False @classmethod - def create(cls, name, contents, flags=None, measure=False): + def create(cls, name, contents, **kwargs): if isinstance(contents, str | bytes): mode = 'wt' if isinstance(contents, str) else 'wb' tmp = tempfile.NamedTemporaryFile(mode=mode, prefix=f'tmp{name}') @@ -227,7 +227,7 @@ class Section: else: tmp = None - return cls(name, contents, tmpfile=tmp, flags=flags, measure=measure) + return cls(name, contents, tmpfile=tmp, **kwargs) @classmethod def parse_arg(cls, s): @@ -333,9 +333,10 @@ def check_inputs(opts): def find_tool(name, fallback=None, opts=None): if opts and opts.tools: - tool = opts.tools / name - if tool.exists(): - return tool + for d in opts.tools: + tool = d / name + if tool.exists(): + return tool return fallback or name @@ -435,6 +436,18 @@ def join_initrds(initrds): assert False +def pe_validate(filename): + import pefile + + pe = pefile.PE(filename) + + sections = sorted(pe.sections, key=lambda s: (s.VirtualAddress, s.Misc_VirtualSize)) + + for l, r in itertools.pairwise(sections): + if l.VirtualAddress + l.Misc_VirtualSize > r.VirtualAddress + r.Misc_VirtualSize: + raise ValueError(f'Section "{l.Name.decode()}" ({l.VirtualAddress}, {l.Misc_VirtualSize}) overlaps with section "{r.Name.decode()}" ({r.VirtualAddress}, {r.Misc_VirtualSize})') + + def make_uki(opts): # kernel payload signing @@ -532,24 +545,27 @@ def make_uki(opts): else: output = opts.output - objcopy_tool = find_tool('objcopy', opts=opts) + objcopy_tool = find_tool('llvm-objcopy', 'objcopy', opts=opts) cmd = [ objcopy_tool, opts.stub, *itertools.chain.from_iterable( - ('--add-section', f'{s.name}={s.content}', - '--change-section-vma', f'{s.name}=0x{s.offset:x}') + ('--add-section', f'{s.name}={s.content}', + '--set-section-flags', f"{s.name}={','.join(s.flags)}") for s in uki.sections), - *itertools.chain.from_iterable( - ('--set-section-flags', f"{s.name}={','.join(s.flags)}") - for s in uki.sections - if s.flags is not None), output, ] + + if pathlib.Path(objcopy_tool).name != 'llvm-objcopy': + cmd += itertools.chain.from_iterable( + ('--change-section-vma', f'{s.name}=0x{s.offset:x}') for s in uki.sections) + print('+', shell_join(cmd)) subprocess.check_call(cmd) + pe_validate(output) + # UKI signing if opts.sb_key: @@ -668,7 +684,8 @@ usage: ukify [options…] linux initrd… p.add_argument('--tools', type=pathlib.Path, - help='a directory with systemd-measure and other tools') + nargs='+', + help='Directories to search for tools (systemd-measure, llvm-objcopy, ...)') p.add_argument('--output', '-o', type=pathlib.Path, |