From: Jan Kiszka <[email protected]> Current ARM toolchains use 8-byte alignment for the EFI binaries, and that leads to the text section being loaded at a virtual address that will immediate overlap with an expanded PE header like we produce when adding sections. Resolve that by moving the text to address 0x1000 in that case. This will give us sufficient room for a reasonable amount of sections.
Changing the virtual address also requires to move AddressOfEntryPoint and BaseOfCode in the PE header. Signed-off-by: Jan Kiszka <[email protected]> --- tools/bg_gen_unified_kernel | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/tools/bg_gen_unified_kernel b/tools/bg_gen_unified_kernel index 2dc0bcd..28c8f0d 100755 --- a/tools/bg_gen_unified_kernel +++ b/tools/bg_gen_unified_kernel @@ -49,6 +49,8 @@ class Section: class PEHeaders: OPT_OFFS_SIZE_OF_INIT_DATA = 0x8 + OPT_OFFS_ADDRESS_OF_ENTRY_POINT = 0x10 + OPT_OFFS_BASE_OF_CODE = 0x14 OPT_OFFS_SECTION_ALIGNMENT = 0x20 OPT_OFFS_FILE_ALIGNMENT = 0x24 OPT_OFFS_SIZE_OF_IMAGE = 0x38 @@ -131,6 +133,20 @@ class PEHeaders: def set_size_of_init_data(self, size): self.set_opt_header_field(PEHeaders.OPT_OFFS_SIZE_OF_INIT_DATA, size) + def get_address_of_entry_point(self): + return self.get_opt_header_field( + PEHeaders.OPT_OFFS_ADDRESS_OF_ENTRY_POINT) + + def set_address_of_entry_point(self, addr): + self.set_opt_header_field(PEHeaders.OPT_OFFS_ADDRESS_OF_ENTRY_POINT, + addr) + + def get_base_of_code(self): + return self.get_opt_header_field(PEHeaders.OPT_OFFS_BASE_OF_CODE) + + def set_base_of_code(self, base): + self.set_opt_header_field(PEHeaders.OPT_OFFS_BASE_OF_CODE, base) + def get_section_alignment(self): return self.get_opt_header_field(PEHeaders.OPT_OFFS_SECTION_ALIGNMENT) @@ -256,6 +272,27 @@ def main(): dtb_virt += section.data_size current_offs = section.data_offs + section.data_size + # + # Some ARM toolchains use a minimal alignment and put the text section at + # a too low virtual address. This causes troubles when we relocated + # sections because the PE header is also loaded into memory. + # + # Align the virtual address of the text section to 4K therefore. + # + for sect in pe_headers.sections: + if sect.name == b'.text\0\0\0' and sect.virt_addr < 0x1000: + if pe_headers.first_data > 0x1000: + print("PE header too larger - way too many DTBs?!", + file=sys.stderr) + exit(1) + virt_relocation = 0x1000 - sect.virt_addr + sect.virt_addr = 0x1000 + pe_headers.set_address_of_entry_point( + pe_headers.get_address_of_entry_point() + virt_relocation) + pe_headers.set_base_of_code( + pe_headers.get_base_of_code() + virt_relocation) + break + # Build unified image header image = pe_headers.dos_header + pe_headers.coff_header + \ pe_headers.opt_header -- 2.35.3 -- You received this message because you are subscribed to the Google Groups "EFI Boot Guard" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/efibootguard-dev/da0198ad8262709c431746de59527175037d7000.1655731805.git.jan.kiszka%40siemens.com.
