From 3dc80527ab3dc0d7cc0960cb197cf06ae9634754 Mon Sep 17 00:00:00 2001 From: Mahavir Jain Date: Fri, 12 Jul 2024 11:50:17 +0530 Subject: [PATCH] feat: add compiler config for not merging const sections Probably GCC-13.x and on-wards uses "-fmerge-constants" to merge the const section (string/floating-point) across compilation units. This makes it difficult to properly analyze the size output of rodata section across libraries, the merged section (big in size) is showed across a single library. The config option added here can help to disable this compiler behavior and help to provide better size analysis. It can be used during development phase only as it increases rodata section size. --- CMakeLists.txt | 4 ++++ Kconfig | 9 +++++++++ docs/en/api-guides/tools/idf-size.rst | 2 +- .../system/build_test/sdkconfig.ci.no_merge_constants | 1 + 4 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 tools/test_apps/system/build_test/sdkconfig.ci.no_merge_constants diff --git a/CMakeLists.txt b/CMakeLists.txt index b381db8484..6cedae7de3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -136,6 +136,10 @@ if(CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_DISABLE) list(APPEND compile_definitions "-DNDEBUG") endif() +if(CONFIG_COMPILER_NO_MERGE_CONSTANTS) + list(APPEND compile_options "-fno-merge-constants") +endif() + if(CONFIG_COMPILER_STACK_CHECK_MODE_NORM) list(APPEND compile_options "-fstack-protector") elseif(CONFIG_COMPILER_STACK_CHECK_MODE_STRONG) diff --git a/Kconfig b/Kconfig index b5c529cbeb..244a1f9e5e 100644 --- a/Kconfig +++ b/Kconfig @@ -514,6 +514,15 @@ mainmenu "Espressif IoT Development Framework Configuration" help Stack smashing protection. + config COMPILER_NO_MERGE_CONSTANTS + bool "Disable merging const sections" + depends on IDF_TOOLCHAIN_GCC + help + Disable merging identical constants (string/floating-point) across compilation units. + This helps in better size analysis of the application binary as the rodata section + distribution is more uniform across libraries. On downside, it may increase + the binary size and hence should be used during development phase only. + config COMPILER_WARN_WRITE_STRINGS bool "Enable -Wwrite-strings warning flag" default "n" diff --git a/docs/en/api-guides/tools/idf-size.rst b/docs/en/api-guides/tools/idf-size.rst index d456f5392e..0d5741621f 100644 --- a/docs/en/api-guides/tools/idf-size.rst +++ b/docs/en/api-guides/tools/idf-size.rst @@ -136,7 +136,7 @@ The table is sorted in descending order of the total contribution of the static .. note:: - The size of the ``.rodata`` section in the ``Flash Data`` memory type may appear very large for a single archive. This occurs due to linker relaxations. The linker may attempt to combine object file sections with ``MERGE`` and ``STRINGS`` flags from all archives into one to perform tail string optimization. Consequently, one archive may end up with a very large ``.rodata`` section, containing string literals from other archives. This is evident in the ``.rodata`` section of the ``libesp_app_format.a`` archive. + The size of the ``.rodata`` section in the ``Flash Data`` memory type may appear very large for a single archive. This occurs due to linker relaxations. The linker may attempt to combine object file sections with ``MERGE`` and ``STRINGS`` flags from all archives into one to perform tail string optimization. Consequently, one archive may end up with a very large ``.rodata`` section, containing string literals from other archives. This is evident in the ``.rodata`` section of the ``libesp_app_format.a`` archive. The specific compiler behavior here can be turned off by enabling :ref:`CONFIG_COMPILER_NO_MERGE_CONSTANTS` option (only for GCC toolchain), please read help for more details. Source File Usage Summary ``idf.py size-files`` diff --git a/tools/test_apps/system/build_test/sdkconfig.ci.no_merge_constants b/tools/test_apps/system/build_test/sdkconfig.ci.no_merge_constants new file mode 100644 index 0000000000..d30e4da72b --- /dev/null +++ b/tools/test_apps/system/build_test/sdkconfig.ci.no_merge_constants @@ -0,0 +1 @@ +CONFIG_COMPILER_NO_MERGE_CONSTANTS=y