nx.c 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. #include <u.h>
  2. #include <libc.h>
  3. #define RET 0xc3
  4. int success;
  5. int cases;
  6. void
  7. handler(void *v, char *s)
  8. {
  9. success++;
  10. exits(nil);
  11. }
  12. void
  13. callinsn(char *name, char *buf)
  14. {
  15. void (*f)(void);
  16. if (notify(handler)){
  17. fprint(2, "%r\n");
  18. exits("notify fails");
  19. }
  20. f = (void *)buf;
  21. f();
  22. print("FAIL %s\n", name);
  23. exits("FAIL");
  24. }
  25. void
  26. writeptr(char *name, void *ptr)
  27. {
  28. if (notify(handler)){
  29. fprint(2, "%r\n");
  30. exits("notify fails");
  31. }
  32. *(uintptr_t*)ptr = 0xdeadbeef;
  33. print("FAIL %s\n", name);
  34. exits("FAIL");
  35. }
  36. void
  37. main(void)
  38. {
  39. char *str = "hello world";
  40. char stk[128];
  41. char *mem;
  42. switch(rfork(RFMEM|RFPROC)){
  43. case -1:
  44. sysfatal("rfork");
  45. case 0:
  46. stk[0] = RET;
  47. callinsn("exec stack", stk);
  48. default:
  49. cases++;
  50. waitpid();
  51. }
  52. switch(rfork(RFMEM|RFPROC)){
  53. case -1:
  54. sysfatal("rfork");
  55. case 0:
  56. mem = malloc(128);
  57. mem[0] = RET;
  58. callinsn("exec heap", mem);
  59. default:
  60. cases++;
  61. waitpid();
  62. }
  63. switch(rfork(RFMEM|RFPROC)){
  64. case -1:
  65. sysfatal("rfork");
  66. case 0:
  67. writeptr("write code", (void*)&main);
  68. default:
  69. cases++;
  70. waitpid();
  71. }
  72. switch(rfork(RFMEM|RFPROC)){
  73. case -1:
  74. sysfatal("rfork");
  75. case 0:
  76. writeptr("write rodata", (void*)str);
  77. default:
  78. cases++;
  79. waitpid();
  80. }
  81. if(success == cases){
  82. print("PASS\n");
  83. exits("PASS");
  84. }
  85. print("FAIL\n");
  86. exits("FAIL");
  87. }