signal.c (ef6a778ea2af4ebcf08a84cc9314cfe7cf2a2299) signal.c (a70dadc7f1a3e96a7179c6c3a6ccd1a0ea65760a)
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 "qemu/osdep.h"
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 "qemu/osdep.h"
20#include "qemu/bitops.h"
20#include <sys/ucontext.h>
21#include <sys/resource.h>
22
23#include "qemu.h"
24#include "qemu-common.h"
25#include "target_signal.h"
26#include "trace.h"
27

--- 241 unchanged lines hidden (view full) ---

269#endif
270
271/* siginfo conversion */
272
273static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
274 const siginfo_t *info)
275{
276 int sig = host_to_target_signal(info->si_signo);
21#include <sys/ucontext.h>
22#include <sys/resource.h>
23
24#include "qemu.h"
25#include "qemu-common.h"
26#include "target_signal.h"
27#include "trace.h"
28

--- 241 unchanged lines hidden (view full) ---

270#endif
271
272/* siginfo conversion */
273
274static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
275 const siginfo_t *info)
276{
277 int sig = host_to_target_signal(info->si_signo);
278 int si_code = info->si_code;
279 int si_type;
277 tinfo->si_signo = sig;
278 tinfo->si_errno = 0;
279 tinfo->si_code = info->si_code;
280
280 tinfo->si_signo = sig;
281 tinfo->si_errno = 0;
282 tinfo->si_code = info->si_code;
283
281 if (sig == TARGET_SIGILL || sig == TARGET_SIGFPE || sig == TARGET_SIGSEGV
282 || sig == TARGET_SIGBUS || sig == TARGET_SIGTRAP) {
283 /* Should never come here, but who knows. The information for
284 the target is irrelevant. */
285 tinfo->_sifields._sigfault._addr = 0;
286 } else if (sig == TARGET_SIGIO) {
287 tinfo->_sifields._sigpoll._band = info->si_band;
288 tinfo->_sifields._sigpoll._fd = info->si_fd;
289 } else if (sig == TARGET_SIGCHLD) {
290 tinfo->_sifields._sigchld._pid = info->si_pid;
291 tinfo->_sifields._sigchld._uid = info->si_uid;
292 tinfo->_sifields._sigchld._status
284 /* This is awkward, because we have to use a combination of
285 * the si_code and si_signo to figure out which of the union's
286 * members are valid. (Within the host kernel it is always possible
287 * to tell, but the kernel carefully avoids giving userspace the
288 * high 16 bits of si_code, so we don't have the information to
289 * do this the easy way...) We therefore make our best guess,
290 * bearing in mind that a guest can spoof most of the si_codes
291 * via rt_sigqueueinfo() if it likes.
292 *
293 * Once we have made our guess, we record it in the top 16 bits of
294 * the si_code, so that tswap_siginfo() later can use it.
295 * tswap_siginfo() will strip these top bits out before writing
296 * si_code to the guest (sign-extending the lower bits).
297 */
298
299 switch (si_code) {
300 case SI_USER:
301 case SI_TKILL:
302 case SI_KERNEL:
303 /* Sent via kill(), tkill() or tgkill(), or direct from the kernel.
304 * These are the only unspoofable si_code values.
305 */
306 tinfo->_sifields._kill._pid = info->si_pid;
307 tinfo->_sifields._kill._uid = info->si_uid;
308 si_type = QEMU_SI_KILL;
309 break;
310 default:
311 /* Everything else is spoofable. Make best guess based on signal */
312 switch (sig) {
313 case TARGET_SIGCHLD:
314 tinfo->_sifields._sigchld._pid = info->si_pid;
315 tinfo->_sifields._sigchld._uid = info->si_uid;
316 tinfo->_sifields._sigchld._status
293 = host_to_target_waitstatus(info->si_status);
317 = host_to_target_waitstatus(info->si_status);
294 tinfo->_sifields._sigchld._utime = info->si_utime;
295 tinfo->_sifields._sigchld._stime = info->si_stime;
296 } else if (sig >= TARGET_SIGRTMIN) {
297 tinfo->_sifields._rt._pid = info->si_pid;
298 tinfo->_sifields._rt._uid = info->si_uid;
299 /* XXX: potential problem if 64 bit */
300 tinfo->_sifields._rt._sigval.sival_ptr
318 tinfo->_sifields._sigchld._utime = info->si_utime;
319 tinfo->_sifields._sigchld._stime = info->si_stime;
320 si_type = QEMU_SI_CHLD;
321 break;
322 case TARGET_SIGIO:
323 tinfo->_sifields._sigpoll._band = info->si_band;
324 tinfo->_sifields._sigpoll._fd = info->si_fd;
325 si_type = QEMU_SI_POLL;
326 break;
327 default:
328 /* Assume a sigqueue()/mq_notify()/rt_sigqueueinfo() source. */
329 tinfo->_sifields._rt._pid = info->si_pid;
330 tinfo->_sifields._rt._uid = info->si_uid;
331 /* XXX: potential problem if 64 bit */
332 tinfo->_sifields._rt._sigval.sival_ptr
301 = (abi_ulong)(unsigned long)info->si_value.sival_ptr;
333 = (abi_ulong)(unsigned long)info->si_value.sival_ptr;
334 si_type = QEMU_SI_RT;
335 break;
336 }
337 break;
302 }
338 }
339
340 tinfo->si_code = deposit32(si_code, 16, 16, si_type);
303}
304
305static void tswap_siginfo(target_siginfo_t *tinfo,
306 const target_siginfo_t *info)
307{
341}
342
343static void tswap_siginfo(target_siginfo_t *tinfo,
344 const target_siginfo_t *info)
345{
308 int sig = info->si_signo;
309 tinfo->si_signo = tswap32(sig);
310 tinfo->si_errno = tswap32(info->si_errno);
311 tinfo->si_code = tswap32(info->si_code);
346 int si_type = extract32(info->si_code, 16, 16);
347 int si_code = sextract32(info->si_code, 0, 16);
312
348
313 if (sig == TARGET_SIGILL || sig == TARGET_SIGFPE || sig == TARGET_SIGSEGV
314 || sig == TARGET_SIGBUS || sig == TARGET_SIGTRAP) {
315 tinfo->_sifields._sigfault._addr
316 = tswapal(info->_sifields._sigfault._addr);
317 } else if (sig == TARGET_SIGIO) {
318 tinfo->_sifields._sigpoll._band
319 = tswap32(info->_sifields._sigpoll._band);
320 tinfo->_sifields._sigpoll._fd = tswap32(info->_sifields._sigpoll._fd);
321 } else if (sig == TARGET_SIGCHLD) {
322 tinfo->_sifields._sigchld._pid
323 = tswap32(info->_sifields._sigchld._pid);
324 tinfo->_sifields._sigchld._uid
325 = tswap32(info->_sifields._sigchld._uid);
326 tinfo->_sifields._sigchld._status
327 = tswap32(info->_sifields._sigchld._status);
328 tinfo->_sifields._sigchld._utime
329 = tswapal(info->_sifields._sigchld._utime);
330 tinfo->_sifields._sigchld._stime
331 = tswapal(info->_sifields._sigchld._stime);
332 } else if (sig >= TARGET_SIGRTMIN) {
333 tinfo->_sifields._rt._pid = tswap32(info->_sifields._rt._pid);
334 tinfo->_sifields._rt._uid = tswap32(info->_sifields._rt._uid);
335 tinfo->_sifields._rt._sigval.sival_ptr
336 = tswapal(info->_sifields._rt._sigval.sival_ptr);
349 __put_user(info->si_signo, &tinfo->si_signo);
350 __put_user(info->si_errno, &tinfo->si_errno);
351 __put_user(si_code, &tinfo->si_code);
352
353 /* We can use our internal marker of which fields in the structure
354 * are valid, rather than duplicating the guesswork of
355 * host_to_target_siginfo_noswap() here.
356 */
357 switch (si_type) {
358 case QEMU_SI_KILL:
359 __put_user(info->_sifields._kill._pid, &tinfo->_sifields._kill._pid);
360 __put_user(info->_sifields._kill._uid, &tinfo->_sifields._kill._uid);
361 break;
362 case QEMU_SI_TIMER:
363 __put_user(info->_sifields._timer._timer1,
364 &tinfo->_sifields._timer._timer1);
365 __put_user(info->_sifields._timer._timer2,
366 &tinfo->_sifields._timer._timer2);
367 break;
368 case QEMU_SI_POLL:
369 __put_user(info->_sifields._sigpoll._band,
370 &tinfo->_sifields._sigpoll._band);
371 __put_user(info->_sifields._sigpoll._fd,
372 &tinfo->_sifields._sigpoll._fd);
373 break;
374 case QEMU_SI_FAULT:
375 __put_user(info->_sifields._sigfault._addr,
376 &tinfo->_sifields._sigfault._addr);
377 break;
378 case QEMU_SI_CHLD:
379 __put_user(info->_sifields._sigchld._pid,
380 &tinfo->_sifields._sigchld._pid);
381 __put_user(info->_sifields._sigchld._uid,
382 &tinfo->_sifields._sigchld._uid);
383 __put_user(info->_sifields._sigchld._status,
384 &tinfo->_sifields._sigchld._status);
385 __put_user(info->_sifields._sigchld._utime,
386 &tinfo->_sifields._sigchld._utime);
387 __put_user(info->_sifields._sigchld._stime,
388 &tinfo->_sifields._sigchld._stime);
389 break;
390 case QEMU_SI_RT:
391 __put_user(info->_sifields._rt._pid, &tinfo->_sifields._rt._pid);
392 __put_user(info->_sifields._rt._uid, &tinfo->_sifields._rt._uid);
393 __put_user(info->_sifields._rt._sigval.sival_ptr,
394 &tinfo->_sifields._rt._sigval.sival_ptr);
395 break;
396 default:
397 g_assert_not_reached();
337 }
338}
339
398 }
399}
400
340
341void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info)
342{
343 host_to_target_siginfo_noswap(tinfo, info);
344 tswap_siginfo(tinfo, tinfo);
345}
346
347/* XXX: we support only POSIX RT signals are used. */
348/* XXX: find a solution for 64 bit (additional malloced data is needed) */

