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