[PATCH 00/11] Add support for 32-bit ARM

43 views
Skip to first unread message

Jan Kiszka

unread,
Jun 20, 2022, 9:30:07 AM6/20/22
to efibootg...@googlegroups.com, Christian Storm
Prepare and enabling building ARM 32-bit binaries. This is bascially a
build-system topic, with one exception: this fixes the section list on
x86 so that we can drop an open-coded relocation for the watchdog probe
functions.

The bigger part of the series is about extending bg_gen_unified_kernel
to support the unfortunately small file alignment in the ARM binaries
as generated by current binutils. We now support relocating sections in
the unified kernel image when adding a section header overflows into the
section data.

Jan

Jan Kiszka (11):
Makefile: Put x86-specifics under ARCH_IS_X86 condition
Makefile: Widen section list for EFI binaries
ci: Add upcoming dependency autoconf-archive
Add support for compiling ARM binaries
bg_gen_unified_kernel: Fix first_data calculation for empty sections
bg_gen_unified_kernel: Fix pycodestyle warnings
bg_gen_unified_kernel: Use file alignment of stub
bg_gen_unified_kernel: Prepare for relocatable sections
bg_gen_unified_kernel: Adjust virtual address of text section
bg_gen_unified_kernel: Make sections relocatable
ci: Add ARM

.github/workflows/main.yaml | 37 ++++++++-
Makefile.am | 36 ++++++---
configure.ac | 10 +++
main.c | 7 +-
tools/bg_gen_unified_kernel | 150 +++++++++++++++++++++++++-----------
tools/tests/Makefile.am | 4 +
6 files changed, 179 insertions(+), 65 deletions(-)

--
2.35.3

Jan Kiszka

unread,
Jun 20, 2022, 9:30:08 AM6/20/22
to efibootg...@googlegroups.com, Christian Storm
From: Jan Kiszka <jan.k...@siemens.com>

Buildsystem-wise, we are ready now. We just need to append
-mgeneraly-regs-only on modern gcc (e.g. with Debian 11) to ensure that
no unsupported FPU instructions get used. We also want to suppress the
for us meaningless warnings about mismatching wchar sizes - we do not
use any of the functions (from the compiler runtime) that triggers this.

Signed-off-by: Jan Kiszka <jan.k...@siemens.com>
---
Makefile.am | 12 ++++++++++++
configure.ac | 9 +++++++++
tools/tests/Makefile.am | 4 ++++
3 files changed, 25 insertions(+)

diff --git a/Makefile.am b/Makefile.am
index 8d550ff..856908f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -110,6 +110,10 @@ lib_LTLIBRARIES = libebgenv.la
libebgenv_la_SOURCES = $(libebgenv_a_SOURCES)
libebgenv_la_LDFLAGS = -version-info 0:0:0

+if ARCH_ARM
+libebgenv_la_LDFLAGS += -Wl,--no-wchar-size-warning
+endif
+
#
# bg_setenv binary
#
@@ -124,6 +128,10 @@ bg_setenv_SOURCES = \
bg_setenv_CFLAGS = \
$(AM_CFLAGS) -static

+if ARCH_ARM
+bg_setenv_LDFLAGS = -Wl,--no-wchar-size-warning
+endif
+
bg_setenv_LDADD = \
$(top_builddir)/libebgenv.a \
-lz
@@ -208,6 +216,10 @@ efi_cflags += \
-mno-mmx \
-mno-red-zone
endif
+if ARCH_ARM
+efi_cflags += \
+ $(CFLAGS_MGENERAL_REGS_ONLY)
+endif

efi_ldflags = \
-T $(GNUEFI_LIB_DIR)/elf_$(ARCH)_efi.lds \
diff --git a/configure.ac b/configure.ac
index 0f079bb..d39b5fa 100644
--- a/configure.ac
+++ b/configure.ac
@@ -86,6 +86,7 @@ SET_ARCH(I586, i586*|i686*)
SET_ARCH(X86_64, x86_64*)
SET_ARCH(IA64, ia64*)
SET_ARCH(AARCH64, aarch64*)
+SET_ARCH(ARM, arm*)

ARCH=$(echo $host | sed "s/\(-\).*$//")

@@ -99,10 +100,18 @@ AM_COND_IF(ARCH_X86_64, [
AM_COND_IF(ARCH_AARCH64, [
MACHINE_TYPE_NAME=aa64])

+AM_COND_IF(ARCH_ARM, [
+ MACHINE_TYPE_NAME=arm])
+
AC_SUBST([ARCH])
AC_SUBST([MACHINE_TYPE_NAME])
AM_CONDITIONAL([ARCH_IS_X86], [test "$ARCH" = "ia32" -o "$ARCH" = "x86_64"])

+AX_CHECK_COMPILE_FLAG([-mgeneral-regs-only],
+ [CFLAGS_MGENERAL_REGS_ONLY=-mgeneral-regs-only],
+ [CFLAGS_MGENERAL_REGS_ONLY=])
+AC_SUBST([CFLAGS_MGENERAL_REGS_ONLY])
+
# Checks from autoscan:
AC_CHECK_FUNCS([getmntent])
AC_CHECK_FUNCS([memset])
diff --git a/tools/tests/Makefile.am b/tools/tests/Makefile.am
index 78c5d54..3947ab5 100644
--- a/tools/tests/Makefile.am
+++ b/tools/tests/Makefile.am
@@ -29,6 +29,10 @@ AM_CFLAGS = \
-D_GNU_SOURCE \
-g

+if ARCH_ARM
+AM_LDFLAGS = -Wl,--no-wchar-size-warning
+endif
+
libtest_env_api_fat_a_SRC = \
../../env/env_api.c \
../../env/env_api_fat.c \
--
2.35.3

Jan Kiszka

unread,
Jun 20, 2022, 9:30:08 AM6/20/22
to efibootg...@googlegroups.com, Christian Storm
From: Jan Kiszka <jan.k...@siemens.com>

No functional changes.

Signed-off-by: Jan Kiszka <jan.k...@siemens.com>
---
tools/bg_gen_unified_kernel | 25 +++++++++++++------------
1 file changed, 13 insertions(+), 12 deletions(-)

diff --git a/tools/bg_gen_unified_kernel b/tools/bg_gen_unified_kernel
index e484b99..d3d77fa 100755
--- a/tools/bg_gen_unified_kernel
+++ b/tools/bg_gen_unified_kernel
@@ -205,9 +205,9 @@ def main():
cmdline_offs = align(len(stub), 512)
cmdline_size = align(len(cmdline), 512)
section = Section(b'.cmdline', cmdline_size, 0x30000,
- cmdline_size, cmdline_offs,
- Section.IMAGE_SCN_CNT_INITIALIZED_DATA |
- Section.IMAGE_SCN_MEM_READ)
+ cmdline_size, cmdline_offs,
+ Section.IMAGE_SCN_CNT_INITIALIZED_DATA |
+ Section.IMAGE_SCN_MEM_READ)
pe_headers.add_section(section)

kernel = args.kernel.read()
@@ -217,9 +217,9 @@ def main():
kernel_size = align(len(kernel), 512)
kernel_virt_size = max(kernel_size, kernel_pe_headers.get_size_of_image())
section = Section(b'.kernel', kernel_virt_size, 0x2000000,
- kernel_size, kernel_offs,
- Section.IMAGE_SCN_CNT_INITIALIZED_DATA |
- Section.IMAGE_SCN_MEM_READ)
+ kernel_size, kernel_offs,
+ Section.IMAGE_SCN_CNT_INITIALIZED_DATA |
+ Section.IMAGE_SCN_MEM_READ)
pe_headers.add_section(section)
pe_headers.set_section_alignment(kernel_pe_headers.get_section_alignment())

