14#include "llvm/Config/config.h"
30#include <zircon/syscalls.h>
34extern "C" void sys_icache_invalidate(
const void *
Addr,
size_t len);
36extern "C" void __clear_cache(
void *,
void *);
39static int getPosixProtectionFlags(
unsigned Flags) {
46 return PROT_READ | PROT_WRITE;
48 return PROT_READ | PROT_EXEC;
51 return PROT_READ | PROT_WRITE | PROT_EXEC;
53#if defined(__FreeBSD__) || defined(__powerpc__)
59 return PROT_READ | PROT_EXEC;
74 const MemoryBlock *
const NearBlock,
75 unsigned PFlags, std::error_code &EC) {
76 EC = std::error_code();
87 fd = open(
"/dev/zero", O_RDWR);
94 int MMFlags = MAP_PRIVATE;
98 int Protect = getPosixProtectionFlags(PFlags);
100#if defined(__NetBSD__) && defined(PROT_MPROTECT)
101 Protect |= PROT_MPROTECT(PROT_READ | PROT_WRITE | PROT_EXEC);
105 uintptr_t Start = NearBlock ?
reinterpret_cast<uintptr_t
>(NearBlock->base()) +
106 NearBlock->allocatedSize()
115 void *
Addr = ::mmap(
reinterpret_cast<void *
>(Start),
PageSize * NumPages,
116 Protect, MMFlags, fd, 0);
117 if (
Addr == MAP_FAILED) {
119#if !defined(MAP_ANON)
126#if !defined(MAP_ANON)
129 return MemoryBlock();
132#if !defined(MAP_ANON)
144 if (EC != std::error_code())
145 return MemoryBlock();
152 if (
M.Address ==
nullptr ||
M.AllocatedSize == 0)
153 return std::error_code();
155 if (0 != ::munmap(
M.Address,
M.AllocatedSize))
161 return std::error_code();
167 if (
M.Address ==
nullptr ||
M.AllocatedSize == 0)
168 return std::error_code();
171 return std::error_code(EINVAL, std::generic_category());
173 int Protect = getPosixProtectionFlags(Flags);
181#if defined(__arm__) || defined(__aarch64__)
186 if (InvalidateCache && !(Protect & PROT_READ)) {
187 int Result = ::mprotect((
void *)Start,
End - Start, Protect | PROT_READ);
192 InvalidateCache =
false;
196 int Result = ::mprotect((
void *)Start,
End - Start, Protect);
204 return std::error_code();
213#if defined(__APPLE__)
215#if (defined(__powerpc__) || defined(__arm__) || defined(__arm64__))
216 sys_icache_invalidate(
const_cast<void *
>(
Addr), Len);
219#elif defined(__Fuchsia__)
221 zx_status_t
Status = zx_cache_flush(
Addr, Len, ZX_CACHE_FLUSH_INSN);
222 assert(
Status == ZX_OK &&
"cannot invalidate instruction cache");
226#if defined(__powerpc__) && defined(__GNUC__)
227 const size_t LineSize = 32;
229 const intptr_t
Mask = ~(LineSize - 1);
230 const intptr_t StartLine = ((intptr_t)
Addr) &
Mask;
231 const intptr_t EndLine = ((intptr_t)
Addr + Len + LineSize - 1) &
Mask;
233 for (intptr_t Line = StartLine;
Line < EndLine;
Line += LineSize)
234 asm volatile(
"dcbf 0, %0" : :
"r"(Line));
235 asm volatile(
"sync");
237 for (intptr_t Line = StartLine;
Line < EndLine;
Line += LineSize)
238 asm volatile(
"icbi 0, %0" : :
"r"(Line));
239 asm volatile(
"isync");
240#elif (defined(__arm__) || defined(__aarch64__) || defined(__loongarch__) || \
241 defined(__mips__)) && \
244 const char *Start =
static_cast<const char *
>(
Addr);
245 const char *
End = Start +
Len;
246 __clear_cache(
const_cast<char *
>(Start),
const_cast<char *
>(
End));
static cl::opt< int > PageSize("imp-null-check-page-size", cl::desc("The page size of the target in bytes"), cl::init(4096), cl::Hidden)
Provides a library for accessing information about this process and other processes on the operating ...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static std::error_code releaseMappedMemory(MemoryBlock &Block)
This method releases a block of memory that was allocated with the allocateMappedMemory method.
static MemoryBlock allocateMappedMemory(size_t NumBytes, const MemoryBlock *const NearBlock, unsigned Flags, std::error_code &EC)
This method allocates a block of memory that is suitable for loading dynamically generated code (e....
static void InvalidateInstructionCache(const void *Addr, size_t Len)
InvalidateInstructionCache - Before the JIT can run a block of code that has been emitted it must inv...
static std::error_code protectMappedMemory(const MemoryBlock &Block, unsigned Flags)
This method sets the protection flags for a block of memory to the state specified by /p Flags.
static unsigned getPageSizeEstimate()
Get the process's estimated page size.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
void ValgrindDiscardTranslations(const void *Addr, size_t Len)
This is an optimization pass for GlobalISel generic memory operations.
std::error_code errnoAsErrorCode()
Helper to get errno as an std::error_code.
uintptr_t alignAddr(const void *Addr, Align Alignment)
Aligns Addr to Alignment bytes, rounding up.