324 |
the effective address of the memory exception. 'is_write' is 1 if a |
the effective address of the memory exception. 'is_write' is 1 if a |
325 |
write caused the exception and otherwise 0'. 'old_set' is the |
write caused the exception and otherwise 0'. 'old_set' is the |
326 |
signal set which should be restored */ |
signal set which should be restored */ |
327 |
static inline int handle_cpu_signal(unsigned long pc, |
static inline int handle_cpu_signal(unsigned long pc, unsigned long address, |
328 |
unsigned long address, |
int is_write, sigset_t *old_set) |
|
int is_write, |
|
|
sigset_t *old_set) |
|
329 |
{ |
{ |
330 |
#if defined(DEBUG_SIGNAL) |
#if defined(DEBUG_SIGNAL) |
331 |
printf("qemu: SIGSEGV pc=0x%08lx address=%08lx wr=%d oldset=0x%08lx\n", |
printf("qemu: SIGSEGV pc=0x%08lx address=%08lx wr=%d oldset=0x%08lx\n", |
353 |
} |
} |
354 |
} |
} |
355 |
|
|
356 |
|
#if defined(__i386__) |
357 |
|
|
358 |
int cpu_x86_signal_handler(int host_signum, struct siginfo *info, |
int cpu_x86_signal_handler(int host_signum, struct siginfo *info, |
359 |
void *puc) |
void *puc) |
360 |
{ |
{ |
|
#if defined(__i386__) |
|
361 |
struct ucontext *uc = puc; |
struct ucontext *uc = puc; |
362 |
unsigned long pc; |
unsigned long pc; |
|
sigset_t *pold_set; |
|
363 |
|
|
364 |
#ifndef REG_EIP |
#ifndef REG_EIP |
365 |
/* for glibc 2.1 */ |
/* for glibc 2.1 */ |
368 |
#define REG_TRAPNO TRAPNO |
#define REG_TRAPNO TRAPNO |
369 |
#endif |
#endif |
370 |
pc = uc->uc_mcontext.gregs[REG_EIP]; |
pc = uc->uc_mcontext.gregs[REG_EIP]; |
|
pold_set = &uc->uc_sigmask; |
|
371 |
return handle_cpu_signal(pc, (unsigned long)info->si_addr, |
return handle_cpu_signal(pc, (unsigned long)info->si_addr, |
372 |
uc->uc_mcontext.gregs[REG_TRAPNO] == 0xe ? |
uc->uc_mcontext.gregs[REG_TRAPNO] == 0xe ? |
373 |
(uc->uc_mcontext.gregs[REG_ERR] >> 1) & 1 : 0, |
(uc->uc_mcontext.gregs[REG_ERR] >> 1) & 1 : 0, |
374 |
pold_set); |
&uc->uc_sigmask); |
375 |
|
} |
376 |
|
|
377 |
#elif defined(__powerpc) |
#elif defined(__powerpc) |
378 |
|
|
379 |
|
int cpu_x86_signal_handler(int host_signum, struct siginfo *info, |
380 |
|
void *puc) |
381 |
|
{ |
382 |
struct ucontext *uc = puc; |
struct ucontext *uc = puc; |
383 |
struct pt_regs *regs = uc->uc_mcontext.regs; |
struct pt_regs *regs = uc->uc_mcontext.regs; |
384 |
unsigned long pc; |
unsigned long pc; |
|
sigset_t *pold_set; |
|
385 |
int is_write; |
int is_write; |
386 |
|
|
387 |
pc = regs->nip; |
pc = regs->nip; |
|
pold_set = &uc->uc_sigmask; |
|
388 |
is_write = 0; |
is_write = 0; |
389 |
#if 0 |
#if 0 |
390 |
/* ppc 4xx case */ |
/* ppc 4xx case */ |
395 |
is_write = 1; |
is_write = 1; |
396 |
#endif |
#endif |
397 |
return handle_cpu_signal(pc, (unsigned long)info->si_addr, |
return handle_cpu_signal(pc, (unsigned long)info->si_addr, |
398 |
is_write, pold_set); |
is_write, &uc->uc_sigmask); |
399 |
|
} |
400 |
|
|
401 |
#else |
#else |
402 |
|
|
403 |
#error CPU specific signal handler needed |
#error CPU specific signal handler needed |
404 |
return 0; |
|
405 |
#endif |
#endif |
|
} |
|