xref: /freebsd/contrib/llvm-project/compiler-rt/lib/scudo/standalone/trusty.cpp (revision fe6060f10f634930ff71b7c50291ddc610da2475)
1*fe6060f1SDimitry Andric //===-- trusty.cpp ---------------------------------------------*- C++ -*-===//
2*fe6060f1SDimitry Andric //
3*fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*fe6060f1SDimitry Andric //
7*fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
8*fe6060f1SDimitry Andric 
9*fe6060f1SDimitry Andric #include "platform.h"
10*fe6060f1SDimitry Andric 
11*fe6060f1SDimitry Andric #if SCUDO_TRUSTY
12*fe6060f1SDimitry Andric 
13*fe6060f1SDimitry Andric #include "common.h"
14*fe6060f1SDimitry Andric #include "mutex.h"
15*fe6060f1SDimitry Andric #include "string_utils.h"
16*fe6060f1SDimitry Andric #include "trusty.h"
17*fe6060f1SDimitry Andric 
18*fe6060f1SDimitry Andric #include <errno.h>           // for errno
19*fe6060f1SDimitry Andric #include <stdio.h>           // for printf()
20*fe6060f1SDimitry Andric #include <stdlib.h>          // for getenv()
21*fe6060f1SDimitry Andric #include <sys/auxv.h>        // for getauxval()
22*fe6060f1SDimitry Andric #include <time.h>            // for clock_gettime()
23*fe6060f1SDimitry Andric #include <trusty_syscalls.h> // for _trusty_brk()
24*fe6060f1SDimitry Andric 
25*fe6060f1SDimitry Andric #define SBRK_ALIGN 32
26*fe6060f1SDimitry Andric 
27*fe6060f1SDimitry Andric namespace scudo {
28*fe6060f1SDimitry Andric 
29*fe6060f1SDimitry Andric uptr getPageSize() { return getauxval(AT_PAGESZ); }
30*fe6060f1SDimitry Andric 
31*fe6060f1SDimitry Andric void NORETURN die() { abort(); }
32*fe6060f1SDimitry Andric 
33*fe6060f1SDimitry Andric void *map(UNUSED void *Addr, uptr Size, UNUSED const char *Name, uptr Flags,
34*fe6060f1SDimitry Andric           UNUSED MapPlatformData *Data) {
35*fe6060f1SDimitry Andric   // Calling _trusty_brk(0) returns the current program break.
36*fe6060f1SDimitry Andric   uptr ProgramBreak = reinterpret_cast<uptr>(_trusty_brk(0));
37*fe6060f1SDimitry Andric   uptr Start;
38*fe6060f1SDimitry Andric   uptr End;
39*fe6060f1SDimitry Andric 
40*fe6060f1SDimitry Andric   Start = roundUpTo(ProgramBreak, SBRK_ALIGN);
41*fe6060f1SDimitry Andric   // Don't actually extend the heap if MAP_NOACCESS flag is set since this is
42*fe6060f1SDimitry Andric   // the case where Scudo tries to reserve a memory region without mapping
43*fe6060f1SDimitry Andric   // physical pages.
44*fe6060f1SDimitry Andric   if (Flags & MAP_NOACCESS)
45*fe6060f1SDimitry Andric     return reinterpret_cast<void *>(Start);
46*fe6060f1SDimitry Andric 
47*fe6060f1SDimitry Andric   // Attempt to extend the heap by Size bytes using _trusty_brk.
48*fe6060f1SDimitry Andric   End = roundUpTo(Start + Size, SBRK_ALIGN);
49*fe6060f1SDimitry Andric   ProgramBreak =
50*fe6060f1SDimitry Andric       reinterpret_cast<uptr>(_trusty_brk(reinterpret_cast<void *>(End)));
51*fe6060f1SDimitry Andric   if (ProgramBreak < End) {
52*fe6060f1SDimitry Andric     errno = ENOMEM;
53*fe6060f1SDimitry Andric     dieOnMapUnmapError(Size);
54*fe6060f1SDimitry Andric     return nullptr;
55*fe6060f1SDimitry Andric   }
56*fe6060f1SDimitry Andric   return reinterpret_cast<void *>(Start); // Base of new reserved region.
57*fe6060f1SDimitry Andric }
58*fe6060f1SDimitry Andric 
59*fe6060f1SDimitry Andric // Unmap is a no-op since Trusty uses sbrk instead of memory mapping.
60*fe6060f1SDimitry Andric void unmap(UNUSED void *Addr, UNUSED uptr Size, UNUSED uptr Flags,
61*fe6060f1SDimitry Andric            UNUSED MapPlatformData *Data) {}
62*fe6060f1SDimitry Andric 
63*fe6060f1SDimitry Andric void setMemoryPermission(UNUSED uptr Addr, UNUSED uptr Size, UNUSED uptr Flags,
64*fe6060f1SDimitry Andric                          UNUSED MapPlatformData *Data) {}
65*fe6060f1SDimitry Andric 
66*fe6060f1SDimitry Andric void releasePagesToOS(UNUSED uptr BaseAddress, UNUSED uptr Offset,
67*fe6060f1SDimitry Andric                       UNUSED uptr Size, UNUSED MapPlatformData *Data) {}
68*fe6060f1SDimitry Andric 
69*fe6060f1SDimitry Andric const char *getEnv(const char *Name) { return getenv(Name); }
70*fe6060f1SDimitry Andric 
71*fe6060f1SDimitry Andric // All mutex operations are a no-op since Trusty doesn't currently support
72*fe6060f1SDimitry Andric // threads.
73*fe6060f1SDimitry Andric bool HybridMutex::tryLock() { return true; }
74*fe6060f1SDimitry Andric 
75*fe6060f1SDimitry Andric void HybridMutex::lockSlow() {}
76*fe6060f1SDimitry Andric 
77*fe6060f1SDimitry Andric void HybridMutex::unlock() {}
78*fe6060f1SDimitry Andric 
79*fe6060f1SDimitry Andric u64 getMonotonicTime() {
80*fe6060f1SDimitry Andric   timespec TS;
81*fe6060f1SDimitry Andric   clock_gettime(CLOCK_MONOTONIC, &TS);
82*fe6060f1SDimitry Andric   return static_cast<u64>(TS.tv_sec) * (1000ULL * 1000 * 1000) +
83*fe6060f1SDimitry Andric          static_cast<u64>(TS.tv_nsec);
84*fe6060f1SDimitry Andric }
85*fe6060f1SDimitry Andric 
86*fe6060f1SDimitry Andric u32 getNumberOfCPUs() { return 0; }
87*fe6060f1SDimitry Andric 
88*fe6060f1SDimitry Andric u32 getThreadID() { return 0; }
89*fe6060f1SDimitry Andric 
90*fe6060f1SDimitry Andric bool getRandom(UNUSED void *Buffer, UNUSED uptr Length, UNUSED bool Blocking) {
91*fe6060f1SDimitry Andric   return false;
92*fe6060f1SDimitry Andric }
93*fe6060f1SDimitry Andric 
94*fe6060f1SDimitry Andric void outputRaw(const char *Buffer) { printf("%s", Buffer); }
95*fe6060f1SDimitry Andric 
96*fe6060f1SDimitry Andric void setAbortMessage(UNUSED const char *Message) {}
97*fe6060f1SDimitry Andric 
98*fe6060f1SDimitry Andric } // namespace scudo
99*fe6060f1SDimitry Andric 
100*fe6060f1SDimitry Andric #endif // SCUDO_TRUSTY
101