|
@@ -517,6 +517,8 @@ static int core_dump_signal(int sig)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+int host_interrupt_signal;
|
|
|
|
+
|
|
static void signal_table_init(const char *rtsig_map)
|
|
static void signal_table_init(const char *rtsig_map)
|
|
{
|
|
{
|
|
int hsig, tsig, count;
|
|
int hsig, tsig, count;
|
|
@@ -580,10 +582,10 @@ static void signal_table_init(const char *rtsig_map)
|
|
* Attempts for configure "missing" signals via sigaction will be
|
|
* Attempts for configure "missing" signals via sigaction will be
|
|
* silently ignored.
|
|
* silently ignored.
|
|
*
|
|
*
|
|
- * Reserve one signal for internal usage (see below).
|
|
|
|
|
|
+ * Reserve two signals for internal usage (see below).
|
|
*/
|
|
*/
|
|
|
|
|
|
- hsig = SIGRTMIN + 1;
|
|
|
|
|
|
+ hsig = SIGRTMIN + 2;
|
|
for (tsig = TARGET_SIGRTMIN;
|
|
for (tsig = TARGET_SIGRTMIN;
|
|
hsig <= SIGRTMAX && tsig <= TARGET_NSIG;
|
|
hsig <= SIGRTMAX && tsig <= TARGET_NSIG;
|
|
hsig++, tsig++) {
|
|
hsig++, tsig++) {
|
|
@@ -604,12 +606,17 @@ static void signal_table_init(const char *rtsig_map)
|
|
host_to_target_signal_table[SIGABRT] = 0;
|
|
host_to_target_signal_table[SIGABRT] = 0;
|
|
for (hsig = SIGRTMIN; hsig <= SIGRTMAX; hsig++) {
|
|
for (hsig = SIGRTMIN; hsig <= SIGRTMAX; hsig++) {
|
|
if (!host_to_target_signal_table[hsig]) {
|
|
if (!host_to_target_signal_table[hsig]) {
|
|
- host_to_target_signal_table[hsig] = TARGET_SIGABRT;
|
|
|
|
- break;
|
|
|
|
|
|
+ if (host_interrupt_signal) {
|
|
|
|
+ host_to_target_signal_table[hsig] = TARGET_SIGABRT;
|
|
|
|
+ break;
|
|
|
|
+ } else {
|
|
|
|
+ host_interrupt_signal = hsig;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (hsig > SIGRTMAX) {
|
|
if (hsig > SIGRTMAX) {
|
|
- fprintf(stderr, "No rt signals left for SIGABRT mapping\n");
|
|
|
|
|
|
+ fprintf(stderr,
|
|
|
|
+ "No rt signals left for interrupt and SIGABRT mapping\n");
|
|
exit(EXIT_FAILURE);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -689,6 +696,8 @@ void signal_init(const char *rtsig_map)
|
|
}
|
|
}
|
|
sigact_table[tsig - 1]._sa_handler = thand;
|
|
sigact_table[tsig - 1]._sa_handler = thand;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ sigaction(host_interrupt_signal, &act, NULL);
|
|
}
|
|
}
|
|
|
|
|
|
/* Force a synchronously taken signal. The kernel force_sig() function
|
|
/* Force a synchronously taken signal. The kernel force_sig() function
|
|
@@ -1036,6 +1045,12 @@ static void host_signal_handler(int host_sig, siginfo_t *info, void *puc)
|
|
bool sync_sig = false;
|
|
bool sync_sig = false;
|
|
void *sigmask;
|
|
void *sigmask;
|
|
|
|
|
|
|
|
+ if (host_sig == host_interrupt_signal) {
|
|
|
|
+ ts->signal_pending = 1;
|
|
|
|
+ cpu_exit(thread_cpu);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
/*
|
|
/*
|
|
* Non-spoofed SIGSEGV and SIGBUS are synchronous, and need special
|
|
* Non-spoofed SIGSEGV and SIGBUS are synchronous, and need special
|
|
* handling wrt signal blocking and unwinding. Non-spoofed SIGILL,
|
|
* handling wrt signal blocking and unwinding. Non-spoofed SIGILL,
|