brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.9 KiB · 41c6632 Raw
104 lines · plain
1//===- NativeMemoryAPIs.inc -------------------------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// Generic wrappers for unix-style memory APIs (mmap, mprotect, etc.).10//11//===----------------------------------------------------------------------===//12 13#include "orc-rt/Error.h"14#include "orc-rt/MemoryFlags.h"15 16#include <fcntl.h>17#include <string.h>18#include <sys/errno.h>19#include <sys/mman.h>20 21namespace {22 23int toNativeProtFlags(orc_rt::MemProt MP) {24  int Prot = PROT_NONE;25  if ((MP & orc_rt::MemProt::Read) != orc_rt::MemProt::None)26    Prot |= PROT_READ;27  if ((MP & orc_rt::MemProt::Write) != orc_rt::MemProt::None)28    Prot |= PROT_WRITE;29  if ((MP & orc_rt::MemProt::Exec) != orc_rt::MemProt::None)30    Prot |= PROT_EXEC;31  return Prot;32}33 34#if defined(__APPLE__)35extern "C" void sys_icache_invalidate(const void *Addr, size_t Size);36#else37extern "C" void __clear_cache(void *Start, void *End);38#endif39 40static void invalidateInstructionCache(void *Addr, size_t Size) {41#if defined(__APPLE__)42  sys_icache_invalidate(Addr, Size);43#else44  __clear_cache(Addr, reinterpret_cast<char *>(Addr) + Size);45#endif46}47 48orc_rt::Expected<void *> hostOSMemoryReserve(size_t Size) {49  if (Size == 0)50    return nullptr;51 52  int FD = 0;53  int MapFlags = MAP_PRIVATE;54 55#if defined(MAP_ANON)56  // If MAP_ANON is available then use it.57  FD = -1;58  MapFlags |= MAP_ANON;59#else // !defined(MAP_ANON)60  // Fall back to /dev/zero for strict POSIX.61  fd = open("/dev/zero", O_RDWR);62  if (fd == -1) {63    auto ErrNum = errno;64    return make_error<orc_rt::StringError>(65        std::string("Could not open /dev/zero for memory reserve: ") +66        strerror(ErrNum));67  }68#endif69 70  void *Addr = mmap(nullptr, Size, PROT_READ | PROT_WRITE, MapFlags, FD, 0);71  if (Addr == MAP_FAILED) {72    auto ErrNum = errno;73    return orc_rt::make_error<orc_rt::StringError>(74        std::string("mmap for memory reserve failed: ") + strerror(ErrNum));75  }76 77  return Addr;78}79 80orc_rt::Error hostOSMemoryRelease(void *Base, size_t Size) {81  if (munmap(Base, Size) != 0) {82    auto ErrNum = errno;83    return orc_rt::make_error<orc_rt::StringError>(84        std::string("munmap for memory release failed: ") + strerror(ErrNum));85  }86  return orc_rt::Error::success();87}88 89orc_rt::Error hostOSMemoryProtect(void *Base, size_t Size, orc_rt::MemProt MP) {90  if (mprotect(Base, Size, toNativeProtFlags(MP)) != 0) {91    auto ErrNum = errno;92    return orc_rt::make_error<orc_rt::StringError>(93        std::string("mprotect for memory finalize failed: ") +94        strerror(ErrNum));95  }96 97  if ((MP & orc_rt::MemProt::Exec) != orc_rt::MemProt::None)98    invalidateInstructionCache(Base, Size);99 100  return orc_rt::Error::success();101}102 103} // anonymous namespace104