stub_segv.c 1.5 KB

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