--- 151 unchanged lines hidden (view full) ---

500 as possible */
501int queue_signal(CPUArchState *env, int sig, target_siginfo_t *info)
502{
503 CPUState *cpu = ENV_GET_CPU(env);
504 TaskState *ts = cpu->opaque;
505
506 trace_user_queue_signal(env, sig);
507
401void host_to_target_siginfo(target_siginfo_t *tinfo, const siginfo_t *info)
402{
403 host_to_target_siginfo_noswap(tinfo, info);
404 tswap_siginfo(tinfo, tinfo);
405}
406
407/* XXX: we support only POSIX RT signals are used. */
408/* XXX: find a solution for 64 bit (additional malloced data is needed) */

--- 151 unchanged lines hidden (view full) ---

560 as possible */
561int queue_signal(CPUArchState *env, int sig, target_siginfo_t *info)
562{
563 CPUState *cpu = ENV_GET_CPU(env);
564 TaskState *ts = cpu->opaque;
565
566 trace_user_queue_signal(env, sig);
567
568 /* Currently all callers define siginfo structures which
569 * use the _sifields._sigfault union member, so we can
570 * set the type here. If that changes we should push this
571 * out so the si_type is passed in by callers.
572 */
573 info->si_code = deposit32(info->si_code, 16, 16, QEMU_SI_FAULT);
574
508 ts->sync_signal.info = *info;
509 ts->sync_signal.pending = sig;
510 /* signal that a new signal is pending */
511 atomic_set(&ts->signal_pending, 1);
512 return 1; /* indicates that the signal was queued */
513}
514
515#ifndef HAVE_SAFE_SYSCALL

--- 5371 unchanged lines hidden ---
575 ts->sync_signal.info = *info;
576 ts->sync_signal.pending = sig;
577 /* signal that a new signal is pending */
578 atomic_set(&ts->signal_pending, 1);
579 return 1; /* indicates that the signal was queued */
580}
581
582#ifndef HAVE_SAFE_SYSCALL

--- 5371 unchanged lines hidden ---