[uClinux-dev] __stack_start for ColdFire uClinux

Greg Ungerer gerg at snapgear.com
Wed Sep 26 08:48:17 EDT 2012


Hi Larry,

On 09/26/2012 12:49 PM, Larry Baker wrote:
> I have been chasing what I suspect are stack overflows in NTP.  I spotted mention of that there was a gcc option, -fstack-check-symbol=__stack_start, for run-time stack checking on uClinux.  I tried that, but it caused an internal compiler error.  My development environment is the Sourcery (now Mentor Graphics) CodeBench Lite for ColdFire uClinux SDK.  I modified their GCC source to add support for -fstack-limit-symbol.  Unfortunately, using the __stack_start symbol to detect stack overflow does not seem to be working out.  For my test uClinux executable, stack-overflow.c:
>
> #include <stdio.h>
>
> void overflow( int i ) {
>
> /* Allocate automatic array j[256] so stack limit checking works. */
>
>     int j[256];
>
> /* Stack limit checking tests only whether the stack is large enough for  */
> /* the initial stack allocation: saved registers and automatic variables. */
> /* Stack limit checking does not test for stack overflow in the body of a */
> /* function.  That is what happens when j[] is not present.  When j[] is  */
> /* too large, the program will abnormally terminate on its own (illegal   */
> /* instruction trap?).  j[256] works.                                     */
>
>     i++;
>     printf( "i = %i\n", i );
>     overflow( i );
>
> }
>
> int main() {
>
>     overflow( 0 );
>
>     return 0;
>
> }
>
> the stack is allocated 4K (0x1000).

How are you setting the app stack size?


>  When I hacked the .s file to print out the stack pointer and __stack start, it shows that there is more than 4K between the value in the stack pointer and __stack_start:
>
> %sp = 0x405f3ee4
> __stack_start = 0x405f08b4
>
> That is not what I was expecting.
>
> Can someone shed some light on why %sp is not roughly __stack_start + 0x1000?
>
> __stack_start is defined in the linker script from the Sourcery SDK, m68k-uclinux/lib/elf2flt.ld, right after .bss and before .junk:
>
> 	.bss : {
> 		. = ALIGN(0x4) ;
> 		_sbss = ALIGN(0x4) ;
> 		__bss_start = . ;
> 		*(.dynsbss)
> 		*(.sbss)
> 		*(.sbss.*)
> 		*(.scommon)
> 		*(.dynbss)
> 		*(.bss)
> 		*(.bss.*)
> 		*(.bss*)
> 		*(.gnu.linkonce.b*)
> 		*(COMMON)
> 		. = ALIGN(0x10) ;
> 		_ebss = . ;
> 		_end = . ;
> 		end = . ;
> 	} > flatmem
>
> 	.stack : {
> 		. = ALIGN(0x4);
> 		__stack_start = .;
> 	}

This is a little deceptive, and not completely accurate in general.

If you look at what binfmt_flat.c does when loading a flat format file
you will see that that point is labeled the start of the "brk" region.
When allocating the memory for the process (text, data, stack) we may
get a larger region than requested(1). We use the extra space if we get
it, and that will push the stack further away from the end of the data
region if we do. This is probably what you are seeing. A little trace
in binfmt_flat.c will let you see the exact regions and addresses you
are getting on process start.

(1) Page aligning or buddy allocator rounding means we may get a bit
     more, or even potentially a lot more.

Regards
Greg


------------------------------------------------------------------------
Greg Ungerer  --  Principal Engineer        EMAIL:     gerg at snapgear.com
SnapGear Group, McAfee                      PHONE:       +61 7 3435 2888
8 Gardner Close,                            FAX:         +61 7 3891 3630
Milton, QLD, 4064, Australia                WEB: http://www.SnapGear.com



More information about the uClinux-dev mailing list