This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

gcc-2.95.2 hp-hpux11.00 wrong assembly directive .CALLINFO


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

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]