1*7c3d14c8STreehugger Robot //===-- esan.cpp ----------------------------------------------------------===//
2*7c3d14c8STreehugger Robot //
3*7c3d14c8STreehugger Robot // The LLVM Compiler Infrastructure
4*7c3d14c8STreehugger Robot //
5*7c3d14c8STreehugger Robot // This file is distributed under the University of Illinois Open Source
6*7c3d14c8STreehugger Robot // License. See LICENSE.TXT for details.
7*7c3d14c8STreehugger Robot //
8*7c3d14c8STreehugger Robot //===----------------------------------------------------------------------===//
9*7c3d14c8STreehugger Robot //
10*7c3d14c8STreehugger Robot // This file is a part of EfficiencySanitizer, a family of performance tuners.
11*7c3d14c8STreehugger Robot //
12*7c3d14c8STreehugger Robot // Linux-specific code for the Esan run-time.
13*7c3d14c8STreehugger Robot //===----------------------------------------------------------------------===//
14*7c3d14c8STreehugger Robot
15*7c3d14c8STreehugger Robot #include "sanitizer_common/sanitizer_platform.h"
16*7c3d14c8STreehugger Robot #if SANITIZER_FREEBSD || SANITIZER_LINUX
17*7c3d14c8STreehugger Robot
18*7c3d14c8STreehugger Robot #include "esan.h"
19*7c3d14c8STreehugger Robot #include "esan_shadow.h"
20*7c3d14c8STreehugger Robot #include "interception/interception.h"
21*7c3d14c8STreehugger Robot #include "sanitizer_common/sanitizer_common.h"
22*7c3d14c8STreehugger Robot #include <sys/mman.h>
23*7c3d14c8STreehugger Robot #include <errno.h>
24*7c3d14c8STreehugger Robot
25*7c3d14c8STreehugger Robot namespace __esan {
26*7c3d14c8STreehugger Robot
verifyAddressSpace()27*7c3d14c8STreehugger Robot void verifyAddressSpace() {
28*7c3d14c8STreehugger Robot #if SANITIZER_LINUX && defined(__x86_64__)
29*7c3d14c8STreehugger Robot // The kernel determines its mmap base from the stack size limit.
30*7c3d14c8STreehugger Robot // Our Linux 64-bit shadow mapping assumes the stack limit is less than a
31*7c3d14c8STreehugger Robot // terabyte, which keeps the mmap region above 0x7e00'.
32*7c3d14c8STreehugger Robot uptr StackLimit = GetStackSizeLimitInBytes();
33*7c3d14c8STreehugger Robot if (StackSizeIsUnlimited() || StackLimit > MaxStackSize) {
34*7c3d14c8STreehugger Robot VReport(1, "The stack size limit is beyond the maximum supported.\n"
35*7c3d14c8STreehugger Robot "Re-execing with a stack size below 1TB.\n");
36*7c3d14c8STreehugger Robot SetStackSizeLimitInBytes(MaxStackSize);
37*7c3d14c8STreehugger Robot ReExec();
38*7c3d14c8STreehugger Robot }
39*7c3d14c8STreehugger Robot #endif
40*7c3d14c8STreehugger Robot }
41*7c3d14c8STreehugger Robot
liesWithinSingleAppRegion(uptr Start,SIZE_T Size)42*7c3d14c8STreehugger Robot static bool liesWithinSingleAppRegion(uptr Start, SIZE_T Size) {
43*7c3d14c8STreehugger Robot uptr AppStart, AppEnd;
44*7c3d14c8STreehugger Robot for (int i = 0; getAppRegion(i, &AppStart, &AppEnd); ++i) {
45*7c3d14c8STreehugger Robot if (Start >= AppStart && Start + Size - 1 <= AppEnd) {
46*7c3d14c8STreehugger Robot return true;
47*7c3d14c8STreehugger Robot }
48*7c3d14c8STreehugger Robot }
49*7c3d14c8STreehugger Robot return false;
50*7c3d14c8STreehugger Robot }
51*7c3d14c8STreehugger Robot
fixMmapAddr(void ** Addr,SIZE_T Size,int Flags)52*7c3d14c8STreehugger Robot bool fixMmapAddr(void **Addr, SIZE_T Size, int Flags) {
53*7c3d14c8STreehugger Robot if (*Addr) {
54*7c3d14c8STreehugger Robot if (!liesWithinSingleAppRegion((uptr)*Addr, Size)) {
55*7c3d14c8STreehugger Robot VPrintf(1, "mmap conflict: [%p-%p) is not in an app region\n",
56*7c3d14c8STreehugger Robot *Addr, (uptr)*Addr + Size);
57*7c3d14c8STreehugger Robot if (Flags & MAP_FIXED) {
58*7c3d14c8STreehugger Robot errno = EINVAL;
59*7c3d14c8STreehugger Robot return false;
60*7c3d14c8STreehugger Robot } else {
61*7c3d14c8STreehugger Robot *Addr = 0;
62*7c3d14c8STreehugger Robot }
63*7c3d14c8STreehugger Robot }
64*7c3d14c8STreehugger Robot }
65*7c3d14c8STreehugger Robot return true;
66*7c3d14c8STreehugger Robot }
67*7c3d14c8STreehugger Robot
checkMmapResult(uptr Addr,SIZE_T Size)68*7c3d14c8STreehugger Robot uptr checkMmapResult(uptr Addr, SIZE_T Size) {
69*7c3d14c8STreehugger Robot if ((void *)Addr == MAP_FAILED)
70*7c3d14c8STreehugger Robot return Addr;
71*7c3d14c8STreehugger Robot if (!liesWithinSingleAppRegion(Addr, Size)) {
72*7c3d14c8STreehugger Robot // FIXME: attempt to dynamically add this as an app region if it
73*7c3d14c8STreehugger Robot // fits our shadow criteria.
74*7c3d14c8STreehugger Robot // We could also try to remap somewhere else.
75*7c3d14c8STreehugger Robot Printf("ERROR: unsupported mapping at [%p-%p)\n", Addr, Addr+Size);
76*7c3d14c8STreehugger Robot Die();
77*7c3d14c8STreehugger Robot }
78*7c3d14c8STreehugger Robot return Addr;
79*7c3d14c8STreehugger Robot }
80*7c3d14c8STreehugger Robot
81*7c3d14c8STreehugger Robot } // namespace __esan
82*7c3d14c8STreehugger Robot
83*7c3d14c8STreehugger Robot #endif // SANITIZER_FREEBSD || SANITIZER_LINUX
84