| OLD | NEW |
| (Empty) |
| 1 //===- subzero/crosstest/stack_hack.x8664.c - X8664 stack hack ------------===// | |
| 2 // | |
| 3 // The Subzero Code Generator | |
| 4 // | |
| 5 // This file is distributed under the University of Illinois Open Source | |
| 6 // License. See LICENSE.TXT for details. | |
| 7 // | |
| 8 //===----------------------------------------------------------------------===// | |
| 9 // | |
| 10 // Implements main() for crosstests in x86-64. | |
| 11 // | |
| 12 //===----------------------------------------------------------------------===// | |
| 13 #include <assert.h> | |
| 14 #include <stdint.h> | |
| 15 | |
| 16 #include <sys/mman.h> | |
| 17 | |
| 18 // X8664_STACK_HACK needs to be defined before xdefs.h is included. | |
| 19 #define X8664_STACK_HACK | |
| 20 #include "xdefs.h" | |
| 21 | |
| 22 /// xSetStack is used to set %rsp to NewRsp. OldRsp is a pointer that will be | |
| 23 /// used to save the old %rsp value. | |
| 24 #define xSetStack(NewRsp, OldRsp) \ | |
| 25 do { \ | |
| 26 __asm__ volatile("xchgq %1, %%rsp\n\t" \ | |
| 27 "xchgq %1, %0" \ | |
| 28 : "=r"(*(OldRsp)) \ | |
| 29 : "r"(NewRsp)); \ | |
| 30 } while (0) | |
| 31 | |
| 32 extern int wrapped_main(int argc, char *argv[]); | |
| 33 | |
| 34 unsigned char *xStackStart(uint32 StackEnd, uint32 Size) { | |
| 35 const uint32 PageBoundary = 4 << 20; // 4 MB. | |
| 36 const uint64 StackStart = StackEnd - Size; | |
| 37 assert(StackStart + (PageBoundary - 1) & ~(PageBoundary - 1) && | |
| 38 "StackStart not aligned to page boundary."); | |
| 39 (void)PageBoundary; | |
| 40 assert((StackStart & 0xFFFFFFFF00000000ull) == 0 && "StackStart wraps."); | |
| 41 return (unsigned char *)StackStart; | |
| 42 } | |
| 43 | |
| 44 unsigned char *xAllocStack(uint64 StackEnd, uint32 Size) { | |
| 45 assert((StackEnd & 0xFFFFFFFF00000000ull) == 0 && "Invalid StackEnd."); | |
| 46 void *Stack = | |
| 47 mmap(xStackStart(StackEnd, Size), Size, PROT_READ | PROT_WRITE, | |
| 48 MAP_FIXED | MAP_PRIVATE | MAP_GROWSDOWN | MAP_ANONYMOUS, -1, 0); | |
| 49 assert(Stack != MAP_FAILED && "mmap failed. no stack."); | |
| 50 return Stack; | |
| 51 } | |
| 52 | |
| 53 void xDeallocStack(uint64 StackEnd, uint32 Size) { | |
| 54 assert((StackEnd & 0xFFFFFFFF00000000ull) == 0 && "Invalid StackEnd."); | |
| 55 munmap(xStackStart(StackEnd, Size), Size); | |
| 56 } | |
| 57 | |
| 58 int main(int argc, char *argv[]) { | |
| 59 // These "locals" need to live **NOT** in the stack. | |
| 60 static int Argc; | |
| 61 static char **Argv; | |
| 62 static const uint32_t StackEnd = 0x80000000; | |
| 63 static const uint32_t StackSize = 40 * 1024 * 1024; | |
| 64 static unsigned char *new_rsp; | |
| 65 static unsigned char *old_rsp; | |
| 66 static unsigned char *dummy_rsp; | |
| 67 static int Failures; | |
| 68 Argc = argc; | |
| 69 Argv = argv; | |
| 70 new_rsp = xAllocStack(StackEnd, StackSize) + StackSize; | |
| 71 xSetStack(new_rsp, &old_rsp); | |
| 72 Failures = wrapped_main(Argc, Argv); | |
| 73 xSetStack(old_rsp, &new_rsp); | |
| 74 xDeallocStack(StackEnd, StackSize); | |
| 75 return Failures; | |
| 76 } | |
| OLD | NEW |