Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add cross platform filesystem support #94

Merged
merged 32 commits into from
Jan 25, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
5160bac
Correctly handle existing objects
momo5502 Jan 24, 2025
32d91bd
Fix semaphores and mutexes
momo5502 Jan 24, 2025
f23fe93
Fix handle closing
momo5502 Jan 24, 2025
0698120
Log caller
momo5502 Jan 24, 2025
e175c83
Support verbose logging
momo5502 Jan 24, 2025
df089e9
Fix current thread id
momo5502 Jan 24, 2025
8854968
Rename spawned thread count to prevent confusion
momo5502 Jan 24, 2025
739cbbf
Fix verbose logging
momo5502 Jan 24, 2025
24bebc4
Prepare filesystem support
momo5502 Jan 21, 2025
77cb4d1
Add script to create root folder
momo5502 Jan 21, 2025
64e21ff
Add root dumping to workflow
momo5502 Jan 21, 2025
e15bb33
Dump API set
momo5502 Jan 21, 2025
b581d74
Fix test matrix
momo5502 Jan 21, 2025
ec13332
Implement root fs handling
momo5502 Jan 22, 2025
d836567
Fix PE parsing
momo5502 Jan 22, 2025
4300422
Fix path key
momo5502 Jan 22, 2025
114d87c
Fix test
momo5502 Jan 22, 2025
795badf
Retain permissions when uploading artifacts
momo5502 Jan 22, 2025
2256568
Fix casing
momo5502 Jan 22, 2025
aa162cc
Fix debug tests
momo5502 Jan 22, 2025
4d31331
Update unicorn
momo5502 Jan 22, 2025
7d65059
Test auto var init
momo5502 Jan 22, 2025
e9f7051
Add macOS intel tests
momo5502 Jan 22, 2025
ff51fbc
Update compiler-env.cmake
momo5502 Jan 22, 2025
6b43e53
Don't build universal binaries on macOS
momo5502 Jan 23, 2025
d360a06
Archive more DLLs and retain root fs for a day
momo5502 Jan 24, 2025
2c1e6f1
Fix formatting
momo5502 Jan 24, 2025
c4a02d3
Add more DLLs
momo5502 Jan 24, 2025
376015a
This fixes #104
momo5502 Jan 24, 2025
0454120
Serialize file system
momo5502 Jan 25, 2025
4cd0986
Support host/default apiset loc and empty emulation root
momo5502 Jan 25, 2025
a3c6e9a
Cleanup emulation root handling
momo5502 Jan 25, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
129 changes: 82 additions & 47 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,57 @@ jobs:
clang-format-version: '19'
check-path: 'src'

dump-registry:
name: Dump Registry
runs-on: windows-latest

dump-root:
name: Dump Root FS
runs-on: ${{ matrix.runner }}
needs: [build]
strategy:
fail-fast: false
matrix:
platform:
- Windows 2025
- Windows 2022
- Windows 2019
include:
- platform: Windows 2025
runner: windows-2025
- platform: Windows 2022
runner: windows-2022
- platform: Windows 2019
runner: windows-2019
steps:
- name: Checkout Source
uses: actions/checkout@v4

- name: Dump Registry
run: src/tools/grab-registry.bat
- name: Download DirectX Runtime
run: curl -L -o directx_Jun2010_redist.exe https://download.microsoft.com/download/8/4/A/84A35BF1-DAFE-4AE8-82AF-AD2AE20B6B14/directx_Jun2010_redist.exe

- name: Extract DirectX Runtime
run: ./directx_Jun2010_redist.exe /Q /T:"${{github.workspace}}/dxrt"

- name: Install DirectX Runtime
run: "cmd /c \"start /wait .\\dxrt\\dxsetup.exe /silent\""

- name: Download Windows Artifacts
uses: pyTooling/download-artifact@v4
with:
name: Windows Release Artifacts
path: build/release/artifacts

- name: Dump Root FS
run: src/tools/create-root.bat

- name: Dump API Set
run: cd root && ../build/release/artifacts/dump-apiset.exe

- name: Upload Artifacts
uses: actions/upload-artifact@v4
uses: pyTooling/upload-artifact@v4
with:
name: Temp Registry Dump
path: |
registry/*
name: ${{ matrix.platform }} Root FS
path: "*"
working-directory: root
retention-days: 1

build:
name: Build
Expand All @@ -55,7 +90,8 @@ jobs:
- Windows
- Linux GCC
- Linux Clang
- macOS
- macOS arm64
- macOS x86_64
- Android x86_64
- Android arm64-v8a
configuration:
Expand All @@ -73,8 +109,10 @@ jobs:
- platform: Linux Clang
runner: ubuntu-24.04
clang-version: 18
- platform: macOS
- platform: macOS arm64
runner: macos-latest
- platform: macOS x86_64
runner: macos-13
- platform: Android x86_64
runner: ubuntu-24.04
abi: x86_64
Expand Down Expand Up @@ -127,35 +165,36 @@ jobs:
if: ${{ !startsWith(matrix.platform, 'Android') }}

- name: Upload Artifacts
uses: actions/upload-artifact@v4
uses: pyTooling/upload-artifact@v4
with:
name: ${{ matrix.platform }} ${{matrix.configuration}} Artifacts
path: |
build/${{matrix.preset}}/artifacts/*
working-directory: build/${{matrix.preset}}/artifacts/
path: "*"

- name: Upload Test Configuration
uses: actions/upload-artifact@v4
uses: pyTooling/upload-artifact@v4
with:
name: Temp ${{ matrix.platform }} ${{matrix.configuration}} Test Config
path: |
build/${{matrix.preset}}/**/CTestTestfile.cmake

path: "**/CTestTestfile.cmake"
working-directory: build/${{matrix.preset}}

test:
name: Test
runs-on: ${{ matrix.runner }}
needs: [dump-registry, build]
needs: [dump-root, build]
strategy:
fail-fast: false
matrix:
platform:
# TODO: Move different windows platforms into registry dump matrix
filesystem:
- Windows 2025
- Windows 2022
- Windows 2019
platform:
- Windows
- Linux GCC
- Linux Clang
- macOS
- macOS arm64
- macOS x86_64
configuration:
- Debug
- Release
Expand All @@ -164,58 +203,54 @@ jobs:
preset: debug
- configuration: Release
preset: release
- platform: Windows 2025
build-platform: Windows
runner: windows-2025
- platform: Windows 2022
build-platform: Windows
runner: windows-2022
- platform: Windows 2019
build-platform: Windows
runner: windows-2019
- platform: Windows
runner: windows-latest
- platform: Linux GCC
build-platform: Linux GCC
runner: ubuntu-24.04
- platform: Linux Clang
build-platform: Linux Clang
runner: ubuntu-24.04
- platform: macOS
build-platform: macOS
- platform: macOS arm64
runner: macos-latest
- platform: macOS x86_64
runner: macos-13
steps:
- name: Download Test Config
uses: actions/download-artifact@v4
uses: pyTooling/download-artifact@v4
with:
name: Temp ${{ matrix.build-platform }} ${{matrix.configuration}} Test Config
name: Temp ${{ matrix.platform }} ${{matrix.configuration}} Test Config
path: build/${{matrix.preset}}

- name: Download Artifacts
uses: actions/download-artifact@v4
uses: pyTooling/download-artifact@v4
with:
name: ${{ matrix.build-platform }} ${{matrix.configuration}} Artifacts
name: ${{ matrix.platform }} ${{matrix.configuration}} Artifacts
path: build/${{matrix.preset}}/artifacts

- name: Download Windows Artifacts
uses: actions/download-artifact@v4
if: "${{ matrix.build-platform != 'Windows' }}"
uses: pyTooling/download-artifact@v4
if: "${{ matrix.platform != 'Windows' }}"
with:
name: Windows ${{matrix.configuration}} Artifacts
path: build/${{matrix.preset}}/artifacts

- name: Download Registry Dump
uses: actions/download-artifact@v4
- name: Download Root FS
uses: pyTooling/download-artifact@v4
with:
name: Temp Registry Dump
path: build/${{matrix.preset}}/artifacts/registry
name: ${{ matrix.filesystem }} Root FS
path: build/${{matrix.preset}}/artifacts/root

- name: Copy Test Sample
run: cp build/${{matrix.preset}}/artifacts/test-sample.exe build/${{matrix.preset}}/artifacts/root/filesys/c/

- name: CMake Test
run: cd build/${{matrix.preset}} && ctest --verbose
if: "${{ matrix.build-platform == 'Windows' }}"
env:
EMULATOR_ROOT: ${{github.workspace}}/build/${{matrix.preset}}/artifacts/root

summary:
name: Pipeline Summary
runs-on: ubuntu-24.04
needs: [dump-registry, build, test, verify-formatting]
needs: [dump-root, build, test, verify-formatting]
if: always()
steps:
- uses: geekyeggo/delete-artifact@v5
Expand Down
6 changes: 5 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

set(CMAKE_OSX_DEPLOYMENT_TARGET 11.0)
set(CMAKE_OSX_ARCHITECTURES "arm64;x86_64")

# Prevent unicorn from generating universal binaries on macOS
# It doesn't support it, even if it thinks it does...
set(ENV{ARCHFLAGS} "nope")


##########################################

Expand Down
7 changes: 6 additions & 1 deletion cmake/compiler-env.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON)
##########################################

if(UNIX)
momo_add_c_and_cxx_compile_options(-fvisibility=hidden)
momo_add_c_and_cxx_compile_options(
-fvisibility=hidden
-ftrivial-auto-var-init=zero
)
endif()

##########################################
Expand Down Expand Up @@ -91,6 +94,8 @@ if(MSVC)
momo_add_release_link_options(
#/LTCG
)

add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
endif()

##########################################
Expand Down
2 changes: 1 addition & 1 deletion deps/unicorn
18 changes: 17 additions & 1 deletion src/analyzer/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ namespace
{
bool use_gdb{false};
bool concise_logging{false};
bool verbose_logging{false};
std::string registry_path{"./registry"};
std::string emulation_root{};
};

void watch_system_objects(windows_emulator& win_emu, const bool cache_logging)
Expand Down Expand Up @@ -107,6 +109,7 @@ namespace
emulator_settings settings{
.application = args[0],
.registry_directory = options.registry_path,
.emulation_root = options.emulation_root,
.arguments = parse_arguments(args),
.silent_until_main = options.concise_logging,
};
Expand All @@ -116,7 +119,7 @@ namespace
(void)&watch_system_objects;
watch_system_objects(win_emu, options.concise_logging);
win_emu.buffer_stdout = true;
// win_emu.verbose_calls = true;
win_emu.verbose_calls = options.verbose_logging;

const auto& exe = *win_emu.process().executable;

Expand Down Expand Up @@ -200,10 +203,23 @@ namespace
{
options.use_gdb = true;
}
else if (arg == "-v")
{
options.verbose_logging = true;
}
else if (arg == "-c")
{
options.concise_logging = true;
}
else if (arg == "-e")
{
if (args.size() < 2)
{
throw std::runtime_error("No emulation root path provided after -e");
}
arg_it = args.erase(arg_it);
options.emulation_root = args[0];
}
else if (arg == "-r")
{
if (args.size() < 2)
Expand Down
2 changes: 2 additions & 0 deletions src/common/network/address.hpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#pragma once

#if _WIN32
#ifndef _CRT_SECURE_NO_WARNINGS
#define _CRT_SECURE_NO_WARNINGS
#endif
#define _CRT_NO_POSIX_ERROR_CODES
#define NOMINMAX
#define WIN32_LEAN_AND_MEAN
Expand Down
2 changes: 2 additions & 0 deletions src/common/platform/status.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ using NTSTATUS = std::uint32_t;
#define STATUS_ACCESS_DENIED ((NTSTATUS)0xC0000022L)
#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS)0xC0000023L)
#define STATUS_OBJECT_NAME_NOT_FOUND ((NTSTATUS)0xC0000034L)
#define STATUS_MUTANT_NOT_OWNED ((NTSTATUS)0xC0000046L)
#define STATUS_SEMAPHORE_LIMIT_EXCEEDED ((NTSTATUS)0xC0000047L)
#define STATUS_NO_TOKEN ((NTSTATUS)0xC000007CL)
#define STATUS_FILE_INVALID ((NTSTATUS)0xC0000098L)
#define STATUS_MEMORY_NOT_ALLOCATED ((NTSTATUS)0xC00000A0L)
Expand Down
9 changes: 5 additions & 4 deletions src/common/platform/unicode.hpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#pragma once

#include <string>
#include <filesystem>

template <typename Traits>
struct UNICODE_STRING
Expand Down Expand Up @@ -62,9 +63,9 @@ inline std::string w_to_u8(const std::wstring_view w_view)
}

#ifndef OS_WINDOWS
inline int open_unicode(FILE** handle, const std::u16string& fileName, const std::u16string& mode)
inline int open_unicode(FILE** handle, const std::filesystem::path& fileName, const std::u16string& mode)
{
*handle = fopen(u16_to_u8(fileName).c_str(), u16_to_u8(mode).c_str());
*handle = fopen(fileName.string().c_str(), u16_to_u8(mode).c_str());
return errno;
}
#else
Expand All @@ -73,8 +74,8 @@ inline std::wstring u16_to_w(const std::u16string& u16str)
return std::wstring(reinterpret_cast<const wchar_t*>(u16str.data()), u16str.size());
}

inline auto open_unicode(FILE** handle, const std::u16string& fileName, const std::u16string& mode)
inline auto open_unicode(FILE** handle, const std::filesystem::path& fileName, const std::u16string& mode)
{
return _wfopen_s(handle, u16_to_w(fileName).c_str(), u16_to_w(mode).c_str());
return _wfopen_s(handle, fileName.wstring().c_str(), u16_to_w(mode).c_str());
}
#endif
2 changes: 1 addition & 1 deletion src/common/platform/win_pefile.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -278,7 +278,7 @@ typedef struct _IMAGE_BASE_RELOCATION
{
DWORD VirtualAddress;
DWORD SizeOfBlock;
WORD TypeOffset[1];
// WORD TypeOffset[1];
} IMAGE_BASE_RELOCATION, *PIMAGE_BASE_RELOCATION;

#endif
Expand Down
5 changes: 4 additions & 1 deletion src/common/utils/path_key.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ namespace utils

static std::filesystem::path canonicalize_path(const std::filesystem::path& key)
{
auto path = key.lexically_normal().wstring();
auto key_string = key.u16string();
std::ranges::replace(key_string, u'\\', '/');

auto path = std::filesystem::path(key_string).lexically_normal().wstring();
return utils::string::to_lower_consume(path);
}

Expand Down
Loading
Loading