diff --git a/CMakeLists.txt b/CMakeLists.txt index 4dae14c8cd..55c9109f90 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,6 +27,12 @@ else() list(APPEND cxx_compile_options "-fno-exceptions") endif() +if(CONFIG_COMPILER_CXX_RTTI) + list(APPEND cxx_compile_options "-frtti") +else() + list(APPEND cxx_compile_options "-fno-rtti") +endif() + if(CONFIG_COMPILER_DISABLE_GCC8_WARNINGS) list(APPEND compile_options "-Wno-parentheses" "-Wno-sizeof-pointer-memaccess" diff --git a/Kconfig b/Kconfig index 92c76c38d5..815f87d072 100644 --- a/Kconfig +++ b/Kconfig @@ -237,6 +237,15 @@ mainmenu "Espressif IoT Development Framework Configuration" Size (in bytes) of the emergency memory pool for C++ exceptions. This pool will be used to allocate memory for thrown exceptions when there is not enough memory on the heap. + config COMPILER_CXX_RTTI + # Invisible option, until the toolchain with RTTI support is released. + # Use prompt "Enable C++ run-time type info (RTTI)" when updating. + bool + help + Enabling this option compiles all C++ files with RTTI support enabled. + This increases binary size (typically by tens of kB) but allows using + dynamic_cast conversion and typeid operator. + choice COMPILER_STACK_CHECK_MODE prompt "Stack smashing protection mode" default COMPILER_STACK_CHECK_MODE_NONE diff --git a/components/esp32/CMakeLists.txt b/components/esp32/CMakeLists.txt index 7d9ad3872d..70a3805939 100644 --- a/components/esp32/CMakeLists.txt +++ b/components/esp32/CMakeLists.txt @@ -56,6 +56,11 @@ else() target_linker_script(${COMPONENT_LIB} INTERFACE "ld/esp32.extram.bss.ld") endif() + if(NOT CONFIG_COMPILER_CXX_RTTI) + # This has to be linked before esp32.project.ld + target_linker_script(${COMPONENT_LIB} INTERFACE "ld/esp32.discard-rtti.ld") + endif() + # Process the template file through the linker script generation mechanism, and use the output for linking the # final binary target_linker_script(${COMPONENT_LIB} INTERFACE "${CMAKE_CURRENT_LIST_DIR}/ld/esp32.project.ld.in" diff --git a/components/esp32/component.mk b/components/esp32/component.mk index 8f999b26d6..836f242e20 100644 --- a/components/esp32/component.mk +++ b/components/esp32/component.mk @@ -5,18 +5,23 @@ COMPONENT_SRCDIRS := . ifdef CONFIG_SPIRAM_ALLOW_BSS_SEG_EXTERNAL_MEMORY - # This linker script must come before esp32.project.ld - LINKER_SCRIPTS += esp32.extram.bss.ld + # This linker script must come before esp32.project.ld + LINKER_SCRIPTS += esp32.extram.bss.ld endif -#Linker scripts used to link the final application. -#Warning: These linker scripts are only used when the normal app is compiled; the bootloader -#specifies its own scripts. +ifndef CONFIG_COMPILER_CXX_RTTI + # This linker script must come before esp32.project.ld + LINKER_SCRIPTS += esp32.discard-rtti.ld +endif + +# Linker scripts used to link the final application. +# Warning: These linker scripts are only used when the normal app is compiled; the bootloader +# specifies its own scripts. LINKER_SCRIPTS += $(COMPONENT_BUILD_DIR)/esp32.project.ld esp32.peripherals.ld -#ld_include_panic_highint_hdl is added as an undefined symbol because otherwise the -#linker will ignore panic_highint_hdl.S as it has no other files depending on any -#symbols in it. +# ld_include_panic_highint_hdl is added as an undefined symbol because otherwise the +# linker will ignore panic_highint_hdl.S as it has no other files depending on any +# symbols in it. COMPONENT_ADD_LDFLAGS += -L $(COMPONENT_PATH)/ld \ -T esp32_out.ld \ -u ld_include_panic_highint_hdl \ diff --git a/components/esp32/ld/esp32.discard-rtti.ld b/components/esp32/ld/esp32.discard-rtti.ld new file mode 100644 index 0000000000..f9fdff9947 --- /dev/null +++ b/components/esp32/ld/esp32.discard-rtti.ld @@ -0,0 +1,11 @@ +/* This is only included if CONFIG_COMPILER_CXX_RTTI is not set, to + * move RTTI sections of libstdc++ to an unused non-loadable memory region. + */ + +SECTIONS +{ + .rodata.discard-rtti (NOLOAD): + { + *libstdc++.a:(.rodata._ZTI* .rodata._ZTS*) + } > discard_seg +} diff --git a/components/esp32/ld/esp32.ld b/components/esp32/ld/esp32.ld index 0400fc2ab3..cb0f14437b 100644 --- a/components/esp32/ld/esp32.ld +++ b/components/esp32/ld/esp32.ld @@ -98,6 +98,11 @@ MEMORY /* external memory ,including data and text */ extern_ram_seg(RWX) : org = 0x3F800000, len = 0x400000 + + /* This is not a memory range which can really be accessed; we use it as a "bitbucket" + where non-loadable sections, which aren't used at run time, can be discarded. + */ + discard_seg (R) : org = 0x00000000, len = 0x10000000 } #if defined(CONFIG_ESP32_USE_FIXED_STATIC_RAM_SIZE) diff --git a/make/project.mk b/make/project.mk index a8ec59f405..61e80ac068 100644 --- a/make/project.mk +++ b/make/project.mk @@ -468,7 +468,6 @@ CXXFLAGS ?= EXTRA_CXXFLAGS ?= CXXFLAGS := $(strip \ -std=gnu++11 \ - -fno-rtti \ $(OPTIMIZATION_FLAGS) $(DEBUG_FLAGS) \ $(COMMON_FLAGS) \ $(COMMON_WARNING_FLAGS) \ @@ -481,6 +480,12 @@ else CXXFLAGS += -fno-exceptions endif +ifdef CONFIG_COMPILER_CXX_RTTI +CXXFLAGS += -frtti +else +CXXFLAGS += -fno-rtti +endif + ARFLAGS := cru export CFLAGS CPPFLAGS CXXFLAGS ARFLAGS diff --git a/tools/cmake/build.cmake b/tools/cmake/build.cmake index f495ed8fa9..c3bbdeafff 100644 --- a/tools/cmake/build.cmake +++ b/tools/cmake/build.cmake @@ -114,8 +114,7 @@ function(__build_set_default_build_specifications) list(APPEND c_compile_options "-std=gnu99" "-Wno-old-style-declaration") - list(APPEND cxx_compile_options "-std=gnu++11" - "-fno-rtti") + list(APPEND cxx_compile_options "-std=gnu++11") idf_build_set_property(COMPILE_DEFINITIONS "${compile_definitions}" APPEND) idf_build_set_property(COMPILE_OPTIONS "${compile_options}" APPEND)