Larry Baker
2012-09-26 02:49:17 UTC
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). 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 = .;
}
.junk 0 : { *(.rel*) *(.rela*) }
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_info 0 : { *(.debug_info) }
.debug_line 0 : { *(.debug_line) }
.debug_pubnames 0 : { *(.debug_pubnames) }
.debug_aranges 0 : { *(.debug_aranges) }
Is stack: in the wrong place?
Larry Baker
US Geological Survey
650-329-5608
baker at usgs.gov
#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). 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 = .;
}
.junk 0 : { *(.rel*) *(.rela*) }
/* Stabs debugging sections. */
.stab 0 : { *(.stab) }
.stabstr 0 : { *(.stabstr) }
.stab.excl 0 : { *(.stab.excl) }
.stab.exclstr 0 : { *(.stab.exclstr) }
.stab.index 0 : { *(.stab.index) }
.stab.indexstr 0 : { *(.stab.indexstr) }
.comment 0 : { *(.comment) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_info 0 : { *(.debug_info) }
.debug_line 0 : { *(.debug_line) }
.debug_pubnames 0 : { *(.debug_pubnames) }
.debug_aranges 0 : { *(.debug_aranges) }
Is stack: in the wrong place?
Larry Baker
US Geological Survey
650-329-5608
baker at usgs.gov