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: