This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
gcc-2.95.2 hp-hpux11.00 wrong assembly directive .CALLINFO
- To: gcc-bugs at gcc dot gnu dot org
- Subject: gcc-2.95.2 hp-hpux11.00 wrong assembly directive .CALLINFO
- From: Stef Van Vlierberghe <stef dot van-vlierberghe at eurocontrol dot be>
- Date: Thu, 28 Sep 2000 3:05:07 METDST
- Cc: philippe at raven dot ifps dot cfmu dot eurocontrol dot be
Introduction :
The program problem.c illustrates how gcc does not generate the correct
assembly directives for HP's assembler (when using -mno-gas) to obtain correct
unwind descriptors.
The effect is that HP's unwind utilities may fail in any executable that
contains code generated by gcc.
I identify the problem, references the relevant documents, explain in
detail why the directives are wrong, and what they should have been,
but I am absolutely clueless on what goes on inside the gcc that generates
them.
After problem.c I've included problem.i and problem.s, but they are probably
not needed.
The relevant versions :
stef harrier ot: gcc --version
2.95.2
stef harrier ot: what `whence as`
/usr/ccs/bin/as:
HP-UX SLLIC/OPTIMIZER UX.11.01.119 (ROSE): 03/30/99
HP92453-03 UX.11.01.08 (ROSE) PA-RISC 2.0 Assembler Apr 1 1999
stef harrier ot: what `whence ld`
/usr/bin/ld:
92453-07 linker command s800.sgs ld B.11.13 REL 990903
ld_msgs.cat: $Revision: 1.85 $
stef harrier ot: what /usr/lib/libcl.a
/usr/lib/libcl.a:
libcl.a version B.11.01.02 - Oct 05, 1999
fs_amod.s $Revision: 1.9.1.1 $
Unwind Library Version UX.11.01.03(GS IB4) - November 16, 1998
Trap Library version UX.11.01.03(GS IB4) - November 16, 1998
stef harrier ot: uname -a
HP-UX harrier B.11.00 A 9000/782 2014298448 two-user license
To see how HP's cc handles the program problem.c :
stef harrier ot: cc +DA1.1 problem.c /lib/libcl.a; a.out
pc=0x00003e9f
pc=0x00003f17
pc=0x00003f4f
pc=0x00003f2b
pc=0xc013cb37
To show the problem (no output is produced when using gcc instead of cc) :
stef harrier ot: gcc -mno-gas problem.c /lib/libcl.a; a.out
stef harrier ot:
To repair the problem, one can correct the generated assembly :
gcc -mno-gas -S problem.c
Now, each line :
.CALLINFO FRAME=<size>,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=3
must be changed into :
.CALLINFO FRAME=<size>-48,CALLS,SAVE_RP
this can be done by following ksh code :
(
IFS=''
while read -r LINE
do
if [[ $LINE = *.CALLINFO* ]]
then
FSIZE=$(echo "$LINE" | sed -e 's/^.*\.CALLINFO FRAME=\(.*\),CALLS.*$/\1/')
echo "\t.CALLINFO FRAME=$(($FSIZE-48)),CALLS,SAVE_RP"
else
echo "$LINE"
fi
done < problem.s > patched.s
)
Now using HP's assembler and gcc to link, the problem is repaired.
stef harrier ot: as -o patched.o patched.s; gcc patched.o /lib/libcl.a; a.out
pc=0x0000403f
pc=0x000040c3
pc=0x000040f3
pc=0x00003efb
pc=0xc013cb37
To understand the problem :
As far as I understand the errors can be explained by following docs :
"The 32-bit PA-RISC Run-time Architecture Document"
from http:devresource.hp.com/STK/partner/rad_11_0_32.pdf :
SAVE_SP : true if entry value of SP is saved in current_SP-4
"HP Assembler Reference Manual, 4.Assembler Directives, .CALLINFO Directive"
from http://docs.hp.com
ENTRY_GR : Specifies the high end boundary of the Entry/Save regiester partition.
...
When a procedure uses therse regiesters, the Assembler saves their
values.
FRAME=number : The size specified for the frame should not include space for the
stack frame marker or the fixed argument area. The inclusion of the
CALLER (aka CALLS) parameter always allocates space for the stack
frame marker and the fixed argument area.
If we look at the simplest function :
try_unwind1
.PROC
.CALLINFO FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=3
.ENTRY
stw %r2,-20(%r30)
copy %r3,%r1
copy %r30,%r3
stwm %r1,64(%r30)
.CALL
bl try_unwind,%r2
nop
L$0014
ldw -20(%r3),%r2
ldo 64(%r3),%r30
ldwm -64(%r30),%r3
bv,n %r0(%r2)
.EXIT
.PROCEND
And its GDB view :
0x40a8 <try_unwind1>: stw rp,-14(sr0,sp)
0x40ac <try_unwind1+4>: ldo 0(r3),r1
0x40b0 <try_unwind1+8>: ldo 0(sp),r3
0x40b4 <try_unwind1+12>: stwm r1,40(sr0,sp)
0x40b8 <try_unwind1+16>: bl 0x401c <try_unwind>,rp
0x40bc <try_unwind1+20>: nop
0x40c0 <try_unwind1+24>: ldw -14(sr0,r3),rp
0x40c4 <try_unwind1+28>: ldo 40(r3),sp
0x40c8 <try_unwind1+32>: ldwm -40(sr0,sp),r3
0x40cc <try_unwind1+36>: bv,n r0(rp)
We can compare this to what HP's assembler generates when you
let it deal with the .CALLINFO implied instructions (i.e. let
it generate the instructions to save and restore callee-saves
registers, stack pointer, and return address. This can be done
by replacing .ENTRY and .EXIT by .ENTER and .LEAVE :
try_unwind1
.PROC
.CALLINFO FRAME=16,CALLS,SAVE_RP,ENTRY_GR=3
.ENTER
.CALL
bl try_unwind,%r2
nop
L$0014
.LEAVE
.PROCEND
And its GDB view :
0x40a8 <try_unwind1>: stw rp,-14(sr0,sp)
0x40ac <try_unwind1+4>: stwm r3,48(sr0,sp)
0x40b0 <try_unwind1+8>: bl 0x401c <try_unwind>,rp
0x40b4 <try_unwind1+12>: nop
0x40b8 <try_unwind1+16>: ldw -5c(sr0,sp),rp
0x40bc <try_unwind1+20>: bv r0(rp)
0x40c0 <try_unwind1+24>: ldwm -48(sr0,sp),r3
Conclusions :
- gdb generates a FRAME=<frame_size> that includes the 48 bytes too many.
- gdb generates a SAVE_SP parameter, as if it did save the previous stack
pointer at SP-4, while it did not generate such code.
- gdb generates an ENTRY_GR=3 parameter, as if it did save rp at its
designated location 0x48 (72) below the stack pointer, while it did
save it at 0x40 (64) below the stack pointer.
A few conclusions that are not immediately related to the problem :
- at least in this problem instance, if you let the hard work to HP's as,
and do not handle entry/exit code in the gcc backend, you get a 7-instruction
result instead of a 10-instruction result. If this would be a general trend,
the extra work in the gcc backend results in less efficient code, which does
not sound like a good choice.
- if you use the .ENTER and .LEAVE directives above with gas (out of curiosity),
then you are invited to report a bug, while the intent was probably to
just report that these are not supported/implemented :
stef harrier ot: /cm/ot/TOOL/GNU.LATEST/build_G!7.0.11/generated/bin/as -o patched.o patched.s
patched.s: Assembler messages:
patched.s:172: Internal error, aborting at ./config/tc-hppa.c line 4503
Please report this bug.
stef harrier ot: /cm/ot/TOOL/GNU.LATEST/build_G!7.0.11/generated/bin/as --version
GNU assembler 2.9.1
Copyright 1997 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License. This program has absolutely no warranty.
This assembler was configured for a target of `hppa1.0-hp-hpux11.00'.
Source and temporary files :
problem.c :
#include <sys/types.h>
#include <stddef.h>
#include <stdio.h>
typedef struct current_frame_def {
unsigned cur_frsize; /* Frame size of current routine. */
unsigned cursp; /* The current value of stack pointer. */
unsigned currls; /* PC-space of the calling routine. */
unsigned currlo; /* PC-offset of the calling routine. */
unsigned curdp; /* Data Pointer of the current routine. */
unsigned toprp; /* Initial value of RP. */
unsigned topmrp; /* Initial value of MRP. */
unsigned topsr0; /* Initial value of sr0. */
unsigned topsr4; /* Initial value of sr4 */
unsigned r3; /* Initial value of gr3 */
unsigned cur_r19; /* GR19 value of the calling routine. */
/* Used only in HP-UX. */
int r4;
unsigned long reserved[4];
} current_frame_def;
typedef struct previous_frame_def {
unsigned prev_frsize; /* frame size of calling routine. */
unsigned prevSP; /* SP of calling routine. */
unsigned prevRLS; /* PC_space of calling routine's caller. */
unsigned prevRLO; /* PC_offset of calling routine's caller. */
unsigned prevDP; /* DP of calling routine. */
unsigned udescr0; /* low word of calling routine's unwind */
/* descriptor. */
unsigned udescr1; /* high word of calling routine's unwind */
/* descriptor. */
unsigned ustart; /* start of the unwind region. */
unsigned uend; /* end of the unwind region. */
unsigned uw_index; /* index into the unwind table. */
unsigned prev_r19; /* GR19 value of the caller's caller. */
int r3;
int r4;
unsigned long reserved[4];
} previous_frame_def;
int backtrace (array, size)
void **array;
int size;
{
struct current_frame_def cfd;
struct previous_frame_def pfd;
unsigned status;
int cnt=0;
U_init_frame_record (&cfd);
U_prep_frame_rec_for_unwind (&cfd);
cnt = 0;
while (cnt < size)
{
status = U_get_previous_frame_x (&cfd, &pfd, sizeof(previous_frame_def));
if (status)
{ fprintf(stderr,
"__gnat_unwind: error pc=0x%.8x sp=0x%.8x\n",
cfd.currlo, cfd.cursp);
cfd.currlo = 0;
/* Recover from the error, as the only purpose might be to log
a recoverable error's origin and continue. The caller will
interpret the zero value for program counter as loop termination.
*/
}
else
U_copy_frame_info (&cfd, &pfd);
if (cfd.currlo == 0) return cnt ;
array[cnt] = (void *) cfd.currlo;
cnt++;
}
return cnt;
}
try_unwind()
{int trace[10];
int count=backtrace(trace, 10);
int i;
for (i=0;i<count;i++)
fprintf(stderr, "pc=0x%.8x\n", trace[i]);
}
try_unwind1()
{ try_unwind(); }
main ()
{
try_unwind1();
}
problem.i :
# 1 "problem.c"
# 1 "/net/rhino/disc1/cm/ot/gnu/gcc-2.95.2/generated/lib/gcc-lib/hppa2.0w-hp-hpux11.00/2.95.2/include/sys/types.h" 1 3
# 1 "/usr/include/sys/stdsyms.h" 1 3
# 65 "/usr/include/sys/stdsyms.h" 3
# 87 "/usr/include/sys/stdsyms.h" 3
# 198 "/usr/include/sys/stdsyms.h" 3
# 216 "/usr/include/sys/stdsyms.h" 3
# 259 "/usr/include/sys/stdsyms.h" 3
# 273 "/usr/include/sys/stdsyms.h" 3
# 300 "/usr/include/sys/stdsyms.h" 3
# 323 "/usr/include/sys/stdsyms.h" 3
# 10 "/net/rhino/disc1/cm/ot/gnu/gcc-2.95.2/generated/lib/gcc-lib/hppa2.0w-hp-hpux11.00/2.95.2/include/sys/types.h" 2 3
# 1 "/usr/include/sys/_inttypes.h" 1 3
# 49 "/usr/include/sys/_inttypes.h" 3
typedef char int8_t;
typedef unsigned char uint8_t;
typedef short int16_t;
typedef unsigned short uint16_t;
typedef int int32_t;
typedef unsigned int uint32_t;
typedef int intfast_t;
typedef unsigned int uintfast_t;
typedef long long int64_t;
typedef unsigned long long uint64_t;
typedef int64_t intmax_t;
typedef uint64_t uintmax_t;
typedef long intptr_t;
typedef unsigned long uintptr_t;
typedef char int_least8_t;
typedef unsigned char uint_least8_t;
typedef int int_fast8_t;
typedef unsigned int uint_fast8_t;
typedef short int_least16_t;
typedef unsigned short uint_least16_t;
typedef int int_fast16_t;
typedef unsigned int uint_fast16_t;
typedef int int_least32_t;
typedef unsigned int uint_least32_t;
typedef int int_fast32_t;
typedef unsigned int uint_fast32_t;
typedef int64_t int_least64_t;
typedef int64_t int_fast64_t;
typedef uint64_t uint_least64_t;
typedef uint64_t uint_fast64_t;
typedef uint32_t ptr32_t;
# 11 "/net/rhino/disc1/cm/ot/gnu/gcc-2.95.2/generated/lib/gcc-lib/hppa2.0w-hp-hpux11.00/2.95.2/include/sys/types.h" 2 3
typedef int mqd_t;
typedef int32_t dev_t;
typedef uint32_t ino32_t;
typedef uint64_t ino64_t;
typedef unsigned long ino_t;
typedef uint16_t mode_t;
typedef uint16_t nlink_t;
typedef int32_t fpos32_t;
typedef int64_t fpos64_t;
typedef long fpos_t;
typedef uint32_t fsblkcnt32_t;
typedef uint64_t fsblkcnt64_t;
typedef unsigned long fsblkcnt_t;
typedef int32_t off32_t;
typedef int64_t off64_t;
typedef long off_t;
typedef uint32_t fsfilcnt32_t;
typedef uint64_t fsfilcnt64_t;
typedef unsigned long fsfilcnt_t;
typedef int32_t blkcnt32_t;
typedef int64_t blkcnt64_t;
typedef long blkcnt_t;
typedef int32_t pid_t;
typedef int32_t lwpid_t;
typedef int32_t gid_t;
typedef int32_t uid_t;
typedef int32_t tid_t;
typedef long ssize_t;
typedef uint16_t __site_t;
typedef uint16_t __cnode_t;
typedef long time_t;
typedef unsigned int size_t;
typedef uint32_t clock_t;
typedef int32_t key_t;
typedef unsigned short __ushort;
typedef int32_t __daddr_t;
typedef char *__caddr_t;
typedef int32_t __swblk_t;
typedef __caddr_t caddr_t;
typedef int32_t id_t;
typedef uint32_t useconds_t;
typedef uint32_t rlim32_t;
typedef uint64_t rlim64_t;
typedef unsigned long rlim_t;
typedef __site_t site_t;
typedef unsigned char u_char;
typedef unsigned short u_short;
typedef unsigned int u_int;
typedef unsigned long u_long;
typedef unsigned int uint;
typedef unsigned short ushort;
typedef unsigned char ubit8;
typedef unsigned short ubit16;
typedef uint32_t ubit32;
typedef char sbit8;
typedef short sbit16;
typedef int32_t sbit32;
typedef __swblk_t swblk_t;
typedef __daddr_t daddr_t;
typedef __cnode_t cnode_t;
# 1 "/net/rhino/disc1/cm/ot/gnu/gcc-2.95.2/generated/lib/gcc-lib/hppa2.0w-hp-hpux11.00/2.95.2/include/machine/vmtypes.h" 1 3
typedef uintptr_t paddr_t;
typedef intptr_t page_t;
typedef int32_t pgcnt_t;
typedef uint32_t physpfn_t;
typedef uintptr_t iophyspfn_t;
typedef uintptr_t pgaddr_t;
typedef uint32_t space_t;
typedef uint32_t prot_t;
# 332 "/net/rhino/disc1/cm/ot/gnu/gcc-2.95.2/generated/lib/gcc-lib/hppa2.0w-hp-hpux11.00/2.95.2/include/sys/types.h" 2 3
typedef unsigned long ulong_t;
typedef int16_t cnt_t;
typedef uint32_t cdno_t;
typedef uint16_t use_t;
typedef struct _physadr { intptr_t r[1]; } *physadr;
typedef struct _quad { long val[2]; } quad;
typedef int spu_t;
typedef short cpu_t;
typedef struct label_t {
int32_t lbl_rp;
int32_t lbl_sp;
int32_t lbl_s[17];
int32_t lbl_ss[1];
double lbl_sf[10];
} label_t;
typedef struct lkinfo {
char *lk_name;
int lk_flags;
long lk_pad[2];
} lkinfo_t;
typedef unsigned long pl_t;
typedef char *dm_message;
typedef int32_t aid_t;
typedef pid_t sid_t;
# 1 "/usr/include/sys/_fd_macros.h" 1 3
typedef int32_t __fd_mask;
typedef struct fd_set {
long fds_bits[((( 2048 )+(( (sizeof(long) * 8) )-1))/( (sizeof(long) * 8) )) ];
} fd_set;
# 109 "/usr/include/sys/_fd_macros.h" 3
# 412 "/net/rhino/disc1/cm/ot/gnu/gcc-2.95.2/generated/lib/gcc-lib/hppa2.0w-hp-hpux11.00/2.95.2/include/sys/types.h" 2 3
typedef __fd_mask fd_mask;
typedef int32_t dir_off_t;
# 496 "/net/rhino/disc1/cm/ot/gnu/gcc-2.95.2/generated/lib/gcc-lib/hppa2.0w-hp-hpux11.00/2.95.2/include/sys/types.h" 3
# 198 "problem.c" 2
# 1 "/net/rhino/disc1/cm/ot/gnu/gcc-2.95.2/generated/lib/gcc-lib/hppa2.0w-hp-hpux11.00/2.95.2/include/stddef.h" 1 3
# 61 "/net/rhino/disc1/cm/ot/gnu/gcc-2.95.2/generated/lib/gcc-lib/hppa2.0w-hp-hpux11.00/2.95.2/include/stddef.h" 3
typedef int ptrdiff_t;
# 187 "/net/rhino/disc1/cm/ot/gnu/gcc-2.95.2/generated/lib/gcc-lib/hppa2.0w-hp-hpux11.00/2.95.2/include/stddef.h" 3
typedef unsigned int wchar_t;
typedef unsigned int wint_t;
# 317 "/net/rhino/disc1/cm/ot/gnu/gcc-2.95.2/generated/lib/gcc-lib/hppa2.0w-hp-hpux11.00/2.95.2/include/stddef.h" 3
# 199 "problem.c" 2
# 1 "/net/rhino/disc1/cm/ot/gnu/gcc-2.95.2/generated/lib/gcc-lib/hppa2.0w-hp-hpux11.00/2.95.2/include/stdio.h" 1 3
# 1 "/net/rhino/disc1/cm/ot/gnu/gcc-2.95.2/generated/lib/gcc-lib/hppa2.0w-hp-hpux11.00/2.95.2/include/stdarg.h" 1 3
# 1 "/net/rhino/disc1/cm/ot/gnu/gcc-2.95.2/generated/lib/gcc-lib/hppa2.0w-hp-hpux11.00/2.95.2/include/va-pa.h" 1 3
typedef void *__gnuc_va_list;
# 52 "/net/rhino/disc1/cm/ot/gnu/gcc-2.95.2/generated/lib/gcc-lib/hppa2.0w-hp-hpux11.00/2.95.2/include/va-pa.h" 3
# 24 "/net/rhino/disc1/cm/ot/gnu/gcc-2.95.2/generated/lib/gcc-lib/hppa2.0w-hp-hpux11.00/2.95.2/include/stdarg.h" 2 3
# 137 "/net/rhino/disc1/cm/ot/gnu/gcc-2.95.2/generated/lib/gcc-lib/hppa2.0w-hp-hpux11.00/2.95.2/include/stdarg.h" 3
# 209 "/net/rhino/disc1/cm/ot/gnu/gcc-2.95.2/generated/lib/gcc-lib/hppa2.0w-hp-hpux11.00/2.95.2/include/stdarg.h" 3
# 2 "/net/rhino/disc1/cm/ot/gnu/gcc-2.95.2/generated/lib/gcc-lib/hppa2.0w-hp-hpux11.00/2.95.2/include/stdio.h" 2 3
# 26 "/net/rhino/disc1/cm/ot/gnu/gcc-2.95.2/generated/lib/gcc-lib/hppa2.0w-hp-hpux11.00/2.95.2/include/stdio.h" 3
typedef struct {
int __cnt;
unsigned char *__ptr;
unsigned char *__base;
unsigned short __flag;
unsigned char __fileL;
unsigned char __fileH;
} FILE;
typedef struct {
int __cnt;
unsigned char *__ptr;
unsigned char *__base;
unsigned short __flag;
unsigned char __fileL;
unsigned char __fileH;
unsigned char *__bufendp;
unsigned char *__newbase;
unsigned char __smbuf[8 +2*4];
void *__unused;
} _FILEX;
# 1 "/usr/include/sys/_null.h" 1 3
# 87 "/net/rhino/disc1/cm/ot/gnu/gcc-2.95.2/generated/lib/gcc-lib/hppa2.0w-hp-hpux11.00/2.95.2/include/stdio.h" 2 3
# 1 "/usr/include/sys/_size_t.h" 1 3
# 91 "/net/rhino/disc1/cm/ot/gnu/gcc-2.95.2/generated/lib/gcc-lib/hppa2.0w-hp-hpux11.00/2.95.2/include/stdio.h" 2 3
# 103 "/net/rhino/disc1/cm/ot/gnu/gcc-2.95.2/generated/lib/gcc-lib/hppa2.0w-hp-hpux11.00/2.95.2/include/stdio.h" 3
typedef double *__va_list;
extern FILE __iob[];
extern int remove(const char *);
extern int rename(const char *, const char *);
extern char *tmpnam(char *);
extern int fclose(FILE *);
extern int fflush(FILE *);
extern void setbuf(FILE *, char *);
extern int setvbuf(FILE *, char *, int, size_t);
extern int fprintf(FILE *, const char *, ...);
extern int fscanf(FILE *, const char *,...);
extern int printf(const char *,...);
extern int scanf(const char *,...);
extern int sprintf(char *, const char *,...);
extern int sscanf(const char *, const char *,...);
extern int fgetc(FILE *);
extern char *fgets(char *, int, FILE *);
extern int fputc(int, FILE *);
extern int fputs(const char *, FILE *);
extern int getc(FILE *);
extern int getchar(void);
extern char *gets(char *);
extern int putc(int, FILE *);
extern int putchar(int);
extern int puts(const char *);
extern int ungetc(int, FILE *);
extern FILE *tmpfile(void);
extern int fgetpos(FILE *, fpos_t *);
extern int fsetpos(FILE *, const fpos_t *);
extern FILE *fopen(const char *, const char *);
extern FILE *freopen(const char *, const char *, FILE *);
extern int fseek(FILE *, long int, int);
extern long int ftell(FILE *);
extern void rewind(FILE *);
extern void clearerr(FILE *);
extern int feof(FILE *);
extern int ferror(FILE *);
extern void perror(const char *);
# 200 "/net/rhino/disc1/cm/ot/gnu/gcc-2.95.2/generated/lib/gcc-lib/hppa2.0w-hp-hpux11.00/2.95.2/include/stdio.h" 3
# 263 "/net/rhino/disc1/cm/ot/gnu/gcc-2.95.2/generated/lib/gcc-lib/hppa2.0w-hp-hpux11.00/2.95.2/include/stdio.h" 3
extern size_t fread(void *, size_t, size_t, FILE *);
extern size_t fwrite(const void *, size_t, size_t, FILE *);
extern int __flsbuf(unsigned char, FILE *);
extern int __filbuf(FILE *);
# 333 "/net/rhino/disc1/cm/ot/gnu/gcc-2.95.2/generated/lib/gcc-lib/hppa2.0w-hp-hpux11.00/2.95.2/include/stdio.h" 3
extern char *ctermid(char *);
extern int fileno(FILE *);
extern FILE *fdopen(int, const char *);
typedef double *__va_list__;
extern char *optarg;
extern int opterr;
extern int optind;
extern int optopt;
extern int getopt(int, char * const [], const char *);
extern char *cuserid(char *);
extern int getw(FILE *);
extern int putw(int, FILE *);
extern int pclose(FILE *);
extern FILE *popen(const char *, const char *);
extern char *tempnam(const char *, const char *);
extern int vprintf(const char *, __gnuc_va_list);
extern int vfprintf(FILE *, const char *, __gnuc_va_list);
extern int vsprintf(char *, const char *, __gnuc_va_list);
extern int snprintf(char *, size_t, char *,...);
extern int vsnprintf(char *, size_t, const char *, __gnuc_va_list);
extern int vscanf(const char *, __gnuc_va_list);
extern int vfscanf(FILE *, const char *, __gnuc_va_list);
extern int vsscanf(char *, const char *, __gnuc_va_list);
extern void flockfile(FILE *);
extern int ftrylockfile(FILE *);
extern void funlockfile(FILE *);
# 471 "/net/rhino/disc1/cm/ot/gnu/gcc-2.95.2/generated/lib/gcc-lib/hppa2.0w-hp-hpux11.00/2.95.2/include/stdio.h" 3
# 499 "/net/rhino/disc1/cm/ot/gnu/gcc-2.95.2/generated/lib/gcc-lib/hppa2.0w-hp-hpux11.00/2.95.2/include/stdio.h" 3
extern unsigned char *__bufendtab[];
# 548 "/net/rhino/disc1/cm/ot/gnu/gcc-2.95.2/generated/lib/gcc-lib/hppa2.0w-hp-hpux11.00/2.95.2/include/stdio.h" 3
# 605 "/net/rhino/disc1/cm/ot/gnu/gcc-2.95.2/generated/lib/gcc-lib/hppa2.0w-hp-hpux11.00/2.95.2/include/stdio.h" 3
# 614 "/net/rhino/disc1/cm/ot/gnu/gcc-2.95.2/generated/lib/gcc-lib/hppa2.0w-hp-hpux11.00/2.95.2/include/stdio.h" 3
# 200 "problem.c" 2
typedef struct current_frame_def {
unsigned cur_frsize;
unsigned cursp;
unsigned currls;
unsigned currlo;
unsigned curdp;
unsigned toprp;
unsigned topmrp;
unsigned topsr0;
unsigned topsr4;
unsigned r3;
unsigned cur_r19;
int r4;
unsigned long reserved[4];
} current_frame_def;
typedef struct previous_frame_def {
unsigned prev_frsize;
unsigned prevSP;
unsigned prevRLS;
unsigned prevRLO;
unsigned prevDP;
unsigned udescr0;
unsigned udescr1;
unsigned ustart;
unsigned uend;
unsigned uw_index;
unsigned prev_r19;
int r3;
int r4;
unsigned long reserved[4];
} previous_frame_def;
int backtrace (array, size)
void **array;
int size;
{
struct current_frame_def cfd;
struct previous_frame_def pfd;
unsigned status;
int cnt=0;
U_init_frame_record (&cfd);
U_prep_frame_rec_for_unwind (&cfd);
cnt = 0;
while (cnt < size)
{
status = U_get_previous_frame_x (&cfd, &pfd, sizeof(previous_frame_def));
if (status)
{ fprintf((&__iob[2]) ,
"__gnat_unwind: error pc=0x%.8x sp=0x%.8x\n",
cfd.currlo, cfd.cursp);
cfd.currlo = 0;
}
else
U_copy_frame_info (&cfd, &pfd);
if (cfd.currlo == 0) return cnt ;
array[cnt] = (void *) cfd.currlo;
cnt++;
}
return cnt;
}
try_unwind()
{int trace[10];
int count=backtrace(trace, 10);
int i;
for (i=0;i<count;i++)
fprintf((&__iob[2]) , "pc=0x%.8x\n", trace[i]);
}
try_unwind1()
{ try_unwind(); }
main ()
{
try_unwind1();
}
problem.s :
.SPACE $PRIVATE$
.SUBSPA $DATA$,QUAD=1,ALIGN=8,ACCESS=31
.SUBSPA $BSS$,QUAD=1,ALIGN=8,ACCESS=31,ZERO,SORT=82
.SPACE $TEXT$
.SUBSPA $LIT$,QUAD=0,ALIGN=8,ACCESS=44
.SUBSPA $CODE$,QUAD=0,ALIGN=8,ACCESS=44,CODE_ONLY
.IMPORT $global$,DATA
.IMPORT $$dyncall,MILLICODE
; gcc_compiled.:
.IMPORT U_init_frame_record,CODE
.IMPORT U_prep_frame_rec_for_unwind,CODE
.IMPORT U_get_previous_frame_x,CODE
.IMPORT fprintf,CODE
.IMPORT __iob,DATA
.SPACE $TEXT$
.SUBSPA $LIT$
.align 4
L$C0000
.STRING "__gnat_unwind: error pc=0x%.8x sp=0x%.8x\x0a\x00"
.IMPORT U_copy_frame_info,CODE
.SPACE $TEXT$
.SUBSPA $CODE$
.align 4
.EXPORT backtrace,ENTRY,PRIV_LEV=3,ARGW0=GR,ARGW1=GR,RTNVAL=GR
backtrace
.PROC
.CALLINFO FRAME=256,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=3
.ENTRY
stw %r2,-20(%r30)
copy %r3,%r1
copy %r30,%r3
stwm %r1,256(%r30)
stw %r26,-36(%r3)
stw %r25,-40(%r3)
stw %r0,148(%r3)
ldo 8(%r3),%r26
.CALL ARGW0=GR
bl U_init_frame_record,%r2
nop
ldo 8(%r3),%r26
.CALL ARGW0=GR
bl U_prep_frame_rec_for_unwind,%r2
nop
stw %r0,148(%r3)
L$0003
ldw 148(%r3),%r19
ldw -40(%r3),%r20
comb,>,n %r20,%r19,L$0005
b,n L$0004
L$0005
ldo 72(%r3),%r19
ldo 8(%r3),%r26
copy %r19,%r25
ldi 68,%r24
.CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
bl U_get_previous_frame_x,%r2
nop
stw %r28,144(%r3)
ldw 144(%r3),%r19
comib,=,n 0,%r19,L$0006
addil LR'__iob-$global$,%r27
ldo RR'__iob-$global$+32(%r1),%r26
ldil LR'L$C0000,%r19
ldo RR'L$C0000(%r19),%r25
ldw 20(%r3),%r24
ldw 12(%r3),%r23
.CALL ARGW0=GR,ARGW1=GR,ARGW2=GR,ARGW3=GR
bl fprintf,%r2
nop
stw %r0,20(%r3)
b,n L$0007
L$0006
ldo 72(%r3),%r19
ldo 8(%r3),%r26
copy %r19,%r25
.CALL ARGW0=GR,ARGW1=GR
bl U_copy_frame_info,%r2
nop
L$0007
ldw 20(%r3),%r19
comib,<>,n 0,%r19,L$0008
ldw 148(%r3),%r19
copy %r19,%r28
b,n L$0002
L$0008
ldw 148(%r3),%r19
ldw -36(%r3),%r20
sh2addl %r19,%r20,%r19
ldw 20(%r3),%r20
stw %r20,0(%r19)
ldw 148(%r3),%r19
ldo 1(%r19),%r20
stw %r20,148(%r3)
b,n L$0003
L$0004
ldw 148(%r3),%r19
copy %r19,%r28
b,n L$0002
L$0002
ldw -20(%r3),%r2
ldo 64(%r3),%r30
ldwm -64(%r30),%r3
bv,n %r0(%r2)
.EXIT
.PROCEND
.SPACE $TEXT$
.SUBSPA $LIT$
.align 4
L$C0001
.STRING "pc=0x%.8x\x0a\x00"
.SPACE $TEXT$
.SUBSPA $CODE$
.align 4
.EXPORT try_unwind,ENTRY,PRIV_LEV=3,RTNVAL=GR
try_unwind
.PROC
.CALLINFO FRAME=128,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=3
.ENTRY
stw %r2,-20(%r30)
copy %r3,%r1
copy %r30,%r3
stwm %r1,128(%r30)
ldo 8(%r3),%r26
ldi 10,%r25
.CALL ARGW0=GR,ARGW1=GR
bl backtrace,%r2
nop
copy %r28,%r19
stw %r19,48(%r3)
stw %r0,52(%r3)
L$0010
ldw 52(%r3),%r19
ldw 48(%r3),%r20
comb,>,n %r20,%r19,L$0013
b,n L$0011
L$0013
ldw 52(%r3),%r19
copy %r19,%r20
zdep %r20,29,30,%r19
ldo 8(%r3),%r20
addl %r20,%r19,%r19
addil LR'__iob-$global$,%r27
ldo RR'__iob-$global$+32(%r1),%r26
ldil LR'L$C0001,%r20
ldo RR'L$C0001(%r20),%r25
ldw 0(%r19),%r24
.CALL ARGW0=GR,ARGW1=GR,ARGW2=GR
bl fprintf,%r2
nop
L$0012
ldw 52(%r3),%r19
ldo 1(%r19),%r20
stw %r20,52(%r3)
b,n L$0010
L$0011
L$0009
ldw -20(%r3),%r2
ldo 64(%r3),%r30
ldwm -64(%r30),%r3
bv,n %r0(%r2)
.EXIT
.PROCEND
.align 4
.EXPORT try_unwind1,ENTRY,PRIV_LEV=3,RTNVAL=GR
try_unwind1
.PROC
.CALLINFO FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=3
.ENTRY
stw %r2,-20(%r30)
copy %r3,%r1
copy %r30,%r3
stwm %r1,64(%r30)
.CALL
bl try_unwind,%r2
nop
L$0014
ldw -20(%r3),%r2
ldo 64(%r3),%r30
ldwm -64(%r30),%r3
bv,n %r0(%r2)
.EXIT
.PROCEND
.IMPORT __main,CODE
.align 4
.EXPORT main,ENTRY,PRIV_LEV=3,RTNVAL=GR
main
.PROC
.CALLINFO FRAME=64,CALLS,SAVE_RP,SAVE_SP,ENTRY_GR=3
.ENTRY
stw %r2,-20(%r30)
copy %r3,%r1
copy %r30,%r3
stwm %r1,64(%r30)
.CALL
bl __main,%r2
nop
.CALL
bl try_unwind1,%r2
nop
L$0015
ldw -20(%r3),%r2
ldo 64(%r3),%r30
ldwm -64(%r30),%r3
bv,n %r0(%r2)
.EXIT
.PROCEND
Thank you for your help,
--
Stef Van Vlierberghe Eurocontrol - CFMU room 22238
stef.van-vlierberghe@eurocontrol.be Raketstraat 96
Tel: +32 2 729 97 32 B-1130 BRUSSELS
Fax: +32 2 729 90 22 Belgium