stub_segv.c 1.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. /*
  2. * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com)
  3. * Licensed under the GPL
  4. */
  5. #include <stddef.h>
  6. #include <signal.h>
  7. #include <linux/compiler.h>
  8. #include <asm/unistd.h>
  9. #include "uml-config.h"
  10. #include "sysdep/sigcontext.h"
  11. #include "sysdep/faultinfo.h"
  12. #include "sysdep/stub.h"
  13. /* Copied from sys-x86_64/signal.c - Can't find an equivalent definition
  14. * in the libc headers anywhere.
  15. */
  16. struct rt_sigframe
  17. {
  18. char *pretcode;
  19. struct ucontext uc;
  20. struct siginfo info;
  21. };
  22. /* Copied here from <linux/kernel.h> - we're userspace. */
  23. #define container_of(ptr, type, member) ({ \
  24. const typeof( ((type *)0)->member ) *__mptr = (ptr); \
  25. (type *)( (char *)__mptr - offsetof(type,member) );})
  26. void __attribute__ ((__section__ (".__syscall_stub")))
  27. stub_segv_handler(int sig)
  28. {
  29. struct ucontext *uc;
  30. int pid;
  31. __asm__ __volatile__("movq %%rdx, %0" : "=g" (uc) :);
  32. GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA),
  33. &uc->uc_mcontext);
  34. pid = stub_syscall0(__NR_getpid);
  35. stub_syscall2(__NR_kill, pid, SIGUSR1);
  36. /* sys_sigreturn expects that the stack pointer will be 8 bytes into
  37. * the signal frame. So, we use the ucontext pointer, which we know
  38. * already, to get the signal frame pointer, and add 8 to that.
  39. */
  40. __asm__ __volatile__("movq %0, %%rsp; movq %1, %%rax ; syscall": :
  41. "g" ((unsigned long)
  42. container_of(uc, struct rt_sigframe, uc) + 8),
  43. "g" (__NR_rt_sigreturn));
  44. }