Support compilation with emscripten (#205)

This commit is contained in:
Maurice Heumann
2025-04-18 10:29:17 +02:00
committed by GitHub
28 changed files with 824 additions and 442 deletions

View File

@@ -161,6 +161,7 @@ jobs:
- iOS arm64
- Android x86_64
- Android arm64-v8a
- Emscripten
configuration:
- Debug
- Release
@@ -201,6 +202,9 @@ jobs:
abi: arm64-v8a
rust-target: aarch64-linux-android
cmake-options: "-DCMAKE_TOOLCHAIN_FILE=$GITHUB_WORKSPACE/cmake/toolchain/android-ndk.cmake"
- platform: Emscripten
runner: ubuntu-24.04
cmake-options: "-DMOMO_ENABLE_RUST_CODE=Off -DCMAKE_TOOLCHAIN_FILE=$(dirname $(which emcc))/cmake/Modules/Platform/Emscripten.cmake"
steps:
- name: Checkout Source
uses: actions/checkout@v4
@@ -214,6 +218,10 @@ jobs:
if: "${{ matrix.rust-target }}"
run: rustup target add ${{ matrix.rust-target }}
- name: Install Emscripten
if: "${{ matrix.platform == 'Emscripten' }}"
uses: mymindstorm/setup-emsdk@v14
- name: Install Clang
if: "${{ matrix.platform == 'Linux x86_64 Clang' }}"
run: |
@@ -473,10 +481,88 @@ jobs:
arch: ${{matrix.architecture}}
script: "adb push build/${{matrix.preset}}/artifacts/* /data/local/tmp && adb shell \"cd /data/local/tmp && export LD_LIBRARY_PATH=. && chmod +x ./analyzer && EMULATOR_ICICLE=${{ matrix.emulator == 'Icicle' }} ./analyzer -e ./root c:/test-sample.exe\""
build-page:
name: Build Page
runs-on: ubuntu-latest
needs: [create-emulation-root, build]
permissions:
contents: read
pages: write
id-token: write
steps:
- name: Checkout Source
uses: actions/checkout@v4
with:
submodules: recursive
- name: Download Emscripten Artifacts
uses: pyTooling/download-artifact@v4
with:
name: Emscripten Release Artifacts
path: build/release/artifacts
- name: Download Windows Artifacts
uses: pyTooling/download-artifact@v4
with:
name: Windows x86_64 Release Artifacts
path: build/release/artifacts
- name: Download Emulation Root
uses: pyTooling/download-artifact@v4
with:
name: Windows 2022 Emulation Root
path: build/release/artifacts/root
- name: Copy Sample
run: cp ./build/release/artifacts/test-sample.exe build/release/artifacts/root/filesys/c/
- name: Create Emulation Root zip
run: cd ./build/release/artifacts && zip -r "${{github.workspace}}/page/root.zip" ./root
- name: Copy Files
run: |
cp ./build/release/artifacts/analyzer.js ./page/
cp ./build/release/artifacts/analyzer.wasm ./page/
- name: Upload Page Artifacts
uses: pyTooling/upload-artifact@v4
with:
name: Page Artifacts
working-directory: page/
path: "*"
deploy-page:
name: Deploy Page
runs-on: ubuntu-latest
needs: [build-page, summary]
if: github.repository_owner == 'momo5502' && github.event_name == 'push' && github.ref == 'refs/heads/main'
permissions:
contents: read
pages: write
id-token: write
steps:
- name: Download Page Artifacts
uses: pyTooling/download-artifact@v4
with:
name: Page Artifacts
path: ./page/
- name: Setup Pages
uses: actions/configure-pages@v5
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: ./page
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
summary:
name: Pipeline Summary
runs-on: ubuntu-24.04
needs: [clang-tidy, build-apiset-dumper, smoke-test-android, create-emulation-root, build, test, win-test, verify-formatting]
needs: [build-page, clang-tidy, build-apiset-dumper, smoke-test-android, create-emulation-root, build, test, win-test, verify-formatting]
if: always()
steps:
- uses: geekyeggo/delete-artifact@v5

2
.gitmodules vendored
View File

@@ -2,7 +2,7 @@
path = deps/unicorn
url = ../unicorn.git
shallow = true
branch = dev
branch = wasm
[submodule "deps/reflect"]
path = deps/reflect
url = https://github.com/qlibs/reflect.git

View File

@@ -22,7 +22,12 @@ cmake_policy(SET CMP0069 NEW)
set(CMAKE_POLICY_DEFAULT_CMP0069 NEW)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
##########################################
if(NOT CMAKE_SYSTEM_NAME MATCHES "Emscripten")
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
endif()
##########################################
@@ -83,6 +88,22 @@ endif()
##########################################
if(CMAKE_SYSTEM_NAME MATCHES "Emscripten")
add_link_options(
-sALLOW_MEMORY_GROWTH=1
-sASSERTIONS
-sWASM_BIGINT
-sENVIRONMENT=web
-sUSE_OFFSET_CONVERTER
-sEXCEPTION_CATCHING_ALLOWED=[..]
-sEXIT_RUNTIME
#-lnodefs.js -sNODERAWFS=1
#-sASYNCIFY
)
endif()
##########################################
if(MSVC)
string(REPLACE "/EHsc" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
string(REPLACE "/EHs" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")

View File

@@ -0,0 +1,40 @@
set(CMAKE_SYSTEM_NAME Emscripten)
set(CMAKE_SYSTEM_VERSION 1)
# Specify the cross-compilers
set(CMAKE_C_COMPILER emcc)
set(CMAKE_CXX_COMPILER em++)
# Set the Emscripten root directory
set(EMSCRIPTEN_ROOT_PATH $ENV{EMSDK}/upstream/emscripten)
# Set the Emscripten toolchain file
set(CMAKE_SYSROOT ${EMSCRIPTEN_ROOT_PATH}/system)
# Set the Emscripten include directories
set(CMAKE_FIND_ROOT_PATH ${EMSCRIPTEN_ROOT_PATH}/system/include)
# Set the Emscripten library directories
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
# Set the Emscripten linker
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s USE_SDL=2 -s USE_SDL_MIXER=2")
# Set the Emscripten runtime
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} --shell-file shell_minimal.html")
# Set the Emscripten optimization flags
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3")
# Set the Emscripten debug flags
set(CMAKE_BUILD_TYPE Release)
# Set the Emscripten output format
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -o <TARGET>.html")
# Set the Emscripten file extensions
set(CMAKE_EXECUTABLE_SUFFIX ".js")
# Set the Emscripten runtime options
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -s EXPORTED_FUNCTIONS='[_main]' -s EXPORTED_RUNTIME_METHODS='[\"cwrap\"]'")

View File

@@ -335,7 +335,7 @@ function(momo_strip_target target)
return()
endif()
if(MSVC OR MOMO_ENABLE_SANITIZER OR CMAKE_SYSTEM_NAME STREQUAL "iOS" OR CMAKE_SYSTEM_NAME STREQUAL "Android")
if(MSVC OR MOMO_ENABLE_SANITIZER OR CMAKE_SYSTEM_NAME STREQUAL "iOS" OR CMAKE_SYSTEM_NAME STREQUAL "Android" OR CMAKE_SYSTEM_NAME MATCHES "Emscripten")
return()
endif()

1
deps/CMakeLists.txt vendored
View File

@@ -1,5 +1,4 @@
set(UNICORN_ARCH "x86" CACHE STRING "")
add_subdirectory(unicorn)
##########################################

2
deps/unicorn vendored

BIN
page/bigboiii.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

35
page/emulator.js Normal file
View File

@@ -0,0 +1,35 @@
onmessage = async (event) => {
const data = event.data;
if (data.message == "run") {
runEmulation(data.data);
}
};
function logLine(text) {
postMessage(text);
}
function runEmulation(filesystem) {
globalThis.Module = {
arguments: ["-b", "-c", "-e", "./root", "c:/test-sample.exe",],
onRuntimeInitialized: function () {
filesystem.forEach(e => {
if (e.name.endsWith("/")) {
FS.mkdir(e.name.slice(0, -1));
} else {
const dirs = e.name.split("/")
const file = dirs.pop();
const buffer = new Uint8Array(e.data);
FS.createDataFile("/" + dirs.join('/'), file, buffer, true, true);
}
})
},
print: logLine,
printErr: logLine,
postRun: () => {
self.close();
},
};
importScripts('./analyzer.js?1');
}

432
page/index.html Normal file
View File

@@ -0,0 +1,432 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title>Windows User Space Emulator</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=Open+Sans:ital,wght@0,300..800;1,300..800&display=swap');
html,
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
body {
background-color: #242322;
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
color: #f0f0f0;
position: relative;
flex-direction: column;
font-family: "Open Sans", sans-serif;
}
.buttons {
z-index: 201;
margin-top: 10px;
margin-bottom: 15px;
display: flex;
gap: 15px;
}
.button {
text-decoration: none;
box-shadow: 0 2px 3px rgba(0, 0, 0, .1);
transition: all .1s ease-out;
color: #f3f3f3d2;
background-color: rgba(26, 25, 24, 0.54);
padding: 12px;
border-radius: 14px;
min-width: 100px;
text-align: center;
display: inline-block;
transition: all 0.2s ease;
border: 1px solid rgba(255, 255, 255, 0);
}
.button:hover {
border: 1px solid rgba(255, 255, 255, 0.13);
}
.background-container {
position: fixed;
inset: 0px;
z-index: -1;
}
.background-container::before {
content: "";
position: fixed;
width: 100%;
height: 100%;
top: 0px;
background-image: url(./bigboiii.webp);
background-repeat: no-repeat;
background-size: cover;
background-position: center center;
opacity: 0.25;
filter: saturate(1.3) contrast(1.3) brightness(0.5);
transform: scale(1.3);
}
.background-container::after {
content: "";
position: fixed;
width: 100%;
top: 0px;
height: 100%;
background-image: url(./noise.webp);
background-repeat: repeat;
opacity: 0.1;
mix-blend-mode: overlay;
}
.eclipse {
position: fixed;
pointer-events: none;
z-index: 0;
}
.eclipse1 {
bottom: -260px;
left: 0;
}
.eclipse2 {
top: -260px;
right: 0;
transform: rotate(180deg);
}
.terminal-container {
width: 95%;
max-width: 1000px;
height: 700px;
background-color: rgba(34, 33, 32, 0.76);
border-radius: 12px;
box-shadow: 0 5px 20px rgba(0, 0, 0, 0.4);
overflow: hidden;
display: flex;
flex-direction: column;
z-index: 200;
margin: 15px;
}
.terminal-header {
background-color: #333231;
;
padding: 8px 16px;
display: flex;
justify-content: space-between;
align-items: center;
}
.terminal-title {
display: flex;
align-items: center;
gap: 8px;
}
.terminal-buttons {
display: flex;
gap: 8px;
}
.terminal-button {
width: 12px;
height: 12px;
border-radius: 50%;
cursor: pointer;
}
.close-button {
background-color: #ff5f56;
}
.minimize-button {
background-color: #ffbd2e;
}
.maximize-button {
background-color: #27c93f;
}
#output {
flex: 1;
padding: 16px;
overflow-y: auto;
font-size: 14px;
line-height: 1.5;
font-weight: 600;
font-family: monospace;
}
.terminal-black {
color: #0C0C0C;
}
.terminal-red {
color: #FF3131;
}
.terminal-green {
color: #86C000;
}
.terminal-yellow {
color: #FFB940;
}
.terminal-blue {
color: #00ADF7;
}
.terminal-cyan {
color: #3A96DD;
}
.terminal-pink {
color: #9750DD;
}
.terminal-white {
color: #ECECEC;
}
.terminal-dark-gray {
color: rgb(65, 65, 65);
}
@media (pointer:fine) {
::-webkit-scrollbar {
width: 20px;
}
::-webkit-scrollbar-track {
background-color: transparent;
}
::-webkit-scrollbar-thumb {
background-color: rgba(97, 97, 97, 0.4);
border-radius: 20px;
min-height: 50px;
border: 6px solid transparent;
background-clip: content-box;
transition: all 0.1s linear;
}
::-webkit-scrollbar-thumb:hover {
background-color: rgba(97, 97, 97, 0.8);
}
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jszip/3.7.1/jszip.min.js"></script>
<script>
function openDatabase() {
return new Promise((resolve, reject) => {
const request = indexedDB.open('cacheDB', 1);
request.onerror = (event) => {
reject('Database error: ' + event.target.errorCode);
};
request.onsuccess = (event) => {
resolve(event.target.result);
};
request.onupgradeneeded = (event) => {
const db = event.target.result;
if (!db.objectStoreNames.contains('cacheStore')) {
db.createObjectStore('cacheStore', { keyPath: 'id' });
}
};
});
}
async function saveData(id, data) {
const db = await openDatabase();
return new Promise((resolve, reject) => {
const transaction = db.transaction(['cacheStore'], 'readwrite');
const objectStore = transaction.objectStore('cacheStore');
const request = objectStore.put({ id: id, data: data });
request.onsuccess = () => {
resolve('Data saved successfully');
};
request.onerror = (event) => {
reject('Save error: ' + event.target.errorCode);
};
});
}
async function getData(id) {
const db = await openDatabase();
return new Promise((resolve, reject) => {
const transaction = db.transaction(['cacheStore'], 'readonly');
const objectStore = transaction.objectStore('cacheStore');
const request = objectStore.get(id);
request.onsuccess = (event) => {
if (event.target.result) {
resolve(event.target.result.data);
} else {
resolve(null);
}
};
request.onerror = (event) => {
reject('Retrieve error: ' + event.target.errorCode);
};
});
}
async function cacheAndUseData(id, asyncFunction) {
try {
let data = await getData(id);
if (!data) {
data = await asyncFunction();
await saveData(id, data);
}
return data;
} catch (error) {
console.error('Error:', error);
throw error;
}
}
function fetchFilesystemZip() {
return fetch("./root.zip?1", {
method: "GET",
headers: {
'Content-Type': 'application/octet-stream',
},
responseType: "arraybuffer"
}).then(r => r.arrayBuffer());
}
async function parseZipFromArrayBuffer(arrayBuffer) {
const zip = await JSZip.loadAsync(arrayBuffer);
const files = [];
const progress = {
files: 0,
processed: 0,
};
zip.forEach(function (relativePath, zipEntry) {
progress.files += 1;
files.push(zipEntry.async('arraybuffer').then(data => {
progress.processed += 1;
logLine(`Processing filesystem: ${progress.processed}/${progress.files}: ${relativePath}`);
return { name: relativePath, data };
}));
});
return await Promise.all(files);
}
async function fetchFilesystem() {
logLine("Downloading filesystem...");
const filesys = await fetchFilesystemZip();
return await parseZipFromArrayBuffer(filesys);
}
function getFilesystem() {
return cacheAndUseData("emulator-filesystem-2", fetchFilesystem);
}
function printText(lines) {
if (lines.length == 0) {
return;
}
var outputDiv = document.getElementById('output');
if (!outputDiv) {
return;
}
var text = lines.join("<br>");
if (outputDiv.innerHTML.length > 0) {
text = "<br>" + text;
}
outputDiv.innerHTML += text;
outputDiv.scrollTop = outputDiv.scrollHeight;
}
function flushLines() {
const lines = globalThis.logLines;
globalThis.logLines = [];
printText(lines);
requestAnimationFrame(flushLines);
}
function logLine(text) {
globalThis.logLines.push(text);
}
async function startEmulation() {
if (window.emulationStarted) {
return;
}
window.emulationStarted = true;
const filesystem = await getFilesystem();
logLine("Starting emulation...");
const worker = new Worker("./emulator.js?4");
worker.onmessage = (event) => {
logLine(event.data);
};
worker.postMessage({
message: "run",
data: filesystem,
});
}
window.addEventListener("load", () => {
globalThis.logLines = globalThis.logLines || [];
flushLines();
});
</script>
</head>
<body>
<div class="background-container"></div>
<img class="eclipse eclipse1" src="why-eclipse.svg" />
<img class="eclipse eclipse2" src="why-eclipse2.svg" />
<div class="terminal-container">
<div class="terminal-header">
<div class="terminal-buttons">
<div class="terminal-button close-button"></div>
<div class="terminal-button minimize-button"></div>
<div class="terminal-button maximize-button"></div>
</div>
<div class="terminal-title">
<span>Windows User Space Emulator</span>
</div>
<div></div>
</div>
<div id="output"></div>
</div>
<div class="buttons">
<a class="button" href="#" onclick="startEmulation()">Start Emulation</a>
<!--<a class="button" href="#" onclick="startEmulation()">Select .exe</a>-->
<a class="button" href="https://github.com/momo5502/emulator" target="_blank">GitHub</a>
</div>
</body>
</html>

BIN
page/noise.webp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

20
page/why-eclipse.svg Normal file
View File

@@ -0,0 +1,20 @@
<svg width="697" height="1177" viewBox="0 0 697 1177" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_f_27_189)">
<circle cx="71.5" cy="528.5" r="278.5" fill="#86C000" fill-opacity="0.21"/>
</g>
<g filter="url(#filter1_f_27_189)">
<circle cx="284.5" cy="764.5" r="162.5" fill="#3A96DD" fill-opacity="0.31"/>
</g>
<defs>
<filter id="filter0_f_27_189" x="-457" y="0" width="1057" height="1057" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="125" result="effect1_foregroundBlur_27_189"/>
</filter>
<filter id="filter1_f_27_189" x="-128" y="352" width="825" height="825" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="125" result="effect1_foregroundBlur_27_189"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

20
page/why-eclipse2.svg Normal file
View File

@@ -0,0 +1,20 @@
<svg width="697" height="1177" viewBox="0 0 697 1177" fill="none" xmlns="http://www.w3.org/2000/svg">
<g filter="url(#filter0_f_27_189)">
<circle cx="71.5" cy="528.5" r="278.5" fill="#FF3131" fill-opacity="0.21"/>
</g>
<g filter="url(#filter1_f_27_189)">
<circle cx="284.5" cy="764.5" r="162.5" fill="#FFB940" fill-opacity="0.31"/>
</g>
<defs>
<filter id="filter0_f_27_189" x="-457" y="0" width="1057" height="1057" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="125" result="effect1_foregroundBlur_27_189"/>
</filter>
<filter id="filter1_f_27_189" x="-128" y="352" width="825" height="825" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
<feBlend mode="normal" in="SourceGraphic" in2="BackgroundImageFix" result="shape"/>
<feGaussianBlur stdDeviation="125" result="effect1_foregroundBlur_27_189"/>
</filter>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -13,7 +13,9 @@ endif()
set(CARGO_TRIPLE)
set(CARGO_OPTIONS)
if(WIN32 AND CMAKE_SIZEOF_VOID_P EQUAL 4)
if (CMAKE_SYSTEM_NAME STREQUAL "Emscripten")
set(CARGO_TRIPLE "wasm32-unknown-emscripten")
elseif(WIN32 AND CMAKE_SIZEOF_VOID_P EQUAL 4)
set(CARGO_TRIPLE "i686-pc-windows-msvc")
elseif(CMAKE_SYSTEM_NAME STREQUAL "iOS")
set(CARGO_TRIPLE "aarch64-apple-ios")

View File

@@ -43,30 +43,12 @@ version = "1.0.97"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dcfed56ad506cb2c684a14971b8861fdc3baaaae314b9e5f9bb532cbe3ba7a4f"
[[package]]
name = "arbitrary"
version = "1.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dde20b3d026af13f561bdd0f15edf01fc734f0dafcedbaf42bba506a9517f223"
[[package]]
name = "autocfg"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
[[package]]
name = "base64"
version = "0.21.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567"
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.9.0"
@@ -86,12 +68,6 @@ dependencies = [
"serde",
]
[[package]]
name = "bumpalo"
version = "3.17.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
[[package]]
name = "bytemuck"
version = "1.22.0"
@@ -113,148 +89,6 @@ dependencies = [
"cfg-if",
]
[[package]]
name = "cranelift"
version = "0.113.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "27711210499725bafe52c320a988e27283e6cf477ee8edac57e8275bef8ea550"
dependencies = [
"cranelift-codegen",
"cranelift-frontend",
"cranelift-module",
]
[[package]]
name = "cranelift-bforest"
version = "0.113.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "540b193ff98b825a1f250a75b3118911af918a734154c69d80bcfcf91e7e9522"
dependencies = [
"cranelift-entity",
]
[[package]]
name = "cranelift-bitset"
version = "0.113.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7cb269598b9557ab942d687d3c1086d77c4b50dcf35813f3a65ba306fd42279"
[[package]]
name = "cranelift-codegen"
version = "0.113.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46566d7c83a8bff4150748d66020f4c7224091952aa4b4df1ec4959c39d937a1"
dependencies = [
"bumpalo",
"cranelift-bforest",
"cranelift-bitset",
"cranelift-codegen-meta",
"cranelift-codegen-shared",
"cranelift-control",
"cranelift-entity",
"cranelift-isle",
"gimli",
"hashbrown 0.14.5",
"log",
"regalloc2",
"rustc-hash",
"smallvec",
"target-lexicon",
]
[[package]]
name = "cranelift-codegen-meta"
version = "0.113.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2df8a86a34236cc75a8a6a271973da779c2aeb36c43b6e14da474cf931317082"
dependencies = [
"cranelift-codegen-shared",
]
[[package]]
name = "cranelift-codegen-shared"
version = "0.113.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf75340b6a57b7c7c1b74f10d3d90883ee6d43a554be8131a4046c2ebcf5eb65"
[[package]]
name = "cranelift-control"
version = "0.113.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2e84495bc5d23d86aad8c86f8ade4af765b94882af60d60e271d3153942f1978"
dependencies = [
"arbitrary",
]
[[package]]
name = "cranelift-entity"
version = "0.113.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "963c17147b80df351965e57c04d20dbedc85bcaf44c3436780a59a3f1ff1b1c2"
dependencies = [
"cranelift-bitset",
]
[[package]]
name = "cranelift-frontend"
version = "0.113.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "727f02acbc4b4cb2ba38a6637101d579db50190df1dd05168c68e762851a3dd5"
dependencies = [
"cranelift-codegen",
"log",
"smallvec",
"target-lexicon",
]
[[package]]
name = "cranelift-isle"
version = "0.113.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32b00cc2e03c748f2531eea01c871f502b909d30295fdcad43aec7bf5c5b4667"
[[package]]
name = "cranelift-jit"
version = "0.113.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f74630af581f32b99c8f4e06ee45799383ecc0795e3ff8aa86b7584bb2d643fd"
dependencies = [
"anyhow",
"cranelift-codegen",
"cranelift-control",
"cranelift-entity",
"cranelift-module",
"cranelift-native",
"libc",
"log",
"region",
"target-lexicon",
"wasmtime-jit-icache-coherence",
"windows-sys 0.59.0",
]
[[package]]
name = "cranelift-module"
version = "0.113.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6aaa16c4f18a15be310df221ea544f516acc42fc58ca96e09a3d08651744efa1"
dependencies = [
"anyhow",
"cranelift-codegen",
"cranelift-control",
]
[[package]]
name = "cranelift-native"
version = "0.113.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbeaf978dc7c1a2de8bbb9162510ed218eb156697bc45590b8fbdd69bb08e8de"
dependencies = [
"cranelift-codegen",
"libc",
"target-lexicon",
]
[[package]]
name = "crc32fast"
version = "1.4.2"
@@ -276,16 +110,6 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "errno"
version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "976dd42dc7e85965fe702eb8164f21f450704bdde31faefd6471dba214cb594e"
dependencies = [
"libc",
"windows-sys 0.59.0",
]
[[package]]
name = "fallible-iterator"
version = "0.3.0"
@@ -340,15 +164,6 @@ dependencies = [
"crunchy",
]
[[package]]
name = "hashbrown"
version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
dependencies = [
"ahash",
]
[[package]]
name = "hashbrown"
version = "0.15.2"
@@ -370,12 +185,12 @@ dependencies = [
[[package]]
name = "icicle-cpu"
version = "0.1.0"
source = "git+https://github.com/icicle-emu/icicle-emu#fe930922ea1ec39578ee545ccced61649f3da00a"
source = "git+https://github.com/momo5502/icicle-emu#70c9ed338d931da705a4a7a8ec2110cc677d970c"
dependencies = [
"addr2line",
"ahash",
"anyhow",
"bitflags 2.9.0",
"bitflags",
"bytemuck",
"gimli",
"half",
@@ -387,30 +202,12 @@ dependencies = [
"tracing",
]
[[package]]
name = "icicle-jit"
version = "0.2.0"
source = "git+https://github.com/icicle-emu/icicle-emu#fe930922ea1ec39578ee545ccced61649f3da00a"
dependencies = [
"cranelift",
"cranelift-codegen",
"cranelift-jit",
"cranelift-module",
"cranelift-native",
"icicle-cpu",
"memoffset",
"pcode",
"target-lexicon",
"tracing",
"wasmtime-jit-debug",
]
[[package]]
name = "icicle-linux"
version = "0.1.0"
source = "git+https://github.com/icicle-emu/icicle-emu#fe930922ea1ec39578ee545ccced61649f3da00a"
source = "git+https://github.com/momo5502/icicle-emu#70c9ed338d931da705a4a7a8ec2110cc677d970c"
dependencies = [
"bitflags 2.9.0",
"bitflags",
"bstr",
"bytemuck",
"icicle-cpu",
@@ -424,7 +221,7 @@ dependencies = [
[[package]]
name = "icicle-mem"
version = "0.3.0"
source = "git+https://github.com/icicle-emu/icicle-emu#fe930922ea1ec39578ee545ccced61649f3da00a"
source = "git+https://github.com/momo5502/icicle-emu#70c9ed338d931da705a4a7a8ec2110cc677d970c"
dependencies = [
"ahash",
"tracing",
@@ -433,11 +230,10 @@ dependencies = [
[[package]]
name = "icicle-vm"
version = "0.2.0"
source = "git+https://github.com/icicle-emu/icicle-emu#fe930922ea1ec39578ee545ccced61649f3da00a"
source = "git+https://github.com/momo5502/icicle-emu#70c9ed338d931da705a4a7a8ec2110cc677d970c"
dependencies = [
"anyhow",
"icicle-cpu",
"icicle-jit",
"icicle-linux",
"ihex",
"object",
@@ -464,7 +260,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e"
dependencies = [
"equivalent",
"hashbrown 0.15.2",
"hashbrown",
]
[[package]]
@@ -473,27 +269,12 @@ version = "0.2.171"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6"
[[package]]
name = "linux-raw-sys"
version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
[[package]]
name = "log"
version = "0.4.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
[[package]]
name = "mach2"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19b955cdeb2a02b9117f121ce63aa52d08ade45de53e48fe6a38b39c10f6f709"
dependencies = [
"libc",
]
[[package]]
name = "memchr"
version = "2.7.4"
@@ -509,15 +290,6 @@ dependencies = [
"libc",
]
[[package]]
name = "memoffset"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
dependencies = [
"autocfg",
]
[[package]]
name = "miniz_oxide"
version = "0.8.8"
@@ -535,7 +307,7 @@ checksum = "62948e14d923ea95ea2c7c86c71013138b66525b86bdc08d2dcc262bdb497b87"
dependencies = [
"crc32fast",
"flate2",
"hashbrown 0.15.2",
"hashbrown",
"indexmap",
"memchr",
"ruzstd",
@@ -550,7 +322,7 @@ checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
[[package]]
name = "pcode"
version = "0.2.0"
source = "git+https://github.com/icicle-emu/icicle-emu#fe930922ea1ec39578ee545ccced61649f3da00a"
source = "git+https://github.com/momo5502/icicle-emu#70c9ed338d931da705a4a7a8ec2110cc677d970c"
[[package]]
name = "pin-project-lite"
@@ -576,31 +348,6 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "regalloc2"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12908dbeb234370af84d0579b9f68258a0f67e201412dd9a2814e6f45b2fc0f0"
dependencies = [
"hashbrown 0.14.5",
"log",
"rustc-hash",
"slice-group-by",
"smallvec",
]
[[package]]
name = "region"
version = "3.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6b6ebd13bc009aef9cd476c1310d49ac354d36e240cf1bd753290f3dc7199a7"
dependencies = [
"bitflags 1.3.2",
"libc",
"mach2",
"windows-sys 0.52.0",
]
[[package]]
name = "ron"
version = "0.8.1"
@@ -608,7 +355,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b91f7eff05f748767f183df4320a63d6936e9c6107d97c9e6bdd9784f4289c94"
dependencies = [
"base64",
"bitflags 2.9.0",
"bitflags",
"serde",
"serde_derive",
]
@@ -619,25 +366,6 @@ version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
[[package]]
name = "rustc-hash"
version = "2.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
[[package]]
name = "rustix"
version = "0.38.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154"
dependencies = [
"bitflags 2.9.0",
"errno",
"libc",
"linux-raw-sys",
"windows-sys 0.59.0",
]
[[package]]
name = "ruzstd"
version = "0.7.3"
@@ -682,7 +410,7 @@ dependencies = [
[[package]]
name = "sleigh-compile"
version = "0.3.0"
source = "git+https://github.com/icicle-emu/icicle-emu#fe930922ea1ec39578ee545ccced61649f3da00a"
source = "git+https://github.com/momo5502/icicle-emu#70c9ed338d931da705a4a7a8ec2110cc677d970c"
dependencies = [
"pcode",
"serde",
@@ -695,23 +423,17 @@ dependencies = [
[[package]]
name = "sleigh-parse"
version = "0.3.0"
source = "git+https://github.com/icicle-emu/icicle-emu#fe930922ea1ec39578ee545ccced61649f3da00a"
source = "git+https://github.com/momo5502/icicle-emu#70c9ed338d931da705a4a7a8ec2110cc677d970c"
[[package]]
name = "sleigh-runtime"
version = "0.1.0"
source = "git+https://github.com/icicle-emu/icicle-emu#fe930922ea1ec39578ee545ccced61649f3da00a"
source = "git+https://github.com/momo5502/icicle-emu#70c9ed338d931da705a4a7a8ec2110cc677d970c"
dependencies = [
"pcode",
"sleigh-parse",
]
[[package]]
name = "slice-group-by"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "826167069c09b99d56f31e9ae5c99049e932a98c9dc2dac47645b08dbbf76ba7"
[[package]]
name = "smallvec"
version = "1.15.0"
@@ -817,122 +539,6 @@ version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasmtime-jit-debug"
version = "26.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f02a0118d471de665565ed200bc56673eaa10cc8e223dfe2cef5d50ed0d9d143"
dependencies = [
"object",
"rustix",
"wasmtime-versioned-export-macros",
]
[[package]]
name = "wasmtime-jit-icache-coherence"
version = "26.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da47fba49af72581bc0dc67c8faaf5ee550e6f106e285122a184a675193701a5"
dependencies = [
"anyhow",
"cfg-if",
"libc",
"windows-sys 0.59.0",
]
[[package]]
name = "wasmtime-versioned-export-macros"
version = "26.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "db8efb877c9e5e67239d4553bb44dd2a34ae5cfb728f3cf2c5e64439c6ca6ee7"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "windows-sys"
version = "0.52.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-sys"
version = "0.59.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e38bc4d79ed67fd075bcc251a1c39b32a1776bbe92e5bef1f0bf1f8c531853b"
dependencies = [
"windows-targets",
]
[[package]]
name = "windows-targets"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
dependencies = [
"windows_aarch64_gnullvm",
"windows_aarch64_msvc",
"windows_i686_gnu",
"windows_i686_gnullvm",
"windows_i686_msvc",
"windows_x86_64_gnu",
"windows_x86_64_gnullvm",
"windows_x86_64_msvc",
]
[[package]]
name = "windows_aarch64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
[[package]]
name = "windows_aarch64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
[[package]]
name = "windows_i686_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
[[package]]
name = "windows_i686_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
[[package]]
name = "windows_i686_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
[[package]]
name = "windows_x86_64_gnu"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
[[package]]
name = "windows_x86_64_gnullvm"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
[[package]]
name = "windows_x86_64_msvc"
version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "xml-rs"
version = "0.8.25"

View File

@@ -7,6 +7,6 @@ edition = "2024"
crate-type = ["staticlib"]
[dependencies]
icicle-vm = { git = "https://github.com/icicle-emu/icicle-emu" }
icicle-cpu = { git = "https://github.com/icicle-emu/icicle-emu" }
pcode = { git = "https://github.com/icicle-emu/icicle-emu" }
icicle-vm = { git = "https://github.com/momo5502/icicle-emu" }
icicle-cpu = { git = "https://github.com/momo5502/icicle-emu" }
pcode = { git = "https://github.com/momo5502/icicle-emu" }

View File

@@ -25,8 +25,8 @@ extern "C"
int32_t icicle_unmap_memory(icicle_emulator*, uint64_t address, uint64_t length);
int32_t icicle_read_memory(icicle_emulator*, uint64_t address, void* data, size_t length);
int32_t icicle_write_memory(icicle_emulator*, uint64_t address, const void* data, size_t length);
int32_t icicle_save_registers(icicle_emulator*, data_accessor_func* accessor, void* accessor_data);
int32_t icicle_restore_registers(icicle_emulator*, const void* data, size_t length);
void icicle_save_registers(icicle_emulator*, data_accessor_func* accessor, void* accessor_data);
void icicle_restore_registers(icicle_emulator*, const void* data, size_t length);
uint32_t icicle_add_syscall_hook(icicle_emulator*, raw_func* callback, void* data);
uint32_t icicle_add_interrupt_hook(icicle_emulator*, interrupt_func* callback, void* data);
uint32_t icicle_add_execution_hook(icicle_emulator*, uint64_t address, ptr_func* callback, void* data);

View File

@@ -0,0 +1,91 @@
#pragma once
#include <array>
#include <memory>
#include <functional>
#include <utils/object.hpp>
template <typename T, size_t N>
T resolve_indexed_argument_internal(const std::array<size_t, N>& args, size_t& index)
{
const auto a1 = args[index++];
if constexpr (sizeof(T) <= sizeof(a1) || sizeof(size_t) > 4)
{
return T(a1);
}
else
{
const auto a2 = args[index++];
const auto arg = (a1 | (static_cast<uint64_t>(a2) << 32));
return T(arg);
}
}
template <typename T, size_t N>
T resolve_indexed_argument(const std::array<size_t, N>& args, size_t& index)
{
auto arg = resolve_indexed_argument_internal<T, N>(args, index);
return arg;
}
template <typename ReturnType, typename... Args>
class function_wrapper_tcg : public utils::object
{
public:
using user_data_pointer = void*;
using c_function_type = ReturnType(Args..., user_data_pointer);
using functor_type = std::function<ReturnType(Args...)>;
function_wrapper_tcg() = default;
function_wrapper_tcg(functor_type functor)
: functor_(std::make_unique<functor_type>(std::move(functor)))
{
}
c_function_type* get_c_function() const
{
auto* func = +[](const size_t a1, const size_t a2, const size_t a3, const size_t a4, const size_t a5,
const size_t a6, const size_t a7, const size_t a8, const size_t a9, const size_t a10,
const size_t a11, const size_t a12) -> uint64_t {
const std::array arguments = {a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11, a12};
const auto lambda = +[](Args... args, user_data_pointer user_data) -> ReturnType {
return (*static_cast<functor_type*>(user_data))(std::forward<Args>(args)...);
};
size_t index = 0;
std::tuple<Args..., user_data_pointer> func_args{
resolve_indexed_argument<std::remove_cv_t<std::remove_reference_t<Args>>>(arguments, index)...,
resolve_indexed_argument<user_data_pointer>(arguments, index)};
(void)index;
if constexpr (!std::is_void_v<ReturnType>)
{
return uint64_t(std::apply(lambda, std::move(func_args)));
}
std::apply(lambda, std::move(func_args));
return 0;
};
return reinterpret_cast<c_function_type*>(reinterpret_cast<void*>(func));
}
void* get_function() const
{
return reinterpret_cast<void*>(this->get_c_function());
}
user_data_pointer get_user_data() const
{
return this->functor_.get();
}
private:
std::unique_ptr<functor_type> functor_{};
};

View File

@@ -7,6 +7,7 @@
#include "unicorn_hook.hpp"
#include "function_wrapper.hpp"
#include "function_wrapper_tcg.hpp"
#include <ranges>
namespace unicorn
@@ -385,10 +386,6 @@ namespace unicorn
emulator_hook* hook_instruction(const int instruction_type, instruction_hook_callback callback) override
{
function_wrapper<int, uc_engine*> wrapper([c = std::move(callback)](uc_engine*) {
return (c() == instruction_hook_continuation::skip_instruction) ? 1 : 0;
});
unicorn_hook hook{*this};
auto container = std::make_unique<hook_container>();
@@ -396,18 +393,38 @@ namespace unicorn
if (inst_type == x64_hookable_instructions::invalid)
{
function_wrapper<int, uc_engine*> wrapper([c = std::move(callback)](uc_engine*) {
return (c() == instruction_hook_continuation::skip_instruction) ? 1 : 0;
});
uce(uc_hook_add(*this, hook.make_reference(), UC_HOOK_INSN_INVALID, wrapper.get_function(),
wrapper.get_user_data(), 0, std::numeric_limits<pointer_type>::max()));
container->add(std::move(wrapper), std::move(hook));
}
else
else if (inst_type == x64_hookable_instructions::syscall)
{
function_wrapper<void, uc_engine*> wrapper([c = std::move(callback)](uc_engine*) { c(); });
const auto uc_instruction = map_hookable_instruction(inst_type);
uce(uc_hook_add(*this, hook.make_reference(), UC_HOOK_INSN, wrapper.get_function(),
wrapper.get_user_data(), 0, std::numeric_limits<pointer_type>::max(),
uc_instruction));
}
container->add(std::move(wrapper), std::move(hook));
container->add(std::move(wrapper), std::move(hook));
}
else
{
function_wrapper<int, uc_engine*> wrapper([c = std::move(callback)](uc_engine*) {
return (c() == instruction_hook_continuation::skip_instruction) ? 1 : 0;
});
const auto uc_instruction = map_hookable_instruction(inst_type);
uce(uc_hook_add(*this, hook.make_reference(), UC_HOOK_INSN, wrapper.get_function(),
wrapper.get_user_data(), 0, std::numeric_limits<pointer_type>::max(),
uc_instruction));
container->add(std::move(wrapper), std::move(hook));
}
auto* result = container->as_opaque_hook();
@@ -533,7 +550,7 @@ namespace unicorn
c(address); //
};
function_wrapper<void, uc_engine*, uint64_t, uint32_t> wrapper(std::move(exec_wrapper));
function_wrapper_tcg<void, uc_engine*, uint64_t, uint32_t> wrapper(std::move(exec_wrapper));
unicorn_hook hook{*this};

View File

@@ -13,6 +13,8 @@
#define OS_MAC
#elif defined(__linux__)
#define OS_LINUX
#elif defined(__EMSCRIPTEN__)
#define OS_EMSCRIPTEN
#else
#error "Unsupported platform"
#endif

View File

@@ -883,6 +883,7 @@ typedef struct _KERNEL_USER_TIMES
struct THREAD_TLS_INFO
{
ULONG Flags;
uint32_t _Padding;
union
{

View File

@@ -8,6 +8,7 @@ struct UNICODE_STRING
{
USHORT Length;
USHORT MaximumLength;
uint32_t _Padding;
EMULATOR_CAST(typename Traits::PVOID, char16_t*) Buffer;
};

View File

@@ -4,7 +4,7 @@
#include <gtest/gtest.h>
#include <windows_emulator.hpp>
#include "static_socket_factory.hpp"
#include <network/static_socket_factory.hpp>
#define ASSERT_NOT_TERMINATED(win_emu) \
do \

View File

@@ -6,16 +6,19 @@
namespace
{
#ifdef _WIN32
#define COLOR(win, posix) win
#define COLOR(win, posix, web) win
using color_type = WORD;
#elif defined(__EMSCRIPTEN__)
#define COLOR(win, posix, web) web
using color_type = const char*;
#else
#define COLOR(win, posix) posix
#define COLOR(win, posix, web) posix
using color_type = const char*;
#endif
color_type get_reset_color()
{
return COLOR(7, "\033[0m");
return COLOR(7, "\033[0m", "</span>");
}
color_type get_color_type(const color c)
@@ -25,23 +28,23 @@ namespace
switch (c)
{
case black:
return COLOR(0x8, "\033[0;90m");
return COLOR(0x8, "\033[0;90m", "<span class=\"terminal-black\">");
case red:
return COLOR(0xC, "\033[0;91m");
return COLOR(0xC, "\033[0;91m", "<span class=\"terminal-red\">");
case green:
return COLOR(0xA, "\033[0;92m");
return COLOR(0xA, "\033[0;92m", "<span class=\"terminal-green\">");
case yellow:
return COLOR(0xE, "\033[0;93m");
return COLOR(0xE, "\033[0;93m", "<span class=\"terminal-yellow\">");
case blue:
return COLOR(0x9, "\033[0;94m");
return COLOR(0x9, "\033[0;94m", "<span class=\"terminal-blue\">");
case cyan:
return COLOR(0xB, "\033[0;96m");
return COLOR(0xB, "\033[0;96m", "<span class=\"terminal-cyan\">");
case pink:
return COLOR(0xD, "\033[0;95m");
return COLOR(0xD, "\033[0;95m", "<span class=\"terminal-pink\">");
case white:
return COLOR(0xF, "\033[0;97m");
return COLOR(0xF, "\033[0;97m", "<span class=\"terminal-white\">");
case dark_gray:
return COLOR(0x8, "\033[0;97m");
return COLOR(0x8, "\033[0;97m", "<span class=\"terminal-dark-gray\">");
case gray:
default:
return get_reset_color();

View File

@@ -259,7 +259,7 @@ mapped_module map_module_from_file(memory_manager& memory, std::filesystem::path
const auto data = utils::io::read_file(file);
if (data.empty())
{
throw std::runtime_error("Bad file data");
throw std::runtime_error("Bad file data: " + file.string());
}
return map_module_from_data(memory, data, std::move(file));

View File

@@ -1,6 +1,6 @@
#pragma once
#include <network/socket_factory.hpp>
#include "socket_factory.hpp"
namespace network
{

View File

@@ -16,6 +16,8 @@
#include "exception_dispatch.hpp"
#include "apiset/apiset.hpp"
#include "network/static_socket_factory.hpp"
constexpr auto MAX_INSTRUCTIONS_PER_TIME_SLICE = 100000;
namespace
@@ -257,7 +259,11 @@ namespace
return std::move(interfaces.socket_factory);
}
#ifdef OS_EMSCRIPTEN
return network::create_static_socket_factory();
#else
return std::make_unique<network::socket_factory>();
#endif
}
}