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.23 by gbeauche, 2003-08-17T10:52:52Z

# 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  
48 < // Is the fault to be ignored?
49 < static bool sigsegv_ignore_fault = false;
48 > // Ignore range chain
49 > struct ignore_range_t {
50 >        sigsegv_address_t       start;
51 >        unsigned long           length;
52 >        int                                     transfer_type;
53 > };
54 >
55 > typedef list<ignore_range_t> ignore_range_list_t;
56 > ignore_range_list_t sigsegv_ignore_ranges;
57  
58   // User's SIGSEGV handler
59   static sigsegv_fault_handler_t sigsegv_fault_handler = 0;
# Line 52 | Line 64 | static sigsegv_state_dumper_t sigsegv_st
64   // Actual SIGSEGV handler installer
65   static bool sigsegv_do_install_handler(int sig);
66  
67 + // Find ignore range matching address
68 + static inline ignore_range_list_t::iterator sigsegv_find_ignore_range(sigsegv_address_t address)
69 + {
70 +        ignore_range_list_t::iterator it;
71 +        for (it = sigsegv_ignore_ranges.begin(); it != sigsegv_ignore_ranges.end(); it++)
72 +                if (address >= it->start && address < it->start + it->length)
73 +                        break;
74 +        return it;
75 + }
76 +
77  
78   /*
79   *  Instruction decoding aids
80   */
81  
60 // Transfer type
61 enum transfer_type_t {
62        TYPE_UNKNOWN,
63        TYPE_LOAD,
64        TYPE_STORE
65 };
66
82   // Transfer size
83   enum transfer_size_t {
84          SIZE_UNKNOWN,
# Line 72 | Line 87 | enum transfer_size_t {
87          SIZE_LONG
88   };
89  
90 + // Transfer type
91 + typedef sigsegv_transfer_type_t transfer_type_t;
92 +
93   #if (defined(powerpc) || defined(__powerpc__) || defined(__ppc__))
94   // Addressing mode
95   enum addressing_mode_t {
# Line 103 | Line 121 | static void powerpc_decode_instruction(i
121          signed int imm = (signed short)(opcode & 0xffff);
122          
123          // Analyze opcode
124 <        transfer_type_t transfer_type = TYPE_UNKNOWN;
124 >        transfer_type_t transfer_type = SIGSEGV_TRANSFER_UNKNOWN;
125          transfer_size_t transfer_size = SIZE_UNKNOWN;
126          addressing_mode_t addr_mode = MODE_UNKNOWN;
127          switch (primop) {
128          case 31:
129                  switch (exop) {
130                  case 23:        // lwzx
131 <                        transfer_type = TYPE_LOAD; transfer_size = SIZE_LONG; addr_mode = MODE_X; break;
131 >                        transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_LONG; addr_mode = MODE_X; break;
132                  case 55:        // lwzux
133 <                        transfer_type = TYPE_LOAD; transfer_size = SIZE_LONG; addr_mode = MODE_UX; break;
133 >                        transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_LONG; addr_mode = MODE_UX; break;
134                  case 87:        // lbzx
135 <                        transfer_type = TYPE_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_X; break;
135 >                        transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_X; break;
136                  case 119:       // lbzux
137 <                        transfer_type = TYPE_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_UX; break;
137 >                        transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_UX; break;
138                  case 151:       // stwx
139 <                        transfer_type = TYPE_STORE; transfer_size = SIZE_LONG; addr_mode = MODE_X; break;
139 >                        transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_LONG; addr_mode = MODE_X; break;
140                  case 183:       // stwux
141 <                        transfer_type = TYPE_STORE; transfer_size = SIZE_LONG; addr_mode = MODE_UX; break;
141 >                        transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_LONG; addr_mode = MODE_UX; break;
142                  case 215:       // stbx
143 <                        transfer_type = TYPE_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_X; break;
143 >                        transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_X; break;
144                  case 247:       // stbux
145 <                        transfer_type = TYPE_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_UX; break;
145 >                        transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_UX; break;
146                  case 279:       // lhzx
147 <                        transfer_type = TYPE_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_X; break;
147 >                        transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_X; break;
148                  case 311:       // lhzux
149 <                        transfer_type = TYPE_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_UX; break;
149 >                        transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_UX; break;
150                  case 343:       // lhax
151 <                        transfer_type = TYPE_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_X; break;
151 >                        transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_X; break;
152                  case 375:       // lhaux
153 <                        transfer_type = TYPE_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_UX; break;
153 >                        transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_UX; break;
154                  case 407:       // sthx
155 <                        transfer_type = TYPE_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_X; break;
155 >                        transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_X; break;
156                  case 439:       // sthux
157 <                        transfer_type = TYPE_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_UX; break;
157 >                        transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_UX; break;
158                  }
159                  break;
160          
161          case 32:        // lwz
162 <                transfer_type = TYPE_LOAD; transfer_size = SIZE_LONG; addr_mode = MODE_NORM; break;
162 >                transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_LONG; addr_mode = MODE_NORM; break;
163          case 33:        // lwzu
164 <                transfer_type = TYPE_LOAD; transfer_size = SIZE_LONG; addr_mode = MODE_U; break;
164 >                transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_LONG; addr_mode = MODE_U; break;
165          case 34:        // lbz
166 <                transfer_type = TYPE_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_NORM; break;
166 >                transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_NORM; break;
167          case 35:        // lbzu
168 <                transfer_type = TYPE_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_U; break;
168 >                transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_BYTE; addr_mode = MODE_U; break;
169          case 36:        // stw
170 <                transfer_type = TYPE_STORE; transfer_size = SIZE_LONG; addr_mode = MODE_NORM; break;
170 >                transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_LONG; addr_mode = MODE_NORM; break;
171          case 37:        // stwu
172 <                transfer_type = TYPE_STORE; transfer_size = SIZE_LONG; addr_mode = MODE_U; break;
172 >                transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_LONG; addr_mode = MODE_U; break;
173          case 38:        // stb
174 <                transfer_type = TYPE_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_NORM; break;
174 >                transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_NORM; break;
175          case 39:        // stbu
176 <                transfer_type = TYPE_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_U; break;
176 >                transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_BYTE; addr_mode = MODE_U; break;
177          case 40:        // lhz
178 <                transfer_type = TYPE_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_NORM; break;
178 >                transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_NORM; break;
179          case 41:        // lhzu
180 <                transfer_type = TYPE_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_U; break;
180 >                transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_U; break;
181          case 42:        // lha
182 <                transfer_type = TYPE_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_NORM; break;
182 >                transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_NORM; break;
183          case 43:        // lhau
184 <                transfer_type = TYPE_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_U; break;
184 >                transfer_type = SIGSEGV_TRANSFER_LOAD; transfer_size = SIZE_WORD; addr_mode = MODE_U; break;
185          case 44:        // sth
186 <                transfer_type = TYPE_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_NORM; break;
186 >                transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_NORM; break;
187          case 45:        // sthu
188 <                transfer_type = TYPE_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_U; break;
188 >                transfer_type = SIGSEGV_TRANSFER_STORE; transfer_size = SIZE_WORD; addr_mode = MODE_U; break;
189          }
190          
191          // Calculate effective address
# Line 215 | Line 233 | static void powerpc_decode_instruction(i
233   #endif
234   #define SIGSEGV_FAULT_HANDLER_ARGLIST   int sig, siginfo_t *sip, void *scp
235   #define SIGSEGV_FAULT_ADDRESS                   sip->si_addr
236 + #if defined(__NetBSD__) || defined(__FreeBSD__)
237 + #if (defined(i386) || defined(__i386__))
238 + #define SIGSEGV_FAULT_INSTRUCTION               (((struct sigcontext *)scp)->sc_eip)
239 + #define SIGSEGV_REGISTER_FILE                   ((unsigned int *)&(((struct sigcontext *)scp)->sc_edi)) /* EDI is the first GPR (even below EIP) in sigcontext */
240 + #define SIGSEGV_SKIP_INSTRUCTION                ix86_skip_instruction
241 + #endif
242 + #endif
243   #if defined(__linux__)
244   #if (defined(i386) || defined(__i386__))
245   #include <sys/ucontext.h>
# Line 223 | Line 248 | static void powerpc_decode_instruction(i
248   #define SIGSEGV_REGISTER_FILE                   (unsigned int *)SIGSEGV_CONTEXT_REGS
249   #define SIGSEGV_SKIP_INSTRUCTION                ix86_skip_instruction
250   #endif
251 + #if (defined(x86_64) || defined(__x86_64__))
252 + #include <sys/ucontext.h>
253 + #define SIGSEGV_CONTEXT_REGS                    (((ucontext_t *)scp)->uc_mcontext.gregs)
254 + #define SIGSEGV_FAULT_INSTRUCTION               SIGSEGV_CONTEXT_REGS[16] /* should use REG_RIP instead */
255 + #define SIGSEGV_REGISTER_FILE                   (unsigned long *)SIGSEGV_CONTEXT_REGS
256 + #endif
257   #if (defined(ia64) || defined(__ia64__))
258   #define SIGSEGV_FAULT_INSTRUCTION               (((struct sigcontext *)scp)->sc_ip & ~0x3ULL) /* slot number is in bits 0 and 1 */
259   #endif
# Line 388 | Line 419 | enum {
419          X86_REG_EDI = 4
420   };
421   #endif
422 + #if defined(__NetBSD__) || defined(__FreeBSD__)
423 + enum {
424 +        X86_REG_EIP = 10,
425 +        X86_REG_EAX = 7,
426 +        X86_REG_ECX = 6,
427 +        X86_REG_EDX = 5,
428 +        X86_REG_EBX = 4,
429 +        X86_REG_ESP = 13,
430 +        X86_REG_EBP = 2,
431 +        X86_REG_ESI = 1,
432 +        X86_REG_EDI = 0
433 + };
434 + #endif
435   // FIXME: this is partly redundant with the instruction decoding phase
436   // to discover transfer type and register number
437   static inline int ix86_step_over_modrm(unsigned char * p)
# Line 429 | Line 473 | static bool ix86_skip_instruction(unsign
473          if (eip == 0)
474                  return false;
475          
476 <        transfer_type_t transfer_type = TYPE_UNKNOWN;
476 >        transfer_type_t transfer_type = SIGSEGV_TRANSFER_UNKNOWN;
477          transfer_size_t transfer_size = SIZE_LONG;
478          
479          int reg = -1;
# Line 444 | Line 488 | static bool ix86_skip_instruction(unsign
488  
489          // Decode instruction
490          switch (eip[0]) {
491 +        case 0x0f:
492 +            switch (eip[1]) {
493 +            case 0xb6: // MOVZX r32, r/m8
494 +            case 0xb7: // MOVZX r32, r/m16
495 +                switch (eip[2] & 0xc0) {
496 +                case 0x80:
497 +                    reg = (eip[2] >> 3) & 7;
498 +                    transfer_type = SIGSEGV_TRANSFER_LOAD;
499 +                    break;
500 +                case 0x40:
501 +                    reg = (eip[2] >> 3) & 7;
502 +                    transfer_type = SIGSEGV_TRANSFER_LOAD;
503 +                    break;
504 +                case 0x00:
505 +                    reg = (eip[2] >> 3) & 7;
506 +                    transfer_type = SIGSEGV_TRANSFER_LOAD;
507 +                    break;
508 +                }
509 +                len += 3 + ix86_step_over_modrm(eip + 2);
510 +                break;
511 +            }
512 +          break;
513          case 0x8a: // MOV r8, r/m8
514                  transfer_size = SIZE_BYTE;
515          case 0x8b: // MOV r32, r/m32 (or 16-bit operation)
516                  switch (eip[1] & 0xc0) {
517                  case 0x80:
518                          reg = (eip[1] >> 3) & 7;
519 <                        transfer_type = TYPE_LOAD;
519 >                        transfer_type = SIGSEGV_TRANSFER_LOAD;
520                          break;
521                  case 0x40:
522                          reg = (eip[1] >> 3) & 7;
523 <                        transfer_type = TYPE_LOAD;
523 >                        transfer_type = SIGSEGV_TRANSFER_LOAD;
524                          break;
525                  case 0x00:
526                          reg = (eip[1] >> 3) & 7;
527 <                        transfer_type = TYPE_LOAD;
527 >                        transfer_type = SIGSEGV_TRANSFER_LOAD;
528                          break;
529                  }
530                  len += 2 + ix86_step_over_modrm(eip + 1);
# Line 469 | Line 535 | static bool ix86_skip_instruction(unsign
535                  switch (eip[1] & 0xc0) {
536                  case 0x80:
537                          reg = (eip[1] >> 3) & 7;
538 <                        transfer_type = TYPE_STORE;
538 >                        transfer_type = SIGSEGV_TRANSFER_STORE;
539                          break;
540                  case 0x40:
541                          reg = (eip[1] >> 3) & 7;
542 <                        transfer_type = TYPE_STORE;
542 >                        transfer_type = SIGSEGV_TRANSFER_STORE;
543                          break;
544                  case 0x00:
545                          reg = (eip[1] >> 3) & 7;
546 <                        transfer_type = TYPE_STORE;
546 >                        transfer_type = SIGSEGV_TRANSFER_STORE;
547                          break;
548                  }
549                  len += 2 + ix86_step_over_modrm(eip + 1);
550                  break;
551          }
552  
553 <        if (transfer_type == TYPE_UNKNOWN) {
553 >        if (transfer_type == SIGSEGV_TRANSFER_UNKNOWN) {
554                  // Unknown machine code, let it crash. Then patch the decoder
555                  return false;
556          }
557  
558 <        if (transfer_type == TYPE_LOAD && reg != -1) {
558 >        if (transfer_type == SIGSEGV_TRANSFER_LOAD && reg != -1) {
559                  static const int x86_reg_map[8] = {
560                          X86_REG_EAX, X86_REG_ECX, X86_REG_EDX, X86_REG_EBX,
561                          X86_REG_ESP, X86_REG_EBP, X86_REG_ESI, X86_REG_EDI
# Line 515 | Line 581 | static bool ix86_skip_instruction(unsign
581   #if DEBUG
582          printf("%08x: %s %s access", regs[X86_REG_EIP],
583                     transfer_size == SIZE_BYTE ? "byte" : transfer_size == SIZE_WORD ? "word" : "long",
584 <                   transfer_type == TYPE_LOAD ? "read" : "write");
584 >                   transfer_type == SIGSEGV_TRANSFER_LOAD ? "read" : "write");
585          
586          if (reg != -1) {
587                  static const char * x86_reg_str_map[8] = {
588                          "eax", "ecx", "edx", "ebx",
589                          "esp", "ebp", "esi", "edi"
590                  };
591 <                printf(" %s register %%%s", transfer_type == TYPE_LOAD ? "to" : "from", x86_reg_str_map[reg]);
591 >                printf(" %s register %%%s", transfer_type == SIGSEGV_TRANSFER_LOAD ? "to" : "from", x86_reg_str_map[reg]);
592          }
593          printf(", %d bytes instruction\n", len);
594   #endif
# Line 539 | Line 605 | static bool powerpc_skip_instruction(uns
605          instruction_t instr;
606          powerpc_decode_instruction(&instr, *nip_p, regs);
607          
608 <        if (instr.transfer_type == TYPE_UNKNOWN) {
608 >        if (instr.transfer_type == SIGSEGV_TRANSFER_UNKNOWN) {
609                  // Unknown machine code, let it crash. Then patch the decoder
610                  return false;
611          }
612  
613 +        ignore_range_list_t::iterator it = sigsegv_find_ignore_range((sigsegv_address_t)instr.addr);
614 +        if (it == sigsegv_ignore_ranges.end() || ((it->transfer_type & instr.transfer_type) != instr.transfer_type)) {
615 +                // Address doesn't fall into ignore ranges list, let it crash.
616 +                return false;
617 +        }
618 +
619   #if DEBUG
620          printf("%08x: %s %s access", *nip_p,
621                     instr.transfer_size == SIZE_BYTE ? "byte" : instr.transfer_size == SIZE_WORD ? "word" : "long",
622 <                   instr.transfer_type == TYPE_LOAD ? "read" : "write");
622 >                   instr.transfer_type == SIGSEGV_TRANSFER_LOAD ? "read" : "write");
623          
624          if (instr.addr_mode == MODE_U || instr.addr_mode == MODE_UX)
625                  printf(" r%d (ra = %08x)\n", instr.ra, instr.addr);
626 <        if (instr.transfer_type == TYPE_LOAD)
626 >        if (instr.transfer_type == SIGSEGV_TRANSFER_LOAD)
627                  printf(" r%d (rd = 0)\n", instr.rd);
628   #endif
629          
630          if (instr.addr_mode == MODE_U || instr.addr_mode == MODE_UX)
631                  regs[instr.ra] = instr.addr;
632 <        if (instr.transfer_type == TYPE_LOAD)
632 >        if (instr.transfer_type == SIGSEGV_TRANSFER_LOAD)
633                  regs[instr.rd] = 0;
634          
635          *nip_p += 4;
# Line 596 | Line 668 | static void sigsegv_handler(SIGSEGV_FAUL
668                  fault_recovered = true;
669          }
670   #if HAVE_SIGSEGV_SKIP_INSTRUCTION
671 <        else if (sigsegv_ignore_fault) {
671 >        else if (sigsegv_ignore_ranges.size() > 0) {
672                  // Call the instruction skipper with the register file available
673                  if (SIGSEGV_SKIP_INSTRUCTION(SIGSEGV_REGISTER_FILE))
674                          fault_recovered = true;
# Line 626 | Line 698 | static bool sigsegv_do_install_handler(i
698   {
699          // Setup SIGSEGV handler to process writes to frame buffer
700   #ifdef HAVE_SIGACTION
701 <        struct sigaction vosf_sa;
702 <        sigemptyset(&vosf_sa.sa_mask);
703 <        vosf_sa.sa_sigaction = sigsegv_handler;
704 <        vosf_sa.sa_flags = SA_SIGINFO;
705 <        return (sigaction(sig, &vosf_sa, 0) == 0);
701 >        struct sigaction sigsegv_sa;
702 >        sigemptyset(&sigsegv_sa.sa_mask);
703 >        sigsegv_sa.sa_sigaction = sigsegv_handler;
704 >        sigsegv_sa.sa_flags = SA_SIGINFO;
705 >        return (sigaction(sig, &sigsegv_sa, 0) == 0);
706   #else
707          return (signal(sig, (signal_handler)sigsegv_handler) != SIG_ERR);
708   #endif
# Line 642 | Line 714 | static bool sigsegv_do_install_handler(i
714   {
715          // Setup SIGSEGV handler to process writes to frame buffer
716   #ifdef HAVE_SIGACTION
717 <        struct sigaction vosf_sa;
718 <        sigemptyset(&vosf_sa.sa_mask);
719 <        vosf_sa.sa_handler = (signal_handler)sigsegv_handler;
717 >        struct sigaction sigsegv_sa;
718 >        sigemptyset(&sigsegv_sa.sa_mask);
719 >        sigsegv_sa.sa_handler = (signal_handler)sigsegv_handler;
720 >        sigsegv_sa.sa_flags = 0;
721   #if !EMULATED_68K && defined(__NetBSD__)
722 <        sigaddset(&vosf_sa.sa_mask, SIGALRM);
723 <        vosf_sa.sa_flags = SA_ONSTACK;
651 < #else
652 <        vosf_sa.sa_flags = 0;
722 >        sigaddset(&sigsegv_sa.sa_mask, SIGALRM);
723 >        sigsegv_sa.sa_flags |= SA_ONSTACK;
724   #endif
725 <        return (sigaction(sig, &vosf_sa, 0) == 0);
725 >        return (sigaction(sig, &sigsegv_sa, 0) == 0);
726   #else
727          return (signal(sig, (signal_handler)sigsegv_handler) != SIG_ERR);
728   #endif
# Line 690 | Line 761 | void sigsegv_deinstall_handler(void)
761  
762  
763   /*
764 < *  SIGSEGV ignore state modifier
764 > *  Add SIGSEGV ignore range
765   */
766  
767 < void sigsegv_set_ignore_state(bool ignore_fault)
767 > void sigsegv_add_ignore_range(sigsegv_address_t address, unsigned long length, int transfer_type)
768   {
769 <        sigsegv_ignore_fault = ignore_fault;
769 >        ignore_range_t ignore_range;
770 >        ignore_range.start = address;
771 >        ignore_range.length = length;
772 >        ignore_range.transfer_type = transfer_type;
773 >        sigsegv_ignore_ranges.push_front(ignore_range);
774 > }
775 >
776 >
777 > /*
778 > *  Remove SIGSEGV ignore range. Range must match installed one, otherwise FALSE is returned.
779 > */
780 >
781 > bool sigsegv_remove_ignore_range(sigsegv_address_t address, unsigned long length, int transfer_type)
782 > {
783 >        ignore_range_list_t::iterator it;
784 >        for (it = sigsegv_ignore_ranges.begin(); it != sigsegv_ignore_ranges.end(); it++)
785 >                if (it->start == address && it->length == length && ((it->transfer_type & transfer_type) == transfer_type))
786 >                        break;
787 >
788 >        if (it != sigsegv_ignore_ranges.end()) {
789 >                if (it->transfer_type != transfer_type)
790 >                        it->transfer_type &= ~transfer_type;
791 >                else
792 >                        sigsegv_ignore_ranges.erase(it);
793 >                return true;
794 >        }
795 >
796 >        return false;
797   }
798  
799  
# Line 766 | Line 864 | int main(void)
864          if (!sigsegv_install_handler(sigsegv_insn_handler))
865                  return 1;
866          
867 <        if (vm_protect((char *)page, page_size, VM_PAGE_WRITE) < 0)
867 >        if (vm_protect((char *)page, page_size, VM_PAGE_READ | VM_PAGE_WRITE) < 0)
868                  return 1;
869          
870          for (int i = 0; i < page_size; i++)
# Line 775 | Line 873 | int main(void)
873          if (vm_protect((char *)page, page_size, VM_PAGE_NOACCESS) < 0)
874                  return 1;
875          
876 <        sigsegv_set_ignore_state(true);
876 >        sigsegv_add_ignore_range((char *)page, page_size, SIGSEGV_TRANSFER_LOAD | SIGSEGV_TRANSFER_STORE);
877  
878   #define TEST_SKIP_INSTRUCTION(TYPE) do {                                \
879                  const unsigned int TAG = 0x12345678;                    \

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines