Back to index

glibc  2.9
Defines | Functions | Variables
sigtramp.c File Reference
#include "/usr/include/sys/signal.h"
#include <signal.h>
#include <stddef.h>
#include <errno.h>

Go to the source code of this file.


#define KERNEL
#define sigvec   sun_sigvec
#define sigstack   sun_sigstack
#define sigcontext   sun_sigcontext
#define mytramp   1


int __raw_sigvec (int sig, CONST struct sigvec *vec, struct sigvec *ovec)
static void trampoline (int sig)
int __sigvec (int sig, const struct sigvec *vec, struct sigvec *ovec)


static __sighandler_t handlers [NSIG]

Define Documentation

#define KERNEL

Definition at line 24 of file sigtramp.c.

#define mytramp   1

Definition at line 57 of file sigtramp.c.

#define sigcontext   sun_sigcontext

Definition at line 27 of file sigtramp.c.

#define sigstack   sun_sigstack

Definition at line 26 of file sigtramp.c.

#define sigvec   sun_sigvec

Definition at line 25 of file sigtramp.c.

Function Documentation

int __raw_sigvec ( int  sig,
CONST struct sigvec vec,
struct sigvec ovec 
int __sigvec ( int  sig,
const struct sigvec vec,
struct sigvec ovec 

Definition at line 201 of file sigtramp.c.

#ifndef       mytramp
  extern void _sigtramp (int);
#define       trampoline    _sigtramp
  struct sigvec myvec;
  int mask;
  __sighandler_t ohandler;

  if (sig <= 0 || sig >= NSIG)
      __set_errno (EINVAL);
      return -1;

  mask = __sigblock (sigmask(sig));

  ohandler = handlers[sig];

  if (vec != NULL &&
      vec->sv_handler != SIG_IGN && vec->sv_handler != SIG_DFL)
      handlers[sig] = vec->sv_handler;
      myvec = *vec;
      myvec.sv_handler = trampoline;
      vec = &myvec;

  if (__raw_sigvec(sig, vec, ovec) < 0)
      int save = errno;
      (void) __sigsetmask(mask);
      errno = save;
      return -1;

  if (ovec != NULL && ovec->sv_handler == trampoline)
    ovec->sv_handler = ohandler;

  (void) __sigsetmask (mask);

  return 0;

Here is the call graph for this function:

static void trampoline ( int  sig) [static]

Definition at line 71 of file sigtramp.c.

  /* We use `double' and `long long int' so `std' (store doubleword) insns,
     which might be faster than single-word stores, will be generated.  */
  register double f0 asm("%f0");
  register double f2 asm("%f2");
  register double f4 asm("%f4");
  register double f6 asm("%f6");
  register double f8 asm("%f8");
  register double f10 asm("%f10");
  register double f12 asm("%f12");
  register double f14 asm("%f14");
  register double f16 asm("%f16");
  register double f18 asm("%f18");
  register double f20 asm("%f20");
  register double f22 asm("%f22");
  register double f24 asm("%f24");
  register double f26 asm("%f26");
  register double f28 asm("%f28");
  register double f30 asm("%f30");
  register long long int g2 asm("%g2");
  register long long int g4 asm("%g4");
  register long long int g6 asm("%g6");
  register int *fp asm("%fp");

  int code;
  register struct sigcontext *context asm("%i0"); /* See end of fn.  */
  void *addr;
  int y;
  double fpsave[16];
  int fsr;
  int savefpu;
  long long int glsave[3];

  /* SIG isn't really passed as an arg.
     The args to the signal handler are at fp[16..19].  */
  sig = fp[16];
  code = fp[17];
  context = (struct sigcontext *) fp[18];
  addr = (PTR) fp[19];

  /* Save the Y register.  */
  asm("rd %%y, %0" : "=r" (y));

  /* Save the FPU regs if the FPU enable bit is set in the PSR,
     and the signal isn't an FP exception.  */
  savefpu = (context->sc_psr & 0x1000) && sig != SIGFPE;
  if (savefpu)
      fpsave[0] = f0;
      fpsave[1] = f2;
      fpsave[2] = f4;
      fpsave[3] = f6;
      fpsave[4] = f8;
      fpsave[5] = f10;
      fpsave[6] = f12;
      fpsave[7] = f14;
      fpsave[8] = f16;
      fpsave[9] = f18;
      fpsave[10] = f20;
      fpsave[11] = f22;
      fpsave[12] = f24;
      fpsave[13] = f26;
      fpsave[14] = f28;
      fpsave[15] = f30;

      /* Force it into a stack slot so the asm won't barf.  Sigh.  */
      (void) &fsr;
      asm("st %%fsr, %0" : "=m" (fsr));

  /* Save the global registers (except for %g1, which is a scratch reg).  */
  glsave[0] = g2;
  glsave[1] = g4;
  glsave[2] = g6;

  /* Call the user's handler.  */
  (*((void (*) (int sig, int code, struct sigcontext *context,
              void *addr)) handlers[sig]))
    (sig, code, context, addr);

  /* Restore the Y register.  */
  asm("mov %0, %%y" : : "r" (y));

  if (savefpu)
      /* Restore the FPU regs.  */
      f0 = fpsave[0];
      f2 = fpsave[1];
      f4 = fpsave[2];
      f6 = fpsave[3];
      f8 = fpsave[4];
      f10 = fpsave[5];
      f12 = fpsave[6];
      f14 = fpsave[7];
      f16 = fpsave[8];
      f18 = fpsave[9];
      f20 = fpsave[10];
      f22 = fpsave[11];
      f24 = fpsave[12];
      f26 = fpsave[13];
      f28 = fpsave[14];
      f30 = fpsave[15];

      asm("ld %0, %%fsr" : : "m" (fsr));

  /* Restore the globals.  */
  g2 = glsave[0];
  g4 = glsave[1];
  g6 = glsave[2];

  /* Unwind a frame, and do a "sigcleanup" system call.
     The system call apparently does a return.
     I don't know what it's for.  Ask Sun.  */
  asm("restore %%g0, 139, %%g1\n"
      "ta 0\n"
      "! this should be i0: %0"    /* Useless insn that will never be executed, */
                            /* here to make the compiler happy.  */
      : /* No outputs.  */ :
      /* CONTEXT is bound to %i0.  We reference it as an input here to make
        sure the compiler considers it live at this point, and preserves
        the value in that register.  The restore makes %i0 become %o0, the
        argument to the system call.  */
      "r" (context));

Here is the call graph for this function:

Here is the caller graph for this function:

Variable Documentation

__sighandler_t handlers[NSIG] [static]

Definition at line 59 of file sigtramp.c.