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'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?
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)
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
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.
Thiemo
--
Best regards,
Dmitry Adamushko
|