[PATCH v2 23/30] sandbox: Augment the linker script for MSYS2

Simon Glass sjg at chromium.org
Sun Apr 30 03:29:56 CEST 2023


We need to place the linker lists, etc. in the .rdata section but this
is not possible with the default linker script. We can only add new
sections, which causes Windows to give an "Exec format error" error.

Add a rule to create a new linker script, by obtaining the one from
the linker and adding some things to the end of the .rdata section.

Signed-off-by: Simon Glass <sjg at chromium.org>
---

Changes in v2:
- Add an awk script to augment the built-in link script

 Makefile                          | 17 ++++++++++++-----
 arch/sandbox/config.mk            | 19 ++++++++++++++++++-
 arch/sandbox/cpu/u-boot-pe.lds.in | 25 +++++++++++++++++++++++++
 scripts/add_to_rdata.awk          | 25 +++++++++++++++++++++++++
 4 files changed, 80 insertions(+), 6 deletions(-)
 create mode 100644 arch/sandbox/cpu/u-boot-pe.lds.in
 create mode 100644 scripts/add_to_rdata.awk

diff --git a/Makefile b/Makefile
index a328652f0f23..760c143049aa 100644
--- a/Makefile
+++ b/Makefile
@@ -1734,6 +1734,12 @@ else
 u-boot-keep-syms-lto :=
 endif
 
+ifeq ($(MSYS_VERSION),0)
+add_ld_script := -T u-boot.lds
+else
+add_ld_script := u-boot.lds
+endif
+
 # Rule to link u-boot
 # May be overridden by arch/$(ARCH)/config.mk
 ifeq ($(LTO_ENABLE),y)
@@ -1742,7 +1748,7 @@ quiet_cmd_u-boot__ ?= LTO     $@
 		$(CC) -nostdlib -nostartfiles					\
 		$(LTO_FINAL_LDFLAGS) $(c_flags)					\
 		$(KBUILD_LDFLAGS:%=-Wl,%) $(LDFLAGS_u-boot:%=-Wl,%) -o $@	\
-		-T u-boot.lds $(u-boot-init)					\
+		$(add_ld_script) $(u-boot-init)					\
 		-Wl,--whole-archive						\
 			$(u-boot-main)						\
 			$(u-boot-keep-syms-lto)					\
@@ -1753,7 +1759,7 @@ quiet_cmd_u-boot__ ?= LTO     $@
 else
 quiet_cmd_u-boot__ ?= LD      $@
       cmd_u-boot__ ?= $(LD) $(KBUILD_LDFLAGS) $(LDFLAGS_u-boot) -o $@		\
-		-T u-boot.lds $(u-boot-init)					\
+		$(add_ld_script) $(u-boot-init)					\
 		--whole-archive							\
 			$(u-boot-main)						\
 		--no-whole-archive						\
@@ -1905,10 +1911,11 @@ endif
 # prepare2 creates a makefile if using a separate output directory
 prepare2: prepare3 outputmakefile cfg
 
+# Allow the linker script to be generated from LDSCRIPT_IN
 prepare1: prepare2 $(version_h) $(timestamp_h) $(dt_h) $(env_h) \
-                   include/config/auto.conf
-ifeq ($(wildcard $(LDSCRIPT)),)
-	@echo >&2 "  Could not find linker script."
+                   include/config/auto.conf $(if $(LDSCRIPT_IN),$(LDSCRIPT))
+ifeq ($(wildcard $(LDSCRIPT))$(LDSCRIPT_IN),)
+	@echo >&2 "  Could not find linker script $(LDSCRIPT)"
 	@/bin/false
 endif
 
diff --git a/arch/sandbox/config.mk b/arch/sandbox/config.mk
index 2d184c5f652a..c97c39d4301b 100644
--- a/arch/sandbox/config.mk
+++ b/arch/sandbox/config.mk
@@ -1,4 +1,4 @@
-# SPDX-License-Identifier: GPL-2.0+
+	# SPDX-License-Identifier: GPL-2.0+
 # Copyright (c) 2011 The Chromium OS Authors.
 
 PLATFORM_CPPFLAGS += -D__SANDBOX__ -U_FORTIFY_SOURCE
@@ -71,3 +71,20 @@ EFI_CRT0 := crt0_sandbox_efi.o
 EFI_RELOC := reloc_sandbox_efi.o
 AFLAGS_crt0_sandbox_efi.o += -DHOST_ARCH="$(HOST_ARCH)"
 CFLAGS_reloc_sandbox_efi.o += -DHOST_ARCH="$(HOST_ARCH)"
+
+ifneq ($(MSYS_VERSION),0)
+LDSCRIPT := $(objtree)/u-boot-pe.lds
+
+AWK_RDATA := ${srctree}/scripts/add_to_rdata.awk
+LDSCRIPT_IN := ${srctree}/arch/sandbox/cpu/u-boot-pe.lds.in
+
+quiet_cmd_gen_lds = GEN LDS $@
+cmd_gen_lds = echo "int main() { return 0; }" | $(CC) -x c - -Wl,-verbose | \
+		awk -f $(AWK_RDATA) -v INFILE=$< >$@
+
+# Write out the contents of INFILE immediately before the close of the .rdata
+# block
+$(LDSCRIPT): $(LDSCRIPT_IN) $(AWK_RDATA) FORCE
+	$(call if_changed,gen_lds)
+
+endif
diff --git a/arch/sandbox/cpu/u-boot-pe.lds.in b/arch/sandbox/cpu/u-boot-pe.lds.in
new file mode 100644
index 000000000000..0ec7ef3bb350
--- /dev/null
+++ b/arch/sandbox/cpu/u-boot-pe.lds.in
@@ -0,0 +1,25 @@
+	/* U-Boot additions from here on */
+	. = ALIGN(4);
+	KEEP(*(SORT(__u_boot_list*)));
+
+	*(_u_boot_sandbox_getopt_start)
+	*(_u_boot_sandbox_getopt)
+	*(_u_boot_sandbox_getopt_end)
+
+	*(___efi_runtime_start)
+	*(efi_runtime_text)
+	*(efi_runtime_data)
+	*(___efi_runtime_stop)
+
+	*(___efi_runtime_rel_start)
+	*(.relefi_runtime_text)
+	*(.relefi_runtime_data)
+	*(___efi_runtime_rel_stop)
+
+	. = ALIGN(4);
+	*(.rodata.ttf.init)
+	*(.rodata.splash.init)
+	*(.rodata.helloworld.init)
+	*(.dtb.init.rodata)
+
+	/* U-Boot additions end */
diff --git a/scripts/add_to_rdata.awk b/scripts/add_to_rdata.awk
new file mode 100644
index 000000000000..43fdfe8bb789
--- /dev/null
+++ b/scripts/add_to_rdata.awk
@@ -0,0 +1,25 @@
+# SPDX-License-Identifier: GPL-2.0+
+#
+# Copyright 2023 Google, Inc
+#
+# Awk script to extract the default link script from the linker and write out
+# the contents of INFILE immediately before the close of the .rdata section.
+
+# to a C string which can be compiled into U-Boot.
+
+# INS = 1 if we are inside the link script (delimited by ======== lines)
+# INR = 1 if we are inside the .rdata section
+
+# When we see } while in the .rdata part of the link script, insert INFILE
+/}/ { if (INS && INR) { while ((getline < INFILE) > 0) {print}; DONE=1; INR=0; $0="}"; }}
+
+# Find start and end of link script
+/===================/ { if (INS) exit; INS=1; next; }
+
+# If inside the link script, print each line
+{ if (INS) print; }
+
+# Detect the .rdata section and get ready to insert INFILE when we see the end }
+/\.rdata.*:/ {INR=1; }
+
+END { if (!DONE) { print "add_to_rdata.awk: Could not find link script in ld output" > "/dev/stderr"; exit 1;} }
-- 
2.40.1.495.gc816e09b53d-goog



More information about the U-Boot mailing list