mirror of
https://github.com/apache/nuttx.git
synced 2026-09-09 02:16:35 +00:00
arch, boards, cmake: Build C++ ELF modules without __cxa_atexit.
A C++ module with a static object does not link. GCC registers each such object's destructor with __cxa_atexit(dtor, obj, &__dso_handle), and __dso_handle comes from crtbegin, which a module does not link: hello++3.cxx:119: undefined reference to `__dso_handle' It is reachable today with CONFIG_PIC, where a module is linked as an executable and the symbol has to resolve. Without it the link is relocatable, the symbol stays undefined and nothing complains until something makes it resolve. -fno-use-cxa-atexit registers the destructors with atexit() instead, which puts them in .fini_array. That is also where libelf_uninit() looks for them when the module is unloaded, so the flag that makes the link work is also the flag that makes the destructors run. The option goes wherever CXXELFFLAGS is defined, which is the architecture Toolchain.defs and the boards that reassign it. The toolchains that are not GCC or Clang are left alone: ceva, tricore, z16 and the z80 family. The CMake build sets it once, next to where the architecture elf.cmake is included. A generator expression keeps it off the C compiles, because the option is valid for C++ alone and GCC warns about it otherwise, and the compiler id gates it so that a toolchain which is neither GCC nor Clang does not see it. It cannot go in the toolchain file itself: CMake reads that file again inside try_compile, in a project that has not included the NuttX extensions, so the call is an unknown command there. Reproduced with apps/examples/elf on mps3-an547:picostest with CONFIG_PIC enabled: hello++3 fails to link before and links after. Assisted-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
This commit is contained in:
parent
c5619cb3fe
commit
0d31418ba8
29 changed files with 127 additions and 0 deletions
|
|
@ -516,6 +516,20 @@ if(EXISTS ${NUTTX_DIR}/arch/${CONFIG_ARCH}/src/cmake/elf.cmake)
|
|||
include(${NUTTX_DIR}/arch/${CONFIG_ARCH}/src/cmake/elf.cmake)
|
||||
endif()
|
||||
|
||||
# The default registers each static object's destructor with __cxa_atexit(dtor,
|
||||
# obj, &__dso_handle), and __dso_handle comes from crtbegin, which a module does
|
||||
# not link. Turning it off also puts the destructors in .fini_array, which is
|
||||
# where the loader looks for them when the module is unloaded.
|
||||
#
|
||||
# GCC and Clang alone take the option, which is why the architectures built by
|
||||
# another compiler do not carry it in their Toolchain.defs either. ARMClang
|
||||
# reports ARMClang, so it keeps it. The generator expression keeps the option
|
||||
# off the C compiles, which it is not valid for.
|
||||
|
||||
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
|
||||
nuttx_elf_compile_options($<$<COMPILE_LANGUAGE:CXX>:-fno-use-cxa-atexit>)
|
||||
endif()
|
||||
|
||||
include(platform)
|
||||
|
||||
if(CONFIG_ARCH_TOOLCHAIN_TASKING)
|
||||
|
|
|
|||
|
|
@ -633,6 +633,10 @@ 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
|
||||
|
||||
CXXELFFLAGS += -fno-use-cxa-atexit
|
||||
|
||||
ifeq ($(CONFIG_PIC),y)
|
||||
# ARCHCFLAGS, not CFLAGS: board Make.defs reassign CFLAGS with ':='
|
||||
# after including this file, which would discard the flag.
|
||||
|
|
|
|||
|
|
@ -292,6 +292,10 @@ LDMODULEFLAGS = -r -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/elf/gnu-elf.ld)
|
|||
CELFFLAGS = $(CFLAGS) -fvisibility=hidden # --target1-abs
|
||||
CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden # --target1-abs
|
||||
|
||||
# __dso_handle comes from crtbegin, which a module does not link
|
||||
|
||||
CXXELFFLAGS += -fno-use-cxa-atexit
|
||||
|
||||
LDELFFLAGS = -r -e _start
|
||||
ifneq ($(CONFIG_BUILD_KERNEL),y)
|
||||
# Flat build and protected elf entry point use crt0,
|
||||
|
|
|
|||
|
|
@ -219,5 +219,9 @@ LDMODULEFLAGS = -r -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/elf/gnu-elf.ld)
|
|||
CELFFLAGS = $(CFLAGS) -fvisibility=hidden
|
||||
CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden
|
||||
|
||||
# __dso_handle comes from crtbegin, which a module does not link
|
||||
|
||||
CXXELFFLAGS += -fno-use-cxa-atexit
|
||||
|
||||
LDELFFLAGS = -r -e _start
|
||||
LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)elf$(DELIM)gnu-elf.ld)
|
||||
|
|
|
|||
|
|
@ -115,5 +115,9 @@ LDMODULEFLAGS = -r -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/elf/gnu-elf.ld)
|
|||
CELFFLAGS = $(CFLAGS) -fvisibility=hidden
|
||||
CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden
|
||||
|
||||
# __dso_handle comes from crtbegin, which a module does not link
|
||||
|
||||
CXXELFFLAGS += -fno-use-cxa-atexit
|
||||
|
||||
LDELFFLAGS = -r -e _start
|
||||
LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)elf$(DELIM)gnu-elf.ld)
|
||||
|
|
|
|||
|
|
@ -332,5 +332,9 @@ LDMODULEFLAGS = -EL -r -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/elf/gnu-elf.ld
|
|||
CELFFLAGS = $(CFLAGS) -fvisibility=hidden
|
||||
CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden
|
||||
|
||||
# __dso_handle comes from crtbegin, which a module does not link
|
||||
|
||||
CXXELFFLAGS += -fno-use-cxa-atexit
|
||||
|
||||
LDELFFLAGS = -r -e _start
|
||||
LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)elf$(DELIM)gnu-elf.ld)
|
||||
|
|
|
|||
|
|
@ -146,5 +146,9 @@ LDMODULEFLAGS = -r -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/elf/gnu-elf.ld)
|
|||
CELFFLAGS = $(CFLAGS) -fvisibility=hidden
|
||||
CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden
|
||||
|
||||
# __dso_handle comes from crtbegin, which a module does not link
|
||||
|
||||
CXXELFFLAGS += -fno-use-cxa-atexit
|
||||
|
||||
LDELFFLAGS = -r -e _start
|
||||
LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)elf$(DELIM)gnu-elf.ld)
|
||||
|
|
|
|||
|
|
@ -94,5 +94,9 @@ LDMODULEFLAGS = -r -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/elf/gnu-elf.ld)
|
|||
CELFFLAGS = $(CFLAGS) -fvisibility=hidden
|
||||
CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden
|
||||
|
||||
# __dso_handle comes from crtbegin, which a module does not link
|
||||
|
||||
CXXELFFLAGS += -fno-use-cxa-atexit
|
||||
|
||||
LDELFFLAGS = -r -e _start
|
||||
LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)elf$(DELIM)gnu-elf.ld)
|
||||
|
|
|
|||
|
|
@ -132,5 +132,9 @@ LDMODULEFLAGS = -r -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/elf/gnu-elf.ld)
|
|||
CELFFLAGS = $(CFLAGS) -fvisibility=hidden
|
||||
CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden
|
||||
|
||||
# __dso_handle comes from crtbegin, which a module does not link
|
||||
|
||||
CXXELFFLAGS += -fno-use-cxa-atexit
|
||||
|
||||
LDELFFLAGS = -r -e _start
|
||||
LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)elf$(DELIM)gnu-elf.ld)
|
||||
|
|
|
|||
|
|
@ -449,6 +449,10 @@ LDMODULEFLAGS = -r -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/elf/gnu-elf.ld)
|
|||
CELFFLAGS = $(CFLAGS) -fvisibility=hidden
|
||||
CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden
|
||||
|
||||
# __dso_handle comes from crtbegin, which a module does not link
|
||||
|
||||
CXXELFFLAGS += -fno-use-cxa-atexit
|
||||
|
||||
LDELFFLAGS = -e _start
|
||||
|
||||
ifeq ($(CONFIG_BINFMT_ELF_RELOCATABLE),y)
|
||||
|
|
|
|||
|
|
@ -137,5 +137,9 @@ LDMODULEFLAGS = -r -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/elf/gnu-elf.ld)
|
|||
CELFFLAGS = $(CFLAGS) -fvisibility=hidden
|
||||
CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden
|
||||
|
||||
# __dso_handle comes from crtbegin, which a module does not link
|
||||
|
||||
CXXELFFLAGS += -fno-use-cxa-atexit
|
||||
|
||||
LDELFFLAGS = -r -e _start
|
||||
LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)elf$(DELIM)gnu-elf.ld)
|
||||
|
|
|
|||
|
|
@ -106,5 +106,9 @@ LDMODULEFLAGS = -r -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/elf/gnu-elf.ld)
|
|||
CELFFLAGS = $(CFLAGS) -fvisibility=hidden
|
||||
CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden
|
||||
|
||||
# __dso_handle comes from crtbegin, which a module does not link
|
||||
|
||||
CXXELFFLAGS += -fno-use-cxa-atexit
|
||||
|
||||
LDELFFLAGS = -r -e _start
|
||||
LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)elf$(DELIM)gnu-elf.ld)
|
||||
|
|
|
|||
|
|
@ -286,6 +286,10 @@ endif
|
|||
CELFFLAGS = $(CFLAGS) -fvisibility=hidden
|
||||
CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden
|
||||
|
||||
# __dso_handle comes from crtbegin, which a module does not link
|
||||
|
||||
CXXELFFLAGS += -fno-use-cxa-atexit
|
||||
|
||||
LDELFFLAGS = -r -e _start
|
||||
ifneq ($(CONFIG_BUILD_KERNEL),y)
|
||||
# Flat build and protected elf entry point use crt0,
|
||||
|
|
|
|||
|
|
@ -236,6 +236,10 @@ LDMODULEFLAGS = -r -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/elf/gnu-elf.ld)
|
|||
CELFFLAGS = $(CFLAGS) -fvisibility=hidden -mtext-section-literals
|
||||
CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden -mtext-section-literals
|
||||
|
||||
# __dso_handle comes from crtbegin, which a module does not link
|
||||
|
||||
CXXELFFLAGS += -fno-use-cxa-atexit
|
||||
|
||||
LDELFFLAGS = -r -e _start
|
||||
LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)elf$(DELIM)gnu-elf.ld)
|
||||
ifneq ($(CONFIG_BUILD_KERNEL),y)
|
||||
|
|
|
|||
|
|
@ -240,6 +240,10 @@ LDMODULEFLAGS = -r -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/elf/gnu-elf.ld)
|
|||
CELFFLAGS = $(CFLAGS) -fvisibility=hidden -mtext-section-literals
|
||||
CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden -mtext-section-literals
|
||||
|
||||
# __dso_handle comes from crtbegin, which a module does not link
|
||||
|
||||
CXXELFFLAGS += -fno-use-cxa-atexit
|
||||
|
||||
LDELFFLAGS = -r -e _start
|
||||
LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)libs$(DELIM)libc$(DELIM)elf$(DELIM)gnu-elf.ld)
|
||||
ifneq ($(CONFIG_BUILD_KERNEL),y)
|
||||
|
|
|
|||
|
|
@ -50,5 +50,9 @@ LDNXFLATFLAGS = -e main -s 2048
|
|||
CELFFLAGS = $(CFLAGS) -mlong-calls # --target1-abs
|
||||
CXXELFFLAGS = $(CXXFLAGS) -mlong-calls # --target1-abs
|
||||
|
||||
# __dso_handle comes from crtbegin, which a module does not link
|
||||
|
||||
CXXELFFLAGS += -fno-use-cxa-atexit
|
||||
|
||||
LDELFFLAGS = -r -e main
|
||||
LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/elf/gnu-elf.ld)
|
||||
|
|
|
|||
|
|
@ -44,5 +44,9 @@ LDNXFLATFLAGS = -e main -s 2048
|
|||
CELFFLAGS = $(CFLAGS) -mlong-calls # --target1-abs
|
||||
CXXELFFLAGS = $(CXXFLAGS) -mlong-calls # --target1-abs
|
||||
|
||||
# __dso_handle comes from crtbegin, which a module does not link
|
||||
|
||||
CXXELFFLAGS += -fno-use-cxa-atexit
|
||||
|
||||
LDELFFLAGS = -r -e main
|
||||
LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/binfmt/elf/gnu-elf.ld)
|
||||
|
|
|
|||
|
|
@ -42,5 +42,9 @@ LDNXFLATFLAGS = -e main -s 2048
|
|||
CELFFLAGS = $(CFLAGS) -mlong-calls # --target1-abs
|
||||
CXXELFFLAGS = $(CXXFLAGS) -mlong-calls # --target1-abs
|
||||
|
||||
# __dso_handle comes from crtbegin, which a module does not link
|
||||
|
||||
CXXELFFLAGS += -fno-use-cxa-atexit
|
||||
|
||||
LDELFFLAGS = -r -e main
|
||||
LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/binfmt/elf/gnu-elf.ld)
|
||||
|
|
|
|||
|
|
@ -42,5 +42,9 @@ LDNXFLATFLAGS = -e main -s 2048
|
|||
CELFFLAGS = $(CFLAGS) -mlong-calls # --target1-abs
|
||||
CXXELFFLAGS = $(CXXFLAGS) -mlong-calls # --target1-abs
|
||||
|
||||
# __dso_handle comes from crtbegin, which a module does not link
|
||||
|
||||
CXXELFFLAGS += -fno-use-cxa-atexit
|
||||
|
||||
LDELFFLAGS = -r -e main
|
||||
LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/binfmt/elf/gnu-elf.ld)
|
||||
|
|
|
|||
|
|
@ -42,5 +42,9 @@ LDNXFLATFLAGS = -e main -s 2048
|
|||
CELFFLAGS = $(CFLAGS) -mlong-calls # --target1-abs
|
||||
CXXELFFLAGS = $(CXXFLAGS) -mlong-calls # --target1-abs
|
||||
|
||||
# __dso_handle comes from crtbegin, which a module does not link
|
||||
|
||||
CXXELFFLAGS += -fno-use-cxa-atexit
|
||||
|
||||
LDELFFLAGS = -r -e main
|
||||
LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/binfmt/elf/gnu-elf.ld)
|
||||
|
|
|
|||
|
|
@ -42,5 +42,9 @@ LDNXFLATFLAGS = -e main -s 2048
|
|||
CELFFLAGS = $(CFLAGS) -mlong-calls # --target1-abs
|
||||
CXXELFFLAGS = $(CXXFLAGS) -mlong-calls # --target1-abs
|
||||
|
||||
# __dso_handle comes from crtbegin, which a module does not link
|
||||
|
||||
CXXELFFLAGS += -fno-use-cxa-atexit
|
||||
|
||||
LDELFFLAGS = -r -e main
|
||||
LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/binfmt/elf/gnu-elf.ld)
|
||||
|
|
|
|||
|
|
@ -63,5 +63,9 @@ LDMODULEFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/elf/gnu-elf.ld)
|
|||
CELFFLAGS = $(CFLAGS)
|
||||
CXXELFFLAGS = $(CXXFLAGS)
|
||||
|
||||
# __dso_handle comes from crtbegin, which a module does not link
|
||||
|
||||
CXXELFFLAGS += -fno-use-cxa-atexit
|
||||
|
||||
LDELFFLAGS = -melf32lriscv -r -e main
|
||||
LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/binfmt/elf/gnu-elf.ld)
|
||||
|
|
|
|||
|
|
@ -63,5 +63,9 @@ LDMODULEFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/elf/gnu-elf.ld)
|
|||
CELFFLAGS = $(CFLAGS)
|
||||
CXXELFFLAGS = $(CXXFLAGS)
|
||||
|
||||
# __dso_handle comes from crtbegin, which a module does not link
|
||||
|
||||
CXXELFFLAGS += -fno-use-cxa-atexit
|
||||
|
||||
LDELFFLAGS = -melf32lriscv -r -e main
|
||||
LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/binfmt/elf/gnu-elf.ld)
|
||||
|
|
|
|||
|
|
@ -287,6 +287,11 @@ endif
|
|||
|
||||
CELFFLAGS = $(CFLAGS) -fvisibility=hidden
|
||||
CXXELFFLAGS = $(CXXFLAGS) -fvisibility=hidden
|
||||
|
||||
# __dso_handle comes from crtbegin, which a module does not link
|
||||
|
||||
CXXELFFLAGS += -fno-use-cxa-atexit
|
||||
|
||||
# -fno-pic to avoid GOT relocations
|
||||
CELFFLAGS += -fno-pic
|
||||
CXXELFFLAGS += -fno-pic
|
||||
|
|
|
|||
|
|
@ -67,5 +67,9 @@ LDMODULEFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/elf/gnu-elf.ld)
|
|||
CELFFLAGS = $(CFLAGS) -mtext-section-literals
|
||||
CXXELFFLAGS = $(CXXFLAGS) -mtext-section-literals
|
||||
|
||||
# __dso_handle comes from crtbegin, which a module does not link
|
||||
|
||||
CXXELFFLAGS += -fno-use-cxa-atexit
|
||||
|
||||
LDELFFLAGS = -r -e main
|
||||
LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)$(DELIM)binfmt$(DELIM)elf$(DELIM)gnu-elf.ld)
|
||||
|
|
|
|||
|
|
@ -67,5 +67,9 @@ LDMODULEFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/elf/gnu-elf.ld)
|
|||
CELFFLAGS = $(CFLAGS) -mtext-section-literals
|
||||
CXXELFFLAGS = $(CXXFLAGS) -mtext-section-literals
|
||||
|
||||
# __dso_handle comes from crtbegin, which a module does not link
|
||||
|
||||
CXXELFFLAGS += -fno-use-cxa-atexit
|
||||
|
||||
LDELFFLAGS = -r -e main
|
||||
LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/binfmt/elf/gnu-elf.ld)
|
||||
|
|
|
|||
|
|
@ -67,5 +67,9 @@ LDMODULEFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/elf/gnu-elf.ld)
|
|||
CELFFLAGS = $(CFLAGS) -mtext-section-literals
|
||||
CXXELFFLAGS = $(CXXFLAGS) -mtext-section-literals
|
||||
|
||||
# __dso_handle comes from crtbegin, which a module does not link
|
||||
|
||||
CXXELFFLAGS += -fno-use-cxa-atexit
|
||||
|
||||
LDELFFLAGS = -r -e main
|
||||
LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/binfmt/elf/gnu-elf.ld)
|
||||
|
|
|
|||
|
|
@ -67,5 +67,9 @@ LDMODULEFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/elf/gnu-elf.ld)
|
|||
CELFFLAGS = $(CFLAGS) -mtext-section-literals
|
||||
CXXELFFLAGS = $(CXXFLAGS) -mtext-section-literals
|
||||
|
||||
# __dso_handle comes from crtbegin, which a module does not link
|
||||
|
||||
CXXELFFLAGS += -fno-use-cxa-atexit
|
||||
|
||||
LDELFFLAGS = -r -e main
|
||||
LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/binfmt/elf/gnu-elf.ld)
|
||||
|
|
|
|||
|
|
@ -67,5 +67,9 @@ LDMODULEFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/elf/gnu-elf.ld)
|
|||
CELFFLAGS = $(CFLAGS) -mtext-section-literals
|
||||
CXXELFFLAGS = $(CXXFLAGS) -mtext-section-literals
|
||||
|
||||
# __dso_handle comes from crtbegin, which a module does not link
|
||||
|
||||
CXXELFFLAGS += -fno-use-cxa-atexit
|
||||
|
||||
LDELFFLAGS = -r -e main
|
||||
LDELFFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/binfmt/libelf/gnu-elf.ld)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue