Add a script to allow the U-Boot sandbox executable to be built for Windows. Add a note as to why this seems to be necessary for now.
Signed-off-by: Simon Glass <s...@chromium.org> --- Makefile | 11 +- arch/sandbox/config.mk | 4 + arch/sandbox/cpu/u-boot-pe.lds | 447 +++++++++++++++++++++++++++++++++ 3 files changed, 460 insertions(+), 2 deletions(-) create mode 100644 arch/sandbox/cpu/u-boot-pe.lds diff --git a/Makefile b/Makefile index dd3fcd1782e5..0aa97a2c3b48 100644 --- a/Makefile +++ b/Makefile @@ -1730,6 +1730,13 @@ 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 +$(warning msys) +endif + # Rule to link u-boot # May be overridden by arch/$(ARCH)/config.mk ifeq ($(LTO_ENABLE),y) @@ -1738,7 +1745,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) \ @@ -1749,7 +1756,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 \ diff --git a/arch/sandbox/config.mk b/arch/sandbox/config.mk index 2d184c5f652a..e05daf57ef8e 100644 --- a/arch/sandbox/config.mk +++ b/arch/sandbox/config.mk @@ -71,3 +71,7 @@ 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 = $(srctree)/arch/sandbox/cpu/u-boot-pe.lds +endif diff --git a/arch/sandbox/cpu/u-boot-pe.lds b/arch/sandbox/cpu/u-boot-pe.lds new file mode 100644 index 000000000000..031e70fafd03 --- /dev/null +++ b/arch/sandbox/cpu/u-boot-pe.lds @@ -0,0 +1,447 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * U-Boot note: This was obtained by using the -verbose linker option. The + * U-Boot additions are marked below. + * + * Ideally we would add sections to the executable, as is done with the Linux + * build. But PE executables do not appear to work correctly if unexpected + * sections are present: + * + * $ /tmp/b/sandbox/u-boot.exe + * -bash: /tmp/b/sandbox/u-boot.exe: cannot execute binary file: Exec format error + * + * So we take a approach of rewriting the whole file, for now. This will likely + * break in the future when a toolchain change is made. + */ + +/* Default linker script, for normal executables */ +/* Copyright (C) 2014-2023 Free Software Foundation, Inc. + Copying and distribution of this script, with or without modification, + are permitted in any medium without royalty provided the copyright + notice and this notice are preserved. */ + +OUTPUT_FORMAT(pei-x86-64) +SEARCH_DIR("/usr/x86_64-pc-msys/lib"); SEARCH_DIR("/usr/lib"); SEARCH_DIR("/usr/lib/w32api"); +SECTIONS +{ + /* Make the virtual address and file offset synced if the alignment is + lower than the target page size. */ + . = SIZEOF_HEADERS; + . = ALIGN(__section_alignment__); + .text __image_base__ + ( __section_alignment__ < 0x1000 ? . : __section_alignment__ ) : + { + KEEP (*(SORT_NONE(.init))) + *(.text) + *(SORT(.text$*)) + *(.text.*) + *(.gnu.linkonce.t.*) + *(.glue_7t) + *(.glue_7) + . = ALIGN(8); + /* Note: we always define __CTOR_LIST__ and ___CTOR_LIST__ here, + we do not PROVIDE them. This is because the ctors.o startup + code in libgcc defines them as common symbols, with the + expectation that they will be overridden by the definitions + here. If we PROVIDE the symbols then they will not be + overridden and global constructors will not be run. + See PR 22762 for more details. + + This does mean that it is not possible for a user to define + their own __CTOR_LIST__ and __DTOR_LIST__ symbols; if they do, + the content from those variables are included but the symbols + defined here silently take precedence. If they truly need to + be redefined, a custom linker script will have to be used. + (The custom script can just be a copy of this script with the + PROVIDE() qualifiers added). + In particular this means that ld -Ur does not work, because + the proper __CTOR_LIST__ set by ld -Ur is overridden by a + bogus __CTOR_LIST__ set by the final link. See PR 46. */ + ___CTOR_LIST__ = .; + __CTOR_LIST__ = .; + LONG (-1); LONG (-1); + KEEP (*(.ctors)); + KEEP (*(.ctor)); + KEEP (*(SORT_BY_NAME(.ctors.*))); + LONG (0); LONG (0); + /* See comment about __CTOR_LIST__ above. The same reasoning + applies here too. */ + ___DTOR_LIST__ = .; + __DTOR_LIST__ = .; + LONG (-1); LONG (-1); + KEEP (*(.dtors)); + KEEP (*(.dtor)); + KEEP (*(SORT_BY_NAME(.dtors.*))); + LONG (0); LONG (0); + KEEP (*(SORT_NONE(.fini))) + /* ??? Why is .gcc_exc here? */ + *(.gcc_exc) + PROVIDE (etext = .); + KEEP (*(.gcc_except_table)) + } + /* The Cygwin32 library uses a section to avoid copying certain data + on fork. This used to be named ".data". The linker used + to include this between __data_start__ and __data_end__, but that + breaks building the cygwin32 dll. Instead, we name the section + ".data_cygwin_nocopy" and explicitly include it after __data_end__. */ + .data BLOCK(__section_alignment__) : + { + __data_start__ = . ; + *(.data) + *(.data2) + *(SORT(.data$*)) + KEEP(*(.jcr)) + __data_end__ = . ; + *(.data_cygwin_nocopy) + } + .rdata BLOCK(__section_alignment__) : + { + *(.rdata) + *(SORT(.rdata$*)) + . = ALIGN(4); + __rt_psrelocs_start = .; + KEEP(*(.rdata_runtime_pseudo_reloc)) + __rt_psrelocs_end = .; + + /* 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 */ + } + __rt_psrelocs_size = __rt_psrelocs_end - __rt_psrelocs_start; + ___RUNTIME_PSEUDO_RELOC_LIST_END__ = .; + __RUNTIME_PSEUDO_RELOC_LIST_END__ = .; + ___RUNTIME_PSEUDO_RELOC_LIST__ = . - __rt_psrelocs_size; + __RUNTIME_PSEUDO_RELOC_LIST__ = . - __rt_psrelocs_size; + .eh_frame BLOCK(__section_alignment__) : + { + KEEP (*(.eh_frame*)) + } + .pdata BLOCK(__section_alignment__) : + { + KEEP(*(.pdata*)) + } + .xdata BLOCK(__section_alignment__) : + { + KEEP(*(.xdata*)) + } + .bss BLOCK(__section_alignment__) : + { + __bss_start__ = . ; + *(.bss) + *(COMMON) + __bss_end__ = . ; + } + .edata BLOCK(__section_alignment__) : + { + *(.edata) + } + /DISCARD/ : + { + *(.debug$S) + *(.debug$T) + *(.debug$F) + *(.drectve) + *(.note.GNU-stack) + *(.gnu.lto_*) + } + .idata BLOCK(__section_alignment__) : + { + /* This cannot currently be handled with grouped sections. + See pep.em:sort_sections. */ + KEEP (SORT(*)(.idata$2)) + KEEP (SORT(*)(.idata$3)) + /* These zeroes mark the end of the import list. */ + LONG (0); LONG (0); LONG (0); LONG (0); LONG (0); + . = ALIGN(8); + KEEP (SORT(*)(.idata$4)) + __IAT_start__ = .; + SORT(*)(.idata$5) + __IAT_end__ = .; + KEEP (SORT(*)(.idata$6)) + KEEP (SORT(*)(.idata$7)) + } + .CRT BLOCK(__section_alignment__) : + { + ___crt_xc_start__ = . ; + KEEP (*(SORT(.CRT$XC*))) /* C initialization */ + ___crt_xc_end__ = . ; + ___crt_xi_start__ = . ; + KEEP (*(SORT(.CRT$XI*))) /* C++ initialization */ + ___crt_xi_end__ = . ; + ___crt_xl_start__ = . ; + KEEP (*(SORT(.CRT$XL*))) /* TLS callbacks */ + /* ___crt_xl_end__ is defined in the TLS Directory support code */ + ___crt_xp_start__ = . ; + KEEP (*(SORT(.CRT$XP*))) /* Pre-termination */ + ___crt_xp_end__ = . ; + ___crt_xt_start__ = . ; + KEEP (*(SORT(.CRT$XT*))) /* Termination */ + ___crt_xt_end__ = . ; + } + /* Windows TLS expects .tls$AAA to be at the start and .tls$ZZZ to be + at the end of the .tls section. This is important because _tls_start MUST + be at the beginning of the section to enable SECREL32 relocations with TLS + data. */ + .tls BLOCK(__section_alignment__) : + { + ___tls_start__ = . ; + KEEP (*(.tls$AAA)) + KEEP (*(.tls)) + KEEP (*(.tls$)) + KEEP (*(SORT(.tls$*))) + KEEP (*(.tls$ZZZ)) + ___tls_end__ = . ; + } + .endjunk BLOCK(__section_alignment__) : + { + /* end is deprecated, don't use it */ + PROVIDE (end = .); + PROVIDE ( _end = .); + __end__ = .; + } + .rsrc BLOCK(__section_alignment__) : SUBALIGN(4) + { + KEEP (*(.rsrc)) + KEEP (*(.rsrc$*)) + } + .reloc BLOCK(__section_alignment__) : + { + *(.reloc) + } + .stab BLOCK(__section_alignment__) (NOLOAD) : + { + *(.stab) + } + .stabstr BLOCK(__section_alignment__) (NOLOAD) : + { + *(.stabstr) + } + /* DWARF debug sections. + Symbols in the DWARF debugging sections are relative to the beginning + of the section. Unlike other targets that fake this by putting the + section VMA at 0, the PE format will not allow it. */ + /* DWARF 1.1 and DWARF 2. */ + .debug_aranges BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_aranges) + } + .zdebug_aranges BLOCK(__section_alignment__) (NOLOAD) : + { + *(.zdebug_aranges) + } + .debug_pubnames BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_pubnames) + } + .zdebug_pubnames BLOCK(__section_alignment__) (NOLOAD) : + { + *(.zdebug_pubnames) + } + /* DWARF 2. */ + .debug_info BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_info .gnu.linkonce.wi.*) + } + .zdebug_info BLOCK(__section_alignment__) (NOLOAD) : + { + *(.zdebug_info .zdebug.gnu.linkonce.wi.*) + } + .debug_abbrev BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_abbrev) + } + .zdebug_abbrev BLOCK(__section_alignment__) (NOLOAD) : + { + *(.zdebug_abbrev) + } + .debug_line BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_line) + } + .zdebug_line BLOCK(__section_alignment__) (NOLOAD) : + { + *(.zdebug_line) + } + .debug_frame BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_frame*) + } + .zdebug_frame BLOCK(__section_alignment__) (NOLOAD) : + { + *(.zdebug_frame*) + } + .debug_str BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_str) + } + .zdebug_str BLOCK(__section_alignment__) (NOLOAD) : + { + *(.zdebug_str) + } + .debug_loc BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_loc) + } + .zdebug_loc BLOCK(__section_alignment__) (NOLOAD) : + { + *(.zdebug_loc) + } + .debug_macinfo BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_macinfo) + } + .zdebug_macinfo BLOCK(__section_alignment__) (NOLOAD) : + { + *(.zdebug_macinfo) + } + /* SGI/MIPS DWARF 2 extensions. */ + .debug_weaknames BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_weaknames) + } + .zdebug_weaknames BLOCK(__section_alignment__) (NOLOAD) : + { + *(.zdebug_weaknames) + } + .debug_funcnames BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_funcnames) + } + .zdebug_funcnames BLOCK(__section_alignment__) (NOLOAD) : + { + *(.zdebug_funcnames) + } + .debug_typenames BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_typenames) + } + .zdebug_typenames BLOCK(__section_alignment__) (NOLOAD) : + { + *(.zdebug_typenames) + } + .debug_varnames BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_varnames) + } + .zdebug_varnames BLOCK(__section_alignment__) (NOLOAD) : + { + *(.zdebug_varnames) + } + /* DWARF 3. */ + .debug_pubtypes BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_pubtypes) + } + .zdebug_pubtypes BLOCK(__section_alignment__) (NOLOAD) : + { + *(.zdebug_pubtypes) + } + .debug_ranges BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_ranges) + } + .zdebug_ranges BLOCK(__section_alignment__) (NOLOAD) : + { + *(.zdebug_ranges) + } + /* DWARF 4. */ + .debug_types BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_types .gnu.linkonce.wt.*) + } + .zdebug_types BLOCK(__section_alignment__) (NOLOAD) : + { + *(.zdebug_types .gnu.linkonce.wt.*) + } + /* DWARF 5. */ + .debug_addr BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_addr) + } + .zdebug_addr BLOCK(__section_alignment__) (NOLOAD) : + { + *(.zdebug_addr) + } + .debug_line_str BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_line_str) + } + .zdebug_line_str BLOCK(__section_alignment__) (NOLOAD) : + { + *(.zdebug_line_str) + } + .debug_loclists BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_loclists) + } + .zdebug_loclists BLOCK(__section_alignment__) (NOLOAD) : + { + *(.zdebug_loclists) + } + .debug_macro BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_macro) + } + .zdebug_macro BLOCK(__section_alignment__) (NOLOAD) : + { + *(.zdebug_macro) + } + .debug_names BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_names) + } + .zdebug_names BLOCK(__section_alignment__) (NOLOAD) : + { + *(.zdebug_names) + } + .debug_rnglists BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_rnglists) + } + .zdebug_rnglists BLOCK(__section_alignment__) (NOLOAD) : + { + *(.zdebug_rnglists) + } + .debug_str_offsets BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_str_offsets) + } + .zdebug_str_offsets BLOCK(__section_alignment__) (NOLOAD) : + { + *(.zdebug_str_offsets) + } + .debug_sup BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_sup) + } + /* For Go and Rust. */ + .debug_gdb_scripts BLOCK(__section_alignment__) (NOLOAD) : + { + *(.debug_gdb_scripts) + } + .zdebug_gdb_scripts BLOCK(__section_alignment__) (NOLOAD) : + { + *(.zdebug_gdb_scripts) + } +} -- 2.40.0.634.g4ca3ef3211-goog