43 |
|
return mmap((caddr_t)hint, size, PROT_READ | PROT_WRITE, MAP_PRIVATE, zero_fd, 0); |
44 |
|
} |
45 |
|
|
46 |
< |
|
47 |
< |
/* |
48 |
< |
* Screen fault handler |
49 |
< |
*/ |
50 |
< |
|
51 |
< |
const uintptr INVALID_PC = (uintptr)-1; |
52 |
< |
|
53 |
< |
static inline void do_handle_screen_fault(uintptr addr, uintptr pc = INVALID_PC) |
46 |
> |
// Screen fault handler |
47 |
> |
static bool screen_fault_handler(sigsegv_address_t fault_address, sigsegv_address_t fault_instruction) |
48 |
|
{ |
49 |
+ |
D(bug("screen_fault_handler: ADDR=0x%08X from IP=0x%08X\n", fault_address, fault_instruction)); |
50 |
+ |
const uintptr addr = (uintptr)fault_address; |
51 |
+ |
|
52 |
|
/* Someone attempted to write to the frame buffer. Make it writeable |
53 |
|
* now so that the data could actually be written. It will be made |
54 |
|
* read-only back in one of the screen update_*() functions. |
61 |
|
mprotect(page_ad, mainBuffer.pageSize, PROT_READ | PROT_WRITE); |
62 |
|
mainBuffer.dirty = true; |
63 |
|
UNLOCK_VOSF; |
64 |
< |
return; |
64 |
> |
return true; |
65 |
|
} |
66 |
|
|
67 |
|
/* Otherwise, we don't know how to handle the fault, let it crash */ |
68 |
|
fprintf(stderr, "do_handle_screen_fault: unhandled address 0x%08X", addr); |
69 |
< |
if (pc != INVALID_PC) |
70 |
< |
fprintf(stderr, " [IP=0x%08X]", pc); |
69 |
> |
if (fault_instruction != SIGSEGV_INVALID_PC) |
70 |
> |
fprintf(stderr, " [IP=0x%08X]", fault_instruction); |
71 |
|
fprintf(stderr, "\n"); |
72 |
< |
|
76 |
< |
signal(SIGSEGV, SIG_DFL); |
72 |
> |
return false; |
73 |
|
} |
74 |
|
|
79 |
– |
#if defined(HAVE_SIGINFO_T) |
80 |
– |
|
81 |
– |
static void Screen_fault_handler(int, siginfo_t * sip, void *) |
82 |
– |
{ |
83 |
– |
D(bug("Screen_fault_handler: ADDR=0x%08X\n", sip->si_addr)); |
84 |
– |
do_handle_screen_fault((uintptr)sip->si_addr); |
85 |
– |
} |
86 |
– |
|
87 |
– |
#elif defined(HAVE_SIGCONTEXT_SUBTERFUGE) |
88 |
– |
|
89 |
– |
# if defined(__i386__) && defined(__linux__) |
90 |
– |
static void Screen_fault_handler(int, struct sigcontext scs) |
91 |
– |
{ |
92 |
– |
D(bug("Screen_fault_handler: ADDR=0x%08X from IP=0x%08X\n", scs.cr2, scs.eip)); |
93 |
– |
do_handle_screen_fault((uintptr)scs.cr2, (uintptr)scs.eip); |
94 |
– |
} |
95 |
– |
|
96 |
– |
# elif defined(__m68k__) && defined(__NetBSD__) |
97 |
– |
|
98 |
– |
# include <m68k/frame.h> |
99 |
– |
static void Screen_fault_handler(int, int code, struct sigcontext *scp) |
100 |
– |
{ |
101 |
– |
D(bug("Screen_fault_handler: ADDR=0x%08X\n", code)); |
102 |
– |
struct sigstate { |
103 |
– |
int ss_flags; |
104 |
– |
struct frame ss_frame; |
105 |
– |
}; |
106 |
– |
struct sigstate *state = (struct sigstate *)scp->sc_ap; |
107 |
– |
uintptr fault_addr; |
108 |
– |
switch (state->ss_frame.f_format) { |
109 |
– |
case 7: // 68040 access error |
110 |
– |
// "code" is sometimes unreliable (i.e. contains NULL or a bogus address), reason unknown |
111 |
– |
fault_addr = state->ss_frame.f_fmt7.f_fa; |
112 |
– |
break; |
113 |
– |
default: |
114 |
– |
fault_addr = (uintptr)code; |
115 |
– |
break; |
116 |
– |
} |
117 |
– |
do_handle_screen_fault(fault_addr); |
118 |
– |
} |
119 |
– |
|
120 |
– |
# elif defined(__powerpc__) && defined(__linux__) |
121 |
– |
|
122 |
– |
static void Screen_fault_handler(int, struct sigcontext_struct *scs) |
123 |
– |
{ |
124 |
– |
D(bug("Screen_fault_handler: ADDR=0x%08X from IP=0x%08X\n", scs->regs->dar, scs->regs->nip)); |
125 |
– |
do_handle_screen_fault((uintptr)scs->regs->dar, (uintptr)scs->regs->nip); |
126 |
– |
} |
127 |
– |
|
128 |
– |
# else |
129 |
– |
# error "No suitable subterfuge for Video on SEGV signals" |
130 |
– |
# endif |
131 |
– |
#else |
132 |
– |
# error "Can't do Video on SEGV signals" |
133 |
– |
#endif |
134 |
– |
|
135 |
– |
|
136 |
– |
/* |
137 |
– |
* Screen fault handler initialization |
138 |
– |
*/ |
139 |
– |
|
140 |
– |
#if defined(HAVE_SIGINFO_T) |
141 |
– |
static bool Screen_fault_handler_init() |
142 |
– |
{ |
143 |
– |
// Setup SIGSEGV handler to process writes to frame buffer |
144 |
– |
sigemptyset(&vosf_sa.sa_mask); |
145 |
– |
vosf_sa.sa_sigaction = Screen_fault_handler; |
146 |
– |
vosf_sa.sa_flags = SA_SIGINFO; |
147 |
– |
return (sigaction(SIGSEGV, &vosf_sa, NULL) == 0); |
148 |
– |
} |
149 |
– |
#elif defined(HAVE_SIGCONTEXT_SUBTERFUGE) |
150 |
– |
static bool Screen_fault_handler_init() |
151 |
– |
{ |
152 |
– |
// Setup SIGSEGV handler to process writes to frame buffer |
153 |
– |
sigemptyset(&vosf_sa.sa_mask); |
154 |
– |
vosf_sa.sa_handler = (void (*)(int)) Screen_fault_handler; |
155 |
– |
#if !EMULATED_68K && defined(__NetBSD__) |
156 |
– |
sigaddset(&vosf_sa.sa_mask, SIGALRM); |
157 |
– |
vosf_sa.sa_flags = SA_ONSTACK; |
158 |
– |
#else |
159 |
– |
vosf_sa.sa_flags = 0; |
160 |
– |
#endif |
161 |
– |
return (sigaction(SIGSEGV, &vosf_sa, NULL) == 0); |
162 |
– |
} |
163 |
– |
#endif |
164 |
– |
|
165 |
– |
|
75 |
|
/* |
76 |
|
* Update display for Windowed mode and VOSF |
77 |
|
*/ |