diff options
Diffstat (limited to 'docs/dynarmic')
| -rw-r--r-- | docs/dynarmic/Design.md | 84 | ||||
| -rw-r--r-- | docs/dynarmic/README.md | 323 |
2 files changed, 51 insertions, 356 deletions
diff --git a/docs/dynarmic/Design.md b/docs/dynarmic/Design.md index 020cfd65bd..77272e2220 100644 --- a/docs/dynarmic/Design.md +++ b/docs/dynarmic/Design.md @@ -1,44 +1,44 @@ # Dynarmic Design Documentation -Dynarmic is a dynamic recompiler for the ARMv6K architecture. Future plans for dynarmic include +Dynarmic is a dynamic recompiler for the ARMv6K architecture. Future plans for Dynarmic include support for other versions of the ARM architecture, having a interpreter mode, and adding support for other architectures. Users of this library interact with it primarily through the interface provided in -[`src/dynarmic/interface`](../src/dynarmic/interface). Users specify how dynarmic's CPU core interacts with +[`src/dynarmic/interface`](../../src/dynarmic/src/dynarmic/interface). Users specify how Dynarmic's CPU core interacts with the rest of their system providing an implementation of the relevant `UserCallbacks` interface. Users setup the CPU state using member functions of `Jit`, then call `Jit::Execute` to start CPU execution. The callbacks defined on `UserCallbacks` may be called from dynamically generated code, so users of the library should not depend on the stack being in a walkable state for unwinding. -* A32: [`Jit`](../src/dynarmic/interface/A32/a32.h), [`UserCallbacks`](../src/dynarmic/interface/A32/config.h) -* A64: [`Jit`](../src/dynarmic/interface/A64/a64.h), [`UserCallbacks`](../src/dynarmic/interface/A64/config.h) +* A32: [`Jit`](../../src/dynarmic/src/dynarmic/interface/A32/a32.h), [`UserCallbacks`](../../src/dynarmic/src/dynarmic/interface/A32/config.h) +* A64: [`Jit`](../../src/dynarmic/src/dynarmic/interface/A64/a64.h), [`UserCallbacks`](../../src/dynarmic/src/dynarmic/interface/A64/config.h) Dynarmic reads instructions from memory by calling `UserCallbacks::MemoryReadCode`. These instructions then pass through several stages: 1. Decoding (Identifying what type of instruction it is and breaking it up into fields) 2. Translation (Generation of high-level IR from the instruction) -3. Optimization (Eliminiation of redundant microinstructions, other speed improvements) +3. Optimization (Elimination of redundant microinstructions, other speed improvements) 4. Emission (Generation of host-executable code into memory) 5. Execution (Host CPU jumps to the start of emitted code and runs it) Using the A32 frontend with the x64 backend as an example: * Decoding is done by [double dispatch](https://en.wikipedia.org/wiki/Visitor_pattern) in - [`src/frontend/A32/decoder/{arm.h,thumb16.h,thumb32.h}`](../src/dynarmic/frontend/A32/decoder/). -* Translation is done by the visitors in [`src/dynarmic/frontend/A32/translate/translate_{arm,thumb}.cpp`](../src/dynarmic/frontend/A32/translate/). - The function [`Translate`](../src/dynarmic/frontend/A32/translate/translate.h) takes a starting memory location, + [`src/frontend/A32/decoder/{arm.h,thumb16.h,thumb32.h}`](../../src/dynarmic/src/dynarmic/frontend/A32/decoder/). +* Translation is done by the visitors in [`src/dynarmic/frontend/A32/translate/translate_{arm,thumb}.cpp`](../../src/dynarmic/src/dynarmic/frontend/A32/translate/). + The function [`Translate`](../../src/dynarmic/src/dynarmic/frontend/A32/translate/a32_translate.cpp) takes a starting memory location, some CPU state, and memory reader callback and returns a basic block of IR. -* The IR can be found under [`src/frontend/ir/`](../src/dynarmic/ir/). -* Optimizations can be found under [`src/ir_opt/`](../src/dynarmic/ir/opt/). -* Emission is done by `EmitX64` which can be found in [`src/dynarmic/backend/x64/emit_x64.{h,cpp}`](../src/dynarmic/backend/x64/). -* Execution is performed by calling `BlockOfCode::RunCode` in [`src/dynarmic/backend/x64/block_of_code.{h,cpp}`](../src/dynarmic/backend/x64/). +* The IR can be found under [`src/frontend/ir/`](../../src/dynarmic/src/dynarmic/ir/). +* Optimizations can be found under [`src/ir/opt_passes.cpp`](../../src/dynarmic/src/dynarmic/ir/opt_passes.cpp). +* Emission is done by `EmitX64` which can be found in [`src/dynarmic/backend/x64/emit_x64.{h,cpp}`](../../src/dynarmic/src/dynarmic/backend/x64/). +* Execution is performed by calling `BlockOfCode::RunCode` in [`src/dynarmic/backend/x64/block_of_code.{h,cpp}`](../../src/dynarmic/src/dynarmic/backend/x64/). ## Decoder The decoder is a double dispatch decoder. Each instruction is represented by a line in the relevant -instruction table. Here is an example line from [`arm.h`](../src/dynarmic/frontend/A32/decoder/arm.h): +instruction table. Here is an example line from [`arm.h`](../../src/dynarmic/src/dynarmic/frontend/A32/decoder/arm.h): INST(&V::arm_ADC_imm, "ADC (imm)", "cccc0010101Snnnnddddrrrrvvvvvvvv") @@ -61,7 +61,7 @@ error results. ## Translator The translator is a visitor that uses the decoder to decode instructions. The translator generates IR code with the -help of the [`IREmitter` class](../src/dynarmic/ir/ir_emitter.h). An example of a translation function follows: +help of the [`IREmitter` class](../../src/dynarmic/src/dynarmic/ir/ir_emitter.h). An example of a translation function follows: bool ArmTranslatorVisitor::arm_ADC_imm(Cond cond, bool S, Reg n, Reg d, int rotate, Imm8 imm8) { u32 imm32 = ArmExpandImm(rotate, imm8); @@ -107,7 +107,7 @@ function analyser in the medium-term future. Dynarmic's intermediate representation is typed. Each microinstruction may take zero or more arguments and may return zero or more arguments. A subset of the microinstructions available is documented below. -A complete list of microinstructions can be found in [src/dynarmic/ir/opcodes.inc](../src/dynarmic/ir/opcodes.inc). +A complete list of microinstructions can be found in [src/dynarmic/ir/opcodes.inc](../../src/dynarmic/src/dynarmic/ir/opcodes.inc). The below lists some commonly used microinstructions. @@ -273,7 +273,7 @@ Exclusive OR (i.e.: XOR) ### Callback: {Read,Write}Memory{8,16,32,64} -```c++ +```cpp <u8> ReadMemory8(<u32> vaddr) <u8> ReadMemory16(<u32> vaddr) <u8> ReadMemory32(<u32> vaddr) @@ -288,7 +288,7 @@ Memory access. ### Terminal: ReturnToDispatch -```c++ +```cpp SetTerm(IR::Term::ReturnToDispatch{}) ``` @@ -297,7 +297,7 @@ The dispatcher will use the value in R15 to determine what comes next. ### Terminal: LinkBlock -```c++ +```cpp SetTerm(IR::Term::LinkBlock{next}) ``` @@ -307,7 +307,7 @@ dispatcher, which will return control to the host. ### Terminal: LinkBlockFast -```c++ +```cpp SetTerm(IR::Term::LinkBlockFast{next}) ``` @@ -316,7 +316,7 @@ This promises guarantees that must be held at runtime - i.e that the program won ### Terminal: PopRSBHint -```c++ +```cpp SetTerm(IR::Term::PopRSBHint{}) ``` @@ -328,7 +328,7 @@ this optimization or doesn't have a RSB may choose to implement this exactly as ### Terminal: If -```c++ +```cpp SetTerm(IR::Term::If{cond, term_then, term_else}) ``` @@ -366,7 +366,7 @@ Do NEVER modify `%r15`, we must make it clear that this register is "immutable" ### `Scratch` -```c++ +```cpp Xbyak::Reg64 ScratchGpr(HostLocList desired_locations = any_gpr); Xbyak::Xmm ScratchXmm(HostLocList desired_locations = any_xmm); ``` @@ -375,7 +375,7 @@ At runtime, allocate one of the registers in `desired_locations`. You are free t ### Pure `Use` -```c++ +```cpp Xbyak::Reg64 UseGpr(Argument& arg); Xbyak::Xmm UseXmm(Argument& arg); OpArg UseOpArg(Argument& arg); @@ -391,7 +391,7 @@ This register **must not** have it's value changed. ### `UseScratch` -```c++ +```cpp Xbyak::Reg64 UseScratchGpr(Argument& arg); Xbyak::Xmm UseScratchXmm(Argument& arg); void UseScratch(Argument& arg, HostLoc host_loc); @@ -409,7 +409,7 @@ You are free to modify the value in the register. The register is discarded at t A `Define` is the defintion of a value. This is the only time when a value may be set. -```c++ +```cpp void DefineValue(IR::Inst* inst, const Xbyak::Reg& reg); ``` @@ -420,7 +420,7 @@ value to the specified register `reg`. Adding a `Define` to an existing value. -```c++ +```cpp void DefineValue(IR::Inst* inst, Argument& arg); ``` @@ -458,7 +458,7 @@ One complication dynarmic has is that a compiled block is not uniquely identifia the PC alone, but bits in the FPSCR and CPSR are also relevant. We resolve this by computing a 64-bit `UniqueHash` that is guaranteed to uniquely identify a block. -```c++ +```cpp u64 LocationDescriptor::UniqueHash() const { // This value MUST BE UNIQUE. // This calculation has to match up with EmitX64::EmitTerminalPopRSBHint @@ -482,18 +482,18 @@ point. Each element in `rsb_location_descriptors` is a `UniqueHash` and they each correspond to an element in `rsb_codeptrs`. `rsb_codeptrs` contains the host addresses for the corresponding the compiled blocks. -`RSBSize` was chosen by performance testing. Note that this is bigger than the +`RSB_SIZE` was chosen by performance testing. Note that this is bigger than the size of the real RSB in hardware (which has 3 entries). Larger RSBs than 8 showed degraded performance. -```c++ +```cpp struct JitState { // ... - static constexpr size_t RSBSize = 8; // MUST be a power of 2. + static constexpr size_t RSB_SIZE = 8; // MUST be a power of 2. u32 rsb_ptr = 0; - std::array<u64, RSBSize> rsb_location_descriptors; - std::array<u64, RSBSize> rsb_codeptrs; + std::array<u64, RSB_SIZE> rsb_location_descriptors; + std::array<u64, RSB_SIZE> rsb_codeptrs; void ResetRSB(); // ... @@ -505,7 +505,7 @@ struct JitState { We insert our prediction at the insertion point iff the RSB doesn't already contain a prediction with the same `UniqueHash`. -```c++ +```cpp void EmitX64::EmitPushRSB(IR::Block&, IR::Inst* inst) { using namespace Xbyak::util; @@ -521,7 +521,7 @@ void EmitX64::EmitPushRSB(IR::Block&, IR::Inst* inst) { code->mov(index_reg, dword[code.ABI_JIT_PTR + offsetof(JitState, rsb_ptr)]); code->add(index_reg, 1); - code->and_(index_reg, u32(JitState::RSBSize - 1)); + code->and_(index_reg, u32(JitState::RSB_SIZE - 1)); code->mov(loc_desc_reg, u64(imm64)); CodePtr patch_location = code->getCurr<CodePtr>(); @@ -530,7 +530,7 @@ void EmitX64::EmitPushRSB(IR::Block&, IR::Inst* inst) { code->EnsurePatchLocationSize(patch_location, 10); Xbyak::Label label; - for (size_t i = 0; i < JitState::RSBSize; ++i) { + for (size_t i = 0; i < JitState::RSB_SIZE; ++i) { code->cmp(loc_desc_reg, qword[code.ABI_JIT_PTR + offsetof(JitState, rsb_location_descriptors) + i * sizeof(u64)]); code->je(label, code->T_SHORT); } @@ -544,12 +544,12 @@ void EmitX64::EmitPushRSB(IR::Block&, IR::Inst* inst) { In pseudocode: -```c++ - for (i := 0 .. RSBSize-1) +```cpp + for (i := 0 .. RSB_SIZE-1) if (rsb_location_descriptors[i] == imm64) goto label; rsb_ptr++; - rsb_ptr %= RSBSize; + rsb_ptr %= RSB_SIZE; rsb_location_desciptors[rsb_ptr] = imm64; //< The UniqueHash rsb_codeptr[rsb_ptr] = /* codeptr corresponding to the UniqueHash */; label: @@ -559,7 +559,7 @@ label: To check if a predicition is in the RSB, we linearly scan the RSB. -```c++ +```cpp void EmitX64::EmitTerminalPopRSBHint(IR::Term::PopRSBHint, IR::LocationDescriptor initial_location) { using namespace Xbyak::util; @@ -571,7 +571,7 @@ void EmitX64::EmitTerminalPopRSBHint(IR::Term::PopRSBHint, IR::LocationDescripto code->or_(rbx, rcx); code->mov(rax, u64(code->GetReturnFromRunCodeAddress())); - for (size_t i = 0; i < JitState::RSBSize; ++i) { + for (size_t i = 0; i < JitState::RSB_SIZE; ++i) { code->cmp(rbx, qword[code.ABI_JIT_PTR + offsetof(JitState, rsb_location_descriptors) + i * sizeof(u64)]); code->cmove(rax, qword[code.ABI_JIT_PTR + offsetof(JitState, rsb_codeptrs) + i * sizeof(u64)]); } @@ -582,10 +582,10 @@ void EmitX64::EmitTerminalPopRSBHint(IR::Term::PopRSBHint, IR::LocationDescripto In pseudocode: -```c++ +```cpp rbx := ComputeUniqueHash() rax := ReturnToDispatch -for (i := 0 .. RSBSize-1) +for (i := 0 .. RSB_SIZE-1) if (rbx == rsb_location_descriptors[i]) rax = rsb_codeptrs[i] goto rax diff --git a/docs/dynarmic/README.md b/docs/dynarmic/README.md index 376e1f6b37..0fa893d550 100644 --- a/docs/dynarmic/README.md +++ b/docs/dynarmic/README.md @@ -3,175 +3,20 @@ Dynarmic A dynamic recompiler for ARM. -Highlight features: +*Note that an adversarial guest program [can determine if it's being ran under Dynarmic](#disadvantages-of-dynarmic). Preventing this is not a goal of this project.* -- Fast dynamic binary translation via Just-in-Time compilation -- Clean API -- Implemented in modern C++20 -- Hooks exposed for easy code instrumentation -- Code injection support for very fine-grained instrumentation -- Support for unusual address space setups (bring-your-own memory system) -- Native support for most popular operating systems (Windows, macOS, Linux, FreeBSD, OpenBSD, NetBSD, Android) +Cortex-A57 (32 and 64 bit) is the emulated guest target. See [ArchVersion](../../src/dynarmic/src/dynarmic/interface/A32/arch_version.h). -*Please note that an adversarial guest program [can determine if it is being run under dynarmic](#disadvantages-of-dynarmic). Preventing this is not a goal of this project.* +The only supported host architectures are x86-64, and AArch64. There are no plans to support any 32-bit architectures. -### Supported guest architectures - -* v3 -* v4 -* v4T -* v5TE -* v6K -* v6T2 -* v7A -* 32-bit v8 -* 64-bit v8 - -You can specify the specific guest version using [ArchVersion](src/dynarmic/interface/A32/arch_version.h). - -There are no plans to support v1 or v2. - -### Supported host architectures - -* x86-64 -* AArch64 - -There are no plans to support any 32-bit architecture. - -Important API Changes in v6.x Series ------------------------------------- - -* **v6.7.0** - * To support use cases where one wants to have the guest to have the same address space as the host, `nullptr` is now a valid value for `fastmem_pointer`. - **This change is not backwards-compatible.** If you were previously using `nullptr` to represent an invalid fastmem arena, you will now have to use `std::nullopt`. - - -Documentation -------------- +See [an example usage](../../src/dynarmic/tests/print_info.cpp). Design documentation can be found at [./Design.md](./Design.md). - -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 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; -} -``` - Alternatives to Dynarmic ------------------------ -Here are some projects with the same goals as dynarmic: +Here are some projects with the same goals as Dynarmic: * [Unicorn](https://www.unicorn-engine.org/) - Recompiling multi-architecture CPU emulator, based on QEMU * [SkyEye](http://skyeye.sourceforge.net) - Cached interpreter for ARM @@ -189,8 +34,8 @@ More general alternatives: Disadvantages of Dynarmic ------------------------- -In the pursuit of speed, some behavior not commonly depended upon is elided. Therefore this emulator does not match spec. -Please note that this would mean that a guest application can easily determine if it is being run under instrumentation. +In the pursuit of speed, some behavior not commonly depended upon is elided. Hence this emulator doesn't match spec. +Note that this would mean that a guest application can easily determine if it's being ran under instrumentation. Known examples: @@ -205,156 +50,6 @@ Use this code base at your own risk. Legal ----- -dynarmic is under a 0BSD license. See LICENSE.txt for more details. - -dynarmic uses several other libraries, whose licenses are included below: - -### biscuit - -``` -Copyright 2021 Lioncash/Lioncache - -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. -``` - -### 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. -``` - -### mcl & oaknut - -``` -MIT License - -Copyright (c) 2022 merryhime <https://mary.rs> - -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. ------------------------------------------------------------------------------ -ソースコード形式かバイナリ形式か、変更するかしないかを問わず、以下の条件を満た -す場合に限り、再頒布および使用が許可されます。 +Dynarmic is under a GPLv3 license, check the relevant file headers for more information. -ソースコードを再頒布する場合、上記の著作権表示、本条件一覧、および下記免責条項 -を含めること。 -バイナリ形式で再頒布する場合、頒布物に付属のドキュメント等の資料に、上記の著作 -権表示、本条件一覧、および下記免責条項を含めること。 -書面による特別の許可なしに、本ソフトウェアから派生した製品の宣伝または販売促進 -に、著作権者の名前またはコントリビューターの名前を使用してはならない。 -本ソフトウェアは、著作権者およびコントリビューターによって「現状のまま」提供さ -れており、明示黙示を問わず、商業的な使用可能性、および特定の目的に対する適合性 -に関する暗黙の保証も含め、またそれに限定されない、いかなる保証もありません。 -著作権者もコントリビューターも、事由のいかんを問わず、 損害発生の原因いかんを -問わず、かつ責任の根拠が契約であるか厳格責任であるか(過失その他の)不法行為で -あるかを問わず、仮にそのような損害が発生する可能性を知らされていたとしても、 -本ソフトウェアの使用によって発生した(代替品または代用サービスの調達、使用の -喪失、データの喪失、利益の喪失、業務の中断も含め、またそれに限定されない)直接 -損害、間接損害、偶発的な損害、特別損害、懲罰的損害、または結果損害について、 -一切責任を負わないものとします。 -``` +Dynarmic uses several open-source libraries, whose licenses are included inside thereof. |
