void-linux / void-packages

The Void source packages collection
https://voidlinux.org
Other
2.6k stars 2.16k forks source link

binutils update breaks refind #49170

Open slymattz opened 8 months ago

slymattz commented 8 months ago

Is this a new report?

Yes

System Info

Void 6.1.79_1 x86_64 GenuineIntel uptodate rrFFFFFF

Package(s) Affected

refind-0.14.0.2_2

Does a report exist for this bug with the project's home (upstream) and/or another distro?

https://sourceware.org/bugzilla/show_bug.cgi?id=26206 https://wiki.debian.org/SecureBoot#arm64_problems

Expected behaviour

The package should cross-compile for aarch64.

As noted by @meator on IRC, Makefile for rEFInd mentions the following part which doesn't sound like their confident enough of cross-building: ###########################################################################

#
# GNU-EFI build rules; should work with any CPU architecture and GNU-EFI
# version 3.0u or later, but cross-compiling requires adding odd
# components and is untested....
#
###########################################################################

@sgn maintainer ping

Actual behaviour

The package won't cross-compile for aarch64-glibc. It spits the following error:

/usr/bin/aarch64-linux-gnu-ld -L./../libeg/ -L./../mok/ -L./../EfiLib/ -L./../gzip -T /usr/aarch64-linux-gnu/usr/lib/elf_aarch64_efi.lds -shared -Bsymbolic -nostdlib -L/usr/aarch64-linux-gnu/usr/lib -L/usr/aarch64-linux-gnu/usr/lib /usr/aarch64-linux-gnu/usr/lib/crt0-efi-aarch64.o -defsym=EFI_SUBSYSTEM=0xa apple.o config.o crc32.o driver_support.o gpt.o icns.o install.o launch_efi.o launch_legacy.o lib.o line_edit.o linux.o log.o main.o menu.o mystrings.o pointer.o scan.o screen.o \
      -o refind_aa64.so -leg -lmok -lEfiLib -lgzip -lefi -lgnuefi /usr/lib/gcc/aarch64-linux-gnu/13.2.0/libgcc.a
/usr/bin/aarch64-linux-gnu-objcopy -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel \
           -j .rela -j .rel.* -j .rela.* -j .rel* -j .rela* \
           -j .reloc -O binary refind_aa64.so refind_aa64.efi
/usr/bin/aarch64-linux-gnu-objcopy --set-section-alignment '.sbat=512' --add-section \
              .sbat=./../refind-sbat.csv --adjust-section-vma \
              .sbat+10000000 refind_aa64.efi
/usr/bin/aarch64-linux-gnu-objcopy: refind_aa64.efi: file format not recognized
/usr/bin/aarch64-linux-gnu-objcopy: --change-section-vma .sbat+0x989680 never used
/usr/bin/aarch64-linux-gnu-objcopy: --change-section-lma .sbat+0x989680 never used
make[1]: *** [Makefile:54: refind_aa64.efi] Error 1
make[1]: Leaving directory '/builddir/refind-0.14.0.2/refind'
make: *** [Makefile:89: gnuefi] Error 2
=> ERROR: refind-0.14.0.2_2: do_build: 'make ARCH=${_ARCH} EFIINC=${XBPS_CROSS_BASE}/usr/include/efi GNUEFILIB=${XBPS_CROSS_BASE}/usr/lib EFILIB=${XBPS_CROSS_BASE}/usr/lib EFICRT0=${XBPS_CROSS_BASE}/usr/lib gnuefi fs_gnuefi' exited with 2
=> ERROR:   in do_build() at srcpkgs/refind/template:29
[1]    8370 exit 1     ./xbps-src -a aarch64 pkg refind

It also won't cross-compile for aarch64-musl:

screen.c: In function 'CheckFatalError':
screen.c:387:22: warning: passing argument 1 of 'PoolPrint' from incompatible pointer type [-Wincompatible-pointer-types]
  387 |     Temp = PoolPrint(L"Fatal Error: %s %s", ErrorName, where);
      |                      ^~~~~~~~~~~~~~~~~~~~~
      |                      |
      |                      short unsigned int *
/usr/aarch64-linux-musl/usr/include/efi/efilib.h:564:26: note: expected 'const CHAR16 *' {aka 'const unsigned int *'} but argument is of type 'short unsigned int *'
  564 |     IN CONST CHAR16     *fmt,
