I was reordering memory layout and I wanted layout which places my custom section as the first data section, then .data section immediately after that.
I learned after many hours wasted that no matter what I do, start address of .data section is *hardcoded*, no matter what I do in my linker file. Ugh. Okay, so I've figured that the file which defines this is specs-<mcu_name>, so for atmega32u4, the file contains, among other things, this:
*link_data_start: -Tdata 0x800100
Why the value in linker file is overwritten with this is beyond me. Nevertheless, I've figured there might be a way to override the inclusion of this spec file with my own which doesn't define start address of .data. Looking at the avr-gcc --help I've seen this:
-specs=<file> Override built-in specs with the contents of <file>
Yay! Immediately, I've copied the specs file to my project dir, removed the link_data_start and compiled with avr-gcc <flags> -specs=<path/to/my/specs/file>
Looking at the generated .map file, I see that the .data address is again the same. Removing the link_data_start in the original file results in correct .data address, which suggests that:
1)overriding is broken
2) user-specified specs file doesn't override original one so this is a documentation issue.
I've tried to delete the original file, but then avr-gcc doesn't want to run at all:
laptop:src testing$ avr-gcc -mmcu=atmega32u4 -specs=board/avr/variants/atmega32u4/specs-atmega32u4 -v Using built-in specs. Reading specs from board/avr/variants/atmega32u4/specs-atmega32u4 Reading specs from device-specs/specs-atmega32u4 avr-gcc: error: device-specs/specs-atmega32u4: No such file or directory
It's frustrating that the avr-gcc is so insistent on this "magic".
Before others suggest that I simply pass -T flag with my .data start address: I do not know which address it will be - it depends on the size of the first section in data region. It's linkers job to determine that, not mine.
I've temporarily "fixed" this issue by renaming .data section in linker file with ".mydata" which works. The issue with this is that avr-size doesn't report correct RAM usage in this case since it only counts .data, .bss and .noinit.