This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
Bug in calling conventions on alpha*-dec-osf* (was Re: Stepping over functions in gdb fails on alphaev56-dec-osf5.0)
- To: gcc-bugs at gcc dot gnu dot org
- Subject: Bug in calling conventions on alpha*-dec-osf* (was Re: Stepping over functions in gdb fails on alphaev56-dec-osf5.0)
- From: Andrew Hobson <ahobson at eng dot mindspring dot net>
- Date: 02 Mar 2000 11:17:14 -0500
- References: <kjbt5nvf9x.fsf@gamma.eng.mindspring.net>
On 11 Feb 2000 12:07:54 -0500, Andrew Hobson <ahobson@eng.mindspring.net> said:
> I'm not positive this is a bug in gcc; it might be a bug in gdb.
Okay, now I'm sure it's a bug in gcc.
> $ cat t.c
> void
> bar(void)
> {
> }
>
> void
> foo(void)
> {
> bar();
> }
> int
> main(int argc, char *argv[])
> {
> bar(); /* next fine */
> foo(); /* next broken */
> return 0;
> }
> $ gcc -v --save-temps -g t.c -o t
> Reading specs from /usr/local/lib/gcc-lib/alphaev56-dec-osf5.0/2.96/specs
> gcc version 2.96 20000207 (experimental)
> /usr/local/lib/gcc-lib/alphaev56-dec-osf5.0/2.96/cpp -lang-c -v -D__GNUC__=2 -D__GNUC_MINOR__=96 -Dunix -D__osf__ -D_LONGLONG -DSYSTYPE_BSD -D_SYSTYPE_BSD -D__unix__ -D__osf__ -D_LONGLONG -D__SYSTYPE_BSD__ -D_SYSTYPE_BSD -D__unix -D__SYSTYPE_BSD -Asystem(unix) -Asystem(xpg4) -g -D__LANGUAGE_C__ -D__LANGUAGE_C -DLANGUAGE_C -Acpu(alpha) -Amachine(alpha) -D__alpha -D__alpha__ -D__alpha_ev5__ -Acpu(ev5) -D__alpha_bwx__ -Acpu(bwx) t.c t.i
> GNU CPP version 2.96 20000207 (experimental) (cpplib)
> #include "..." search starts here:
> #include <...> search starts here:
> /usr/local/include
> /usr/local/alphaev56-dec-osf5.0/include
> /usr/local/lib/gcc-lib/alphaev56-dec-osf5.0/2.96/include
> /usr/include
> End of search list.
> /usr/local/lib/gcc-lib/alphaev56-dec-osf5.0/2.96/cc1 t.i -quiet -dumpbase t.c -g -version -o t.s
> GNU C version 2.96 20000207 (experimental) (alphaev56-dec-osf5.0) compiled by GNU C version 2.96 20000207 (experimental).
> as -g -nocpp -O0 -o t.o t.s
> /usr/local/lib/gcc-lib/alphaev56-dec-osf5.0/2.96/mips-tfile -v -I t.o~ -o t.o t.s
> mips-tfile version 2.96 20000207 (experimental)
> /usr/local/lib/gcc-lib/alphaev56-dec-osf5.0/2.96/collect2 -G 8 -O1 -call_shared -o t /usr/lib/cmplrs/cc/crt0.o -L/usr/local/lib/gcc-lib/alphaev56-dec-osf5.0/2.96 -L/usr/lib/cmplrs/cc -L/usr/local/lib/gcc-lib/alphaev56-dec-osf5.0/2.96/../../.. t.o -lgcc -lc -lgcc
> The assembly code looks like this:
> [snip]
> bar:
> .frame $15,16,$26,0
> .mask 0x4008000,-16
> $bar..ng:
> $LM1:
> #.stabn 68,0,3,$LM1
> $LM2:
> #.stabn 68,0,4,$LM2
> [snip]
> foo:
> .frame $15,16,$26,0
> .mask 0x4008000,-16
> ldgp $29,0($27)
> $foo..ng:
> $LM3:
> #.stabn 68,0,8,$LM3
> $LM4:
> #.stabn 68,0,9,$LM4
> [snip]
> $LM7:
> #.stabn 68,0,15,$LM7
> bsr $26,$bar..ng
> $LM8:
> #.stabn 68,0,16,$LM8
> bsr $26,$foo..ng
>
> [snip]
According to
http://www.unix.digital.com/faqs/publications/base_doc/DOCUMENTATION/V50_HTML/ARH9LATE/LNKGCHPT.HTM#calling-section
and
http://www.unix.digital.com/faqs/publications/base_doc/DOCUMENTATION/V40F_HTML/APS31DTE/DOCU_012.HTM#calling_section
2.If you are writing a procedure that references static storage,
calls other procedures, uses constants greater than 31 bits in
size, or uses floating constants, you must load the $gp register
with the global pointer value for the procedure:
ldgp $gp,0($27)
Register $27 contains the procedure value (the address of this
procedure as supplied by the caller).
Since the calls to foo and bar are actually jumps to the labels
'$foo..ng' and '$bar..ng', the ldgp instruction isn't being called,
thus violating the calling conventions as documented.
Note that the documents also say:
4.To generate information used by the debugger and exception
handler, you must include a .frame directive:
.frame framereg,framesize,returnreg
The virtual frame pointer does not have a register allocated for
it. It consists of the framereg ($sp, in most cases) added to the
framesize (see step 3). Figure 6-2 shows the stack components.
So I consider the fact that the .frame directive is before the label
jumped to a bug.
I can't figure out why the '$foo..ng' convention is used at all.
I tried changing alpha.h and alpha.md so to jump to foo instead of
$foo..ng, but that caused references to global variables to fail
because $gp has been changed by the ldgp instruction.
DEC cc always offsets globals from $gp (e.g. lda $2,global($29)). If
I change alpha.md to do that, everything seems to work without
optimization.
If I compile with -O2, the optimization engine removes the offset, so
everything fails again.
Please let me know if you need more information.
Thank you,
Drew