u-boot/arch/x86/config.mk

110 lines
2.6 KiB
Makefile
Raw Normal View History

#
# (C) Copyright 2000-2002
# Wolfgang Denk, DENX Software Engineering, wd@denx.de.
#
# SPDX-License-Identifier: GPL-2.0+
#
CONFIG_STANDALONE_LOAD_ADDR ?= 0x40000
PLATFORM_CPPFLAGS += -fno-strict-aliasing
PLATFORM_CPPFLAGS += -fomit-frame-pointer
PF_CPPFLAGS_X86 := $(call cc-option, -fno-toplevel-reorder, \
$(call cc-option, -fno-unit-at-a-time)) \
$(call cc-option, -mpreferred-stack-boundary=2)
PLATFORM_CPPFLAGS += $(PF_CPPFLAGS_X86)
PLATFORM_CPPFLAGS += -fno-dwarf2-cfi-asm
ifdef CONFIG_SPL_BUILD
IS_32BIT := y
else
ifndef CONFIG_X86_64
IS_32BIT := y
endif
endif
ifeq ($(IS_32BIT),y)
PLATFORM_CPPFLAGS += -march=i386 -m32
else
PLATFORM_CPPFLAGS += $(if $(CONFIG_SPL_BUILD),,-fpic) -fno-common
endif
PLATFORM_RELFLAGS += -ffunction-sections -fvisibility=hidden
PLATFORM_LDFLAGS += -Bsymbolic -Bsymbolic-functions
PLATFORM_LDFLAGS += -m $(if $(IS_32BIT),elf_i386,elf_x86_64)
x86: Wrap small helper functions from libgcc to avoid an ABI mismatch When gcc compiles some 64 bit operations on a 32 bit machine, it generates calls to small functions instead of instructions which do the job directly. Those functions are defined in libgcc and transparently provide whatever functionality was necessary. Unfortunately, u-boot can be built with a non-standard ABI when libgcc isn't. More specifically, u-boot uses -mregparm. When the u-boot and libgcc are linked together, very confusing bugs can crop up, for instance seemingly normal integer division or modulus getting the wrong answer or even raising a spurious divide by zero exception. This change borrows (steals) a technique and some code from coreboot which solves this problem by creating wrappers which translate the calling convention when calling the functions in libgcc. Unfortunately that means that these instructions which had already been turned into functions have even more overhead, but more importantly it makes them work properly. To find all of the functions that needed wrapping, u-boot was compiled without linking in libgcc. All the symbols the linker complained were undefined were presumed to be the symbols that are needed from libgcc. These were a subset of the symbols covered by the coreboot code, so it was used unmodified. To prevent symbols which are provided by libgcc but not currently wrapped (or even known about) from being silently linked against by code generated by libgcc, a new copy of libgcc is created where all the symbols are prefixed with __normal_. Without being purposefully wrapped, these symbols will cause linker errors instead of silently introducing very subtle, confusing bugs. Another approach would be to whitelist symbols from libgcc and strip out all the others. The problem with this approach is that it requires the white listed symbols to be specified three times, once for objcopy, once so the linker inserts the wrapped, and once to generate the wrapper itself, while this implementation needs it to be listed only twice. There isn't much tangible difference in what each approach produces, so this one was preferred. Signed-off-by: Gabe Black <gabeblack@chromium.org>
2011-11-16 23:01:37 +00:00
LDFLAGS_FINAL += --wrap=__divdi3 --wrap=__udivdi3
LDFLAGS_FINAL += --wrap=__moddi3 --wrap=__umoddi3
# This is used in the top-level Makefile which does not include
# PLATFORM_LDFLAGS
LDFLAGS_EFI_PAYLOAD := -Bsymbolic -Bsymbolic-functions -shared --no-undefined
OBJCOPYFLAGS_EFI := -j .text -j .sdata -j .data -j .dynamic -j .dynsym \
-j .rel -j .rela -j .reloc
ifeq ($(IS_32BIT),y)
CFLAGS_NON_EFI := -mregparm=3
endif
CFLAGS_EFI := -fpic -fshort-wchar
ifeq ($(CONFIG_EFI_STUB_64BIT),)
CFLAGS_EFI += $(call cc-option, -mno-red-zone)
EFIARCH = ia32
EFIPAYLOAD_BFDTARGET = elf32-i386
else
EFIARCH = x86_64
EFIPAYLOAD_BFDTARGET = elf64-x86-64
endif
EFIPAYLOAD_BFDARCH = i386
LDSCRIPT_EFI := $(srctree)/arch/x86/lib/elf_$(EFIARCH)_efi.lds
EFISTUB := crt0_$(EFIARCH)_efi.o reloc_$(EFIARCH)_efi.o
OBJCOPYFLAGS_EFI += --target=efi-app-$(EFIARCH)
CPPFLAGS_REMOVE_crt0-efi-$(EFIARCH).o += $(CFLAGS_NON_EFI)
CPPFLAGS_crt0-efi-$(EFIARCH).o += $(CFLAGS_EFI)
ifeq ($(CONFIG_EFI_APP),y)
PLATFORM_CPPFLAGS += $(CFLAGS_EFI)
LDFLAGS_FINAL += -znocombreloc -shared
LDSCRIPT := $(LDSCRIPT_EFI)
else
PLATFORM_CPPFLAGS += $(CFLAGS_NON_EFI)
PLATFORM_LDFLAGS += --emit-relocs
LDFLAGS_FINAL += --gc-sections $(if $(CONFIG_SPL_BUILD),,-pie)
endif
ifdef CONFIG_X86_64
ifndef CONFIG_SPL_BUILD
PLATFORM_CPPFLAGS += -D__x86_64__
else
PLATFORM_CPPFLAGS += -D__I386__
endif
else
PLATFORM_CPPFLAGS += -D__I386__
endif
ifneq ($(CONFIG_EFI_STUB)$(CONFIG_CMD_BOOTEFI_HELLO_COMPILE),)
ifneq ($(CONFIG_EFI_STUB_64BIT),)
EFI_LDS := elf_x86_64_efi.lds
EFI_CRT0 := crt0_x86_64_efi.o
EFI_RELOC := reloc_x86_64_efi.o
EFI_TARGET := --target=efi-app-ia32
else
EFI_LDS := elf_ia32_efi.lds
EFI_CRT0 := crt0_ia32_efi.o
EFI_RELOC := reloc_ia32_efi.o
EFI_TARGET := --target=efi-app-x86_64
endif
endif