diff --git a/Kbuild b/Kbuild index 1eac091594..bf52e54051 100644 --- a/Kbuild +++ b/Kbuild @@ -10,6 +10,8 @@ generic-offsets-file := include/generated/generic-asm-offsets.h always := $(generic-offsets-file) targets := lib/asm-offsets.s +CFLAGS_REMOVE_asm-offsets.o := $(LTO_CFLAGS) + $(obj)/$(generic-offsets-file): $(obj)/lib/asm-offsets.s FORCE $(call filechk,offsets,__GENERIC_ASM_OFFSETS_H__) diff --git a/Kconfig b/Kconfig index 86f0a39bb0..f8c1a77bed 100644 --- a/Kconfig +++ b/Kconfig @@ -85,6 +85,30 @@ config SPL_OPTIMIZE_INLINING do what it thinks is best, which is desirable in some cases for size reasons. +config ARCH_SUPPORTS_LTO + bool + +config LTO + bool "Enable Link Time Optimizations" + depends on ARCH_SUPPORTS_LTO + default n + help + This option enables Link Time Optimization (LTO), a mechanism which + allows the compiler to optimize between different compilation units. + + This can optimize away dead code paths, resulting in smaller binary + size (if CC_OPTIMIZE_FOR_SIZE is enabled). + + This option is not available for every architecture and may + introduce bugs. + + Currently, when compiling with GCC, due to a weird bug regarding + jobserver, the final linking will not respect make's --jobs argument. + Instead all available processors will be used (as reported by the + nproc command). + + If unsure, say n. + config TPL_OPTIMIZE_INLINING bool "Allow compiler to uninline functions marked 'inline' in TPL" depends on TPL diff --git a/Makefile b/Makefile index 9615f8b3a0..a038c6d6b6 100644 --- a/Makefile +++ b/Makefile @@ -676,6 +676,31 @@ else KBUILD_CFLAGS += -O2 endif +LTO_CFLAGS := +LTO_FINAL_LDFLAGS := +export LTO_CFLAGS LTO_FINAL_LDFLAGS +ifdef CONFIG_LTO + ifeq ($(cc-name),clang) + LTO_CFLAGS += -flto + LTO_FINAL_LDFLAGS += -flto + + AR = $(shell $(CC) -print-prog-name=llvm-ar) + NM = $(shell $(CC) -print-prog-name=llvm-nm) + else + NPROC := $(shell nproc 2>/dev/null || echo 1) + LTO_CFLAGS += -flto=$(NPROC) + LTO_FINAL_LDFLAGS += -fuse-linker-plugin -flto=$(NPROC) + + # use plugin aware tools + AR = $(CROSS_COMPILE)gcc-ar + NM = $(CROSS_COMPILE)gcc-nm + endif + + CFLAGS_NON_EFI += $(LTO_CFLAGS) + + KBUILD_CFLAGS += $(LTO_CFLAGS) +endif + ifeq ($(CONFIG_STACKPROTECTOR),y) KBUILD_CFLAGS += $(call cc-option,-fstack-protector-strong) CFLAGS_EFI += $(call cc-option,-fno-stack-protector) @@ -972,6 +997,8 @@ LDFLAGS_u-boot += $(LDFLAGS_FINAL) # Avoid 'Not enough room for program headers' error on binutils 2.28 onwards. LDFLAGS_u-boot += $(call ld-option, --no-dynamic-linker) +LDFLAGS_u-boot += --build-id=none + ifeq ($(CONFIG_ARC)$(CONFIG_NIOS2)$(CONFIG_X86)$(CONFIG_XTENSA),) LDFLAGS_u-boot += -Ttext $(CONFIG_SYS_TEXT_BASE) endif @@ -1708,14 +1735,54 @@ u-boot-swap.bin: u-boot.bin FORCE ARCH_POSTLINK := $(wildcard $(srctree)/arch/$(ARCH)/Makefile.postlink) +# Generate linker list symbols references to force compiler to not optimize +# them away when compiling with LTO +ifdef CONFIG_LTO +u-boot-keep-syms-lto := keep-syms-lto.o +u-boot-keep-syms-lto_c := $(patsubst %.o,%.c,$(u-boot-keep-syms-lto)) + +quiet_cmd_keep_syms_lto = KSL $@ + cmd_keep_syms_lto = \ + NM=$(NM) $(srctree)/scripts/gen_ll_addressable_symbols.sh $^ >$@ + +quiet_cmd_keep_syms_lto_cc = KSLCC $@ + cmd_keep_syms_lto_cc = \ + $(CC) $(filter-out $(LTO_CFLAGS),$(c_flags)) -c -o $@ $< + +$(u-boot-keep-syms-lto_c): $(u-boot-main) + $(call if_changed,keep_syms_lto) +$(u-boot-keep-syms-lto): $(u-boot-keep-syms-lto_c) + $(call if_changed,keep_syms_lto_cc) +else +u-boot-keep-syms-lto := +endif + # Rule to link u-boot # May be overridden by arch/$(ARCH)/config.mk +ifdef CONFIG_LTO +quiet_cmd_u-boot__ ?= LTO $@ + cmd_u-boot__ ?= \ + $(CC) -nostdlib -nostartfiles \ + $(LTO_FINAL_LDFLAGS) $(c_flags) \ + $(KBUILD_LDFLAGS:%=-Wl,%) $(LDFLAGS_u-boot:%=-Wl,%) -o $@ \ + -T u-boot.lds $(u-boot-init) \ + -Wl,--whole-archive \ + $(u-boot-main) \ + $(u-boot-keep-syms-lto) \ + $(PLATFORM_LIBS) \ + -Wl,--no-whole-archive \ + -Wl,-Map,u-boot.map; \ + $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true) +else quiet_cmd_u-boot__ ?= LD $@ - cmd_u-boot__ ?= $(LD) $(KBUILD_LDFLAGS) $(LDFLAGS_u-boot) -o $@ \ - -T u-boot.lds $(u-boot-init) \ - --start-group $(u-boot-main) --end-group \ - $(PLATFORM_LIBS) -Map u-boot.map; \ - $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true) + cmd_u-boot__ ?= $(LD) $(KBUILD_LDFLAGS) $(LDFLAGS_u-boot) -o $@ \ + -T u-boot.lds $(u-boot-init) \ + --whole-archive \ + $(u-boot-main) \ + --no-whole-archive \ + $(PLATFORM_LIBS) -Map u-boot.map; \ + $(if $(ARCH_POSTLINK), $(MAKE) -f $(ARCH_POSTLINK) $@, true) +endif quiet_cmd_smap = GEN common/system_map.o cmd_smap = \ @@ -1724,7 +1791,7 @@ cmd_smap = \ $(CC) $(c_flags) -DSYSTEM_MAP="\"$${smap}\"" \ -c $(srctree)/common/system_map.c -o common/system_map.o -u-boot: $(u-boot-init) $(u-boot-main) u-boot.lds FORCE +u-boot: $(u-boot-init) $(u-boot-main) $(u-boot-keep-syms-lto) u-boot.lds FORCE +$(call if_changed,u-boot__) ifeq ($(CONFIG_KALLSYMS),y) $(call cmd,smap) @@ -2007,7 +2074,7 @@ CLEAN_FILES += include/bmp_logo.h include/bmp_logo_data.h tools/version.h \ boot* u-boot* MLO* SPL System.map fit-dtb.blob* \ u-boot-ivt.img.log u-boot-dtb.imx.log SPL.log u-boot.imx.log \ lpc32xx-* bl31.c bl31.elf bl31_*.bin image.map tispl.bin* \ - idbloader.img flash.bin flash.log defconfig + idbloader.img flash.bin flash.log defconfig keep-syms-lto.c # Directories & files removed with 'make mrproper' MRPROPER_DIRS += include/config include/generated spl tpl \ diff --git a/arch/Kconfig b/arch/Kconfig index 6c4b81a486..49813a4c9b 100644 --- a/arch/Kconfig +++ b/arch/Kconfig @@ -33,6 +33,7 @@ config ARC config ARM bool "ARM architecture" + select ARCH_SUPPORTS_LTO select CREATE_ARCH_SYMLINK select HAVE_PRIVATE_LIBGCC if !ARM64 select SUPPORT_OF_CONTROL @@ -101,6 +102,7 @@ config RISCV config SANDBOX bool "Sandbox" + select ARCH_SUPPORTS_LTO select BOARD_LATE_INIT select BZIP2 select CMD_POWEROFF @@ -124,6 +126,7 @@ config SANDBOX select SUPPORT_EXTENSION_SCAN imply BITREVERSE select BLOBLIST + imply LTO imply CMD_DM imply CMD_EXCEPTION imply CMD_GETTIME diff --git a/arch/arm/config.mk b/arch/arm/config.mk index e79f0104b9..16c63e1266 100644 --- a/arch/arm/config.mk +++ b/arch/arm/config.mk @@ -15,9 +15,15 @@ CFLAGS_NON_EFI := -fno-pic -ffixed-r9 -ffunction-sections -fdata-sections \ -fstack-protector-strong CFLAGS_EFI := -fpic -fshort-wchar +ifneq ($(CONFIG_LTO)$(CONFIG_USE_PRIVATE_LIBGCC),yy) LDFLAGS_FINAL += --gc-sections -PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections \ - -fno-common -ffixed-r9 +endif + +ifndef CONFIG_LTO +PLATFORM_RELFLAGS += -ffunction-sections -fdata-sections +endif + +PLATFORM_RELFLAGS += -fno-common -ffixed-r9 PLATFORM_RELFLAGS += $(call cc-option, -msoft-float) \ $(call cc-option,-mshort-load-bytes,$(call cc-option,-malignment-traps,)) diff --git a/arch/arm/cpu/arm926ejs/Makefile b/arch/arm/cpu/arm926ejs/Makefile index af63d5cc5e..98aafe805a 100644 --- a/arch/arm/cpu/arm926ejs/Makefile +++ b/arch/arm/cpu/arm926ejs/Makefile @@ -25,6 +25,8 @@ ifndef CONFIG_HAS_THUMB2 CFLAGS_cpu.o := -marm CFLAGS_cache.o := -marm +CFLAGS_REMOVE_cpu.o := $(LTO_CFLAGS) +CFLAGS_REMOVE_cache.o := $(LTO_CFLAGS) endif endif diff --git a/arch/arm/cpu/arm926ejs/mxs/mxs.c b/arch/arm/cpu/arm926ejs/mxs/mxs.c index 344b9b4e55..4d21e3df76 100644 --- a/arch/arm/cpu/arm926ejs/mxs/mxs.c +++ b/arch/arm/cpu/arm926ejs/mxs/mxs.c @@ -25,6 +25,7 @@ #include #include #include +#include #include DECLARE_GLOBAL_DATA_PTR; @@ -98,7 +99,6 @@ int arch_cpu_init(void) { struct mxs_clkctrl_regs *clkctrl_regs = (struct mxs_clkctrl_regs *)MXS_CLKCTRL_BASE; - extern uint32_t _start; mx28_fixup_vt((uint32_t)&_start); diff --git a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c index a16a15e79d..0a8985b90a 100644 --- a/arch/arm/cpu/arm926ejs/mxs/spl_boot.c +++ b/arch/arm/cpu/arm926ejs/mxs/spl_boot.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include "mxs_init.h" @@ -100,7 +101,6 @@ static void mxs_spl_fixup_vectors(void) * thus this fixup. Our vectoring table is PIC, so copying is * fine. */ - extern uint32_t _start; /* cppcheck-suppress nullPointer */ memcpy(0x0, &_start, 0x60); @@ -122,7 +122,7 @@ void mxs_common_spl_init(const uint32_t arg, const uint32_t *resptr, { struct mxs_spl_data *data = MXS_SPL_DATA; uint8_t bootmode = mxs_get_bootmode_index(); - gd = &gdata; + set_gd(&gdata); mxs_spl_fixup_vectors(); diff --git a/arch/arm/cpu/arm926ejs/spear/spl.c b/arch/arm/cpu/arm926ejs/spear/spl.c index 08b98a2d06..b5b9945a87 100644 --- a/arch/arm/cpu/arm926ejs/spear/spl.c +++ b/arch/arm/cpu/arm926ejs/spear/spl.c @@ -22,7 +22,7 @@ * The BSS cannot be used for this purpose because it will be zeroed after * having stored the pointer, so force the location to the data section. */ -u32 bootrom_stash_sp __attribute__((section(".data"))); +u32 bootrom_stash_sp __section(".data"); static void ddr_clock_init(void) { diff --git a/arch/arm/cpu/armv7/kona-common/clk-stubs.c b/arch/arm/cpu/armv7/kona-common/clk-stubs.c index 2dfa3f7e73..4eddaca887 100644 --- a/arch/arm/cpu/armv7/kona-common/clk-stubs.c +++ b/arch/arm/cpu/armv7/kona-common/clk-stubs.c @@ -14,7 +14,7 @@ int __weak clk_sdio_enable(void *base, u32 rate, u32 *actual_ratep) return 0; } -int __weak clk_bsc_enable(void *base, u32 rate, u32 *actual_ratep) +int __weak clk_bsc_enable(void *base) { return 0; } diff --git a/arch/arm/cpu/armv7/ls102xa/ls102xa_psci.c b/arch/arm/cpu/armv7/ls102xa/ls102xa_psci.c index 4a4b3c6f23..28a7945207 100644 --- a/arch/arm/cpu/armv7/ls102xa/ls102xa_psci.c +++ b/arch/arm/cpu/armv7/ls102xa/ls102xa_psci.c @@ -13,7 +13,7 @@ #include #include "fsl_epu.h" -#define __secure __attribute__((section("._secure.text"))) +#define __secure __section("._secure.text") #define CCSR_GICD_CTLR 0x1000 #define CCSR_GICC_CTLR 0x2000 diff --git a/arch/arm/cpu/armv8/spl_data.c b/arch/arm/cpu/armv8/spl_data.c index 8fd986a67a..8f1231c86e 100644 --- a/arch/arm/cpu/armv8/spl_data.c +++ b/arch/arm/cpu/armv8/spl_data.c @@ -6,8 +6,8 @@ #include #include -char __data_save_start[0] __section(.__data_save_start); -char __data_save_end[0] __section(.__data_save_end); +char __data_save_start[0] __section(".__data_save_start"); +char __data_save_end[0] __section(".__data_save_end"); u32 cold_reboot_flag = 1; diff --git a/arch/arm/cpu/armv8/u-boot-spl.lds b/arch/arm/cpu/armv8/u-boot-spl.lds index 0e67ab09d7..9edb662b09 100644 --- a/arch/arm/cpu/armv8/u-boot-spl.lds +++ b/arch/arm/cpu/armv8/u-boot-spl.lds @@ -77,6 +77,7 @@ SECTIONS KEEP(*(.__bss_end)); } >.sdram + /DISCARD/ : { *(.rela*) } /DISCARD/ : { *(.dynsym) } /DISCARD/ : { *(.dynstr*) } /DISCARD/ : { *(.dynamic*) } diff --git a/arch/arm/include/asm/global_data.h b/arch/arm/include/asm/global_data.h index fba655f3b9..2aff1c467c 100644 --- a/arch/arm/include/asm/global_data.h +++ b/arch/arm/include/asm/global_data.h @@ -91,7 +91,7 @@ struct arch_global_data { #include -#ifdef __clang__ +#if defined(__clang__) || defined(CONFIG_LTO) #define DECLARE_GLOBAL_DATA_PTR #define gd get_gd() @@ -122,8 +122,10 @@ static inline void set_gd(volatile gd_t *gd_ptr) { #ifdef CONFIG_ARM64 __asm__ volatile("ldr x18, %0\n" : : "m"(gd_ptr)); -#else +#elif __ARM_ARCH >= 7 __asm__ volatile("ldr r9, %0\n" : : "m"(gd_ptr)); +#else + __asm__ volatile("mov r9, %0\n" : : "r"(gd_ptr)); #endif } diff --git a/arch/arm/include/asm/secure.h b/arch/arm/include/asm/secure.h index 64e5582c1f..c7b00be8e0 100644 --- a/arch/arm/include/asm/secure.h +++ b/arch/arm/include/asm/secure.h @@ -4,8 +4,8 @@ #include #include -#define __secure __attribute__ ((section ("._secure.text"))) -#define __secure_data __attribute__ ((section ("._secure.data"))) +#define __secure __section("._secure.text") +#define __secure_data __section("._secure.data") #ifndef __ASSEMBLY__ @@ -22,7 +22,7 @@ typedef struct secure_svc_tbl { */ #define DECLARE_SECURE_SVC(_name, _id, _fn) \ static const secure_svc_tbl_t __secure_svc_ ## _name \ - __attribute__((used, section("._secure_svc_tbl_entries"))) \ + __used __section("._secure_svc_tbl_entries") \ = { \ .id = _id, \ .func = _fn } diff --git a/arch/arm/include/asm/setup.h b/arch/arm/include/asm/setup.h index 3a4e902af1..e0e2d7e360 100644 --- a/arch/arm/include/asm/setup.h +++ b/arch/arm/include/asm/setup.h @@ -235,7 +235,7 @@ struct tagtable { int (*parse)(const struct tag *); }; -#define __tag __attribute__((unused, __section__(".taglist"))) +#define __tag __attribute__((unused)) __section(".taglist") #define __tagtable(tag, fn) \ static struct tagtable __tagtable_##fn __tag = { tag, fn } diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 27b12e7f2b..7f66332715 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -45,6 +45,8 @@ obj-$(CONFIG_SEMIHOSTING) += semihosting.o obj-y += bdinfo.o obj-y += sections.o +CFLAGS_REMOVE_sections.o := $(LTO_CFLAGS) + obj-y += stack.o ifdef CONFIG_CPU_V7M obj-y += interrupts_m.o @@ -64,6 +66,7 @@ endif obj-y += cache.o obj-$(CONFIG_SYS_ARM_CACHE_CP15) += cache-cp15.o +CFLAGS_REMOVE_cache-cp15.o := $(LTO_CFLAGS) obj-y += psci-dt.o diff --git a/arch/arm/lib/sections.c b/arch/arm/lib/sections.c index 3bb2d8468c..857879711c 100644 --- a/arch/arm/lib/sections.c +++ b/arch/arm/lib/sections.c @@ -2,6 +2,7 @@ /* * Copyright 2013 Albert ARIBAUD */ +#include /** * These two symbols are declared in a C file so that the linker @@ -18,18 +19,18 @@ * aliasing warnings. */ -char __bss_start[0] __attribute__((section(".__bss_start"))); -char __bss_end[0] __attribute__((section(".__bss_end"))); -char __image_copy_start[0] __attribute__((section(".__image_copy_start"))); -char __image_copy_end[0] __attribute__((section(".__image_copy_end"))); -char __rel_dyn_start[0] __attribute__((section(".__rel_dyn_start"))); -char __rel_dyn_end[0] __attribute__((section(".__rel_dyn_end"))); -char __secure_start[0] __attribute__((section(".__secure_start"))); -char __secure_end[0] __attribute__((section(".__secure_end"))); -char __secure_stack_start[0] __attribute__((section(".__secure_stack_start"))); -char __secure_stack_end[0] __attribute__((section(".__secure_stack_end"))); -char __efi_runtime_start[0] __attribute__((section(".__efi_runtime_start"))); -char __efi_runtime_stop[0] __attribute__((section(".__efi_runtime_stop"))); -char __efi_runtime_rel_start[0] __attribute__((section(".__efi_runtime_rel_start"))); -char __efi_runtime_rel_stop[0] __attribute__((section(".__efi_runtime_rel_stop"))); -char _end[0] __attribute__((section(".__end"))); +char __bss_start[0] __section(".__bss_start"); +char __bss_end[0] __section(".__bss_end"); +char __image_copy_start[0] __section(".__image_copy_start"); +char __image_copy_end[0] __section(".__image_copy_end"); +char __rel_dyn_start[0] __section(".__rel_dyn_start"); +char __rel_dyn_end[0] __section(".__rel_dyn_end"); +char __secure_start[0] __section(".__secure_start"); +char __secure_end[0] __section(".__secure_end"); +char __secure_stack_start[0] __section(".__secure_stack_start"); +char __secure_stack_end[0] __section(".__secure_stack_end"); +char __efi_runtime_start[0] __section(".__efi_runtime_start"); +char __efi_runtime_stop[0] __section(".__efi_runtime_stop"); +char __efi_runtime_rel_start[0] __section(".__efi_runtime_rel_start"); +char __efi_runtime_rel_stop[0] __section(".__efi_runtime_rel_stop"); +char _end[0] __section(".__end"); diff --git a/arch/arm/lib/spl.c b/arch/arm/lib/spl.c index b2b54f28fc..8e2bdf3536 100644 --- a/arch/arm/lib/spl.c +++ b/arch/arm/lib/spl.c @@ -26,7 +26,7 @@ DECLARE_GLOBAL_DATA_PTR; * WARNING: This is going away very soon. Don't use it and don't submit * pafches that rely on it. The global_data area is set up in crt0.S. */ -gd_t gdata __attribute__ ((section(".data"))); +gd_t gdata __section(".data"); #endif /* diff --git a/arch/arm/mach-at91/spl.c b/arch/arm/mach-at91/spl.c index 156150c89c..8d537998c9 100644 --- a/arch/arm/mach-at91/spl.c +++ b/arch/arm/mach-at91/spl.c @@ -26,7 +26,7 @@ void at91_disable_wdt(void) #include struct { u32 r4; -} bootrom_stash __attribute__((section(".data"))); +} bootrom_stash __section(".data"); u32 spl_boot_device(void) { diff --git a/arch/arm/mach-exynos/spl_boot.c b/arch/arm/mach-exynos/spl_boot.c index 27f0dac182..722449881a 100644 --- a/arch/arm/mach-exynos/spl_boot.c +++ b/arch/arm/mach-exynos/spl_boot.c @@ -279,7 +279,7 @@ void memzero(void *s, size_t n) */ static void setup_global_data(gd_t *gdp) { - gd = gdp; + set_gd(gdp); memzero((void *)gd, sizeof(gd_t)); gd->flags |= GD_FLG_RELOC; gd->baudrate = CONFIG_BAUDRATE; diff --git a/arch/arm/mach-imx/imx8m/clock_imx8mm.c b/arch/arm/mach-imx/imx8m/clock_imx8mm.c index 029d06f27f..65d476e037 100644 --- a/arch/arm/mach-imx/imx8m/clock_imx8mm.c +++ b/arch/arm/mach-imx/imx8m/clock_imx8mm.c @@ -846,7 +846,7 @@ int set_clk_eqos(enum enet_freq type) return 0; } -int imx_eqos_txclk_set_rate(u32 rate) +int imx_eqos_txclk_set_rate(ulong rate) { u32 val; u32 eqos_post_div; diff --git a/arch/arm/mach-imx/imx8m/soc.c b/arch/arm/mach-imx/imx8m/soc.c index 36abb2e57f..0c44022a6d 100644 --- a/arch/arm/mach-imx/imx8m/soc.c +++ b/arch/arm/mach-imx/imx8m/soc.c @@ -537,7 +537,7 @@ enum boot_device get_boot_device(void) ret = g_rom_api->query_boot_infor(QUERY_BT_DEV, &boot, ((uintptr_t)&boot) ^ QUERY_BT_DEV); - gd = pgd; + set_gd(pgd); if (ret != ROM_API_OKAY) { puts("ROMAPI: failure at query_boot_info\n"); diff --git a/arch/arm/mach-imx/spl_imx_romapi.c b/arch/arm/mach-imx/spl_imx_romapi.c index 9f4d95982e..d2085dabd3 100644 --- a/arch/arm/mach-imx/spl_imx_romapi.c +++ b/arch/arm/mach-imx/spl_imx_romapi.c @@ -45,7 +45,7 @@ static ulong spl_romapi_read_seekable(struct spl_load_info *load, ret = g_rom_api->download_image(buf, offset, byte, ((uintptr_t)buf) ^ offset ^ byte); - gd = pgd; + set_gd(pgd); if (ret == ROM_API_OKAY) return count; @@ -73,7 +73,7 @@ static int spl_romapi_load_image_seekable(struct spl_image_info *spl_image, ret |= g_rom_api->query_boot_infor(QUERY_IMG_OFF, &image_offset, ((uintptr_t)&image_offset) ^ QUERY_IMG_OFF); - gd = pgd; + set_gd(pgd); if (ret != ROM_API_OKAY) { puts("ROMAPI: Failure query boot infor pagesize/offset\n"); @@ -94,7 +94,7 @@ static int spl_romapi_load_image_seekable(struct spl_image_info *spl_image, size = ALIGN(sizeof(struct image_header), pagesize); ret = g_rom_api->download_image((u8 *)header, offset, size, ((uintptr_t)header) ^ offset ^ size); - gd = pgd; + set_gd(pgd); if (ret != ROM_API_OKAY) { printf("ROMAPI: download failure offset 0x%x size 0x%x\n", @@ -180,7 +180,7 @@ static int spl_romapi_load_image_stream(struct spl_image_info *spl_image, ret = g_rom_api->query_boot_infor(QUERY_PAGE_SZ, &pagesize, ((uintptr_t)&pagesize) ^ QUERY_PAGE_SZ); - gd = pgd; + set_gd(pgd); if (ret != ROM_API_OKAY) puts("failure at query_boot_info\n"); @@ -192,7 +192,7 @@ static int spl_romapi_load_image_stream(struct spl_image_info *spl_image, for (i = 0; i < 640; i++) { ret = g_rom_api->download_image(p, 0, pg, ((uintptr_t)p) ^ pg); - gd = pgd; + set_gd(pgd); if (ret != ROM_API_OKAY) { puts("Steam(USB) download failure\n"); @@ -213,7 +213,7 @@ static int spl_romapi_load_image_stream(struct spl_image_info *spl_image, if (p - pfit < sizeof(struct fdt_header)) { ret = g_rom_api->download_image(p, 0, pg, ((uintptr_t)p) ^ pg); - gd = pgd; + set_gd(pgd); if (ret != ROM_API_OKAY) { puts("Steam(USB) download failure\n"); @@ -237,7 +237,7 @@ static int spl_romapi_load_image_stream(struct spl_image_info *spl_image, ret = g_rom_api->download_image(p, 0, imagesize, ((uintptr_t)p) ^ imagesize); - gd = pgd; + set_gd(pgd); p += imagesize; @@ -280,7 +280,7 @@ int board_return_to_bootrom(struct spl_image_info *spl_image, ret = g_rom_api->query_boot_infor(QUERY_BT_DEV, &boot, ((uintptr_t)&boot) ^ QUERY_BT_DEV); - gd = pgd; + set_gd(pgd); if (ret != ROM_API_OKAY) { puts("ROMAPI: failure at query_boot_info\n"); diff --git a/arch/arm/mach-k3/am642_init.c b/arch/arm/mach-k3/am642_init.c index 885f181d58..a433702b4e 100644 --- a/arch/arm/mach-k3/am642_init.c +++ b/arch/arm/mach-k3/am642_init.c @@ -44,7 +44,7 @@ static void ctrl_mmr_unlock(void) * it to the .data section. */ u32 bootindex __section(".data"); -static struct rom_extended_boot_data bootdata __section(.data); +static struct rom_extended_boot_data bootdata __section(".data"); static void store_boot_info_from_rom(void) { diff --git a/arch/arm/mach-k3/am6_init.c b/arch/arm/mach-k3/am6_init.c index d78d2b8751..425b3f93c8 100644 --- a/arch/arm/mach-k3/am6_init.c +++ b/arch/arm/mach-k3/am6_init.c @@ -77,7 +77,7 @@ static void ctrl_mmr_unlock(void) * but the .bss is cleared between writing and reading this variable, so move * it to the .data section. */ -u32 bootindex __attribute__((section(".data"))); +u32 bootindex __section(".data"); static void store_boot_index_from_rom(void) { diff --git a/arch/arm/mach-k3/j721e_init.c b/arch/arm/mach-k3/j721e_init.c index 1a4f796e5e..76a04a9035 100644 --- a/arch/arm/mach-k3/j721e_init.c +++ b/arch/arm/mach-k3/j721e_init.c @@ -125,8 +125,8 @@ void k3_mmc_restart_clock(void) * but the .bss is cleared between writing and reading this variable, so move * it to the .data section. */ -u32 bootindex __attribute__((section(".data"))); -static struct rom_extended_boot_data bootdata __section(.data); +u32 bootindex __section(".data"); +static struct rom_extended_boot_data bootdata __section(".data"); static void store_boot_info_from_rom(void) { diff --git a/arch/arm/mach-keystone/Makefile b/arch/arm/mach-keystone/Makefile index 3e076e12ec..6c7c25090a 100644 --- a/arch/arm/mach-keystone/Makefile +++ b/arch/arm/mach-keystone/Makefile @@ -9,6 +9,7 @@ obj-y += init.o obj-y += psc.o obj-y += clock.o obj-y += mon.o +CFLAGS_REMOVE_mon.o := $(LTO_CFLAGS) ifndef CONFIG_SPL_BUILD obj-y += cmd_clock.o obj-y += cmd_mon.o diff --git a/arch/arm/mach-mvebu/mbus.c b/arch/arm/mach-mvebu/mbus.c index f29abe5911..3b1b9f73eb 100644 --- a/arch/arm/mach-mvebu/mbus.c +++ b/arch/arm/mach-mvebu/mbus.c @@ -98,9 +98,9 @@ struct mvebu_mbus_soc_data { }; struct mvebu_mbus_state mbus_state - __attribute__ ((section(".data"))); + __section(".data"); static struct mbus_dram_target_info mbus_dram_info - __attribute__ ((section(".data"))); + __section(".data"); /* * Functions to manipulate the address decoding windows diff --git a/arch/arm/mach-mvebu/timer.c b/arch/arm/mach-mvebu/timer.c index 43b3ed15d0..557a378776 100644 --- a/arch/arm/mach-mvebu/timer.c +++ b/arch/arm/mach-mvebu/timer.c @@ -14,7 +14,7 @@ #define TIMER_LOAD_VAL 0xffffffff -static int init_done __attribute__((section(".data"))) = 0; +static int init_done __section(".data") = 0; /* * Timer initialization diff --git a/arch/arm/mach-nexell/clock.c b/arch/arm/mach-nexell/clock.c index a0ba2d8e0c..d5b46a87a1 100644 --- a/arch/arm/mach-nexell/clock.c +++ b/arch/arm/mach-nexell/clock.c @@ -99,7 +99,7 @@ static const char * const clk_core[] = { * in board_init_f(), respectively! I.e. global variables can not be used! */ static struct clk_dev_peri clk_periphs[] - __attribute__((section(".data"))) = { + __section(".data") = { CLK_PERI_1S(DEV_NAME_TIMER, 0, CLK_ID_TIMER_0, PHY_BASEADDR_CLKGEN14, (I_PLL_0_2)), CLK_PERI_1S(DEV_NAME_TIMER, 1, CLK_ID_TIMER_1, @@ -167,7 +167,7 @@ static struct clk_dev_peri clk_periphs[] #define MAX_DIVIDER ((1 << 8) - 1) /* 256, align 2 */ static struct clk_dev st_clk_devs[CLK_DEVS_NUM] - __attribute__((section(".data"))); + __section(".data"); #define clk_dev_get(n) ((struct clk_dev *)&st_clk_devs[n]) #define clk_container(p) (container_of(p, struct clk_dev, clk)) @@ -196,7 +196,7 @@ struct _core_hz_ { * in board_init_f(), respectively! I.e. global variables can not be used! */ /* core clock */ -static struct _core_hz_ core_hz __attribute__((section(".data"))); +static struct _core_hz_ core_hz __section(".data"); #define CORE_HZ_SIZE (sizeof(core_hz) / 4) diff --git a/arch/arm/mach-nexell/timer.c b/arch/arm/mach-nexell/timer.c index fecee67265..3b311fd22a 100644 --- a/arch/arm/mach-nexell/timer.c +++ b/arch/arm/mach-nexell/timer.c @@ -23,9 +23,9 @@ * Section ".data" must be used because BSS is not available before relocation, * in board_init_f(), respectively! I.e. global variables can not be used! */ -static unsigned long timestamp __attribute__ ((section(".data"))); -static unsigned long lastdec __attribute__ ((section(".data"))); -static int timerinit __attribute__ ((section(".data"))); +static unsigned long timestamp __section(".data"); +static unsigned long lastdec __section(".data"); +static int timerinit __section(".data"); /* macro to hw timer tick config */ static long TIMER_FREQ = 1000000; diff --git a/arch/arm/mach-omap2/omap3/Makefile b/arch/arm/mach-omap2/omap3/Makefile index 91ed8ebc9f..151bdf6ebc 100644 --- a/arch/arm/mach-omap2/omap3/Makefile +++ b/arch/arm/mach-omap2/omap3/Makefile @@ -9,6 +9,7 @@ CFLAGS_clock.o += -marm obj-y := lowlevel_init.o obj-y += board.o +CFLAGS_REMOVE_board.o := $(LTO_CFLAGS) obj-y += boot.o obj-y += clock.o obj-y += sys_info.o diff --git a/arch/arm/mach-rockchip/board.c b/arch/arm/mach-rockchip/board.c index c386b52987..5304eb055c 100644 --- a/arch/arm/mach-rockchip/board.c +++ b/arch/arm/mach-rockchip/board.c @@ -139,7 +139,7 @@ static struct dwc3_device dwc3_device_data = { .hsphy_mode = USBPHY_INTERFACE_MODE_UTMIW, }; -int usb_gadget_handle_interrupts(void) +int usb_gadget_handle_interrupts(int index) { dwc3_uboot_handle_interrupt(0); return 0; diff --git a/arch/arm/mach-socfpga/spl_a10.c b/arch/arm/mach-socfpga/spl_a10.c index 92231b5ba3..b5f43f09d1 100644 --- a/arch/arm/mach-socfpga/spl_a10.c +++ b/arch/arm/mach-socfpga/spl_a10.c @@ -40,7 +40,7 @@ DECLARE_GLOBAL_DATA_PTR; SOCFPGA_PHYS_OCRAM_SIZE - \ BOOTROM_SHARED_MEM_SIZE) #define RST_STATUS_SHARED_ADDR (BOOTROM_SHARED_MEM_ADDR + 0x438) -static u32 rst_mgr_status __section(.data); +static u32 rst_mgr_status __section(".data"); /* * Bootrom will clear the status register in reset manager and stores the diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c index 503538e26d..9b84132eda 100644 --- a/arch/arm/mach-sunxi/board.c +++ b/arch/arm/mach-sunxi/board.c @@ -39,7 +39,7 @@ struct fel_stash { uint32_t cr; }; -struct fel_stash fel_stash __attribute__((section(".data"))); +struct fel_stash fel_stash __section(".data"); #ifdef CONFIG_ARM64 #include diff --git a/arch/arm/mach-tegra/board.c b/arch/arm/mach-tegra/board.c index 21852e2388..95d6555a0d 100644 --- a/arch/arm/mach-tegra/board.c +++ b/arch/arm/mach-tegra/board.c @@ -45,7 +45,7 @@ enum { UART_COUNT = 5, }; -static bool from_spl __attribute__ ((section(".data"))); +static bool from_spl __section(".data"); #ifndef CONFIG_SPL_BUILD void save_boot_params(unsigned long r0, unsigned long r1, unsigned long r2, diff --git a/arch/arm/mach-tegra/cboot.c b/arch/arm/mach-tegra/cboot.c index bb46fb23ff..55eb819860 100644 --- a/arch/arm/mach-tegra/cboot.c +++ b/arch/arm/mach-tegra/cboot.c @@ -49,7 +49,7 @@ extern struct mm_region tegra_mem_map[]; */ /* The number of valid entries in ram_banks[] */ -static int ram_bank_count __attribute__((section(".data"))); +static int ram_bank_count __section(".data"); /* * The usable top-of-RAM for U-Boot. This is both: @@ -57,15 +57,15 @@ static int ram_bank_count __attribute__((section(".data"))); * b) At the end of a region that has enough space to hold the relocated U-Boot * and all other allocations made around it (stack, heap, page tables, etc.) */ -static u64 ram_top __attribute__((section(".data"))); +static u64 ram_top __section(".data"); /* The base address of the region of RAM that ends at ram_top */ -static u64 region_base __attribute__((section(".data"))); +static u64 region_base __section(".data"); /* * Explicitly put this in the .data section because it is written before the * .bss section is zeroed out but it needs to persist. */ -unsigned long cboot_boot_x0 __attribute__((section(".data"))); +unsigned long cboot_boot_x0 __section(".data"); void cboot_save_boot_params(unsigned long x0, unsigned long x1, unsigned long x2, unsigned long x3) diff --git a/arch/arm/mach-tegra/tegra20/Makefile b/arch/arm/mach-tegra/tegra20/Makefile index faaf30d068..bb17c90cca 100644 --- a/arch/arm/mach-tegra/tegra20/Makefile +++ b/arch/arm/mach-tegra/tegra20/Makefile @@ -10,6 +10,7 @@ endif # flags for any startup files it might use. CFLAGS_warmboot_avp.o = -march=armv4t -U__LINUX_ARM_ARCH__ \ -D__LINUX_ARM_ARCH__=4 +CFLAGS_REMOVE_warmboot_avp.o := $(LTO_CFLAGS) obj-y += clock.o funcmux.o pinmux.o obj-$(CONFIG_TEGRA_LP0) += warmboot.o crypto.o warmboot_avp.o diff --git a/arch/mips/mach-jz47xx/jz4780/jz4780.c b/arch/mips/mach-jz47xx/jz4780/jz4780.c index 43f5651f83..fefba12873 100644 --- a/arch/mips/mach-jz47xx/jz4780/jz4780.c +++ b/arch/mips/mach-jz47xx/jz4780/jz4780.c @@ -23,7 +23,7 @@ #ifdef CONFIG_SPL_BUILD /* Pointer to the global data structure for SPL */ DECLARE_GLOBAL_DATA_PTR; -gd_t gdata __attribute__ ((section(".bss"))); +gd_t gdata __section(".bss"); void board_init_f(ulong dummy) { diff --git a/arch/nds32/include/asm/setup.h b/arch/nds32/include/asm/setup.h index 8217bbf6fe..a7d52373c6 100644 --- a/arch/nds32/include/asm/setup.h +++ b/arch/nds32/include/asm/setup.h @@ -155,7 +155,7 @@ struct tagtable { #ifdef __KERNEL__ -#define __tag __used __attribute__((__section__(".taglist"))) +#define __tag __used __section(".taglist") #define __tagtable(tag, fn) \ static struct tagtable __tagtable_##fn __tag = { tag, fn } @@ -182,8 +182,8 @@ struct early_params { }; #define __early_param(name, fn) \ -static struct early_params __early_##fn __used \ -__attribute__((__section__("__early_param"))) = { name, fn } +static struct early_params __early_##fn __used \ +__section("__early_param") = { name, fn } #endif #endif diff --git a/arch/powerpc/include/asm/cache.h b/arch/powerpc/include/asm/cache.h index 445a366807..ac8eeb4caa 100644 --- a/arch/powerpc/include/asm/cache.h +++ b/arch/powerpc/include/asm/cache.h @@ -41,8 +41,8 @@ #define __cacheline_aligned __attribute__((__aligned__(L1_CACHE_BYTES))) #else #define __cacheline_aligned \ - __attribute__((__aligned__(L1_CACHE_BYTES), \ - __section__(".data.cacheline_aligned"))) + __attribute__((__aligned__(L1_CACHE_BYTES))) \ + __section(".data.cacheline_aligned") #endif #if defined(__KERNEL__) && !defined(__ASSEMBLY__) diff --git a/arch/riscv/cpu/cpu.c b/arch/riscv/cpu/cpu.c index 296e458db4..c894ac10b5 100644 --- a/arch/riscv/cpu/cpu.c +++ b/arch/riscv/cpu/cpu.c @@ -17,10 +17,10 @@ * before the bss section is available. */ #ifdef CONFIG_OF_PRIOR_STAGE -phys_addr_t prior_stage_fdt_address __attribute__((section(".data"))); +phys_addr_t prior_stage_fdt_address __section(".data"); #endif #ifndef CONFIG_XIP -u32 hart_lottery __attribute__((section(".data"))) = 0; +u32 hart_lottery __section(".data") = 0; /* * The main hart running U-Boot has acquired available_harts_lock until it has diff --git a/arch/sandbox/config.mk b/arch/sandbox/config.mk index 189e9c2b0c..1f8cb61c8b 100644 --- a/arch/sandbox/config.mk +++ b/arch/sandbox/config.mk @@ -17,13 +17,21 @@ PLATFORM_CPPFLAGS += $(shell $(SDL_CONFIG) --cflags) endif cmd_u-boot__ = $(CC) -o $@ -Wl,-T u-boot.lds $(u-boot-init) \ - -Wl,--start-group $(u-boot-main) -Wl,--end-group \ + $(LTO_FINAL_LDFLAGS) \ + -Wl,--whole-archive \ + $(u-boot-main) \ + $(u-boot-keep-syms-lto) \ + -Wl,--no-whole-archive \ $(PLATFORM_LIBS) -Wl,-Map -Wl,u-boot.map cmd_u-boot-spl = (cd $(obj) && $(CC) -o $(SPL_BIN) -Wl,-T u-boot-spl.lds \ + $(LTO_FINAL_LDFLAGS) \ $(patsubst $(obj)/%,%,$(u-boot-spl-init)) \ - -Wl,--start-group $(patsubst $(obj)/%,%,$(u-boot-spl-main)) \ - $(patsubst $(obj)/%,%,$(u-boot-spl-platdata)) -Wl,--end-group \ + -Wl,--whole-archive \ + $(patsubst $(obj)/%,%,$(u-boot-spl-main)) \ + $(patsubst $(obj)/%,%,$(u-boot-spl-platdata)) \ + $(patsubst $(obj)/%,%,$(u-boot-spl-keep-syms-lto)) \ + -Wl,--no-whole-archive \ $(PLATFORM_LIBS) -Wl,-Map -Wl,u-boot-spl.map -Wl,--gc-sections) CONFIG_ARCH_DEVICE_TREE := sandbox diff --git a/arch/sandbox/cpu/os.c b/arch/sandbox/cpu/os.c index b9ad341861..0d21827e1b 100644 --- a/arch/sandbox/cpu/os.c +++ b/arch/sandbox/cpu/os.c @@ -375,7 +375,8 @@ static struct option *long_opts; int os_parse_args(struct sandbox_state *state, int argc, char *argv[]) { - struct sandbox_cmdline_option **sb_opt = __u_boot_sandbox_option_start; + struct sandbox_cmdline_option **sb_opt = + __u_boot_sandbox_option_start(); size_t num_options = __u_boot_sandbox_option_count(); size_t i; diff --git a/arch/sandbox/cpu/start.c b/arch/sandbox/cpu/start.c index e87365e800..63ca514ebd 100644 --- a/arch/sandbox/cpu/start.c +++ b/arch/sandbox/cpu/start.c @@ -58,7 +58,8 @@ static int h_compare_opt(const void *p1, const void *p2) int sandbox_early_getopt_check(void) { struct sandbox_state *state = state_get_current(); - struct sandbox_cmdline_option **sb_opt = __u_boot_sandbox_option_start; + struct sandbox_cmdline_option **sb_opt = + __u_boot_sandbox_option_start(); size_t num_options = __u_boot_sandbox_option_count(); size_t i; int max_arg_len, max_noarg_len; diff --git a/arch/sandbox/cpu/u-boot-spl.lds b/arch/sandbox/cpu/u-boot-spl.lds index 18160436a3..6754f4ef6c 100644 --- a/arch/sandbox/cpu/u-boot-spl.lds +++ b/arch/sandbox/cpu/u-boot-spl.lds @@ -21,9 +21,11 @@ SECTIONS __priv_data_end = .; } - __u_boot_sandbox_option_start = .; - _u_boot_sandbox_getopt : { KEEP(*(.u_boot_sandbox_getopt)) } - __u_boot_sandbox_option_end = .; + _u_boot_sandbox_getopt : { + *(.u_boot_sandbox_getopt_start) + KEEP(*(.u_boot_sandbox_getopt)) + *(.u_boot_sandbox_getopt_end) + } } INSERT AFTER .data; diff --git a/arch/sandbox/cpu/u-boot.lds b/arch/sandbox/cpu/u-boot.lds index a1f509c9ab..6d710618f5 100644 --- a/arch/sandbox/cpu/u-boot.lds +++ b/arch/sandbox/cpu/u-boot.lds @@ -13,9 +13,11 @@ SECTIONS KEEP(*(SORT(.u_boot_list*))); } - __u_boot_sandbox_option_start = .; - _u_boot_sandbox_getopt : { *(.u_boot_sandbox_getopt) } - __u_boot_sandbox_option_end = .; + _u_boot_sandbox_getopt : { + *(.u_boot_sandbox_getopt_start) + *(.u_boot_sandbox_getopt) + *(.u_boot_sandbox_getopt_end) + } .__efi_runtime_start : { *(.__efi_runtime_start) diff --git a/arch/sandbox/include/asm/getopt.h b/arch/sandbox/include/asm/getopt.h index 3048c2cc30..d2145ad6e2 100644 --- a/arch/sandbox/include/asm/getopt.h +++ b/arch/sandbox/include/asm/getopt.h @@ -44,7 +44,7 @@ struct sandbox_cmdline_option { .callback = sandbox_cmdline_cb_##f, \ }; \ /* Ppointer to the struct in a special section for the linker script */ \ - static __attribute__((section(".u_boot_sandbox_getopt"), used)) \ + static __used __section(".u_boot_sandbox_getopt") \ struct sandbox_cmdline_option \ *sandbox_cmdline_option_##f##_ptr = \ &sandbox_cmdline_option_##f diff --git a/arch/sandbox/include/asm/sections.h b/arch/sandbox/include/asm/sections.h index fbc1bd11a3..f4351ae7db 100644 --- a/arch/sandbox/include/asm/sections.h +++ b/arch/sandbox/include/asm/sections.h @@ -13,12 +13,27 @@ struct sandbox_cmdline_option; -extern struct sandbox_cmdline_option *__u_boot_sandbox_option_start[], - *__u_boot_sandbox_option_end[]; +static inline struct sandbox_cmdline_option ** +__u_boot_sandbox_option_start(void) +{ + static char start[0] __aligned(4) __attribute__((unused)) + __section(".u_boot_sandbox_getopt_start"); + + return (struct sandbox_cmdline_option **)&start; +} + +static inline struct sandbox_cmdline_option ** +__u_boot_sandbox_option_end(void) +{ + static char end[0] __aligned(4) __attribute__((unused)) + __section(".u_boot_sandbox_getopt_end"); + + return (struct sandbox_cmdline_option **)&end; +} static inline size_t __u_boot_sandbox_option_count(void) { - return __u_boot_sandbox_option_end - __u_boot_sandbox_option_start; + return __u_boot_sandbox_option_end() - __u_boot_sandbox_option_start(); } #endif diff --git a/arch/sandbox/lib/sections.c b/arch/sandbox/lib/sections.c index 697a8167dd..2559eeea38 100644 --- a/arch/sandbox/lib/sections.c +++ b/arch/sandbox/lib/sections.c @@ -3,10 +3,11 @@ * Copyright 2013 Albert ARIBAUD * */ +#include -char __efi_runtime_start[0] __attribute__((section(".__efi_runtime_start"))); -char __efi_runtime_stop[0] __attribute__((section(".__efi_runtime_stop"))); +char __efi_runtime_start[0] __section(".__efi_runtime_start"); +char __efi_runtime_stop[0] __section(".__efi_runtime_stop"); char __efi_runtime_rel_start[0] - __attribute__((section(".__efi_runtime_rel_start"))); + __section(".__efi_runtime_rel_start"); char __efi_runtime_rel_stop[0] - __attribute__((section(".__efi_runtime_rel_stop"))); + __section(".__efi_runtime_rel_stop"); diff --git a/arch/x86/cpu/coreboot/timestamp.c b/arch/x86/cpu/coreboot/timestamp.c index 7f133cefae..3ad611a530 100644 --- a/arch/x86/cpu/coreboot/timestamp.c +++ b/arch/x86/cpu/coreboot/timestamp.c @@ -11,7 +11,7 @@ #include #include -static struct timestamp_table *ts_table __attribute__((section(".data"))); +static struct timestamp_table *ts_table __section(".data"); void timestamp_init(void) { diff --git a/arch/x86/lib/coreboot/cb_sysinfo.c b/arch/x86/lib/coreboot/cb_sysinfo.c index e2c65bfb1e..748fa4ee53 100644 --- a/arch/x86/lib/coreboot/cb_sysinfo.c +++ b/arch/x86/lib/coreboot/cb_sysinfo.c @@ -21,7 +21,7 @@ DECLARE_GLOBAL_DATA_PTR; * with zeroes when transitioning from "ROM", which is really RAM, to other * RAM. */ -struct sysinfo_t lib_sysinfo __attribute__((section(".data"))); +struct sysinfo_t lib_sysinfo __section(".data"); /* * Some of this is x86 specific, and the rest of it is generic. Right now, diff --git a/arch/x86/lib/sections.c b/arch/x86/lib/sections.c index 8d1700776d..375029ead0 100644 --- a/arch/x86/lib/sections.c +++ b/arch/x86/lib/sections.c @@ -2,10 +2,11 @@ /* * Copyright 2013 Albert ARIBAUD */ +#include -char __efi_runtime_start[0] __attribute__((section(".__efi_runtime_start"))); -char __efi_runtime_stop[0] __attribute__((section(".__efi_runtime_stop"))); +char __efi_runtime_start[0] __section(".__efi_runtime_start"); +char __efi_runtime_stop[0] __section(".__efi_runtime_stop"); char __efi_runtime_rel_start[0] - __attribute__((section(".__efi_runtime_rel_start"))); + __section(".__efi_runtime_rel_start"); char __efi_runtime_rel_stop[0] - __attribute__((section(".__efi_runtime_rel_stop"))); + __section(".__efi_runtime_rel_stop"); diff --git a/arch/xtensa/cpu/cpu.c b/arch/xtensa/cpu/cpu.c index 85d3464607..a09e103fc1 100644 --- a/arch/xtensa/cpu/cpu.c +++ b/arch/xtensa/cpu/cpu.c @@ -20,7 +20,7 @@ DECLARE_GLOBAL_DATA_PTR; -gd_t *gd __attribute__((section(".data"))); +gd_t *gd __section(".data"); #if defined(CONFIG_DISPLAY_CPUINFO) /* diff --git a/board/bosch/shc/board.c b/board/bosch/shc/board.c index e893781887..86356e3875 100644 --- a/board/bosch/shc/board.c +++ b/board/bosch/shc/board.c @@ -45,7 +45,7 @@ DECLARE_GLOBAL_DATA_PTR; -static struct shc_eeprom __attribute__((section(".data"))) header; +static struct shc_eeprom __section(".data") header; static int shc_eeprom_valid; /* diff --git a/board/broadcom/bcmstb/bcmstb.c b/board/broadcom/bcmstb/bcmstb.c index ee0a341077..076ac94144 100644 --- a/board/broadcom/bcmstb/bcmstb.c +++ b/board/broadcom/bcmstb/bcmstb.c @@ -22,7 +22,7 @@ DECLARE_GLOBAL_DATA_PTR; -#define BCMSTB_DATA_SECTION __attribute__((section(".data"))) +#define BCMSTB_DATA_SECTION __section(".data") struct bcmstb_boot_parameters bcmstb_boot_parameters BCMSTB_DATA_SECTION; diff --git a/board/samsung/arndale/arndale_spl.c b/board/samsung/arndale/arndale_spl.c index baa5048335..6ad0273e04 100644 --- a/board/samsung/arndale/arndale_spl.c +++ b/board/samsung/arndale/arndale_spl.c @@ -10,7 +10,7 @@ /* Parameters of early board initialization in SPL */ static struct spl_machine_param machine_param - __attribute__((section(".machine_param"))) = { + __section(".machine_param") = { .signature = SIGNATURE, .version = 1, .params = "vmubfasirM", diff --git a/board/samsung/common/exynos5-dt.c b/board/samsung/common/exynos5-dt.c index 4463cdcb87..1318ea716a 100644 --- a/board/samsung/common/exynos5-dt.c +++ b/board/samsung/common/exynos5-dt.c @@ -126,7 +126,7 @@ static struct dwc3_device dwc3_device_data = { .index = 0, }; -int usb_gadget_handle_interrupts(void) +int usb_gadget_handle_interrupts(int index) { dwc3_uboot_handle_interrupt(0); return 0; diff --git a/board/samsung/smdk5250/smdk5250_spl.c b/board/samsung/smdk5250/smdk5250_spl.c index eb25dfc0a0..b0ef34dd6a 100644 --- a/board/samsung/smdk5250/smdk5250_spl.c +++ b/board/samsung/smdk5250/smdk5250_spl.c @@ -12,7 +12,7 @@ /* Parameters of early board initialization in SPL */ static struct spl_machine_param machine_param - __attribute__((section(".machine_param"))) = { + __section(".machine_param") = { .signature = SIGNATURE, .version = 1, .params = "vmubfasirM", diff --git a/board/samsung/smdk5420/smdk5420_spl.c b/board/samsung/smdk5420/smdk5420_spl.c index 72748ec089..84126f5608 100644 --- a/board/samsung/smdk5420/smdk5420_spl.c +++ b/board/samsung/smdk5420/smdk5420_spl.c @@ -12,7 +12,7 @@ /* Parameters of early board initialization in SPL */ static struct spl_machine_param machine_param - __attribute__((section(".machine_param"))) = { + __section(".machine_param") = { .signature = SIGNATURE, .version = 1, .params = "vmubfasirM", diff --git a/board/siemens/draco/board.c b/board/siemens/draco/board.c index b512bdbfab..01fdfb5cb4 100644 --- a/board/siemens/draco/board.c +++ b/board/siemens/draco/board.c @@ -41,7 +41,7 @@ #include #ifdef CONFIG_SPL_BUILD -static struct draco_baseboard_id __attribute__((section(".data"))) settings; +static struct draco_baseboard_id __section(".data") settings; #if DDR_PLL_FREQ == 303 #if !defined(CONFIG_TARGET_ETAMIN) diff --git a/board/xilinx/common/fru_ops.c b/board/xilinx/common/fru_ops.c index 44f0913f2e..6ed63bb7ee 100644 --- a/board/xilinx/common/fru_ops.c +++ b/board/xilinx/common/fru_ops.c @@ -14,7 +14,7 @@ #include "fru.h" -struct fru_table fru_data __section(.data); +struct fru_table fru_data __section(".data"); static u16 fru_cal_area_len(u8 len) { diff --git a/cmd/stackprot_test.c b/cmd/stackprot_test.c index 36f5bac8d2..1e26193e88 100644 --- a/cmd/stackprot_test.c +++ b/cmd/stackprot_test.c @@ -9,9 +9,16 @@ static int do_test_stackprot_fail(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[]) { + /* + * In order to avoid having the compiler optimize away the stack smashing + * we need to do a little something here. + */ char a[128]; memset(a, 0xa5, 512); + + printf("We have smashed our stack as this should not exceed 128: sizeof(a) = %ld\n", strlen(a)); + return 0; } diff --git a/configs/am3517_evm_defconfig b/configs/am3517_evm_defconfig index bae0e0af35..d61eec94a4 100644 --- a/configs/am3517_evm_defconfig +++ b/configs/am3517_evm_defconfig @@ -1,3 +1,4 @@ +CONFIG_LTO=y CONFIG_ARM=y # CONFIG_SPL_USE_ARCH_MEMCPY is not set # CONFIG_SPL_USE_ARCH_MEMSET is not set diff --git a/configs/da850evm_defconfig b/configs/da850evm_defconfig index cbb7bcf0b6..8b93f33552 100644 --- a/configs/da850evm_defconfig +++ b/configs/da850evm_defconfig @@ -1,3 +1,4 @@ +CONFIG_LTO=y CONFIG_ARM=y CONFIG_SYS_THUMB_BUILD=y CONFIG_ARCH_DAVINCI=y diff --git a/configs/da850evm_direct_nor_defconfig b/configs/da850evm_direct_nor_defconfig index 4ea41ca005..2610a82f7a 100644 --- a/configs/da850evm_direct_nor_defconfig +++ b/configs/da850evm_direct_nor_defconfig @@ -1,3 +1,4 @@ +CONFIG_LTO=y CONFIG_ARM=y CONFIG_ARCH_CPU_INIT=y CONFIG_ARCH_DAVINCI=y diff --git a/configs/da850evm_nand_defconfig b/configs/da850evm_nand_defconfig index 9a86e57334..b347c01283 100644 --- a/configs/da850evm_nand_defconfig +++ b/configs/da850evm_nand_defconfig @@ -1,3 +1,4 @@ +CONFIG_LTO=y CONFIG_ARM=y CONFIG_SYS_THUMB_BUILD=y CONFIG_ARCH_DAVINCI=y diff --git a/configs/imx6q_logic_defconfig b/configs/imx6q_logic_defconfig index 36dc24d080..0f8aea6983 100644 --- a/configs/imx6q_logic_defconfig +++ b/configs/imx6q_logic_defconfig @@ -1,3 +1,4 @@ +CONFIG_LTO=y CONFIG_ARM=y CONFIG_ARCH_MX6=y CONFIG_SYS_TEXT_BASE=0x17800000 diff --git a/configs/imx8mm_beacon_defconfig b/configs/imx8mm_beacon_defconfig index 6b26daee5c..6b2dc24b85 100644 --- a/configs/imx8mm_beacon_defconfig +++ b/configs/imx8mm_beacon_defconfig @@ -1,3 +1,4 @@ +CONFIG_LTO=y CONFIG_ARM=y CONFIG_ARCH_IMX8M=y CONFIG_SYS_TEXT_BASE=0x40200000 diff --git a/configs/imx8mm_venice_defconfig b/configs/imx8mm_venice_defconfig index d8228a4b9f..4b0e5d04d8 100644 --- a/configs/imx8mm_venice_defconfig +++ b/configs/imx8mm_venice_defconfig @@ -1,3 +1,4 @@ +CONFIG_LTO=y CONFIG_ARM=y CONFIG_ARCH_IMX8M=y CONFIG_SYS_TEXT_BASE=0x40200000 diff --git a/configs/imx8mn_beacon_2g_defconfig b/configs/imx8mn_beacon_2g_defconfig index c60bebc3ed..cc4c56c422 100644 --- a/configs/imx8mn_beacon_2g_defconfig +++ b/configs/imx8mn_beacon_2g_defconfig @@ -1,3 +1,4 @@ +CONFIG_LTO=y CONFIG_ARM=y CONFIG_ARCH_IMX8M=y CONFIG_SYS_TEXT_BASE=0x40200000 diff --git a/configs/imx8mn_beacon_defconfig b/configs/imx8mn_beacon_defconfig index db904d7735..66fe9d34c0 100644 --- a/configs/imx8mn_beacon_defconfig +++ b/configs/imx8mn_beacon_defconfig @@ -1,3 +1,4 @@ +CONFIG_LTO=y CONFIG_ARM=y CONFIG_ARCH_IMX8M=y CONFIG_SYS_TEXT_BASE=0x40200000 diff --git a/configs/nokia_rx51_defconfig b/configs/nokia_rx51_defconfig index f79613260f..802568aea7 100644 --- a/configs/nokia_rx51_defconfig +++ b/configs/nokia_rx51_defconfig @@ -1,3 +1,4 @@ +CONFIG_LTO=y CONFIG_ARM=y # CONFIG_SYS_THUMB_BUILD is not set CONFIG_ARCH_OMAP2PLUS=y diff --git a/configs/omap3_logic_defconfig b/configs/omap3_logic_defconfig index 12483ffee2..7b17b28e6d 100644 --- a/configs/omap3_logic_defconfig +++ b/configs/omap3_logic_defconfig @@ -1,3 +1,4 @@ +CONFIG_LTO=y CONFIG_ARM=y # CONFIG_SPL_USE_ARCH_MEMCPY is not set # CONFIG_SPL_USE_ARCH_MEMSET is not set diff --git a/configs/r8a774a1_beacon_defconfig b/configs/r8a774a1_beacon_defconfig index 58d3f9f019..8e65654318 100644 --- a/configs/r8a774a1_beacon_defconfig +++ b/configs/r8a774a1_beacon_defconfig @@ -1,3 +1,4 @@ +CONFIG_LTO=y CONFIG_ARM=y CONFIG_ARCH_RMOBILE=y CONFIG_SYS_TEXT_BASE=0x50000000 diff --git a/configs/r8a774b1_beacon_defconfig b/configs/r8a774b1_beacon_defconfig index c0d2d1bf53..37584db185 100644 --- a/configs/r8a774b1_beacon_defconfig +++ b/configs/r8a774b1_beacon_defconfig @@ -1,3 +1,4 @@ +CONFIG_LTO=y CONFIG_ARM=y CONFIG_ARCH_RMOBILE=y CONFIG_SYS_TEXT_BASE=0x50000000 diff --git a/configs/r8a774e1_beacon_defconfig b/configs/r8a774e1_beacon_defconfig index 800c7b8c79..8a65e86380 100644 --- a/configs/r8a774e1_beacon_defconfig +++ b/configs/r8a774e1_beacon_defconfig @@ -1,3 +1,4 @@ +CONFIG_LTO=y CONFIG_ARM=y CONFIG_ARCH_RMOBILE=y CONFIG_SYS_TEXT_BASE=0x50000000 diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 57c4e153ba..d4047c04f5 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c @@ -110,7 +110,7 @@ static int waiting_for_cmd_completed(void __iomem *offset, return (i < timeout_msec) ? 0 : -1; } -int __weak ahci_link_up(struct ahci_uc_priv *uc_priv, u8 port) +int __weak ahci_link_up(struct ahci_uc_priv *uc_priv, int port) { u32 tmp; int j = 0; diff --git a/drivers/bios_emulator/biosemu.c b/drivers/bios_emulator/biosemu.c index 9d4f07c074..82befbae66 100644 --- a/drivers/bios_emulator/biosemu.c +++ b/drivers/bios_emulator/biosemu.c @@ -50,7 +50,7 @@ #include "biosemui.h" BE_sysEnv _BE_env = {{0}}; -static X86EMU_memFuncs _BE_mem __attribute__((section(GOT2_TYPE))) = { +static X86EMU_memFuncs _BE_mem __section(GOT2_TYPE) = { BE_rdb, BE_rdw, BE_rdl, @@ -59,7 +59,7 @@ static X86EMU_memFuncs _BE_mem __attribute__((section(GOT2_TYPE))) = { BE_wrl, }; -static X86EMU_pioFuncs _BE_pio __attribute__((section(GOT2_TYPE))) = { +static X86EMU_pioFuncs _BE_pio __section(GOT2_TYPE) = { BE_inb, BE_inw, BE_inl, diff --git a/drivers/clk/kendryte/clk.c b/drivers/clk/kendryte/clk.c index 2d6ac03693..41c712e03f 100644 --- a/drivers/clk/kendryte/clk.c +++ b/drivers/clk/kendryte/clk.c @@ -347,7 +347,7 @@ static const struct k210_comp_params k210_comps[] = { #undef COMP_NOMUX_ID #undef COMP_LIST -static struct clk *k210_bypass_children __section(.data); +static struct clk *k210_bypass_children __section(".data"); /* Helper functions to create sub-clocks */ static struct clk_mux *k210_create_mux(const struct k210_mux_params *params, @@ -473,7 +473,7 @@ cleanup_mux: return comp; } -static bool __section(.data) probed; +static bool __section(".data") probed; /* reset probed so we will probe again post-relocation */ static int k210_clk_bind(struct udevice *dev) diff --git a/drivers/core/regmap.c b/drivers/core/regmap.c index b51ce108c1..3206f3d112 100644 --- a/drivers/core/regmap.c +++ b/drivers/core/regmap.c @@ -435,7 +435,36 @@ int regmap_raw_read(struct regmap *map, uint offset, void *valp, size_t val_len) int regmap_read(struct regmap *map, uint offset, uint *valp) { - return regmap_raw_read(map, offset, valp, map->width); + union { + u8 v8; + u16 v16; + u32 v32; + u64 v64; + } u; + int res; + + res = regmap_raw_read(map, offset, &u, map->width); + if (res) + return res; + + switch (map->width) { + case REGMAP_SIZE_8: + *valp = u.v8; + break; + case REGMAP_SIZE_16: + *valp = u.v16; + break; + case REGMAP_SIZE_32: + *valp = u.v32; + break; + case REGMAP_SIZE_64: + *valp = u.v64; + break; + default: + unreachable(); + } + + return 0; } static inline void __write_8(u8 *addr, const u8 *val, @@ -546,7 +575,33 @@ int regmap_raw_write(struct regmap *map, uint offset, const void *val, int regmap_write(struct regmap *map, uint offset, uint val) { - return regmap_raw_write(map, offset, &val, map->width); + union { + u8 v8; + u16 v16; + u32 v32; + u64 v64; + } u; + + switch (map->width) { + case REGMAP_SIZE_8: + u.v8 = val; + break; + case REGMAP_SIZE_16: + u.v16 = val; + break; + case REGMAP_SIZE_32: + u.v32 = val; + break; + case REGMAP_SIZE_64: + u.v64 = val; + break; + default: + debug("%s: regmap size %zu unknown\n", __func__, + (size_t)map->width); + return -EINVAL; + } + + return regmap_raw_write(map, offset, &u, map->width); } int regmap_update_bits(struct regmap *map, uint offset, uint mask, uint val) diff --git a/drivers/firmware/psci.c b/drivers/firmware/psci.c index 6755e74e3f..89cb7d88e5 100644 --- a/drivers/firmware/psci.c +++ b/drivers/firmware/psci.c @@ -42,7 +42,7 @@ #if CONFIG_IS_ENABLED(EFI_LOADER) int __efi_runtime_data psci_method; #else -int psci_method __attribute__ ((section(".data"))); +int psci_method __section(".data"); #endif unsigned long __efi_runtime invoke_psci_fn diff --git a/drivers/mtd/nand/raw/mxc_nand_spl.c b/drivers/mtd/nand/raw/mxc_nand_spl.c index e1e542519d..2f054b60ed 100644 --- a/drivers/mtd/nand/raw/mxc_nand_spl.c +++ b/drivers/mtd/nand/raw/mxc_nand_spl.c @@ -326,7 +326,7 @@ int nand_spl_load_image(uint32_t from, unsigned int size, void *buf) * configured and available since this code loads the main U-Boot image * from NAND into SDRAM and starts it from there. */ -void nand_boot(void) +__used void nand_boot(void) { __attribute__((noreturn)) void (*uboot)(void); diff --git a/drivers/pinctrl/nxp/pinctrl-imx5.c b/drivers/pinctrl/nxp/pinctrl-imx5.c index 71e0c94c96..b32b748cfc 100644 --- a/drivers/pinctrl/nxp/pinctrl-imx5.c +++ b/drivers/pinctrl/nxp/pinctrl-imx5.c @@ -10,7 +10,7 @@ #include "pinctrl-imx.h" -static struct imx_pinctrl_soc_info imx5_pinctrl_soc_info __attribute__((section(".data"))); +static struct imx_pinctrl_soc_info imx5_pinctrl_soc_info __section(".data"); static int imx5_pinctrl_probe(struct udevice *dev) { diff --git a/drivers/pinctrl/nxp/pinctrl-imx7.c b/drivers/pinctrl/nxp/pinctrl-imx7.c index 8301413ac7..77ddb8e0b9 100644 --- a/drivers/pinctrl/nxp/pinctrl-imx7.c +++ b/drivers/pinctrl/nxp/pinctrl-imx7.c @@ -9,7 +9,7 @@ #include "pinctrl-imx.h" -static struct imx_pinctrl_soc_info imx7_pinctrl_soc_info __attribute__((section(".data"))); +static struct imx_pinctrl_soc_info imx7_pinctrl_soc_info __section(".data"); static struct imx_pinctrl_soc_info imx7_lpsr_pinctrl_soc_info = { .flags = ZERO_OFFSET_VALID, diff --git a/drivers/pinctrl/nxp/pinctrl-imx8m.c b/drivers/pinctrl/nxp/pinctrl-imx8m.c index 99c6d014d6..6ea66a080b 100644 --- a/drivers/pinctrl/nxp/pinctrl-imx8m.c +++ b/drivers/pinctrl/nxp/pinctrl-imx8m.c @@ -8,7 +8,7 @@ #include "pinctrl-imx.h" -static struct imx_pinctrl_soc_info imx8mq_pinctrl_soc_info __attribute__((section(".data"))); +static struct imx_pinctrl_soc_info imx8mq_pinctrl_soc_info __section(".data"); static int imx8mq_pinctrl_probe(struct udevice *dev) { diff --git a/drivers/power/pmic/pmic_tps62362.c b/drivers/power/pmic/pmic_tps62362.c index 76fd14db59..59190d6f67 100644 --- a/drivers/power/pmic/pmic_tps62362.c +++ b/drivers/power/pmic/pmic_tps62362.c @@ -11,7 +11,7 @@ #include #if CONFIG_IS_ENABLED(DM_I2C) -struct udevice *tps62362_dev __attribute__((section(".data"))) = NULL; +struct udevice *tps62362_dev __section(".data") = NULL; #endif /** diff --git a/drivers/power/pmic/pmic_tps65217.c b/drivers/power/pmic/pmic_tps65217.c index 54b5bed99a..c7f532df4d 100644 --- a/drivers/power/pmic/pmic_tps65217.c +++ b/drivers/power/pmic/pmic_tps65217.c @@ -8,7 +8,7 @@ #include #include -struct udevice *tps65217_dev __attribute__((section(".data"))) = NULL; +struct udevice *tps65217_dev __section(".data") = NULL; /** * tps65217_reg_read() - Generic function that can read a TPS65217 register diff --git a/drivers/power/pmic/pmic_tps65218.c b/drivers/power/pmic/pmic_tps65218.c index f8bae4545c..6717490180 100644 --- a/drivers/power/pmic/pmic_tps65218.c +++ b/drivers/power/pmic/pmic_tps65218.c @@ -86,7 +86,7 @@ int tps65218_reg_write(uchar prot_level, uchar dest_reg, uchar dest_val, return 0; } #else -struct udevice *tps65218_dev __attribute__((section(".data"))) = NULL; +struct udevice *tps65218_dev __section(".data") = NULL; int tps65218_reg_read(uchar dest_reg, uchar *dest_val) { diff --git a/drivers/power/pmic/pmic_tps65910.c b/drivers/power/pmic/pmic_tps65910.c index 84a58c28d8..fcd0a654a8 100644 --- a/drivers/power/pmic/pmic_tps65910.c +++ b/drivers/power/pmic/pmic_tps65910.c @@ -8,7 +8,7 @@ #include #include -struct udevice *tps65910_dev __attribute__((section(".data"))) = NULL; +struct udevice *tps65910_dev __section(".data") = NULL; static inline int tps65910_read_reg(int addr, uchar *buf) { diff --git a/drivers/serial/serial_pl01x.c b/drivers/serial/serial_pl01x.c index 4f9de0da76..5283d5ed11 100644 --- a/drivers/serial/serial_pl01x.c +++ b/drivers/serial/serial_pl01x.c @@ -30,8 +30,8 @@ DECLARE_GLOBAL_DATA_PTR; #ifndef CONFIG_DM_SERIAL static volatile unsigned char *const port[] = CONFIG_PL01x_PORTS; -static enum pl01x_type pl01x_type __attribute__ ((section(".data"))); -static struct pl01x_regs *base_regs __attribute__ ((section(".data"))); +static enum pl01x_type pl01x_type __section(".data"); +static struct pl01x_regs *base_regs __section(".data"); #define NUM_PORTS (sizeof(port)/sizeof(port[0])) #endif diff --git a/include/efi_loader.h b/include/efi_loader.h index de1a496a97..522696d635 100644 --- a/include/efi_loader.h +++ b/include/efi_loader.h @@ -217,8 +217,8 @@ extern const efi_guid_t efi_guid_firmware_management_protocol; /* GUID for the ESRT */ extern const efi_guid_t efi_esrt_guid; -extern unsigned int __efi_runtime_start, __efi_runtime_stop; -extern unsigned int __efi_runtime_rel_start, __efi_runtime_rel_stop; +extern char __efi_runtime_start[], __efi_runtime_stop[]; +extern char __efi_runtime_rel_start[], __efi_runtime_rel_stop[]; /** * struct efi_open_protocol_info_item - open protocol info item @@ -678,12 +678,51 @@ ssize_t efi_dp_check_length(const struct efi_device_path *dp, (((_dp)->type == DEVICE_PATH_TYPE_##_type) && \ ((_dp)->sub_type == DEVICE_PATH_SUB_TYPE_##_subtype)) -/* - * Use these to indicate that your code / data should go into the EFI runtime - * section and thus still be available when the OS is running +/** + * __efi_runtime_data - declares a non-const variable for EFI runtime section + * + * This macro indicates that a variable is non-const and should go into the + * EFI runtime section, and thus still be available when the OS is running. + * + * Only use on variables not declared const. + * + * Example: + * + * :: + * + * static __efi_runtime_data my_computed_table[256]; */ -#define __efi_runtime_data __attribute__ ((section (".data.efi_runtime"))) -#define __efi_runtime __attribute__ ((section (".text.efi_runtime"))) +#define __efi_runtime_data __section(".data.efi_runtime") + +/** + * __efi_runtime_rodata - declares a read-only variable for EFI runtime section + * + * This macro indicates that a variable is read-only (const) and should go into + * the EFI runtime section, and thus still be available when the OS is running. + * + * Only use on variables also declared const. + * + * Example: + * + * :: + * + * static const __efi_runtime_rodata my_const_table[] = { 1, 2, 3 }; + */ +#define __efi_runtime_rodata __section(".rodata.efi_runtime") + +/** + * __efi_runtime - declares a function for EFI runtime section + * + * This macro indicates that a function should go into the EFI runtime section, + * and thus still be available when the OS is running. + * + * Example: + * + * :: + * + * static __efi_runtime compute_my_table(void); + */ +#define __efi_runtime __section(".text.efi_runtime") /* Indicate supported runtime services */ efi_status_t efi_init_runtime_supported(void); @@ -888,6 +927,7 @@ efi_status_t efi_launch_capsules(void); /* Without CONFIG_EFI_LOADER we don't have a runtime section, stub it out */ #define __efi_runtime_data +#define __efi_runtime_rodata #define __efi_runtime static inline efi_status_t efi_add_runtime_mmio(void *mmio_ptr, u64 len) { diff --git a/include/errno.h b/include/errno.h index 3af539b9e9..652ad67306 100644 --- a/include/errno.h +++ b/include/errno.h @@ -8,7 +8,13 @@ #include -extern int errno; +#ifdef __SANDBOX__ +#define __errno_asm_label asm("__u_boot_errno") +#else +#define __errno_asm_label +#endif + +extern int errno __errno_asm_label; #define __set_errno(val) do { errno = val; } while (0) diff --git a/include/linker_lists.h b/include/linker_lists.h index 2fea54c834..0575164ce4 100644 --- a/include/linker_lists.h +++ b/include/linker_lists.h @@ -69,8 +69,8 @@ */ #define ll_entry_declare(_type, _name, _list) \ _type _u_boot_list_2_##_list##_2_##_name __aligned(4) \ - __attribute__((unused, \ - section(".u_boot_list_2_"#_list"_2_"#_name))) + __attribute__((unused)) \ + __section(".u_boot_list_2_"#_list"_2_"#_name) /** * ll_entry_declare_list() - Declare a list of link-generated array entries @@ -92,8 +92,8 @@ */ #define ll_entry_declare_list(_type, _name, _list) \ _type _u_boot_list_2_##_list##_2_##_name[] __aligned(4) \ - __attribute__((unused, \ - section(".u_boot_list_2_"#_list"_2_"#_name))) + __attribute__((unused)) \ + __section(".u_boot_list_2_"#_list"_2_"#_name) /* * We need a 0-byte-size type for iterator symbols, and the compiler @@ -125,8 +125,8 @@ #define ll_entry_start(_type, _list) \ ({ \ static char start[0] __aligned(CONFIG_LINKER_LIST_ALIGN) \ - __attribute__((unused, \ - section(".u_boot_list_2_"#_list"_1"))); \ + __attribute__((unused)) \ + __section(".u_boot_list_2_"#_list"_1"); \ (_type *)&start; \ }) @@ -151,8 +151,8 @@ */ #define ll_entry_end(_type, _list) \ ({ \ - static char end[0] __aligned(4) __attribute__((unused, \ - section(".u_boot_list_2_"#_list"_3"))); \ + static char end[0] __aligned(4) __attribute__((unused)) \ + __section(".u_boot_list_2_"#_list"_3"); \ (_type *)&end; \ }) /** @@ -245,8 +245,8 @@ */ #define ll_start(_type) \ ({ \ - static char start[0] __aligned(4) __attribute__((unused, \ - section(".u_boot_list_1"))); \ + static char start[0] __aligned(4) __attribute__((unused)) \ + __section(".u_boot_list_1"); \ (_type *)&start; \ }) @@ -268,8 +268,8 @@ */ #define ll_end(_type) \ ({ \ - static char end[0] __aligned(4) __attribute__((unused, \ - section(".u_boot_list_3"))); \ + static char end[0] __aligned(4) __attribute__((unused)) \ + __section(".u_boot_list_3"); \ (_type *)&end; \ }) diff --git a/include/linux/compiler.h b/include/linux/compiler.h index 5e3b3c08e9..98dd3fc4cc 100644 --- a/include/linux/compiler.h +++ b/include/linux/compiler.h @@ -24,7 +24,7 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val, long ______r; \ static struct ftrace_likely_data \ __aligned(4) \ - __section(_ftrace_annotated_branch) \ + __section("_ftrace_annotated_branch") \ ______f = { \ .data.func = __func__, \ .data.file = __FILE__, \ @@ -60,7 +60,7 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val, #define __trace_if_value(cond) ({ \ static struct ftrace_branch_data \ __aligned(4) \ - __section(_ftrace_branch) \ + __section("_ftrace_branch") \ __if_trace = { \ .func = __func__, \ .file = __FILE__, \ @@ -118,7 +118,7 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val, ".popsection\n\t" /* Annotate a C jump table to allow objtool to follow the code flow */ -#define __annotate_jump_table __section(.rodata..c_jump_table) +#define __annotate_jump_table __section(".rodata..c_jump_table") #else #define annotate_reachable() @@ -294,8 +294,8 @@ unsigned long read_word_at_a_time(const void *addr) * visible to the compiler. */ #define __ADDRESSABLE(sym) \ - static void * __section(.discard.addressable) __used \ - __PASTE(__addressable_##sym, __LINE__) = (void *)&sym; + static void * __section(".discard.addressable") __used \ + __UNIQUE_ID(__PASTE(__addressable_,sym)) = (void *)&sym; /** * offset_to_ptr - convert a relative memory offset to an absolute pointer diff --git a/include/linux/compiler_attributes.h b/include/linux/compiler_attributes.h index cdf0165966..44c9a08d73 100644 --- a/include/linux/compiler_attributes.h +++ b/include/linux/compiler_attributes.h @@ -246,7 +246,7 @@ * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-section-variable-attribute * clang: https://clang.llvm.org/docs/AttributeReference.html#section-declspec-allocate */ -#define __section(S) __attribute__((__section__(#S))) +#define __section(S) __attribute__((__section__(S))) /* * gcc: https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-unused-function-attribute diff --git a/lib/crc32.c b/lib/crc32.c index e9be3bf386..f2acc107fe 100644 --- a/lib/crc32.c +++ b/lib/crc32.c @@ -26,6 +26,7 @@ #ifdef USE_HOSTCC #define __efi_runtime #define __efi_runtime_data +#define __efi_runtime_rodata #endif #define tole(x) cpu_to_le32(x) @@ -88,7 +89,7 @@ static void __efi_runtime make_crc_table(void) * Table of CRC-32's of all single-byte values (made by make_crc_table) */ -static const uint32_t __efi_runtime_data crc_table[256] = { +static const uint32_t __efi_runtime_rodata crc_table[256] = { tole(0x00000000L), tole(0x77073096L), tole(0xee0e612cL), tole(0x990951baL), tole(0x076dc419L), tole(0x706af48fL), tole(0xe963a535L), tole(0x9e6495a3L), tole(0x0edb8832L), tole(0x79dcb8a4L), tole(0xe0d5e91eL), tole(0x97d2d988L), diff --git a/lib/efi_selftest/Makefile b/lib/efi_selftest/Makefile index aa71d0995c..9ff6e1760c 100644 --- a/lib/efi_selftest/Makefile +++ b/lib/efi_selftest/Makefile @@ -10,6 +10,8 @@ ccflags-y += -DHOST_ARCH="$(HOST_ARCH)" CFLAGS_dtbdump.o := $(CFLAGS_EFI) -Os -ffreestanding CFLAGS_REMOVE_dtbdump.o := $(CFLAGS_NON_EFI) +CFLAGS_efi_selftest_miniapp_exception.o := $(CFLAGS_EFI) -Os -ffreestanding +CFLAGS_REMOVE_efi_selftest_miniapp_exception.o := $(CFLAGS_NON_EFI) CFLAGS_efi_selftest_miniapp_exit.o := $(CFLAGS_EFI) -Os -ffreestanding CFLAGS_REMOVE_efi_selftest_miniapp_exit.o := $(CFLAGS_NON_EFI) CFLAGS_efi_selftest_miniapp_return.o := $(CFLAGS_EFI) -Os -ffreestanding diff --git a/lib/errno.c b/lib/errno.c index 8330a8fd14..ca0c756bd9 100644 --- a/lib/errno.c +++ b/lib/errno.c @@ -1 +1,3 @@ -int errno = 0; +#include + +int errno __errno_asm_label = 0; diff --git a/lib/string.c b/lib/string.c index a0cff8fe88..ba176fb08f 100644 --- a/lib/string.c +++ b/lib/string.c @@ -16,6 +16,7 @@ */ #include +#include #include #include #include @@ -513,7 +514,7 @@ char *strswab(const char *s) * * Do not use memset() to access IO space, use memset_io() instead. */ -void * memset(void * s,int c,size_t count) +__used void * memset(void * s,int c,size_t count) { unsigned long *sl = (unsigned long *) s; char *s8; @@ -552,7 +553,7 @@ void * memset(void * s,int c,size_t count) * You should not use this function to access IO space, use memcpy_toio() * or memcpy_fromio() instead. */ -void * memcpy(void *dest, const void *src, size_t count) +__used void * memcpy(void *dest, const void *src, size_t count) { unsigned long *dl = (unsigned long *)dest, *sl = (unsigned long *)src; char *d8, *s8; @@ -586,7 +587,7 @@ void * memcpy(void *dest, const void *src, size_t count) * * Unlike memcpy(), memmove() copes with overlapping areas. */ -void * memmove(void * dest,const void *src,size_t count) +__used void * memmove(void * dest,const void *src,size_t count) { char *tmp, *s; @@ -622,7 +623,7 @@ void * memmove(void * dest,const void *src,size_t count) * @ct: Another area of memory * @count: The size of the area. */ -int memcmp(const void * cs,const void * ct,size_t count) +__used int memcmp(const void * cs,const void * ct,size_t count) { const unsigned char *su1, *su2; int res = 0; diff --git a/lib/trace.c b/lib/trace.c index 9e34b19537..505a31806c 100644 --- a/lib/trace.c +++ b/lib/trace.c @@ -13,8 +13,8 @@ DECLARE_GLOBAL_DATA_PTR; -static char trace_enabled __attribute__((section(".data"))); -static char trace_inited __attribute__((section(".data"))); +static char trace_enabled __section(".data"); +static char trace_inited __section(".data"); /* The header block at the start of the trace memory area */ struct trace_hdr { diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 705a886cb9..7e59ca54cd 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -331,12 +331,11 @@ $(sort $(subdir-obj-y)): $(subdir-ym) ; # Rule to compile a set of .o files into one .o file # ifdef builtin-target -quiet_cmd_link_o_target = LD $@ +quiet_cmd_link_o_target = AR $@ # If the list of objects to link is empty, just create an empty built-in.o cmd_link_o_target = $(if $(strip $(obj-y)),\ - $(LD) $(ld_flags) -r -o $@ $(filter $(obj-y), $^) \ - $(cmd_secanalysis),\ - rm -f $@; $(AR) rcs$(KBUILD_ARFLAGS) $@) + rm -f $@; $(AR) cDPrsT $@ $(filter $(obj-y), $^), \ + rm -f $@; $(AR) cDPrsT$(KBUILD_ARFLAGS) $@) $(builtin-target): $(obj-y) FORCE $(call if_changed,link_o_target) @@ -362,7 +361,7 @@ $(modorder-target): $(subdir-ym) FORCE # ifdef lib-target quiet_cmd_link_l_target = AR $@ -cmd_link_l_target = rm -f $@; $(AR) rcs$(KBUILD_ARFLAGS) $@ $(lib-y) +cmd_link_l_target = rm -f $@; $(AR) cDPrsT$(KBUILD_ARFLAGS) $@ $(lib-y) $(lib-target): $(lib-y) FORCE $(call if_changed,link_l_target) @@ -382,10 +381,11 @@ $(filter $(addprefix $(obj)/, \ $($(subst $(obj)/,,$(@:.o=-objs))) \ $($(subst $(obj)/,,$(@:.o=-y)))), $^) -quiet_cmd_link_multi-y = LD $@ -cmd_link_multi-y = $(LD) $(ld_flags) -r -o $@ $(link_multi_deps) $(cmd_secanalysis) -quiet_cmd_link_multi-m = LD [M] $@ +quiet_cmd_link_multi-y = AR $@ +cmd_link_multi-y = rm -f $@; $(AR) cDPrsT$(KBUILD_ARFLAGS) $@ $(link_multi_deps) + +quiet_cmd_link_multi-m = AR [M] $@ cmd_link_multi-m = $(cmd_link_multi-y) $(multi-used-y): FORCE diff --git a/scripts/Makefile.lib b/scripts/Makefile.lib index 78543c6dd1..78bbebe7e9 100644 --- a/scripts/Makefile.lib +++ b/scripts/Makefile.lib @@ -419,6 +419,9 @@ $(obj)/%_efi.so: $(obj)/%.o $(obj)/efi_crt0.o $(obj)/efi_reloc.o $(obj)/efi_free targets += $(obj)/efi_crt0.o $(obj)/efi_reloc.o $(obj)/efi_freestanding.o +CFLAGS_REMOVE_efi_reloc.o := $(LTO_CFLAGS) +CFLAGS_REMOVE_efi_freestanding.o := $(LTO_CFLAGS) + # ACPI # --------------------------------------------------------------------------- # diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl index c69525fa74..5be1a9ba1b 100644 --- a/scripts/Makefile.spl +++ b/scripts/Makefile.spl @@ -399,6 +399,8 @@ LDFLAGS_$(SPL_BIN) += -T u-boot-spl.lds $(LDFLAGS_FINAL) # Avoid 'Not enough room for program headers' error on binutils 2.28 onwards. LDFLAGS_$(SPL_BIN) += $(call ld-option, --no-dynamic-linker) +LDFLAGS_$(SPL_BIN) += --build-id=none + # Pick the best-match (i.e. SPL_TEXT_BASE for SPL, TPL_TEXT_BASE for TPL) ifneq ($(CONFIG_$(SPL_TPL_)TEXT_BASE),) LDFLAGS_$(SPL_BIN) += -Ttext $(CONFIG_$(SPL_TPL_)TEXT_BASE) @@ -448,18 +450,65 @@ quiet_cmd_sym ?= SYM $@ $(obj)/$(SPL_BIN).sym: $(obj)/$(SPL_BIN) FORCE $(call if_changed,sym) +# Generate linker list symbols references to force compiler to not optimize +# them away when compiling with LTO +ifdef CONFIG_LTO +u-boot-spl-keep-syms-lto := $(obj)/keep-syms-lto.o +u-boot-spl-keep-syms-lto_c := \ + $(patsubst $(obj)/%.o,$(obj)/%.c,$(u-boot-spl-keep-syms-lto)) + +quiet_cmd_keep_syms_lto = KSL $@ + cmd_keep_syms_lto = \ + NM=$(NM) $(srctree)/scripts/gen_ll_addressable_symbols.sh $^ >$@ + +quiet_cmd_keep_syms_lto_cc = KSLCC $@ + cmd_keep_syms_lto_cc = \ + $(CC) $(filter-out $(LTO_CFLAGS),$(c_flags)) -c -o $@ $< + +$(u-boot-spl-keep-syms-lto_c): $(u-boot-spl-main) $(u-boot-spl-platdata) + $(call if_changed,keep_syms_lto) +$(u-boot-spl-keep-syms-lto): $(u-boot-spl-keep-syms-lto_c) + $(call if_changed,keep_syms_lto_cc) +else +u-boot-spl-keep-syms-lto := +endif + # Rule to link u-boot-spl # May be overridden by arch/$(ARCH)/config.mk +ifdef CONFIG_LTO +quiet_cmd_u-boot-spl ?= LTO $@ + cmd_u-boot-spl ?= \ + ( \ + cd $(obj) && \ + $(CC) -nostdlib -nostartfiles $(LTO_FINAL_LDFLAGS) $(c_flags) \ + $(KBUILD_LDFLAGS:%=-Wl,%) $(LDFLAGS_$(@F):%=-Wl,%) \ + $(patsubst $(obj)/%,%,$(u-boot-spl-init)) \ + -Wl,--whole-archive \ + $(patsubst $(obj)/%,%,$(u-boot-spl-main)) \ + $(patsubst $(obj)/%,%,$(u-boot-spl-platdata)) \ + $(patsubst $(obj)/%,%,$(u-boot-spl-keep-syms-lto)) \ + $(PLATFORM_LIBS) \ + -Wl,--no-whole-archive \ + -Wl,-Map,$(SPL_BIN).map -o $(SPL_BIN) \ + ) +else quiet_cmd_u-boot-spl ?= LD $@ - cmd_u-boot-spl ?= (cd $(obj) && $(LD) $(KBUILD_LDFLAGS) $(LDFLAGS_$(@F)) \ - $(patsubst $(obj)/%,%,$(u-boot-spl-init)) --start-group \ - $(patsubst $(obj)/%,%,$(u-boot-spl-main)) \ - $(patsubst $(obj)/%,%,$(u-boot-spl-platdata)) \ - --end-group \ - $(PLATFORM_LIBS) -Map $(SPL_BIN).map -o $(SPL_BIN)) + cmd_u-boot-spl ?= \ + ( \ + cd $(obj) && \ + $(LD) $(KBUILD_LDFLAGS) $(LDFLAGS_$(@F)) \ + $(patsubst $(obj)/%,%,$(u-boot-spl-init)) \ + --whole-archive \ + $(patsubst $(obj)/%,%,$(u-boot-spl-main)) \ + $(patsubst $(obj)/%,%,$(u-boot-spl-platdata)) \ + --no-whole-archive \ + $(PLATFORM_LIBS) -Map $(SPL_BIN).map -o $(SPL_BIN) \ + ) +endif $(obj)/$(SPL_BIN): $(u-boot-spl-platdata) $(u-boot-spl-init) \ - $(u-boot-spl-main) $(obj)/u-boot-spl.lds FORCE + $(u-boot-spl-main) $(u-boot-spl-keep-syms-lto) \ + $(obj)/u-boot-spl.lds FORCE $(call if_changed,u-boot-spl) $(sort $(u-boot-spl-init) $(u-boot-spl-main)): $(u-boot-spl-dirs) ; diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 59a714a95f..08a827535a 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -6073,7 +6073,7 @@ sub process { my $old = substr($rawline, $-[1], $+[1] - $-[1]); my $new = substr($old, 1, -1); if (WARN("PREFER_SECTION", - "__section($new) is preferred over __attribute__((section($old)))\n" . $herecurr) && + "__section(\"$new\") is preferred over __attribute__((section($old)))\n" . $herecurr) && $fix) { $fixed[$fixlinenr] =~ s/\b__attribute__\s*\(\s*\(\s*_*section_*\s*\(\s*\Q$old\E\s*\)\s*\)\s*\)/__section($new)/; } diff --git a/scripts/dtc/pylibfdt/libfdt.i_shipped b/scripts/dtc/pylibfdt/libfdt.i_shipped index 1d69ad38e2..27c29ea260 100644 --- a/scripts/dtc/pylibfdt/libfdt.i_shipped +++ b/scripts/dtc/pylibfdt/libfdt.i_shipped @@ -1010,7 +1010,7 @@ typedef uint32_t fdt32_t; } $1 = (void *)PyByteArray_AsString($input); fdt = $1; - fdt = fdt; /* avoid unused variable warning */ + (void)fdt; /* avoid unused variable warning */ } /* Some functions do change the device tree, so use void * */ @@ -1021,7 +1021,7 @@ typedef uint32_t fdt32_t; } $1 = PyByteArray_AsString($input); fdt = $1; - fdt = fdt; /* avoid unused variable warning */ + (void)fdt; /* avoid unused variable warning */ } /* typemap used for fdt_get_property_by_offset() */ diff --git a/scripts/gen_ll_addressable_symbols.sh b/scripts/gen_ll_addressable_symbols.sh new file mode 100755 index 0000000000..3978a39d97 --- /dev/null +++ b/scripts/gen_ll_addressable_symbols.sh @@ -0,0 +1,12 @@ +#!/bin/bash +# SPDX-License-Identifier: GPL-2.0+ +# Copyright (C) 2020 Marek BehĂșn + +# Generate __ADDRESSABLE(symbol) for every linker list entry symbol, so that LTO +# does not optimize these symbols away + +set -e + +echo '#include ' +$NM "$@" 2>/dev/null | grep -oe '_u_boot_list_2_[a-zA-Z0-9_]*_2_[a-zA-Z0-9_]*' | \ + sort -u | sed -e 's/^\(.*\)/extern char \1[];\n__ADDRESSABLE(\1);/' diff --git a/test/dm/regmap.c b/test/dm/regmap.c index 372a73ca0c..04bb1645d1 100644 --- a/test/dm/regmap.c +++ b/test/dm/regmap.c @@ -306,9 +306,8 @@ static int dm_test_devm_regmap(struct unit_test_state *uts) &dev)); priv = dev_get_priv(dev); - srand(get_ticks() + rand()); for (i = 0; i < REGMAP_TEST_BUF_SZ; i++) { - pattern[i] = rand(); + pattern[i] = i * 0x87654321; ut_assertok(regmap_write(priv->cfg_regmap, i, pattern[i])); } for (i = 0; i < REGMAP_TEST_BUF_SZ; i++) { diff --git a/test/py/conftest.py b/test/py/conftest.py index 1b909cde9d..11a3f307ea 100644 --- a/test/py/conftest.py +++ b/test/py/conftest.py @@ -226,7 +226,7 @@ def pytest_configure(config): import u_boot_console_exec_attach console = u_boot_console_exec_attach.ConsoleExecAttach(log, ubconfig) -re_ut_test_list = re.compile(r'_u_boot_list_2_ut_(.*)_test_2_\1_test_(.*)\s*$') +re_ut_test_list = re.compile(r'[^a-zA-Z0-9_]_u_boot_list_2_ut_(.*)_test_2_\1_test_(.*)\s*$') def generate_ut_subtest(metafunc, fixture_name, sym_path): """Provide parametrization for a ut_subtest fixture.