Dmitry Adamushko wrote: > >Was this example generated by a real world compiler? (Which one?) > > [adamushkad@cplx219]/>mips-linux-uclibc-gcc -v > Reading specs from > /vobs/linux/tools/mips/gcc-3.4.2/bin/../lib/gcc/mips-linux-uclibc/3.4.2/specs > Configured with: > /vobs/linux/tools/buildroot/toolchain_build_mips/gcc-3.4.2/configure > --prefix=/vobs/linux/tools/buildroot/build_mips/staging_dir > --build=i386-pc-linux-gnu > --host=i386-pc-linux-gnu > --target=mips-linux-uclibc > --enable-languages=c,c++ > --enable-shared > --disable-__cxa_atexit > --enable-target-optspace > -with-gnu-ld > --disable-nls > --enable-multilib > Thread model: posix > > gcc version 3.4.2 I figure it doesn't create such an zero access as shown in the example. > >I'm inclined to claim the example is broken WRT ABI rules since it > >doesn't enclose the whole user code in the prologue/epilogue bracket. > > > > It's o32. So it explicitly requires that when the prologue and > epilogue have been used in the function, all the user code must be > place in between, right? That's basically the definition of "prologue" and "epilogue". > In this light, the unlike(ofs == 0) in unwind_stack() aims at catching > cases when <sp> is wrong (if addiu sp,sp,OFFSET is normally the very > first instruction) Technically it is probably ok, since the o32 ABI covers only PIC code, while the kernel is non-PIC. > ok, here is an example from kernel/sched.o (the same compiler). > > 00000098 <enqueue_task>: > 98: 8c820018 lw v0,24(a0) <----- before the > prologue > 9c: 27bdfff8 addiu sp,sp,-8 > a0: afbe0000 sw s8,0(sp) > a4: 000210c0 sll v0,v0,0x3 > a8: 00a21021 addu v0,a1,v0 > ac: 24420018 addiu v0,v0,24 > b0: 8c460004 lw a2,4(v0) > b4: 24830020 addiu v1,a0,32 > b8: ac430004 sw v1,4(v0) > bc: ac820020 sw v0,32(a0) > c0: ac660004 sw a2,4(v1) > c4: acc30000 sw v1,0(a2) > c8: 8c860018 lw a2,24(a0) > cc: 24a70004 addiu a3,a1,4 > d0: 03a0f021 move s8,sp > d4: 00061142 srl v0,a2,0x5 > d8: 00021080 sll v0,v0,0x2 > dc: 00e23821 addu a3,a3,v0 > e0: 8ce30000 lw v1,0(a3) > e4: 30c6001f andi a2,a2,0x1f > e8: 24020001 li v0,1 > ec: 00c21004 sllv v0,v0,a2 > f0: 00621825 or v1,v1,v0 > f4: ace30000 sw v1,0(a3) > f8: 8ca20000 lw v0,0(a1) > fc: 03c0e821 move sp,s8 > 100: 8fbe0000 lw s8,0(sp) > 104: 24420001 addiu v0,v0,1 > 108: 27bd0008 addiu sp,sp,8 > 10c: aca20000 sw v0,0(a1) > 110: 03e00008 jr ra > 114: ac850028 sw a1,40(a0) <------------ > after the epilogue It looks rather broken, given that the stack frame is only used to pointlessly push s8 around. The compiler should have optimized it away. > As I can see, normally this compiler places "addiu sp,sp,FRAME_SIZE" > at the branch delay slot of "jr ra" but e.g. enqueue_task() (example > above) and request_task() are exceptions. btw, the very first > instruction is also placed before the epilogue. > > Are there any configure options that might have caused such a > behaviour [hmmm... e.g. gcc was configured with --ignore-abi-rulles :] > ? Although, I don't think this would be an option-dependent case. Well, breakage happens from time to time in gcc. To cover such cases it would be nice to have a more robust stack unwinder, but that's easier said than done. Thiemo