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.

Reply via email to