Giter Club home page Giter Club logo

uwin's Introduction

uwin

uwin is a (reasonably) portable runtime with implementation of some win32 implementations, aimed at running windows games from around '99.

While being somewhat similar to WINE project, uwin aims to also provide CPU emulation facilities (allowing it to run on non-x86 machines) and more portability (not only UNIX!)

State

This project is very much work and progress and not much works yet.

Right now it contains rusty-x86: mostly functional (but not yet optimized) x86 static recompiler with an interpreter fallback, along with some groundwork for supporting win32 APIs (the coverage is not that good yet).

In terms of Win32 API support, it can run basic console programs and aims to implement support for at least DirectDraw and WinMM sound output. More APIs can come later

There are some notes at the wiki

uwin's People

Contributors

dcnick3 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

uwin's Issues

Implement a scalable way to dispatch recompiled code execution

Currently a large switch-case is generated in uwin-remill. This is fine with small executables, but fails miserably with larger ones (order of 100,000s of recompiled functions) due to scalability problems in modern C++ compilers (see gcc bug). Either using binary trees or perfect hashing might be a good idea.

(For now perfec hashing seems very promising)

Add ability to lift dlls alongside the exe files

Will need to generate the memory map, apply relocations and imports (for target dlls) and then lift.

Replacing indirect dispatches to the native dlls with direct calls might also be a good idea.

Figure out a way to dump readable PSTR values (et al)

Interpreting them correctly requires memory context & some environment. We need to pass those to (a hypothetical) Dump trait.

It's also still unclear how much env do we need (for str - at least memory ctx + current ansi encoding)

Implement windows codepages support

Initial idea was to use ICU, but now it seems that it's not the best way to do this: ICU encodings do not directly correspond to windows codepages. Probably an approach taken by wine is good enough.

win32::svc::locale is broken design, str is a good idea overall

Implement win32 COM

This might be stubbed (I think), but it would be nice to have a generic implementation.

It is used in HoMM3 to get some DirectX services

Make code recompilation more scalable

As for now, attempt to recompile the lifted code for HoMM 3 binary with optimization results in utter failure due to enormous size of llvm Module produced. We either want to chunk the resulting bitcode, so that it can be optimized independently (and in parallel!), or create a custom optimization pipeline that will not get clogged by large modules (or, ideally, do both).

See also #6

Design a threading model to use

What is threading model?

How do we map target execution threads to host threads, how we start, execute, suspend and stop them.

Design requirements:

  • Be as portable as possible, i. e. require only the bare minimum from the host platform. Currently these platforms are considered:
    • linux on x86_64
    • linux on arm64
    • windows on x86_64 (still needs some work, but should work in principle)
    • Atmosphere with libnx on arm64 (Nintendo switch homebrew)
  • Enforce strict mutual exclusion of thread execution (for both the target and native code). This is not required per se, but greatly reduces complexity (mostly concerning the memory ordering issues on arm64, which will require additional work on remill side of things)
  • Be preemptive, i. e. be able to switch threads when target code is executing (think: inifinite loop). This is only for target code, native code may be written so that it will not get stuck.

Different existing implementations:

  • qemu: make the code non-executable and handle the raised signal; needs to enforce special structure of the recompiled code (recompiled target code being separate from the native code). Needs some linker magic
  • LuaJIT: run hook in every looping path (can be changed to just an interrupt variable check). Needs some work on remill side and research into how to find good places to put the hook in LLVM IR (see 1, 2, 3)
  • luavela: similar approach; TODO: is it any different?
  • wine: Uses a combination of sending an async POSIX signal and select inside it. Good approach, but, unfortunately, works only on POSIX platforms, needs adaptation otherwise. (see 1, 2)

All of these approaches might be feasible in uwin, but portability should be considered. (The most restrictive platform for now is the Atmosphere).

Registry design

In the long run, we may want to implement something similar to layered fs (maybe even share some code using templates ;)), but for running HoMM 3 some basic RW access will be enough (in the first iteration INI files were used)

Filesystem design

The current vision is to have a UNIX-style filesystem: you can mount various FS backends to different locations.

