[build] Work around -fPIE patched versions of gcc on all architectures

Several distributions include versions of gcc that are patched to
create position-independent executables by default.  These have caused
multiple problems over the years: see e.g. commits fe61f6d ("[build]
Fix compilation when gcc is patched to default to -fPIE -Wl,-pie"),
5de1346 ("[build] Apply the "-fno-PIE -nopie" workaround only to i386
builds"), 7c395b0 ("[build] Use -no-pie on newer versions of gcc"),
and decee20 ("[build] Disable position-independent code for ARM64 EFI
builds").

The build system currently attempts to work around these mildly broken
patched versions of gcc for the i386 and arm64 architectures.  This
misses the relatively obscure bin-x86_64-pcbios build platform, which
turns out to also require the same workaround.

Attempt to preempt the next such required workaround by moving the
existing i386 version to apply to all platforms and all architectures,
unless -fpie has been requested explicitly by another Makefile (as is
done by arch/x86_64/Makefile.efi).

Signed-off-by: Michael Brown <mcb30@ipxe.org>
pull/252/head
Michael Brown 2021-02-04 02:05:28 +00:00
parent bfb72ec234
commit e80299c56b
3 changed files with 27 additions and 20 deletions

View File

@ -374,6 +374,33 @@ INCDIRS += arch/$(ARCH)/include
INCDIRS += arch/$(ARCH)/include/$(PLATFORM) INCDIRS += arch/$(ARCH)/include/$(PLATFORM)
endif endif
###############################################################################
#
# Especially ugly workarounds
# Some widespread patched versions of gcc include -fPIE -Wl,-pie by
# default. Note that gcc will exit *successfully* if it fails to
# recognise an option that starts with "no", so we have to test for
# output on stderr instead of checking the exit status.
#
# Current versions of gcc require -no-pie; older versions require
# -nopie. We therefore test for both.
#
# This workaround must be determined only after the
# architecture-specific Makefile has been included, since some
# platforms (e.g. bin-x86_64-efi) will explicitly require the use of
# -fpie.
#
ifeq ($(filter -fpie,$(CFLAGS)),)
ifeq ($(CCTYPE),gcc)
PIE_TEST = [ -z "`$(CC) -fno-PIE -no-pie -x c -c /dev/null -o /dev/null 2>&1`" ]
PIE_FLAGS := $(shell $(PIE_TEST) && $(ECHO) '-fno-PIE -no-pie')
PIE_TEST2 = [ -z "`$(CC) -fno-PIE -nopie -x c -c /dev/null -o /dev/null 2>&1`" ]
PIE_FLAGS2 := $(shell $(PIE_TEST2) && $(ECHO) '-fno-PIE -nopie')
WORKAROUND_CFLAGS += $(PIE_FLAGS) $(PIE_FLAGS2)
endif
endif
############################################################################### ###############################################################################
# #
# Source file handling # Source file handling

View File

@ -1,9 +1,5 @@
# -*- makefile -*- : Force emacs to use Makefile mode # -*- makefile -*- : Force emacs to use Makefile mode
# Avoid untranslatable relocations
#
CFLAGS += -fno-pic
# Specify EFI image builder # Specify EFI image builder
# #
ELF2EFI = $(ELF2EFI64) ELF2EFI = $(ELF2EFI64)

View File

@ -69,22 +69,6 @@ CFLAGS += -fshort-wchar
# #
CFLAGS += -Ui386 CFLAGS += -Ui386
# Some widespread patched versions of gcc include -fPIE -Wl,-pie by
# default. Note that gcc will exit *successfully* if it fails to
# recognise an option that starts with "no", so we have to test for
# output on stderr instead of checking the exit status.
#
# Current versions of gcc require -no-pie; older versions require
# -nopie. We therefore test for both.
#
ifeq ($(CCTYPE),gcc)
PIE_TEST = [ -z "`$(CC) -fno-PIE -no-pie -x c -c /dev/null -o /dev/null 2>&1`" ]
PIE_FLAGS := $(shell $(PIE_TEST) && $(ECHO) '-fno-PIE -no-pie')
PIE_TEST2 = [ -z "`$(CC) -fno-PIE -nopie -x c -c /dev/null -o /dev/null 2>&1`" ]
PIE_FLAGS2 := $(shell $(PIE_TEST2) && $(ECHO) '-fno-PIE -nopie')
WORKAROUND_CFLAGS += $(PIE_FLAGS) $(PIE_FLAGS2)
endif
# i386-specific directories containing source files # i386-specific directories containing source files
# #
SRCDIRS += arch/i386/core SRCDIRS += arch/i386/core