From a0797b4ad79ec6f11700882eeea79e4366718dfe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 13 Mar 2024 13:16:17 +0100 Subject: [PATCH 1/5] tools/elf2efi: align columns in tables, unify formatting For tables which represent binary data structures, readability is greatly enhanced if the part which shows field size and type is aligned. This follows the usual style for tables in the rest of the systemd codebase. Also, use the same style for functions: if the function signature is too long to fit in one line, put each parameter on a separate line. Also, for comprehension expressions, if they are split, use the usual Python style. Also, drop format annotations, since the code isn't automatically formatted anymore, and automatic formatting is neither feasible nor a goal for the systemd codebase. --- tools/elf2efi.py | 192 +++++++++++++++++++++++------------------------ 1 file changed, 94 insertions(+), 98 deletions(-) diff --git a/tools/elf2efi.py b/tools/elf2efi.py index 5411a023411..a515d1de4fd 100755 --- a/tools/elf2efi.py +++ b/tools/elf2efi.py @@ -55,26 +55,26 @@ from elftools.elf.relocation import ( class PeCoffHeader(LittleEndianStructure): _fields_ = ( - ("Machine", c_uint16), - ("NumberOfSections", c_uint16), - ("TimeDateStamp", c_uint32), + ("Machine", c_uint16), + ("NumberOfSections", c_uint16), + ("TimeDateStamp", c_uint32), ("PointerToSymbolTable", c_uint32), - ("NumberOfSymbols", c_uint32), + ("NumberOfSymbols", c_uint32), ("SizeOfOptionalHeader", c_uint16), - ("Characteristics", c_uint16), + ("Characteristics", c_uint16), ) class PeDataDirectory(LittleEndianStructure): _fields_ = ( ("VirtualAddress", c_uint32), - ("Size", c_uint32), + ("Size", c_uint32), ) class PeRelocationBlock(LittleEndianStructure): _fields_ = ( - ("PageRVA", c_uint32), + ("PageRVA", c_uint32), ("BlockSize", c_uint32), ) @@ -86,62 +86,62 @@ class PeRelocationBlock(LittleEndianStructure): class PeRelocationEntry(LittleEndianStructure): _fields_ = ( ("Offset", c_uint16, 12), - ("Type", c_uint16, 4), + ("Type", c_uint16, 4), ) class PeOptionalHeaderStart(LittleEndianStructure): _fields_ = ( - ("Magic", c_uint16), - ("MajorLinkerVersion", c_uint8), - ("MinorLinkerVersion", c_uint8), - ("SizeOfCode", c_uint32), - ("SizeOfInitializedData", c_uint32), + ("Magic", c_uint16), + ("MajorLinkerVersion", c_uint8), + ("MinorLinkerVersion", c_uint8), + ("SizeOfCode", c_uint32), + ("SizeOfInitializedData", c_uint32), ("SizeOfUninitializedData", c_uint32), - ("AddressOfEntryPoint", c_uint32), - ("BaseOfCode", c_uint32), + ("AddressOfEntryPoint", c_uint32), + ("BaseOfCode", c_uint32), ) class PeOptionalHeaderMiddle(LittleEndianStructure): _fields_ = ( - ("SectionAlignment", c_uint32), - ("FileAlignment", c_uint32), + ("SectionAlignment", c_uint32), + ("FileAlignment", c_uint32), ("MajorOperatingSystemVersion", c_uint16), ("MinorOperatingSystemVersion", c_uint16), - ("MajorImageVersion", c_uint16), - ("MinorImageVersion", c_uint16), - ("MajorSubsystemVersion", c_uint16), - ("MinorSubsystemVersion", c_uint16), - ("Win32VersionValue", c_uint32), - ("SizeOfImage", c_uint32), - ("SizeOfHeaders", c_uint32), - ("CheckSum", c_uint32), - ("Subsystem", c_uint16), - ("DllCharacteristics", c_uint16), + ("MajorImageVersion", c_uint16), + ("MinorImageVersion", c_uint16), + ("MajorSubsystemVersion", c_uint16), + ("MinorSubsystemVersion", c_uint16), + ("Win32VersionValue", c_uint32), + ("SizeOfImage", c_uint32), + ("SizeOfHeaders", c_uint32), + ("CheckSum", c_uint32), + ("Subsystem", c_uint16), + ("DllCharacteristics", c_uint16), ) class PeOptionalHeaderEnd(LittleEndianStructure): _fields_ = ( - ("LoaderFlags", c_uint32), - ("NumberOfRvaAndSizes", c_uint32), - ("ExportTable", PeDataDirectory), - ("ImportTable", PeDataDirectory), - ("ResourceTable", PeDataDirectory), - ("ExceptionTable", PeDataDirectory), - ("CertificateTable", PeDataDirectory), - ("BaseRelocationTable", PeDataDirectory), - ("Debug", PeDataDirectory), - ("Architecture", PeDataDirectory), - ("GlobalPtr", PeDataDirectory), - ("TLSTable", PeDataDirectory), - ("LoadConfigTable", PeDataDirectory), - ("BoundImport", PeDataDirectory), - ("IAT", PeDataDirectory), + ("LoaderFlags", c_uint32), + ("NumberOfRvaAndSizes", c_uint32), + ("ExportTable", PeDataDirectory), + ("ImportTable", PeDataDirectory), + ("ResourceTable", PeDataDirectory), + ("ExceptionTable", PeDataDirectory), + ("CertificateTable", PeDataDirectory), + ("BaseRelocationTable", PeDataDirectory), + ("Debug", PeDataDirectory), + ("Architecture", PeDataDirectory), + ("GlobalPtr", PeDataDirectory), + ("TLSTable", PeDataDirectory), + ("LoadConfigTable", PeDataDirectory), + ("BoundImport", PeDataDirectory), + ("IAT", PeDataDirectory), ("DelayImportDescriptor", PeDataDirectory), - ("CLRRuntimeHeader", PeDataDirectory), - ("Reserved", PeDataDirectory), + ("CLRRuntimeHeader", PeDataDirectory), + ("Reserved", PeDataDirectory), ) @@ -152,44 +152,44 @@ class PeOptionalHeader(LittleEndianStructure): class PeOptionalHeader32(PeOptionalHeader): _anonymous_ = ("Start", "Middle", "End") _fields_ = ( - ("Start", PeOptionalHeaderStart), - ("BaseOfData", c_uint32), - ("ImageBase", c_uint32), - ("Middle", PeOptionalHeaderMiddle), + ("Start", PeOptionalHeaderStart), + ("BaseOfData", c_uint32), + ("ImageBase", c_uint32), + ("Middle", PeOptionalHeaderMiddle), ("SizeOfStackReserve", c_uint32), - ("SizeOfStackCommit", c_uint32), - ("SizeOfHeapReserve", c_uint32), - ("SizeOfHeapCommit", c_uint32), - ("End", PeOptionalHeaderEnd), + ("SizeOfStackCommit", c_uint32), + ("SizeOfHeapReserve", c_uint32), + ("SizeOfHeapCommit", c_uint32), + ("End", PeOptionalHeaderEnd), ) class PeOptionalHeader32Plus(PeOptionalHeader): _anonymous_ = ("Start", "Middle", "End") _fields_ = ( - ("Start", PeOptionalHeaderStart), - ("ImageBase", c_uint64), - ("Middle", PeOptionalHeaderMiddle), + ("Start", PeOptionalHeaderStart), + ("ImageBase", c_uint64), + ("Middle", PeOptionalHeaderMiddle), ("SizeOfStackReserve", c_uint64), - ("SizeOfStackCommit", c_uint64), - ("SizeOfHeapReserve", c_uint64), - ("SizeOfHeapCommit", c_uint64), - ("End", PeOptionalHeaderEnd), + ("SizeOfStackCommit", c_uint64), + ("SizeOfHeapReserve", c_uint64), + ("SizeOfHeapCommit", c_uint64), + ("End", PeOptionalHeaderEnd), ) class PeSection(LittleEndianStructure): _fields_ = ( - ("Name", c_char * 8), - ("VirtualSize", c_uint32), - ("VirtualAddress", c_uint32), - ("SizeOfRawData", c_uint32), - ("PointerToRawData", c_uint32), + ("Name", c_char * 8), + ("VirtualSize", c_uint32), + ("VirtualAddress", c_uint32), + ("SizeOfRawData", c_uint32), + ("PointerToRawData", c_uint32), ("PointerToRelocations", c_uint32), ("PointerToLinenumbers", c_uint32), - ("NumberOfRelocations", c_uint16), - ("NumberOfLinenumbers", c_uint16), - ("Characteristics", c_uint32), + ("NumberOfRelocations", c_uint16), + ("NumberOfLinenumbers", c_uint16), + ("Characteristics", c_uint32), ) def __init__(self): @@ -206,7 +206,7 @@ assert sizeof(PeOptionalHeader32Plus) == 240 PE_CHARACTERISTICS_RX = 0x60000020 # CNT_CODE|MEM_READ|MEM_EXECUTE PE_CHARACTERISTICS_RW = 0xC0000040 # CNT_INITIALIZED_DATA|MEM_READ|MEM_WRITE -PE_CHARACTERISTICS_R = 0x40000040 # CNT_INITIALIZED_DATA|MEM_READ +PE_CHARACTERISTICS_R = 0x40000040 # CNT_INITIALIZED_DATA|MEM_READ IGNORE_SECTIONS = [ ".eh_frame", @@ -246,9 +246,8 @@ def align_down(x: int, align: int) -> int: def next_section_address(sections: typing.List[PeSection]) -> int: - return align_to( - sections[-1].VirtualAddress + sections[-1].VirtualSize, SECTION_ALIGNMENT - ) + return align_to(sections[-1].VirtualAddress + sections[-1].VirtualSize, + SECTION_ALIGNMENT) def iter_copy_sections(elf: ELFFile) -> typing.Iterator[PeSection]: @@ -376,12 +375,8 @@ def apply_elf_relative_relocation( sections: typing.List[PeSection], addend_size: int, ): - # fmt: off - [target] = [ - pe_s for pe_s in sections - if pe_s.VirtualAddress <= reloc["r_offset"] < pe_s.VirtualAddress + len(pe_s.data) - ] - # fmt: on + [target] = [pe_s for pe_s in sections + if pe_s.VirtualAddress <= reloc["r_offset"] < pe_s.VirtualAddress + len(pe_s.data)] addend_offset = reloc["r_offset"] - target.VirtualAddress @@ -425,9 +420,10 @@ def convert_elf_reloc_table( continue if reloc["r_info_type"] == RELATIVE_RELOC: - apply_elf_relative_relocation( - reloc, elf_image_base, sections, elf.elfclass // 8 - ) + apply_elf_relative_relocation(reloc, + elf_image_base, + sections, + elf.elfclass // 8) # Now that the ELF relocation has been applied, we can create a PE relocation. block_rva = reloc["r_offset"] & ~0xFFF @@ -466,14 +462,12 @@ def convert_elf_relocations( if exe_start and exe_start[0]["st_value"] != 0: raise RuntimeError("Unexpected ELF image base.") - opt.SizeOfHeaders = align_to( - PE_OFFSET - + len(PE_MAGIC) - + sizeof(PeCoffHeader) - + sizeof(opt) - + sizeof(PeSection) * max(len(sections) + 1, minimum_sections), - FILE_ALIGNMENT, - ) + opt.SizeOfHeaders = align_to(PE_OFFSET + + len(PE_MAGIC) + + sizeof(PeCoffHeader) + + sizeof(opt) + + sizeof(PeSection) * max(len(sections) + 1, minimum_sections), + FILE_ALIGNMENT) # We use the basic VMA layout from the ELF image in the PE image. This could cause the first # section to overlap the PE image headers during runtime at VMA 0. We can simply apply a fixed @@ -482,9 +476,8 @@ def convert_elf_relocations( # the ELF portions of the image. segment_offset = 0 if sections[0].VirtualAddress < opt.SizeOfHeaders: - segment_offset = align_to( - opt.SizeOfHeaders - sections[0].VirtualAddress, SECTION_ALIGNMENT - ) + segment_offset = align_to(opt.SizeOfHeaders - sections[0].VirtualAddress, + SECTION_ALIGNMENT) opt.AddressOfEntryPoint = elf["e_entry"] + segment_offset opt.BaseOfCode += segment_offset @@ -495,9 +488,11 @@ def convert_elf_relocations( for reloc_type, reloc_table in dynamic.get_relocation_tables().items(): if reloc_type not in ["REL", "RELA"]: raise RuntimeError("Unsupported relocation type {elf_reloc_type}.") - convert_elf_reloc_table( - elf, reloc_table, opt.ImageBase + segment_offset, sections, pe_reloc_blocks - ) + convert_elf_reloc_table(elf, + reloc_table, + opt.ImageBase + segment_offset, + sections, + pe_reloc_blocks) for pe_s in sections: pe_s.VirtualAddress += segment_offset @@ -517,9 +512,7 @@ def convert_elf_relocations( block.entries.append(PeRelocationEntry()) block.PageRVA += segment_offset - block.BlockSize = ( - sizeof(PeRelocationBlock) + sizeof(PeRelocationEntry) * n_relocs - ) + block.BlockSize = sizeof(PeRelocationBlock) + sizeof(PeRelocationEntry) * n_relocs data += block for entry in sorted(block.entries, key=lambda e: e.Offset): data += entry @@ -539,7 +532,10 @@ def convert_elf_relocations( def write_pe( - file, coff: PeCoffHeader, opt: PeOptionalHeader, sections: typing.List[PeSection] + file, + coff: PeCoffHeader, + opt: PeOptionalHeader, + sections: typing.List[PeSection], ): file.write(b"MZ") file.seek(0x3C, io.SEEK_SET) From 642f991b707672af4530ac802e0be67022cd004d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 13 Mar 2024 13:21:51 +0100 Subject: [PATCH 2/5] tools/elf2efi: split out function to create parser main() is supposed to be lean and mean. --- tools/elf2efi.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/elf2efi.py b/tools/elf2efi.py index a515d1de4fd..759c7ab37ff 100755 --- a/tools/elf2efi.py +++ b/tools/elf2efi.py @@ -632,7 +632,7 @@ def elf2efi(args: argparse.Namespace): write_pe(args.PE, coff, opt, sections) -def main(): +def create_parser() -> argparse.ArgumentParser: parser = argparse.ArgumentParser(description="Convert ELF binaries to PE/EFI") parser.add_argument( "--version-major", @@ -686,7 +686,11 @@ def main(): default="", help="Copy these sections if found", ) + return parser + +def main(): + parser = create_parser() elf2efi(parser.parse_args()) From 8a753717f8734baec3abaf9b6fb4749e61fb9ac9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 13 Mar 2024 14:02:46 +0100 Subject: [PATCH 3/5] tools/elf2efi: rework exception messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RuntimeError is documented as "Unspecified run-time error". It doesn't make much sense for Python. (It originated in Java, where exceptions that can be thrown by a function are declared in the function signature. All code calling such a function must either explicitly catch all possible exception types, or allow them to propagate by listing them in its own exception type list. This is nice in theory, but in practice very annoying. Especially during development, when the list of possible exception types is not finalized, we would end up adding and removing exceptions to functions signatures all the time. Also for code which is designed to call functions recursively, we would soon end up with all functions declaring all possible exception types… To avoid this, people would quite often do fake handling with a block that either prints and ignores an exception, or has just a comment like "fix me later", or even nothing. This often lead to people forgetting to adjust this later on and production code containing such constructs. An escape hatch was opened with RuntimeException and its subclasses, which do not need to be pre-declared. Various memory-related exceptions were added as subclasses of RuntimeException. But later on, people starting using this to not to have to declare all exception types everywhere.) In Python, exceptions do no have to be pre-declared, and for code which just encounters a failure, we should raise a specific exception type. The catch-all class for unexpected input is ValueError. For https://github.com/systemd/systemd/issues/31637: BadSectionError: Section '.data' @0x28000 overlaps previous section @0x28000+0x300=@0x28300 Also, exception strings should not contain trailing periods, because they are often embedded in sentences. --- tools/elf2efi.py | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/tools/elf2efi.py b/tools/elf2efi.py index 759c7ab37ff..a37c5246bdf 100755 --- a/tools/elf2efi.py +++ b/tools/elf2efi.py @@ -250,6 +250,10 @@ def next_section_address(sections: typing.List[PeSection]) -> int: SECTION_ALIGNMENT) +class BadSectionError(ValueError): + "One of the sections is in a bad state" + + def iter_copy_sections(elf: ELFFile) -> typing.Iterator[PeSection]: pe_s = None @@ -260,7 +264,8 @@ def iter_copy_sections(elf: ELFFile) -> typing.Iterator[PeSection]: relro = None for elf_seg in elf.iter_segments(): if elf_seg["p_type"] == "PT_LOAD" and elf_seg["p_align"] != SECTION_ALIGNMENT: - raise RuntimeError("ELF segments are not properly aligned.") + raise BadSectionError(f"ELF segment {elf_seg['p_type']} is not properly aligned" + f" ({elf_seg['p_align']} != {SECTION_ALIGNMENT})") elif elf_seg["p_type"] == "PT_GNU_RELRO": relro = elf_seg @@ -272,7 +277,7 @@ def iter_copy_sections(elf: ELFFile) -> typing.Iterator[PeSection]: ): continue if elf_s["sh_type"] not in ["SHT_PROGBITS", "SHT_NOBITS"]: - raise RuntimeError(f"Unknown section {elf_s.name}.") + raise BadSectionError(f"Unknown section {elf_s.name} with type {elf_s['sh_type']}") if elf_s["sh_flags"] & SH_FLAGS.SHF_EXECINSTR: rwx = PE_CHARACTERISTICS_RX @@ -304,7 +309,7 @@ def iter_copy_sections(elf: ELFFile) -> typing.Iterator[PeSection]: def convert_sections(elf: ELFFile, opt: PeOptionalHeader) -> typing.List[PeSection]: - last_vma = 0 + last_vma = (0, 0) sections = [] for pe_s in iter_copy_sections(elf): @@ -324,10 +329,11 @@ def convert_sections(elf: ELFFile, opt: PeOptionalHeader) -> typing.List[PeSecti PE_CHARACTERISTICS_R: b".rodata", }[pe_s.Characteristics] - # This can happen if not building with `-z separate-code`. - if pe_s.VirtualAddress < last_vma: - raise RuntimeError("Overlapping PE sections.") - last_vma = pe_s.VirtualAddress + pe_s.VirtualSize + # This can happen if not building with '-z separate-code'. + if pe_s.VirtualAddress < sum(last_vma): + raise BadSectionError(f"Section {pe_s.Name.decode()!r} @0x{pe_s.VirtualAddress:x} overlaps" + f" previous section @0x{last_vma[0]:x}+0x{last_vma[1]:x}=@0x{sum(last_vma):x}") + last_vma = (pe_s.VirtualAddress, pe_s.VirtualSize) if pe_s.Name == b".text": opt.BaseOfCode = pe_s.VirtualAddress @@ -354,9 +360,9 @@ def copy_sections( if not elf_s: continue if elf_s.data_alignment > 1 and SECTION_ALIGNMENT % elf_s.data_alignment != 0: - raise RuntimeError(f"ELF section {name} is not aligned.") + raise BadSectionError(f"ELF section {name} is not aligned") if elf_s["sh_flags"] & (SH_FLAGS.SHF_EXECINSTR | SH_FLAGS.SHF_WRITE) != 0: - raise RuntimeError(f"ELF section {name} is not read-only data.") + raise BadSectionError(f"ELF section {name} is not read-only data") pe_s = PeSection() pe_s.Name = name.encode() @@ -438,7 +444,7 @@ def convert_elf_reloc_table( continue - raise RuntimeError(f"Unsupported relocation {reloc}") + raise BadSectionError(f"Unsupported relocation {reloc}") def convert_elf_relocations( @@ -449,18 +455,18 @@ def convert_elf_relocations( ) -> typing.Optional[PeSection]: dynamic = elf.get_section_by_name(".dynamic") if dynamic is None: - raise RuntimeError("ELF .dynamic section is missing.") + raise BadSectionError("ELF .dynamic section is missing") [flags_tag] = dynamic.iter_tags("DT_FLAGS_1") if not flags_tag["d_val"] & ENUM_DT_FLAGS_1["DF_1_PIE"]: - raise RuntimeError("ELF file is not a PIE.") + raise ValueError("ELF file is not a PIE") # This checks that the ELF image base is 0. symtab = elf.get_section_by_name(".symtab") if symtab: exe_start = symtab.get_symbol_by_name("__executable_start") if exe_start and exe_start[0]["st_value"] != 0: - raise RuntimeError("Unexpected ELF image base.") + raise ValueError("Unexpected ELF image base") opt.SizeOfHeaders = align_to(PE_OFFSET + len(PE_MAGIC) @@ -487,7 +493,7 @@ def convert_elf_relocations( pe_reloc_blocks: typing.Dict[int, PeRelocationBlock] = {} for reloc_type, reloc_table in dynamic.get_relocation_tables().items(): if reloc_type not in ["REL", "RELA"]: - raise RuntimeError("Unsupported relocation type {elf_reloc_type}.") + raise BadSectionError(f"Unsupported relocation type {reloc_type}") convert_elf_reloc_table(elf, reloc_table, opt.ImageBase + segment_offset, @@ -548,7 +554,8 @@ def write_pe( offset = opt.SizeOfHeaders for pe_s in sorted(sections, key=lambda s: s.VirtualAddress): if pe_s.VirtualAddress < opt.SizeOfHeaders: - raise RuntimeError(f"Section {pe_s.Name} overlapping PE headers.") + raise BadSectionError(f"Section {pe_s.Name} @0x{pe_s.VirtualAddress:x} overlaps" + " PE headers ending at 0x{opt.SizeOfHeaders:x}") pe_s.PointerToRawData = offset file.write(pe_s) @@ -566,9 +573,9 @@ def write_pe( def elf2efi(args: argparse.Namespace): elf = ELFFile(args.ELF) if not elf.little_endian: - raise RuntimeError("ELF file is not little-endian.") + raise ValueError("ELF file is not little-endian") if elf["e_type"] not in ["ET_DYN", "ET_EXEC"]: - raise RuntimeError("Unsupported ELF type.") + raise ValueError(f"Unsupported ELF type {elf['e_type']}") pe_arch = { "EM_386": 0x014C, @@ -579,7 +586,7 @@ def elf2efi(args: argparse.Namespace): "EM_X86_64": 0x8664, }.get(elf["e_machine"]) if pe_arch is None: - raise RuntimeError(f"Unsupported ELF arch {elf['e_machine']}") + raise ValueError(f"Unsupported ELF architecture {elf['e_machine']}") coff = PeCoffHeader() opt = PeOptionalHeader32() if elf.elfclass == 32 else PeOptionalHeader32Plus() From 6d03e5523cc26a4f4cecf277788ae62bba44f88e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 14 Mar 2024 10:33:11 +0100 Subject: [PATCH 4/5] tools/elf2efi: skip empty .got section and its .relro_padding Resolves https://github.com/systemd/systemd/issues/31637. lld-18 does the section setup differently than older versions. There is a bunch of ordering chagnes, but it also inserts the following: Sections: Idx Name Size VMA LMA File off Algn ... 9 .got 00000000 00000000000283c0 00000000000283c0 000283c0 2**3 CONTENTS, ALLOC, LOAD, DATA 10 .relro_padding 00000c40 00000000000283c0 00000000000283c0 000283c0 2**0 ALLOC 11 .data 00000024 00000000000293c0 00000000000293c0 000283c0 2**4 CONTENTS, ALLOC, LOAD, DATA ... This causes a problem for us, because we try to map the .got to .rodata, and the subsequent .data to .data, and round down the VMA to the nearest page, which causes the PE sections to overlap. https://github.com/llvm/llvm-project/pull/66042 adds .relro_padding to make sure that the RELRO segment is properly write protected and allocated. For our binaries, the .got section is empty, so we can skip it safely, and the .relro_padding section is not useful once .got has been dropped. We don't expect .got sections, but they are apparently inserted on i386 and aarch64 builds. Emit a warning until we figure out why they are there. --- tools/elf2efi.py | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/tools/elf2efi.py b/tools/elf2efi.py index a37c5246bdf..2e7ca9f6c4e 100755 --- a/tools/elf2efi.py +++ b/tools/elf2efi.py @@ -26,6 +26,7 @@ import hashlib import io import os import pathlib +import sys import time import typing from ctypes import ( @@ -212,6 +213,7 @@ IGNORE_SECTIONS = [ ".eh_frame", ".eh_frame_hdr", ".ARM.exidx", + ".relro_padding", ] IGNORE_SECTION_TYPES = [ @@ -274,10 +276,14 @@ def iter_copy_sections(elf: ELFFile) -> typing.Iterator[PeSection]: elf_s["sh_flags"] & SH_FLAGS.SHF_ALLOC == 0 or elf_s["sh_type"] in IGNORE_SECTION_TYPES or elf_s.name in IGNORE_SECTIONS + or elf_s["sh_size"] == 0 ): continue if elf_s["sh_type"] not in ["SHT_PROGBITS", "SHT_NOBITS"]: raise BadSectionError(f"Unknown section {elf_s.name} with type {elf_s['sh_type']}") + if elf_s.name == '.got': + # FIXME: figure out why those sections are inserted + print("WARNING: Non-empty .got section", file=sys.stderr) if elf_s["sh_flags"] & SH_FLAGS.SHF_EXECINSTR: rwx = PE_CHARACTERISTICS_RX From 125f06dd1cc2b658e77adf2f31b349052ff12b1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 22 Mar 2024 15:44:17 +0100 Subject: [PATCH 5/5] =?UTF-8?q?tools/elf2efi:=20elif=E2=86=92if=20to=20mak?= =?UTF-8?q?e=20pylint=20happy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tools/elf2efi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/elf2efi.py b/tools/elf2efi.py index 2e7ca9f6c4e..cb1a284a601 100755 --- a/tools/elf2efi.py +++ b/tools/elf2efi.py @@ -268,7 +268,7 @@ def iter_copy_sections(elf: ELFFile) -> typing.Iterator[PeSection]: if elf_seg["p_type"] == "PT_LOAD" and elf_seg["p_align"] != SECTION_ALIGNMENT: raise BadSectionError(f"ELF segment {elf_seg['p_type']} is not properly aligned" f" ({elf_seg['p_align']} != {SECTION_ALIGNMENT})") - elif elf_seg["p_type"] == "PT_GNU_RELRO": + if elf_seg["p_type"] == "PT_GNU_RELRO": relro = elf_seg for elf_s in elf.iter_sections():