This is an automated email from the ASF dual-hosted git repository. acassis pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/nuttx.git
commit d4453654e4a41b53e374803401708bd4aca5c416 Author: Marco Casaroli <[email protected]> AuthorDate: Wed Oct 21 00:21:34 2026 +0200 arch: Compile an LTO module to machine code when gcc links it. With CONFIG_LTO_FULL, the Toolchain.defs of arm, arm64 and risc-v set LD to the gcc driver, and a loadable module (and a program of a kernel build) is linked with it, because MODULELD defaults to LD. The partial link (-r) of LTO objects keeps only LTO data, which the loader cannot use: "Failed to execute program 'hello': -22", and nm says "plugin needed to handle lto object". Where these Toolchain.defs set LD to gcc for LTO, they now also set LDMODULELTOFLAGS and LDELFLTOFLAGS: -flinker-output=nolto-rel and the compile options of the module. LDMODULEFLAGS and LDELFFLAGS use them next to -r. The link then compiles the objects to machine code with the options of the module (-mthumb, -mlong-calls, ...). Without these options the arm-none-eabi assembler stopped with "invalid constant (3e8) after fixup". crt0.o is now compiled without -flto. It must be machine code in any case, and as LTO data it made LTO warn that crt0 and the program declare main() differently, which -Werror makes an error. Assisted-by: Claude Code:claude-opus-5-5 Signed-off-by: Marco Casaroli <[email protected]> --- arch/arm/src/Makefile | 2 +- arch/arm/src/common/Toolchain.defs | 11 +++++++++-- arch/arm64/src/Makefile | 2 +- arch/arm64/src/Toolchain.defs | 12 ++++++++++-- arch/risc-v/src/Makefile | 2 +- arch/risc-v/src/common/Toolchain.defs | 11 +++++++++-- 6 files changed, 31 insertions(+), 9 deletions(-) diff --git a/arch/arm/src/Makefile b/arch/arm/src/Makefile index 3145100bc8b..5bdff52c61c 100644 --- a/arch/arm/src/Makefile +++ b/arch/arm/src/Makefile @@ -189,7 +189,7 @@ $(LDEMPTY_OBJ): common$(DELIM)arm_ldempty.c $(call COMPILE, $<, $@) $(STARTUP_OBJS): %$(OBJEXT): %.c - $(Q) $(CC) $(CELFFLAGS) -c common$(DELIM)crt0.c -o crt0$(OBJEXT) + $(Q) $(CC) $(filter-out -flto%,$(CELFFLAGS)) -c common$(DELIM)crt0.c -o crt0$(OBJEXT) ifeq ($(CONFIG_BUILD_FLAT),y) $(BIN): $(STARTUP_OBJS) $(OBJS) diff --git a/arch/arm/src/common/Toolchain.defs b/arch/arm/src/common/Toolchain.defs index deea8116de3..bec4dfbb971 100644 --- a/arch/arm/src/common/Toolchain.defs +++ b/arch/arm/src/common/Toolchain.defs @@ -317,6 +317,12 @@ else UNAR := $(CROSSDEV)gcc-ar x NM := $(CROSSDEV)gcc-nm ARCHOPTIMIZATION += -fno-builtin + + # gcc links a module. The loader cannot use LTO data, so a partial link + # (-r) compiles the module to machine code with the module options. + + LDMODULELTOFLAGS = -flinker-output=nolto-rel $(CMODULEFLAGS) + LDELFLTOFLAGS = -flinker-output=nolto-rel $(CELFFLAGS) endif endif @@ -634,7 +640,8 @@ endif CMODULEFLAGS = $(CFLAGS) -fvisibility=hidden -mlong-calls # --target1-abs CXXMODULEFLAGS = $(CXXFLAGS) -fvisibility=hidden -mlong-calls -LDMODULEFLAGS = -r -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/elf/gnu-elf.ld) +LDMODULEFLAGS = -r $(LDMODULELTOFLAGS) \ + -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/elf/gnu-elf.ld) # ELF module definitions @@ -723,7 +730,7 @@ endif else ifneq ($(CONFIG_BINFMT_ELF_EXECUTABLE),y) - LDELFFLAGS += -r + LDELFFLAGS += -r $(LDELFLTOFLAGS) endif endif diff --git a/arch/arm64/src/Makefile b/arch/arm64/src/Makefile index 52bb3d04065..c96178f0ee5 100644 --- a/arch/arm64/src/Makefile +++ b/arch/arm64/src/Makefile @@ -143,7 +143,7 @@ $(sort $(COBJS) $(UCOBJS)): %$(OBJEXT): %.c $(call COMPILE, $<, $@) $(STARTUP_OBJS): %$(OBJEXT): %.c - $(Q) $(CC) $(CELFFLAGS) -c common$(DELIM)crt0.c -o crt0$(OBJEXT) + $(Q) $(CC) $(filter-out -flto%,$(CELFFLAGS)) -c common$(DELIM)crt0.c -o crt0$(OBJEXT) ifeq ($(CONFIG_BUILD_FLAT),y) $(BIN): $(OBJS) $(STARTUP_OBJS) diff --git a/arch/arm64/src/Toolchain.defs b/arch/arm64/src/Toolchain.defs index dad042310ce..102d19c38ac 100644 --- a/arch/arm64/src/Toolchain.defs +++ b/arch/arm64/src/Toolchain.defs @@ -250,6 +250,12 @@ ifeq ($(CONFIG_LTO_FULL),y) NM := $(CROSSDEV)gcc-nm ARCHOPTIMIZATION += -fuse-linker-plugin ARCHOPTIMIZATION += -fno-builtin + + # gcc links a module. The loader cannot use LTO data, so a partial link + # (-r) compiles the module to machine code with the module options. + + LDMODULELTOFLAGS = -flinker-output=nolto-rel $(CMODULEFLAGS) + LDELFLTOFLAGS = -flinker-output=nolto-rel $(CELFFLAGS) endif endif @@ -285,7 +291,8 @@ endif # Loadable module definitions CMODULEFLAGS = $(CFLAGS) -fvisibility=hidden # --target1-abs -LDMODULEFLAGS = -r -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/elf/gnu-elf.ld) +LDMODULEFLAGS = -r $(LDMODULELTOFLAGS) \ + -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/elf/gnu-elf.ld) # ELF module definitions @@ -296,11 +303,12 @@ CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden # --target1-abs CXXELFFLAGS += -fno-use-cxa-atexit -LDELFFLAGS = -r -e _start +LDELFFLAGS = -r $(LDELFLTOFLAGS) -e _start ifneq ($(CONFIG_BUILD_KERNEL),y) # Flat build and protected elf entry point use crt0, # Kernel build will use apps/import/scripts/crt0 LDELFFLAGS += $(TOPDIR)$(DELIM)arch$(DELIM)arm64$(DELIM)src$(DELIM)crt0.o endif + LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)elf$(DELIM)gnu-elf.ld) diff --git a/arch/risc-v/src/Makefile b/arch/risc-v/src/Makefile index 3a75dd4d501..055c057f7a2 100644 --- a/arch/risc-v/src/Makefile +++ b/arch/risc-v/src/Makefile @@ -144,7 +144,7 @@ $(COBJS) $(UCOBJS): %$(OBJEXT): %.c $(call COMPILE, $<, $@) $(STARTUP_OBJS): %$(OBJEXT): %.c - $(Q) $(CC) $(CELFFLAGS) -c common$(DELIM)crt0.c -o crt0$(OBJEXT) + $(Q) $(CC) $(filter-out -flto%,$(CELFFLAGS)) -c common$(DELIM)crt0.c -o crt0$(OBJEXT) ifeq ($(CONFIG_BUILD_FLAT),y) $(BIN): $(STARTUP_OBJS) $(OBJS) diff --git a/arch/risc-v/src/common/Toolchain.defs b/arch/risc-v/src/common/Toolchain.defs index f1262238e11..ab8f08ff0e7 100644 --- a/arch/risc-v/src/common/Toolchain.defs +++ b/arch/risc-v/src/common/Toolchain.defs @@ -389,6 +389,12 @@ else AR := $(CROSSDEV)gcc-ar rcs NM := $(CROSSDEV)gcc-nm ARCHOPTIMIZATION += -fno-builtin + + # gcc links a module. The loader cannot use LTO data, so a partial link + # (-r) compiles the module to machine code with the module options. + + LDMODULELTOFLAGS = -flinker-output=nolto-rel $(CMODULEFLAGS) + LDELFLTOFLAGS = -flinker-output=nolto-rel $(CELFFLAGS) endif endif @@ -442,7 +448,8 @@ endif # Loadable module definitions CMODULEFLAGS = $(CFLAGS) -fvisibility=hidden -LDMODULEFLAGS = -r -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/elf/gnu-elf.ld) +LDMODULEFLAGS = -r $(LDMODULELTOFLAGS) \ + -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/elf/gnu-elf.ld) # ELF module definitions @@ -456,7 +463,7 @@ CXXELFFLAGS += -fno-use-cxa-atexit LDELFFLAGS = -e _start ifeq ($(CONFIG_BINFMT_ELF_RELOCATABLE),y) - LDELFFLAGS += -r + LDELFFLAGS += -r $(LDELFLTOFLAGS) endif ifeq ($(CONFIG_ARCH_RV32),y)
