forked from gdlocalisation/gdl-source-code
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
144 additions
and
158 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
#include <PageManager.hpp> | ||
|
||
using namespace geode::prelude; | ||
|
||
void PageManager::freeAll() { | ||
for (auto& page : m_pages) { | ||
page.free(); | ||
} | ||
} | ||
|
||
PageManager::Page& PageManager::getPageForSize(size_t size) { | ||
if (m_pages.size() > 0 && m_pages.back().canFit(size)) { | ||
return m_pages.back(); | ||
} else { | ||
return allocNewPage(); | ||
} | ||
} | ||
|
||
uint8_t* PageManager::getMemoryForSize(size_t size) { | ||
auto& page = getPageForSize(size); | ||
auto ret = page.getOffsetAddress(); | ||
page.reserve(size); | ||
return ret; | ||
} | ||
|
||
PageManager::Page& PageManager::allocNewPage() { | ||
SYSTEM_INFO sysInfo; | ||
GetSystemInfo(&sysInfo); | ||
|
||
const uint64_t PAGE_SIZE = sysInfo.dwPageSize; | ||
auto targetAddr = base::get() + 0x251000; // approximately the middle of the exe file | ||
void* newPageAddr = nullptr; | ||
uint64_t startAddr = (uint64_t(targetAddr) & ~(PAGE_SIZE - 1)); // round down to nearest page boundary | ||
uint64_t minAddr = std::min(startAddr - 0x7FFFFF00, (uint64_t)sysInfo.lpMinimumApplicationAddress); | ||
uint64_t maxAddr = std::max(startAddr + 0x7FFFFF00, (uint64_t)sysInfo.lpMaximumApplicationAddress); | ||
uint64_t startPage = (startAddr - (startAddr % PAGE_SIZE)); | ||
uint64_t pageOffset = 1; | ||
|
||
while (1) { | ||
uint64_t byteOffset = pageOffset * PAGE_SIZE; | ||
uint64_t highAddr = startPage + byteOffset; | ||
uint64_t lowAddr = (startPage > byteOffset) ? startPage - byteOffset : 0; | ||
bool needsExit = highAddr > maxAddr && lowAddr < minAddr; | ||
|
||
if (highAddr < maxAddr) { | ||
void* outAddr = VirtualAlloc((void*)highAddr, PAGE_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); | ||
if (outAddr) { | ||
newPageAddr = outAddr; | ||
break; | ||
} | ||
} | ||
|
||
if (lowAddr > minAddr) { | ||
void* outAddr = VirtualAlloc((void*)lowAddr, PAGE_SIZE, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); | ||
if (outAddr != nullptr) { | ||
newPageAddr = outAddr; | ||
break; | ||
} | ||
} | ||
|
||
pageOffset++; | ||
|
||
if (needsExit) { | ||
break; | ||
} | ||
} | ||
|
||
if (newPageAddr == nullptr) { | ||
log::error("page failed to alloc (what?)"); | ||
throw std::runtime_error("gdl: page failed to alloc"); | ||
} | ||
|
||
m_pages.push_back(Page {.m_address = (uint8_t*)newPageAddr, .m_totalSize = PAGE_SIZE, .m_offset = 0, .m_id = m_pages.size()}); | ||
|
||
return m_pages.back(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
#pragma once | ||
#include <Geode/Geode.hpp> | ||
|
||
#if defined(GEODE_IS_WINDOWS64) | ||
|
||
class PageManager { | ||
struct Page { | ||
uint8_t* m_address; | ||
size_t m_totalSize; | ||
size_t m_offset; // aka used size | ||
size_t m_id; | ||
|
||
inline uint8_t* getOffsetAddress() { return m_address + m_offset; } | ||
inline bool canFit(size_t len) { return m_totalSize - m_offset >= len; } | ||
inline void reserve(size_t len) { m_offset = std::min(m_offset + len, m_totalSize); } | ||
void free() { | ||
if (m_address) { | ||
VirtualFree(m_address, m_totalSize, MEM_RELEASE); | ||
m_address = nullptr; | ||
m_totalSize = 0; | ||
m_offset = 0; | ||
} | ||
} | ||
}; | ||
|
||
public: | ||
static PageManager& get() { | ||
static PageManager inst; | ||
return inst; | ||
} | ||
|
||
~PageManager() { freeAll(); } | ||
|
||
void freeAll(); | ||
|
||
// if the last page can fit those bytes, return it. otherwise, alloc a new page | ||
Page& getPageForSize(size_t size); | ||
uint8_t* getMemoryForSize(size_t size); | ||
|
||
private: | ||
Page& allocNewPage(); | ||
|
||
std::vector<Page> m_pages; | ||
}; | ||
|
||
#endif |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Submodule utf8
updated
6 files
+1 −1 | .github/workflows/cmake-multi-platform.yml | |
+2 −3 | CMakeLists.txt | |
+7 −7 | README.md | |
+4 −4 | source/utf8/core.h | |
+3 −3 | source/utf8/unchecked.h | |
+6 −8 | tests/CMakeLists.txt |
Submodule zydis
updated
17 files
+8 −61 | .github/workflows/main.yml | |
+2 −0 | CMakeLists.txt | |
+0 −25 | Doxyfile.meson.in | |
+0 −1 | assets/version-bump-checklist.txt | |
+1 −1 | dependencies/zycore | |
+0 −10 | dependencies/zycore.wrap | |
+2 −2 | examples/ZydisPerfTest.c | |
+0 −28 | examples/meson.build | |
+0 −25 | man/meson.build | |
+0 −339 | meson.build | |
+0 −87 | meson_options.txt | |
+1 −1 | resources/VersionInfo.rc | |
+7 −20 | src/Utils.c | |
+0 −1 | subprojects | |
+0 −34 | tests/meson.build | |
+0 −42 | tests/zydis_encoder_types.py | |
+0 −85 | tools/meson.build |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters