Changeset 10774


Ignore:
Timestamp:
Sep 16, 2008, 12:38:25 PM (11 years ago)
Author:
gb
Message:

Hair up the (already hairy ...) code that copies signal handler arguments
from one stack to another to satisfy x8632 Linux constraints.

This doesn't seem to have broken x8664 Linux, but needs to be tested
on x8664 FreeBSD/Darwin/Solaris. (In general, both 64- and 32-bit Linux
is more sensitive to stack layout on exception return than other
platforms are, or we're able to define SIGRETURN as something that'll
restore the context for us. It may be the case that other 32-bit
Unices have constraints similar to Linux's.)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/source/lisp-kernel/x86-exceptions.c

    r10731 r10774  
    12671267
    12681268#ifdef LINUX
     1269/* type of pointer to saved fp state */
     1270#ifdef X8664
     1271typedef fpregset_t FPREGS;
     1272#else
     1273typedef struct _fpstate *FPREGS;
     1274#endif
    12691275LispObj *
    1270 copy_fpregs(ExceptionInformation *xp, LispObj *current, fpregset_t *destptr)
    1271 {
    1272   fpregset_t src = xp->uc_mcontext.fpregs, dest;
     1276copy_fpregs(ExceptionInformation *xp, LispObj *current, FPREGS *destptr)
     1277{
     1278  FPREGS src = (FPREGS)(xp->uc_mcontext.fpregs), dest;
    12731279 
    12741280  if (src) {
    1275     dest = ((fpregset_t)current)-1;
     1281    dest = ((FPREGS)current)-1;
    12761282    *dest = *src;
    12771283    *destptr = dest;
     
    13011307{
    13021308  siginfo_t *dest = ((siginfo_t *)current) - 1;
     1309#if !defined(LINUX) || !defined(X8632)
    13031310  dest = (siginfo_t *) (((LispObj)dest)&~15);
     1311#endif
    13041312  *dest = *info;
    13051313  return (LispObj *)dest;
     
    13071315
    13081316#ifdef LINUX
    1309 typedef fpregset_t copy_ucontext_last_arg_t;
     1317typedef FPREGS copy_ucontext_last_arg_t;
    13101318#else
    13111319typedef void * copy_ucontext_last_arg_t;
     
    13171325{
    13181326  ExceptionInformation *dest = ((ExceptionInformation *)current)-1;
     1327#if !defined(LINUX) || !defined(X8632)
    13191328  dest = (ExceptionInformation *) (((LispObj)dest) & ~15);
     1329#endif
    13201330
    13211331  *dest = *context;
     
    13231333     it is "allocated" ? */
    13241334#ifdef LINUX
    1325   dest->uc_mcontext.fpregs = fp;
     1335  dest->uc_mcontext.fpregs = (fpregset_t)fp;
    13261336#endif
    13271337  dest->uc_stack.ss_sp = 0;
     
    13451355}
    13461356
     1357#ifdef X8632
     1358#ifdef LINUX
     1359/* This is here for debugging.  On entry to a signal handler that
     1360   receives info and context arguments, the stack should look exactly
     1361   like this.  The "pretcode field" of the structure is the address
     1362   of code that does an rt_sigreturn syscall, and rt_sigreturn expects
     1363   %esp at the time of that syscall to be pointing just past the
     1364   pretcode field.
     1365   handle_signal_on_foreign_stack() and helpers have to be very
     1366   careful to duplicate this "structure" exactly.
     1367   Note that on x8664 Linux, rt_sigreturn expects a ucontext to
     1368   be on top of the stack (with a siginfo_t underneath it.)
     1369   It sort of half-works to do sigreturn via setcontext() on
     1370   x8632 Linux, but (a) it may not be available on some distributions
     1371   and (b) even a relatively modern version of it uses "fldenv" to
     1372   restore FP context, and "fldenv" isn't nearly good enough.
     1373*/
     1374
     1375struct rt_sigframe {
     1376        char *pretcode;
     1377        int sig;
     1378        siginfo_t  *pinfo;
     1379        void  *puc;
     1380        siginfo_t info;
     1381        struct ucontext uc;
     1382        struct _fpstate fpstate;
     1383        char retcode[8];
     1384};
     1385struct rt_sigframe *rtsf = 0;
     1386
     1387#endif
     1388#endif
    13471389
    13481390#ifdef DARWIN
     
    13571399
    13581400#ifndef WINDOWS
     1401/* x8632 Linux requires that the stack-allocated siginfo is nearer
     1402   the top of stack than the stack-allocated ucontext.  If other
     1403   platforms care, they expect the ucontext to be nearer the top
     1404   of stack.
     1405*/
     1406
     1407#if defined(LINUX) && defined(X8632)
     1408#define UCONTEXT_ON_TOP_OF_STACK 0
     1409#else
     1410#define UCONTEXT_ON_TOP_OF_STACK 1
     1411#endif
    13591412void
    13601413handle_signal_on_foreign_stack(TCR *tcr,
     
    13701423{
    13711424#ifdef LINUX
    1372   fpregset_t fpregs = NULL;
     1425  FPREGS fpregs = NULL;
    13731426#else
    13741427  void *fpregs = NULL;
     
    13871440  foreign_rsp = copy_darwin_mcontext(UC_MCONTEXT(context), foreign_rsp, &mcontextp);
    13881441#endif
     1442#if UCONTEXT_ON_TOP_OF_STACK
     1443  /* copy info first */
    13891444  foreign_rsp = copy_siginfo(info, foreign_rsp);
    13901445  info_copy = (siginfo_t *)foreign_rsp;
    13911446  foreign_rsp = copy_ucontext(context, foreign_rsp, fpregs);
    13921447  xp = (ExceptionInformation *)foreign_rsp;
     1448#else
     1449  foreign_rsp = copy_ucontext(context, foreign_rsp, fpregs);
     1450  xp = (ExceptionInformation *)foreign_rsp;
     1451  foreign_rsp = copy_siginfo(info, foreign_rsp);
     1452  info_copy = (siginfo_t *)foreign_rsp;
     1453#endif
    13931454#ifdef DARWIN
    13941455  UC_MCONTEXT(xp) = mcontextp;
Note: See TracChangeset for help on using the changeset viewer.