Subject: User profiling bugs
To: None <port-mips@netbsd.org>
From: Ethan Solomita <ethan@geocast.com>
List: port-mips
Date: 04/25/2000 02:37:15
Now that I've got my mips.h in gcc updated, hopefully I can make
*useful* observations again. I think I've found another set of problems
with the compiler/assembler/linker/whatever which is causing profiling
to fail.
Here's the disassembly of sbrk() from libc_p.a. It is identical to
sbrk() from libc.a except for five instructions added to the beginning
of the function which call _mcount(). It'll be clear what the problem is
-- the main body of sbrk() generates $gp based upon $t9 (it's own
address), however those 5 inserted instructions change $t9 to be the
address of _mcount(), leading to the wrong calculation of $gp.
0x47d910 <sbrk>: move $at,$ra
0x47d914 <sbrk+4>: lw $t9,-32636($gp)
0x47d918 <sbrk+8>: nop
0x47d91c <sbrk+12>: jalr $t9
0x47d920 <sbrk+16>: addiu $sp,$sp,-8
0x47d924 <sbrk+20>: lui $gp,0xfb9
0x47d928 <sbrk+24>: addiu $gp,$gp,-10388
0x47d92c <sbrk+28>: addu $gp,$gp,$t9
0
It does nothing to save values on the stack before calling _mcount. One
thing to note is that sbrk comes from sbrk.S -- ie. it's an assembler
code routine, not C source. Here's strchr(), which is based upon C
source:
0x47da64 <strchr>: lui $gp,0xfb9
0x47da68 <strchr+4>: addiu $gp,$gp,-10708
0x47da6c <strchr+8>: addu $gp,$gp,$t9
0x47da70 <strchr+12>: addiu $sp,$sp,-16
0x47da74 <strchr+16>: sw $gp,0($sp)
0x47da78 <strchr+20>: sw $gp,8($sp)
0x47da7c <strchr+24>: move $at,$ra
0x47da80 <strchr+28>: addiu $sp,$sp,-8
0x47da84 <strchr+32>: lw $t9,-32636($gp)
0x47da88 <strchr+36>: nop
0x47da8c <strchr+40>: jalr $t9
0x47da90 <strchr+44>: nop
0x47da94 <strchr+48>: lw $gp,0($sp)
0x47da98 <strchr+52>: nop
Note that the C-based code first generates $gp, then saves it
(twice???) onto the stack, then calls _mcount, and then restores $gp. Do
any of you have more clues than I, and know where to look for this?
Thanks!
-- Ethan