binutils update breaks refind
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
- git clone https://github.com/void-linux/void-packages.git
- cd void-packages
- ./xbps-src -a aarch64 binary-bootstrap
- ./xbps-src -a aarch64 pkg refind
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.
https://wiki.debian.org/SecureBoot#arm64_problems
It may work if we patch -O binary with --target=efi-app-aarch64, :shrug:
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
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.
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-warningsBuilt, 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/
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?