fix(esp_attr): avoid section type conflicts in DRAM_STR under LTO

DRAM_STR placed its backing string in a variable named __c in a section named
after DRAM_ATTR's __COUNTER__ value. Under LTO, when translation units are
merged, two such variables from different units could collide on the same name
and section, producing a "section type conflict" error.

Derive both the variable name and a dedicated .dram1.str subsection from a
single __COUNTER__ value so each DRAM_STR expansion is unique after merging.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Ivan Grokhotkov (bot)
2026-07-14 19:32:19 +02:00
co-authored by Claude Opus 4.8
parent 493a770d40
commit 351abea682
+11 -1
View File
@@ -90,7 +90,17 @@ extern "C" {
// Forces a string into DRAM instead of flash
// Use as esp_rom_printf(DRAM_STR("Hello world!\n"));
#define DRAM_STR(str) (__extension__({static const DRAM_ATTR char __c[] = (str); (const char *)&__c;}))
// The string is placed into a uniquely-named variable in a uniquely-named
// subsection of .dram1. Both names are derived from a single __COUNTER__ value.
// This avoids "section type conflict" errors under LTO, where the local static
// variables generated by DRAM_STR in different translation units would otherwise
// share the same name and the same DRAM_ATTR section name after the units are merged.
#define DRAM_STR(str) _DRAM_STR_IMPL(str, __COUNTER__)
#define _DRAM_STR_COMBINE(x, y) x ## y
#define _DRAM_STR_IMPL(str, counter) \
_DRAM_STR_IMPL2(str, _DRAM_STR_COMBINE(__c, counter), _SECTION_ATTR_IMPL(".dram1.str", counter))
#define _DRAM_STR_IMPL2(str, varname, attr) \
(__extension__({static const attr char varname[] = (str); (const char *)&varname;}))
#if CONFIG_SOC_RTC_FAST_MEM_SUPPORTED || CONFIG_SOC_RTC_SLOW_MEM_SUPPORTED
// Forces data into RTC memory. See "docs/deep-sleep-stub.rst"