On Tue, May 15, 2018 at 1:38 AM Julius Werner <jwer...@chromium.org> wrote:
> Hi, > I'm a firmware/embedded engineer and frequently run into cases where > certain parts of the code need to be placed in a special memory area (for > example, because the area that contains the other code is not yet > initialized or currently inaccessible). My go-to method to solve this is to > mark all functions and globals used by this code with > __attribute__((section)), and using a linker script to map those special > sections to the desired area. This mostly works pretty well. > However, I just found an issue with this when the functions include local > variables like this: > const int some_array[] = { 1, 2, 3, 4, 5, 6 }; > In this case (and with -Os optimization), GCC seems to automatically > reserve some space in the .rodata section to place the array, and the > generated code accesses it there. Of course this breaks my use case if the > generic .rodata section is inaccessible while that function executes. I > have not found any way to work around this without either rewriting the > code to completely avoid those constructs, or manipulating sections > manually at the linker level (in particular, you can't just mark the array > itself with __attribute__((section)), since that attribute is not legal for > locals). > Is this intentional, and if so, does it make sense that it is? I can > understand that it may technically be compliant with the description of > __attribute__((section)) in the GCC manual -- but I think the use case I'm > trying to solve is one of the most common uses of that attribute, and it > seems to become completely impossible due to this. Wouldn't it make more > sense and be more useful if __attribute__((section)) meant "place > *everything* generated as part of this function source code into that > section"? Or at least offer some sort of other extension to be able to > control section placement for those special constants? (Note that GCC > usually seems to place constants for individual variables in the text > section, simply behind the epilogue of the function... so it's also quite > unclear to me why arrays get treated differently at all.) > Apart from this issue, this behavior also seems to "break" > -ffunction-sections/-fdata-sections. Even with both of those set, these > sorts of constants seem to get placed into the same big, common .rodata > section (as opposed to either .text.functionname or .rodata.functionname as > you'd expect). That means that they won't get collected when linking the > binary with --gc-sections and will bloat the code size for projects that > link a lot of code opportunistically and rely on --gc-sections to drop > everything that's not needed for the current configuration. > Is there some clever trick that I missed to work around this, or is this > really not possible with the current GCC? And if so, would you agree that > this is a valid problem that GCC should provide a solution for (in some > form or another)? I think you are asking for per-function constant pool sections. Because we generally cannot avoid the need of a constant pool and dependent on the target that is always global. Note with per-function constant pools you will not benefit from constant pool entry merging across functions. I'm also not aware of any non-target-specific (and thus not implemented on some targets) option to get these. Richard. > Thanks, > Julius