Re: __stack_start for ColdFire uClinux
Larry Baker <[email protected]>
| Newsgroups | gmane.linux.uclinux.devel |
|---|---|
| Message-ID | <[email protected]> |
Greg,
I hacked the .s file for my stack check test program.
The C code:
> # cat 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;
>
> }
# toolchains/freescale-coldfire-2011.09-patched/bin/m68k-uclinux-gcc -mcpu=5208 -fomit-frame-pointer -fno-common -fno-builtin -fno-dwarf2-cfi-asm -msep-data -fstack-limit-symbol=__stack_start -S -o stack-overflow.s stack-overflow.c
The original .s file:
> # cat stack-overflow.s
> #NO_APP
> .file "stack-overflow.c"
> .section .rodata
> .LC0:
> .string "i = %i\n"
> .text
> .align 2
> .globl overflow
> .type overflow, @function
> overflow:
> move.l __stack_start@GOT(%a5),%a0
> lea (1028,%a0),%a0
> cmp.l %sp,%a0
> bls.s .+4
> trap #7
> lea (-1024,%sp),%sp
> move.l %a5,-(%sp)
> addq.l #1,1032(%sp)
> move.l .LC0@GOT(%a5),%d0
> move.l 1032(%sp),-(%sp)
> move.l %d0,-(%sp)
> move.l printf@GOT(%a5),%d0
> move.l %d0,%a0
> jsr (%a0)
> addq.l #8,%sp
> move.l 1032(%sp),-(%sp)
> move.l overflow@GOT(%a5),%d0
> move.l %d0,%a0
> jsr (%a0)
> addq.l #4,%sp
> move.l (%sp)+,%a5
> lea (1024,%sp),%sp
> rts
> .size overflow, .-overflow
> .align 2
> .globl main
> .type main, @function
> main:
> move.l __stack_start@GOT(%a5),%a0
> addq.l #4,%a0
> cmp.l %sp,%a0
> bls.s .+4
> trap #7
> move.l %a5,-(%sp)
> clr.l -(%sp)
> move.l overflow@GOT(%a5),%d0
> move.l %d0,%a0
> jsr (%a0)
> addq.l #4,%sp
> clr.l %d0
> move.l (%sp)+,%a5
> rts
> .size main, .-main
> .ident "GCC: (GNU) 4.6.1 20120905 (patched)"
> .section .note.GNU-stack,"",@progbits
My hacked .s file to add printf's:
> # cat stack-overflow.s
> #NO_APP
> .file "stack-overflow.c"
> .section .rodata
> .LC0:
> .string "i = %i\n"
> .LC1:
> .string "__stack_start = %p\n"
> .LC2:
> .string "%%sp = %p\n"
> .text
> .align 2
> .globl overflow
> .type overflow, @function
> overflow:
> move.l __stack_start@GOT(%a5),%a0
> lea (1028,%a0),%a0
> cmp.l %sp,%a0
> bls.s .+4
> trap #7
> lea (-1024,%sp),%sp
> move.l %a5,-(%sp)
> addq.l #1,1032(%sp)
> move.l .LC0@GOT(%a5),%d0
> move.l 1032(%sp),-(%sp)
> move.l %d0,-(%sp)
> move.l printf@GOT(%a5),%d0
> move.l %d0,%a0
> jsr (%a0)
> addq.l #8,%sp
> move.l %sp,-(%sp)
> move.l .LC2@GOT(%a5),-(%sp)
> move.l printf@GOT(%a5),%a0
> jsr (%a0)
> addq.l #8,%sp
> move.l 1032(%sp),-(%sp)
> move.l overflow@GOT(%a5),%d0
> move.l %d0,%a0
> jsr (%a0)
> addq.l #4,%sp
> move.l (%sp)+,%a5
> lea (1024,%sp),%sp
> rts
> .size overflow, .-overflow
> .align 2
> .globl main
> .type main, @function
> main:
> move.l __stack_start@GOT(%a5),%a0
> addq.l #4,%a0
> cmp.l %sp,%a0
> bls.s .+4
> trap #7
> move.l %a5,-(%sp)
> move.l __stack_start@GOT(%a5),-(%sp)
> move.l .LC1@GOT(%a5),-(%sp)
> move.l printf@GOT(%a5),%a0
> jsr (%a0)
> addq.l #8,%sp
> move.l %sp,-(%sp)
> move.l .LC2@GOT(%a5),-(%sp)
> move.l printf@GOT(%a5),%a0
> jsr (%a0)
> addq.l #8,%sp
> clr.l -(%sp)
> move.l overflow@GOT(%a5),%d0
> move.l %d0,%a0
> jsr (%a0)
> addq.l #4,%sp
> clr.l %d0
> move.l (%sp)+,%a5
> rts
> .size main, .-main
> .ident "GCC: (GNU) 4.6.1 20120905 (patched)"
> .section .note.GNU-stack,"",@progbits
# toolchains/freescale-coldfire-2011.09-patched/bin/m68k-uclinux-gcc -mcpu=5208 -fomit-frame-pointer -fno-common -fno-builtin -fno-dwarf2-cfi-asm -msep-data -fstack-limit-symbol=__stack_start -o check-stack-overflow stack-overflow.s
When I run the hacked version, the stack pointer is nowhere near __stack_start, yet I suspect a stack overflow has clobbered something and caused the hardware watchdog timer to trip:
> / # /usr/bin/check-stack-overflow
> __stack_start = 0x406148b4
> %sp = 0x40617ee4
> i = 1
> %sp = 0x40617ad8
> i = 2
> %sp = 0x406176cc
> i = 3
> %sp = 0x406172c0
> i = 4
> %sp = 0x40616eb4
> i = 5
> %sp = 0x40616aa8
> i = 6
> %s
>
> Watchdog Timer Reset
There must be code between __stack_start and the initial stack pointer. Yes? binfmt_flat.c knows all? By the way, where is binfmt_flat.c?
I'm on vacation for five days. I'll pick this up again when I get back.
Thanks,
Larry Baker
US Geological Survey
650-329-5608
[email protected]
_______________________________________________
uClinux-dev mailing list
[email protected]
http://mailman.uclinux.org/mailman/listinfo/uclinux-dev
This message was resent by [email protected]
To unsubscribe see:
http://mailman.uclinux.org/mailman/options/uclinux-dev