xref: /aosp_15_r20/external/compiler-rt/lib/esan/esan_linux.cpp (revision 7c3d14c8b49c529e04be81a3ce6f5cc23712e4c6)
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