nuttx/boards/risc-v/esp32c6/esp32c6-devkitc/scripts/Make.defs
Marco Casaroli 0d31418ba8 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>
2026-09-04 15:44:24 -03:00

71 lines
2.7 KiB
Text

############################################################################
# boards/risc-v/esp32c6/esp32c6-devkitc/scripts/Make.defs
#
# SPDX-License-Identifier: Apache-2.0
#
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership. The
# ASF licenses this file to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance with the
# License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
###########################################################################
include $(TOPDIR)/.config
include $(TOPDIR)/tools/Config.mk
include $(TOPDIR)/tools/espressif/Config.mk
include $(TOPDIR)/arch/risc-v/src/common/Toolchain.defs
# Remove quotes from CONFIG_ESPRESSIF_CHIP_SERIES configuration
CHIP_SERIES = $(patsubst "%",%,$(CONFIG_ESPRESSIF_CHIP_SERIES))
# Pick the linker scripts from the board level if they exist, if not
# pick the common linker scripts.
ARCHSCRIPT += $(BOARD_COMMON_DIR)/scripts/$(CHIP_SERIES)_aliases.ld
ARCHSCRIPT += $(call FINDSCRIPT,$(CHIP_SERIES)_flat_memory.ld)
ifeq ($(CONFIG_ESPRESSIF_SIMPLE_BOOT),y)
ARCHSCRIPT += $(call FINDSCRIPT,$(CHIP_SERIES)_sections.ld)
else ifeq ($(CONFIG_ESPRESSIF_BOOTLOADER_MCUBOOT),y)
ARCHSCRIPT += $(call FINDSCRIPT,$(CHIP_SERIES)_sections.ld)
else
ARCHSCRIPT += $(call FINDSCRIPT,$(CHIP_SERIES)_legacy_sections.ld)
endif
CFLAGS := $(ARCHCFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS) -Werror=return-type
CPICFLAGS = $(ARCHPICFLAGS) $(CFLAGS)
CXXFLAGS := $(ARCHCXXFLAGS) $(ARCHOPTIMIZATION) $(ARCHCPUFLAGS) $(ARCHXXINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS)
CXXPICFLAGS = $(ARCHPICFLAGS) $(CXXFLAGS)
CPPFLAGS := $(ARCHINCLUDES) $(ARCHDEFINES) $(EXTRAFLAGS)
AFLAGS := $(CFLAGS) -D__ASSEMBLY__
# Loadable module definitions
CMODULEFLAGS = $(CFLAGS)
LDMODULEFLAGS = -melf32lriscv -r -e module_initialize
LDMODULEFLAGS += -T $(call CONVERT_PATH,$(TOPDIR)/libs/libc/elf/gnu-elf.ld)
# ELF module definitions
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)