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