15 #include "llvm/Config/config.h"
41 uint8_t *SectionMemoryManager::allocateSection(
47 assert(!(Alignment & (Alignment - 1)) &&
"Alignment must be a power of two.");
49 uintptr_t RequiredSize = Alignment * ((Size + Alignment - 1) / Alignment + 1);
52 MemoryGroup &MemGroup = [&]() -> MemoryGroup & {
66 for (FreeMemBlock &FreeMB : MemGroup.FreeMem) {
67 if (FreeMB.Free.allocatedSize() >= RequiredSize) {
68 Addr = (uintptr_t)FreeMB.Free.base();
69 uintptr_t EndOfBlock =
Addr + FreeMB.Free.allocatedSize();
73 if (FreeMB.PendingPrefixIndex == (
unsigned)-1) {
75 MemGroup.PendingMem.push_back(sys::MemoryBlock((
void *)
Addr,
Size));
79 FreeMB.PendingPrefixIndex = MemGroup.PendingMem.size() - 1;
81 sys::MemoryBlock &PendingMB =
82 MemGroup.PendingMem[FreeMB.PendingPrefixIndex];
83 PendingMB = sys::MemoryBlock(PendingMB.base(),
84 Addr + Size - (uintptr_t)PendingMB.base());
89 sys::MemoryBlock((
void *)(
Addr + Size), EndOfBlock -
Addr - Size);
90 return (uint8_t *)
Addr;
105 Purpose, RequiredSize, &MemGroup.Near,
117 if (CodeMem.Near.base() ==
nullptr)
119 if (RODataMem.Near.base() ==
nullptr)
121 if (RWDataMem.Near.base() ==
nullptr)
125 MemGroup.AllocatedMem.push_back(MB);
126 Addr = (uintptr_t)MB.base();
127 uintptr_t EndOfBlock =
Addr + MB.allocatedSize();
133 MemGroup.PendingMem.push_back(sys::MemoryBlock((
void *)
Addr,
Size));
137 unsigned FreeSize = EndOfBlock -
Addr -
Size;
140 FreeMB.Free = sys::MemoryBlock((
void *)(
Addr + Size), FreeSize);
141 FreeMB.PendingPrefixIndex = (unsigned)-1;
142 MemGroup.FreeMem.push_back(FreeMB);
146 return (uint8_t *)
Addr;
154 ec = applyMemoryGroupPermissions(CodeMem,
158 *ErrMsg = ec.message();
167 *ErrMsg = ec.message();
185 size_t StartOverlap =
188 size_t TrimmedSize =
M.allocatedSize();
189 TrimmedSize -= StartOverlap;
190 TrimmedSize -= TrimmedSize %
PageSize;
204 SectionMemoryManager::applyMemoryGroupPermissions(MemoryGroup &MemGroup,
205 unsigned Permissions) {
206 for (sys::MemoryBlock &MB : MemGroup.PendingMem)
210 MemGroup.PendingMem.clear();
214 for (FreeMemBlock &FreeMB : MemGroup.FreeMem) {
217 FreeMB.PendingPrefixIndex = (unsigned)-1;
221 erase_if(MemGroup.FreeMem, [](FreeMemBlock &FreeMB) {
222 return FreeMB.Free.allocatedSize() == 0;
225 return std::error_code();
231 Block.allocatedSize());
235 for (MemoryGroup *Group : {&CodeMem, &RWDataMem, &RODataMem}) {
243 void SectionMemoryManager::anchor() {}
248 class DefaultMMapper final :
public SectionMemoryManager::MemoryMapper {
252 size_t NumBytes,
const sys::MemoryBlock *
const NearBlock,
253 unsigned Flags, std::error_code &EC)
override {
257 std::error_code protectMappedMemory(
const sys::MemoryBlock &Block,
258 unsigned Flags)
override {
262 std::error_code releaseMappedMemory(sys::MemoryBlock &M)
override {
267 DefaultMMapper DefaultMMapperInstance;
271 : MMapper(MM ? *MM : DefaultMMapperInstance) {}