xref: /freebsd/contrib/llvm-project/compiler-rt/lib/scudo/standalone/trusty.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
1fe6060f1SDimitry Andric //===-- trusty.cpp ---------------------------------------------*- C++ -*-===//
2fe6060f1SDimitry Andric //
3fe6060f1SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4fe6060f1SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5fe6060f1SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6fe6060f1SDimitry Andric //
7fe6060f1SDimitry Andric //===----------------------------------------------------------------------===//
8fe6060f1SDimitry Andric 
9fe6060f1SDimitry Andric #include "platform.h"
10fe6060f1SDimitry Andric 
11fe6060f1SDimitry Andric #if SCUDO_TRUSTY
12fe6060f1SDimitry Andric 
13fe6060f1SDimitry Andric #include "common.h"
14fe6060f1SDimitry Andric #include "mutex.h"
15*5f757f3fSDimitry Andric #include "report_linux.h"
16fe6060f1SDimitry Andric #include "trusty.h"
17fe6060f1SDimitry Andric 
18fe6060f1SDimitry Andric #include <errno.h>           // for errno
1906c3fb27SDimitry Andric #include <lk/err_ptr.h>      // for PTR_ERR and IS_ERR
20fe6060f1SDimitry Andric #include <stdio.h>           // for printf()
21fe6060f1SDimitry Andric #include <stdlib.h>          // for getenv()
22fe6060f1SDimitry Andric #include <sys/auxv.h>        // for getauxval()
23fe6060f1SDimitry Andric #include <time.h>            // for clock_gettime()
2406c3fb27SDimitry Andric #include <trusty_err.h>      // for lk_err_to_errno()
25fe6060f1SDimitry Andric #include <trusty_syscalls.h> // for _trusty_brk()
2606c3fb27SDimitry Andric #include <uapi/mm.h>         // for MMAP flags
27fe6060f1SDimitry Andric 
28fe6060f1SDimitry Andric namespace scudo {
29fe6060f1SDimitry Andric 
30fe6060f1SDimitry Andric uptr getPageSize() { return getauxval(AT_PAGESZ); }
31fe6060f1SDimitry Andric 
32fe6060f1SDimitry Andric void NORETURN die() { abort(); }
33fe6060f1SDimitry Andric 
3406c3fb27SDimitry Andric void *map(void *Addr, uptr Size, const char *Name, uptr Flags,
35fe6060f1SDimitry Andric           UNUSED MapPlatformData *Data) {
3606c3fb27SDimitry Andric   uint32_t MmapFlags =
3706c3fb27SDimitry Andric       MMAP_FLAG_ANONYMOUS | MMAP_FLAG_PROT_READ | MMAP_FLAG_PROT_WRITE;
38fe6060f1SDimitry Andric 
3906c3fb27SDimitry Andric   // If the MAP_NOACCESS flag is set, Scudo tries to reserve
4006c3fb27SDimitry Andric   // a memory region without mapping physical pages. This corresponds
4106c3fb27SDimitry Andric   // to MMAP_FLAG_NO_PHYSICAL in Trusty.
42fe6060f1SDimitry Andric   if (Flags & MAP_NOACCESS)
4306c3fb27SDimitry Andric     MmapFlags |= MMAP_FLAG_NO_PHYSICAL;
4406c3fb27SDimitry Andric   if (Addr)
4506c3fb27SDimitry Andric     MmapFlags |= MMAP_FLAG_FIXED_NOREPLACE;
46fe6060f1SDimitry Andric 
4706c3fb27SDimitry Andric   if (Flags & MAP_MEMTAG)
4806c3fb27SDimitry Andric     MmapFlags |= MMAP_FLAG_PROT_MTE;
4906c3fb27SDimitry Andric 
5006c3fb27SDimitry Andric   void *P = (void *)_trusty_mmap(Addr, Size, MmapFlags, 0);
5106c3fb27SDimitry Andric 
5206c3fb27SDimitry Andric   if (IS_ERR(P)) {
5306c3fb27SDimitry Andric     errno = lk_err_to_errno(PTR_ERR(P));
54*5f757f3fSDimitry Andric     if (!(Flags & MAP_ALLOWNOMEM) || errno != ENOMEM)
55*5f757f3fSDimitry Andric       reportMapError(Size);
56fe6060f1SDimitry Andric     return nullptr;
57fe6060f1SDimitry Andric   }
5806c3fb27SDimitry Andric 
5906c3fb27SDimitry Andric   return P;
60fe6060f1SDimitry Andric }
61fe6060f1SDimitry Andric 
62fe6060f1SDimitry Andric void unmap(UNUSED void *Addr, UNUSED uptr Size, UNUSED uptr Flags,
6306c3fb27SDimitry Andric            UNUSED MapPlatformData *Data) {
6406c3fb27SDimitry Andric   if (_trusty_munmap(Addr, Size) != 0)
65*5f757f3fSDimitry Andric     reportUnmapError(reinterpret_cast<uptr>(Addr), Size);
6606c3fb27SDimitry Andric }
67fe6060f1SDimitry Andric 
68fe6060f1SDimitry Andric void setMemoryPermission(UNUSED uptr Addr, UNUSED uptr Size, UNUSED uptr Flags,
69fe6060f1SDimitry Andric                          UNUSED MapPlatformData *Data) {}
70fe6060f1SDimitry Andric 
71fe6060f1SDimitry Andric void releasePagesToOS(UNUSED uptr BaseAddress, UNUSED uptr Offset,
72fe6060f1SDimitry Andric                       UNUSED uptr Size, UNUSED MapPlatformData *Data) {}
73fe6060f1SDimitry Andric 
74fe6060f1SDimitry Andric const char *getEnv(const char *Name) { return getenv(Name); }
75fe6060f1SDimitry Andric 
76fe6060f1SDimitry Andric // All mutex operations are a no-op since Trusty doesn't currently support
77fe6060f1SDimitry Andric // threads.
78fe6060f1SDimitry Andric bool HybridMutex::tryLock() { return true; }
79fe6060f1SDimitry Andric 
80fe6060f1SDimitry Andric void HybridMutex::lockSlow() {}
81fe6060f1SDimitry Andric 
82fe6060f1SDimitry Andric void HybridMutex::unlock() {}
83fe6060f1SDimitry Andric 
8406c3fb27SDimitry Andric void HybridMutex::assertHeldImpl() {}
8506c3fb27SDimitry Andric 
86fe6060f1SDimitry Andric u64 getMonotonicTime() {
87fe6060f1SDimitry Andric   timespec TS;
88fe6060f1SDimitry Andric   clock_gettime(CLOCK_MONOTONIC, &TS);
89fe6060f1SDimitry Andric   return static_cast<u64>(TS.tv_sec) * (1000ULL * 1000 * 1000) +
90fe6060f1SDimitry Andric          static_cast<u64>(TS.tv_nsec);
91fe6060f1SDimitry Andric }
92fe6060f1SDimitry Andric 
9306c3fb27SDimitry Andric u64 getMonotonicTimeFast() {
9406c3fb27SDimitry Andric #if defined(CLOCK_MONOTONIC_COARSE)
9506c3fb27SDimitry Andric   timespec TS;
9606c3fb27SDimitry Andric   clock_gettime(CLOCK_MONOTONIC_COARSE, &TS);
9706c3fb27SDimitry Andric   return static_cast<u64>(TS.tv_sec) * (1000ULL * 1000 * 1000) +
9806c3fb27SDimitry Andric          static_cast<u64>(TS.tv_nsec);
9906c3fb27SDimitry Andric #else
10006c3fb27SDimitry Andric   return getMonotonicTime();
10106c3fb27SDimitry Andric #endif
10206c3fb27SDimitry Andric }
10306c3fb27SDimitry Andric 
104fe6060f1SDimitry Andric u32 getNumberOfCPUs() { return 0; }
105fe6060f1SDimitry Andric 
106fe6060f1SDimitry Andric u32 getThreadID() { return 0; }
107fe6060f1SDimitry Andric 
108fe6060f1SDimitry Andric bool getRandom(UNUSED void *Buffer, UNUSED uptr Length, UNUSED bool Blocking) {
109fe6060f1SDimitry Andric   return false;
110fe6060f1SDimitry Andric }
111fe6060f1SDimitry Andric 
112fe6060f1SDimitry Andric void outputRaw(const char *Buffer) { printf("%s", Buffer); }
113fe6060f1SDimitry Andric 
114fe6060f1SDimitry Andric void setAbortMessage(UNUSED const char *Message) {}
115fe6060f1SDimitry Andric 
116fe6060f1SDimitry Andric } // namespace scudo
117fe6060f1SDimitry Andric 
118fe6060f1SDimitry Andric #endif // SCUDO_TRUSTY
119