https://gcc.gnu.org/bugzilla/show_bug.cgi?id=116489

            Bug ID: 116489
           Summary: Conflict between noinit and section __attribute__
                    makes object files (and static libraries)
                    unnecessarily large
           Product: gcc
           Version: 12.3.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: stefan.tauner at gmx dot at
  Target Milestone: ---

I am working on an embedded (--freestanding etc.) project with my own linker
script. In that I define a special section where I want to place a 4 MiB-sized
variable of type uint8_t[] (heap for FreeRTOS). To do so, I have added
"__attribute__((section(".noinit_PSRAM")))" to the variable's definition.
This CU with the variable is compiled and put into a static library that is
then linked to the final application. This works correctly.

However, the resulting .a is unnecessarily large: 4.3 MiB. I tried to reduce
this by adding the 'noinit' attribute and ran into the following error
(probably because of -Werror... didn't check TBH):

error: ignoring attribute 'section' because it conflicts with attribute
'noinit' [-Werror=attributes]

This is apparently intended behavior (cf. attr_section_exclusions in
c-attribs.cc) but I am not sure if it's strictly necessary. It's definitely not
optimal though... when using the `noinit` attribute without 'section' the
library is reduced to 216 KiB, factor 20.

Looking at the output of objdump of the respective .o file one can see the
difference is exactly as expected:

The noinit version gets its own .noinit-prefixed section (due to
-fdata-sections) and only the ALLOC flag:
 15 .noinit.ucHeap 00400000  00000000  00000000  00000308  2**0
                  ALLOC

The other one is put into the given section but additionally got the CONTENTS,
LOAD, DATA flags:
 15 .noinit_PSRAM 00400000  00000000  00000000  00000308  2**0
                  CONTENTS, ALLOC, LOAD, DATA

Of course these values are tiny nowadays but I was still wondering if the
behavior could be improved, or if gcc could somehow be convinced to do the
equivalent of 'noinit' even if 'section()' is used.

In any case, the behavior seems to be undocumented: Neither option mentions
this conflict:
 -
https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-noinit-variable-attribute
 -
https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-section-variable-attribute

Reply via email to