screen.c: In function 'CheckError':
screen.c:410:22: warning: passing argument 1 of 'PoolPrint' from incompatible pointer type [-Wincompatible-pointer-types]
  410 |     Temp = PoolPrint(L"Error: %s %s", ErrorName, where);
      |                      ^~~~~~~~~~~~~~~
      |                      |
      |                      short unsigned int *
/usr/aarch64-linux-musl/usr/include/efi/efilib.h:564:26: note: expected 'const CHAR16 *' {aka 'const unsigned int *'} but argument is of type 'short unsigned int *'
  564 |     IN CONST CHAR16     *fmt,
/usr/bin/aarch64-linux-musl-ld -L./../libeg/ -L./../mok/ -L./../EfiLib/ -L./../gzip -T /usr/aarch64-linux-musl/usr/lib/elf_aarch64_efi.lds -shared -Bsymbolic -nostdlib -L/usr/aarch64-linux-musl/usr/lib -L/usr/aarch64-linux-musl/usr/lib /usr/aarch64-linux-musl/usr/lib/crt0-efi-aarch64.o -defsym=EFI_SUBSYSTEM=0xa apple.o config.o crc32.o driver_support.o gpt.o icns.o install.o launch_efi.o launch_legacy.o lib.o line_edit.o linux.o log.o main.o menu.o mystrings.o pointer.o scan.o screen.o \
      -o refind_aa64.so -leg -lmok -lEfiLib -lgzip -lefi -lgnuefi /usr/lib/gcc/aarch64-linux-musl/13.2.0/libgcc.a
/usr/bin/aarch64-linux-musl-objcopy -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel \
           -j .rela -j .rel.* -j .rela.* -j .rel* -j .rela* \
           -j .reloc -O binary refind_aa64.so refind_aa64.efi
/usr/bin/aarch64-linux-musl-objcopy --set-section-alignment '.sbat=512' --add-section \
              .sbat=./../refind-sbat.csv --adjust-section-vma \
              .sbat+10000000 refind_aa64.efi
/usr/bin/aarch64-linux-musl-objcopy: refind_aa64.efi: file format not recognized
/usr/bin/aarch64-linux-musl-objcopy: --change-section-vma .sbat+0x989680 never used
/usr/bin/aarch64-linux-musl-objcopy: --change-section-lma .sbat+0x989680 never used
make[1]: *** [Makefile:54: refind_aa64.efi] Error 1
make[1]: Leaving directory '/builddir/refind-0.14.0.2/refind'
make: *** [Makefile:89: gnuefi] Error 2
=> ERROR: refind-0.14.0.2_2: do_build: 'make ARCH=${_ARCH} EFIINC=${XBPS_CROSS_BASE}/usr/include/efi GNUEFILIB=${XBPS_CROSS_BASE}/usr/lib EFILIB=${XBPS_CROSS_BASE}/usr/lib EFICRT0=${XBPS_CROSS_BASE}/usr/lib gnuefi fs_gnuefi' exited with 2
=> ERROR:   in do_build() at srcpkgs/refind/template:29
[1]    9222 exit 1     ./xbps-src -a aarch64-musl pkg refind

Steps to reproduce

  1. git clone https://github.com/void-linux/void-packages.git
  2. cd void-packages
  3. ./xbps-src -a aarch64 binary-bootstrap
  4. ./xbps-src -a aarch64 pkg refind
sgn commented 8 months ago

It's not about cross.

It's about objcopy not knowing how to deal with EFI format on arm64 in the past. On arm64, objcopy uses -O binary, unlike the specific --target=efi-app-x86_64 for amd64.

Update to binutils breaks refind build.

sgn commented 8 months ago

https://wiki.debian.org/SecureBoot#arm64_problems

sgn commented 8 months ago

It may work if we patch -O binary with --target=efi-app-aarch64, :shrug:

sgn commented 8 months ago
Index: refind-0.14.0.2/Make.common
===================================================================
--- refind-0.14.0.2.orig/Make.common
+++ refind-0.14.0.2/Make.common
@@ -140,8 +140,6 @@ endif

 ifeq ($(ARCH), aarch64)
   GNUEFI_CFLAGS += -DEFIAARCH64
-  FORMAT          = -O binary
-  FORMAT_DRIVER   = -O binary
   SUBSYSTEM_LDFLAG = -defsym=EFI_SUBSYSTEM=0xa
   LDFLAGS         += --warn-common --no-undefined --fatal-warnings

Built, not tested in anyway

slymattz commented 8 months ago