@@ -229,9 +229,9 @@ def main():
initrd = args.initrd.read()
initrd_size = align(len(initrd), 512)
section = Section(b'.initrd', initrd_size, 0x6000000,
- initrd_size, initrd_offs,
- Section.IMAGE_SCN_CNT_INITIALIZED_DATA |
- Section.IMAGE_SCN_MEM_READ)
+ initrd_size, initrd_offs,
+ Section.IMAGE_SCN_CNT_INITIALIZED_DATA |
+ Section.IMAGE_SCN_MEM_READ)
pe_headers.add_section(section)

current_offs = initrd_offs + initrd_size
@@ -244,9 +244,9 @@ def main():
dtb_offs.append(current_offs)
dtb_size = align(len(dtb[n]), 512)
section = Section(bytes('.dtb-{}'.format(n + 1), 'ascii'),
- dtb_size, dtb_virt, dtb_size, dtb_offs[n],
- Section.IMAGE_SCN_CNT_INITIALIZED_DATA |
- Section.IMAGE_SCN_MEM_READ)
+ dtb_size, dtb_virt, dtb_size, dtb_offs[n],
+ Section.IMAGE_SCN_CNT_INITIALIZED_DATA |
+ Section.IMAGE_SCN_MEM_READ)
pe_headers.add_section(section)
dtb_virt += dtb_size
current_offs += dtb_size
@@ -280,5 +280,6 @@ def main():

args.output.write(image)

+
if __name__ == "__main__":
main()
--
2.35.3

Jan Kiszka

unread,
Jun 20, 2022, 9:30:08 AM6/20/22
to efibootg...@googlegroups.com, Christian Storm
From: Jan Kiszka <jan.k...@siemens.com>

Rather than hard-coding some alignment, use that of the stub loader in
order to be consistent in the generated image.

Signed-off-by: Jan Kiszka <jan.k...@siemens.com>
---
tools/bg_gen_unified_kernel | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)

diff --git a/tools/bg_gen_unified_kernel b/tools/bg_gen_unified_kernel
index d3d77fa..45d9cbc 100755
--- a/tools/bg_gen_unified_kernel
+++ b/tools/bg_gen_unified_kernel
@@ -50,6 +50,7 @@ class Section:
class PEHeaders:
OPT_OFFS_SIZE_OF_INIT_DATA = 0x8
OPT_OFFS_SECTION_ALIGNMENT = 0x20
+ OPT_OFFS_FILE_ALIGNMENT = 0x24
OPT_OFFS_SIZE_OF_IMAGE = 0x38

def __init__(self, name, blob):
@@ -138,6 +139,9 @@ class PEHeaders:
alignment)
self.set_size_of_image(align(self.get_size_of_image(), alignment))

+ def get_file_alignment(self):
+ return self.get_opt_header_field(PEHeaders.OPT_OFFS_FILE_ALIGNMENT)
+
def get_size_of_image(self):
return self.get_opt_header_field(PEHeaders.OPT_OFFS_SIZE_OF_IMAGE)

@@ -200,10 +204,11 @@ def main():
stub = args.stub.read()

pe_headers = PEHeaders('stub image', stub)
+ file_align = pe_headers.get_file_alignment()

# Add extra section headers
- cmdline_offs = align(len(stub), 512)
- cmdline_size = align(len(cmdline), 512)
+ cmdline_offs = align(len(stub), file_align)
+ cmdline_size = align(len(cmdline), file_align)
section = Section(b'.cmdline', cmdline_size, 0x30000,
cmdline_size, cmdline_offs,
Section.IMAGE_SCN_CNT_INITIALIZED_DATA |
@@ -214,7 +219,7 @@ def main():
kernel_pe_headers = PEHeaders('kernel', kernel)

kernel_offs = cmdline_offs + cmdline_size
- kernel_size = align(len(kernel), 512)
+ kernel_size = align(len(kernel), file_align)
kernel_virt_size = max(kernel_size, kernel_pe_headers.get_size_of_image())
section = Section(b'.kernel', kernel_virt_size, 0x2000000,
kernel_size, kernel_offs,
@@ -227,7 +232,7 @@ def main():
initrd_size = 0
if args.initrd:
initrd = args.initrd.read()
- initrd_size = align(len(initrd), 512)
+ initrd_size = align(len(initrd), file_align)
section = Section(b'.initrd', initrd_size, 0x6000000,
initrd_size, initrd_offs,
Section.IMAGE_SCN_CNT_INITIALIZED_DATA |
@@ -242,7 +247,7 @@ def main():
for n in range(len(args.dtb)):
dtb.append(args.dtb[n].read())
dtb_offs.append(current_offs)
- dtb_size = align(len(dtb[n]), 512)
+ dtb_size = align(len(dtb[n]), file_align)
section = Section(bytes('.dtb-{}'.format(n + 1), 'ascii'),
dtb_size, dtb_virt, dtb_size, dtb_offs[n],
Section.IMAGE_SCN_CNT_INITIALIZED_DATA |
@@ -276,7 +281,7 @@ def main():
image += dtb[n]

# Align to promised size of last section
- image += bytearray(align(len(image), 512) - len(image))
+ image += bytearray(align(len(image), file_align) - len(image))

args.output.write(image)

--
2.35.3

Jan Kiszka

unread,
Jun 20, 2022, 9:30:08 AM6/20/22
to efibootg...@googlegroups.com, Christian Storm
From: Jan Kiszka <jan.k...@siemens.com>

Empty sections tend to have a zero data offset and will then invalidate
the calculation of the first section data in the file.

Signed-off-by: Jan Kiszka <jan.k...@siemens.com>
---
tools/bg_gen_unified_kernel | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/tools/bg_gen_unified_kernel b/tools/bg_gen_unified_kernel
index 5f3727c..e484b99 100755
--- a/tools/bg_gen_unified_kernel
+++ b/tools/bg_gen_unified_kernel
@@ -108,7 +108,7 @@ class PEHeaders:
file=sys.stderr)
exit(1)

- if section.data_offs < self.first_data:
+ if section.data_size and section.data_offs < self.first_data:
self.first_data = section.data_offs

self.sections.append(section)
--
2.35.3

Jan Kiszka

unread,
Jun 20, 2022, 9:30:09 AM6/20/22
to efibootg...@googlegroups.com, Christian Storm
From: Jan Kiszka <jan.k...@siemens.com>

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 <jan.k...@siemens.com>
---
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

Jan Kiszka

unread,
Jun 20, 2022, 9:30:09 AM6/20/22
to efibootg...@googlegroups.com, Christian Storm
From: Jan Kiszka <jan.k...@siemens.com>

Signed-off-by: Jan Kiszka <jan.k...@siemens.com>
---
.github/workflows/main.yaml | 26 ++++++++++++++++++++++++++
1 file changed, 26 insertions(+)

diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml
index 7d33c76..429557b 100644
--- a/.github/workflows/main.yaml
+++ b/.github/workflows/main.yaml
@@ -29,6 +29,7 @@ jobs:
- amd64
- i386
- arm64
+ - arm
- cppcheck
steps:
- name: Checkout
@@ -69,6 +70,24 @@ jobs:
autoconf-archive gcc-aarch64-linux-gnu libc6-dev-arm64-cross \
gnu-efi:arm64 libz-dev:arm64 libpci-dev:arm64 check:arm64 \
qemu-user-static
+ - name: Install arm dependencies
+ if: ${{ matrix.target == 'arm' }}
+ run: |
+ sudo dpkg --add-architecture armhf
+ sudo sed -i 's/^deb /deb [arch=amd64] /g' /etc/apt/sources.list
+ sudo sh -c "cat <<EOF > /etc/apt/sources.list.d/ports.list
+ deb [arch=armhf] http://ports.ubuntu.com/ focal main restricted
+ deb [arch=armhf] http://ports.ubuntu.com/ focal-updates main restricted
+ deb [arch=armhf] http://ports.ubuntu.com/ focal universe
+ deb [arch=armhf] http://ports.ubuntu.com/ focal-updates universe
+ deb [arch=armhf] http://ports.ubuntu.com/ focal multiverse
+ deb [arch=armhf] http://ports.ubuntu.com/ focal-updates multiverse
+ EOF"
+ sudo apt-get update
+ sudo apt-get install --no-install-recommends \
+ autoconf-archive gcc-arm-linux-gnueabihf libc6-dev-armhf-cross \
+ gnu-efi:armhf libz-dev:armhf libpci-dev:armhf check:armhf \
+ qemu-user-static
- name: Install cppcheck
if: ${{ matrix.target == 'cppcheck' }}
run: |
@@ -113,6 +132,13 @@ jobs:
../configure --host=aarch64-linux-gnu \
PKG_CONFIG=/usr/bin/aarch64-linux-gnu-pkg-config
make check -j $(nproc)
+ - name: Build arm
+ if: ${{ matrix.target == 'arm' }}
+ run: |
+ cd build
+ ../configure --host=arm-linux-gnueabihf \
+ PKG_CONFIG=/usr/bin/arm-linux-gnueabihf-pkg-config
+ make check -j $(nproc)
- name: Run cppcheck
if: ${{ matrix.target == 'cppcheck' }}
run: |
--
2.35.3

Jan Kiszka

unread,
Jun 20, 2022, 9:30:09 AM6/20/22
to efibootg...@googlegroups.com, Christian Storm
From: Jan Kiszka <jan.k...@siemens.com>

If the stub image comes with a too small alignment, it's easy to grow
the PE header into the section data. This unfortunately happens on ARM
with current toolchains.

Resolve that by moving the sections up as needed when a new section is
adding that causes an overflow. As the code has been prepared to account
for changing layouts between stub parsing, section adding and final
image writing, the actual changes are now small.

Signed-off-by: Jan Kiszka <jan.k...@siemens.com>
---
tools/bg_gen_unified_kernel | 24 +++++++++++++++++++-----
1 file changed, 19 insertions(+), 5 deletions(-)

diff --git a/tools/bg_gen_unified_kernel b/tools/bg_gen_unified_kernel
index 28c8f0d..e954fa5 100755
--- a/tools/bg_gen_unified_kernel
+++ b/tools/bg_gen_unified_kernel
@@ -54,6 +54,7 @@ class PEHeaders:
OPT_OFFS_SECTION_ALIGNMENT = 0x20
OPT_OFFS_FILE_ALIGNMENT = 0x24
OPT_OFFS_SIZE_OF_IMAGE = 0x38
+ OPT_OFFS_SIZE_OF_HEADERS = 0x3C

def __init__(self, name, blob):
# Parse headers: DOS, COFF, optional header
@@ -164,13 +165,19 @@ class PEHeaders:
def set_size_of_image(self, size):
self.set_opt_header_field(PEHeaders.OPT_OFFS_SIZE_OF_IMAGE, size)

+ def get_size_of_headers(self):
+ return self.get_opt_header_field(PEHeaders.OPT_OFFS_SIZE_OF_HEADERS)
+
+ def set_size_of_headers(self, size):
+ self.set_opt_header_field(PEHeaders.OPT_OFFS_SIZE_OF_HEADERS, size)
+
def add_section(self, section):
self.header_size += 0x28
-
- # check space for adding extra sections
- if self.first_data < self.header_size:
- print("FIXME: section data requires relocation", file=sys.stderr)
- exit(1)
+ size_of_headers = self.get_size_of_headers()
+ if self.header_size > size_of_headers:
+ size_of_headers = align(self.header_size,
+ self.get_file_alignment())
+ self.set_size_of_headers(size_of_headers)

self.sections.append(section)
self.coff_header = struct.pack('<6sH16s', self.coff_header[:6],
@@ -186,6 +193,13 @@ class PEHeaders:
new_size = self.get_size_of_init_data() + section.data_size
self.set_size_of_init_data(new_size)

+ if size_of_headers > self.first_data:
+ file_relocation = size_of_headers - self.first_data
+ self.first_data += file_relocation
+ for sect in self.sections:
+ if sect.data_size > 0:
+ sect.data_offs += file_relocation
+

def main():
parser = argparse.ArgumentParser(
--
2.35.3

Jan Kiszka

unread,
Jun 20, 2022, 9:30:09 AM6/20/22
to efibootg...@googlegroups.com, Christian Storm
From: Jan Kiszka <jan.k...@siemens.com>

We want to support moving the stub stections around in case the section
headers grow into them in the output file. To prepare for that, change
the we the unified image is created: Use the section objects to obtain
size and specifically file position during image creation. That makes it
easier to move the data around while new sections are being added and
later - when writing out - refer to the right offsets.

Signed-off-by: Jan Kiszka <jan.k...@siemens.com>
---
tools/bg_gen_unified_kernel | 75 +++++++++++++++++++------------------
1 file changed, 39 insertions(+), 36 deletions(-)

diff --git a/tools/bg_gen_unified_kernel b/tools/bg_gen_unified_kernel
index 45d9cbc..2dc0bcd 100755
--- a/tools/bg_gen_unified_kernel
+++ b/tools/bg_gen_unified_kernel
@@ -204,57 +204,57 @@ def main():
stub = args.stub.read()

pe_headers = PEHeaders('stub image', stub)
+ stub_first_data = pe_headers.first_data
file_align = pe_headers.get_file_alignment()

# Add extra section headers
- cmdline_offs = align(len(stub), file_align)
- cmdline_size = align(len(cmdline), file_align)
- section = Section(b'.cmdline', cmdline_size, 0x30000,
- cmdline_size, cmdline_offs,
- Section.IMAGE_SCN_CNT_INITIALIZED_DATA |
- Section.IMAGE_SCN_MEM_READ)
- pe_headers.add_section(section)
+ current_offs = align(len(stub), file_align)
+ sect_size = align(len(cmdline), file_align)
+ cmdline_section = Section(b'.cmdline', sect_size, 0x30000,
+ sect_size, current_offs,
+ Section.IMAGE_SCN_CNT_INITIALIZED_DATA |
+ Section.IMAGE_SCN_MEM_READ)
+ pe_headers.add_section(cmdline_section)

kernel = args.kernel.read()
kernel_pe_headers = PEHeaders('kernel', kernel)

- kernel_offs = cmdline_offs + cmdline_size
- kernel_size = align(len(kernel), file_align)
- kernel_virt_size = max(kernel_size, kernel_pe_headers.get_size_of_image())
- section = Section(b'.kernel', kernel_virt_size, 0x2000000,
- kernel_size, kernel_offs,
- Section.IMAGE_SCN_CNT_INITIALIZED_DATA |
- Section.IMAGE_SCN_MEM_READ)
- pe_headers.add_section(section)
+ current_offs = cmdline_section.data_offs + cmdline_section.data_size
+ sect_size = align(len(kernel), file_align)
+ virt_size = max(sect_size, kernel_pe_headers.get_size_of_image())
+ kernel_section = Section(b'.kernel', virt_size, 0x2000000,
+ sect_size, current_offs,
+ Section.IMAGE_SCN_CNT_INITIALIZED_DATA |
+ Section.IMAGE_SCN_MEM_READ)
+ pe_headers.add_section(kernel_section)
pe_headers.set_section_alignment(kernel_pe_headers.get_section_alignment())

- initrd_offs = kernel_offs + kernel_size
- initrd_size = 0
+ current_offs = kernel_section.data_offs + kernel_section.data_size
if args.initrd:
initrd = args.initrd.read()
- initrd_size = align(len(initrd), file_align)
- section = Section(b'.initrd', initrd_size, 0x6000000,
- initrd_size, initrd_offs,
- Section.IMAGE_SCN_CNT_INITIALIZED_DATA |
- Section.IMAGE_SCN_MEM_READ)
- pe_headers.add_section(section)
+ sect_size = align(len(initrd), file_align)
+ initrd_section = Section(b'.initrd', sect_size, 0x6000000,
+ sect_size, current_offs,
+ Section.IMAGE_SCN_CNT_INITIALIZED_DATA |
+ Section.IMAGE_SCN_MEM_READ)
+ pe_headers.add_section(initrd_section)
+ current_offs = initrd_section.data_offs + initrd_section.data_size

- current_offs = initrd_offs + initrd_size
dtb_virt = 0x40000
dtb = []
- dtb_offs = []
- dtb_size = 0
+ dtb_section = []
for n in range(len(args.dtb)):
dtb.append(args.dtb[n].read())
- dtb_offs.append(current_offs)
- dtb_size = align(len(dtb[n]), file_align)
+ sect_size = align(len(dtb[n]), file_align)
section = Section(bytes('.dtb-{}'.format(n + 1), 'ascii'),
- dtb_size, dtb_virt, dtb_size, dtb_offs[n],
+ sect_size, dtb_virt, sect_size, current_offs,
Section.IMAGE_SCN_CNT_INITIALIZED_DATA |
Section.IMAGE_SCN_MEM_READ)
pe_headers.add_section(section)
- dtb_virt += dtb_size
- current_offs += dtb_size
+ dtb_section.append(section)
+
+ dtb_virt += section.data_size
+ current_offs = section.data_offs + section.data_size

# Build unified image header
image = pe_headers.dos_header + pe_headers.coff_header + \
@@ -262,22 +262,25 @@ def main():
for section in pe_headers.sections:
image += section.get_struct()

+ # Pad till first section data
+ image += bytearray(pe_headers.first_data - len(image))
+
# Write remaining stub
- image += stub[len(image):]
+ image += stub[stub_first_data:]

# Write data of extra sections
- image += bytearray(cmdline_offs - len(image))
+ image += bytearray(cmdline_section.data_offs - len(image))
image += cmdline

- image += bytearray(kernel_offs - len(image))
+ image += bytearray(kernel_section.data_offs - len(image))
image += kernel

if args.initrd:
- image += bytearray(initrd_offs - len(image))
+ image += bytearray(initrd_section.data_offs - len(image))
image += initrd

for n in range(len(dtb)):
- image += bytearray(dtb_offs[n] - len(image))
+ image += bytearray(dtb_section[n].data_offs - len(image))
image += dtb[n]

# Align to promised size of last section
--
2.35.3

Jan Kiszka

unread,
Jun 27, 2022, 3:27:40 AM6/27/22
to efibootg...@googlegroups.com, Christian Storm
s/larger/large/

Will fix up directly if there are no other remarks.

Jan

> + 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

--
Siemens AG, Technology
Competence Center Embedded Linux

Christian Storm

unread,
Jul 1, 2022, 7:41:53 AM7/1/22
to efibootg...@googlegroups.com
Hi,

> Buildsystem-wise, we are ready now. We just need to append
> -mgeneraly-regs-only on modern gcc (e.g. with Debian 11) to ensure that

Typo, it's mgeneral-regs-only and not mgeneral*y*-regs-only.
Kind regards,
Christian

--
Dr. Christian Storm
Siemens AG, Technology, T CED SES-DE
Otto-Hahn-Ring 6, 81739 München, Germany

Jan Kiszka

unread,
Jul 1, 2022, 9:32:28 AM7/1/22
to efibootg...@googlegroups.com
On 01.07.22 13:43, Christian Storm wrote:
> Hi,
>
>> Buildsystem-wise, we are ready now. We just need to append
>> -mgeneraly-regs-only on modern gcc (e.g. with Debian 11) to ensure that
>
> Typo, it's mgeneral-regs-only and not mgeneral*y*-regs-only.
>

Thanks, fixed locally.

Jan

Christian Storm

unread,
Jul 1, 2022, 9:57:34 AM7/1/22
to efibootg...@googlegroups.com
Hi,

> We want to support moving the stub stections around in case the section

Typo, it needs to read 'sections' not 'stections'.

> headers grow into them in the output file. To prepare for that, change
> the we the unified image is created: Use the section objects to obtain

No proper sentence: '[...] the we the [...]'.

Christian Storm

unread,
Jul 1, 2022, 10:01:37 AM7/1/22
to efibootg...@googlegroups.com
Hi,

> If the stub image comes with a too small alignment, it's easy to grow
> the PE header into the section data. This unfortunately happens on ARM
> with current toolchains.
>
> Resolve that by moving the sections up as needed when a new section is
> adding that causes an overflow. As the code has been prepared to account

Shouldn't that read 'added'?

Jan Kiszka

unread,
Jul 1, 2022, 10:09:01 AM7/1/22
to efibootg...@googlegroups.com
On 01.07.22 15:58, Christian Storm wrote:
> Hi,
>
>> We want to support moving the stub stections around in case the section
>
> Typo, it needs to read 'sections' not 'stections'.
>
>> headers grow into them in the output file. To prepare for that, change
>> the we the unified image is created: Use the section objects to obtain
>
> No proper sentence: '[...] the we the [...]'.
>

My brain thought of "change how the unified image is created" but then
my fingers got distracted.

Fixed locally, thanks,

Jan Kiszka

unread,
Jul 1, 2022, 10:09:52 AM7/1/22
to efibootg...@googlegroups.com
On 01.07.22 16:02, Christian Storm wrote:
> Hi,
>
>> If the stub image comes with a too small alignment, it's easy to grow
>> the PE header into the section data. This unfortunately happens on ARM
>> with current toolchains.
>>
>> Resolve that by moving the sections up as needed when a new section is
>> adding that causes an overflow. As the code has been prepared to account
>
> Shouldn't that read 'added'?

Yes...

Jan Kiszka

unread,
Jul 1, 2022, 3:28:19 PM7/1/22
to efibootg...@googlegroups.com
On 01.07.22 16:02, Christian Storm wrote:
> Hi,
>
>> If the stub image comes with a too small alignment, it's easy to grow
>> the PE header into the section data. This unfortunately happens on ARM
>> with current toolchains.
>>
>> Resolve that by moving the sections up as needed when a new section is
>> adding that causes an overflow. As the code has been prepared to account
>
> Shouldn't that read 'added'?

Fixed.

As there were just issues with the commit logs which I've all fixed,
I'll not resent and rather move the final version of this series to
master (after a coverity run). Later series/patches require functional
changes, and that will lead to v2 of them.

Thanks,

Jan Kiszka

unread,
Jul 1, 2022, 3:39:19 PM7/1/22
to efibootg...@googlegroups.com, Christian Storm
From: Jan Kiszka <jan.k...@siemens.com>

Signed-off-by: Jan Kiszka <jan.k...@siemens.com>
---

Changes in v2:
- add autoconf-archive also to coverity workflow

.github/workflows/coverity.yaml | 4 ++--
.github/workflows/main.yaml | 26 ++++++++++++++++++++++++++
2 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/.github/workflows/coverity.yaml b/.github/workflows/coverity.yaml
index 01145f5..0879f70 100644
--- a/.github/workflows/coverity.yaml
+++ b/.github/workflows/coverity.yaml
@@ -1,7 +1,7 @@
#
# EFI Boot Guard
#
-# Copyright (c) Siemens AG, 2021
+# Copyright (c) Siemens AG, 2021-2022
#
# Authors:
# Claudius Heine <c...@denx.de>
@@ -33,7 +33,7 @@ jobs:
run: |
sudo apt-get update
sudo apt-get install --no-install-recommends \
- gcc-multilib gnu-efi libz-dev libpci-dev check
+ autoconf-archive gcc-multilib gnu-efi libz-dev libpci-dev check
- name: Install Coverity
run: |
wget https://scan.coverity.com/download/cxx/linux64 \
Reply all
Reply to author
Forward
0 new messages