Possible backends include:

  • static asset data (See #8)
  • host system directory (need to handle the case-sensitivity/insensitivity situations)
  • custom fs on a block device (might be useful for host systems without the file system, but no such are planned (yet))
  • overlay (like linux overlayfs); may be useful to allow writes to the emulated application directory (like in HoMM 3, which uses it to store hiscores)

Add support for address ranges inside the namemap

A function can contain multiple basic blocks, but now only the first basic block address will match with the label address and not all recompiled basic blocks will get the original function name.

Add an emulation fallback when the target jumps to a block not recompiled

It is not possible to fully statically analyze the program to find all of its basic blocks, so some fallback should developed at least. Emulation should be a good strategy: we always can do it. Also, this way we can dynamically collect all the basic blocks entered and feed them back to recompilation step, reducing the amount of code not recompiled.

Some library implementing the x86 emulation through fetch-decode-execute should be found (or implemented).

Some possible candidates (probably needs more research):

  • halfix: C implementation. Uses A LOT of global variables, so probably will need to be refactored to be of use. On the other hand, it is fairly easy to separate the cpu emulation code from everything else
  • JPC: Java implementation. Not usable per se, but might be worth taking a look at
  • v86: JS implementation. Ditto
  • libx86emu: C++ library. Seems to be good, but claims that not much instructions are implemented. CPU is fully isolated and instrumentable
  • x86emu: C++ full-system emulator. CPU component does not seem to be isolated
  • unicorn: CPU emulation framework. Seems to be cool, but probably would not work on Atmosphere (portability)
  • Pokas x86 Emulator: Not entirely sure how good it is, but seems to be of a design similar to what is needed. Portability and instruction coverage are unknown, need to research more
  • The x86 Emulator plugin for IDAPro: ???

rusty-x86: Unicorn engine tests are flaky

These problems have risen after migration from unicorn to unicorn-engine crate, which itself was prompted by ABI-breaking update of 2.0.1 of unicorn itself:

I think there is some thread synchronization issue in the unicorn-engine (or LLVM, which was also updated!), as some tests are non-deterministically failing with multiple threads but are fine in single-threaded context.

Then there is a problem of the pushfd_pop_eax test, which simply does

pushf
pop eax

The mismatch is that rusty-x86 has EAX be 0, while unicorn has it be 2. This result is stable, but I don't think it's right

Console IO

For now, only basic support without precise semantics:

  • WriteConsole (stdout and stdin)
  • ReadConsole (might block the thread, so depends on #3 & #20)

Low-level functions will require to implement an actual screen buffer, which is not needed yet

UI API design

For the begging, some API to get a frame buffer with desired resolution/pixel format & handle mouse and keyboard input. Should be enough to make HoMM 3 (which only uses a DirectDraw framebuffer and several offscreen DirectDraw surfaces).

If we were to implement the windowing, we might want to integrate more deeply with existing windowing systems. Or, for more portability, create our own windowing system, which will use this exact framebuffer as a target.

Implement callbacks to target code from native code

Need to implement:

  1. function pointer type projections & codegen for them
  2. a way to actually transfer execution back and forth between native and target code that will work nicely with selected threading model (see #3)

Should include a way for recompiled code/emulator to understand that the return is being done to the native code (probably by introducing a special return address)

Naming

Project name isn't cute enough - should rename to uwuin

Implement End-to-End testing

The idea is to have some EXE files that should be lifted, recompiled and emulated and to have some assertions about it's behavior. One variant may be "their output should be same under WINE and uwin", but this is not the only way to do this...

Need to give some thinking in it

Add source location information to the recompiled code

This is to ease debugging, because, as of now, when debugging, you can only know the location up to a basic block.
The location will (somehow) signify the original instruction address. Probably the filename should be path to the original module and line number should be the address.

Consider packaging dependencies to conan or other c++ dependency manager

What to look out for:

  • need custom repo (patches, custom build configurations and that stuff)
  • build for libnx with devkitpro (as one of targets)
  • ability to use a edit package without publishing it (to debug linked changes)

Also a good question: how to do CI with dependent PRs? How will the build system at CI time will get the source/binary?

Asset subsystem

Need to implement a generic way to bundle non-executable data with the program. Probably will need several back-ends for different platforms (put to data/other section on Linux, as the load is on demand; use romfs for libnx/Atmosphere)

What it can be used for:

  • embedding localization data (like encoding mapping tables or locale information)
  • embedding the target executable file, dlls and their resources (for the ease of distribution)
  • embedding the ICU data (if we will stick with it)
  • etc

Design & implement win32 thread message queue

In windows each thread has a message queue, which can be accessed with various win32 APIs (PostMessage, PostThreadMessage, GetMessage, PeekMessage, TranslateMessage, DispatchMessage and others).

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.