I have been trying to figure out why my .noinit data is getting cleared on startup, but not having any luck. I have a tiny416 and mega4809, both show the same problem.
The following is a minimal piece of code to demonstrate my problem-
//attiny416, mplabx 5.15, xc8 2.05, gcc 5.4.0 //turn off ld garbage collection of unused sections for this test //====================== // .noinit test //====================== char data_var = 4; char bss_var; char noinit_var __attribute(( section(".noinit") )); int main(void) { for(;;){} } /* result ====================== 00803f01 g O .noinit 00000001 noinit_var 00803f02 g O .data 00000001 data_var 00803f00 g O .bss 00000001 bss_var 00000034 <.dinit>: //my comments added 34: 3f 02 0x3f02 - start of data 36: 3f 03 0x3f03 - end of data 38: 00 00 0x00 = do load data 3a: a2 3f from flash starting at 0x00a2 3c: 01 3f 0x3f01 - start of .noinit 3e: 02 80 0x3f02 - end of .noinit, 0x80 = do clear bss 40: 3f 00 0x3f00 - start of bss 42: 3f 01 0x3f01 - end of bss 44: 80 00 0x80 = do clear bss */
the data init code from libgcc uses the .dinit data shown above to run through sections of data/bss- either initializing data from flash or clearing ram (bss). The clearing of bss is indicated by a starting and ending address followed by 0x80 (bit 7 set). Initialized data has a starting and ending address, a 0x00 (bit 7 clear) and a starting flash address.
Why the .noinit section address is showing up in .dinit, I guess is the question. Maybe I'm doing something obviously wrong, or its a known problem, or ? I downloaded gcc/binutils source code for these versions (I think), but that's always an exercise in trying to read obfuscated code and usually I am left wondering why it works at all. I grep a bunch, but there is not much to be found for '.noinit', and nothing to be found for '.dinit' (something/somewhere is producing that section). I'm not even sure I'm looking at the right libgcc source code as it doesn't really match up with what I'm seeing for init code (mine loads values from .dinit, and it looks like libgcc source I'm looking at uses hard coded values).
This is what the produced .s file looks like (--save-temps)-
.file "newmain.c" __SP_H__ = 0x3e __SP_L__ = 0x3d __SREG__ = 0x3f __CCP__ = 0x34 __tmp_reg__ = 0 __zero_reg__ = 1 .section .text.startup.main,code .global main .type main, @function main: /* prologue: function */ /* frame size = 0 */ /* stack size = 0 */ .L__stack_usage = 0 .L2: rjmp .L2 .size main, .-main .global noinit_var .section .noinit,bss .type noinit_var, @object .size noinit_var, 1 noinit_var: .zero 1 .comm bss_var,1,1 .global data_var .section .data.data_var,data .type data_var, @object .size data_var, 1 data_var: .byte 4 .ident "GCC: (AVR_8_bit_GNU_Toolchain_3.6.2_122) 5.4.0" .global __do_copy_data .global __do_clear_bss
that noinit_var section doesn't look right (shouldn't @progbits be specified or something?)
Any suggestions? I can come up with various ways to get equivalent of noinit data, but just want to find out why .noinit section is not working in my case.