PageRenderTime 44ms CodeModel.GetById 17ms RepoModel.GetById 0ms app.codeStats 0ms

/tools/qemu-xen/darwin-user/signal.c

https://bitbucket.org/ace0/xen-restore-information
C | 453 lines | 338 code | 66 blank | 49 comment | 73 complexity | dc0c0296ae4ea115b6bcaa9d88e6e137 MD5 | raw file
  1. /*
  2. * Emulation of Linux signals
  3. *
  4. * Copyright (c) 2003 Fabrice Bellard
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include <stdlib.h>
  20. #include <stdio.h>
  21. #include <string.h>
  22. #include <stdarg.h>
  23. #include <unistd.h>
  24. #include <errno.h>
  25. #include <sys/ucontext.h>
  26. #ifdef __ia64__
  27. #undef uc_mcontext
  28. #undef uc_sigmask
  29. #undef uc_stack
  30. #undef uc_link
  31. #endif
  32. #include "qemu.h"
  33. #include "qemu-common.h"
  34. #define DEBUG_SIGNAL
  35. #define MAX_SIGQUEUE_SIZE 1024
  36. struct sigqueue {
  37. struct sigqueue *next;
  38. target_siginfo_t info;
  39. };
  40. struct emulated_sigaction {
  41. struct target_sigaction sa;
  42. int pending; /* true if signal is pending */
  43. struct sigqueue *first;
  44. struct sigqueue info; /* in order to always have memory for the
  45. first signal, we put it here */
  46. };
  47. static struct sigaltstack target_sigaltstack_used = {
  48. 0, 0, SA_DISABLE
  49. };
  50. static struct emulated_sigaction sigact_table[NSIG];
  51. static struct sigqueue sigqueue_table[MAX_SIGQUEUE_SIZE]; /* siginfo queue */
  52. static struct sigqueue *first_free; /* first free siginfo queue entry */
  53. static int signal_pending; /* non zero if a signal may be pending */
  54. static void host_signal_handler(int host_signum, siginfo_t *info,
  55. void *puc);
  56. static inline int host_to_target_signal(int sig)
  57. {
  58. return sig;
  59. }
  60. static inline int target_to_host_signal(int sig)
  61. {
  62. return sig;
  63. }
  64. /* siginfo conversion */
  65. void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info)
  66. {
  67. }
  68. void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo)
  69. {
  70. }
  71. void signal_init(void)
  72. {
  73. struct sigaction act;
  74. int i;
  75. /* set all host signal handlers. ALL signals are blocked during
  76. the handlers to serialize them. */
  77. sigfillset(&act.sa_mask);
  78. act.sa_flags = SA_SIGINFO;
  79. act.sa_sigaction = host_signal_handler;
  80. for(i = 1; i < NSIG; i++) {
  81. sigaction(i, &act, NULL);
  82. }
  83. memset(sigact_table, 0, sizeof(sigact_table));
  84. first_free = &sigqueue_table[0];
  85. for(i = 0; i < MAX_SIGQUEUE_SIZE - 1; i++)
  86. sigqueue_table[i].next = &sigqueue_table[i + 1];
  87. sigqueue_table[MAX_SIGQUEUE_SIZE - 1].next = NULL;
  88. }
  89. /* signal queue handling */
  90. static inline struct sigqueue *alloc_sigqueue(void)
  91. {
  92. struct sigqueue *q = first_free;
  93. if (!q)
  94. return NULL;
  95. first_free = q->next;
  96. return q;
  97. }
  98. static inline void free_sigqueue(struct sigqueue *q)
  99. {
  100. q->next = first_free;
  101. first_free = q;
  102. }
  103. /* abort execution with signal */
  104. void QEMU_NORETURN force_sig(int sig)
  105. {
  106. int host_sig;
  107. host_sig = target_to_host_signal(sig);
  108. fprintf(stderr, "qemu: uncaught target signal %d (%s) - exiting\n",
  109. sig, strsignal(host_sig));
  110. _exit(-host_sig);
  111. }
  112. /* queue a signal so that it will be send to the virtual CPU as soon
  113. as possible */
  114. int queue_signal(int sig, target_siginfo_t *info)
  115. {
  116. struct emulated_sigaction *k;
  117. struct sigqueue *q, **pq;
  118. target_ulong handler;
  119. #if defined(DEBUG_SIGNAL)
  120. fprintf(stderr, "queue_signal: sig=%d\n",
  121. sig);
  122. #endif
  123. k = &sigact_table[sig - 1];
  124. handler = (target_ulong)k->sa.sa_handler;
  125. if (handler == SIG_DFL) {
  126. /* default handler : ignore some signal. The other are fatal */
  127. if (sig != SIGCHLD &&
  128. sig != SIGURG &&
  129. sig != SIGWINCH) {
  130. force_sig(sig);
  131. } else {
  132. return 0; /* indicate ignored */
  133. }
  134. } else if (handler == host_to_target_signal(SIG_IGN)) {
  135. /* ignore signal */
  136. return 0;
  137. } else if (handler == host_to_target_signal(SIG_ERR)) {
  138. force_sig(sig);
  139. } else {
  140. pq = &k->first;
  141. if (!k->pending) {
  142. /* first signal */
  143. q = &k->info;
  144. } else {
  145. q = alloc_sigqueue();
  146. if (!q)
  147. return -EAGAIN;
  148. while (*pq != NULL)
  149. pq = &(*pq)->next;
  150. }
  151. *pq = q;
  152. q->info = *info;
  153. q->next = NULL;
  154. k->pending = 1;
  155. /* signal that a new signal is pending */
  156. signal_pending = 1;
  157. return 1; /* indicates that the signal was queued */
  158. }
  159. }
  160. static void host_signal_handler(int host_signum, siginfo_t *info,
  161. void *puc)
  162. {
  163. int sig;
  164. target_siginfo_t tinfo;
  165. /* the CPU emulator uses some host signals to detect exceptions,
  166. we we forward to it some signals */
  167. if (host_signum == SIGSEGV || host_signum == SIGBUS) {
  168. if (cpu_signal_handler(host_signum, (void*)info, puc))
  169. return;
  170. }
  171. /* get target signal number */
  172. sig = host_to_target_signal(host_signum);
  173. if (sig < 1 || sig > NSIG)
  174. return;
  175. #if defined(DEBUG_SIGNAL)
  176. fprintf(stderr, "qemu: got signal %d\n", sig);
  177. #endif
  178. if (queue_signal(sig, &tinfo) == 1) {
  179. /* interrupt the virtual CPU as soon as possible */
  180. cpu_exit(global_env);
  181. }
  182. }
  183. int do_sigaltstack(const struct sigaltstack *ss, struct sigaltstack *oss)
  184. {
  185. /* XXX: test errors */
  186. if(oss)
  187. {
  188. oss->ss_sp = tswap32(target_sigaltstack_used.ss_sp);
  189. oss->ss_size = tswap32(target_sigaltstack_used.ss_size);
  190. oss->ss_flags = tswap32(target_sigaltstack_used.ss_flags);
  191. }
  192. if(ss)
  193. {
  194. target_sigaltstack_used.ss_sp = tswap32(ss->ss_sp);
  195. target_sigaltstack_used.ss_size = tswap32(ss->ss_size);
  196. target_sigaltstack_used.ss_flags = tswap32(ss->ss_flags);
  197. }
  198. return 0;
  199. }
  200. int do_sigaction(int sig, const struct sigaction *act,
  201. struct sigaction *oact)
  202. {
  203. struct emulated_sigaction *k;
  204. struct sigaction act1;
  205. int host_sig;
  206. if (sig < 1 || sig > NSIG)
  207. return -EINVAL;
  208. k = &sigact_table[sig - 1];
  209. #if defined(DEBUG_SIGNAL)
  210. fprintf(stderr, "sigaction 1 sig=%d act=0x%08x, oact=0x%08x\n",
  211. sig, (int)act, (int)oact);
  212. #endif
  213. if (oact) {
  214. #if defined(DEBUG_SIGNAL)
  215. fprintf(stderr, "sigaction 1 sig=%d act=0x%08x, oact=0x%08x\n",
  216. sig, (int)act, (int)oact);
  217. #endif
  218. oact->sa_handler = tswapl(k->sa.sa_handler);
  219. oact->sa_flags = tswapl(k->sa.sa_flags);
  220. oact->sa_mask = tswapl(k->sa.sa_mask);
  221. }
  222. if (act) {
  223. #if defined(DEBUG_SIGNAL)
  224. fprintf(stderr, "sigaction handler 0x%x flag 0x%x mask 0x%x\n",
  225. act->sa_handler, act->sa_flags, act->sa_mask);
  226. #endif
  227. k->sa.sa_handler = tswapl(act->sa_handler);
  228. k->sa.sa_flags = tswapl(act->sa_flags);
  229. k->sa.sa_mask = tswapl(act->sa_mask);
  230. /* we update the host signal state */
  231. host_sig = target_to_host_signal(sig);
  232. if (host_sig != SIGSEGV && host_sig != SIGBUS) {
  233. #if defined(DEBUG_SIGNAL)
  234. fprintf(stderr, "sigaction handler going to call sigaction\n",
  235. act->sa_handler, act->sa_flags, act->sa_mask);
  236. #endif
  237. sigfillset(&act1.sa_mask);
  238. act1.sa_flags = SA_SIGINFO;
  239. if (k->sa.sa_flags & SA_RESTART)
  240. act1.sa_flags |= SA_RESTART;
  241. /* NOTE: it is important to update the host kernel signal
  242. ignore state to avoid getting unexpected interrupted
  243. syscalls */
  244. if (k->sa.sa_handler == SIG_IGN) {
  245. act1.sa_sigaction = (void *)SIG_IGN;
  246. } else if (k->sa.sa_handler == SIG_DFL) {
  247. act1.sa_sigaction = (void *)SIG_DFL;
  248. } else {
  249. act1.sa_sigaction = host_signal_handler;
  250. }
  251. sigaction(host_sig, &act1, NULL);
  252. }
  253. }
  254. return 0;
  255. }
  256. #ifdef TARGET_I386
  257. static inline void *
  258. get_sigframe(struct emulated_sigaction *ka, CPUX86State *env, size_t frame_size)
  259. {
  260. /* XXX Fix that */
  261. if(target_sigaltstack_used.ss_flags & SA_DISABLE)
  262. {
  263. int esp;
  264. /* Default to using normal stack */
  265. esp = env->regs[R_ESP];
  266. return (void *)((esp - frame_size) & -8ul);
  267. }
  268. else
  269. {
  270. return target_sigaltstack_used.ss_sp;
  271. }
  272. }
  273. static void setup_frame(int sig, struct emulated_sigaction *ka,
  274. void *set, CPUState *env)
  275. {
  276. void *frame;
  277. fprintf(stderr, "setup_frame %d\n", sig);
  278. frame = get_sigframe(ka, env, sizeof(*frame));
  279. /* Set up registers for signal handler */
  280. env->regs[R_ESP] = (unsigned long) frame;
  281. env->eip = (unsigned long) ka->sa.sa_handler;
  282. env->eflags &= ~TF_MASK;
  283. return;
  284. give_sigsegv:
  285. if (sig == SIGSEGV)
  286. ka->sa.sa_handler = SIG_DFL;
  287. force_sig(SIGSEGV /* , current */);
  288. }
  289. long do_sigreturn(CPUState *env, int num)
  290. {
  291. int i = 0;
  292. struct target_sigcontext *scp = get_int_arg(&i, env);
  293. /* XXX Get current signal number */
  294. /* XXX Adjust accordin to sc_onstack, sc_mask */
  295. if(tswapl(scp->sc_onstack) & 0x1)
  296. target_sigaltstack_used.ss_flags |= ~SA_DISABLE;
  297. else
  298. target_sigaltstack_used.ss_flags &= SA_DISABLE;
  299. int set = tswapl(scp->sc_eax);
  300. sigprocmask(SIG_SETMASK, &set, NULL);
  301. fprintf(stderr, "do_sigreturn: partially implemented %x EAX:%x EBX:%x\n", scp->sc_mask, tswapl(scp->sc_eax), tswapl(scp->sc_ebx));
  302. fprintf(stderr, "ECX:%x EDX:%x EDI:%x\n", scp->sc_ecx, tswapl(scp->sc_edx), tswapl(scp->sc_edi));
  303. fprintf(stderr, "EIP:%x\n", tswapl(scp->sc_eip));
  304. env->regs[R_EAX] = tswapl(scp->sc_eax);
  305. env->regs[R_EBX] = tswapl(scp->sc_ebx);
  306. env->regs[R_ECX] = tswapl(scp->sc_ecx);
  307. env->regs[R_EDX] = tswapl(scp->sc_edx);
  308. env->regs[R_EDI] = tswapl(scp->sc_edi);
  309. env->regs[R_ESI] = tswapl(scp->sc_esi);
  310. env->regs[R_EBP] = tswapl(scp->sc_ebp);
  311. env->regs[R_ESP] = tswapl(scp->sc_esp);
  312. env->segs[R_SS].selector = (void*)tswapl(scp->sc_ss);
  313. env->eflags = tswapl(scp->sc_eflags);
  314. env->eip = tswapl(scp->sc_eip);
  315. env->segs[R_CS].selector = (void*)tswapl(scp->sc_cs);
  316. env->segs[R_DS].selector = (void*)tswapl(scp->sc_ds);
  317. env->segs[R_ES].selector = (void*)tswapl(scp->sc_es);
  318. env->segs[R_FS].selector = (void*)tswapl(scp->sc_fs);
  319. env->segs[R_GS].selector = (void*)tswapl(scp->sc_gs);
  320. /* Again, because our caller's caller will reset EAX */
  321. return env->regs[R_EAX];
  322. }
  323. #else
  324. static void setup_frame(int sig, struct emulated_sigaction *ka,
  325. void *set, CPUState *env)
  326. {
  327. fprintf(stderr, "setup_frame: not implemented\n");
  328. }
  329. long do_sigreturn(CPUState *env, int num)
  330. {
  331. int i = 0;
  332. struct target_sigcontext *scp = get_int_arg(&i, env);
  333. fprintf(stderr, "do_sigreturn: not implemented\n");
  334. return -ENOSYS;
  335. }
  336. #endif
  337. void process_pending_signals(void *cpu_env)
  338. {
  339. struct emulated_sigaction *k;
  340. struct sigqueue *q;
  341. target_ulong handler;
  342. int sig;
  343. if (!signal_pending)
  344. return;
  345. k = sigact_table;
  346. for(sig = 1; sig <= NSIG; sig++) {
  347. if (k->pending)
  348. goto handle_signal;
  349. k++;
  350. }
  351. /* if no signal is pending, just return */
  352. signal_pending = 0;
  353. return;
  354. handle_signal:
  355. #ifdef DEBUG_SIGNAL
  356. fprintf(stderr, "qemu: process signal %d\n", sig);
  357. #endif
  358. /* dequeue signal */
  359. q = k->first;
  360. k->first = q->next;
  361. if (!k->first)
  362. k->pending = 0;
  363. sig = gdb_handlesig (cpu_env, sig);
  364. if (!sig) {
  365. fprintf (stderr, "Lost signal\n");
  366. abort();
  367. }
  368. handler = k->sa.sa_handler;
  369. if (handler == SIG_DFL) {
  370. /* default handler : ignore some signal. The other are fatal */
  371. if (sig != SIGCHLD &&
  372. sig != SIGURG &&
  373. sig != SIGWINCH) {
  374. force_sig(sig);
  375. }
  376. } else if (handler == SIG_IGN) {
  377. /* ignore sig */
  378. } else if (handler == SIG_ERR) {
  379. force_sig(sig);
  380. } else {
  381. setup_frame(sig, k, 0, cpu_env);
  382. if (k->sa.sa_flags & SA_RESETHAND)
  383. k->sa.sa_handler = SIG_DFL;
  384. }
  385. if (q != &k->info)
  386. free_sigqueue(q);
  387. }