-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathstack.cc
73 lines (56 loc) · 1.5 KB
/
stack.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include "stack.h"
#include "resource_limit.h"
#include <cassert>
#include <cstring>
#include <cstddef>
#include <stdint.h>
#include <unistd.h>
#include <sys/mman.h>
namespace {
static std::size_t stack_size = resource_limit::cur<RLIMIT_STACK>();
static int stack_prot = 0
| PROT_READ
| PROT_WRITE
;
static int stack_flags = 0
| MAP_PRIVATE
| MAP_ANONYMOUS
| MAP_STACK
#ifdef MAP_UNINITIALIZED
| MAP_UNINITIALIZED
#endif
#ifdef MAP_NORESERVE
| MAP_NORESERVE
#endif
;
static long page_size = sysconf(_SC_PAGE_SIZE);
static long page_mask = page_size - 1;
void* adjust(void* p, ptrdiff_t d) {
return reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(p) + d);
}
};
stack::stack()
{
ss_flags = 0;
ss_size = stack_size;
assert(MINSIGSTKSZ <= ss_size);
assert(0 == (page_size & (page_size-1)));
ss_size += 2 * page_size;
const long page_mask = page_size - 1;
ss_size += page_mask;
ss_size &= ~page_mask;
ss_sp = mmap(NULL, ss_size, stack_prot, stack_flags, -1, 0);
if (MAP_FAILED == ss_sp)
throw std::bad_alloc();
ss_sp = adjust(ss_sp, page_size);
ss_size -= 2 * page_size;
TRY(mprotect, adjust(ss_sp, -page_size), page_size, PROT_NONE);
TRY(mprotect, adjust(ss_sp, ss_size), page_size, PROT_NONE);
}
stack::~stack() {
TRY_ABORT(munmap, adjust(ss_sp, -page_size), ss_size + 2 * page_size);
memset(this, 0, sizeof *this);
}
void * stack::base() const { return ss_sp; }
std::size_t stack::size() const { return ss_size; }
//