https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78903
Bug ID: 78903 Summary: __attribute__((section(".ram"))) ignored with -Os or -flto Product: gcc Version: 6.2.1 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c Assignee: unassigned at gcc dot gnu.org Reporter: chrysn at fsfe dot org Target Milestone: --- Created attachment 40400 --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40400&action=edit example for amd64 linux where a function in should-be-crashing .data is inlined into regular text When function calls are inlined due to -Os or -flto, an __attribute__((section(".ram"))) gets ignored. This bites for example when GCC somewhere before 5.4 started inlining flash writing sequences on ARM CortexM3 EFM32 chips in emlib where such an attribute should have made sure that the flash is not accessed for program code during the flash operation; there, it surfaced due to link time optimization. I've created a minimal test case that seems equivalent to me, it is attached as test.c. Instead of moving code to RAM like in the original but harder-to-reproduce example on ARM, it is placing a test function `f()` in ".data", which on my system makes the program segfault when the f is invoked. When compiled without optimizations ("gcc-7 test.c -o test"), the resulting program crashes as expected, probably trying to execute ".data" and running into protections. In the original microcontroller example, that crash would have been a successful execution from RAM. With "gcc-7 -Os test.c -o test", the call to `f()` is inlined and the program exits successfully. In the original example, this would have a concurrent access to flash and would have caused some undefined state in the processor. In both cases, the compiler outputs "Warning: ignoring changed section attributes for .data"; there is no equivalent output in the original ARM example as ".ram" is a valid section there in the linker script. My build system is Debian sid on amd64 running linux 4.9.0-rc8. The behavior was obsered on arm-none-eabi-gcc 5.4, and on "regular" (amd64 debian built) gcc 6.2.1-7 and 7-20161217-1. As a workaround, I'm currently marking the function __attribute__((noinline)). I might be having a "x-y problem" with the compiler here as my main intention is "keep your $pc off flash until this call returns" but I tell it "copy this to ram" and thus need to enhance the instructions to "and don't place copies anywhere else" and would appreciate suggestions on how to do it better, but __attribute__((section(".ram"))) seems to be the accepted way of doing it. A short inquery on freenode/#gcc indicated that this might be an optimizer bug.