From 1d12e8778bde982b6456efaabefa239d48d95096 Mon Sep 17 00:00:00 2001 From: TSR Berry <20988865+TSRBerry@users.noreply.github.com> Date: Mon, 31 Oct 2022 22:56:44 +0100 Subject: [PATCH 01/43] bindings: Rename dotnet project to UnicornEngine Add a few more properties to prepare a nuget package --- bindings/const_generator.py | 4 ++-- bindings/dotnet/UnicornDotNet.sln | 2 +- .../Binding/BindingFactory.fs | 2 +- .../Binding/IBinding.fs | 2 +- .../Binding/MockBinding.fs | 2 +- .../Binding/NativeBinding.fs | 2 +- .../{UnicornManaged => UnicornEngine}/Const/Arm.fs | 2 +- .../{UnicornManaged => UnicornEngine}/Const/Arm64.fs | 2 +- .../Const/Common.fs | 2 +- .../{UnicornManaged => UnicornEngine}/Const/M68k.fs | 2 +- .../{UnicornManaged => UnicornEngine}/Const/Mips.fs | 2 +- .../{UnicornManaged => UnicornEngine}/Const/Ppc.fs | 2 +- .../{UnicornManaged => UnicornEngine}/Const/Riscv.fs | 2 +- .../{UnicornManaged => UnicornEngine}/Const/S390x.fs | 2 +- .../{UnicornManaged => UnicornEngine}/Const/Sparc.fs | 2 +- .../Const/TriCore.fs | 2 +- .../{UnicornManaged => UnicornEngine}/Const/X86.fs | 2 +- .../ConvertUtility.fs | 2 +- .../InternalHooks.fs | 2 +- .../{UnicornManaged => UnicornEngine}/Unicorn.fs | 6 +++--- .../UnicornEngine.fsproj} | 12 +++++++++--- .../UnicornEngineException.fs | 2 +- bindings/dotnet/UnicornSamples/ShellcodeSample.cs | 4 ++-- bindings/dotnet/UnicornSamples/UnicornSamples.csproj | 4 ++-- bindings/dotnet/UnicornSamples/X86Sample32.cs | 4 ++-- 25 files changed, 39 insertions(+), 33 deletions(-) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/Binding/BindingFactory.fs (84%) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/Binding/IBinding.fs (97%) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/Binding/MockBinding.fs (98%) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/Binding/NativeBinding.fs (99%) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/Const/Arm.fs (99%) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/Const/Arm64.fs (99%) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/Const/Common.fs (99%) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/Const/M68k.fs (97%) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/Const/Mips.fs (99%) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/Const/Ppc.fs (99%) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/Const/Riscv.fs (99%) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/Const/S390x.fs (99%) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/Const/Sparc.fs (99%) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/Const/TriCore.fs (99%) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/Const/X86.fs (99%) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/ConvertUtility.fs (94%) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/InternalHooks.fs (98%) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/Unicorn.fs (99%) rename bindings/dotnet/{UnicornManaged/UnicornManaged.fsproj => UnicornEngine/UnicornEngine.fsproj} (79%) rename bindings/dotnet/{UnicornManaged => UnicornEngine}/UnicornEngineException.fs (83%) diff --git a/bindings/const_generator.py b/bindings/const_generator.py index 2a74c864..6d529630 100644 --- a/bindings/const_generator.py +++ b/bindings/const_generator.py @@ -90,10 +90,10 @@ template = { 'comment_close': '', }, 'dotnet': { - 'header': "// For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT\n\nnamespace UnicornManaged.Const\n\nopen System\n\n[]\nmodule %s =\n", + 'header': "// For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT\n\nnamespace UnicornEngine.Const\n\nopen System\n\n[]\nmodule %s =\n", 'footer': "\n", 'line_format': ' let UC_%s = %s\n', - 'out_file': os.path.join('dotnet', 'UnicornManaged', 'Const', '%s.fs'), + 'out_file': os.path.join('dotnet', 'UnicornEngine', 'Const', '%s.fs'), # prefixes for constant filenames of all archs - case sensitive 'arm.h': 'Arm', 'arm64.h': 'Arm64', diff --git a/bindings/dotnet/UnicornDotNet.sln b/bindings/dotnet/UnicornDotNet.sln index 90aa5b60..abe168e9 100644 --- a/bindings/dotnet/UnicornDotNet.sln +++ b/bindings/dotnet/UnicornDotNet.sln @@ -5,7 +5,7 @@ VisualStudioVersion = 14.0.23107.0 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UnicornSamples", "UnicornSamples\UnicornSamples.csproj", "{B80B5987-1E24-4309-8BF9-C4F91270F21C}" EndProject -Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "UnicornManaged", "UnicornManaged\UnicornManaged.fsproj", "{0C21F1C1-2725-4A46-9022-1905F85822A5}" +Project("{F2A71F9B-5D33-465A-A702-920D77279786}") = "UnicornEngine", "UnicornEngine\UnicornEngine.fsproj", "{0C21F1C1-2725-4A46-9022-1905F85822A5}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/bindings/dotnet/UnicornManaged/Binding/BindingFactory.fs b/bindings/dotnet/UnicornEngine/Binding/BindingFactory.fs similarity index 84% rename from bindings/dotnet/UnicornManaged/Binding/BindingFactory.fs rename to bindings/dotnet/UnicornEngine/Binding/BindingFactory.fs index 6ea0b183..30c7f821 100644 --- a/bindings/dotnet/UnicornManaged/Binding/BindingFactory.fs +++ b/bindings/dotnet/UnicornEngine/Binding/BindingFactory.fs @@ -1,4 +1,4 @@ -namespace UnicornManaged.Binding +namespace UnicornEngine.Binding module BindingFactory = diff --git a/bindings/dotnet/UnicornManaged/Binding/IBinding.fs b/bindings/dotnet/UnicornEngine/Binding/IBinding.fs similarity index 97% rename from bindings/dotnet/UnicornManaged/Binding/IBinding.fs rename to bindings/dotnet/UnicornEngine/Binding/IBinding.fs index 7ef6d279..b6c3edc0 100644 --- a/bindings/dotnet/UnicornManaged/Binding/IBinding.fs +++ b/bindings/dotnet/UnicornEngine/Binding/IBinding.fs @@ -1,4 +1,4 @@ -namespace UnicornManaged.Binding +namespace UnicornEngine.Binding open System diff --git a/bindings/dotnet/UnicornManaged/Binding/MockBinding.fs b/bindings/dotnet/UnicornEngine/Binding/MockBinding.fs similarity index 98% rename from bindings/dotnet/UnicornManaged/Binding/MockBinding.fs rename to bindings/dotnet/UnicornEngine/Binding/MockBinding.fs index 7b99c8e5..3eeefe89 100644 --- a/bindings/dotnet/UnicornManaged/Binding/MockBinding.fs +++ b/bindings/dotnet/UnicornEngine/Binding/MockBinding.fs @@ -1,4 +1,4 @@ -namespace UnicornManaged.Binding +namespace UnicornEngine.Binding open System diff --git a/bindings/dotnet/UnicornManaged/Binding/NativeBinding.fs b/bindings/dotnet/UnicornEngine/Binding/NativeBinding.fs similarity index 99% rename from bindings/dotnet/UnicornManaged/Binding/NativeBinding.fs rename to bindings/dotnet/UnicornEngine/Binding/NativeBinding.fs index 6be7b2f3..efaccc48 100644 --- a/bindings/dotnet/UnicornManaged/Binding/NativeBinding.fs +++ b/bindings/dotnet/UnicornEngine/Binding/NativeBinding.fs @@ -1,4 +1,4 @@ -namespace UnicornManaged.Binding +namespace UnicornEngine.Binding open System open System.Runtime.InteropServices diff --git a/bindings/dotnet/UnicornManaged/Const/Arm.fs b/bindings/dotnet/UnicornEngine/Const/Arm.fs similarity index 99% rename from bindings/dotnet/UnicornManaged/Const/Arm.fs rename to bindings/dotnet/UnicornEngine/Const/Arm.fs index 08766baf..8a275261 100644 --- a/bindings/dotnet/UnicornManaged/Const/Arm.fs +++ b/bindings/dotnet/UnicornEngine/Const/Arm.fs @@ -1,6 +1,6 @@ // For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT -namespace UnicornManaged.Const +namespace UnicornEngine.Const open System diff --git a/bindings/dotnet/UnicornManaged/Const/Arm64.fs b/bindings/dotnet/UnicornEngine/Const/Arm64.fs similarity index 99% rename from bindings/dotnet/UnicornManaged/Const/Arm64.fs rename to bindings/dotnet/UnicornEngine/Const/Arm64.fs index 4c509d03..9e9878a7 100644 --- a/bindings/dotnet/UnicornManaged/Const/Arm64.fs +++ b/bindings/dotnet/UnicornEngine/Const/Arm64.fs @@ -1,6 +1,6 @@ // For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT -namespace UnicornManaged.Const +namespace UnicornEngine.Const open System diff --git a/bindings/dotnet/UnicornManaged/Const/Common.fs b/bindings/dotnet/UnicornEngine/Const/Common.fs similarity index 99% rename from bindings/dotnet/UnicornManaged/Const/Common.fs rename to bindings/dotnet/UnicornEngine/Const/Common.fs index 72b5cb3a..73f9663c 100644 --- a/bindings/dotnet/UnicornManaged/Const/Common.fs +++ b/bindings/dotnet/UnicornEngine/Const/Common.fs @@ -1,6 +1,6 @@ // For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT -namespace UnicornManaged.Const +namespace UnicornEngine.Const open System diff --git a/bindings/dotnet/UnicornManaged/Const/M68k.fs b/bindings/dotnet/UnicornEngine/Const/M68k.fs similarity index 97% rename from bindings/dotnet/UnicornManaged/Const/M68k.fs rename to bindings/dotnet/UnicornEngine/Const/M68k.fs index b9189d2d..768bc12b 100644 --- a/bindings/dotnet/UnicornManaged/Const/M68k.fs +++ b/bindings/dotnet/UnicornEngine/Const/M68k.fs @@ -1,6 +1,6 @@ // For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT -namespace UnicornManaged.Const +namespace UnicornEngine.Const open System diff --git a/bindings/dotnet/UnicornManaged/Const/Mips.fs b/bindings/dotnet/UnicornEngine/Const/Mips.fs similarity index 99% rename from bindings/dotnet/UnicornManaged/Const/Mips.fs rename to bindings/dotnet/UnicornEngine/Const/Mips.fs index 7f85a0cf..d4818783 100644 --- a/bindings/dotnet/UnicornManaged/Const/Mips.fs +++ b/bindings/dotnet/UnicornEngine/Const/Mips.fs @@ -1,6 +1,6 @@ // For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT -namespace UnicornManaged.Const +namespace UnicornEngine.Const open System diff --git a/bindings/dotnet/UnicornManaged/Const/Ppc.fs b/bindings/dotnet/UnicornEngine/Const/Ppc.fs similarity index 99% rename from bindings/dotnet/UnicornManaged/Const/Ppc.fs rename to bindings/dotnet/UnicornEngine/Const/Ppc.fs index 1727c157..54a18b3b 100644 --- a/bindings/dotnet/UnicornManaged/Const/Ppc.fs +++ b/bindings/dotnet/UnicornEngine/Const/Ppc.fs @@ -1,6 +1,6 @@ // For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT -namespace UnicornManaged.Const +namespace UnicornEngine.Const open System diff --git a/bindings/dotnet/UnicornManaged/Const/Riscv.fs b/bindings/dotnet/UnicornEngine/Const/Riscv.fs similarity index 99% rename from bindings/dotnet/UnicornManaged/Const/Riscv.fs rename to bindings/dotnet/UnicornEngine/Const/Riscv.fs index bf578024..fe61ec2c 100644 --- a/bindings/dotnet/UnicornManaged/Const/Riscv.fs +++ b/bindings/dotnet/UnicornEngine/Const/Riscv.fs @@ -1,6 +1,6 @@ // For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT -namespace UnicornManaged.Const +namespace UnicornEngine.Const open System diff --git a/bindings/dotnet/UnicornManaged/Const/S390x.fs b/bindings/dotnet/UnicornEngine/Const/S390x.fs similarity index 99% rename from bindings/dotnet/UnicornManaged/Const/S390x.fs rename to bindings/dotnet/UnicornEngine/Const/S390x.fs index 97f7ec4b..c4bd76e6 100644 --- a/bindings/dotnet/UnicornManaged/Const/S390x.fs +++ b/bindings/dotnet/UnicornEngine/Const/S390x.fs @@ -1,6 +1,6 @@ // For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT -namespace UnicornManaged.Const +namespace UnicornEngine.Const open System diff --git a/bindings/dotnet/UnicornManaged/Const/Sparc.fs b/bindings/dotnet/UnicornEngine/Const/Sparc.fs similarity index 99% rename from bindings/dotnet/UnicornManaged/Const/Sparc.fs rename to bindings/dotnet/UnicornEngine/Const/Sparc.fs index 8eb8cc23..8350af5c 100644 --- a/bindings/dotnet/UnicornManaged/Const/Sparc.fs +++ b/bindings/dotnet/UnicornEngine/Const/Sparc.fs @@ -1,6 +1,6 @@ // For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT -namespace UnicornManaged.Const +namespace UnicornEngine.Const open System diff --git a/bindings/dotnet/UnicornManaged/Const/TriCore.fs b/bindings/dotnet/UnicornEngine/Const/TriCore.fs similarity index 99% rename from bindings/dotnet/UnicornManaged/Const/TriCore.fs rename to bindings/dotnet/UnicornEngine/Const/TriCore.fs index 0c82fb97..b2c78e2e 100644 --- a/bindings/dotnet/UnicornManaged/Const/TriCore.fs +++ b/bindings/dotnet/UnicornEngine/Const/TriCore.fs @@ -1,6 +1,6 @@ // For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT -namespace UnicornManaged.Const +namespace UnicornEngine.Const open System diff --git a/bindings/dotnet/UnicornManaged/Const/X86.fs b/bindings/dotnet/UnicornEngine/Const/X86.fs similarity index 99% rename from bindings/dotnet/UnicornManaged/Const/X86.fs rename to bindings/dotnet/UnicornEngine/Const/X86.fs index 8d2fd5b3..5e115b9e 100644 --- a/bindings/dotnet/UnicornManaged/Const/X86.fs +++ b/bindings/dotnet/UnicornEngine/Const/X86.fs @@ -1,6 +1,6 @@ // For Unicorn Engine. AUTO-GENERATED FILE, DO NOT EDIT -namespace UnicornManaged.Const +namespace UnicornEngine.Const open System diff --git a/bindings/dotnet/UnicornManaged/ConvertUtility.fs b/bindings/dotnet/UnicornEngine/ConvertUtility.fs similarity index 94% rename from bindings/dotnet/UnicornManaged/ConvertUtility.fs rename to bindings/dotnet/UnicornEngine/ConvertUtility.fs index 5e455bf7..a453c861 100644 --- a/bindings/dotnet/UnicornManaged/ConvertUtility.fs +++ b/bindings/dotnet/UnicornEngine/ConvertUtility.fs @@ -1,4 +1,4 @@ -namespace UnicornManaged +namespace UnicornEngine open System diff --git a/bindings/dotnet/UnicornManaged/InternalHooks.fs b/bindings/dotnet/UnicornEngine/InternalHooks.fs similarity index 98% rename from bindings/dotnet/UnicornManaged/InternalHooks.fs rename to bindings/dotnet/UnicornEngine/InternalHooks.fs index 36cfc3ce..d9e87954 100644 --- a/bindings/dotnet/UnicornManaged/InternalHooks.fs +++ b/bindings/dotnet/UnicornEngine/InternalHooks.fs @@ -1,4 +1,4 @@ -namespace UnicornManaged +namespace UnicornEngine open System open System.Runtime.InteropServices diff --git a/bindings/dotnet/UnicornManaged/Unicorn.fs b/bindings/dotnet/UnicornEngine/Unicorn.fs similarity index 99% rename from bindings/dotnet/UnicornManaged/Unicorn.fs rename to bindings/dotnet/UnicornEngine/Unicorn.fs index 31decbcd..7d401300 100644 --- a/bindings/dotnet/UnicornManaged/Unicorn.fs +++ b/bindings/dotnet/UnicornEngine/Unicorn.fs @@ -1,11 +1,11 @@ -namespace UnicornManaged +namespace UnicornEngine open System open System.Collections.Generic open System.Runtime.InteropServices open System.Linq -open UnicornManaged.Const -open UnicornManaged.Binding +open UnicornEngine.Const +open UnicornEngine.Binding // exported hooks type CodeHook = delegate of Unicorn * Int64 * Int32 * Object -> unit diff --git a/bindings/dotnet/UnicornManaged/UnicornManaged.fsproj b/bindings/dotnet/UnicornEngine/UnicornEngine.fsproj similarity index 79% rename from bindings/dotnet/UnicornManaged/UnicornManaged.fsproj rename to bindings/dotnet/UnicornEngine/UnicornEngine.fsproj index 1a66562a..c117557c 100644 --- a/bindings/dotnet/UnicornManaged/UnicornManaged.fsproj +++ b/bindings/dotnet/UnicornEngine/UnicornEngine.fsproj @@ -1,11 +1,13 @@  net6.0 - UnicornManaged - UnicornManaged + UnicornEngine.Unicorn + UnicornEngine Copyright © Antonio Parata 2016 https://github.com/unicorn-engine/unicorn - 2.0.0 + .NET bindings for unicorn + 2.0.0 + $(VersionSuffix) 0c21f1c1-2725-4a46-9022-1905f85822a5 true true @@ -15,6 +17,10 @@ 3 + + none + + diff --git a/bindings/dotnet/UnicornManaged/UnicornEngineException.fs b/bindings/dotnet/UnicornEngine/UnicornEngineException.fs similarity index 83% rename from bindings/dotnet/UnicornManaged/UnicornEngineException.fs rename to bindings/dotnet/UnicornEngine/UnicornEngineException.fs index fd582557..68622951 100644 --- a/bindings/dotnet/UnicornManaged/UnicornEngineException.fs +++ b/bindings/dotnet/UnicornEngine/UnicornEngineException.fs @@ -1,4 +1,4 @@ -namespace UnicornManaged +namespace UnicornEngine open System diff --git a/bindings/dotnet/UnicornSamples/ShellcodeSample.cs b/bindings/dotnet/UnicornSamples/ShellcodeSample.cs index 7982e5e4..08ab59b1 100644 --- a/bindings/dotnet/UnicornSamples/ShellcodeSample.cs +++ b/bindings/dotnet/UnicornSamples/ShellcodeSample.cs @@ -3,8 +3,8 @@ using Gee.External.Capstone.X86; using System; using System.Diagnostics; using System.Text; -using UnicornManaged; -using UnicornManaged.Const; +using UnicornEngine; +using UnicornEngine.Const; namespace UnicornSamples { diff --git a/bindings/dotnet/UnicornSamples/UnicornSamples.csproj b/bindings/dotnet/UnicornSamples/UnicornSamples.csproj index bd603441..4ba2d49e 100644 --- a/bindings/dotnet/UnicornSamples/UnicornSamples.csproj +++ b/bindings/dotnet/UnicornSamples/UnicornSamples.csproj @@ -17,9 +17,9 @@ - + {0c21f1c1-2725-4a46-9022-1905f85822a5} - UnicornManaged + UnicornEngine diff --git a/bindings/dotnet/UnicornSamples/X86Sample32.cs b/bindings/dotnet/UnicornSamples/X86Sample32.cs index 24333839..bff69e79 100644 --- a/bindings/dotnet/UnicornSamples/X86Sample32.cs +++ b/bindings/dotnet/UnicornSamples/X86Sample32.cs @@ -3,8 +3,8 @@ using Gee.External.Capstone.X86; using System; using System.Diagnostics; using System.Text; -using UnicornManaged; -using UnicornManaged.Const; +using UnicornEngine; +using UnicornEngine.Const; namespace UnicornSamples { From 9928600584a51855e8c6f8bcfc6a7dc86aa2d1ba Mon Sep 17 00:00:00 2001 From: TSR Berry <20988865+TSRBerry@users.noreply.github.com> Date: Mon, 31 Oct 2022 23:43:04 +0100 Subject: [PATCH 02/43] gh: Publish Nuget for dotnet bindings --- .github/workflows/Nuget-publishing.yml | 51 ++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 .github/workflows/Nuget-publishing.yml diff --git a/.github/workflows/Nuget-publishing.yml b/.github/workflows/Nuget-publishing.yml new file mode 100644 index 00000000..dfc6cd25 --- /dev/null +++ b/.github/workflows/Nuget-publishing.yml @@ -0,0 +1,51 @@ +name: Nuget 📦 Distribution + +on: + push: + branches: + - dev + - master + paths-ignore: + - ".gitignore" + - "docs/**" + - "README" + - "CREDITS.TXT" + - "COPYING_GLIB" + - "COPYING.LGPL2" + - "AUTHORS.TXT" + - "CHANGELOG" + - "COPYING" + +permissions: + packages: write + +jobs: + publish: + runs-on: ubuntu-latest + + defaults: + run: + working-directory: bindings/dotnet/UnicornEngine + + steps: + - uses: actions/checkout@v3 + + - name: Get short sha + id: git_short_sha + run: echo "result=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT + + - uses: actions/setup-dotnet@v3 + with: + dotnet-version: 6.0.x + + - name: Authenticate to Github Packages + run: dotnet nuget add source --username "${{ github.repository_owner }}" --password "${{ secrets.GITHUB_TOKEN }}" --store-password-in-clear-text --name github "https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json" + + - name: Package .NET bindings + run: | + [[ "${{ github.ref_name }}" == "master" ]] \ + && dotnet pack -c Release \ + || dotnet pack -c Release --version-suffix="${{ steps.git_short_sha.outputs.result }}" + + - name: 📦 Publish to Github Packages + run: dotnet nuget push "bin/Release/UnicornEngine.Unicorn.*.nupkg" --source "github" --api-key "${{ secrets.GHPR_TOKEN }}" From 5d41b3346f71f04933945a68864c70a478e69c32 Mon Sep 17 00:00:00 2001 From: TSR Berry <20988865+TSRBerry@users.noreply.github.com> Date: Mon, 31 Oct 2022 23:50:53 +0100 Subject: [PATCH 03/43] gh: Publish new packages if bindings get modified --- .github/workflows/Nuget-publishing.yml | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/.github/workflows/Nuget-publishing.yml b/.github/workflows/Nuget-publishing.yml index dfc6cd25..463245db 100644 --- a/.github/workflows/Nuget-publishing.yml +++ b/.github/workflows/Nuget-publishing.yml @@ -5,16 +5,8 @@ on: branches: - dev - master - paths-ignore: - - ".gitignore" - - "docs/**" - - "README" - - "CREDITS.TXT" - - "COPYING_GLIB" - - "COPYING.LGPL2" - - "AUTHORS.TXT" - - "CHANGELOG" - - "COPYING" + paths: + - "bindings/dotnet/UnicornEngine/**" permissions: packages: write From 2e6a88805215a663250756e3ae5513635dcf369c Mon Sep 17 00:00:00 2001 From: TSR Berry <20988865+TSRBerry@users.noreply.github.com> Date: Sat, 5 Nov 2022 02:40:50 +0100 Subject: [PATCH 04/43] dotnet: Add native unicorn libraries to nuget package --- .github/workflows/Nuget-publishing.yml | 102 +++++++++++++++++- .../dotnet/UnicornEngine/UnicornEngine.fsproj | 4 + 2 files changed, 101 insertions(+), 5 deletions(-) diff --git a/.github/workflows/Nuget-publishing.yml b/.github/workflows/Nuget-publishing.yml index 463245db..ce5450bb 100644 --- a/.github/workflows/Nuget-publishing.yml +++ b/.github/workflows/Nuget-publishing.yml @@ -1,18 +1,21 @@ name: Nuget 📦 Distribution on: - push: + workflow_run: + workflows: + - "Build UC2" + types: + - completed branches: - dev - master - paths: - - "bindings/dotnet/UnicornEngine/**" permissions: packages: write jobs: publish: + if: ${{ github.event.workflow_run.conclusion == 'success' }} runs-on: ubuntu-latest defaults: @@ -21,10 +24,99 @@ jobs: steps: - uses: actions/checkout@v3 + with: + ref: ${{ github.event.workflow_run.head_branch }} + + - name: 'Download and extract artifacts' + uses: actions/github-script@v6 + with: + script: | + let fs = require('fs'); + const options = {}; + options.cwd = './bindings/dotnet/UnicornEngine'; + + let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({ + owner: context.repo.owner, + repo: context.repo.repo, + run_id: context.payload.workflow_run.id, + }); + + let sourceDir = ""; + let sourceFile = ""; + let destDir = ""; + let destFile = ""; + for (const artifact of allArtifacts.data.artifacts) { + switch(artifact.name) { + case 'ubuntu-cmake-aarch64.7z': + sourceDir = "lib/"; + sourceFile = "libunicorn.so.*"; + destDir = "runtimes/linux-arm64/native"; + destFile = "libunicorn.so"; + break; + case 'ubuntu-cmake-ppc64le.7z': + sourceDir = "lib/"; + sourceFile = "libunicorn.so.*"; + destDir = "runtimes/linux-ppc64le/native"; + destFile = "libunicorn.so"; + break; + case 'ubuntu-cmake-shared-x64.7z': + sourceDir = "lib/"; + sourceFile = "libunicorn.so.*"; + destDir = "runtimes/linux-x64/native"; + destFile = "libunicorn.so"; + break; + case 'ubuntu-cmake-shared-x86.7z': + sourceDir = "lib/"; + sourceFile = "libunicorn.so.*"; + destDir = "runtimes/linux-x86/native"; + destFile = "libunicorn.so"; + break; + case 'macos-cmake-shared-x64.7z': + sourceDir = "lib/"; + sourceFile = "libunicorn.*.dylib"; + destDir = "runtimes/osx-x64/native"; + destFile = "libunicorn.dylib"; + break; + case 'windows_msvc64_shared.7z': + sourceDir = ""; + sourceFile = "unicorn.dll"; + destDir = "runtimes/win-x64/native"; + destFile = "unicorn.dll"; + break; + case 'windows_msvc32_shared.7z': + sourceDir = ""; + sourceFile = "unicorn.dll"; + destDir = "runtimes/win-x86/native"; + destFile = "unicorn.dll"; + break; + default: + continue; + } + console.log(`Creating destination directory: ${destDir}`); + await exec.exec("mkdir", ["-p", destDir], options); + + console.log(`Downloading artifact: ${artifact.name}.zip`); + let download = await github.rest.actions.downloadArtifact({ + owner: context.repo.owner, + repo: context.repo.repo, + artifact_id: artifact.id, + archive_format: 'zip', + }); + fs.writeFileSync(`/tmp/${artifact.name}.zip`, Buffer.from(download.data)); + + console.log(`Unzipping: /tmp/${artifact.name}.zip`); + await exec.exec("unzip", [`/tmp/${artifact.name}.zip`]); + console.log(`Extracting library from 7z file to: ${destDir}${sourceFile}`); + await exec.exec("7z", ["e", "-o", destDir, `/tmp/${artifact.name}`, `${sourceDir}${sourceFile}`], options); + if (sourceFile != destFile) { + console.log(`Renaming library to: ${destFile}`); + await exec.exec("mv", [`${destDir}/${sourceFile}`, `${destDir}/${destFile}`], options); + } + } - name: Get short sha id: git_short_sha - run: echo "result=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT + run: echo "result=$(git rev-parse --short "${{ github.event.workflow_run.head_sha }}")" >> $GITHUB_OUTPUT - uses: actions/setup-dotnet@v3 with: @@ -35,7 +127,7 @@ jobs: - name: Package .NET bindings run: | - [[ "${{ github.ref_name }}" == "master" ]] \ + [[ "${{ github.event.workflow_run.head_branch }}" == "master" ]] \ && dotnet pack -c Release \ || dotnet pack -c Release --version-suffix="${{ steps.git_short_sha.outputs.result }}" diff --git a/bindings/dotnet/UnicornEngine/UnicornEngine.fsproj b/bindings/dotnet/UnicornEngine/UnicornEngine.fsproj index c117557c..f2142473 100644 --- a/bindings/dotnet/UnicornEngine/UnicornEngine.fsproj +++ b/bindings/dotnet/UnicornEngine/UnicornEngine.fsproj @@ -42,4 +42,8 @@ + + + + From a810da70950363110650c6eb2101db231ae714b4 Mon Sep 17 00:00:00 2001 From: TSR Berry <20988865+TSRBerry@users.noreply.github.com> Date: Sat, 5 Nov 2022 02:56:31 +0100 Subject: [PATCH 05/43] gha: List all native libs before packing .Net distribution --- .github/workflows/Nuget-publishing.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/Nuget-publishing.yml b/.github/workflows/Nuget-publishing.yml index ce5450bb..420a7026 100644 --- a/.github/workflows/Nuget-publishing.yml +++ b/.github/workflows/Nuget-publishing.yml @@ -27,7 +27,7 @@ jobs: with: ref: ${{ github.event.workflow_run.head_branch }} - - name: 'Download and extract artifacts' + - name: Download and extract artifacts uses: actions/github-script@v6 with: script: | @@ -125,7 +125,10 @@ jobs: - name: Authenticate to Github Packages run: dotnet nuget add source --username "${{ github.repository_owner }}" --password "${{ secrets.GITHUB_TOKEN }}" --store-password-in-clear-text --name github "https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json" - - name: Package .NET bindings + - name: List all native libraries + run: find ./runtimes -type f -print + + - name: Package .NET distribution run: | [[ "${{ github.event.workflow_run.head_branch }}" == "master" ]] \ && dotnet pack -c Release \ From 9bb45741b032a98677580a65204c0dbc9d2cbb53 Mon Sep 17 00:00:00 2001 From: TSR Berry <20988865+TSRBerry@users.noreply.github.com> Date: Sat, 5 Nov 2022 03:38:27 +0100 Subject: [PATCH 06/43] gha: Fix 7zip extraction arguments --- .github/workflows/Nuget-publishing.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Nuget-publishing.yml b/.github/workflows/Nuget-publishing.yml index 420a7026..604dc778 100644 --- a/.github/workflows/Nuget-publishing.yml +++ b/.github/workflows/Nuget-publishing.yml @@ -107,7 +107,7 @@ jobs: console.log(`Unzipping: /tmp/${artifact.name}.zip`); await exec.exec("unzip", [`/tmp/${artifact.name}.zip`]); console.log(`Extracting library from 7z file to: ${destDir}${sourceFile}`); - await exec.exec("7z", ["e", "-o", destDir, `/tmp/${artifact.name}`, `${sourceDir}${sourceFile}`], options); + await exec.exec("7z", ["e", `-o${destDir}`, `/tmp/${artifact.name}`, `${sourceDir}${sourceFile}`], options); if (sourceFile != destFile) { console.log(`Renaming library to: ${destFile}`); await exec.exec("mv", [`${destDir}/${sourceFile}`, `${destDir}/${destFile}`], options); From 8275b05ff40f53876302850064340f8a38f1ff44 Mon Sep 17 00:00:00 2001 From: TSR Berry <20988865+TSRBerry@users.noreply.github.com> Date: Sat, 5 Nov 2022 14:29:23 +0100 Subject: [PATCH 07/43] gha: Try to fix 7zip extraction errors --- .github/workflows/Nuget-publishing.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/Nuget-publishing.yml b/.github/workflows/Nuget-publishing.yml index 604dc778..156f42ac 100644 --- a/.github/workflows/Nuget-publishing.yml +++ b/.github/workflows/Nuget-publishing.yml @@ -102,12 +102,12 @@ jobs: artifact_id: artifact.id, archive_format: 'zip', }); - fs.writeFileSync(`/tmp/${artifact.name}.zip`, Buffer.from(download.data)); + fs.writeFileSync(`/home/runner/${artifact.name}.zip`, Buffer.from(download.data)); - console.log(`Unzipping: /tmp/${artifact.name}.zip`); - await exec.exec("unzip", [`/tmp/${artifact.name}.zip`]); - console.log(`Extracting library from 7z file to: ${destDir}${sourceFile}`); - await exec.exec("7z", ["e", `-o${destDir}`, `/tmp/${artifact.name}`, `${sourceDir}${sourceFile}`], options); + console.log(`Unzipping: /home/runner/${artifact.name}.zip`); + await exec.exec("unzip", [`/home/runner/${artifact.name}.zip`]); + console.log(`Extracting library from 7z file to: ${destDir}/${sourceFile}`); + await exec.exec("7z", ["e", `-o${destDir}/`, `/home/runner/${artifact.name}`, `${sourceDir}${sourceFile}`], options); if (sourceFile != destFile) { console.log(`Renaming library to: ${destFile}`); await exec.exec("mv", [`${destDir}/${sourceFile}`, `${destDir}/${destFile}`], options); From 331c11fea1b9d8052889fa673f4cf8e6eeec06f3 Mon Sep 17 00:00:00 2001 From: TSR Berry <20988865+TSRBerry@users.noreply.github.com> Date: Sat, 5 Nov 2022 16:45:32 +0100 Subject: [PATCH 08/43] gha: Fix unzip extracting to the wrong directory --- .github/workflows/Nuget-publishing.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Nuget-publishing.yml b/.github/workflows/Nuget-publishing.yml index 156f42ac..53e25218 100644 --- a/.github/workflows/Nuget-publishing.yml +++ b/.github/workflows/Nuget-publishing.yml @@ -105,7 +105,7 @@ jobs: fs.writeFileSync(`/home/runner/${artifact.name}.zip`, Buffer.from(download.data)); console.log(`Unzipping: /home/runner/${artifact.name}.zip`); - await exec.exec("unzip", [`/home/runner/${artifact.name}.zip`]); + await exec.exec("unzip", [`/home/runner/${artifact.name}.zip`, "-d", "/home/runner/"]); console.log(`Extracting library from 7z file to: ${destDir}/${sourceFile}`); await exec.exec("7z", ["e", `-o${destDir}/`, `/home/runner/${artifact.name}`, `${sourceDir}${sourceFile}`], options); if (sourceFile != destFile) { From d5ea8f675000e70e4dfd9706418ffd0a385a653d Mon Sep 17 00:00:00 2001 From: TSR Berry <20988865+TSRBerry@users.noreply.github.com> Date: Sat, 5 Nov 2022 17:51:23 +0100 Subject: [PATCH 09/43] gha: Get correct file name before renaming --- .github/workflows/Nuget-publishing.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/Nuget-publishing.yml b/.github/workflows/Nuget-publishing.yml index 53e25218..9aaff37e 100644 --- a/.github/workflows/Nuget-publishing.yml +++ b/.github/workflows/Nuget-publishing.yml @@ -45,6 +45,7 @@ jobs: let sourceFile = ""; let destDir = ""; let destFile = ""; + var output = {}; for (const artifact of allArtifacts.data.artifacts) { switch(artifact.name) { case 'ubuntu-cmake-aarch64.7z': @@ -109,7 +110,9 @@ jobs: console.log(`Extracting library from 7z file to: ${destDir}/${sourceFile}`); await exec.exec("7z", ["e", `-o${destDir}/`, `/home/runner/${artifact.name}`, `${sourceDir}${sourceFile}`], options); if (sourceFile != destFile) { - console.log(`Renaming library to: ${destFile}`); + output = await exec.getExecOutput("ls", [destDir], options); + sourceFile = output.stdout.trim(); + console.log(`Renaming ${sourceFile} to ${destFile}`); await exec.exec("mv", [`${destDir}/${sourceFile}`, `${destDir}/${destFile}`], options); } } From 8edffe048e235d6159a09ff17794fa8e523b317c Mon Sep 17 00:00:00 2001 From: Kevin Schneider Date: Mon, 14 Nov 2022 19:59:38 +0100 Subject: [PATCH 10/43] add riscv constants to python binding module --- bindings/python/unicorn/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/python/unicorn/__init__.py b/bindings/python/unicorn/__init__.py index 9d2b717c..219de992 100644 --- a/bindings/python/unicorn/__init__.py +++ b/bindings/python/unicorn/__init__.py @@ -1,4 +1,4 @@ # Unicorn Python bindings, by Nguyen Anh Quynnh -from . import arm_const, arm64_const, mips_const, sparc_const, m68k_const, x86_const +from . import arm_const, arm64_const, mips_const, sparc_const, m68k_const, x86_const, riscv_const from .unicorn_const import * from .unicorn import Uc, uc_version, uc_arch_supported, version_bind, debug, UcError, __version__ From dfea3f9e45d47419b5c94982452c7257392730bf Mon Sep 17 00:00:00 2001 From: TSR Berry <20988865+TSRBerry@users.noreply.github.com> Date: Tue, 22 Nov 2022 17:48:54 +0100 Subject: [PATCH 11/43] nuget: Build native libraries in jobs --- .github/workflows/Nuget-publishing.yml | 486 ++++++++++++++++++++----- 1 file changed, 385 insertions(+), 101 deletions(-) diff --git a/.github/workflows/Nuget-publishing.yml b/.github/workflows/Nuget-publishing.yml index 9aaff37e..e0edb5f1 100644 --- a/.github/workflows/Nuget-publishing.yml +++ b/.github/workflows/Nuget-publishing.yml @@ -1,11 +1,17 @@ name: Nuget 📦 Distribution on: - workflow_run: - workflows: - - "Build UC2" - types: - - completed + push: + paths-ignore: + - ".gitignore" + - "docs/**" + - "README" + - "CREDITS.TXT" + - "COPYING_GLIB" + - "COPYING.LGPL2" + - "AUTHORS.TXT" + - "CHANGELOG" + - "COPYING" branches: - dev - master @@ -14,128 +20,406 @@ permissions: packages: write jobs: - publish: - if: ${{ github.event.workflow_run.conclusion == 'success' }} - runs-on: ubuntu-latest + Windows: + runs-on: ${{ matrix.config.os }} + name: ${{ matrix.config.name }} + strategy: + fail-fast: true + matrix: + config: + - { + os: windows-2019, + arch: x64, + python-arch: x64, + python-ver: '3.8', + name: 'windows-x64 MSVC 64bit shared', + msvc-arch: x64, + artifact: 'windows_msvc64_shared.7z', + shared: 'yes', + build_type: 'Release', + archiver: '7z a', + generators: 'Visual Studio 16 2019' + } + - { + os: windows-2019, + arch: x86, + python-arch: x86, + python-ver: '3.8', + name: 'windows-x86 MSVC 32bit shared', + msvc-arch: x86, + artifact: 'windows_msvc32_shared.7z', + shared: 'yes', + build_type: 'Release', + archiver: '7z a', + generators: 'Visual Studio 16 2019' + } + compiler: [ gcc ] + steps: + - uses: actions/checkout@v2 - defaults: - run: - working-directory: bindings/dotnet/UnicornEngine + - name: '🛠️ Win MSVC 64 setup' + if: contains(matrix.config.name, 'MSVC 64') + uses: microsoft/setup-msbuild@v1 + + - name: '🛠️ Win MSVC 64 dev cmd setup' + if: contains(matrix.config.name, 'MSVC 64') + uses: ilammy/msvc-dev-cmd@v1 + with: + arch: x64 + + - name: '🚧 Win MSVC 64 build' + if: contains(matrix.config.name, 'MSVC 64') + shell: bash + run: | + choco install ninja cmake + ninja --version + cmake --version + mkdir build + cmake \ + -S . \ + -B . \ + -DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} \ + -G "${{ matrix.config.generators }}" \ + -DCMAKE_INSTALL_PREFIX:PATH=instdir \ + -DBUILD_SHARED_LIBS=${{ matrix.config.shared }} + cmake --build . --config ${{ matrix.config.build_type }} + cmake --install . --strip --config ${{ matrix.config.build_type }} + ctest -VV -C ${{ matrix.config.build_type }} + mv Release instdir + + - name: '🛠️ Win MSVC 32 setup' + if: contains(matrix.config.name, 'MSVC 32') + uses: ilammy/msvc-dev-cmd@v1 + with: + arch: x86 + + - name: '🚧 Win MSVC 32 build' + if: contains(matrix.config.name, 'MSVC 32') + shell: bash + run: | + choco install ninja cmake + ninja --version + cmake --version + mkdir build + cmake \ + -S . \ + -B . \ + -A "win32" \ + -DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} \ + -G "${{ matrix.config.generators }}" \ + -DCMAKE_INSTALL_PREFIX:PATH=instdir \ + -DBUILD_SHARED_LIBS=${{ matrix.config.shared }} + cmake --build . --config ${{ matrix.config.build_type }} + cmake --install . --strip --config ${{ matrix.config.build_type }} + ctest -VV -C ${{ matrix.config.build_type }} + mv Release instdir + + - name: '📦 Pack artifact' + if: always() + shell: bash + working-directory: instdir + run: | + ls -laR + ${{ matrix.config.archiver }} ../${{ matrix.config.artifact }} . ../test* + + - name: '📤 Upload artifact' + if: always() + uses: actions/upload-artifact@v1 + with: + path: ./${{ matrix.config.artifact }} + name: ${{ matrix.config.artifact }} + + Macos: + runs-on: ${{ matrix.config.os }} + name: ${{ matrix.config.name }} - ${{ matrix.compiler }} + strategy: + fail-fast: true + matrix: + config: + - { + os: macos-latest, + arch: x64, + python-arch: x64, + python-ver: '3.8', + name: 'macos-x64 cmake shared', + shared: 'yes', + artifact: 'macos-cmake-shared-x64.7z', + build_type: 'Release', + archiver: '7za a', + generators: 'Ninja' + } + compiler: [ gcc ] + steps: + - uses: actions/checkout@v2 + + - name: '🚧 Mac build' + if: contains(matrix.config.name, 'macos-x64') + shell: bash + run: | + brew install p7zip cmake ninja + ninja --version + cmake --version + mkdir build + mkdir instdir + cmake \ + -S . \ + -B . \ + -DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} \ + -G "${{ matrix.config.generators }}" \ + -DCMAKE_INSTALL_PREFIX:PATH=instdir \ + -DBUILD_SHARED_LIBS=${{ matrix.config.shared }} + cmake --build . --config ${{ matrix.config.build_type }} + cmake --install . --strip + ctest -VV -C ${{ matrix.config.build_type }} + + - name: '📦 Pack artifact' + if: always() + shell: bash + working-directory: instdir + run: | + ls -laR + ${{ matrix.config.archiver }} ../${{ matrix.config.artifact }} . ../test* + + - name: '📤 Upload artifact' + if: always() + uses: actions/upload-artifact@v1 + with: + path: ./${{ matrix.config.artifact }} + name: ${{ matrix.config.artifact }} + + Linux: + runs-on: ${{ matrix.config.os }} + name: ${{ matrix.config.name }} - ${{ matrix.compiler }} + strategy: + fail-fast: false + matrix: + config: + - { + os: ubuntu-latest, + arch: x64, + python-arch: x64, + python-ver: '3.8', + name: 'ubuntu-x64 cmake shared', + shared: 'yes', + artifact: 'ubuntu-cmake-shared-x64.7z', + build_type: 'Release', + archiver: '7z a', + generators: 'Ninja' + } + - { + os: ubuntu-latest, + arch: x86, + python-arch: x86, + python-ver: '3.8', + name: 'ubuntu-x86 cmake shared', + shared: 'yes', + artifact: 'ubuntu-cmake-shared-x86.7z', + build_type: 'Release', + archiver: '7z a', + generators: 'Ninja' + } + - { + os: ubuntu-latest, + arch: aarch64, + python-arch: aarch64, + python-ver: '3.8', + name: 'ubuntu-aarch64 cmake', + artifact: 'ubuntu-cmake-aarch64.7z', + build_type: 'Release', + archiver: '7z a', + generators: 'Ninja', + distro: ubuntu20.04 + } + - { + os: ubuntu-latest, + arch: ppc64le, + python-arch: ppc, + python-ver: '3.8', + name: 'ubuntu-ppc64le cmake', + artifact: 'ubuntu-cmake-ppc64le.7z', + build_type: 'Release', + archiver: '7z a', + generators: 'Ninja', + distro: ubuntu20.04 + } + compiler: [ gcc ] + steps: + - uses: actions/checkout@v2 + + - name: '🚧 Linux x64/x86 build' + if: contains(matrix.config.arch, 'x64') || contains(matrix.config.arch, 'x86') + shell: 'script -q -e -c "bash {0}"' + run: | + if [ ${{ matrix.config.arch }} == 'x64' ]; then + sudo apt install -q -y libcmocka-dev ninja-build + else + export CFLAGS="-m32" LDFLAGS="-m32" LDFLAGS_STATIC="-m32" UNICORN_QEMU_FLAGS="--cpu=i386" + sudo dpkg --add-architecture i386 + sudo apt install -q -y lib32ncurses-dev lib32z1-dev lib32gcc-9-dev libc6-dev-i386 gcc-multilib \ + libcmocka-dev:i386 libcmocka0:i386 libc6:i386 libgcc-s1:i386 ninja-build + fi + mkdir build + mkdir instdir + cmake \ + -S . \ + -B . \ + -DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} \ + -G "${{ matrix.config.generators }}" \ + -DCMAKE_INSTALL_PREFIX:PATH=instdir \ + -DBUILD_SHARED_LIBS=${{ matrix.config.shared }} + cmake --build . --config ${{ matrix.config.build_type }} + cmake --install . --strip + ctest -VV -C ${{ matrix.config.build_type }} + + - name: '🚧 Linux ppc64le/aarch64 build' + if: contains(matrix.config.arch, 'ppc64le') || contains(matrix.config.arch, 'aarch64') + uses: uraimo/run-on-arch-action@v2.0.5 + with: + arch: ${{ matrix.config.arch }} + distro: ${{ matrix.config.distro }} + setup: | + mkdir -p "${PWD}/instdir" + dockerRunArgs: | + --volume "${PWD}/instdir:/instdir" + shell: /bin/sh + install: | + apt-get update -q -y + apt-get install -q -y git cmake build-essential automake libcmocka-dev pkg-config ${{ matrix.compiler }} ninja-build + run: | + mkdir build + cmake \ + -S . \ + -B . \ + -DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} \ + -G "${{ matrix.config.generators }}" \ + -DCMAKE_INSTALL_PREFIX:PATH=/instdir + cmake --build . --config ${{ matrix.config.build_type }} + cmake --install . --strip + ctest -VV -C ${{ matrix.config.build_type }} + + - name: '📦 Pack artifact' + if: always() + shell: bash + working-directory: instdir + run: | + ls -laR + ${{ matrix.config.archiver }} ../${{ matrix.config.artifact }} . ../test* + + - name: '📤 Upload artifact' + if: always() + uses: actions/upload-artifact@v1 + with: + path: ./${{ matrix.config.artifact }} + name: ${{ matrix.config.artifact }} + + publish: + needs: ["Windows", "Macos", "Linux"] + if: ${{ needs.Windows.result == 'success' && needs.Macos.result == 'success' && needs.Linux.result == 'success' }} + runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - with: - ref: ${{ github.event.workflow_run.head_branch }} - - name: Download and extract artifacts - uses: actions/github-script@v6 + - name: Download artifacts + uses: actions/download-artifact@v3 with: - script: | - let fs = require('fs'); - const options = {}; - options.cwd = './bindings/dotnet/UnicornEngine'; - - let allArtifacts = await github.rest.actions.listWorkflowRunArtifacts({ - owner: context.repo.owner, - repo: context.repo.repo, - run_id: context.payload.workflow_run.id, - }); - - let sourceDir = ""; - let sourceFile = ""; - let destDir = ""; - let destFile = ""; - var output = {}; - for (const artifact of allArtifacts.data.artifacts) { - switch(artifact.name) { - case 'ubuntu-cmake-aarch64.7z': - sourceDir = "lib/"; - sourceFile = "libunicorn.so.*"; - destDir = "runtimes/linux-arm64/native"; - destFile = "libunicorn.so"; - break; - case 'ubuntu-cmake-ppc64le.7z': - sourceDir = "lib/"; - sourceFile = "libunicorn.so.*"; - destDir = "runtimes/linux-ppc64le/native"; - destFile = "libunicorn.so"; - break; - case 'ubuntu-cmake-shared-x64.7z': - sourceDir = "lib/"; - sourceFile = "libunicorn.so.*"; - destDir = "runtimes/linux-x64/native"; - destFile = "libunicorn.so"; - break; - case 'ubuntu-cmake-shared-x86.7z': - sourceDir = "lib/"; - sourceFile = "libunicorn.so.*"; - destDir = "runtimes/linux-x86/native"; - destFile = "libunicorn.so"; - break; - case 'macos-cmake-shared-x64.7z': - sourceDir = "lib/"; - sourceFile = "libunicorn.*.dylib"; - destDir = "runtimes/osx-x64/native"; - destFile = "libunicorn.dylib"; - break; - case 'windows_msvc64_shared.7z': - sourceDir = ""; - sourceFile = "unicorn.dll"; - destDir = "runtimes/win-x64/native"; - destFile = "unicorn.dll"; - break; - case 'windows_msvc32_shared.7z': - sourceDir = ""; - sourceFile = "unicorn.dll"; - destDir = "runtimes/win-x86/native"; - destFile = "unicorn.dll"; - break; - default: - continue; - } - console.log(`Creating destination directory: ${destDir}`); - await exec.exec("mkdir", ["-p", destDir], options); - - console.log(`Downloading artifact: ${artifact.name}.zip`); - let download = await github.rest.actions.downloadArtifact({ - owner: context.repo.owner, - repo: context.repo.repo, - artifact_id: artifact.id, - archive_format: 'zip', - }); - fs.writeFileSync(`/home/runner/${artifact.name}.zip`, Buffer.from(download.data)); - - console.log(`Unzipping: /home/runner/${artifact.name}.zip`); - await exec.exec("unzip", [`/home/runner/${artifact.name}.zip`, "-d", "/home/runner/"]); - console.log(`Extracting library from 7z file to: ${destDir}/${sourceFile}`); - await exec.exec("7z", ["e", `-o${destDir}/`, `/home/runner/${artifact.name}`, `${sourceDir}${sourceFile}`], options); - if (sourceFile != destFile) { - output = await exec.getExecOutput("ls", [destDir], options); - sourceFile = output.stdout.trim(); - console.log(`Renaming ${sourceFile} to ${destFile}`); - await exec.exec("mv", [`${destDir}/${sourceFile}`, `${destDir}/${destFile}`], options); - } + path: artifacts + + - name: Extract artifacts + shell: python + run: | + import subprocess + import os + + artifactPath = os.path.join(os.getcwd(), "artifacts") + bindingsPath = os.path.join(os.getcwd(), "bindings", "dotnet", "UnicornEngine") + + ARTIFACT_CONFIG = { + "ubuntu-cmake-aarch64.7z": { + "sourceDir": "lib/", + "sourceFile": "libunicorn.so.*", + "destDir": "runtimes/linux-arm64/native", + "destFile": "libunicorn.so" + }, + "ubuntu-cmake-ppc64le.7z": { + "sourceDir": "lib/", + "sourceFile": "libunicorn.so.*", + "destDir": "runtimes/linux-ppc64le/native", + "destFile": "libunicorn.so" + }, + "ubuntu-cmake-shared-x86.7z": { + "sourceDir": "lib/", + "sourceFile": "libunicorn.so.*", + "destDir": "runtimes/linux-x64/native", + "destFile": "libunicorn.so" + }, + "macos-cmake-shared-x64.7z": { + "sourceDir": "lib/", + "sourceFile": "libunicorn.*.dylib", + "destDir": "runtimes/osx-x64/native", + "destFile": "libunicorn.dylib" + }, + "windows_msvc64_shared.7z": { + "sourceDir": "", + "sourceFile": "unicorn.dll", + "destDir": "runtimes/win-x64/native", + "destFile": "unicorn.dll" + }, + "windows_msvc32_shared.7z": { + "sourceDir": "", + "sourceFile": "unicorn.dll", + "destDir": "runtimes/win-x86/native", + "destFile": "unicorn.dll" } + } + + if len(os.listdir(artifactPath)) < len(ARTIFACT_CONFIG.keys()): + print("Some artifacts are missing. Aborting.") + exit(1) + + for artifact in os.listdir(artifactPath): + if artifact in ARTIFACT_CONFIG.keys(): + print("Working on:", artifact) + config = ARTIFACT_CONFIG[artifact] + destDir = os.path.join(bindingsPath, config["destDir"]) + print("Creating dir:", destDir) + os.makedirs(destDir, exist_ok=True) + + print(f"Extracting library from 7z file to: {config['destDir']}/{config['sourceFile']}") + result = subprocess.run(["7z", "e", f"-o{destDir}/", os.path.join(artifactPath, artifact), f"{config['sourceDir']}{config['sourceFile']}"]) + result.check_returncode() + + if config["sourceFile"] != config["destFile"]: + output = subprocess.run(["ls", destDir], stdout=subprocess.PIPE) + sourceFile = output.stdout.decode().strip() + print(f"Renaming {sourceFile} to {config['destFile']}") + os.rename(os.path.join(destDir, sourceFile), os.path.join(destDir, config["destFile"])) + + print("Done!") - name: Get short sha id: git_short_sha - run: echo "result=$(git rev-parse --short "${{ github.event.workflow_run.head_sha }}")" >> $GITHUB_OUTPUT + run: echo "result=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT - uses: actions/setup-dotnet@v3 with: dotnet-version: 6.0.x - name: Authenticate to Github Packages + working-directory: bindings/dotnet/UnicornEngine run: dotnet nuget add source --username "${{ github.repository_owner }}" --password "${{ secrets.GITHUB_TOKEN }}" --store-password-in-clear-text --name github "https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json" - name: List all native libraries + working-directory: bindings/dotnet/UnicornEngine run: find ./runtimes -type f -print - name: Package .NET distribution + working-directory: bindings/dotnet/UnicornEngine run: | [[ "${{ github.event.workflow_run.head_branch }}" == "master" ]] \ && dotnet pack -c Release \ || dotnet pack -c Release --version-suffix="${{ steps.git_short_sha.outputs.result }}" - name: 📦 Publish to Github Packages + working-directory: bindings/dotnet/UnicornEngine run: dotnet nuget push "bin/Release/UnicornEngine.Unicorn.*.nupkg" --source "github" --api-key "${{ secrets.GHPR_TOKEN }}" From 9dc001d686ca364946d641ea8c0277ac6af13795 Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Wed, 7 Dec 2022 01:36:44 +0800 Subject: [PATCH 12/43] remove unused code in PPC & dis-asm.h --- qemu/include/disas/dis-asm.h | 519 --------------------------- qemu/target/ppc/translate_init.inc.c | 151 -------- 2 files changed, 670 deletions(-) delete mode 100644 qemu/include/disas/dis-asm.h diff --git a/qemu/include/disas/dis-asm.h b/qemu/include/disas/dis-asm.h deleted file mode 100644 index c5f9fa08..00000000 --- a/qemu/include/disas/dis-asm.h +++ /dev/null @@ -1,519 +0,0 @@ -/* Interface between the opcode library and its callers. - Written by Cygnus Support, 1993. - - The opcode library (libopcodes.a) provides instruction decoders for - a large variety of instruction sets, callable with an identical - interface, for making instruction-processing programs more independent - of the instruction set being processed. */ - -#ifndef DISAS_DIS_ASM_H -#define DISAS_DIS_ASM_H - -typedef void *PTR; -typedef uint64_t bfd_vma; -typedef int64_t bfd_signed_vma; -typedef uint8_t bfd_byte; -#define sprintf_vma(s,x) sprintf (s, "%0" PRIx64, x) -#define snprintf_vma(s,ss,x) snprintf (s, ss, "%0" PRIx64, x) - -#define BFD64 - -enum bfd_flavour { - bfd_target_unknown_flavour, - bfd_target_aout_flavour, - bfd_target_coff_flavour, - bfd_target_ecoff_flavour, - bfd_target_elf_flavour, - bfd_target_ieee_flavour, - bfd_target_nlm_flavour, - bfd_target_oasys_flavour, - bfd_target_tekhex_flavour, - bfd_target_srec_flavour, - bfd_target_ihex_flavour, - bfd_target_som_flavour, - bfd_target_os9k_flavour, - bfd_target_versados_flavour, - bfd_target_msdos_flavour, - bfd_target_evax_flavour -}; - -enum bfd_endian { BFD_ENDIAN_BIG, BFD_ENDIAN_LITTLE, BFD_ENDIAN_UNKNOWN }; - -enum bfd_architecture -{ - bfd_arch_unknown, /* File arch not known */ - bfd_arch_obscure, /* Arch known, not one of these */ - bfd_arch_m68k, /* Motorola 68xxx */ -#define bfd_mach_m68000 1 -#define bfd_mach_m68008 2 -#define bfd_mach_m68010 3 -#define bfd_mach_m68020 4 -#define bfd_mach_m68030 5 -#define bfd_mach_m68040 6 -#define bfd_mach_m68060 7 -#define bfd_mach_cpu32 8 -#define bfd_mach_mcf5200 9 -#define bfd_mach_mcf5206e 10 -#define bfd_mach_mcf5307 11 -#define bfd_mach_mcf5407 12 -#define bfd_mach_mcf528x 13 -#define bfd_mach_mcfv4e 14 -#define bfd_mach_mcf521x 15 -#define bfd_mach_mcf5249 16 -#define bfd_mach_mcf547x 17 -#define bfd_mach_mcf548x 18 - bfd_arch_vax, /* DEC Vax */ - bfd_arch_i960, /* Intel 960 */ - /* The order of the following is important. - lower number indicates a machine type that - only accepts a subset of the instructions - available to machines with higher numbers. - The exception is the "ca", which is - incompatible with all other machines except - "core". */ - -#define bfd_mach_i960_core 1 -#define bfd_mach_i960_ka_sa 2 -#define bfd_mach_i960_kb_sb 3 -#define bfd_mach_i960_mc 4 -#define bfd_mach_i960_xa 5 -#define bfd_mach_i960_ca 6 -#define bfd_mach_i960_jx 7 -#define bfd_mach_i960_hx 8 - - bfd_arch_a29k, /* AMD 29000 */ - bfd_arch_sparc, /* SPARC */ -#define bfd_mach_sparc 1 -/* The difference between v8plus and v9 is that v9 is a true 64 bit env. */ -#define bfd_mach_sparc_sparclet 2 -#define bfd_mach_sparc_sparclite 3 -#define bfd_mach_sparc_v8plus 4 -#define bfd_mach_sparc_v8plusa 5 /* with ultrasparc add'ns. */ -#define bfd_mach_sparc_sparclite_le 6 -#define bfd_mach_sparc_v9 7 -#define bfd_mach_sparc_v9a 8 /* with ultrasparc add'ns. */ -#define bfd_mach_sparc_v8plusb 9 /* with cheetah add'ns. */ -#define bfd_mach_sparc_v9b 10 /* with cheetah add'ns. */ -/* Nonzero if MACH has the v9 instruction set. */ -#define bfd_mach_sparc_v9_p(mach) \ - ((mach) >= bfd_mach_sparc_v8plus && (mach) <= bfd_mach_sparc_v9b \ - && (mach) != bfd_mach_sparc_sparclite_le) - bfd_arch_mips, /* MIPS Rxxxx */ -#define bfd_mach_mips3000 3000 -#define bfd_mach_mips3900 3900 -#define bfd_mach_mips4000 4000 -#define bfd_mach_mips4010 4010 -#define bfd_mach_mips4100 4100 -#define bfd_mach_mips4300 4300 -#define bfd_mach_mips4400 4400 -#define bfd_mach_mips4600 4600 -#define bfd_mach_mips4650 4650 -#define bfd_mach_mips5000 5000 -#define bfd_mach_mips6000 6000 -#define bfd_mach_mips8000 8000 -#define bfd_mach_mips10000 10000 -#define bfd_mach_mips16 16 - bfd_arch_i386, /* Intel 386 */ -#define bfd_mach_i386_i386 0 -#define bfd_mach_i386_i8086 1 -#define bfd_mach_i386_i386_intel_syntax 2 -#define bfd_mach_x86_64 3 -#define bfd_mach_x86_64_intel_syntax 4 - bfd_arch_we32k, /* AT&T WE32xxx */ - bfd_arch_tahoe, /* CCI/Harris Tahoe */ - bfd_arch_i860, /* Intel 860 */ - bfd_arch_romp, /* IBM ROMP PC/RT */ - bfd_arch_alliant, /* Alliant */ - bfd_arch_convex, /* Convex */ - bfd_arch_m88k, /* Motorola 88xxx */ - bfd_arch_pyramid, /* Pyramid Technology */ - bfd_arch_h8300, /* Hitachi H8/300 */ -#define bfd_mach_h8300 1 -#define bfd_mach_h8300h 2 -#define bfd_mach_h8300s 3 - bfd_arch_powerpc, /* PowerPC */ -#define bfd_mach_ppc 0 -#define bfd_mach_ppc64 1 -#define bfd_mach_ppc_403 403 -#define bfd_mach_ppc_403gc 4030 -#define bfd_mach_ppc_e500 500 -#define bfd_mach_ppc_505 505 -#define bfd_mach_ppc_601 601 -#define bfd_mach_ppc_602 602 -#define bfd_mach_ppc_603 603 -#define bfd_mach_ppc_ec603e 6031 -#define bfd_mach_ppc_604 604 -#define bfd_mach_ppc_620 620 -#define bfd_mach_ppc_630 630 -#define bfd_mach_ppc_750 750 -#define bfd_mach_ppc_860 860 -#define bfd_mach_ppc_a35 35 -#define bfd_mach_ppc_rs64ii 642 -#define bfd_mach_ppc_rs64iii 643 -#define bfd_mach_ppc_7400 7400 - bfd_arch_rs6000, /* IBM RS/6000 */ - bfd_arch_hppa, /* HP PA RISC */ -#define bfd_mach_hppa10 10 -#define bfd_mach_hppa11 11 -#define bfd_mach_hppa20 20 -#define bfd_mach_hppa20w 25 - bfd_arch_d10v, /* Mitsubishi D10V */ - bfd_arch_z8k, /* Zilog Z8000 */ -#define bfd_mach_z8001 1 -#define bfd_mach_z8002 2 - bfd_arch_h8500, /* Hitachi H8/500 */ - bfd_arch_sh, /* Hitachi SH */ -#define bfd_mach_sh 1 -#define bfd_mach_sh2 0x20 -#define bfd_mach_sh_dsp 0x2d -#define bfd_mach_sh2a 0x2a -#define bfd_mach_sh2a_nofpu 0x2b -#define bfd_mach_sh2e 0x2e -#define bfd_mach_sh3 0x30 -#define bfd_mach_sh3_nommu 0x31 -#define bfd_mach_sh3_dsp 0x3d -#define bfd_mach_sh3e 0x3e -#define bfd_mach_sh4 0x40 -#define bfd_mach_sh4_nofpu 0x41 -#define bfd_mach_sh4_nommu_nofpu 0x42 -#define bfd_mach_sh4a 0x4a -#define bfd_mach_sh4a_nofpu 0x4b -#define bfd_mach_sh4al_dsp 0x4d -#define bfd_mach_sh5 0x50 - bfd_arch_alpha, /* Dec Alpha */ -#define bfd_mach_alpha 1 -#define bfd_mach_alpha_ev4 0x10 -#define bfd_mach_alpha_ev5 0x20 -#define bfd_mach_alpha_ev6 0x30 - bfd_arch_arm, /* Advanced Risc Machines ARM */ -#define bfd_mach_arm_unknown 0 -#define bfd_mach_arm_2 1 -#define bfd_mach_arm_2a 2 -#define bfd_mach_arm_3 3 -#define bfd_mach_arm_3M 4 -#define bfd_mach_arm_4 5 -#define bfd_mach_arm_4T 6 -#define bfd_mach_arm_5 7 -#define bfd_mach_arm_5T 8 -#define bfd_mach_arm_5TE 9 -#define bfd_mach_arm_XScale 10 -#define bfd_mach_arm_ep9312 11 -#define bfd_mach_arm_iWMMXt 12 -#define bfd_mach_arm_iWMMXt2 13 - bfd_arch_ns32k, /* National Semiconductors ns32000 */ - bfd_arch_w65, /* WDC 65816 */ - bfd_arch_tic30, /* Texas Instruments TMS320C30 */ - bfd_arch_v850, /* NEC V850 */ -#define bfd_mach_v850 0 - bfd_arch_arc, /* Argonaut RISC Core */ -#define bfd_mach_arc_base 0 - bfd_arch_m32r, /* Mitsubishi M32R/D */ -#define bfd_mach_m32r 0 /* backwards compatibility */ - bfd_arch_mn10200, /* Matsushita MN10200 */ - bfd_arch_mn10300, /* Matsushita MN10300 */ - bfd_arch_cris, /* Axis CRIS */ -#define bfd_mach_cris_v0_v10 255 -#define bfd_mach_cris_v32 32 -#define bfd_mach_cris_v10_v32 1032 - bfd_arch_microblaze, /* Xilinx MicroBlaze. */ - bfd_arch_moxie, /* The Moxie core. */ - bfd_arch_ia64, /* HP/Intel ia64 */ -#define bfd_mach_ia64_elf64 64 -#define bfd_mach_ia64_elf32 32 - bfd_arch_nios2, /* Nios II */ -#define bfd_mach_nios2 0 -#define bfd_mach_nios2r1 1 -#define bfd_mach_nios2r2 2 - bfd_arch_lm32, /* Lattice Mico32 */ -#define bfd_mach_lm32 1 - bfd_arch_rx, /* Renesas RX */ -#define bfd_mach_rx 0x75 -#define bfd_mach_rx_v2 0x76 -#define bfd_mach_rx_v3 0x77 - bfd_arch_last - }; -#define bfd_mach_s390_31 31 -#define bfd_mach_s390_64 64 - -typedef struct symbol_cache_entry -{ - const char *name; - union - { - PTR p; - bfd_vma i; - } udata; -} asymbol; - -typedef int (*fprintf_function)(FILE *f, const char *fmt, ...) - GCC_FMT_ATTR(2, 3); - -enum dis_insn_type { - dis_noninsn, /* Not a valid instruction */ - dis_nonbranch, /* Not a branch instruction */ - dis_branch, /* Unconditional branch */ - dis_condbranch, /* Conditional branch */ - dis_jsr, /* Jump to subroutine */ - dis_condjsr, /* Conditional jump to subroutine */ - dis_dref, /* Data reference instruction */ - dis_dref2 /* Two data references in instruction */ -}; - -/* This struct is passed into the instruction decoding routine, - and is passed back out into each callback. The various fields are used - for conveying information from your main routine into your callbacks, - for passing information into the instruction decoders (such as the - addresses of the callback functions), or for passing information - back from the instruction decoders to their callers. - - It must be initialized before it is first passed; this can be done - by hand, or using one of the initialization macros below. */ - -typedef struct disassemble_info { - fprintf_function fprintf_func; - FILE *stream; - PTR application_data; - - /* Target description. We could replace this with a pointer to the bfd, - but that would require one. There currently isn't any such requirement - so to avoid introducing one we record these explicitly. */ - /* The bfd_flavour. This can be bfd_target_unknown_flavour. */ - enum bfd_flavour flavour; - /* The bfd_arch value. */ - enum bfd_architecture arch; - /* The bfd_mach value. */ - unsigned long mach; - /* Endianness (for bi-endian cpus). Mono-endian cpus can ignore this. */ - enum bfd_endian endian; - - /* An array of pointers to symbols either at the location being disassembled - or at the start of the function being disassembled. The array is sorted - so that the first symbol is intended to be the one used. The others are - present for any misc. purposes. This is not set reliably, but if it is - not NULL, it is correct. */ - asymbol **symbols; - /* Number of symbols in array. */ - int num_symbols; - - /* For use by the disassembler. - The top 16 bits are reserved for public use (and are documented here). - The bottom 16 bits are for the internal use of the disassembler. */ - unsigned long flags; -#define INSN_HAS_RELOC 0x80000000 -#define INSN_ARM_BE32 0x00010000 - PTR private_data; - - /* Function used to get bytes to disassemble. MEMADDR is the - address of the stuff to be disassembled, MYADDR is the address to - put the bytes in, and LENGTH is the number of bytes to read. - INFO is a pointer to this struct. - Returns an errno value or 0 for success. */ - int (*read_memory_func) - (bfd_vma memaddr, bfd_byte *myaddr, int length, - struct disassemble_info *info); - - /* Function which should be called if we get an error that we can't - recover from. STATUS is the errno value from read_memory_func and - MEMADDR is the address that we were trying to read. INFO is a - pointer to this struct. */ - void (*memory_error_func) - (int status, bfd_vma memaddr, struct disassemble_info *info); - - /* Function called to print ADDR. */ - void (*print_address_func) - (bfd_vma addr, struct disassemble_info *info); - - /* Function called to print an instruction. The function is architecture - * specific. - */ - int (*print_insn)(bfd_vma addr, struct disassemble_info *info); - - /* Function called to determine if there is a symbol at the given ADDR. - If there is, the function returns 1, otherwise it returns 0. - This is used by ports which support an overlay manager where - the overlay number is held in the top part of an address. In - some circumstances we want to include the overlay number in the - address, (normally because there is a symbol associated with - that address), but sometimes we want to mask out the overlay bits. */ - int (* symbol_at_address_func) - (bfd_vma addr, struct disassemble_info * info); - - /* These are for buffer_read_memory. */ - bfd_byte *buffer; - bfd_vma buffer_vma; - int buffer_length; - - /* This variable may be set by the instruction decoder. It suggests - the number of bytes objdump should display on a single line. If - the instruction decoder sets this, it should always set it to - the same value in order to get reasonable looking output. */ - int bytes_per_line; - - /* the next two variables control the way objdump displays the raw data */ - /* For example, if bytes_per_line is 8 and bytes_per_chunk is 4, the */ - /* output will look like this: - 00: 00000000 00000000 - with the chunks displayed according to "display_endian". */ - int bytes_per_chunk; - enum bfd_endian display_endian; - - /* Results from instruction decoders. Not all decoders yet support - this information. This info is set each time an instruction is - decoded, and is only valid for the last such instruction. - - To determine whether this decoder supports this information, set - insn_info_valid to 0, decode an instruction, then check it. */ - - char insn_info_valid; /* Branch info has been set. */ - char branch_delay_insns; /* How many sequential insn's will run before - a branch takes effect. (0 = normal) */ - char data_size; /* Size of data reference in insn, in bytes */ - enum dis_insn_type insn_type; /* Type of instruction */ - bfd_vma target; /* Target address of branch or dref, if known; - zero if unknown. */ - bfd_vma target2; /* Second target address for dref2 */ - - /* Command line options specific to the target disassembler. */ - char * disassembler_options; - - /* Field intended to be used by targets in any way they deem suitable. */ - int64_t target_info; - - /* Options for Capstone disassembly. */ - int cap_arch; - int cap_mode; - int cap_insn_unit; - int cap_insn_split; - -} disassemble_info; - - -/* Standard disassemblers. Disassemble one instruction at the given - target address. Return number of bytes processed. */ -typedef int (*disassembler_ftype) (bfd_vma, disassemble_info *); - -int print_insn_tci(bfd_vma, disassemble_info*); -int print_insn_big_mips (bfd_vma, disassemble_info*); -int print_insn_little_mips (bfd_vma, disassemble_info*); -int print_insn_nanomips (bfd_vma, disassemble_info*); -int print_insn_i386 (bfd_vma, disassemble_info*); -int print_insn_m68k (bfd_vma, disassemble_info*); -int print_insn_z8001 (bfd_vma, disassemble_info*); -int print_insn_z8002 (bfd_vma, disassemble_info*); -int print_insn_h8300 (bfd_vma, disassemble_info*); -int print_insn_h8300h (bfd_vma, disassemble_info*); -int print_insn_h8300s (bfd_vma, disassemble_info*); -int print_insn_h8500 (bfd_vma, disassemble_info*); -int print_insn_arm_a64 (bfd_vma, disassemble_info*); -int print_insn_alpha (bfd_vma, disassemble_info*); -disassembler_ftype arc_get_disassembler (int, int); -int print_insn_arm (bfd_vma, disassemble_info*); -int print_insn_sparc (bfd_vma, disassemble_info*); -int print_insn_big_a29k (bfd_vma, disassemble_info*); -int print_insn_little_a29k (bfd_vma, disassemble_info*); -int print_insn_i960 (bfd_vma, disassemble_info*); -int print_insn_sh (bfd_vma, disassemble_info*); -int print_insn_shl (bfd_vma, disassemble_info*); -int print_insn_hppa (bfd_vma, disassemble_info*); -int print_insn_m32r (bfd_vma, disassemble_info*); -int print_insn_m88k (bfd_vma, disassemble_info*); -int print_insn_mn10200 (bfd_vma, disassemble_info*); -int print_insn_mn10300 (bfd_vma, disassemble_info*); -int print_insn_moxie (bfd_vma, disassemble_info*); -int print_insn_ns32k (bfd_vma, disassemble_info*); -int print_insn_big_powerpc (bfd_vma, disassemble_info*); -int print_insn_little_powerpc (bfd_vma, disassemble_info*); -int print_insn_rs6000 (bfd_vma, disassemble_info*); -int print_insn_w65 (bfd_vma, disassemble_info*); -int print_insn_d10v (bfd_vma, disassemble_info*); -int print_insn_v850 (bfd_vma, disassemble_info*); -int print_insn_tic30 (bfd_vma, disassemble_info*); -int print_insn_ppc (bfd_vma, disassemble_info*); -int print_insn_s390 (bfd_vma, disassemble_info*); -int print_insn_crisv32 (bfd_vma, disassemble_info*); -int print_insn_crisv10 (bfd_vma, disassemble_info*); -int print_insn_microblaze (bfd_vma, disassemble_info*); -int print_insn_ia64 (bfd_vma, disassemble_info*); -int print_insn_lm32 (bfd_vma, disassemble_info*); -int print_insn_big_nios2 (bfd_vma, disassemble_info*); -int print_insn_little_nios2 (bfd_vma, disassemble_info*); -int print_insn_xtensa (bfd_vma, disassemble_info*); -int print_insn_riscv32 (bfd_vma, disassemble_info*); -int print_insn_riscv64 (bfd_vma, disassemble_info*); -int print_insn_rx(bfd_vma, disassemble_info *); - -#if 0 -/* Fetch the disassembler for a given BFD, if that support is available. */ -disassembler_ftype disassembler(bfd *); -#endif - - -/* This block of definitions is for particular callers who read instructions - into a buffer before calling the instruction decoder. */ - -/* Here is a function which callers may wish to use for read_memory_func. - It gets bytes from a buffer. */ -int buffer_read_memory(bfd_vma, bfd_byte *, int, struct disassemble_info *); - -/* This function goes with buffer_read_memory. - It prints a message using info->fprintf_func and info->stream. */ -void perror_memory(int, bfd_vma, struct disassemble_info *); - - -/* Just print the address in hex. This is included for completeness even - though both GDB and objdump provide their own (to print symbolic - addresses). */ -void generic_print_address(bfd_vma, struct disassemble_info *); - -/* Always true. */ -int generic_symbol_at_address(bfd_vma, struct disassemble_info *); - -/* Macro to initialize a disassemble_info struct. This should be called - by all applications creating such a struct. */ -#define INIT_DISASSEMBLE_INFO(INFO, STREAM, FPRINTF_FUNC) \ - (INFO).flavour = bfd_target_unknown_flavour, \ - (INFO).arch = bfd_arch_unknown, \ - (INFO).mach = 0, \ - (INFO).endian = BFD_ENDIAN_UNKNOWN, \ - INIT_DISASSEMBLE_INFO_NO_ARCH(INFO, STREAM, FPRINTF_FUNC) - -/* Call this macro to initialize only the internal variables for the - disassembler. Architecture dependent things such as byte order, or machine - variant are not touched by this macro. This makes things much easier for - GDB which must initialize these things separately. */ - -#define INIT_DISASSEMBLE_INFO_NO_ARCH(INFO, STREAM, FPRINTF_FUNC) \ - (INFO).fprintf_func = (FPRINTF_FUNC), \ - (INFO).stream = (STREAM), \ - (INFO).symbols = NULL, \ - (INFO).num_symbols = 0, \ - (INFO).private_data = NULL, \ - (INFO).buffer = NULL, \ - (INFO).buffer_vma = 0, \ - (INFO).buffer_length = 0, \ - (INFO).read_memory_func = buffer_read_memory, \ - (INFO).memory_error_func = perror_memory, \ - (INFO).print_address_func = generic_print_address, \ - (INFO).print_insn = NULL, \ - (INFO).symbol_at_address_func = generic_symbol_at_address, \ - (INFO).flags = 0, \ - (INFO).bytes_per_line = 0, \ - (INFO).bytes_per_chunk = 0, \ - (INFO).display_endian = BFD_ENDIAN_UNKNOWN, \ - (INFO).disassembler_options = NULL, \ - (INFO).insn_info_valid = 0 - -#ifndef ATTRIBUTE_UNUSED -#define ATTRIBUTE_UNUSED __attribute__((unused)) -#endif - -/* from libbfd */ - -bfd_vma bfd_getl64 (const bfd_byte *addr); -bfd_vma bfd_getl32 (const bfd_byte *addr); -bfd_vma bfd_getb32 (const bfd_byte *addr); -bfd_vma bfd_getl16 (const bfd_byte *addr); -bfd_vma bfd_getb16 (const bfd_byte *addr); -typedef bool bfd_boolean; - -#endif /* DISAS_DIS_ASM_H */ diff --git a/qemu/target/ppc/translate_init.inc.c b/qemu/target/ppc/translate_init.inc.c index a2d5c587..caef69be 100644 --- a/qemu/target/ppc/translate_init.inc.c +++ b/qemu/target/ppc/translate_init.inc.c @@ -27,7 +27,6 @@ #include "mmu-book3s-v3.h" #include "qemu/cutils.h" #include "fpu/softfloat.h" -#include "disas/dis-asm.h" /* * Generic callbacks: @@ -3456,7 +3455,6 @@ POWERPC_FAMILY(401)(CPUClass *oc, void *data) pcc->mmu_model = POWERPC_MMU_REAL; pcc->excp_model = POWERPC_EXCP_40x; pcc->bus_model = PPC_FLAGS_INPUT_401; - pcc->bfd_mach = bfd_mach_ppc_403; pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK; } @@ -3511,7 +3509,6 @@ POWERPC_FAMILY(401x2)(CPUClass *oc, void *data) pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z; pcc->excp_model = POWERPC_EXCP_40x; pcc->bus_model = PPC_FLAGS_INPUT_401; - pcc->bfd_mach = bfd_mach_ppc_403; pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK; } @@ -3564,7 +3561,6 @@ POWERPC_FAMILY(401x3)(CPUClass *oc, void *data) pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z; pcc->excp_model = POWERPC_EXCP_40x; pcc->bus_model = PPC_FLAGS_INPUT_401; - pcc->bfd_mach = bfd_mach_ppc_403; pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK; } @@ -3620,7 +3616,6 @@ POWERPC_FAMILY(IOP480)(CPUClass *oc, void *data) pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z; pcc->excp_model = POWERPC_EXCP_40x; pcc->bus_model = PPC_FLAGS_INPUT_401; - pcc->bfd_mach = bfd_mach_ppc_403; pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK; } @@ -3666,7 +3661,6 @@ POWERPC_FAMILY(403)(CPUClass *oc, void *data) pcc->mmu_model = POWERPC_MMU_REAL; pcc->excp_model = POWERPC_EXCP_40x; pcc->bus_model = PPC_FLAGS_INPUT_401; - pcc->bfd_mach = bfd_mach_ppc_403; pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_PX | POWERPC_FLAG_BUS_CLK; } @@ -3730,7 +3724,6 @@ POWERPC_FAMILY(403GCX)(CPUClass *oc, void *data) pcc->mmu_model = POWERPC_MMU_SOFT_4xx_Z; pcc->excp_model = POWERPC_EXCP_40x; pcc->bus_model = PPC_FLAGS_INPUT_401; - pcc->bfd_mach = bfd_mach_ppc_403; pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_PX | POWERPC_FLAG_BUS_CLK; } @@ -3794,7 +3787,6 @@ POWERPC_FAMILY(405)(CPUClass *oc, void *data) pcc->mmu_model = POWERPC_MMU_SOFT_4xx; pcc->excp_model = POWERPC_EXCP_40x; pcc->bus_model = PPC_FLAGS_INPUT_405; - pcc->bfd_mach = bfd_mach_ppc_403; pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE | POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK; } @@ -3896,7 +3888,6 @@ POWERPC_FAMILY(440EP)(CPUClass *oc, void *data) pcc->mmu_model = POWERPC_MMU_BOOKE; pcc->excp_model = POWERPC_EXCP_BOOKE; pcc->bus_model = PPC_FLAGS_INPUT_BookE; - pcc->bfd_mach = bfd_mach_ppc_403; pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE | POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK; } @@ -3933,7 +3924,6 @@ POWERPC_FAMILY(460EX)(CPUClass *oc, void *data) pcc->mmu_model = POWERPC_MMU_BOOKE; pcc->excp_model = POWERPC_EXCP_BOOKE; pcc->bus_model = PPC_FLAGS_INPUT_BookE; - pcc->bfd_mach = bfd_mach_ppc_403; pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE | POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK; } @@ -4015,7 +4005,6 @@ POWERPC_FAMILY(440GP)(CPUClass *oc, void *data) pcc->mmu_model = POWERPC_MMU_BOOKE; pcc->excp_model = POWERPC_EXCP_BOOKE; pcc->bus_model = PPC_FLAGS_INPUT_BookE; - pcc->bfd_mach = bfd_mach_ppc_403; pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE | POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK; } @@ -4098,7 +4087,6 @@ POWERPC_FAMILY(440x4)(CPUClass *oc, void *data) pcc->mmu_model = POWERPC_MMU_BOOKE; pcc->excp_model = POWERPC_EXCP_BOOKE; pcc->bus_model = PPC_FLAGS_INPUT_BookE; - pcc->bfd_mach = bfd_mach_ppc_403; pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE | POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK; } @@ -4198,7 +4186,6 @@ POWERPC_FAMILY(440x5)(CPUClass *oc, void *data) pcc->mmu_model = POWERPC_MMU_BOOKE; pcc->excp_model = POWERPC_EXCP_BOOKE; pcc->bus_model = PPC_FLAGS_INPUT_BookE; - pcc->bfd_mach = bfd_mach_ppc_403; pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE | POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK; } @@ -4235,7 +4222,6 @@ POWERPC_FAMILY(440x5wDFPU)(CPUClass *oc, void *data) pcc->mmu_model = POWERPC_MMU_BOOKE; pcc->excp_model = POWERPC_EXCP_BOOKE; pcc->bus_model = PPC_FLAGS_INPUT_BookE; - pcc->bfd_mach = bfd_mach_ppc_403; pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DWE | POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK; } @@ -4279,7 +4265,6 @@ POWERPC_FAMILY(MPC5xx)(CPUClass *oc, void *data) pcc->mmu_model = POWERPC_MMU_REAL; pcc->excp_model = POWERPC_EXCP_603; pcc->bus_model = PPC_FLAGS_INPUT_RCPU; - pcc->bfd_mach = bfd_mach_ppc_505; pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK; } @@ -4323,7 +4308,6 @@ POWERPC_FAMILY(MPC8xx)(CPUClass *oc, void *data) pcc->mmu_model = POWERPC_MMU_MPC8xx; pcc->excp_model = POWERPC_EXCP_603; pcc->bus_model = PPC_FLAGS_INPUT_RCPU; - pcc->bfd_mach = bfd_mach_ppc_860; pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK; } @@ -4404,7 +4388,6 @@ POWERPC_FAMILY(G2)(CPUClass *oc, void *data) pcc->mmu_model = POWERPC_MMU_SOFT_6xx; pcc->excp_model = POWERPC_EXCP_G2; pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_ec603e; pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK; } @@ -4485,7 +4468,6 @@ POWERPC_FAMILY(G2LE)(CPUClass *oc, void *data) pcc->mmu_model = POWERPC_MMU_SOFT_6xx; pcc->excp_model = POWERPC_EXCP_G2; pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_ec603e; pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK; } @@ -4637,7 +4619,6 @@ POWERPC_FAMILY(e200)(CPUClass *oc, void *data) pcc->mmu_model = POWERPC_MMU_BOOKE206; pcc->excp_model = POWERPC_EXCP_BOOKE; pcc->bus_model = PPC_FLAGS_INPUT_BookE; - pcc->bfd_mach = bfd_mach_ppc_860; pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE | POWERPC_FLAG_UBLE | POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK; @@ -4737,7 +4718,6 @@ POWERPC_FAMILY(e300)(CPUClass *oc, void *data) pcc->mmu_model = POWERPC_MMU_SOFT_6xx; pcc->excp_model = POWERPC_EXCP_603; pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_603; pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK; } @@ -5024,7 +5004,6 @@ POWERPC_FAMILY(e500v1)(CPUClass *oc, void *data) pcc->mmu_model = POWERPC_MMU_BOOKE206; pcc->excp_model = POWERPC_EXCP_BOOKE; pcc->bus_model = PPC_FLAGS_INPUT_BookE; - pcc->bfd_mach = bfd_mach_ppc_860; pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE | POWERPC_FLAG_UBLE | POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK; @@ -5071,7 +5050,6 @@ POWERPC_FAMILY(e500v2)(CPUClass *oc, void *data) #endif pcc->excp_model = POWERPC_EXCP_BOOKE; pcc->bus_model = PPC_FLAGS_INPUT_BookE; - pcc->bfd_mach = bfd_mach_ppc_860; pcc->flags = POWERPC_FLAG_SPE | POWERPC_FLAG_CE | POWERPC_FLAG_UBLE | POWERPC_FLAG_DE | POWERPC_FLAG_BUS_CLK; @@ -5116,7 +5094,6 @@ POWERPC_FAMILY(e500mc)(CPUClass *oc, void *data) pcc->excp_model = POWERPC_EXCP_BOOKE; pcc->bus_model = PPC_FLAGS_INPUT_BookE; /* FIXME: figure out the correct flag for e500mc */ - pcc->bfd_mach = bfd_mach_ppc_e500; pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE | POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; } @@ -5164,7 +5141,6 @@ POWERPC_FAMILY(e5500)(CPUClass *oc, void *data) pcc->excp_model = POWERPC_EXCP_BOOKE; pcc->bus_model = PPC_FLAGS_INPUT_BookE; /* FIXME: figure out the correct flag for e5500 */ - pcc->bfd_mach = bfd_mach_ppc_e500; pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE | POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; } @@ -5211,7 +5187,6 @@ POWERPC_FAMILY(e6500)(CPUClass *oc, void *data) pcc->mmu_model = POWERPC_MMU_BOOKE206; pcc->excp_model = POWERPC_EXCP_BOOKE; pcc->bus_model = PPC_FLAGS_INPUT_BookE; - pcc->bfd_mach = bfd_mach_ppc_e500; pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_DE | POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_VRE; } @@ -5287,7 +5262,6 @@ POWERPC_FAMILY(601)(CPUClass *oc, void *data) pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault; pcc->excp_model = POWERPC_EXCP_601; pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_601; pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_RTC_CLK; } @@ -5328,7 +5302,6 @@ POWERPC_FAMILY(601v)(CPUClass *oc, void *data) pcc->mmu_model = POWERPC_MMU_601; pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault; pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_601; pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_RTC_CLK; } @@ -5396,7 +5369,6 @@ POWERPC_FAMILY(602)(CPUClass *oc, void *data) pcc->mmu_model = POWERPC_MMU_SOFT_6xx; pcc->excp_model = POWERPC_EXCP_602; pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_602; pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK; } @@ -5462,7 +5434,6 @@ POWERPC_FAMILY(603)(CPUClass *oc, void *data) pcc->mmu_model = POWERPC_MMU_SOFT_6xx; pcc->excp_model = POWERPC_EXCP_603; pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_603; pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK; } @@ -5528,7 +5499,6 @@ POWERPC_FAMILY(603E)(CPUClass *oc, void *data) pcc->mmu_model = POWERPC_MMU_SOFT_6xx; pcc->excp_model = POWERPC_EXCP_603E; pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_ec603e; pcc->flags = POWERPC_FLAG_TGPR | POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_BUS_CLK; } @@ -5589,7 +5559,6 @@ POWERPC_FAMILY(604)(CPUClass *oc, void *data) pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault; pcc->excp_model = POWERPC_EXCP_604; pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_604; pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; } @@ -5670,7 +5639,6 @@ POWERPC_FAMILY(604E)(CPUClass *oc, void *data) pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault; pcc->excp_model = POWERPC_EXCP_604; pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_604; pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; } @@ -5738,7 +5706,6 @@ POWERPC_FAMILY(740)(CPUClass *oc, void *data) pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault; pcc->excp_model = POWERPC_EXCP_7x0; pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_750; pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; } @@ -5815,7 +5782,6 @@ POWERPC_FAMILY(750)(CPUClass *oc, void *data) pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault; pcc->excp_model = POWERPC_EXCP_7x0; pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_750; pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; } @@ -6015,7 +5981,6 @@ POWERPC_FAMILY(750cl)(CPUClass *oc, void *data) pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault; pcc->excp_model = POWERPC_EXCP_7x0; pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_750; pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; } @@ -6095,7 +6060,6 @@ POWERPC_FAMILY(750cx)(CPUClass *oc, void *data) pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault; pcc->excp_model = POWERPC_EXCP_7x0; pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_750; pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; } @@ -6180,7 +6144,6 @@ POWERPC_FAMILY(750fx)(CPUClass *oc, void *data) pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault; pcc->excp_model = POWERPC_EXCP_7x0; pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_750; pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; } @@ -6265,7 +6228,6 @@ POWERPC_FAMILY(750gx)(CPUClass *oc, void *data) pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault; pcc->excp_model = POWERPC_EXCP_7x0; pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_750; pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; } @@ -6340,7 +6302,6 @@ POWERPC_FAMILY(745)(CPUClass *oc, void *data) pcc->mmu_model = POWERPC_MMU_SOFT_6xx; pcc->excp_model = POWERPC_EXCP_7x5; pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_750; pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; } @@ -6426,7 +6387,6 @@ POWERPC_FAMILY(755)(CPUClass *oc, void *data) pcc->mmu_model = POWERPC_MMU_SOFT_6xx; pcc->excp_model = POWERPC_EXCP_7x5; pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_750; pcc->flags = POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; } @@ -6501,7 +6461,6 @@ POWERPC_FAMILY(7400)(CPUClass *oc, void *data) pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault; pcc->excp_model = POWERPC_EXCP_74xx; pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_7400; pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; @@ -6583,7 +6542,6 @@ POWERPC_FAMILY(7410)(CPUClass *oc, void *data) pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault; pcc->excp_model = POWERPC_EXCP_74xx; pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_7400; pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; @@ -6690,7 +6648,6 @@ POWERPC_FAMILY(7440)(CPUClass *oc, void *data) pcc->mmu_model = POWERPC_MMU_SOFT_74xx; pcc->excp_model = POWERPC_EXCP_74xx; pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_7400; pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; @@ -6823,7 +6780,6 @@ POWERPC_FAMILY(7450)(CPUClass *oc, void *data) pcc->mmu_model = POWERPC_MMU_SOFT_74xx; pcc->excp_model = POWERPC_EXCP_74xx; pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_7400; pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; @@ -6959,7 +6915,6 @@ POWERPC_FAMILY(7445)(CPUClass *oc, void *data) pcc->mmu_model = POWERPC_MMU_SOFT_74xx; pcc->excp_model = POWERPC_EXCP_74xx; pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_7400; pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; @@ -7097,7 +7052,6 @@ POWERPC_FAMILY(7455)(CPUClass *oc, void *data) pcc->mmu_model = POWERPC_MMU_SOFT_74xx; pcc->excp_model = POWERPC_EXCP_74xx; pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_7400; pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; @@ -7260,7 +7214,6 @@ POWERPC_FAMILY(7457)(CPUClass *oc, void *data) pcc->mmu_model = POWERPC_MMU_SOFT_74xx; pcc->excp_model = POWERPC_EXCP_74xx; pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_7400; pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; @@ -7400,7 +7353,6 @@ POWERPC_FAMILY(e600)(CPUClass *oc, void *data) pcc->handle_mmu_fault = ppc_hash32_handle_mmu_fault; pcc->excp_model = POWERPC_EXCP_74xx; pcc->bus_model = PPC_FLAGS_INPUT_6xx; - pcc->bfd_mach = bfd_mach_ppc_7400; pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; @@ -8264,7 +8216,6 @@ POWERPC_FAMILY(970)(CPUClass *oc, void *data) pcc->hash64_opts = &ppc_hash64_opts_basic; pcc->excp_model = POWERPC_EXCP_970; pcc->bus_model = PPC_FLAGS_INPUT_970; - pcc->bfd_mach = bfd_mach_ppc64; pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; @@ -8340,7 +8291,6 @@ POWERPC_FAMILY(POWER5P)(CPUClass *oc, void *data) pcc->lrg_decr_bits = 32; pcc->excp_model = POWERPC_EXCP_970; pcc->bus_model = PPC_FLAGS_INPUT_970; - pcc->bfd_mach = bfd_mach_ppc64; pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; @@ -8481,7 +8431,6 @@ POWERPC_FAMILY(POWER7)(CPUClass *oc, void *data) pcc->lrg_decr_bits = 32; pcc->excp_model = POWERPC_EXCP_POWER7; pcc->bus_model = PPC_FLAGS_INPUT_POWER7; - pcc->bfd_mach = bfd_mach_ppc64; pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR | @@ -8656,7 +8605,6 @@ POWERPC_FAMILY(POWER8)(CPUClass *oc, void *data) pcc->n_host_threads = 8; pcc->excp_model = POWERPC_EXCP_POWER8; pcc->bus_model = PPC_FLAGS_INPUT_POWER7; - pcc->bfd_mach = bfd_mach_ppc64; pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR | @@ -8869,7 +8817,6 @@ POWERPC_FAMILY(POWER9)(CPUClass *oc, void *data) pcc->n_host_threads = 4; pcc->excp_model = POWERPC_EXCP_POWER9; pcc->bus_model = PPC_FLAGS_INPUT_POWER9; - pcc->bfd_mach = bfd_mach_ppc64; pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR | @@ -9080,7 +9027,6 @@ POWERPC_FAMILY(POWER10)(CPUClass *oc, void *data) pcc->lrg_decr_bits = 56; pcc->excp_model = POWERPC_EXCP_POWER9; pcc->bus_model = PPC_FLAGS_INPUT_POWER9; - pcc->bfd_mach = bfd_mach_ppc64; pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK | POWERPC_FLAG_CFAR | @@ -10257,7 +10203,6 @@ static void ppc_cpu_instance_init(struct uc_struct *uc, CPUState *obj) env->insns_flags = pcc->insns_flags; env->insns_flags2 = pcc->insns_flags2; env->flags = pcc->flags; - env->bfd_mach = pcc->bfd_mach; env->check_pow = pcc->check_pow; /* @@ -10290,74 +10235,12 @@ static bool ppc_pvr_match_default(PowerPCCPUClass *pcc, uint32_t pvr) return pcc->pvr == pvr; } -#if 0 -static gchar *ppc_gdb_arch_name(CPUState *cs) -{ -#if defined(TARGET_PPC64) - return g_strdup("powerpc:common64"); -#else - return g_strdup("powerpc:common"); -#endif -} - -static void ppc_disas_set_info(CPUState *cs, disassemble_info *info) -{ - PowerPCCPU *cpu = POWERPC_CPU(cs); - CPUPPCState *env = &cpu->env; - - if ((env->hflags >> MSR_LE) & 1) { - info->endian = BFD_ENDIAN_LITTLE; - } - info->mach = env->bfd_mach; - if (!env->bfd_mach) { -#ifdef TARGET_PPC64 - info->mach = bfd_mach_ppc64; -#else - info->mach = bfd_mach_ppc; -#endif - } - info->disassembler_options = (char *)"any"; - info->print_insn = print_insn_ppc; - - info->cap_arch = CS_ARCH_PPC; -#ifdef TARGET_PPC64 - info->cap_mode = CS_MODE_64; -#endif -} - -static Property ppc_cpu_properties[] = { - DEFINE_PROP_BOOL("pre-2.8-migration", PowerPCCPU, pre_2_8_migration, false), - DEFINE_PROP_BOOL("pre-2.10-migration", PowerPCCPU, pre_2_10_migration, - false), - DEFINE_PROP_BOOL("pre-3.0-migration", PowerPCCPU, pre_3_0_migration, - false), - DEFINE_PROP_END_OF_LIST(), -}; -#endif - static void ppc_cpu_class_init(struct uc_struct *uc, CPUClass *oc) { PowerPCCPUClass *pcc = POWERPC_CPU_CLASS(oc); CPUClass *cc = CPU_CLASS(oc); -#if 0 - DeviceClass *dc = DEVICE_CLASS(oc); - - device_class_set_parent_realize(dc, ppc_cpu_realize, - &pcc->parent_realize); - device_class_set_parent_unrealize(dc, ppc_cpu_unrealize, - &pcc->parent_unrealize); -#endif pcc->pvr_match = ppc_pvr_match_default; pcc->interrupts_big_endian = ppc_cpu_interrupts_big_endian_always; -#if 0 - device_class_set_props(dc, ppc_cpu_properties); - - device_class_set_parent_reset(dc, ppc_cpu_reset, &pcc->parent_reset); - - cc->class_by_name = ppc_cpu_class_by_name; - pcc->parent_parse_features = cc->parse_features; - cc->parse_features = ppc_cpu_parse_featurestr; -#endif /* parent class is CPUClass, parent_reset() is cpu_common_reset(). */ pcc->parent_reset = cc->reset; /* overwrite the CPUClass->reset to arch reset: arm_cpu_reset(). */ @@ -10366,47 +10249,13 @@ static void ppc_cpu_class_init(struct uc_struct *uc, CPUClass *oc) cc->has_work = ppc_cpu_has_work; cc->do_interrupt = ppc_cpu_do_interrupt; cc->cpu_exec_interrupt = ppc_cpu_exec_interrupt; -#if 0 - cc->dump_state = ppc_cpu_dump_state; - cc->dump_statistics = ppc_cpu_dump_statistics; -#endif cc->set_pc = ppc_cpu_set_pc; -#if 0 - cc->gdb_read_register = ppc_cpu_gdb_read_register; - cc->gdb_write_register = ppc_cpu_gdb_write_register; -#endif cc->do_unaligned_access = ppc_cpu_do_unaligned_access; cc->get_phys_page_debug = ppc_cpu_get_phys_page_debug; -#if 0 - cc->vmsd = &vmstate_ppc_cpu; - cc->write_elf64_note = ppc64_cpu_write_elf64_note; - cc->write_elf32_note = ppc32_cpu_write_elf32_note; - - cc->gdb_num_core_regs = 71; - cc->gdb_get_dynamic_xml = ppc_gdb_get_dynamic_xml; -#ifdef USE_APPLE_GDB - cc->gdb_read_register = ppc_cpu_gdb_read_register_apple; - cc->gdb_write_register = ppc_cpu_gdb_write_register_apple; - cc->gdb_num_core_regs = 71 + 32; -#endif - - cc->gdb_arch_name = ppc_gdb_arch_name; -#if defined(TARGET_PPC64) - cc->gdb_core_xml_file = "power64-core.xml"; -#else - cc->gdb_core_xml_file = "power-core.xml"; -#endif - cc->virtio_is_big_endian = ppc_cpu_is_big_endian; -#endif cc->tcg_initialize = ppc_translate_init; cc->tlb_fill = ppc_cpu_tlb_fill; cc->cpu_exec_enter = ppc_cpu_exec_enter; cc->cpu_exec_exit = ppc_cpu_exec_exit; - -#if 0 - cc->disas_set_info = ppc_disas_set_info; - dc->fw_name = "PowerPC,UNKNOWN"; -#endif } /* PowerPC CPU definitions from cpu-models.c*/ From 81baee2b1cd1443e986a4b19f7a404652c5a0ea0 Mon Sep 17 00:00:00 2001 From: TSRBerry <20988865+TSRBerry@users.noreply.github.com> Date: Thu, 15 Dec 2022 17:24:53 +0100 Subject: [PATCH 13/43] gha: Fix master branch check --- .github/workflows/Nuget-publishing.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/Nuget-publishing.yml b/.github/workflows/Nuget-publishing.yml index e0edb5f1..fe8b17de 100644 --- a/.github/workflows/Nuget-publishing.yml +++ b/.github/workflows/Nuget-publishing.yml @@ -416,7 +416,7 @@ jobs: - name: Package .NET distribution working-directory: bindings/dotnet/UnicornEngine run: | - [[ "${{ github.event.workflow_run.head_branch }}" == "master" ]] \ + [[ "${{ github.ref_name }}" == "master" ]] \ && dotnet pack -c Release \ || dotnet pack -c Release --version-suffix="${{ steps.git_short_sha.outputs.result }}" From ca7449791101874ed72765f25da6e3e1e3869b0d Mon Sep 17 00:00:00 2001 From: deadash Date: Thu, 29 Dec 2022 14:43:54 +0800 Subject: [PATCH 14/43] Add arch list feature control in Rust Signed-off-by: deadash --- Cargo.toml | 15 +++++++++++++-- bindings/rust/build.rs | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 2 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 3d6d388d..46253df6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -39,5 +39,16 @@ cmake = { version = "0.1" } pkg-config = { version = "0.3" } [features] -default = [] -dynamic_linkage = [] \ No newline at end of file +default = ["arch_all"] +dynamic_linkage = [] +arch_all = ["arch_x86", "arch_arm", "arch_aarch64", "arch_riscv", "arch_mips", "arch_sparc", "arch_m68k", "arch_ppc", "arch_s390x", "arch_tricore"] +arch_x86 = [] +arch_arm = [] +arch_aarch64 = [] +arch_riscv = [] +arch_mips = [] +arch_sparc = [] +arch_m68k = [] +arch_ppc = [] +arch_s390x = [] +arch_tricore = [] \ No newline at end of file diff --git a/bindings/rust/build.rs b/bindings/rust/build.rs index 1f5e2251..04f5431a 100644 --- a/bindings/rust/build.rs +++ b/bindings/rust/build.rs @@ -84,6 +84,43 @@ fn build_with_cmake() { config.generator("Ninja"); } + let mut archs = String::new(); + + if std::env::var("CARGO_FEATURE_ARCH_X86").is_ok() { + archs.push_str("x86;"); + } + if std::env::var("CARGO_FEATURE_ARCH_ARM").is_ok() { + archs.push_str("arm;"); + } + if std::env::var("CARGO_FEATURE_ARCH_AARCH64").is_ok() { + archs.push_str("aarch64;"); + } + if std::env::var("CARGO_FEATURE_ARCH_RISCV").is_ok() { + archs.push_str("riscv;"); + } + if std::env::var("CARGO_FEATURE_ARCH_MIPS").is_ok() { + archs.push_str("mips;"); + } + if std::env::var("CARGO_FEATURE_ARCH_SPARC").is_ok() { + archs.push_str("sparc;"); + } + if std::env::var("CARGO_FEATURE_ARCH_M68K").is_ok() { + archs.push_str("m68k;"); + } + if std::env::var("CARGO_FEATURE_ARCH_PPC").is_ok() { + archs.push_str("ppc;"); + } + if std::env::var("CARGO_FEATURE_ARCH_S390X").is_ok() { + archs.push_str("s390x;"); + } + if std::env::var("CARGO_FEATURE_ARCH_TRICORE").is_ok() { + archs.push_str("tricore;"); + } + + if !archs.is_empty() { + archs.pop(); + } + // need to clear build target and append "build" to the path because // unicorn's CMakeLists.txt doesn't properly support 'install', so we use // the build artifacts from the build directory, which cmake crate sets @@ -91,6 +128,7 @@ fn build_with_cmake() { let dst = config .define("UNICORN_BUILD_TESTS", "OFF") .define("UNICORN_INSTALL", "OFF") + .define("UNICORN_ARCH", archs) .no_build_target(true) .build(); println!( From 549f34f098853c871c12240936909a7b41b84cc4 Mon Sep 17 00:00:00 2001 From: Dominik Maier Date: Thu, 5 Jan 2023 18:10:09 +0100 Subject: [PATCH 15/43] Fix warning for ./setup.py (#1756) --- bindings/python/setup.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bindings/python/setup.py b/bindings/python/setup.py index 8c579ad3..e842db80 100755 --- a/bindings/python/setup.py +++ b/bindings/python/setup.py @@ -8,6 +8,7 @@ import subprocess import shutil import sys import platform +import setuptools from distutils import log from distutils.core import setup From 014cee5bd142f9211dbb86d93b104ef16b04e066 Mon Sep 17 00:00:00 2001 From: Luca Gladiator Date: Tue, 17 Jan 2023 13:49:27 +0100 Subject: [PATCH 16/43] Fix Rust binding memory leak --- bindings/rust/src/ffi.rs | 77 ++++++++++++++++++++++++++++------------ bindings/rust/src/lib.rs | 43 +++++++--------------- 2 files changed, 66 insertions(+), 54 deletions(-) diff --git a/bindings/rust/src/ffi.rs b/bindings/rust/src/ffi.rs index a4624a02..1aea7c20 100644 --- a/bindings/rust/src/ffi.rs +++ b/bindings/rust/src/ffi.rs @@ -1,10 +1,11 @@ #![allow(non_camel_case_types)] #![allow(dead_code)] -use crate::Unicorn; +use crate::{Unicorn, UnicornInner}; use super::unicorn_const::{uc_error, Arch, HookType, MemRegion, MemType, Mode, Query}; -use core::ffi::c_void; +use alloc::rc::Weak; +use core::{cell::UnsafeCell, ffi::c_void}; use libc::{c_char, c_int}; pub type uc_handle = *mut c_void; @@ -89,7 +90,7 @@ extern "C" { pub struct UcHook<'a, D: 'a, F: 'a> { pub callback: F, - pub uc: Unicorn<'a, D>, + pub uc: Weak>>, } pub trait IsUcHook<'a> {} @@ -106,8 +107,11 @@ where F: FnMut(&mut crate::Unicorn, u64, usize) -> u64, { let user_data = unsafe { &mut *user_data }; - debug_assert_eq!(uc, user_data.uc.get_handle()); - (user_data.callback)(&mut user_data.uc, offset, size) + let mut user_data_uc = Unicorn { + inner: user_data.uc.upgrade().unwrap(), + }; + debug_assert_eq!(uc, user_data_uc.get_handle()); + (user_data.callback)(&mut user_data_uc, offset, size) } pub extern "C" fn mmio_write_callback_proxy( @@ -120,8 +124,11 @@ pub extern "C" fn mmio_write_callback_proxy( F: FnMut(&mut crate::Unicorn, u64, usize, u64), { let user_data = unsafe { &mut *user_data }; - debug_assert_eq!(uc, user_data.uc.get_handle()); - (user_data.callback)(&mut user_data.uc, offset, size, value); + let mut user_data_uc = Unicorn { + inner: user_data.uc.upgrade().unwrap(), + }; + debug_assert_eq!(uc, user_data_uc.get_handle()); + (user_data.callback)(&mut user_data_uc, offset, size, value); } pub extern "C" fn code_hook_proxy( @@ -133,8 +140,11 @@ pub extern "C" fn code_hook_proxy( F: FnMut(&mut crate::Unicorn, u64, u32), { let user_data = unsafe { &mut *user_data }; - debug_assert_eq!(uc, user_data.uc.get_handle()); - (user_data.callback)(&mut user_data.uc, address, size); + let mut user_data_uc = Unicorn { + inner: user_data.uc.upgrade().unwrap(), + }; + debug_assert_eq!(uc, user_data_uc.get_handle()); + (user_data.callback)(&mut user_data_uc, address, size); } pub extern "C" fn block_hook_proxy( @@ -146,8 +156,11 @@ pub extern "C" fn block_hook_proxy( F: FnMut(&mut crate::Unicorn, u64, u32), { let user_data = unsafe { &mut *user_data }; - debug_assert_eq!(uc, user_data.uc.get_handle()); - (user_data.callback)(&mut user_data.uc, address, size); + let mut user_data_uc = Unicorn { + inner: user_data.uc.upgrade().unwrap(), + }; + debug_assert_eq!(uc, user_data_uc.get_handle()); + (user_data.callback)(&mut user_data_uc, address, size); } pub extern "C" fn mem_hook_proxy( @@ -162,8 +175,11 @@ where F: FnMut(&mut crate::Unicorn, MemType, u64, usize, i64) -> bool, { let user_data = unsafe { &mut *user_data }; - debug_assert_eq!(uc, user_data.uc.get_handle()); - (user_data.callback)(&mut user_data.uc, mem_type, address, size as usize, value) + let mut user_data_uc = Unicorn { + inner: user_data.uc.upgrade().unwrap(), + }; + debug_assert_eq!(uc, user_data_uc.get_handle()); + (user_data.callback)(&mut user_data_uc, mem_type, address, size as usize, value) } pub extern "C" fn intr_hook_proxy(uc: uc_handle, value: u32, user_data: *mut UcHook) @@ -171,8 +187,11 @@ where F: FnMut(&mut crate::Unicorn, u32), { let user_data = unsafe { &mut *user_data }; - debug_assert_eq!(uc, user_data.uc.get_handle()); - (user_data.callback)(&mut user_data.uc, value); + let mut user_data_uc = Unicorn { + inner: user_data.uc.upgrade().unwrap(), + }; + debug_assert_eq!(uc, user_data_uc.get_handle()); + (user_data.callback)(&mut user_data_uc, value); } pub extern "C" fn insn_in_hook_proxy( @@ -184,8 +203,11 @@ pub extern "C" fn insn_in_hook_proxy( F: FnMut(&mut crate::Unicorn, u32, usize) -> u32, { let user_data = unsafe { &mut *user_data }; - debug_assert_eq!(uc, user_data.uc.get_handle()); - (user_data.callback)(&mut user_data.uc, port, size); + let mut user_data_uc = Unicorn { + inner: user_data.uc.upgrade().unwrap(), + }; + debug_assert_eq!(uc, user_data_uc.get_handle()); + (user_data.callback)(&mut user_data_uc, port, size); } pub extern "C" fn insn_invalid_hook_proxy(uc: uc_handle, user_data: *mut UcHook) -> bool @@ -193,8 +215,11 @@ where F: FnMut(&mut crate::Unicorn) -> bool, { let user_data = unsafe { &mut *user_data }; - debug_assert_eq!(uc, user_data.uc.get_handle()); - (user_data.callback)(&mut user_data.uc) + let mut user_data_uc = Unicorn { + inner: user_data.uc.upgrade().unwrap(), + }; + debug_assert_eq!(uc, user_data_uc.get_handle()); + (user_data.callback)(&mut user_data_uc) } pub extern "C" fn insn_out_hook_proxy( @@ -207,8 +232,11 @@ pub extern "C" fn insn_out_hook_proxy( F: FnMut(&mut crate::Unicorn, u32, usize, u32), { let user_data = unsafe { &mut *user_data }; - debug_assert_eq!(uc, user_data.uc.get_handle()); - (user_data.callback)(&mut user_data.uc, port, size, value); + let mut user_data_uc = Unicorn { + inner: user_data.uc.upgrade().unwrap(), + }; + debug_assert_eq!(uc, user_data_uc.get_handle()); + (user_data.callback)(&mut user_data_uc, port, size, value); } pub extern "C" fn insn_sys_hook_proxy(uc: uc_handle, user_data: *mut UcHook) @@ -216,6 +244,9 @@ where F: FnMut(&mut crate::Unicorn), { let user_data = unsafe { &mut *user_data }; - debug_assert_eq!(uc, user_data.uc.get_handle()); - (user_data.callback)(&mut user_data.uc); + let mut user_data_uc = Unicorn { + inner: user_data.uc.upgrade().unwrap(), + }; + debug_assert_eq!(uc, user_data_uc.get_handle()); + (user_data.callback)(&mut user_data_uc); } diff --git a/bindings/rust/src/lib.rs b/bindings/rust/src/lib.rs index 7959e2d5..a71b9996 100644 --- a/bindings/rust/src/lib.rs +++ b/bindings/rust/src/lib.rs @@ -369,17 +369,13 @@ impl<'a, D> Unicorn<'a, D> { let mut read_data = read_callback.map(|c| { Box::new(ffi::UcHook { callback: c, - uc: Unicorn { - inner: self.inner.clone(), - }, + uc: Rc::downgrade(&self.inner), }) }); let mut write_data = write_callback.map(|c| { Box::new(ffi::UcHook { callback: c, - uc: Unicorn { - inner: self.inner.clone(), - }, + uc: Rc::downgrade(&self.inner), }) }); @@ -586,7 +582,8 @@ impl<'a, D> Unicorn<'a, D> { return Err(uc_error::ARCH); } - let err: uc_error = unsafe { ffi::uc_reg_read(self.get_handle(), curr_reg_id, value.as_mut_ptr() as _) }; + let err: uc_error = + unsafe { ffi::uc_reg_read(self.get_handle(), curr_reg_id, value.as_mut_ptr() as _) }; if err == uc_error::OK { boxed = value.into_boxed_slice(); @@ -622,9 +619,7 @@ impl<'a, D> Unicorn<'a, D> { let mut hook_ptr = core::ptr::null_mut(); let mut user_data = Box::new(ffi::UcHook { callback, - uc: Unicorn { - inner: self.inner.clone(), - }, + uc: Rc::downgrade(&self.inner), }); let err = unsafe { @@ -654,9 +649,7 @@ impl<'a, D> Unicorn<'a, D> { let mut hook_ptr = core::ptr::null_mut(); let mut user_data = Box::new(ffi::UcHook { callback, - uc: Unicorn { - inner: self.inner.clone(), - }, + uc: Rc::downgrade(&self.inner), }); let err = unsafe { @@ -697,9 +690,7 @@ impl<'a, D> Unicorn<'a, D> { let mut hook_ptr = core::ptr::null_mut(); let mut user_data = Box::new(ffi::UcHook { callback, - uc: Unicorn { - inner: self.inner.clone(), - }, + uc: Rc::downgrade(&self.inner), }); let err = unsafe { @@ -730,9 +721,7 @@ impl<'a, D> Unicorn<'a, D> { let mut hook_ptr = core::ptr::null_mut(); let mut user_data = Box::new(ffi::UcHook { callback, - uc: Unicorn { - inner: self.inner.clone(), - }, + uc: Rc::downgrade(&self.inner), }); let err = unsafe { @@ -763,9 +752,7 @@ impl<'a, D> Unicorn<'a, D> { let mut hook_ptr = core::ptr::null_mut(); let mut user_data = Box::new(ffi::UcHook { callback, - uc: Unicorn { - inner: self.inner.clone(), - }, + uc: Rc::downgrade(&self.inner), }); let err = unsafe { @@ -796,9 +783,7 @@ impl<'a, D> Unicorn<'a, D> { let mut hook_ptr = core::ptr::null_mut(); let mut user_data = Box::new(ffi::UcHook { callback, - uc: Unicorn { - inner: self.inner.clone(), - }, + uc: Rc::downgrade(&self.inner), }); let err = unsafe { @@ -830,9 +815,7 @@ impl<'a, D> Unicorn<'a, D> { let mut hook_ptr = core::ptr::null_mut(); let mut user_data = Box::new(ffi::UcHook { callback, - uc: Unicorn { - inner: self.inner.clone(), - }, + uc: Rc::downgrade(&self.inner), }); let err = unsafe { @@ -870,9 +853,7 @@ impl<'a, D> Unicorn<'a, D> { let mut hook_ptr = core::ptr::null_mut(); let mut user_data = Box::new(ffi::UcHook { callback, - uc: Unicorn { - inner: self.inner.clone(), - }, + uc: Rc::downgrade(&self.inner), }); let err = unsafe { From a490ece557606497db1b470d2371ec6a7891911f Mon Sep 17 00:00:00 2001 From: "Takacs, Philipp" Date: Wed, 18 Jan 2023 16:15:36 +0100 Subject: [PATCH 17/43] Do not search for the RAMBlock in split_region The MemoryRegion already contains a pointer to the RAMBlock. So it is not necesary to search for it. --- uc.c | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/uc.c b/uc.c index 667f40ca..964137f8 100644 --- a/uc.c +++ b/uc.c @@ -1254,14 +1254,7 @@ static bool split_region(struct uc_struct *uc, MemoryRegion *mr, // Find the correct and large enough (which contains our target mr) // to create the content backup. - QLIST_FOREACH(block, &uc->ram_list.blocks, next) - { - // block->offset is the offset within ram_addr_t, not GPA - if (block->mr->addr <= mr->addr && - block->used_length + block->mr->addr >= mr->end) { - break; - } - } + block = mr->ram_block; if (block == NULL) { return false; @@ -2431,4 +2424,4 @@ void trace_end(uc_tracer *tracer, trace_loc loc, const char *fmt, ...) fprintf(stderr, "%.6fus\n", (double)(end - tracer->starts[loc]) / (double)(1000)); } -#endif \ No newline at end of file +#endif From aded30f5a87c07b33fbe6e9cff8cf47aa31ded31 Mon Sep 17 00:00:00 2001 From: Luca Gladiator Date: Sat, 21 Jan 2023 13:50:11 +0100 Subject: [PATCH 18/43] Fix insn_in_hook_proxy return type --- bindings/rust/src/ffi.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bindings/rust/src/ffi.rs b/bindings/rust/src/ffi.rs index 1aea7c20..b1c04f57 100644 --- a/bindings/rust/src/ffi.rs +++ b/bindings/rust/src/ffi.rs @@ -199,7 +199,8 @@ pub extern "C" fn insn_in_hook_proxy( port: u32, size: usize, user_data: *mut UcHook, -) where +) -> u32 +where F: FnMut(&mut crate::Unicorn, u32, usize) -> u32, { let user_data = unsafe { &mut *user_data }; @@ -207,7 +208,7 @@ pub extern "C" fn insn_in_hook_proxy( inner: user_data.uc.upgrade().unwrap(), }; debug_assert_eq!(uc, user_data_uc.get_handle()); - (user_data.callback)(&mut user_data_uc, port, size); + (user_data.callback)(&mut user_data_uc, port, size) } pub extern "C" fn insn_invalid_hook_proxy(uc: uc_handle, user_data: *mut UcHook) -> bool From ed9164e47ad2a62fd3f350f8bd5c2518c3a1c784 Mon Sep 17 00:00:00 2001 From: "Takacs, Philipp" Date: Mon, 23 Jan 2023 13:22:55 +0100 Subject: [PATCH 19/43] rust only add mmio callback funktion, if callback is requested The C function uc_mmio_map() allows to add seperate callback functions and userdata for read and write. When the callback functions are NULL unicorn don't try to call this functions. Previous this patch, when i.e. read_callback was None the callback was set to mmio_read_callback_proxy and the userdata was set to NULL. On a callback the mmio_read_callback_proxy then tried to dereference the userdata and caused a segfault. fixes #1762 --- bindings/rust/src/lib.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/bindings/rust/src/lib.rs b/bindings/rust/src/lib.rs index 7959e2d5..2aac940d 100644 --- a/bindings/rust/src/lib.rs +++ b/bindings/rust/src/lib.rs @@ -388,12 +388,18 @@ impl<'a, D> Unicorn<'a, D> { self.get_handle(), address, size, - ffi::mmio_read_callback_proxy:: as _, + match read_data { + Some(_) => ffi::mmio_read_callback_proxy:: as _, + None => ptr::null_mut(), + }, match read_data { Some(ref mut d) => d.as_mut() as *mut _ as _, None => ptr::null_mut(), }, - ffi::mmio_write_callback_proxy:: as _, + match write_data { + Some(_) => ffi::mmio_write_callback_proxy:: as _, + None => ptr::null_mut(), + }, match write_data { Some(ref mut d) => d.as_mut() as *mut _ as _, None => ptr::null_mut(), From 12a79192ee6a4ec5b69130ff3481ac64d93a9b25 Mon Sep 17 00:00:00 2001 From: mio Date: Sat, 28 Jan 2023 22:04:43 +0100 Subject: [PATCH 20/43] Demand paging on Windows --- msvc/config-host.h | 7 +++++++ qemu/accel/tcg/translate-all.c | 18 ++++++++++++++++++ qemu/include/hw/core/cpu.h | 1 + qemu/include/tcg/tcg.h | 5 +++++ qemu/tcg/tcg.c | 18 ++++++++++++++++++ 5 files changed, 49 insertions(+) diff --git a/msvc/config-host.h b/msvc/config-host.h index 943d8593..bf750d2d 100644 --- a/msvc/config-host.h +++ b/msvc/config-host.h @@ -7,3 +7,10 @@ #define CONFIG_CMPXCHG128 1 // #define CONFIG_ATOMIC64 1 #define CONFIG_PLUGIN 1 + +// QEMU by default allocates (and commits) 1GB memory on Windows, and multiple Unicorn instances will result in OOM error easily. +// Unfortunately, Windows doesn't have a similar demand paging feature like mmap(), therefore a workaround is to use tcg regions mechanism. +// Note most Unicorn hacks (and even QEMU!) relies on the assumption that the translation memory won't run out and thus it might result +// in some unexpected errors. If that is case, define to align with QEMU and Unicorn <= 2.0.1 behavior. +// +// #define USE_STATIC_CODE_GEN_BUFFER \ No newline at end of file diff --git a/qemu/accel/tcg/translate-all.c b/qemu/accel/tcg/translate-all.c index 91dd5ce7..aaebd4c5 100644 --- a/qemu/accel/tcg/translate-all.c +++ b/qemu/accel/tcg/translate-all.c @@ -869,6 +869,7 @@ static inline void *alloc_code_gen_buffer(struct uc_struct *uc) return buf; } #elif defined(_WIN32) +#ifdef USE_STATIC_CODE_GEN_BUFFER static inline void *alloc_code_gen_buffer(struct uc_struct *uc) { TCGContext *tcg_ctx = uc->tcg_ctx; @@ -876,6 +877,23 @@ static inline void *alloc_code_gen_buffer(struct uc_struct *uc) return VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE); } +#else +static inline void *alloc_code_gen_buffer(struct uc_struct *uc) +{ + TCGContext *tcg_ctx = uc->tcg_ctx; + size_t size = tcg_ctx->code_gen_buffer_size; + + void* ptr = VirtualAlloc(NULL, size, MEM_RESERVE, + PAGE_EXECUTE_READWRITE); + + // for prolog init + VirtualAlloc(ptr, + uc->qemu_real_host_page_size * UC_TCG_REGION_PAGES_COUNT, + MEM_COMMIT, + PAGE_EXECUTE_READWRITE); + return ptr; +} +#endif void free_code_gen_buffer(struct uc_struct *uc) { TCGContext *tcg_ctx = uc->tcg_ctx; diff --git a/qemu/include/hw/core/cpu.h b/qemu/include/hw/core/cpu.h index d1b7c250..097a7f63 100644 --- a/qemu/include/hw/core/cpu.h +++ b/qemu/include/hw/core/cpu.h @@ -20,6 +20,7 @@ #ifndef QEMU_CPU_H #define QEMU_CPU_H +#include #include "exec/hwaddr.h" #include "exec/memattrs.h" #include "qemu/bitmap.h" diff --git a/qemu/include/tcg/tcg.h b/qemu/include/tcg/tcg.h index f3643fe3..c7eb23ef 100644 --- a/qemu/include/tcg/tcg.h +++ b/qemu/include/tcg/tcg.h @@ -35,6 +35,11 @@ #include "tcg-apple-jit.h" #include "qemu/int128.h" +// Unicorn: Default region size for win32 +#if defined(_WIN32) && !defined(USE_STATIC_CODE_GEN_BUFFER) +#define UC_TCG_REGION_PAGES_COUNT (128) +#endif + /* XXX: make safe guess about sizes */ #define MAX_OP_PER_INSTR 266 diff --git a/qemu/tcg/tcg.c b/qemu/tcg/tcg.c index 4910c67c..d5fba106 100644 --- a/qemu/tcg/tcg.c +++ b/qemu/tcg/tcg.c @@ -23,6 +23,8 @@ */ /* define it to use liveness analysis (better code) */ +#include "tcg/tcg.h" +#include #define USE_TCG_OPTIMIZATIONS #include "qemu/osdep.h" @@ -406,6 +408,13 @@ static void tcg_region_assign(TCGContext *s, size_t curr_region) s->code_gen_buffer = start; s->code_gen_ptr = start; s->code_gen_buffer_size = (char *)end - (char *)start; +#if defined(WIN32) && !defined(USE_STATIC_CODE_GEN_BUFFER) + VirtualAlloc( + s->code_gen_buffer, + ROUND_UP(s->code_gen_buffer_size, s->uc->qemu_real_host_page_size), + MEM_COMMIT, + PAGE_EXECUTE_READWRITE); +#endif memset(s->code_gen_buffer, 0x00, s->code_gen_buffer_size); s->code_gen_highwater = (char *)end - TCG_HIGHWATER; } @@ -500,7 +509,11 @@ void tcg_region_init(TCGContext *tcg_ctx) size_t n_regions; size_t i; +#if defined(WIN32) && !defined(USE_STATIC_CODE_GEN_BUFFER) + n_regions = size / (tcg_ctx->uc->qemu_real_host_page_size * UC_TCG_REGION_PAGES_COUNT); +#else n_regions = 1; +#endif /* The first region will be 'aligned - buf' bytes larger than the others */ aligned = (void *)QEMU_ALIGN_PTR_UP(buf, page_size); @@ -537,6 +550,11 @@ void tcg_region_init(TCGContext *tcg_ctx) } tcg_ctx->tree = g_tree_new(tb_tc_cmp); + +#if defined(WIN32) && !defined(USE_STATIC_CODE_GEN_BUFFER) + // Allocate a region immediately, or the highwater is not set correctly. + tcg_region_alloc(tcg_ctx); +#endif } /* From 513e797d46a958e64f6ef5118a8861d694b60a8a Mon Sep 17 00:00:00 2001 From: mio Date: Sat, 28 Jan 2023 22:10:39 +0100 Subject: [PATCH 21/43] Update comments of the page count --- qemu/include/tcg/tcg.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qemu/include/tcg/tcg.h b/qemu/include/tcg/tcg.h index c7eb23ef..0b4f9a4c 100644 --- a/qemu/include/tcg/tcg.h +++ b/qemu/include/tcg/tcg.h @@ -37,7 +37,7 @@ // Unicorn: Default region size for win32 #if defined(_WIN32) && !defined(USE_STATIC_CODE_GEN_BUFFER) -#define UC_TCG_REGION_PAGES_COUNT (128) +#define UC_TCG_REGION_PAGES_COUNT (128) // Note less pages may cause unexpected and subtle errors. #endif /* XXX: make safe guess about sizes */ From a25adf84f0bdf82113c75d1c63baebe9d3ae994d Mon Sep 17 00:00:00 2001 From: mio Date: Sat, 28 Jan 2023 22:18:39 +0100 Subject: [PATCH 22/43] Rename flags to avoid confusion --- msvc/config-host.h | 4 ++-- qemu/accel/tcg/translate-all.c | 2 +- qemu/include/tcg/tcg.h | 2 +- qemu/tcg/tcg.c | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/msvc/config-host.h b/msvc/config-host.h index bf750d2d..a5e1e190 100644 --- a/msvc/config-host.h +++ b/msvc/config-host.h @@ -11,6 +11,6 @@ // QEMU by default allocates (and commits) 1GB memory on Windows, and multiple Unicorn instances will result in OOM error easily. // Unfortunately, Windows doesn't have a similar demand paging feature like mmap(), therefore a workaround is to use tcg regions mechanism. // Note most Unicorn hacks (and even QEMU!) relies on the assumption that the translation memory won't run out and thus it might result -// in some unexpected errors. If that is case, define to align with QEMU and Unicorn <= 2.0.1 behavior. +// in some unexpected errors. If that is case, define WIN32_QEMU_ALLOC_BUFFER to align with QEMU and Unicorn <= 2.0.1 behavior. // -// #define USE_STATIC_CODE_GEN_BUFFER \ No newline at end of file +// #define WIN32_QEMU_ALLOC_BUFFER \ No newline at end of file diff --git a/qemu/accel/tcg/translate-all.c b/qemu/accel/tcg/translate-all.c index aaebd4c5..56ddb35e 100644 --- a/qemu/accel/tcg/translate-all.c +++ b/qemu/accel/tcg/translate-all.c @@ -869,7 +869,7 @@ static inline void *alloc_code_gen_buffer(struct uc_struct *uc) return buf; } #elif defined(_WIN32) -#ifdef USE_STATIC_CODE_GEN_BUFFER +#ifdef WIN32_QEMU_ALLOC_BUFFER static inline void *alloc_code_gen_buffer(struct uc_struct *uc) { TCGContext *tcg_ctx = uc->tcg_ctx; diff --git a/qemu/include/tcg/tcg.h b/qemu/include/tcg/tcg.h index 0b4f9a4c..1134c75c 100644 --- a/qemu/include/tcg/tcg.h +++ b/qemu/include/tcg/tcg.h @@ -36,7 +36,7 @@ #include "qemu/int128.h" // Unicorn: Default region size for win32 -#if defined(_WIN32) && !defined(USE_STATIC_CODE_GEN_BUFFER) +#if defined(_WIN32) && !defined(WIN32_QEMU_ALLOC_BUFFER) #define UC_TCG_REGION_PAGES_COUNT (128) // Note less pages may cause unexpected and subtle errors. #endif diff --git a/qemu/tcg/tcg.c b/qemu/tcg/tcg.c index d5fba106..cb76f31a 100644 --- a/qemu/tcg/tcg.c +++ b/qemu/tcg/tcg.c @@ -408,7 +408,7 @@ static void tcg_region_assign(TCGContext *s, size_t curr_region) s->code_gen_buffer = start; s->code_gen_ptr = start; s->code_gen_buffer_size = (char *)end - (char *)start; -#if defined(WIN32) && !defined(USE_STATIC_CODE_GEN_BUFFER) +#if defined(WIN32) && !defined(WIN32_QEMU_ALLOC_BUFFER) VirtualAlloc( s->code_gen_buffer, ROUND_UP(s->code_gen_buffer_size, s->uc->qemu_real_host_page_size), @@ -509,7 +509,7 @@ void tcg_region_init(TCGContext *tcg_ctx) size_t n_regions; size_t i; -#if defined(WIN32) && !defined(USE_STATIC_CODE_GEN_BUFFER) +#if defined(WIN32) && !defined(WIN32_QEMU_ALLOC_BUFFER) n_regions = size / (tcg_ctx->uc->qemu_real_host_page_size * UC_TCG_REGION_PAGES_COUNT); #else n_regions = 1; @@ -551,7 +551,7 @@ void tcg_region_init(TCGContext *tcg_ctx) tcg_ctx->tree = g_tree_new(tb_tc_cmp); -#if defined(WIN32) && !defined(USE_STATIC_CODE_GEN_BUFFER) +#if defined(WIN32) && !defined(WIN32_QEMU_ALLOC_BUFFER) // Allocate a region immediately, or the highwater is not set correctly. tcg_region_alloc(tcg_ctx); #endif From cee8e6b5da3af9b699b4af44eb38e4b5ced2bb48 Mon Sep 17 00:00:00 2001 From: TSR Berry <20988865+TSRBerry@users.noreply.github.com> Date: Sun, 29 Jan 2023 00:47:46 +0100 Subject: [PATCH 23/43] gha: Add steps to upload nupkg as artifact & publish to Nuget --- .github/workflows/Nuget-publishing.yml | 47 ++++++++++++++++---------- 1 file changed, 29 insertions(+), 18 deletions(-) diff --git a/.github/workflows/Nuget-publishing.yml b/.github/workflows/Nuget-publishing.yml index fe8b17de..75abbf67 100644 --- a/.github/workflows/Nuget-publishing.yml +++ b/.github/workflows/Nuget-publishing.yml @@ -124,7 +124,7 @@ jobs: - name: '📤 Upload artifact' if: always() - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v2 with: path: ./${{ matrix.config.artifact }} name: ${{ matrix.config.artifact }} @@ -182,7 +182,7 @@ jobs: - name: '📤 Upload artifact' if: always() - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v2 with: path: ./${{ matrix.config.artifact }} name: ${{ matrix.config.artifact }} @@ -251,9 +251,9 @@ jobs: shell: 'script -q -e -c "bash {0}"' run: | if [ ${{ matrix.config.arch }} == 'x64' ]; then - sudo apt install -q -y libcmocka-dev ninja-build + sudo apt install -q -y libcmocka-dev ninja-build else - export CFLAGS="-m32" LDFLAGS="-m32" LDFLAGS_STATIC="-m32" UNICORN_QEMU_FLAGS="--cpu=i386" + export CFLAGS="-m32" LDFLAGS="-m32" LDFLAGS_STATIC="-m32" UNICORN_QEMU_FLAGS="--cpu=i386" sudo dpkg --add-architecture i386 sudo apt install -q -y lib32ncurses-dev lib32z1-dev lib32gcc-9-dev libc6-dev-i386 gcc-multilib \ libcmocka-dev:i386 libcmocka0:i386 libc6:i386 libgcc-s1:i386 ninja-build @@ -307,7 +307,7 @@ jobs: - name: '📤 Upload artifact' if: always() - uses: actions/upload-artifact@v1 + uses: actions/upload-artifact@v2 with: path: ./${{ matrix.config.artifact }} name: ${{ matrix.config.artifact }} @@ -320,20 +320,20 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Download artifacts + - name: 🛠️ Download artifacts uses: actions/download-artifact@v3 with: path: artifacts - - name: Extract artifacts + - name: 🛠️ Extract artifacts shell: python run: | import subprocess import os - + artifactPath = os.path.join(os.getcwd(), "artifacts") bindingsPath = os.path.join(os.getcwd(), "bindings", "dotnet", "UnicornEngine") - + ARTIFACT_CONFIG = { "ubuntu-cmake-aarch64.7z": { "sourceDir": "lib/", @@ -372,11 +372,11 @@ jobs: "destFile": "unicorn.dll" } } - + if len(os.listdir(artifactPath)) < len(ARTIFACT_CONFIG.keys()): print("Some artifacts are missing. Aborting.") exit(1) - + for artifact in os.listdir(artifactPath): if artifact in ARTIFACT_CONFIG.keys(): print("Working on:", artifact) @@ -384,20 +384,20 @@ jobs: destDir = os.path.join(bindingsPath, config["destDir"]) print("Creating dir:", destDir) os.makedirs(destDir, exist_ok=True) - + print(f"Extracting library from 7z file to: {config['destDir']}/{config['sourceFile']}") result = subprocess.run(["7z", "e", f"-o{destDir}/", os.path.join(artifactPath, artifact), f"{config['sourceDir']}{config['sourceFile']}"]) result.check_returncode() - + if config["sourceFile"] != config["destFile"]: output = subprocess.run(["ls", destDir], stdout=subprocess.PIPE) sourceFile = output.stdout.decode().strip() print(f"Renaming {sourceFile} to {config['destFile']}") os.rename(os.path.join(destDir, sourceFile), os.path.join(destDir, config["destFile"])) - + print("Done!") - - name: Get short sha + - name: 🛠️ Get short sha id: git_short_sha run: echo "result=$(git rev-parse --short "${{ github.sha }}")" >> $GITHUB_OUTPUT @@ -405,21 +405,32 @@ jobs: with: dotnet-version: 6.0.x - - name: Authenticate to Github Packages + - name: 🛠️ Authenticate to Github Packages working-directory: bindings/dotnet/UnicornEngine run: dotnet nuget add source --username "${{ github.repository_owner }}" --password "${{ secrets.GITHUB_TOKEN }}" --store-password-in-clear-text --name github "https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json" - - name: List all native libraries + - name: 🛠️ List all native libraries working-directory: bindings/dotnet/UnicornEngine run: find ./runtimes -type f -print - - name: Package .NET distribution + - name: 🚧 Package .NET distribution working-directory: bindings/dotnet/UnicornEngine run: | [[ "${{ github.ref_name }}" == "master" ]] \ && dotnet pack -c Release \ || dotnet pack -c Release --version-suffix="${{ steps.git_short_sha.outputs.result }}" + - name: '📤 Upload artifact' + uses: actions/upload-artifact@v2 + with: + path: ${{ github.workspace }}/bindings/dotnet/UnicornEngine/bin/Release/UnicornEngine.Unicorn.*.nupkg + - name: 📦 Publish to Github Packages working-directory: bindings/dotnet/UnicornEngine run: dotnet nuget push "bin/Release/UnicornEngine.Unicorn.*.nupkg" --source "github" --api-key "${{ secrets.GHPR_TOKEN }}" + + - name: 📦 Publish Nuget package + working-directory: bindings/dotnet/UnicornEngine + run: dotnet nuget push "bin/Release/UnicornEngine.Unicorn.*.nupkg" -k "$NUGET_AUTH_TOKEN" -s https://api.nuget.org/v3/index.json + env: + NUGET_AUTH_TOKEN: ${{ secrets.NUGET_KEY }} From 6e9c6aea5fd79ba271a388eef114ee6410674da1 Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Sat, 4 Feb 2023 13:00:58 +0800 Subject: [PATCH 24/43] bump version to 2.0.2 --- CMakeLists.txt | 2 +- Cargo.toml | 4 ++-- bindings/python/setup.py | 2 +- include/unicorn/unicorn.h | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4110ae53..d94bd464 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,7 +45,7 @@ set(CMAKE_C_STANDARD 11) set(UNICORN_VERSION_MAJOR 2) set(UNICORN_VERSION_MINOR 0) -set(UNICORN_VERSION_PATCH 1) +set(UNICORN_VERSION_PATCH 2) include(bundle_static.cmake) diff --git a/Cargo.toml b/Cargo.toml index 46253df6..6731d9e1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "unicorn-engine" -version = "2.0.1" +version = "2.0.2" authors = ["Ziqiao Kong", "Lukas Seidel"] documentation = "https://github.com/unicorn-engine/unicorn/wiki" edition = "2021" @@ -51,4 +51,4 @@ arch_sparc = [] arch_m68k = [] arch_ppc = [] arch_s390x = [] -arch_tricore = [] \ No newline at end of file +arch_tricore = [] diff --git a/bindings/python/setup.py b/bindings/python/setup.py index e842db80..b8cfbdfa 100755 --- a/bindings/python/setup.py +++ b/bindings/python/setup.py @@ -30,7 +30,7 @@ SRC_DIR = os.path.join(ROOT_DIR, 'src') UC_DIR = SRC_DIR if os.path.exists(SRC_DIR) else os.path.join(ROOT_DIR, '../..') BUILD_DIR = os.path.join(UC_DIR, 'build_python') -VERSION = "2.0.1.post1" +VERSION = "2.0.2" if SYSTEM == 'darwin': LIBRARY_FILE = "libunicorn.2.dylib" diff --git a/include/unicorn/unicorn.h b/include/unicorn/unicorn.h index 4b169d76..54ffd251 100644 --- a/include/unicorn/unicorn.h +++ b/include/unicorn/unicorn.h @@ -72,9 +72,9 @@ typedef size_t uc_hook; // Unicorn API version #define UC_API_MAJOR 2 #define UC_API_MINOR 0 -#define UC_API_PATCH 1 +#define UC_API_PATCH 2 // Release candidate version, 255 means the official release. -#define UC_API_EXTRA 255 +#define UC_API_EXTRA 1 // Unicorn package version #define UC_VERSION_MAJOR UC_API_MAJOR From 7ca4769f2abfb8a0f6bb253ea9a735195d1a59cc Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Sat, 4 Feb 2023 13:01:33 +0800 Subject: [PATCH 25/43] bindings: update version to 2.0.2 --- bindings/dotnet/UnicornManaged/Const/Common.fs | 8 ++++---- bindings/go/unicorn/unicorn_const.go | 8 ++++---- bindings/java/unicorn/UnicornConst.java | 8 ++++---- bindings/pascal/unicorn/UnicornConst.pas | 8 ++++---- bindings/python/unicorn/unicorn_const.py | 8 ++++---- .../ruby/unicorn_gem/lib/unicorn_engine/unicorn_const.rb | 8 ++++---- 6 files changed, 24 insertions(+), 24 deletions(-) diff --git a/bindings/dotnet/UnicornManaged/Const/Common.fs b/bindings/dotnet/UnicornManaged/Const/Common.fs index 72b5cb3a..d6b92eae 100644 --- a/bindings/dotnet/UnicornManaged/Const/Common.fs +++ b/bindings/dotnet/UnicornManaged/Const/Common.fs @@ -9,13 +9,13 @@ module Common = let UC_API_MAJOR = 2 let UC_API_MINOR = 0 - let UC_API_PATCH = 1 - let UC_API_EXTRA = 255 + let UC_API_PATCH = 2 + let UC_API_EXTRA = 1 let UC_VERSION_MAJOR = 2 let UC_VERSION_MINOR = 0 - let UC_VERSION_PATCH = 1 - let UC_VERSION_EXTRA = 255 + let UC_VERSION_PATCH = 2 + let UC_VERSION_EXTRA = 1 let UC_SECOND_SCALE = 1000000 let UC_MILISECOND_SCALE = 1000 let UC_ARCH_ARM = 1 diff --git a/bindings/go/unicorn/unicorn_const.go b/bindings/go/unicorn/unicorn_const.go index 19268ce5..34c97b4a 100644 --- a/bindings/go/unicorn/unicorn_const.go +++ b/bindings/go/unicorn/unicorn_const.go @@ -4,13 +4,13 @@ const ( API_MAJOR = 2 API_MINOR = 0 - API_PATCH = 1 - API_EXTRA = 255 + API_PATCH = 2 + API_EXTRA = 1 VERSION_MAJOR = 2 VERSION_MINOR = 0 - VERSION_PATCH = 1 - VERSION_EXTRA = 255 + VERSION_PATCH = 2 + VERSION_EXTRA = 1 SECOND_SCALE = 1000000 MILISECOND_SCALE = 1000 ARCH_ARM = 1 diff --git a/bindings/java/unicorn/UnicornConst.java b/bindings/java/unicorn/UnicornConst.java index 62759ba6..e63afb79 100644 --- a/bindings/java/unicorn/UnicornConst.java +++ b/bindings/java/unicorn/UnicornConst.java @@ -6,13 +6,13 @@ public interface UnicornConst { public static final int UC_API_MAJOR = 2; public static final int UC_API_MINOR = 0; - public static final int UC_API_PATCH = 1; - public static final int UC_API_EXTRA = 255; + public static final int UC_API_PATCH = 2; + public static final int UC_API_EXTRA = 1; public static final int UC_VERSION_MAJOR = 2; public static final int UC_VERSION_MINOR = 0; - public static final int UC_VERSION_PATCH = 1; - public static final int UC_VERSION_EXTRA = 255; + public static final int UC_VERSION_PATCH = 2; + public static final int UC_VERSION_EXTRA = 1; public static final int UC_SECOND_SCALE = 1000000; public static final int UC_MILISECOND_SCALE = 1000; public static final int UC_ARCH_ARM = 1; diff --git a/bindings/pascal/unicorn/UnicornConst.pas b/bindings/pascal/unicorn/UnicornConst.pas index 26896d13..2d75d4ae 100644 --- a/bindings/pascal/unicorn/UnicornConst.pas +++ b/bindings/pascal/unicorn/UnicornConst.pas @@ -7,13 +7,13 @@ interface const UC_API_MAJOR = 2; UC_API_MINOR = 0; - UC_API_PATCH = 1; - UC_API_EXTRA = 255; + UC_API_PATCH = 2; + UC_API_EXTRA = 1; UC_VERSION_MAJOR = 2; UC_VERSION_MINOR = 0; - UC_VERSION_PATCH = 1; - UC_VERSION_EXTRA = 255; + UC_VERSION_PATCH = 2; + UC_VERSION_EXTRA = 1; UC_SECOND_SCALE = 1000000; UC_MILISECOND_SCALE = 1000; UC_ARCH_ARM = 1; diff --git a/bindings/python/unicorn/unicorn_const.py b/bindings/python/unicorn/unicorn_const.py index f491dd26..96f2949b 100644 --- a/bindings/python/unicorn/unicorn_const.py +++ b/bindings/python/unicorn/unicorn_const.py @@ -2,13 +2,13 @@ UC_API_MAJOR = 2 UC_API_MINOR = 0 -UC_API_PATCH = 1 -UC_API_EXTRA = 255 +UC_API_PATCH = 2 +UC_API_EXTRA = 1 UC_VERSION_MAJOR = 2 UC_VERSION_MINOR = 0 -UC_VERSION_PATCH = 1 -UC_VERSION_EXTRA = 255 +UC_VERSION_PATCH = 2 +UC_VERSION_EXTRA = 1 UC_SECOND_SCALE = 1000000 UC_MILISECOND_SCALE = 1000 UC_ARCH_ARM = 1 diff --git a/bindings/ruby/unicorn_gem/lib/unicorn_engine/unicorn_const.rb b/bindings/ruby/unicorn_gem/lib/unicorn_engine/unicorn_const.rb index e317589e..6dbc46e0 100644 --- a/bindings/ruby/unicorn_gem/lib/unicorn_engine/unicorn_const.rb +++ b/bindings/ruby/unicorn_gem/lib/unicorn_engine/unicorn_const.rb @@ -4,13 +4,13 @@ module UnicornEngine UC_API_MAJOR = 2 UC_API_MINOR = 0 - UC_API_PATCH = 1 - UC_API_EXTRA = 255 + UC_API_PATCH = 2 + UC_API_EXTRA = 1 UC_VERSION_MAJOR = 2 UC_VERSION_MINOR = 0 - UC_VERSION_PATCH = 1 - UC_VERSION_EXTRA = 255 + UC_VERSION_PATCH = 2 + UC_VERSION_EXTRA = 1 UC_SECOND_SCALE = 1000000 UC_MILISECOND_SCALE = 1000 UC_ARCH_ARM = 1 From eb118528b189ed6c4980fcb408636d84188b232e Mon Sep 17 00:00:00 2001 From: Nguyen Anh Quynh Date: Mon, 6 Feb 2023 17:59:16 +0800 Subject: [PATCH 26/43] rename memory_mapping() to find_memory_region() and simplify mem_map() --- include/uc_priv.h | 2 +- qemu/accel/tcg/cputlb.c | 8 ++++---- uc.c | 38 ++++++++++++++++++-------------------- 3 files changed, 23 insertions(+), 25 deletions(-) diff --git a/include/uc_priv.h b/include/uc_priv.h index 030fadce..66b6e83e 100644 --- a/include/uc_priv.h +++ b/include/uc_priv.h @@ -409,7 +409,7 @@ struct uc_context { }; // check if this address is mapped in (via uc_mem_map()) -MemoryRegion *memory_mapping(struct uc_struct *uc, uint64_t address); +MemoryRegion *find_memory_region(struct uc_struct *uc, uint64_t address); // We have to support 32bit system so we can't hold uint64_t on void* static inline void uc_add_exit(uc_engine *uc, uint64_t addr) diff --git a/qemu/accel/tcg/cputlb.c b/qemu/accel/tcg/cputlb.c index 04c892a2..d591e9d1 100644 --- a/qemu/accel/tcg/cputlb.c +++ b/qemu/accel/tcg/cputlb.c @@ -1436,7 +1436,7 @@ load_helper(CPUArchState *env, target_ulong addr, TCGMemOpIdx oi, bool handled; HOOK_FOREACH_VAR_DECLARE; struct uc_struct *uc = env->uc; - MemoryRegion *mr = memory_mapping(uc, addr); + MemoryRegion *mr = find_memory_region(uc, addr); // memory might be still unmapped while reading or fetching if (mr == NULL) { @@ -1480,7 +1480,7 @@ load_helper(CPUArchState *env, target_ulong addr, TCGMemOpIdx oi, if (handled) { uc->invalid_error = UC_ERR_OK; - mr = memory_mapping(uc, addr); + mr = find_memory_region(uc, addr); if (mr == NULL) { uc->invalid_error = UC_ERR_MAP; cpu_exit(uc->cpu); @@ -2010,7 +2010,7 @@ store_helper(CPUArchState *env, target_ulong addr, uint64_t val, } // Load the latest memory mapping. - mr = memory_mapping(uc, addr); + mr = find_memory_region(uc, addr); // Unicorn: callback on invalid memory if (mr == NULL) { @@ -2037,7 +2037,7 @@ store_helper(CPUArchState *env, target_ulong addr, uint64_t val, return; } else { uc->invalid_error = UC_ERR_OK; - mr = memory_mapping(uc, addr); + mr = find_memory_region(uc, addr); if (mr == NULL) { uc->invalid_error = UC_ERR_MAP; cpu_exit(uc->cpu); diff --git a/uc.c b/uc.c index 964137f8..829dda95 100644 --- a/uc.c +++ b/uc.c @@ -552,7 +552,7 @@ static bool check_mem_area(uc_engine *uc, uint64_t address, size_t size) size_t count = 0, len; while (count < size) { - MemoryRegion *mr = memory_mapping(uc, address); + MemoryRegion *mr = find_memory_region(uc, address); if (mr) { len = (size_t)MIN(size - count, mr->end - address); count += len; @@ -587,7 +587,7 @@ uc_err uc_mem_read(uc_engine *uc, uint64_t address, void *_bytes, size_t size) // memory area can overlap adjacent memory blocks while (count < size) { - MemoryRegion *mr = memory_mapping(uc, address); + MemoryRegion *mr = find_memory_region(uc, address); if (mr) { len = (size_t)MIN(size - count, mr->end - address); if (uc->read_mem(&uc->address_space_memory, address, bytes, len) == @@ -632,7 +632,7 @@ uc_err uc_mem_write(uc_engine *uc, uint64_t address, const void *_bytes, // memory area can overlap adjacent memory blocks while (count < size) { - MemoryRegion *mr = memory_mapping(uc, address); + MemoryRegion *mr = find_memory_region(uc, address); if (mr) { uint32_t operms = mr->perms; if (!(operms & UC_PROT_WRITE)) { // write protected @@ -976,8 +976,7 @@ static bool memory_overlap(struct uc_struct *uc, uint64_t begin, size_t size) } // common setup/error checking shared between uc_mem_map and uc_mem_map_ptr -static uc_err mem_map(uc_engine *uc, uint64_t address, size_t size, - uint32_t perms, MemoryRegion *block) +static uc_err mem_map(uc_engine *uc, MemoryRegion *block) { MemoryRegion **regions; int pos; @@ -1060,8 +1059,7 @@ uc_err uc_mem_map(uc_engine *uc, uint64_t address, size_t size, uint32_t perms) return res; } - return mem_map(uc, address, size, perms, - uc->memory_map(uc, address, size, perms)); + return mem_map(uc, uc->memory_map(uc, address, size, perms)); } UNICORN_EXPORT @@ -1085,8 +1083,7 @@ uc_err uc_mem_map_ptr(uc_engine *uc, uint64_t address, size_t size, return res; } - return mem_map(uc, address, size, UC_PROT_ALL, - uc->memory_map_ptr(uc, address, size, perms, ptr)); + return mem_map(uc, uc->memory_map_ptr(uc, address, size, perms, ptr)); } UNICORN_EXPORT @@ -1108,9 +1105,8 @@ uc_err uc_mmio_map(uc_engine *uc, uint64_t address, size_t size, // The callbacks do not need to be checked for NULL here, as their presence // (or lack thereof) will determine the permissions used. - return mem_map(uc, address, size, UC_PROT_NONE, - uc->memory_map_io(uc, address, size, read_cb, write_cb, - user_data_read, user_data_write)); + return mem_map(uc, uc->memory_map_io(uc, address, size, read_cb, write_cb, + user_data_read, user_data_write)); } // Create a backup copy of the indicated MemoryRegion. @@ -1416,14 +1412,14 @@ uc_err uc_mem_protect(struct uc_struct *uc, uint64_t address, size_t size, addr = address; count = 0; while (count < size) { - mr = memory_mapping(uc, addr); + mr = find_memory_region(uc, addr); len = (size_t)MIN(size - count, mr->end - addr); if (mr->ram) { if (!split_region(uc, mr, addr, len, false)) { return UC_ERR_NOMEM; } - mr = memory_mapping(uc, addr); + mr = find_memory_region(uc, addr); // will this remove EXEC permission? if (((mr->perms & UC_PROT_EXEC) != 0) && ((perms & UC_PROT_EXEC) == 0)) { @@ -1437,7 +1433,7 @@ uc_err uc_mem_protect(struct uc_struct *uc, uint64_t address, size_t size, return UC_ERR_NOMEM; } - mr = memory_mapping(uc, addr); + mr = find_memory_region(uc, addr); mr->perms = perms; } @@ -1496,7 +1492,7 @@ uc_err uc_mem_unmap(struct uc_struct *uc, uint64_t address, size_t size) addr = address; count = 0; while (count < size) { - mr = memory_mapping(uc, addr); + mr = find_memory_region(uc, addr); len = (size_t)MIN(size - count, mr->end - addr); if (!mr->ram) { if (!split_mmio_region(uc, mr, addr, len, true)) { @@ -1510,7 +1506,7 @@ uc_err uc_mem_unmap(struct uc_struct *uc, uint64_t address, size_t size) // if we can retrieve the mapping, then no splitting took place // so unmap here - mr = memory_mapping(uc, addr); + mr = find_memory_region(uc, addr); if (mr != NULL) { uc->memory_unmap(uc, mr); } @@ -1522,7 +1518,7 @@ uc_err uc_mem_unmap(struct uc_struct *uc, uint64_t address, size_t size) } // find the memory region of this address -MemoryRegion *memory_mapping(struct uc_struct *uc, uint64_t address) +MemoryRegion *find_memory_region(struct uc_struct *uc, uint64_t address) { unsigned int i; @@ -1537,14 +1533,16 @@ MemoryRegion *memory_mapping(struct uc_struct *uc, uint64_t address) // try with the cache index first i = uc->mapped_block_cache_index; - if (i < uc->mapped_block_count && address >= uc->mapped_blocks[i]->addr && + if (i < uc->mapped_block_count && + address >= uc->mapped_blocks[i]->addr && address < uc->mapped_blocks[i]->end) { return uc->mapped_blocks[i]; } i = bsearch_mapped_blocks(uc, address); - if (i < uc->mapped_block_count && address >= uc->mapped_blocks[i]->addr && + if (i < uc->mapped_block_count && + address >= uc->mapped_blocks[i]->addr && address <= uc->mapped_blocks[i]->end - 1) return uc->mapped_blocks[i]; From 3199dd88dee094c3fc456971e5f469c22cb1160d Mon Sep 17 00:00:00 2001 From: mio Date: Tue, 7 Feb 2023 01:07:38 +0100 Subject: [PATCH 27/43] Detect AVX2 correctly for MSVC --- qemu/tcg/i386/tcg-target.inc.c | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/qemu/tcg/i386/tcg-target.inc.c b/qemu/tcg/i386/tcg-target.inc.c index 260de96c..fc5cdbba 100644 --- a/qemu/tcg/i386/tcg-target.inc.c +++ b/qemu/tcg/i386/tcg-target.inc.c @@ -24,6 +24,10 @@ #include "../tcg-pool.inc.c" +#ifdef _MSC_VER +#include +#endif + #ifdef CONFIG_DEBUG_TCG static const char * const tcg_target_reg_names[TCG_TARGET_NB_REGS] = { #if TCG_TARGET_REG_BITS == 64 @@ -3768,11 +3772,6 @@ static void tcg_target_init(TCGContext *s) have_movbe = (c & bit_MOVBE) != 0; have_popcnt = (c & bit_POPCNT) != 0; -#ifdef _MSC_VER - // FIXME: detect AVX1 & AVX2: https://gist.github.com/hi2p-perim/7855506 - have_avx1 = true; - have_avx2 = true; -#else /* There are a number of things we must check before we can be sure of not hitting invalid opcode. */ if (c & bit_OSXSAVE) { @@ -3780,13 +3779,18 @@ static void tcg_target_init(TCGContext *s) /* The xgetbv instruction is not available to older versions of * the assembler, so we encode the instruction manually. */ +#ifndef _MSC_VER asm(".byte 0x0f, 0x01, 0xd0" : "=a" (xcrl), "=d" (xcrh) : "c" (0)); +#else + unsigned long long bv = _xgetbv(0); + xcrl = bv & 0xFFFFFFFF; + xcrh = (bv >> 32) & 0xFFFFFFFF; +#endif if ((xcrl & 6) == 6) { have_avx1 = (c & bit_AVX) != 0; have_avx2 = (b7 & bit_AVX2) != 0; } } -#endif } #ifdef _MSC_VER From 9c9356da6cf5533a469c9a41e2b95ad0d064b2a7 Mon Sep 17 00:00:00 2001 From: mio Date: Tue, 7 Feb 2023 10:40:30 +0100 Subject: [PATCH 28/43] Bump to 2.0.2-rc1 for csharp --- bindings/dotnet/UnicornEngine/UnicornEngine.fsproj | 2 +- bindings/dotnet/UnicornSamples/UnicornSamples.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/bindings/dotnet/UnicornEngine/UnicornEngine.fsproj b/bindings/dotnet/UnicornEngine/UnicornEngine.fsproj index f2142473..8fd0d790 100644 --- a/bindings/dotnet/UnicornEngine/UnicornEngine.fsproj +++ b/bindings/dotnet/UnicornEngine/UnicornEngine.fsproj @@ -6,7 +6,7 @@ Copyright © Antonio Parata 2016 https://github.com/unicorn-engine/unicorn .NET bindings for unicorn - 2.0.0 + 2.0.2-rc1 $(VersionSuffix) 0c21f1c1-2725-4a46-9022-1905f85822a5 true diff --git a/bindings/dotnet/UnicornSamples/UnicornSamples.csproj b/bindings/dotnet/UnicornSamples/UnicornSamples.csproj index 4ba2d49e..9aea0c7d 100644 --- a/bindings/dotnet/UnicornSamples/UnicornSamples.csproj +++ b/bindings/dotnet/UnicornSamples/UnicornSamples.csproj @@ -6,7 +6,7 @@ UnicornSamples Copyright © Antonio Parata 2016 https://github.com/unicorn-engine/unicorn - 2.0.0 + 2.0.2-rc1 {B80B5987-1E24-4309-8BF9-C4F91270F21C} true From 133504b504b4b9005b26f707d7d68cf18eba2993 Mon Sep 17 00:00:00 2001 From: mio Date: Mon, 20 Feb 2023 20:21:56 +0100 Subject: [PATCH 29/43] Fix wrong IP in x86_16 because of cs_base not substracted --- qemu/target/i386/translate.c | 4 ++-- tests/unit/test_x86.c | 31 +++++++++++++++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/qemu/target/i386/translate.c b/qemu/target/i386/translate.c index b4dc56f2..2cc88f23 100644 --- a/qemu/target/i386/translate.c +++ b/qemu/target/i386/translate.c @@ -4816,7 +4816,7 @@ static target_ulong disas_insn(DisasContext *s, CPUState *cpu) } // Sync PC in advance - gen_jmp_im(s, pc_start); + gen_jmp_im(s, pc_start - s->cs_base); // save the last operand prev_op = tcg_last_op(tcg_ctx); @@ -9314,7 +9314,7 @@ static void i386_tr_insn_start(DisasContextBase *dcbase, CPUState *cpu) DisasContext *dc = container_of(dcbase, DisasContext, base); TCGContext *tcg_ctx = dc->uc->tcg_ctx; - dc->prev_pc = dc->base.pc_next; + dc->prev_pc = dc->base.pc_next - dc->cs_base; tcg_gen_insn_start(tcg_ctx, dc->base.pc_next, dc->cc_op); } diff --git a/tests/unit/test_x86.c b/tests/unit/test_x86.c index ddc84710..110e4b41 100644 --- a/tests/unit/test_x86.c +++ b/tests/unit/test_x86.c @@ -1229,6 +1229,36 @@ static void test_x86_lazy_mapping(void) OK(uc_close(uc)); } +static void test_x86_16_incorrect_ip_cb(uc_engine *uc, uint64_t address, uint32_t size, void* data) +{ + uint16_t cs, ip; + + OK(uc_reg_read(uc, UC_X86_REG_CS, &cs)); + OK(uc_reg_read(uc, UC_X86_REG_IP, &ip)); + + TEST_CHECK(cs == 0x20); + TEST_CHECK(address == ((cs << 4) + ip)); +} + +static void test_x86_16_incorrect_ip(void) +{ + uc_engine *uc; + uc_hook hk1, hk2; + uint16_t cs = 0x20; + char code[] = "\x41"; // INC cx; + + uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_16, code, sizeof(code) - 1); + + OK(uc_hook_add(uc, &hk1, UC_HOOK_BLOCK, test_x86_16_incorrect_ip_cb, NULL, 1, 0)); + OK(uc_hook_add(uc, &hk2, UC_HOOK_CODE, test_x86_16_incorrect_ip_cb, NULL, 1, 0)); + + OK(uc_reg_write(uc, UC_X86_REG_CS, &cs)); + + OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0)); + + OK(uc_close(uc)); +} + TEST_LIST = { {"test_x86_in", test_x86_in}, {"test_x86_out", test_x86_out}, @@ -1271,4 +1301,5 @@ TEST_LIST = { {"test_x86_unaligned_access", test_x86_unaligned_access}, #endif {"test_x86_lazy_mapping", test_x86_lazy_mapping}, + {"test_x86_16_incorrect_ip", test_x86_16_incorrect_ip}, {NULL, NULL}}; From 5e5075b4b93fd268b6900914b944a26ff0fb0757 Mon Sep 17 00:00:00 2001 From: mio Date: Mon, 20 Feb 2023 20:27:31 +0100 Subject: [PATCH 30/43] Install pkg-config on macos runners --- .github/workflows/build-uc2.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build-uc2.yml b/.github/workflows/build-uc2.yml index 7ee95894..ded889ef 100644 --- a/.github/workflows/build-uc2.yml +++ b/.github/workflows/build-uc2.yml @@ -305,7 +305,7 @@ jobs: if: contains(matrix.config.name, 'macos-x64') shell: bash run: | - brew install p7zip cmake ninja + brew install p7zip cmake ninja pkg-config ninja --version cmake --version mkdir build @@ -325,7 +325,7 @@ jobs: if: contains(matrix.config.name, 'android') shell: bash run: | - brew install p7zip cmake ninja + brew install p7zip cmake ninja pkg-config mkdir build mkdir instdir cmake . -DCMAKE_TOOLCHAIN_FILE="$ANDROID_NDK/build/cmake/android.toolchain.cmake" \ From 2d5d72e6c7f46f2b230d857c2434c5362be6118c Mon Sep 17 00:00:00 2001 From: mio Date: Mon, 20 Feb 2023 20:51:37 +0100 Subject: [PATCH 31/43] Install deps for macos --- .github/workflows/PyPI-publishing.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/PyPI-publishing.yml b/.github/workflows/PyPI-publishing.yml index 5f254bc2..b152c144 100644 --- a/.github/workflows/PyPI-publishing.yml +++ b/.github/workflows/PyPI-publishing.yml @@ -96,7 +96,12 @@ jobs: run: | choco install ninja cmake - - name: '🛠️ Install dependencies' + - name: '🛠️ macOS dependencies' + if: contains(matrix.config.name, 'macos') + run: | + brew install p7zip cmake ninja pkg-config + + - name: '🛠️ pip dependencies' run: | pip install setuptools wheel From 8a6f4e54c2eea179e321a44c54a85e031f56c24b Mon Sep 17 00:00:00 2001 From: mio Date: Mon, 20 Feb 2023 20:53:52 +0100 Subject: [PATCH 32/43] Install pkg-config for other workflows --- .github/workflows/Crate-publishing.yml | 6 ++++++ .github/workflows/Nuget-publishing.yml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/.github/workflows/Crate-publishing.yml b/.github/workflows/Crate-publishing.yml index eb1e0470..e20ba172 100644 --- a/.github/workflows/Crate-publishing.yml +++ b/.github/workflows/Crate-publishing.yml @@ -67,6 +67,12 @@ jobs: run: | choco install ninja cmake + - name: '🛠️ macOS build dependencies' + if: contains(matrix.config.os, 'macOS') + shell: bash + run: | + brew install p7zip cmake ninja pkg-config + - name: '🚧 Cargo test' if: "!startsWith(github.ref, 'refs/tags')" run: | diff --git a/.github/workflows/Nuget-publishing.yml b/.github/workflows/Nuget-publishing.yml index 75abbf67..3a6f0207 100644 --- a/.github/workflows/Nuget-publishing.yml +++ b/.github/workflows/Nuget-publishing.yml @@ -156,7 +156,7 @@ jobs: if: contains(matrix.config.name, 'macos-x64') shell: bash run: | - brew install p7zip cmake ninja + brew install p7zip cmake ninja pkg-config ninja --version cmake --version mkdir build From a91319908d67644cc4cc9befc8bdb1eb04ed083e Mon Sep 17 00:00:00 2001 From: mio Date: Mon, 20 Feb 2023 20:57:50 +0100 Subject: [PATCH 33/43] Remove obsolete Brewfile --- Brewfile | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 Brewfile diff --git a/Brewfile b/Brewfile deleted file mode 100644 index 82c65634..00000000 --- a/Brewfile +++ /dev/null @@ -1,6 +0,0 @@ -# Travis CI setup for MacOS Brew - -# used for testing framework -brew "cmocka" -# used for cross assembly of code for testing -brew "crosstool-ng" From b961ebc9cb9063775de0de65667b7fb7035902c1 Mon Sep 17 00:00:00 2001 From: Choongwoo Han Date: Sat, 25 Feb 2023 23:40:03 -0800 Subject: [PATCH 34/43] [dotnet] Set begin > end address for hooks --- bindings/dotnet/UnicornEngine/Unicorn.fs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/bindings/dotnet/UnicornEngine/Unicorn.fs b/bindings/dotnet/UnicornEngine/Unicorn.fs index 7d401300..8aaeaaf0 100644 --- a/bindings/dotnet/UnicornEngine/Unicorn.fs +++ b/bindings/dotnet/UnicornEngine/Unicorn.fs @@ -249,7 +249,7 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = |> Seq.iter(fun eventFlag -> let funcPointer = Marshal.GetFunctionPointerForDelegate(new EventMemHookInternal(trampoline)) let hh = new UIntPtr(allocate(IntPtr.Size)) - match binding.HookAddNoarg(_eng.[0], hh, eventFlag, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 0, uint64 0) |> this.CheckResult with + match binding.HookAddNoarg(_eng.[0], hh, eventFlag, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 1, uint64 0) |> this.CheckResult with | Some e -> raise e | None -> () ) @@ -274,7 +274,7 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = if _inHooks |> Seq.isEmpty then let funcPointer = Marshal.GetFunctionPointerForDelegate(new InHookInternal(trampoline)) let hh = new UIntPtr(allocate(IntPtr.Size)) - match binding.HookAddArg0(_eng.[0], hh, Common.UC_HOOK_INSN, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 0, uint64 0, X86.UC_X86_INS_IN) |> this.CheckResult with + match binding.HookAddArg0(_eng.[0], hh, Common.UC_HOOK_INSN, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 1, uint64 0, X86.UC_X86_INS_IN) |> this.CheckResult with | Some e -> raise e | None -> () _inHooks.Add(callback, userData) @@ -290,7 +290,7 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = if _outHooks |> Seq.isEmpty then let funcPointer = Marshal.GetFunctionPointerForDelegate(new OutHookInternal(trampoline)) let hh = new UIntPtr(allocate(IntPtr.Size)) - match binding.HookAddArg0(_eng.[0], hh, Common.UC_HOOK_INSN, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 0, uint64 0, X86.UC_X86_INS_OUT) |> this.CheckResult with + match binding.HookAddArg0(_eng.[0], hh, Common.UC_HOOK_INSN, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 1, uint64 0, X86.UC_X86_INS_OUT) |> this.CheckResult with | Some e -> raise e | None -> () _outHooks.Add(callback, userData) @@ -306,7 +306,7 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = if _syscallHooks |> Seq.isEmpty then let funcPointer = Marshal.GetFunctionPointerForDelegate(new SyscallHookInternal(trampoline)) let hh = new UIntPtr(allocate(IntPtr.Size)) - match binding.HookAddArg0(_eng.[0], hh, Common.UC_HOOK_INSN, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 0, uint64 0, X86.UC_X86_INS_SYSCALL) |> this.CheckResult with + match binding.HookAddArg0(_eng.[0], hh, Common.UC_HOOK_INSN, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 1, uint64 0, X86.UC_X86_INS_SYSCALL) |> this.CheckResult with | Some e -> raise e | None -> () _syscallHooks.Add(callback, userData) From 14404ef04b55662f605c00b31a479e50caff72ab Mon Sep 17 00:00:00 2001 From: "Takacs, Philipp" Date: Mon, 27 Feb 2023 12:34:38 +0100 Subject: [PATCH 35/43] [x86] don't hardcode cpuid results The cpuid results are set by the selected cpu. CLOSES #1787 --- qemu/target/i386/unicorn.c | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/qemu/target/i386/unicorn.c b/qemu/target/i386/unicorn.c index f10b70e2..4541044e 100644 --- a/qemu/target/i386/unicorn.c +++ b/qemu/target/i386/unicorn.c @@ -69,17 +69,6 @@ void x86_reg_reset(struct uc_struct *uc) { CPUArchState *env = uc->cpu->env_ptr; - env->features[FEAT_1_EDX] = CPUID_CX8 | CPUID_CMOV | CPUID_SSE2 | - CPUID_FXSR | CPUID_SSE | CPUID_CLFLUSH; - env->features[FEAT_1_ECX] = CPUID_EXT_SSSE3 | CPUID_EXT_SSE41 | - CPUID_EXT_SSE42 | CPUID_EXT_AES | - CPUID_EXT_CX16; - env->features[FEAT_8000_0001_EDX] = CPUID_EXT2_3DNOW | CPUID_EXT2_RDTSCP; - env->features[FEAT_8000_0001_ECX] = CPUID_EXT3_LAHF_LM | CPUID_EXT3_ABM | - CPUID_EXT3_SKINIT | CPUID_EXT3_CR8LEG; - env->features[FEAT_7_0_EBX] = CPUID_7_0_EBX_BMI1 | CPUID_7_0_EBX_BMI2 | - CPUID_7_0_EBX_ADX | CPUID_7_0_EBX_SMAP; - memset(env->regs, 0, sizeof(env->regs)); memset(env->segs, 0, sizeof(env->segs)); memset(env->cr, 0, sizeof(env->cr)); From 03a793e9345bea4736f29f21d0d2e26cf89a3491 Mon Sep 17 00:00:00 2001 From: Choongwoo Han Date: Tue, 28 Feb 2023 19:31:58 -0800 Subject: [PATCH 36/43] [dotnet] Fix garbage collected hooks and wrong signature --- .../dotnet/UnicornEngine/InternalHooks.fs | 4 +- bindings/dotnet/UnicornEngine/Unicorn.fs | 41 ++++++++++++++----- 2 files changed, 32 insertions(+), 13 deletions(-) diff --git a/bindings/dotnet/UnicornEngine/InternalHooks.fs b/bindings/dotnet/UnicornEngine/InternalHooks.fs index d9e87954..062de03c 100644 --- a/bindings/dotnet/UnicornEngine/InternalHooks.fs +++ b/bindings/dotnet/UnicornEngine/InternalHooks.fs @@ -14,10 +14,10 @@ type internal BlockHookInternal = delegate of IntPtr * Int64 * Int32 * IntPtr -> type internal InterruptHookInternal = delegate of IntPtr * Int32 * IntPtr -> unit [] -type internal MemReadHookInternal = delegate of IntPtr * Int64 * Int32 * IntPtr -> unit +type internal MemReadHookInternal = delegate of IntPtr * Int32 * Int64 * Int32 * IntPtr -> unit [] -type internal MemWriteHookInternal = delegate of IntPtr * Int64 * Int32 * Int64 * IntPtr -> unit +type internal MemWriteHookInternal = delegate of IntPtr * Int32 * Int64 * Int32 * Int64 * IntPtr -> unit [] type internal EventMemHookInternal = delegate of IntPtr * Int32 * Int64 * Int32 * Int64 * IntPtr-> Boolean diff --git a/bindings/dotnet/UnicornEngine/Unicorn.fs b/bindings/dotnet/UnicornEngine/Unicorn.fs index 8aaeaaf0..e353bf0c 100644 --- a/bindings/dotnet/UnicornEngine/Unicorn.fs +++ b/bindings/dotnet/UnicornEngine/Unicorn.fs @@ -32,6 +32,7 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = let _outHooks = new List<(OutHook * Object)>() let _syscallHooks = new List<(SyscallHook * Object)>() let _disposablePointers = new List() + let _hookInternals = new List(); let _eventMemMap = [ @@ -153,7 +154,9 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = |> Seq.iter(fun (callback, userData) -> callback.Invoke(this, addr, size, userData)) if _codeHooks |> Seq.isEmpty then - let funcPointer = Marshal.GetFunctionPointerForDelegate(new CodeHookInternal(trampoline)) + let codeHookInternal = new CodeHookInternal(trampoline) + _hookInternals.Add(codeHookInternal) + let funcPointer = Marshal.GetFunctionPointerForDelegate(codeHookInternal) let hh = new UIntPtr(allocate(IntPtr.Size)) match binding.HookAddNoarg(_eng.[0], hh, Common.UC_HOOK_CODE, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 beginAddr, uint64 endAddr) |> this.CheckResult with | Some e -> raise e | None -> () @@ -172,7 +175,9 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = |> Seq.iter(fun (callback, userData) -> callback.Invoke(this, addr, size, userData)) if _blockHooks |> Seq.isEmpty then - let funcPointer = Marshal.GetFunctionPointerForDelegate(new BlockHookInternal(trampoline)) + let blockHookInternal = new BlockHookInternal(trampoline) + _hookInternals.Add(blockHookInternal) + let funcPointer = Marshal.GetFunctionPointerForDelegate(blockHookInternal) let hh = new UIntPtr(allocate(IntPtr.Size)) match binding.HookAddNoarg(_eng.[0], hh, Common.UC_HOOK_BLOCK, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 beginAddr, uint64 endAddr) |> this.CheckResult with | Some e -> raise e | None -> () @@ -188,7 +193,9 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = |> Seq.iter(fun (callback, userData) -> callback.Invoke(this, intNumber, userData)) if _interruptHooks |> Seq.isEmpty then - let funcPointer = Marshal.GetFunctionPointerForDelegate(new InterruptHookInternal(trampoline)) + let interruptHookInternal = new InterruptHookInternal(trampoline) + _hookInternals.Add(interruptHookInternal) + let funcPointer = Marshal.GetFunctionPointerForDelegate(interruptHookInternal) let hh = new UIntPtr(allocate(IntPtr.Size)) match binding.HookAddNoarg(_eng.[0], hh, Common.UC_HOOK_INTR, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, hookBegin, hookEnd) |> this.CheckResult with | Some e -> raise e | None -> () @@ -202,12 +209,14 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = hookDel _interruptHooks callback member this.AddMemReadHook(callback: MemReadHook, userData: Object, beginAddr: Int64, endAddr: Int64) = - let trampoline(u: IntPtr) (addr: Int64) (size: Int32) (user: IntPtr) = + let trampoline(u: IntPtr) (_eventType: Int32) (addr: Int64) (size: Int32) (user: IntPtr) = _memReadHooks |> Seq.iter(fun (callback, userData) -> callback.Invoke(this, addr, size, userData)) if _memReadHooks |> Seq.isEmpty then - let funcPointer = Marshal.GetFunctionPointerForDelegate(new MemReadHookInternal(trampoline)) + let memReadHookInternal = new MemReadHookInternal(trampoline) + _hookInternals.Add(memReadHookInternal) + let funcPointer = Marshal.GetFunctionPointerForDelegate(memReadHookInternal) let hh = new UIntPtr(allocate(IntPtr.Size)) match binding.HookAddNoarg(_eng.[0], hh, Common.UC_HOOK_MEM_READ, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 beginAddr, uint64 endAddr) |> this.CheckResult with | Some e -> raise e | None -> () @@ -218,12 +227,14 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = hookDel _memReadHooks callback member this.AddMemWriteHook(callback: MemWriteHook, userData: Object, beginAddr: Int64, endAddr: Int64) = - let trampoline(u: IntPtr) (addr: Int64) (size: Int32) (value: Int64) (user: IntPtr) = + let trampoline(u: IntPtr) (_eventType: Int32) (addr: Int64) (size: Int32) (value: Int64) (user: IntPtr) = _memWriteHooks |> Seq.iter(fun (callback, userData) -> callback.Invoke(this, addr, size, value, userData)) if _memWriteHooks |> Seq.isEmpty then - let funcPointer = Marshal.GetFunctionPointerForDelegate(new MemWriteHookInternal(trampoline)) + let memWriteHookInternal = new MemWriteHookInternal(trampoline) + _hookInternals.Add(memWriteHookInternal) + let funcPointer = Marshal.GetFunctionPointerForDelegate(memWriteHookInternal) let hh = new UIntPtr(allocate(IntPtr.Size)) match binding.HookAddNoarg(_eng.[0], hh, Common.UC_HOOK_MEM_WRITE, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 beginAddr, uint64 endAddr) |> this.CheckResult with | Some e -> raise e | None -> () @@ -247,7 +258,9 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = |> Seq.filter(fun eventFlag -> (eventType &&& eventFlag) <> 0) |> Seq.filter(fun eventFlag -> _memEventHooks.[eventFlag] |> Seq.isEmpty) |> Seq.iter(fun eventFlag -> - let funcPointer = Marshal.GetFunctionPointerForDelegate(new EventMemHookInternal(trampoline)) + let memEventHookInternal = new EventMemHookInternal(trampoline) + _hookInternals.Add(memEventHookInternal) + let funcPointer = Marshal.GetFunctionPointerForDelegate(memEventHookInternal) let hh = new UIntPtr(allocate(IntPtr.Size)) match binding.HookAddNoarg(_eng.[0], hh, eventFlag, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 1, uint64 0) |> this.CheckResult with | Some e -> raise e | None -> () @@ -272,7 +285,9 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = |> Seq.last if _inHooks |> Seq.isEmpty then - let funcPointer = Marshal.GetFunctionPointerForDelegate(new InHookInternal(trampoline)) + let inHookInternal = new InHookInternal(trampoline) + _hookInternals.Add(inHookInternal) + let funcPointer = Marshal.GetFunctionPointerForDelegate(inHookInternal) let hh = new UIntPtr(allocate(IntPtr.Size)) match binding.HookAddArg0(_eng.[0], hh, Common.UC_HOOK_INSN, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 1, uint64 0, X86.UC_X86_INS_IN) |> this.CheckResult with | Some e -> raise e | None -> () @@ -288,7 +303,9 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = |> Seq.iter(fun (callback, userData) -> callback.Invoke(this, port, size, value, userData)) if _outHooks |> Seq.isEmpty then - let funcPointer = Marshal.GetFunctionPointerForDelegate(new OutHookInternal(trampoline)) + let outHookInternal = new OutHookInternal(trampoline) + _hookInternals.Add(outHookInternal) + let funcPointer = Marshal.GetFunctionPointerForDelegate(outHookInternal) let hh = new UIntPtr(allocate(IntPtr.Size)) match binding.HookAddArg0(_eng.[0], hh, Common.UC_HOOK_INSN, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 1, uint64 0, X86.UC_X86_INS_OUT) |> this.CheckResult with | Some e -> raise e | None -> () @@ -304,7 +321,9 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = |> Seq.iter(fun (callback, userData) -> callback.Invoke(this, userData)) if _syscallHooks |> Seq.isEmpty then - let funcPointer = Marshal.GetFunctionPointerForDelegate(new SyscallHookInternal(trampoline)) + let syscallHookInternal = new SyscallHookInternal(trampoline) + _hookInternals.Add(syscallHookInternal) + let funcPointer = Marshal.GetFunctionPointerForDelegate(syscallHookInternal) let hh = new UIntPtr(allocate(IntPtr.Size)) match binding.HookAddArg0(_eng.[0], hh, Common.UC_HOOK_INSN, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 1, uint64 0, X86.UC_X86_INS_SYSCALL) |> this.CheckResult with | Some e -> raise e | None -> () From 545c9ed24e62d11b91839ba4b453e19d2df24ba5 Mon Sep 17 00:00:00 2001 From: Choongwoo Han Date: Tue, 28 Feb 2023 20:10:38 -0800 Subject: [PATCH 37/43] [dotnet] Add /MT flag for nuget package build --- .github/workflows/Nuget-publishing.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/Nuget-publishing.yml b/.github/workflows/Nuget-publishing.yml index 3a6f0207..e82961cd 100644 --- a/.github/workflows/Nuget-publishing.yml +++ b/.github/workflows/Nuget-publishing.yml @@ -80,6 +80,7 @@ jobs: -B . \ -DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} \ -G "${{ matrix.config.generators }}" \ + -DCMAKE_C_FLAGS="//MT" \ -DCMAKE_INSTALL_PREFIX:PATH=instdir \ -DBUILD_SHARED_LIBS=${{ matrix.config.shared }} cmake --build . --config ${{ matrix.config.build_type }} @@ -107,6 +108,7 @@ jobs: -A "win32" \ -DCMAKE_BUILD_TYPE=${{ matrix.config.build_type }} \ -G "${{ matrix.config.generators }}" \ + -DCMAKE_C_FLAGS="//MT" \ -DCMAKE_INSTALL_PREFIX:PATH=instdir \ -DBUILD_SHARED_LIBS=${{ matrix.config.shared }} cmake --build . --config ${{ matrix.config.build_type }} From cef7d7d0fbefb0c6e1da7eaf782bef36cf8ad64c Mon Sep 17 00:00:00 2001 From: Audrey Dutcher Date: Mon, 27 Feb 2023 23:31:15 -0700 Subject: [PATCH 38/43] Use libunicorn.so.2 as fallback path --- bindings/python/unicorn/unicorn.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bindings/python/unicorn/unicorn.py b/bindings/python/unicorn/unicorn.py index 2e6a938f..0aacfb13 100644 --- a/bindings/python/unicorn/unicorn.py +++ b/bindings/python/unicorn/unicorn.py @@ -94,7 +94,7 @@ _path_list = [os.getenv('LIBUNICORN_PATH', None), for _path in _path_list: if _path is None: continue - _uc = _load_lib(_path, _lib.get(sys.platform, "libunicorn.so")) + _uc = _load_lib(_path, _lib.get(sys.platform, "libunicorn.so.2")) if _uc is not None: break From b7b1a4d6b4eae2ae12e78ec6cd676a69e4ee9392 Mon Sep 17 00:00:00 2001 From: "Takacs, Philipp" Date: Mon, 6 Mar 2023 15:35:01 +0100 Subject: [PATCH 39/43] difference between stop_request and quit_request quit_request is for internal use. This means the IP register was updated and qemu needs to rebuild the translation blocks. stop_request is set by the user (uc_emu_stop) to indecate that unicorn sould stop emulating. --- include/uc_priv.h | 22 +++++++++++++++++++ qemu/softmmu/cpus.c | 2 +- qemu/target/arm/unicorn_aarch64.c | 2 +- qemu/target/arm/unicorn_arm.c | 2 +- qemu/target/i386/unicorn.c | 4 ++-- qemu/target/m68k/unicorn.c | 2 +- qemu/target/mips/unicorn.c | 2 +- qemu/target/ppc/unicorn.c | 2 +- qemu/target/riscv/unicorn.c | 2 +- qemu/target/s390x/unicorn.c | 2 +- qemu/target/tricore/unicorn.c | 2 +- tests/unit/test_ctl.c | 36 +++++++++++++++++++++++++++++++ uc.c | 13 +---------- 13 files changed, 70 insertions(+), 23 deletions(-) diff --git a/include/uc_priv.h b/include/uc_priv.h index 66b6e83e..60a9b486 100644 --- a/include/uc_priv.h +++ b/include/uc_priv.h @@ -486,6 +486,28 @@ static inline void hooked_regions_check(uc_engine *uc, uint64_t start, length); } +/* + break translation loop: + This is done in two cases: + 1. the user wants to stop the emulation. + 2. the user has set it IP. This requires to restart the internal + CPU emulation and rebuild some translation blocks +*/ +static inline uc_err break_translation_loop(uc_engine *uc) +{ + if (uc->emulation_done) { + return UC_ERR_OK; + } + + // TODO: make this atomic somehow? + if (uc->cpu) { + // exit the current TB + cpu_exit(uc->cpu); + } + + return UC_ERR_OK; +} + #ifdef UNICORN_TRACER #define UC_TRACE_START(loc) trace_start(get_tracer(), loc) #define UC_TRACE_END(loc, fmt, ...) \ diff --git a/qemu/softmmu/cpus.c b/qemu/softmmu/cpus.c index f6b242f3..22511ac7 100644 --- a/qemu/softmmu/cpus.c +++ b/qemu/softmmu/cpus.c @@ -96,7 +96,7 @@ static int tcg_cpu_exec(struct uc_struct *uc) r = cpu_exec(uc, cpu); // quit current TB but continue emulating? - if (uc->quit_request) { + if (uc->quit_request && !uc->stop_request) { // reset stop_request uc->stop_request = false; diff --git a/qemu/target/arm/unicorn_aarch64.c b/qemu/target/arm/unicorn_aarch64.c index fec0db68..fa40330f 100644 --- a/qemu/target/arm/unicorn_aarch64.c +++ b/qemu/target/arm/unicorn_aarch64.c @@ -372,7 +372,7 @@ int arm64_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, if (regid == UC_ARM64_REG_PC) { // force to quit execution and flush TB uc->quit_request = true; - uc_emu_stop(uc); + break_translation_loop(uc); } } diff --git a/qemu/target/arm/unicorn_arm.c b/qemu/target/arm/unicorn_arm.c index bb39b348..e706b12b 100644 --- a/qemu/target/arm/unicorn_arm.c +++ b/qemu/target/arm/unicorn_arm.c @@ -515,7 +515,7 @@ int arm_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, if (regid == UC_ARM_REG_R15) { // force to quit execution and flush TB uc->quit_request = true; - uc_emu_stop(uc); + break_translation_loop(uc); } } diff --git a/qemu/target/i386/unicorn.c b/qemu/target/i386/unicorn.c index 4541044e..3e83b0ba 100644 --- a/qemu/target/i386/unicorn.c +++ b/qemu/target/i386/unicorn.c @@ -1521,7 +1521,7 @@ int x86_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, case UC_X86_REG_IP: // force to quit execution and flush TB uc->quit_request = true; - uc_emu_stop(uc); + break_translation_loop(uc); break; } @@ -1535,7 +1535,7 @@ int x86_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, case UC_X86_REG_IP: // force to quit execution and flush TB uc->quit_request = true; - uc_emu_stop(uc); + break_translation_loop(uc); break; } #endif diff --git a/qemu/target/m68k/unicorn.c b/qemu/target/m68k/unicorn.c index d748ace7..d0a091fa 100644 --- a/qemu/target/m68k/unicorn.c +++ b/qemu/target/m68k/unicorn.c @@ -117,7 +117,7 @@ int m68k_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, if (regid == UC_M68K_REG_PC) { // force to quit execution and flush TB uc->quit_request = true; - uc_emu_stop(uc); + break_translation_loop(uc); } } diff --git a/qemu/target/mips/unicorn.c b/qemu/target/mips/unicorn.c index bd4d5595..792fb45e 100644 --- a/qemu/target/mips/unicorn.c +++ b/qemu/target/mips/unicorn.c @@ -170,7 +170,7 @@ int mips_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, if (regid == UC_MIPS_REG_PC) { // force to quit execution and flush TB uc->quit_request = true; - uc_emu_stop(uc); + break_translation_loop(uc); } } diff --git a/qemu/target/ppc/unicorn.c b/qemu/target/ppc/unicorn.c index b157ce5a..fc8e24f1 100644 --- a/qemu/target/ppc/unicorn.c +++ b/qemu/target/ppc/unicorn.c @@ -361,7 +361,7 @@ int ppc_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, if (regid == UC_PPC_REG_PC) { // force to quit execution and flush TB uc->quit_request = true; - uc_emu_stop(uc); + break_translation_loop(uc); } } diff --git a/qemu/target/riscv/unicorn.c b/qemu/target/riscv/unicorn.c index a440a6bd..8970051e 100644 --- a/qemu/target/riscv/unicorn.c +++ b/qemu/target/riscv/unicorn.c @@ -560,7 +560,7 @@ int riscv_reg_write(struct uc_struct *uc, unsigned int *regs, void *const *vals, if (regid == UC_RISCV_REG_PC) { // force to quit execution and flush TB uc->quit_request = true; - uc_emu_stop(uc); + break_translation_loop(uc); } } diff --git a/qemu/target/s390x/unicorn.c b/qemu/target/s390x/unicorn.c index 469cda7c..6378fe4c 100644 --- a/qemu/target/s390x/unicorn.c +++ b/qemu/target/s390x/unicorn.c @@ -130,7 +130,7 @@ static int s390_reg_write(struct uc_struct *uc, unsigned int *regs, if (regid == UC_S390X_REG_PC) { // force to quit execution and flush TB uc->quit_request = true; - uc_emu_stop(uc); + break_translation_loop(uc); } } diff --git a/qemu/target/tricore/unicorn.c b/qemu/target/tricore/unicorn.c index 88e937bb..a3eac632 100644 --- a/qemu/target/tricore/unicorn.c +++ b/qemu/target/tricore/unicorn.c @@ -229,7 +229,7 @@ int tricore_reg_write(struct uc_struct *uc, unsigned int *regs, if (regid == UC_TRICORE_REG_PC) { // force to quit execution and flush TB uc->quit_request = true; - uc_emu_stop(uc); + break_translation_loop(uc); } } diff --git a/tests/unit/test_ctl.c b/tests/unit/test_ctl.c index 05f4c54e..0c1eeabc 100644 --- a/tests/unit/test_ctl.c +++ b/tests/unit/test_ctl.c @@ -304,6 +304,41 @@ static void test_uc_hook_cached_uaf(void) #endif } +static void test_uc_emu_stop_set_ip_callback(uc_engine *uc, uint64_t address, uint32_t size, void *userdata) +{ + uint64_t rip = code_start + 0xb; + + if (address == code_start + 0x7) { + printf("stoping\n"); + uc_emu_stop(uc); + uc_reg_write(uc, UC_X86_REG_RIP, &rip); + } +} + +static void test_uc_emu_stop_set_ip(void) +{ + uc_engine *uc; + uc_hook h; + uint64_t rip; + + char code[] = "\x48\x31\xc0" // 0x0 xor rax, rax : rax = 0 + "\x90" // 0x3 nop : + "\x48\xff\xc0" // 0x4 inc rax : rax++ + "\x90" // 0x7 nop : <-- going to stop here + "\x48\xff\xc0" // 0x8 inc rax : rax++ + "\x90" // 0xb nop : + "\x0f\x0b" // 0xc ud2 : <-- will raise UC_ERR_INSN_INVALID, but should not never be reached + "\x90" // 0xe nop : + "\x90"; // 0xf nop : + + uc_common_setup(&uc, UC_ARCH_X86, UC_MODE_64, code, sizeof(code) - 1); + OK(uc_hook_add(uc, &h, UC_HOOK_CODE, test_uc_emu_stop_set_ip_callback, NULL, 1, 0)); + OK(uc_emu_start(uc, code_start, code_start + sizeof(code) - 1, 0, 0)); + OK(uc_reg_read(uc, UC_X86_REG_RIP, &rip)); + TEST_CHECK(rip == code_start + 0xb); + OK(uc_close(uc)); +} + TEST_LIST = {{"test_uc_ctl_mode", test_uc_ctl_mode}, {"test_uc_ctl_page_size", test_uc_ctl_page_size}, {"test_uc_ctl_arch", test_uc_ctl_arch}, @@ -315,4 +350,5 @@ TEST_LIST = {{"test_uc_ctl_mode", test_uc_ctl_mode}, {"test_uc_ctl_arm_cpu", test_uc_ctl_arm_cpu}, #endif {"test_uc_hook_cached_uaf", test_uc_hook_cached_uaf}, + {"test_uc_emu_stop_set_ip", test_uc_emu_stop_set_ip}, {NULL, NULL}}; diff --git a/uc.c b/uc.c index 829dda95..76c4eb28 100644 --- a/uc.c +++ b/uc.c @@ -907,19 +907,8 @@ UNICORN_EXPORT uc_err uc_emu_stop(uc_engine *uc) { UC_INIT(uc); - - if (uc->emulation_done) { - return UC_ERR_OK; - } - uc->stop_request = true; - // TODO: make this atomic somehow? - if (uc->cpu) { - // exit the current TB - cpu_exit(uc->cpu); - } - - return UC_ERR_OK; + return break_translation_loop(uc); } // return target index where a memory region at the address exists, or could be From b4b6caf57c9e3c01a66a8b1627859c516e4de6a7 Mon Sep 17 00:00:00 2001 From: Choongwoo Han Date: Sat, 11 Mar 2023 08:51:01 -0800 Subject: [PATCH 40/43] [dotnet] Support HookDel with native bindings call --- bindings/dotnet/UnicornEngine/Unicorn.fs | 281 +++++++++++------------ 1 file changed, 138 insertions(+), 143 deletions(-) diff --git a/bindings/dotnet/UnicornEngine/Unicorn.fs b/bindings/dotnet/UnicornEngine/Unicorn.fs index e353bf0c..56a683b0 100644 --- a/bindings/dotnet/UnicornEngine/Unicorn.fs +++ b/bindings/dotnet/UnicornEngine/Unicorn.fs @@ -22,17 +22,16 @@ and SyscallHook = delegate of Unicorn * Object -> unit and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = // hook callback list - let _codeHooks = new List<(CodeHook * Object)>() - let _blockHooks = new List<(BlockHook * Object)>() - let _interruptHooks = new List<(InterruptHook * Object)>() - let _memReadHooks = new List<(MemReadHook * Object)>() - let _memWriteHooks = new List<(MemWriteHook * Object)>() - let _memEventHooks = new Dictionary>() - let _inHooks = new List<(InHook * Object)>() - let _outHooks = new List<(OutHook * Object)>() - let _syscallHooks = new List<(SyscallHook * Object)>() + let _codeHooks = new List<(CodeHook * (UIntPtr * Object * Object))>() + let _blockHooks = new List<(BlockHook * (UIntPtr * Object * Object))>() + let _interruptHooks = new List<(InterruptHook * (UIntPtr * Object * Object))>() + let _memReadHooks = new List<(MemReadHook * (UIntPtr * Object * Object))>() + let _memWriteHooks = new List<(MemWriteHook * (UIntPtr * Object * Object))>() + let _memEventHooks = new Dictionary>() + let _inHooks = new List<(InHook * (UIntPtr * Object * Object))>() + let _outHooks = new List<(OutHook * (UIntPtr * Object * Object))>() + let _syscallHooks = new List<(SyscallHook * (UIntPtr * Object * Object))>() let _disposablePointers = new List() - let _hookInternals = new List(); let _eventMemMap = [ @@ -46,14 +45,25 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = let mutable _eng = [|UIntPtr.Zero|] - let checkResult(errCode: Int32, errMsg: String) = - if errCode <> Common.UC_ERR_OK then raise(ApplicationException(String.Format("{0}. Error: {1}", errMsg, errCode))) + let strError(errorNo: Int32) = + let errorStringPointer = binding.Strerror(errorNo) + Marshal.PtrToStringAnsi(errorStringPointer) - let hookDel(callbacks: List<'a * Object>) (callback: 'a)= - // TODO: invoke the native function in order to not call the trampoline anymore - callbacks - |> Seq.tryFind(fun item -> match item with | (c, _) -> c = callback) - |> (fun k -> if k.IsSome then callbacks.Remove(k.Value) |> ignore) + let checkResult(errorCode: Int32) = + // return the exception instead of raising it in order to have a more meaningful stack trace + if errorCode <> Common.UC_ERR_OK then + let errorMessage = strError(errorCode) + Some <| UnicornEngineException(errorCode, errorMessage) + else None + + let hookDel(callbacks: List<'a * (UIntPtr * Object * Object)>) (callback: 'a)= + match callbacks |> Seq.tryFind(fun item -> match item with | (c, _) -> c = callback) with + | Some(item) -> + let (hh, _, _) = snd item + match binding.HookDel(_eng.[0], hh) |> checkResult with + | Some e -> raise e + | None -> callbacks.Remove(item) |> ignore + | None -> () let allocate(size: Int32) = let mem = Marshal.AllocHGlobal(size) @@ -64,61 +74,55 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = // initialize event list _eventMemMap |> Seq.map(fun kv -> kv.Key) - |> Seq.iter (fun eventType -> _memEventHooks.Add(eventType, new List())) + |> Seq.iter (fun eventType -> _memEventHooks.Add(eventType, new List())) // init engine _eng <- [|new UIntPtr(allocate(IntPtr.Size))|] let err = binding.UcOpen(uint32 arch, uint32 mode, _eng) - checkResult(err, "Unable to open the Unicorn Engine") + if err <> Common.UC_ERR_OK then + raise(ApplicationException(String.Format("Unable to open the Unicorn Engine. Error: {0}", err))) new(arch, mode) = new Unicorn(arch, mode, BindingFactory.getDefault()) - member private this.CheckResult(errorCode: Int32) = - // return the exception instead of raising it in order to have a more meaningful stack trace - if errorCode <> Common.UC_ERR_OK then - let errorMessage = this.StrError(errorCode) - Some <| UnicornEngineException(errorCode, errorMessage) - else None - member this.MemMap(address: Int64, size: Int64, perm: Int32) = let size = new UIntPtr(uint64 size) - match binding.MemMap(_eng.[0], uint64 address, size, uint32 perm) |> this.CheckResult with + match binding.MemMap(_eng.[0], uint64 address, size, uint32 perm) |> checkResult with | Some e -> raise e | None -> () member this.MemMapPtr(address: Int64, size: Int64, perm: Int32, ptr: IntPtr) = let size = new UIntPtr(uint64 size) let ptr = new UIntPtr(ptr.ToPointer()) - match binding.MemMapPtr(_eng.[0], uint64 address, size, uint32 perm, ptr) |> this.CheckResult with + match binding.MemMapPtr(_eng.[0], uint64 address, size, uint32 perm, ptr) |> checkResult with | Some e -> raise e | None -> () member this.MemUnmap(address: Int64, size: Int64) = let size = new UIntPtr(uint64 size) - match binding.MemUnmap(_eng.[0], uint64 address, size) |> this.CheckResult with + match binding.MemUnmap(_eng.[0], uint64 address, size) |> checkResult with | Some e -> raise e | None -> () member this.MemProtect(address: Int64, size: Int64, ?perm: Int32) = let size = new UIntPtr(uint64 size) let perm = defaultArg perm Common.UC_PROT_ALL - match binding.MemProtect(_eng.[0], uint64 address, size, uint32 perm) |> this.CheckResult with + match binding.MemProtect(_eng.[0], uint64 address, size, uint32 perm) |> checkResult with | Some e -> raise e | None -> () member this.MemWrite(address: Int64, value: Byte array) = - match binding.MemWrite(_eng.[0], uint64 address, value, new UIntPtr(uint32 value.Length)) |> this.CheckResult with + match binding.MemWrite(_eng.[0], uint64 address, value, new UIntPtr(uint32 value.Length)) |> checkResult with | Some e -> raise e | None -> () member this.MemRead(address: Int64, memValue: Byte array) = - match binding.MemRead(_eng.[0], uint64 address, memValue, new UIntPtr(uint32 memValue.Length)) |> this.CheckResult with + match binding.MemRead(_eng.[0], uint64 address, memValue, new UIntPtr(uint32 memValue.Length)) |> checkResult with | Some e -> raise e | None -> () member this.RegWrite(regId: Int32, value: Byte array) = - match binding.RegWrite(_eng.[0], regId, value) |> this.CheckResult with + match binding.RegWrite(_eng.[0], regId, value) |> checkResult with | Some e -> raise e | None -> () member this.RegWrite(regId: Int32, value: Int64) = this.RegWrite(regId, int64ToBytes value) member this.RegRead(regId: Int32, regValue: Byte array) = - match binding.RegRead(_eng.[0], regId, regValue) |> this.CheckResult with + match binding.RegRead(_eng.[0], regId, regValue) |> checkResult with | Some e -> raise e | None -> () member this.RegRead(regId: Int32) = @@ -127,15 +131,15 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = bytesToInt64 buffer member this.EmuStart(beginAddr: Int64, untilAddr: Int64, timeout: Int64, count: Int64) = - match binding.EmuStart(_eng.[0], uint64 beginAddr, uint64 untilAddr, uint64 timeout, uint64 count) |> this.CheckResult with + match binding.EmuStart(_eng.[0], uint64 beginAddr, uint64 untilAddr, uint64 timeout, uint64 count) |> checkResult with | Some e -> raise e | None -> () member this.EmuStop() = - match binding.EmuStop(_eng.[0]) |> this.CheckResult with + match binding.EmuStop(_eng.[0]) |> checkResult with | Some e -> raise e | None -> () member this.Close() = - match binding.Close(_eng.[0]) |> this.CheckResult with + match binding.Close(_eng.[0]) |> checkResult with | Some e -> raise e | None -> () member this.ArchSupported(arch: Int32) = @@ -144,24 +148,18 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = member this.ErrNo() = binding.Errono(_eng.[0]) - member this.StrError(errorNo: Int32) = - let errorStringPointer = binding.Strerror(errorNo) - Marshal.PtrToStringAnsi(errorStringPointer) - member this.AddCodeHook(callback: CodeHook, userData: Object, beginAddr: Int64, endAddr: Int64) = let trampoline(u: IntPtr) (addr: Int64) (size: Int32) (user: IntPtr) = - _codeHooks - |> Seq.iter(fun (callback, userData) -> callback.Invoke(this, addr, size, userData)) + callback.Invoke(this, addr, size, userData) - if _codeHooks |> Seq.isEmpty then - let codeHookInternal = new CodeHookInternal(trampoline) - _hookInternals.Add(codeHookInternal) - let funcPointer = Marshal.GetFunctionPointerForDelegate(codeHookInternal) - let hh = new UIntPtr(allocate(IntPtr.Size)) - match binding.HookAddNoarg(_eng.[0], hh, Common.UC_HOOK_CODE, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 beginAddr, uint64 endAddr) |> this.CheckResult with - | Some e -> raise e | None -> () + let codeHookInternal = new CodeHookInternal(trampoline) + let funcPointer = Marshal.GetFunctionPointerForDelegate(codeHookInternal) + let hh = new UIntPtr(allocate(IntPtr.Size)) + match binding.HookAddNoarg(_eng.[0], hh, Common.UC_HOOK_CODE, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 beginAddr, uint64 endAddr) |> checkResult with + | Some e -> raise e | None -> () - _codeHooks.Add(callback, userData) + let hh = (unativeint)(Marshal.ReadIntPtr((nativeint)hh)) + _codeHooks.Add(callback, (hh, userData, codeHookInternal)) member this.AddCodeHook(callback: CodeHook, beginAddr: Int64, endAddr: Int64) = this.AddCodeHook(callback, null, beginAddr, endAddr) @@ -171,36 +169,32 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = member this.AddBlockHook(callback: BlockHook, userData: Object, beginAddr: Int64, endAddr: Int64) = let trampoline(u: IntPtr) (addr: Int64) (size: Int32) (user: IntPtr) = - _blockHooks - |> Seq.iter(fun (callback, userData) -> callback.Invoke(this, addr, size, userData)) + callback.Invoke(this, addr, size, userData) - if _blockHooks |> Seq.isEmpty then - let blockHookInternal = new BlockHookInternal(trampoline) - _hookInternals.Add(blockHookInternal) - let funcPointer = Marshal.GetFunctionPointerForDelegate(blockHookInternal) - let hh = new UIntPtr(allocate(IntPtr.Size)) - match binding.HookAddNoarg(_eng.[0], hh, Common.UC_HOOK_BLOCK, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 beginAddr, uint64 endAddr) |> this.CheckResult with - | Some e -> raise e | None -> () + let blockHookInternal = new BlockHookInternal(trampoline) + let funcPointer = Marshal.GetFunctionPointerForDelegate(blockHookInternal) + let hh = new UIntPtr(allocate(IntPtr.Size)) + match binding.HookAddNoarg(_eng.[0], hh, Common.UC_HOOK_BLOCK, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 beginAddr, uint64 endAddr) |> checkResult with + | Some e -> raise e | None -> () - _blockHooks.Add(callback, userData) + let hh = (unativeint)(Marshal.ReadIntPtr((nativeint)hh)) + _blockHooks.Add(callback, (hh, userData, blockHookInternal)) member this.HookDel(callback: BlockHook) = hookDel _blockHooks callback member this.AddInterruptHook(callback: InterruptHook, userData: Object, hookBegin: UInt64, hookEnd : UInt64) = let trampoline(u: IntPtr) (intNumber: Int32) (user: IntPtr) = - _interruptHooks - |> Seq.iter(fun (callback, userData) -> callback.Invoke(this, intNumber, userData)) + callback.Invoke(this, intNumber, userData) - if _interruptHooks |> Seq.isEmpty then - let interruptHookInternal = new InterruptHookInternal(trampoline) - _hookInternals.Add(interruptHookInternal) - let funcPointer = Marshal.GetFunctionPointerForDelegate(interruptHookInternal) - let hh = new UIntPtr(allocate(IntPtr.Size)) - match binding.HookAddNoarg(_eng.[0], hh, Common.UC_HOOK_INTR, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, hookBegin, hookEnd) |> this.CheckResult with - | Some e -> raise e | None -> () + let interruptHookInternal = new InterruptHookInternal(trampoline) + let funcPointer = Marshal.GetFunctionPointerForDelegate(interruptHookInternal) + let hh = new UIntPtr(allocate(IntPtr.Size)) + match binding.HookAddNoarg(_eng.[0], hh, Common.UC_HOOK_INTR, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, hookBegin, hookEnd) |> checkResult with + | Some e -> raise e | None -> () - _interruptHooks.Add(callback, userData) + let hh = (unativeint)(Marshal.ReadIntPtr((nativeint)hh)) + _interruptHooks.Add(callback, (hh, userData, interruptHookInternal)) member this.AddInterruptHook(callback: InterruptHook) = this.AddInterruptHook(callback, null, uint64 1, uint64 0) @@ -210,129 +204,130 @@ and Unicorn(arch: Int32, mode: Int32, binding: IBinding) = member this.AddMemReadHook(callback: MemReadHook, userData: Object, beginAddr: Int64, endAddr: Int64) = let trampoline(u: IntPtr) (_eventType: Int32) (addr: Int64) (size: Int32) (user: IntPtr) = - _memReadHooks - |> Seq.iter(fun (callback, userData) -> callback.Invoke(this, addr, size, userData)) + callback.Invoke(this, addr, size, userData) - if _memReadHooks |> Seq.isEmpty then - let memReadHookInternal = new MemReadHookInternal(trampoline) - _hookInternals.Add(memReadHookInternal) - let funcPointer = Marshal.GetFunctionPointerForDelegate(memReadHookInternal) - let hh = new UIntPtr(allocate(IntPtr.Size)) - match binding.HookAddNoarg(_eng.[0], hh, Common.UC_HOOK_MEM_READ, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 beginAddr, uint64 endAddr) |> this.CheckResult with - | Some e -> raise e | None -> () + let memReadHookInternal = new MemReadHookInternal(trampoline) + let funcPointer = Marshal.GetFunctionPointerForDelegate(memReadHookInternal) + let hh = new UIntPtr(allocate(IntPtr.Size)) + match binding.HookAddNoarg(_eng.[0], hh, Common.UC_HOOK_MEM_READ, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 beginAddr, uint64 endAddr) |> checkResult with + | Some e -> raise e | None -> () - _memReadHooks.Add(callback, userData) + let hh = (unativeint)(Marshal.ReadIntPtr((nativeint)hh)) + _memReadHooks.Add(callback, (hh, userData, memReadHookInternal)) member this.HookDel(callback: MemReadHook) = hookDel _memReadHooks callback member this.AddMemWriteHook(callback: MemWriteHook, userData: Object, beginAddr: Int64, endAddr: Int64) = let trampoline(u: IntPtr) (_eventType: Int32) (addr: Int64) (size: Int32) (value: Int64) (user: IntPtr) = - _memWriteHooks - |> Seq.iter(fun (callback, userData) -> callback.Invoke(this, addr, size, value, userData)) + callback.Invoke(this, addr, size, value, userData) - if _memWriteHooks |> Seq.isEmpty then - let memWriteHookInternal = new MemWriteHookInternal(trampoline) - _hookInternals.Add(memWriteHookInternal) - let funcPointer = Marshal.GetFunctionPointerForDelegate(memWriteHookInternal) - let hh = new UIntPtr(allocate(IntPtr.Size)) - match binding.HookAddNoarg(_eng.[0], hh, Common.UC_HOOK_MEM_WRITE, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 beginAddr, uint64 endAddr) |> this.CheckResult with - | Some e -> raise e | None -> () + let memWriteHookInternal = new MemWriteHookInternal(trampoline) + let funcPointer = Marshal.GetFunctionPointerForDelegate(memWriteHookInternal) + let hh = new UIntPtr(allocate(IntPtr.Size)) + match binding.HookAddNoarg(_eng.[0], hh, Common.UC_HOOK_MEM_WRITE, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 beginAddr, uint64 endAddr) |> checkResult with + | Some e -> raise e | None -> () - _memWriteHooks.Add(callback, userData) + let hh = (unativeint)(Marshal.ReadIntPtr((nativeint)hh)) + _memWriteHooks.Add(callback, (hh, userData, memWriteHookInternal)) member this.HookDel(callback: MemWriteHook) = hookDel _memWriteHooks callback - member this.AddEventMemHook(callback: EventMemHook, eventType: Int32, userData: Object) = + member this.AddEventMemHook(callback: EventMemHook, eventType: Int32, userData: Object, beginAddr: Int64, endAddr: Int64) = let trampoline(u: IntPtr) (eventType: Int32) (addr: Int64) (size: Int32) (value: Int64) (user: IntPtr) = - _memEventHooks.Keys - |> Seq.filter(fun eventFlag -> (eventType &&& eventFlag) <> 0) - |> Seq.map(fun eventflag -> _memEventHooks.[eventflag]) - |> Seq.concat - |> Seq.map(fun (callback, userData) -> callback.Invoke(this, eventType, addr, size, value, userData)) - |> Seq.forall id + callback.Invoke(this, eventType, addr, size, value, userData) // register the event if not already done _memEventHooks.Keys |> Seq.filter(fun eventFlag -> (eventType &&& eventFlag) <> 0) - |> Seq.filter(fun eventFlag -> _memEventHooks.[eventFlag] |> Seq.isEmpty) |> Seq.iter(fun eventFlag -> let memEventHookInternal = new EventMemHookInternal(trampoline) - _hookInternals.Add(memEventHookInternal) let funcPointer = Marshal.GetFunctionPointerForDelegate(memEventHookInternal) let hh = new UIntPtr(allocate(IntPtr.Size)) - match binding.HookAddNoarg(_eng.[0], hh, eventFlag, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 1, uint64 0) |> this.CheckResult with + match binding.HookAddNoarg(_eng.[0], hh, eventFlag, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 beginAddr, uint64 endAddr) |> checkResult with | Some e -> raise e | None -> () + + let hh = (unativeint)(Marshal.ReadIntPtr((nativeint)hh)) + _memEventHooks.[eventFlag].Add((callback, (hh, userData, memEventHookInternal))) ) - // register the callbacks - _memEventHooks.Keys - |> Seq.filter(fun eventFlag -> (eventType &&& eventFlag) <> 0) - |> Seq.iter(fun eventFlag -> _memEventHooks.[eventFlag].Add((callback, userData))) + member this.AddEventMemHook(callback: EventMemHook, eventType: Int32, userData: Object) = + this.AddEventMemHook(callback, eventType, userData, 1, 0) member this.AddEventMemHook(callback: EventMemHook, eventType: Int32) = this.AddEventMemHook(callback, eventType, null) member this.HookDel(callback: EventMemHook) = - let callbacks = (_memEventHooks.Values |> Seq.concat).ToList() - hookDel callbacks callback + _memEventHooks.Keys + |> Seq.iter(fun eventFlag -> hookDel _memEventHooks.[eventFlag] callback) + + member this.AddInHook(callback: InHook, userData: Object, beginAddr: Int64, endAddr: Int64) = + let trampoline(u: IntPtr) (port: Int32) (size: Int32) (user: IntPtr) = + callback.Invoke(this, port, size, userData) + + let inHookInternal = new InHookInternal(trampoline) + let funcPointer = Marshal.GetFunctionPointerForDelegate(inHookInternal) + let hh = new UIntPtr(allocate(IntPtr.Size)) + match binding.HookAddArg0(_eng.[0], hh, Common.UC_HOOK_INSN, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 beginAddr, uint64 endAddr, X86.UC_X86_INS_IN) |> checkResult with + | Some e -> raise e | None -> () + + let hh = (unativeint)(Marshal.ReadIntPtr((nativeint)hh)) + _inHooks.Add(callback, (hh, userData, inHookInternal)) member this.AddInHook(callback: InHook, userData: Object) = - let trampoline(u: IntPtr) (port: Int32) (size: Int32) (user: IntPtr) = - _inHooks - |> Seq.map(fun (callback, userData) -> callback.Invoke(this, port, size, userData)) - |> Seq.last - - if _inHooks |> Seq.isEmpty then - let inHookInternal = new InHookInternal(trampoline) - _hookInternals.Add(inHookInternal) - let funcPointer = Marshal.GetFunctionPointerForDelegate(inHookInternal) - let hh = new UIntPtr(allocate(IntPtr.Size)) - match binding.HookAddArg0(_eng.[0], hh, Common.UC_HOOK_INSN, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 1, uint64 0, X86.UC_X86_INS_IN) |> this.CheckResult with - | Some e -> raise e | None -> () - - _inHooks.Add(callback, userData) + this.AddInHook(callback, userData, 1, 0) member this.AddInHook(callback: InHook) = this.AddInHook(callback, null) - member this.AddOutHook(callback: OutHook, userData: Object) = + member this.HookDel(callback: InHook) = + hookDel _inHooks callback + + member this.AddOutHook(callback: OutHook, userData: Object, beginAddr: Int64, endAddr: Int64) = let trampoline(u: IntPtr) (port: Int32) (size: Int32) (value: Int32) (user: IntPtr) = - _outHooks - |> Seq.iter(fun (callback, userData) -> callback.Invoke(this, port, size, value, userData)) + callback.Invoke(this, port, size, value, userData) - if _outHooks |> Seq.isEmpty then - let outHookInternal = new OutHookInternal(trampoline) - _hookInternals.Add(outHookInternal) - let funcPointer = Marshal.GetFunctionPointerForDelegate(outHookInternal) - let hh = new UIntPtr(allocate(IntPtr.Size)) - match binding.HookAddArg0(_eng.[0], hh, Common.UC_HOOK_INSN, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 1, uint64 0, X86.UC_X86_INS_OUT) |> this.CheckResult with - | Some e -> raise e | None -> () + let outHookInternal = new OutHookInternal(trampoline) + let funcPointer = Marshal.GetFunctionPointerForDelegate(outHookInternal) + let hh = new UIntPtr(allocate(IntPtr.Size)) + match binding.HookAddArg0(_eng.[0], hh, Common.UC_HOOK_INSN, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 beginAddr, uint64 endAddr, X86.UC_X86_INS_OUT) |> checkResult with + | Some e -> raise e | None -> () - _outHooks.Add(callback, userData) + let hh = (unativeint)(Marshal.ReadIntPtr((nativeint)hh)) + _outHooks.Add(callback, (hh, userData, outHookInternal)) + + member this.AddOutHook(callback: OutHook, userData: Object) = + this.AddOutHook(callback, userData, 1, 0) member this.AddOutHook(callback: OutHook) = this.AddOutHook(callback, null) - member this.AddSyscallHook(callback: SyscallHook, userData: Object) = + member this.HookDel(callback: OutHook) = + hookDel _outHooks callback + + member this.AddSyscallHook(callback: SyscallHook, userData: Object, beginAddr: Int64, endAddr: Int64) = let trampoline(u: IntPtr) (user: IntPtr) = - _syscallHooks - |> Seq.iter(fun (callback, userData) -> callback.Invoke(this, userData)) + callback.Invoke(this, userData) - if _syscallHooks |> Seq.isEmpty then - let syscallHookInternal = new SyscallHookInternal(trampoline) - _hookInternals.Add(syscallHookInternal) - let funcPointer = Marshal.GetFunctionPointerForDelegate(syscallHookInternal) - let hh = new UIntPtr(allocate(IntPtr.Size)) - match binding.HookAddArg0(_eng.[0], hh, Common.UC_HOOK_INSN, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 1, uint64 0, X86.UC_X86_INS_SYSCALL) |> this.CheckResult with - | Some e -> raise e | None -> () + let syscallHookInternal = new SyscallHookInternal(trampoline) + let funcPointer = Marshal.GetFunctionPointerForDelegate(syscallHookInternal) + let hh = new UIntPtr(allocate(IntPtr.Size)) + match binding.HookAddArg0(_eng.[0], hh, Common.UC_HOOK_INSN, new UIntPtr(funcPointer.ToPointer()), IntPtr.Zero, uint64 beginAddr, uint64 endAddr, X86.UC_X86_INS_SYSCALL) |> checkResult with + | Some e -> raise e | None -> () - _syscallHooks.Add(callback, userData) + let hh = (unativeint)(Marshal.ReadIntPtr((nativeint)hh)) + _syscallHooks.Add(callback, (hh, userData, syscallHookInternal)) + + member this.AddSyscallHook(callback: SyscallHook, userData: Object) = + this.AddSyscallHook(callback, userData, 1, 0) member this.AddSyscallHook(callback: SyscallHook) = this.AddSyscallHook(callback, null) + member this.HookDel(callback: SyscallHook) = + hookDel _syscallHooks callback + member this.Version() = let (major, minor) = (new UIntPtr(), new UIntPtr()) let combined = binding.Version(major, minor) From 11fcbad9ff937c922f6666f6f8111b2240efe314 Mon Sep 17 00:00:00 2001 From: mio Date: Sun, 12 Mar 2023 20:28:01 +0100 Subject: [PATCH 41/43] Remove redundant printf --- tests/unit/test_ctl.c | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/unit/test_ctl.c b/tests/unit/test_ctl.c index 0c1eeabc..e1e467d3 100644 --- a/tests/unit/test_ctl.c +++ b/tests/unit/test_ctl.c @@ -309,7 +309,6 @@ static void test_uc_emu_stop_set_ip_callback(uc_engine *uc, uint64_t address, ui uint64_t rip = code_start + 0xb; if (address == code_start + 0x7) { - printf("stoping\n"); uc_emu_stop(uc); uc_reg_write(uc, UC_X86_REG_RIP, &rip); } From 8f2841ecdb4db099d5670fa396012810179d7a06 Mon Sep 17 00:00:00 2001 From: Choongwoo Han Date: Mon, 20 Mar 2023 17:07:15 -0700 Subject: [PATCH 42/43] Cache index for find_memory_region --- uc.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/uc.c b/uc.c index 76c4eb28..ed9663ef 100644 --- a/uc.c +++ b/uc.c @@ -1532,8 +1532,10 @@ MemoryRegion *find_memory_region(struct uc_struct *uc, uint64_t address) if (i < uc->mapped_block_count && address >= uc->mapped_blocks[i]->addr && - address <= uc->mapped_blocks[i]->end - 1) + address < uc->mapped_blocks[i]->end) { + uc->mapped_block_cache_index = i; return uc->mapped_blocks[i]; + } // not found return NULL; From 0a38a0bf1728bfcf6e358e3574211dac4b62446b Mon Sep 17 00:00:00 2001 From: Choongwoo Han Date: Mon, 20 Mar 2023 18:41:59 -0700 Subject: [PATCH 43/43] Fix test failure --- uc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/uc.c b/uc.c index ed9663ef..a1a71366 100644 --- a/uc.c +++ b/uc.c @@ -1524,7 +1524,7 @@ MemoryRegion *find_memory_region(struct uc_struct *uc, uint64_t address) if (i < uc->mapped_block_count && address >= uc->mapped_blocks[i]->addr && - address < uc->mapped_blocks[i]->end) { + address <= uc->mapped_blocks[i]->end - 1) { return uc->mapped_blocks[i]; } @@ -1532,7 +1532,7 @@ MemoryRegion *find_memory_region(struct uc_struct *uc, uint64_t address) if (i < uc->mapped_block_count && address >= uc->mapped_blocks[i]->addr && - address < uc->mapped_blocks[i]->end) { + address <= uc->mapped_blocks[i]->end - 1) { uc->mapped_block_cache_index = i; return uc->mapped_blocks[i]; }