| 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 |