mirror of
https://github.com/systemd/systemd.git
synced 2024-10-27 01:55:22 +03:00
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.
This commit is contained in:
parent
af02814a85
commit
a0797b4ad7
192
tools/elf2efi.py
192
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)
|
||||
|
Loading…
Reference in New Issue
Block a user