For me, the below patch works (I combined https://github.com/void-linux/void-packages/blob/master/srcpkgs/refind/patches/add-cross-compile-support.patch and your proposed changes)

fix_aarch64.patch

--- a/Make.common
+++ b/Make.common
@@ -40,21 +40,13 @@
 # Note: TIANOBASE is defined in master Makefile and exported
 GENFW           = $(TIANOBASE)/BaseTools/Source/C/bin/GenFw
 prefix          = /usr/bin/
-ifeq ($(ARCH),aarch64)
-  CC            = $(prefix)aarch64-linux-gnu-gcc
-  AS            = $(prefix)aarch64-linux-gnu-as
-  LD            = $(prefix)aarch64-linux-gnu-ld
-  AR            = $(prefix)aarch64-linux-gnu-ar
-  RANLIB        = $(prefix)aarch64-linux-gnu-ranlib
-  OBJCOPY       = $(prefix)aarch64-linux-gnu-objcopy
-else
-  CC            = $(prefix)gcc
-  AS            = $(prefix)as
-  LD            = $(prefix)ld
-  AR            = $(prefix)ar
-  RANLIB        = $(prefix)ranlib
-  OBJCOPY       = $(prefix)objcopy
-endif
+
+CC            = $(prefix)$(CROSS_COMPILE)gcc
+AS            = $(prefix)$(CROSS_COMPILE)as
+LD            = $(prefix)$(CROSS_COMPILE)ld
+AR            = $(prefix)$(CROSS_COMPILE)ar
+RANLIB        = $(prefix)$(CROSS_COMPILE)ranlib
+OBJCOPY       = $(prefix)$(CROSS_COMPILE)objcopy

 ifeq ($(MAKEWITH),TIANO)
 # Below file defines TARGET (RELEASE or DEBUG) and TOOL_CHAIN_TAG (GCC44, GCC45, GCC46, or GCC47)
@@ -148,8 +140,8 @@

 ifeq ($(ARCH), aarch64)
   GNUEFI_CFLAGS += -DEFIAARCH64
-  FORMAT          = -O binary
-  FORMAT_DRIVER   = -O binary
+  FORMAT          = --target=efi-app-aarch64
+  FORMAT_DRIVER   = --target=efi-app-aarch64
   SUBSYSTEM_LDFLAG = -defsym=EFI_SUBSYSTEM=0xa
   LDFLAGS         += --warn-common --no-undefined --fatal-warnings

It builds on my system. However, I have no way of checking whether it works natively.

slymattz commented 8 months ago
Index: refind-0.14.0.2/Make.common
===================================================================
--- refind-0.14.0.2.orig/Make.common
+++ refind-0.14.0.2/Make.common
@@ -140,8 +140,6 @@ endif

 ifeq ($(ARCH), aarch64)
   GNUEFI_CFLAGS += -DEFIAARCH64
-  FORMAT          = -O binary
-  FORMAT_DRIVER   = -O binary
   SUBSYSTEM_LDFLAG = -defsym=EFI_SUBSYSTEM=0xa
   LDFLAGS         += --warn-common --no-undefined --fatal-warnings

Built, not tested in anyway

Just wanted to confirm that removing these two lines also enables refind to build successfully for aarch64-glibc and aarch64-musl.

BTW, let me post a link to your patch upstream, just for the record: https://sourceforge.net/p/refind/discussion/general/thread/3ca1db9256/

slymattz commented 8 months ago

Let me recap this bug report. Context: https://lists.gnu.org/archive/html/info-gnu/2022-02/msg00009.html GNU Binutils 2.38

    * Support for efi-app-aarch64, efi-rtdrv-aarch64 and
      efi-bsdrv-aarch64 has been added to objcopy in order to enable
      UEFI development using binutils. 

Solution by @sgn (see @@ -148,8 +140,10 @@): https://github.com/void-linux/void-packages/blob/8f60d7410c76cd192636349b19231eb07a082e4c/srcpkgs/refind/patches/add-cross-compile-support-and-fix-binutils-aarch64.patch

Successful workflow aarch64 builds after applying the patch:

/usr/bin/aarch64-linux-gnu-objcopy -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel \
           -j .rela -j .rel.* -j .rela.* -j .rel* -j .rela* \
       -j .reloc --target=efi-app-aarch64 refind_aa64.so refind_aa64.efi
/usr/bin/aarch64-linux-musl-objcopy -j .text -j .sdata -j .data -j .dynamic -j .dynsym -j .rel \
           -j .rela -j .rel.* -j .rela.* -j .rel* -j .rela* \
       -j .reloc --target=efi-app-aarch64 refind_aa64.so refind_aa64.efi

Do we need native aarch64 testing or would you consider this bug resolved?