352 lines
14 KiB
Markdown
352 lines
14 KiB
Markdown
Dynarmic
|
|
========
|
|
|
|
[![Travis CI Build Status](https://api.travis-ci.org/MerryMage/dynarmic.svg?branch=master)](https://travis-ci.org/MerryMage/dynarmic/branches) [![Appveyor CI Build status](https://ci.appveyor.com/api/projects/status/maeiqr41rgm1innm/branch/master?svg=true)](https://ci.appveyor.com/project/MerryMage/dynarmic/branch/master)
|
|
|
|
A dynamic recompiler for ARM.
|
|
|
|
### Supported guest architectures
|
|
|
|
* ARMv6K
|
|
* 64-bit ARMv8
|
|
|
|
### Supported host architectures
|
|
|
|
* x86-64
|
|
|
|
There are no plans to support x86-32.
|
|
|
|
Alternatives to Dynarmic
|
|
------------------------
|
|
|
|
If you are looking at a recompiler which you can use with minimal effort to run ARM executables on non-native platforms, we would strongly recommend looking at qemu-user-static ([description of qemu-user-static](https://wiki.debian.org/QemuUserEmulation), [using qemu-user-static in combination with Docker to provide a complete emulated environment](https://github.com/multiarch/qemu-user-static)). Having a complete plug-and-play solution is out-of-scope of this project.
|
|
|
|
Here are some projects with the same goals as dynarmic:
|
|
|
|
* [ChocolArm64 from Ryujinx](https://github.com/Ryujinx/Ryujinx/tree/master/ChocolArm64) - ARMv8 recompiler on top of RyuJIT
|
|
* [Unicorn](https://www.unicorn-engine.org/) - Recompiling multi-architecture CPU emulator, based on QEMU
|
|
* [SkyEye](http://skyeye.sourceforge.net) - Cached interpreter for ARM
|
|
|
|
More general alternatives:
|
|
|
|
* [tARMac](https://davidsharp.com/tarmac/) - Tarmac's use of armlets was initial inspiration for us to use an intermediate representation
|
|
* [QEMU](https://www.qemu.org/) - Recompiling multi-architecture system emulator
|
|
* [VisUAL](https://salmanarif.bitbucket.io/visual/index.html) - Visual ARM UAL emulator intended for education
|
|
* A wide variety of other recompilers, interpreters and emulators can be found embedded in other projects, here are some we would recommend looking at:
|
|
* [firebird's recompiler](https://github.com/nspire-emus/firebird) - Takes more of a call-threaded approach to recompilation
|
|
* [higan's arm7tdmi emulator](https://gitlab.com/higan/higan/tree/master/higan/component/processor/arm7tdmi) - Very clean code-style
|
|
* [arm-js by ozaki-r](https://github.com/ozaki-r/arm-js) - Emulates ARMv7A and some peripherals of Versatile Express, in the browser
|
|
|
|
Disadvantages of Dynarmic
|
|
-------------------------
|
|
|
|
In the pursuit of speed, some behavior not commonly depended upon is elided. Therefore this emulator does not match spec.
|
|
|
|
Known examples:
|
|
|
|
* Only user-mode is emulated, there is no emulation of any other privilege levels.
|
|
* FPSR state is approximate.
|
|
* Misaligned loads/stores are not appropriately trapped in certain cases.
|
|
* Exclusive monitor behavior may not match any known physical processor.
|
|
|
|
As with most other hobby ARM emulation projects, no formal verification has been done. Use this code base at your own risk.
|
|
|
|
Documentation
|
|
-------------
|
|
|
|
Design documentation can be found at [docs/Design.md](docs/Design.md).
|
|
|
|
Plans
|
|
-----
|
|
|
|
### Near-term
|
|
|
|
* Complete ARMv8 support
|
|
|
|
### Medium-term
|
|
|
|
* Optimizations
|
|
|
|
### Long-term
|
|
|
|
* ARMv7A guest support
|
|
* ARMv5 guest support
|
|
* ARMv8 host support
|
|
|
|
Usage Example
|
|
-------------
|
|
|
|
The below is a minimal example. Bring-your-own memory system.
|
|
|
|
```cpp
|
|
#include <array>
|
|
#include <cstdint>
|
|
#include <cstdio>
|
|
#include <exception>
|
|
|
|
#include "dynarmic/interface/A32/a32.h"
|
|
#include "dynarmic/interface/A32/config.h"
|
|
|
|
using u8 = std::uint8_t;
|
|
using u16 = std::uint16_t;
|
|
using u32 = std::uint32_t;
|
|
using u64 = std::uint64_t;
|
|
|
|
class MyEnvironment final : public Dynarmic::A32::UserCallbacks {
|
|
public:
|
|
u64 ticks_left = 0;
|
|
std::array<u8, 2048> memory{};
|
|
|
|
u8 MemoryRead8(u32 vaddr) override {
|
|
if (vaddr >= memory.size()) {
|
|
return 0;
|
|
}
|
|
return memory[vaddr];
|
|
}
|
|
|
|
u16 MemoryRead16(u32 vaddr) override {
|
|
return u16(MemoryRead8(vaddr)) | u16(MemoryRead8(vaddr + 1)) << 8;
|
|
}
|
|
|
|
u32 MemoryRead32(u32 vaddr) override {
|
|
return u32(MemoryRead16(vaddr)) | u32(MemoryRead16(vaddr + 2)) << 16;
|
|
}
|
|
|
|
u64 MemoryRead64(u32 vaddr) override {
|
|
return u64(MemoryRead32(vaddr)) | u64(MemoryRead32(vaddr + 4)) << 32;
|
|
}
|
|
|
|
void MemoryWrite8(u32 vaddr, u8 value) override {
|
|
if (vaddr >= memory.size()) {
|
|
return;
|
|
}
|
|
memory[vaddr] = value;
|
|
}
|
|
|
|
void MemoryWrite16(u32 vaddr, u16 value) override {
|
|
MemoryWrite8(vaddr, u8(value));
|
|
MemoryWrite8(vaddr + 1, u8(value >> 8));
|
|
}
|
|
|
|
void MemoryWrite32(u32 vaddr, u32 value) override {
|
|
MemoryWrite16(vaddr, u16(value));
|
|
MemoryWrite16(vaddr + 2, u16(value >> 16));
|
|
}
|
|
|
|
void MemoryWrite64(u32 vaddr, u64 value) override {
|
|
MemoryWrite32(vaddr, u32(value));
|
|
MemoryWrite32(vaddr + 4, u32(value >> 32));
|
|
}
|
|
|
|
void InterpreterFallback(u32 pc, size_t num_instructions) override {
|
|
// This is never called in practice.
|
|
std::terminate();
|
|
}
|
|
|
|
void CallSVC(u32 swi) override {
|
|
// Do something.
|
|
}
|
|
|
|
void ExceptionRaised(u32 pc, Dynarmic::A32::Exception exception) override {
|
|
// Do something.
|
|
}
|
|
|
|
void AddTicks(u64 ticks) override {
|
|
if (ticks > ticks_left) {
|
|
ticks_left = 0;
|
|
return;
|
|
}
|
|
ticks_left -= ticks;
|
|
}
|
|
|
|
u64 GetTicksRemaining() override {
|
|
return ticks_left;
|
|
}
|
|
};
|
|
|
|
int main(int argc, char** argv) {
|
|
MyEnvironment env;
|
|
Dynarmic::A32::UserConfig user_config;
|
|
user_config.callbacks = &env;
|
|
Dynarmic::A32::Jit cpu{user_config};
|
|
|
|
// Execute at least 1 instruction.
|
|
// (Note: More than one instruction may be executed.)
|
|
env.ticks_left = 1;
|
|
|
|
// Write some code to memory.
|
|
env.MemoryWrite16(0, 0x0088); // lsls r0, r1, #2
|
|
env.MemoryWrite16(2, 0xE7FE); // b +#0 (infinite loop)
|
|
|
|
// Setup registers.
|
|
cpu.Regs()[0] = 1;
|
|
cpu.Regs()[1] = 2;
|
|
cpu.Regs()[15] = 0; // PC = 0
|
|
cpu.SetCpsr(0x00000030); // Thumb mode
|
|
|
|
// Execute!
|
|
cpu.Run();
|
|
|
|
// Here we would expect cpu.Regs()[0] == 8
|
|
printf("R0: %u\n", cpu.Regs()[0]);
|
|
|
|
return 0;
|
|
}
|
|
```
|
|
|
|
Legal
|
|
-----
|
|
|
|
dynarmic is under a 0BSD license. See LICENSE.txt for more details.
|
|
|
|
dynarmic uses several other libraries, whose licenses are included below:
|
|
|
|
### catch
|
|
|
|
```
|
|
Boost Software License - Version 1.0 - August 17th, 2003
|
|
|
|
Permission is hereby granted, free of charge, to any person or organization
|
|
obtaining a copy of the software and accompanying documentation covered by
|
|
this license (the "Software") to use, reproduce, display, distribute,
|
|
execute, and transmit the Software, and to prepare derivative works of the
|
|
Software, and to permit third-parties to whom the Software is furnished to
|
|
do so, all subject to the following:
|
|
|
|
The copyright notices in the Software and this entire statement, including
|
|
the above license grant, this restriction and the following disclaimer,
|
|
must be included in all copies of the Software, in whole or in part, and
|
|
all derivative works of the Software, unless such copies or derivative
|
|
works are solely in the form of machine-executable object code generated by
|
|
a source language processor.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT
|
|
SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE
|
|
FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE,
|
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
DEALINGS IN THE SOFTWARE.
|
|
```
|
|
|
|
### fmt
|
|
|
|
```
|
|
Copyright (c) 2012 - 2016, Victor Zverovich
|
|
|
|
All rights reserved.
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
modification, are permitted provided that the following conditions are met:
|
|
|
|
1. Redistributions of source code must retain the above copyright notice, this
|
|
list of conditions and the following disclaimer.
|
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
|
this list of conditions and the following disclaimer in the documentation
|
|
and/or other materials provided with the distribution.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
|
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
|
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
|
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
|
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
|
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
|
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
|
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
```
|
|
|
|
### mp
|
|
|
|
```
|
|
Copyright (C) 2017 MerryMage
|
|
|
|
Permission to use, copy, modify, and/or distribute this software for
|
|
any purpose with or without fee is hereby granted.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
|
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
|
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
|
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
|
|
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
|
|
OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
|
```
|
|
|
|
### robin-map
|
|
|
|
```
|
|
MIT License
|
|
|
|
Copyright (c) 2017 Thibaut Goetghebuer-Planchon <tessil@gmx.com>
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
in the Software without restriction, including without limitation the rights
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in all
|
|
copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
SOFTWARE.
|
|
```
|
|
|
|
### xbyak
|
|
|
|
```
|
|
Copyright (c) 2007 MITSUNARI Shigeo
|
|
All rights reserved.
|
|
|
|
Redistribution and use in source and binary forms, with or without
|
|
modification, are permitted provided that the following conditions are met:
|
|
|
|
Redistributions of source code must retain the above copyright notice, this
|
|
list of conditions and the following disclaimer.
|
|
Redistributions in binary form must reproduce the above copyright notice,
|
|
this list of conditions and the following disclaimer in the documentation
|
|
and/or other materials provided with the distribution.
|
|
Neither the name of the copyright owner nor the names of its contributors may
|
|
be used to endorse or promote products derived from this software without
|
|
specific prior written permission.
|
|
|
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
|
THE POSSIBILITY OF SUCH DAMAGE.
|
|
-----------------------------------------------------------------------------
|
|
ソースコード形式かバイナリ形式か、変更するかしないかを問わず、以下の条件を満た
|
|
す場合に限り、再頒布および使用が許可されます。
|
|
|
|
ソースコードを再頒布する場合、上記の著作権表示、本条件一覧、および下記免責条項
|
|
を含めること。
|
|
バイナリ形式で再頒布する場合、頒布物に付属のドキュメント等の資料に、上記の著作
|
|
権表示、本条件一覧、および下記免責条項を含めること。
|
|
書面による特別の許可なしに、本ソフトウェアから派生した製品の宣伝または販売促進
|
|
に、著作権者の名前またはコントリビューターの名前を使用してはならない。
|
|
本ソフトウェアは、著作権者およびコントリビューターによって「現状のまま」提供さ
|
|
れており、明示黙示を問わず、商業的な使用可能性、および特定の目的に対する適合性
|
|
に関する暗黙の保証も含め、またそれに限定されない、いかなる保証もありません。
|
|
著作権者もコントリビューターも、事由のいかんを問わず、 損害発生の原因いかんを
|
|
問わず、かつ責任の根拠が契約であるか厳格責任であるか(過失その他の)不法行為で
|
|
あるかを問わず、仮にそのような損害が発生する可能性を知らされていたとしても、
|
|
本ソフトウェアの使用によって発生した(代替品または代用サービスの調達、使用の
|
|
喪失、データの喪失、利益の喪失、業務の中断も含め、またそれに限定されない)直接
|
|
損害、間接損害、偶発的な損害、特別損害、懲罰的損害、または結果損害について、
|
|
一切責任を負わないものとします。
|
|
```
|