From 74d0b38156af720baaede300a52c98252024a07b Mon Sep 17 00:00:00 2001 From: Marco Casaroli Date: Fri, 25 Sep 2026 11:33:39 +0200 Subject: [PATCH] arch/arm: Build a loadable module and a shared library as FDPIC too. CONFIG_FDPIC teaches the ELF module path what an FDPIC object is, so an application built as a module gets -mfdpic -fPIC and the arm-uclinuxfdpiceabi linker. The loadable module path, which apps builds with DYNLIB = y and which apps/Library.mk uses for a shared library, was left as it was: a -r partial link with the stock linker. That leaves an object with no dynamic section, so the loader has nothing to bind an import to, and there is no way to build a library an FDPIC module can call. Give that path the same treatment. CMODULEFLAGS and CXXMODULEFLAGS gain the FDPIC compiler flags, and LDMODULEFLAGS links a shared object rather than a partial one. The entry point is left to the caller, because a module is entered at _start while a library is only ever called into. CXXMODULEFLAGS is also defined for the first time. apps/Library.mk compiles every C++ source of a shared library with it and no architecture defined it, so those sources were compiled with no architecture flags at all. Assisted-by: Claude Opus 5 (1M context) Signed-off-by: Marco Casaroli --- arch/arm/src/common/Toolchain.defs | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/arch/arm/src/common/Toolchain.defs b/arch/arm/src/common/Toolchain.defs index a1d6580326384..c169e2d25ecc2 100644 --- a/arch/arm/src/common/Toolchain.defs +++ b/arch/arm/src/common/Toolchain.defs @@ -619,7 +619,10 @@ endif # Loadable module definitions +# CXXMODULEFLAGS is what apps/Library.mk compiles a C++ shared library with. + 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) # ELF module definitions @@ -633,9 +636,11 @@ CELFFLAGS = $(filter-out --fixed-r9,$(CFLAGS)) -fvisibility=hidden \ CXXELFFLAGS = $(filter-out --fixed-r9,$(CXXFLAGS)) -fvisibility=hidden \ -mlong-calls -# __dso_handle comes from crtbegin, which a module does not link +# __dso_handle comes from crtbegin, which neither a module nor a shared +# library links CXXELFFLAGS += -fno-use-cxa-atexit +CXXMODULEFLAGS += -fno-use-cxa-atexit ifeq ($(CONFIG_PIC),y) # ARCHCFLAGS, not CFLAGS: board Make.defs reassign CFLAGS with ':=' @@ -673,6 +678,20 @@ ifeq ($(CONFIG_FDPIC),y) CXXELFFLAGS += -mfdpic -fPIC -Wa,--noexecstack LDELFFLAGS += -m armelf_linux_fdpiceabi -shared -z now + + # A loadable module and a shared library are the same kind of object here, + # so they are built the same way. The partial link the module path uses + # elsewhere leaves no dynamic section, and the loader has nothing to bind + # an import to. + # + # The entry point is left to the caller: a module is entered at _start, + # a library is only called into. + + CMODULEFLAGS += -mfdpic -fPIC -Wa,--noexecstack + CXXMODULEFLAGS += -mfdpic -fPIC -Wa,--noexecstack + + LDMODULEFLAGS = -m armelf_linux_fdpiceabi -shared -z now \ + -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/elf/gnu-elf.ld) else CELFFLAGS += $(PICFLAGS) -mpic-register=r9 CXXELFFLAGS += $(PICFLAGS) -mpic-register=r9