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 <asm/signal.h>
  6. #include <linux/compiler.h>
  7. #include <asm/unistd.h>
  8. #include <asm/ucontext.h>
  9. #include "uml-config.h"
  10. #include "sysdep/sigcontext.h"
  11. #include "sysdep/faultinfo.h"
  12. #include <stddef.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. __asm__("movq %%rdx, %0" : "=g" (uc) :);
  31. GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA),
  32. &uc->uc_mcontext);
  33. __asm__("movq %0, %%rax ; syscall": : "g" (__NR_getpid));
  34. __asm__("movq %%rax, %%rdi ; movq %0, %%rax ; movq %1, %%rsi ;"
  35. "syscall": : "g" (__NR_kill), "g" (SIGUSR1) :
  36. "%rdi", "%rax", "%rsi");
  37. /* sys_sigreturn expects that the stack pointer will be 8 bytes into
  38. * the signal frame. So, we use the ucontext pointer, which we know
  39. * already, to get the signal frame pointer, and add 8 to that.
  40. */
  41. __asm__("movq %0, %%rsp": :
  42. "g" ((unsigned long) container_of(uc, struct rt_sigframe,
  43. uc) + 8));
  44. __asm__("movq %0, %%rax ; syscall" : : "g" (__NR_rt_sigreturn));
  45. }