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.

Reply via email to