ViewVC Help
View File | Revision Log | Show Annotations | Revision Graph | Root Listing
root/cebix/SheepShaver/src/Unix/Linux/paranoia.cpp
(Generate patch)

Comparing SheepShaver/src/Unix/Linux/paranoia.cpp (file contents):
Revision 1.1.1.1 by cebix, 2002-02-04T16:58:13Z vs.
Revision 1.5 by gbeauche, 2005-07-04T06:09:59Z

# Line 2 | Line 2
2   *  paranoia.cpp - Check undocumented features of the Linux kernel that
3   *                 SheepShaver relies upon
4   *
5 < *  SheepShaver (C) 1997-2002 Christian Bauer and Marc Hellwig
5 > *  SheepShaver (C) 1997-2005 Christian Bauer and Marc Hellwig
6   *
7   *  This program is free software; you can redistribute it and/or modify
8   *  it under the terms of the GNU General Public License as published by
# Line 42 | Line 42 | const uint32 SIG_STACK_SIZE = 0x10000;
42  
43   // Prototypes
44   extern "C" void *get_sp(void);
45 < extern "C" void set_r2(uint32 val);
45 > extern "C" void *get_r2(void);
46 > extern "C" void set_r2(void *);
47 > extern "C" void *get_r13(void);
48   extern void paranoia_check(void);
49   static void sigusr2_handler(int sig, sigcontext_struct *sc);
50  
# Line 57 | Line 59 | static void *sig_sc_regs = NULL;
59   static uint32 sig_r2 = 0;
60  
61  
62 + int raise(int sig)
63 + {
64 +        // Reimplement to get rid of access to r2 (TLS pointer)
65 +        return kill(getpid(), sig);
66 + }
67 +
68   void paranoia_check(void)
69   {
70          char str[256];
# Line 95 | Line 103 | void paranoia_check(void)
103          }
104  
105          // Raise SIGUSR2
106 <        set_r2(0xaffebad5);
106 >        TOC = get_r2();
107 >        R13 = get_r13();
108 >        set_r2((void *)0xaffebad5);
109          raise(SIGUSR2);
110 +        if (TOC != get_r2())
111 +                err = 6;
112 +        if (R13 != get_r13())
113 +                err = 7;
114  
115          // Check error code
116          switch (err) {
# Line 115 | Line 129 | void paranoia_check(void)
129                  case 5:
130                          printf("FATAL: sc->regs->gpr[2] in signal handler (%08lx) doesn't have expected value (%08x)\n", (uint32)sig_r2, 0xaffebad5);
131                          break;
132 +                case 6:
133 +                        printf("FATAL: signal handler failed to restore initial r2 value (%08x, was %08x)\n", (uint32)get_r2(), (uint32)TOC);
134 +                        break;
135 +                case 7:
136 +                        printf("FATAL: signal handler failed to restore initial r13 value (%08x, was %08x)\n", get_r13(), (uint32)R13);
137          }
138          if (err) {
139                  printf("Maybe you need a different kernel?\n");
# Line 135 | Line 154 | static void sigusr2_handler(int sig, sig
154          sig_sp = get_sp();
155          if (sig_sp < sig_stack || sig_sp >= ((uint8 *)sig_stack + SIG_STACK_SIZE)) {
156                  err = 1;
157 <                return;
157 >                goto ret;
158          }
159  
160          // Check whether r4 points to info on the stack
161          sig_r4 = sc;
162          if (sig_r4 < sig_stack || sig_r4 >= ((uint8 *)sig_stack + SIG_STACK_SIZE)) {
163                  err = 2;
164 <                return;
164 >                goto ret;
165          }
166  
167          // Check whether r4 looks like a sigcontext
168          sig_sc_signal = sc->signal;
169          if (sig_sc_signal != SIGUSR2) {
170                  err = 3;
171 <                return;
171 >                goto ret;
172          }
173  
174          // Check whether sc->regs points to info on the stack
175          sig_sc_regs = sc->regs;
176          if (sig_sc_regs < sig_stack || sig_sc_regs >= ((uint8 *)sig_stack + SIG_STACK_SIZE)) {
177                  err = 4;
178 <                return;
178 >                goto ret;
179          }
180  
181          // Check whether r2 still holds the value we set it to
182          sig_r2 = sc->regs->gpr[2];
183          if (sig_r2 != 0xaffebad5) {
184                  err = 5;
185 <                return;
185 >                goto ret;
186          }
187 +
188 +        // Restore pointer to Thread Local Storage
189 +  ret:
190 + #ifdef SYSTEM_CLOBBERS_R2
191 +        sc->regs->gpr[2] = (unsigned long)TOC;
192 + #endif
193   }

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines