PDA

View Full Version : Bug - Teensy 3.0 linker script causes .bss to overlap heap



Bill Greiman
11-11-2012, 05:04 PM
I have been chasing several bugs with corrupted memory. It finally dawned on me that global variables were in the heap/stack area.

I added the symbol _end after the .bss section in mk20dx128.ld like this:



.bss : {
. = ALIGN(4);
_sbss = .;
*(.bss*)
. = ALIGN(4);
_ebss = .;
} > RAM
. = ALIGN(4); /* added by Bill Greiman*/
_end = . ; /* added by Bill Greiman*/
_estack = ORIGIN(RAM) + LENGTH(RAM);
}

And ran the following sketch:


extern unsigned long _ebss;
extern unsigned long _end;
void setup() {
Serial.begin(9600);
while(!Serial) {}
delay(2000);
Serial.print("&_ebss ");
Serial.println((int)&_ebss, HEX);
Serial.print("&_end ");
Serial.println((int)&_end, HEX);
}
void loop() {}

The result is:


&_ebss 1FFFEB34
&_end 1FFFEB60

So something is loaded after _ebss. The problem is that _sbrk() in mk20dx128.c assumes the heap starts at _ebss.


void * _sbrk(int incr)
{
static char *heap_end = (char *)&_ebss;
char *prev = heap_end;

heap_end += incr;
return prev;
}


If I add other libraries the difference is greater.

If I add *(COMMON) to the .bss section in mk20dx128.ld like this:


.bss : {
. = ALIGN(4);
_sbss = .;
*(.bss*)
*(COMMON) /* added by Bill Greiman*/
. = ALIGN(4);
_ebss = .;
} > RAM
. = ALIGN(4); /* added by Bill Greiman*/
_end = . ; /* added by Bill Greiman*/
_estack = ORIGIN(RAM) + LENGTH(RAM);
}

I get the correct result:


&_ebss 1FFFEB60
&_end 1FFFEB60


And my memory problems are fixed.

I noticed other linker scripts for CM4 add other stuff to the bss section so this fix may not be correct.

cmason
11-11-2012, 07:28 PM
Nice work!

-c

Paul
11-11-2012, 10:06 PM
Wow, great catch Bill. I didn't realize the linker was locating more stuff where the heap should begin!

I'm testing USB Keyboard now. I was going to do Mouse, Joystick and maybe MIDI... but this is a pretty serious bug, so I'll get "beta8" out right away.

Thanks for putting so much hard work into this. :)