Bug - Teensy 3.0 linker script causes .bss to overlap heap

Bill Greiman

Well-known member
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:
Code:
	.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:
Code:
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.
Code:
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:
Code:
	.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.
 
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. :)
 
Back
Top