[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Porting gcl: Need to get fault address from struct sigcontext



Greetings!  I've just released a new maxima package, but alas, its not
yet very portable.  Here is the current logjam:

maxima is build on top of gcl, which needs to read a fault address
from a sigcontext struct.  Here is how it is done on the i386:
=============================================================================
asm/sigcontext.h
=============================================================================
#ifndef _ASMi386_SIGCONTEXT_H
#define _ASMi386_SIGCONTEXT_H

/*
 * As documented in the iBCS2 standard..
 *
 * The first part of "struct _fpstate" is just the
 * normal i387 hardware setup, the extra "status"
 * word is used to save the coprocessor status word
 * before entering the handler.
 */
struct _fpreg {
	unsigned short significand[4];
	unsigned short exponent;
};

struct _fpstate {
	unsigned long 	cw,
			sw,
			tag,
			ipoff,
			cssel,
			dataoff,
			datasel;
	struct _fpreg	_st[8];
	unsigned long	status;
};

struct sigcontext {
	unsigned short gs, __gsh;
	unsigned short fs, __fsh;
	unsigned short es, __esh;
	unsigned short ds, __dsh;
	unsigned long edi;
	unsigned long esi;
	unsigned long ebp;
	unsigned long esp;
	unsigned long ebx;
	unsigned long edx;
	unsigned long ecx;
	unsigned long eax;
	unsigned long trapno;
	unsigned long err;
	unsigned long eip;
	unsigned short cs, __csh;
	unsigned long eflags;
	unsigned long esp_at_signal;
	unsigned short ss, __ssh;
	struct _fpstate * fpstate;
	unsigned long oldmask;
	unsigned long cr2;
};


#endif
=============================================================================
GET_FAULT_ADDR macro: (works)
=============================================================================
#define GET_FAULT_ADDR(sig,code,sv,a) \
    ((void *)(((struct sigcontext_struct *)(&code))->cr2))     
#endif
=============================================================================

On the m68k, the following appears to work:
=============================================================================
asm/sigcontext.h
=============================================================================
#ifndef _ASM_M68k_SIGCONTEXT_H
#define _ASM_M68k_SIGCONTEXT_H

struct sigcontext {
	unsigned long  sc_mask; 	/* old sigmask */
	unsigned long  sc_usp;		/* old user stack pointer */
	unsigned long  sc_d0;
	unsigned long  sc_d1;
	unsigned long  sc_a0;
	unsigned long  sc_a1;
	unsigned short sc_sr;
	unsigned long  sc_pc;
	unsigned short sc_formatvec;
	unsigned long  sc_fpregs[2*3];  /* room for two fp registers */
	unsigned long  sc_fpcntl[3];
	unsigned char  sc_fpstate[216];
};

=============================================================================
GET_FAULT_ADDR macro: (apparently works)
=============================================================================
/* GET_FAULT_ADDR is a bit complicated to implement on m68k, because the fault
   address can't be found directly in the sigcontext. One has to look at the
   CPU frame, and that one is different for each CPU.
   */
#define GET_FAULT_ADDR(sig,code,sv,a) \
    ({															\
		struct sigcontext *scp = (struct sigcontext *)(sv);		\
		int format = (scp->sc_formatvec >> 12) & 0xf;			\
		unsigned long *framedata = (unsigned long *)(scp + 1);	\
		unsigned long ea;										\
		if (format == 0xa || format == 0xb)						\
			/* 68020/030 */										\
			ea = framedata[2];									\
		else if (format == 7)									\
			/* 68040 */											\
			ea = framedata[3];									\
		else if (format == 4) {									\
			/* 68060 */											\
			ea = framedata[0];									\
			if (framedata[1] & 0x08000000)						\
				/* correct addr on misaligned access */			\
				ea = (ea+4095)&(~4095);							\
		}														\
		ea;														\
	})
#endif
=============================================================================

Here is the sigcontext struct on the alpha:

=============================================================================
struct sigcontext {
	/*
	 * What should we have here? I'd probably better use the same
	 * stack layout as OSF/1, just in case we ever want to try
	 * running their binaries.. 
	 *
	 * This is the basic layout, but I don't know if we'll ever
	 * actually fill in all the values..
	 */
	 long		sc_onstack;
	 long		sc_mask;
	 long		sc_pc;
	 long		sc_ps;
	 long		sc_regs[32];
	 long		sc_ownedfp;
	 long		sc_fpregs[32];
	 unsigned long	sc_fpcr;
	 unsigned long	sc_fp_control;
	 unsigned long	sc_reserved1, sc_reserved2;
	 unsigned long	sc_ssize;
	 char *		sc_sbase;
	 unsigned long	sc_traparg_a0;
	 unsigned long	sc_traparg_a1;
	 unsigned long	sc_traparg_a2;
	 unsigned long	sc_fp_trap_pc;
	 unsigned long	sc_fp_trigger_sum;
	 unsigned long	sc_fp_trigger_inst;
};
=============================================================================

Anyone know what the macro should be here?  Other archs?  Arm?  Sparc
may already be taken care of, but I haven't confirmed that yet.

Any advice appreciated!

Take care,

Camm Maguire			     			camm@enhanced.com
==========================================================================
"The earth is but one country, and mankind its citizens."  --  Baha'u'llah




Reply to: