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

Comparing BasiliskII/src/Unix/sigsegv.cpp (file contents):
Revision 1.16 by gbeauche, 2002-05-20T16:03:37Z vs.
Revision 1.24 by gbeauche, 2003-09-29T07:02:58Z

# Line 29 | Line 29
29   #include "config.h"
30   #endif
31  
32 + #include <list>
33   #include <signal.h>
34   #include "sigsegv.h"
35  
36 + #ifndef NO_STD_NAMESPACE
37 + using std::list;
38 + #endif
39 +
40   // Return value type of a signal handler (standard type if not defined)
41   #ifndef RETSIGTYPE
42   #define RETSIGTYPE void
# Line 40 | Line 45
45   // Type of the system signal handler
46   typedef RETSIGTYPE (*signal_handler)(int);
47  
43 // Is the fault to be ignored?
44 static bool sigsegv_ignore_fault = false;
45
48   // User's SIGSEGV handler
49   static sigsegv_fault_handler_t sigsegv_fault_handler = 0;
50  
# Line 57 | Line 59 | static bool sigsegv_do_install_handler(i
59   *  Instruction decoding aids
60   */
61  
60 // Transfer type
61 enum transfer_type_t {
62        TYPE_UNKNOWN,
63        TYPE_LOAD,
64        TYPE_STORE
65 };
66
62   // Transfer size
63   enum transfer_size_t {
64          SIZE_UNKNOWN,
# Line 72 | Line 67 | enum transfer_size_t {
67          SIZE_LONG
68   };
69  
70 + // Transfer type
71 + typedef sigsegv_transfer_type_t transfer_type_t;
72 +
73   #if (defined(powerpc) || defined(__powerpc__) || defined(__ppc__))
74   // Addressing mode
75   enum addressing_mode_t {
# Line 103 | Line 101 | static void powerpc_decode_instruction(i
101          signed int imm = (signed short)(opcode & 0xffff);
102          
103          // Analyze opcode
104 <        transfer_type_t transfer_type = TYPE_UNKNOWN;
104 >        transfer_type_t transfer_type = SIGSEGV_TRANSFER_UNKNOWN;
105          transfer_size_t transfer_size = SIZE_UNKNOWN;
106          addressing_mode_t addr_mode = MODE_UNKNOWN;
107          switch (primop) {
108          case 31:
109                  switch (exop) {
110                  case 23:        // lwzx
111 <                        transfer_type = TYPE_LOAD; transfer_size = SIZE_LONG; addr_mode = MODE_X; break;
111 >                        transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_LONG; addr_mode = MODE_X; break;
112                  case 55:        // lwzux
113 <                        transfer_type = TYPE_LOAD; transfer_size = SIZE_LONG; addr_mode = MODE_UX; break;
113 >                        transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_LONG; addr_mode = MODE_UX; break;
114                  case 87:        // lbzx
115 <                        transfer_type = TYPE_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_X; break;
115 >                        transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_X; break;
116                  case 119:       // lbzux
117 <                        transfer_type = TYPE_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_UX; break;
117 >                        transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_UX; break;
118                  case 151:       // stwx
119 <                        transfer_type = TYPE_STORE; transfer_size = SIZE_LONG; addr_mode = MODE_X; break;
119 >                        transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_LONG; addr_mode = MODE_X; break;
120                  case 183:       // stwux
121 <                        transfer_type = TYPE_STORE; transfer_size = SIZE_LONG; addr_mode = MODE_UX; break;
121 >                        transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_LONG; addr_mode = MODE_UX; break;
122                  case 215:       // stbx
123 <                        transfer_type = TYPE_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_X; break;
123 >                        transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_X; break;
124                  case 247:       // stbux
125 <                        transfer_type = TYPE_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_UX; break;
125 >                        transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_UX; break;
126                  case 279:       // lhzx
127 <                        transfer_type = TYPE_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_X; break;
127 >                        transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_X; break;
128                  case 311:       // lhzux
129 <                        transfer_type = TYPE_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_UX; break;
129 >                        transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_UX; break;
130                  case 343:       // lhax
131 <                        transfer_type = TYPE_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_X; break;
131 >                        transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_X; break;
132                  case 375:       // lhaux
133 <                        transfer_type = TYPE_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_UX; break;
133 >                        transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_UX; break;
134                  case 407:       // sthx
135 <                        transfer_type = TYPE_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_X; break;
135 >                        transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_X; break;
136                  case 439:       // sthux
137 <                        transfer_type = TYPE_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_UX; break;
137 >                        transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_UX; break;
138                  }
139                  break;
140          
141          case 32:        // lwz
142 <                transfer_type = TYPE_LOAD; transfer_size = SIZE_LONG; addr_mode = MODE_NORM; break;
142 >                transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_LONG; addr_mode = MODE_NORM; break;
143          case 33:        // lwzu
144 <                transfer_type = TYPE_LOAD; transfer_size = SIZE_LONG; addr_mode = MODE_U; break;
144 >                transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_LONG; addr_mode = MODE_U; break;
145          case 34:        // lbz
146 <                transfer_type = TYPE_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_NORM; break;
146 >                transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_NORM; break;
147          case 35:        // lbzu
148 <                transfer_type = TYPE_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_U; break;
148 >                transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_U; break;
149          case 36:        // stw
150 <                transfer_type = TYPE_STORE; transfer_size = SIZE_LONG; addr_mode = MODE_NORM; break;
150 >                transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_LONG; addr_mode = MODE_NORM; break;
151          case 37:        // stwu
152 <                transfer_type = TYPE_STORE; transfer_size = SIZE_LONG; addr_mode = MODE_U; break;
152 >                transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_LONG; addr_mode = MODE_U; break;
153          case 38:        // stb
154 <                transfer_type = TYPE_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_NORM; break;
154 >                transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_NORM; break;
155          case 39:        // stbu
156 <                transfer_type = TYPE_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_U; break;
156 >                transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_U; break;
157          case 40:        // lhz
158 <                transfer_type = TYPE_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_NORM; break;
158 >                transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_NORM; break;
159          case 41:        // lhzu
160 <                transfer_type = TYPE_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_U; break;
160 >                transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_U; break;
161          case 42:        // lha
162 <                transfer_type = TYPE_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_NORM; break;
162 >                transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_NORM; break;
163          case 43:        // lhau
164 <                transfer_type = TYPE_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_U; break;
164 >                transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_U; break;
165          case 44:        // sth
166 <                transfer_type = TYPE_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_NORM; break;
166 >                transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_NORM; break;
167          case 45:        // sthu
168 <                transfer_type = TYPE_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_U; break;
168 >                transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_U; break;
169          }
170          
171          // Calculate effective address
# Line 215 | Line 213 | static void powerpc_decode_instruction(i
213   #endif
214   #define SIGSEGV_FAULT_HANDLER_ARGLIST   int sig, siginfo_t *sip, void *scp
215   #define SIGSEGV_FAULT_ADDRESS                   sip->si_addr
216 + #if defined(__NetBSD__) || defined(__FreeBSD__)
217 + #if (defined(i386) || defined(__i386__))
218 + #define SIGSEGV_FAULT_INSTRUCTION               (((struct sigcontext *)scp)->sc_eip)
219 + #define SIGSEGV_REGISTER_FILE                   ((unsigned int *)&(((struct sigcontext *)scp)->sc_edi)) /* EDI is the first GPR (even below EIP) in sigcontext */
220 + #define SIGSEGV_SKIP_INSTRUCTION                ix86_skip_instruction
221 + #endif
222 + #endif
223   #if defined(__linux__)
224   #if (defined(i386) || defined(__i386__))
225   #include <sys/ucontext.h>
# Line 223 | Line 228 | static void powerpc_decode_instruction(i
228   #define SIGSEGV_REGISTER_FILE                   (unsigned int *)SIGSEGV_CONTEXT_REGS
229   #define SIGSEGV_SKIP_INSTRUCTION                ix86_skip_instruction
230   #endif
231 + #if (defined(x86_64) || defined(__x86_64__))
232 + #include <sys/ucontext.h>
233 + #define SIGSEGV_CONTEXT_REGS                    (((ucontext_t *)scp)->uc_mcontext.gregs)
234 + #define SIGSEGV_FAULT_INSTRUCTION               SIGSEGV_CONTEXT_REGS[16] /* should use REG_RIP instead */
235 + #define SIGSEGV_REGISTER_FILE                   (unsigned long *)SIGSEGV_CONTEXT_REGS
236 + #endif
237   #if (defined(ia64) || defined(__ia64__))
238   #define SIGSEGV_FAULT_INSTRUCTION               (((struct sigcontext *)scp)->sc_ip & ~0x3ULL) /* slot number is in bits 0 and 1 */
239   #endif
# Line 388 | Line 399 | enum {
399          X86_REG_EDI = 4
400   };
401   #endif
402 + #if defined(__NetBSD__) || defined(__FreeBSD__)
403 + enum {
404 +        X86_REG_EIP = 10,
405 +        X86_REG_EAX = 7,
406 +        X86_REG_ECX = 6,
407 +        X86_REG_EDX = 5,
408 +        X86_REG_EBX = 4,
409 +        X86_REG_ESP = 13,
410 +        X86_REG_EBP = 2,
411 +        X86_REG_ESI = 1,
412 +        X86_REG_EDI = 0
413 + };
414 + #endif
415   // FIXME: this is partly redundant with the instruction decoding phase
416   // to discover transfer type and register number
417   static inline int ix86_step_over_modrm(unsigned char * p)
# Line 429 | Line 453 | static bool ix86_skip_instruction(unsign
453          if (eip == 0)
454                  return false;
455          
456 <        transfer_type_t transfer_type = TYPE_UNKNOWN;
456 >        transfer_type_t transfer_type = SIGSEGV_TRANSFER_UNKNOWN;
457          transfer_size_t transfer_size = SIZE_LONG;
458          
459          int reg = -1;
# Line 444 | Line 468 | static bool ix86_skip_instruction(unsign
468  
469          // Decode instruction
470          switch (eip[0]) {
471 +        case 0x0f:
472 +            switch (eip[1]) {
473 +            case 0xb6: // MOVZX r32, r/m8
474 +            case 0xb7: // MOVZX r32, r/m16
475 +                switch (eip[2] & 0xc0) {
476 +                case 0x80:
477 +                    reg = (eip[2] >> 3) & 7;
478 +                    transfer_type = SIGSEGV_TRANSFER_LOAD;
479 +                    break;
480 +                case 0x40:
481 +                    reg = (eip[2] >> 3) & 7;
482 +                    transfer_type = SIGSEGV_TRANSFER_LOAD;
483 +                    break;
484 +                case 0x00:
485 +                    reg = (eip[2] >> 3) & 7;
486 +                    transfer_type = SIGSEGV_TRANSFER_LOAD;
487 +                    break;
488 +                }
489 +                len += 3 + ix86_step_over_modrm(eip + 2);
490 +                break;
491 +            }
492 +          break;
493          case 0x8a: // MOV r8, r/m8
494                  transfer_size = SIZE_BYTE;
495          case 0x8b: // MOV r32, r/m32 (or 16-bit operation)
496                  switch (eip[1] & 0xc0) {
497                  case 0x80:
498                          reg = (eip[1] >> 3) & 7;
499 <                        transfer_type = TYPE_LOAD;
499 >                        transfer_type = SIGSEGV_TRANSFER_LOAD;
500                          break;
501                  case 0x40:
502                          reg = (eip[1] >> 3) & 7;
503 <                        transfer_type = TYPE_LOAD;
503 >                        transfer_type = SIGSEGV_TRANSFER_LOAD;
504                          break;
505                  case 0x00:
506                          reg = (eip[1] >> 3) & 7;
507 <                        transfer_type = TYPE_LOAD;
507 >                        transfer_type = SIGSEGV_TRANSFER_LOAD;
508                          break;
509                  }
510                  len += 2 + ix86_step_over_modrm(eip + 1);
# Line 469 | Line 515 | static bool ix86_skip_instruction(unsign
515                  switch (eip[1] & 0xc0) {
516                  case 0x80:
517                          reg = (eip[1] >> 3) & 7;
518 <                        transfer_type = TYPE_STORE;
518 >                        transfer_type = SIGSEGV_TRANSFER_STORE;
519                          break;
520                  case 0x40:
521                          reg = (eip[1] >> 3) & 7;
522 <                        transfer_type = TYPE_STORE;
522 >                        transfer_type = SIGSEGV_TRANSFER_STORE;
523                          break;
524                  case 0x00:
525                          reg = (eip[1] >> 3) & 7;
526 <                        transfer_type = TYPE_STORE;
526 >                        transfer_type = SIGSEGV_TRANSFER_STORE;
527                          break;
528                  }
529                  len += 2 + ix86_step_over_modrm(eip + 1);
530                  break;
531          }
532  
533 <        if (transfer_type == TYPE_UNKNOWN) {
533 >        if (transfer_type == SIGSEGV_TRANSFER_UNKNOWN) {
534                  // Unknown machine code, let it crash. Then patch the decoder
535                  return false;
536          }
537  
538 <        if (transfer_type == TYPE_LOAD && reg != -1) {
538 >        if (transfer_type == SIGSEGV_TRANSFER_LOAD && reg != -1) {
539                  static const int x86_reg_map[8] = {
540                          X86_REG_EAX, X86_REG_ECX, X86_REG_EDX, X86_REG_EBX,
541                          X86_REG_ESP, X86_REG_EBP, X86_REG_ESI, X86_REG_EDI
# Line 515 | Line 561 | static bool ix86_skip_instruction(unsign
561   #if DEBUG
562          printf("%08x: %s %s access", regs[X86_REG_EIP],
563                     transfer_size == SIZE_BYTE ? "byte" : transfer_size == SIZE_WORD ? "word" : "long",
564 <                   transfer_type == TYPE_LOAD ? "read" : "write");
564 >                   transfer_type == SIGSEGV_TRANSFER_LOAD ? "read" : "write");
565          
566          if (reg != -1) {
567                  static const char * x86_reg_str_map[8] = {
568                          "eax", "ecx", "edx", "ebx",
569                          "esp", "ebp", "esi", "edi"
570                  };
571 <                printf(" %s register %%%s", transfer_type == TYPE_LOAD ? "to" : "from", x86_reg_str_map[reg]);
571 >                printf(" %s register %%%s", transfer_type == SIGSEGV_TRANSFER_LOAD ? "to" : "from", x86_reg_str_map[reg]);
572          }
573          printf(", %d bytes instruction\n", len);
574   #endif
# Line 539 | Line 585 | static bool powerpc_skip_instruction(uns
585          instruction_t instr;
586          powerpc_decode_instruction(&instr, *nip_p, regs);
587          
588 <        if (instr.transfer_type == TYPE_UNKNOWN) {
588 >        if (instr.transfer_type == SIGSEGV_TRANSFER_UNKNOWN) {
589                  // Unknown machine code, let it crash. Then patch the decoder
590                  return false;
591          }
# Line 547 | Line 593 | static bool powerpc_skip_instruction(uns
593   #if DEBUG
594          printf("%08x: %s %s access", *nip_p,
595                     instr.transfer_size == SIZE_BYTE ? "byte" : instr.transfer_size == SIZE_WORD ? "word" : "long",
596 <                   instr.transfer_type == TYPE_LOAD ? "read" : "write");
596 >                   instr.transfer_type == SIGSEGV_TRANSFER_LOAD ? "read" : "write");
597          
598          if (instr.addr_mode == MODE_U || instr.addr_mode == MODE_UX)
599                  printf(" r%d (ra = %08x)\n", instr.ra, instr.addr);
600 <        if (instr.transfer_type == TYPE_LOAD)
600 >        if (instr.transfer_type == SIGSEGV_TRANSFER_LOAD)
601                  printf(" r%d (rd = 0)\n", instr.rd);
602   #endif
603          
604          if (instr.addr_mode == MODE_U || instr.addr_mode == MODE_UX)
605                  regs[instr.ra] = instr.addr;
606 <        if (instr.transfer_type == TYPE_LOAD)
606 >        if (instr.transfer_type == SIGSEGV_TRANSFER_LOAD)
607                  regs[instr.rd] = 0;
608          
609          *nip_p += 4;
# Line 589 | Line 635 | static void sigsegv_handler(SIGSEGV_FAUL
635          bool fault_recovered = false;
636          
637          // Call user's handler and reinstall the global handler, if required
638 <        if (sigsegv_fault_handler(fault_address, fault_instruction)) {
638 >        switch (sigsegv_fault_handler(fault_address, fault_instruction)) {
639 >        case SIGSEGV_RETURN_SUCCESS:
640   #if (defined(HAVE_SIGACTION) ? defined(SIGACTION_NEED_REINSTALL) : defined(SIGNAL_NEED_REINSTALL))
641                  sigsegv_do_install_handler(sig);
642   #endif
643                  fault_recovered = true;
644 <        }
644 >                break;
645   #if HAVE_SIGSEGV_SKIP_INSTRUCTION
646 <        else if (sigsegv_ignore_fault) {
646 >        case SIGSEGV_RETURN_SKIP_INSTRUCTION:
647                  // Call the instruction skipper with the register file available
648                  if (SIGSEGV_SKIP_INSTRUCTION(SIGSEGV_REGISTER_FILE))
649                          fault_recovered = true;
650 <        }
650 >                break;
651   #endif
652 +        }
653  
654          if (!fault_recovered) {
655 <                // FAIL: reinstall default handler for "safe" crash
655 >                // Failure: reinstall default handler for "safe" crash
656   #define FAULT_HANDLER(sig) signal(sig, SIG_DFL);
657                  SIGSEGV_ALL_SIGNALS
658   #undef FAULT_HANDLER
# Line 626 | Line 674 | static bool sigsegv_do_install_handler(i
674   {
675          // Setup SIGSEGV handler to process writes to frame buffer
676   #ifdef HAVE_SIGACTION
677 <        struct sigaction vosf_sa;
678 <        sigemptyset(&vosf_sa.sa_mask);
679 <        vosf_sa.sa_sigaction = sigsegv_handler;
680 <        vosf_sa.sa_flags = SA_SIGINFO;
681 <        return (sigaction(sig, &vosf_sa, 0) == 0);
677 >        struct sigaction sigsegv_sa;
678 >        sigemptyset(&sigsegv_sa.sa_mask);
679 >        sigsegv_sa.sa_sigaction = sigsegv_handler;
680 >        sigsegv_sa.sa_flags = SA_SIGINFO;
681 >        return (sigaction(sig, &sigsegv_sa, 0) == 0);
682   #else
683          return (signal(sig, (signal_handler)sigsegv_handler) != SIG_ERR);
684   #endif
# Line 642 | Line 690 | static bool sigsegv_do_install_handler(i
690   {
691          // Setup SIGSEGV handler to process writes to frame buffer
692   #ifdef HAVE_SIGACTION
693 <        struct sigaction vosf_sa;
694 <        sigemptyset(&vosf_sa.sa_mask);
695 <        vosf_sa.sa_handler = (signal_handler)sigsegv_handler;
693 >        struct sigaction sigsegv_sa;
694 >        sigemptyset(&sigsegv_sa.sa_mask);
695 >        sigsegv_sa.sa_handler = (signal_handler)sigsegv_handler;
696 >        sigsegv_sa.sa_flags = 0;
697   #if !EMULATED_68K && defined(__NetBSD__)
698 <        sigaddset(&vosf_sa.sa_mask, SIGALRM);
699 <        vosf_sa.sa_flags = SA_ONSTACK;
651 < #else
652 <        vosf_sa.sa_flags = 0;
698 >        sigaddset(&sigsegv_sa.sa_mask, SIGALRM);
699 >        sigsegv_sa.sa_flags |= SA_ONSTACK;
700   #endif
701 <        return (sigaction(sig, &vosf_sa, 0) == 0);
701 >        return (sigaction(sig, &sigsegv_sa, 0) == 0);
702   #else
703          return (signal(sig, (signal_handler)sigsegv_handler) != SIG_ERR);
704   #endif
# Line 690 | Line 737 | void sigsegv_deinstall_handler(void)
737  
738  
739   /*
693 *  SIGSEGV ignore state modifier
694 */
695
696 void sigsegv_set_ignore_state(bool ignore_fault)
697 {
698        sigsegv_ignore_fault = ignore_fault;
699 }
700
701
702 /*
740   *  Set callback function when we cannot handle the fault
741   */
742  
# Line 724 | Line 761 | static int page_size;
761   static volatile char * page = 0;
762   static volatile int handler_called = 0;
763  
764 < static bool sigsegv_test_handler(sigsegv_address_t fault_address, sigsegv_address_t instruction_address)
764 > static sigsegv_return_t sigsegv_test_handler(sigsegv_address_t fault_address, sigsegv_address_t instruction_address)
765   {
766          handler_called++;
767          if ((fault_address - 123) != page)
768                  exit(1);
769          if (vm_protect((char *)((unsigned long)fault_address & -page_size), page_size, VM_PAGE_READ | VM_PAGE_WRITE) != 0)
770                  exit(1);
771 <        return true;
771 >        return SIGSEGV_RETURN_SUCCESS;
772   }
773  
774   #ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION
775 < static bool sigsegv_insn_handler(sigsegv_address_t fault_address, sigsegv_address_t instruction_address)
775 > static sigsegv_return_t sigsegv_insn_handler(sigsegv_address_t fault_address, sigsegv_address_t instruction_address)
776   {
777 <        return false;
777 >        if (((unsigned long)fault_address - (unsigned long)page) < page_size)
778 >                return SIGSEGV_SRETURN_KIP_INSTRUCTION;
779 >        return SIGSEGV_RETURN_FAILURE;
780   }
781   #endif
782  
# Line 766 | Line 805 | int main(void)
805          if (!sigsegv_install_handler(sigsegv_insn_handler))
806                  return 1;
807          
808 <        if (vm_protect((char *)page, page_size, VM_PAGE_WRITE) < 0)
808 >        if (vm_protect((char *)page, page_size, VM_PAGE_READ | VM_PAGE_WRITE) < 0)
809                  return 1;
810          
811          for (int i = 0; i < page_size; i++)
# Line 775 | Line 814 | int main(void)
814          if (vm_protect((char *)page, page_size, VM_PAGE_NOACCESS) < 0)
815                  return 1;
816          
778        sigsegv_set_ignore_state(true);
779
817   #define TEST_SKIP_INSTRUCTION(TYPE) do {                                \
818                  const unsigned int TAG = 0x12345678;                    \
819                  TYPE data = *((TYPE *)(page + sizeof(TYPE)));   \

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines