diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 9a6630a4..1ebce953 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -23,7 +23,6 @@ android { packaging { jniLibs { excludes += "**/liblog.so" - excludes += "**/libdobby.so" } resources.excludes.add("META-INF/versions/9/OSGI-INF/MANIFEST.MF") } diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 0ac3fc25..2bb0776d 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -3,3 +3,8 @@ -keep class es.chiteroman.playintegrityfix.CustomKeyStoreSpi -keep class es.chiteroman.playintegrityfix.CustomKeyStoreKeyPairGeneratorSpi$EC -keep class es.chiteroman.playintegrityfix.CustomKeyStoreKeyPairGeneratorSpi$RSA + +-keep class org.bouncycastle.jcajce.provider.** { *; } +-keep class org.bouncycastle.jce.provider.** { *; } + +-dontwarn javax.naming.** diff --git a/app/src/main/cpp/CMakeLists.txt b/app/src/main/cpp/CMakeLists.txt index d3b8b4f4..4f8dc9df 100644 --- a/app/src/main/cpp/CMakeLists.txt +++ b/app/src/main/cpp/CMakeLists.txt @@ -9,7 +9,3 @@ link_libraries(log) link_libraries(cxx::cxx) add_library(${CMAKE_PROJECT_NAME} SHARED main.cpp) - -add_subdirectory(Dobby) - -target_link_libraries(${CMAKE_PROJECT_NAME} PRIVATE dobby_static) \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/.clang-format b/app/src/main/cpp/Dobby/.clang-format deleted file mode 100644 index 17d6bc41..00000000 --- a/app/src/main/cpp/Dobby/.clang-format +++ /dev/null @@ -1,18 +0,0 @@ -BasedOnStyle: LLVM - -IndentWidth: 2 -TabWidth: 2 -UseTab: Never -ColumnLimit: 120 - -FixNamespaceComments: true - -# default is false -#AlignConsecutiveMacros: true -#AlignConsecutiveAssignments: true -#AlignConsecutiveDeclarations: true - -# default is true -ReflowComments: false -SortIncludes : false -AllowShortFunctionsOnASingleLine: false \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/.gitignore b/app/src/main/cpp/Dobby/.gitignore deleted file mode 100644 index 4bbed764..00000000 --- a/app/src/main/cpp/Dobby/.gitignore +++ /dev/null @@ -1,80 +0,0 @@ -.DS_Store -.idea/ -*-build*/ -build-output/ - -CMakeLists.txt.user -CMakeCache.txt -CMakeFiles -CMakeScripts -Testing -Makefile -cmake_install.cmake -install_manifest.txt -compile_commands.json -CTestTestfile.cmake -_deps - -## Build generated -build/ -DerivedData/ - -## Various settings -*.pbxuser -!default.pbxuser -*.mode1v3 -!default.mode1v3 -*.mode2v3 -!default.mode2v3 -*.perspectivev3 -!default.perspectivev3 -xcuserdata/ - -## Other -*.moved-aside -*.xccheckout -*.xcscmblueprint - -## Obj-C/Swift specific -*.hmap -*.ipa -*.dSYM.zip -*.dSYM - -# Prerequisites -*.d - -# Compiled Object files -*.slo -*.lo -*.o -*.obj - -# Precompiled Headers -*.gch -*.pch - -# Compiled Dynamic libraries -*.so -*.dylib -*.dll - -# Fortran module files -*.mod -*.smod - -# Compiled Static libraries -*.lai -*.la -*.a -*.lib - -# Executables -*.exe -*.out -*.app - -# Prefab -/prefab/**/*.a -/prefab/**/*.h -/AndroidManifest.xml diff --git a/app/src/main/cpp/Dobby/CMakeLists.txt b/app/src/main/cpp/Dobby/CMakeLists.txt deleted file mode 100644 index 919d9967..00000000 --- a/app/src/main/cpp/Dobby/CMakeLists.txt +++ /dev/null @@ -1,384 +0,0 @@ -cmake_minimum_required(VERSION 3.5) -project(Dobby) -enable_language(ASM) - -include(cmake/Util.cmake) -include(cmake/Macros.cmake) -include(cmake/build_environment_check.cmake) -include(cmake/auto_source_group.cmake) -include(cmake/xcode_generator_helper.cmake) - -set(CMAKE_CXX_STANDARD 11) -set(CMAKE_CXX_STANDARD_REQUIRED ON) -set(CMAKE_C_STANDARD 11) - -auto_source_group("." "auto-source-group" "\\.(cc|cpp|c|h)$") - -# --- options - -option(DOBBY_DEBUG "Enable debug logging" OFF) - -option(NearBranch "Enable near branch trampoline" ON) - -option(FullFloatingPointRegisterPack "Save and pack all floating-point registers" OFF) - -option(Plugin.SymbolResolver "Enable symbol resolver" ON) - -option(Plugin.ImportTableReplace "Enable import table replace " OFF) - -option(Plugin.Android.BionicLinkerUtil "Enable android bionic linker util" ON) - -option(DOBBY_BUILD_EXAMPLE "Build example" OFF) - -option(DOBBY_BUILD_TEST "Build test" OFF) - -# --- private -option(DOBBY_BUILD_KERNEL_MODE "Build xnu kernel mode" OFF) - -option(Private.Obfuscation "Enable llvm obfuscation" OFF) - -if ((NOT DEFINED CMAKE_BUILD_TYPE) OR (CMAKE_BUILD_TYPE STREQUAL "Debug")) - set(DOBBY_DEBUG ON) -endif () - - -set(compile_definitions "") - -# for arm64, allow access q8 - q31 -if (FullFloatingPointRegisterPack) - set(compile_definitions "${compile_definitions} -DFULL_FLOATING_POINT_REGISTER_PACK") -endif () - -if (DOBBY_BUILD_KERNEL_MODE) - set(compile_definitions "${compile_definitions} -DBUILDING_KERNEL") -endif () - -if (DOBBY_DEBUG) - set(compile_definitions "${compile_definitions} -DDOBBY_DEBUG") -else () - set(compile_definitions "${compile_definitions} -DDOBBY_LOGGING_DISABLE") -endif () - -if (CMAKE_GENERATOR STREQUAL Xcode) -endif () - -include(cmake/compiler_and_linker.cmake) - -message(STATUS "[Dobby] CMAKE_BUILD_TYPE: ${CMAKE_BUILD_TYPE}") -message(STATUS "[Dobby] DOBBY_DEBUG: ${DOBBY_DEBUG}") -message(STATUS "[Dobby] NearBranch: ${NearBranch}") -message(STATUS "[Dobby] FullFloatingPointRegisterPack: ${FullFloatingPointRegisterPack}") -message(STATUS "[Dobby] Plugin.SymbolResolver: ${Plugin.SymbolResolver}") -message(STATUS "[Dobby] Plugin.ImportTableReplace: ${Plugin.ImportTableReplace}") -message(STATUS "[Dobby] Plugin.Android.BionicLinkerUtil: ${Plugin.Android.BionicLinkerUtil}") -message(STATUS "[Dobby] DOBBY_BUILD_EXAMPLE: ${DOBBY_BUILD_EXAMPLE}") -message(STATUS "[Dobby] DOBBY_BUILD_TEST: ${DOBBY_BUILD_TEST}") -message(STATUS "[Dobby] DOBBY_BUILD_KERNEL_MODE: ${DOBBY_BUILD_KERNEL_MODE}") -message(STATUS "[Dobby] Private.Obfuscation: ${Private.Obfuscation}") - -# --- - -include_directories( - . - ./include - ./source - source/dobby - - ./external - ./external/logging - - ./builtin-plugin -) - -if (SYSTEM.Darwin AND (NOT DOBBY_BUILD_KERNEL_MODE)) - include_directories( - source/Backend/UserMode - ) -endif () - -# --- - -set(DOBBY_DIR ${CMAKE_CURRENT_SOURCE_DIR}) -set(dobby.SOURCE_FILE_LIST ${dobby.SOURCE_FILE_LIST} - # cpu - source/core/arch/CpuFeature.cc - source/core/arch/CpuRegister.cc - - # assembler - source/core/assembler/assembler.cc - source/core/assembler/assembler-arm.cc - source/core/assembler/assembler-arm64.cc - source/core/assembler/assembler-ia32.cc - source/core/assembler/assembler-x64.cc - - # codegen - source/core/codegen/codegen-arm.cc - source/core/codegen/codegen-arm64.cc - source/core/codegen/codegen-ia32.cc - source/core/codegen/codegen-x64.cc - - # memory kit - source/MemoryAllocator/CodeBuffer/CodeBufferBase.cc - source/MemoryAllocator/AssemblyCodeBuilder.cc - source/MemoryAllocator/MemoryAllocator.cc - - # instruction relocation - source/InstructionRelocation/arm/InstructionRelocationARM.cc - source/InstructionRelocation/arm64/InstructionRelocationARM64.cc - source/InstructionRelocation/x86/InstructionRelocationX86.cc - source/InstructionRelocation/x86/InstructionRelocationX86Shared.cc - source/InstructionRelocation/x64/InstructionRelocationX64.cc - source/InstructionRelocation/x86/x86_insn_decode/x86_insn_decode.c - - # intercept routing - source/InterceptRouting/InterceptRouting.cpp - - # intercept routing trampoline - source/TrampolineBridge/Trampoline/arm/trampoline_arm.cc - source/TrampolineBridge/Trampoline/arm64/trampoline_arm64.cc - source/TrampolineBridge/Trampoline/x86/trampoline_x86.cc - source/TrampolineBridge/Trampoline/x64/trampoline_x64.cc - - # closure trampoline bridge - arm - source/TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.cc - source/TrampolineBridge/ClosureTrampolineBridge/arm/helper_arm.cc - source/TrampolineBridge/ClosureTrampolineBridge/arm/closure_bridge_arm.cc - source/TrampolineBridge/ClosureTrampolineBridge/arm/ClosureTrampolineARM.cc - # closure trampoline bridge - arm64 - source/TrampolineBridge/ClosureTrampolineBridge/arm64/helper_arm64.cc - source/TrampolineBridge/ClosureTrampolineBridge/arm64/closure_bridge_arm64.cc - source/TrampolineBridge/ClosureTrampolineBridge/arm64/ClosureTrampolineARM64.cc - # closure trampoline bridge - x86 - source/TrampolineBridge/ClosureTrampolineBridge/x86/helper_x86.cc - source/TrampolineBridge/ClosureTrampolineBridge/x86/closure_bridge_x86.cc - source/TrampolineBridge/ClosureTrampolineBridge/x86/ClosureTrampolineX86.cc - # closure trampoline bridge - x64 - source/TrampolineBridge/ClosureTrampolineBridge/x64/helper_x64.cc - source/TrampolineBridge/ClosureTrampolineBridge/x64/closure_bridge_x64.cc - source/TrampolineBridge/ClosureTrampolineBridge/x64/ClosureTrampolineX64.cc - - source/InterceptRouting/Routing/InstructionInstrument/InstructionInstrument.cc - source/InterceptRouting/Routing/InstructionInstrument/RoutingImpl.cc - source/InterceptRouting/Routing/InstructionInstrument/instrument_routing_handler.cc - - source/InterceptRouting/Routing/FunctionInlineHook/FunctionInlineHook.cc - source/InterceptRouting/Routing/FunctionInlineHook/RoutingImpl.cc - - # plugin register - source/InterceptRouting/RoutingPlugin/RoutingPlugin.cc - - # main - source/dobby.cpp - source/Interceptor.cpp - source/InterceptEntry.cpp - ) - - -if (SYSTEM.Darwin AND NOT DOBBY_BUILD_KERNEL_MODE) - set(dobby.SOURCE_FILE_LIST ${dobby.SOURCE_FILE_LIST} - source/Backend/UserMode/PlatformUtil/Darwin/ProcessRuntimeUtility.cc - - source/Backend/UserMode/UnifiedInterface/platform-posix.cc - - source/Backend/UserMode/ExecMemory/code-patch-tool-darwin.cc - source/Backend/UserMode/ExecMemory/clear-cache-tool-all.c - ) - -elseif (SYSTEM.Linux OR SYSTEM.Android) - set(dobby.SOURCE_FILE_LIST ${dobby.SOURCE_FILE_LIST} - source/Backend/UserMode/PlatformUtil/Linux/ProcessRuntimeUtility.cc - - source/Backend/UserMode/UnifiedInterface/platform-posix.cc - - source/Backend/UserMode/ExecMemory/code-patch-tool-posix.cc - source/Backend/UserMode/ExecMemory/clear-cache-tool-all.c - ) -elseif (SYSTEM.Windows) - set(dobby.SOURCE_FILE_LIST ${dobby.SOURCE_FILE_LIST} - source/Backend/UserMode/PlatformUtil/Windows/ProcessRuntimeUtility.cc - - source/Backend/UserMode/UnifiedInterface/platform-windows.cc - - source/Backend/UserMode/ExecMemory/code-patch-tool-windows.cc - source/Backend/UserMode/ExecMemory/clear-cache-tool-all.c - ) -endif () - -if (PROCESSOR.X86_64 OR PROCESSOR.X86) - set(NearBranch ON) -endif () - -# --- - -if (0 AND SYSTEM.iOS AND (NOT DOBBY_BUILD_KERNEL_MODE)) - include_directories( - source/Backend/UserMode/ExecMemory/substrated - ) - set(compile_definitions "${compile_definitions} -DCODE_PATCH_WITH_SUBSTRATED") - set(dobby.SOURCE_FILE_LIST ${dobby.SOURCE_FILE_LIST} - source/Backend/UserMode/ExecMemory/substrated/mach_interface_support - ) -endif () - -# ----- instrument ----- - -if (FunctionWrapper) - set(dobby.SOURCE_FILE_LIST ${dobby.SOURCE_FILE_LIST} - # user mode - multi thread support - # source/UserMode/MultiThreadSupport/ThreadSupport.cpp - # source/UserMode/Thread/PlatformThread.cc - # source/UserMode/Thread/platform-thread-${platform1}.cc - ) - message(FATAL_ERROR "[!] FunctionWrapper plugin is not supported") -endif () - -# --- - -if (NearBranch) - set(dobby.SOURCE_FILE_LIST ${dobby.SOURCE_FILE_LIST} - source/InterceptRouting/RoutingPlugin/NearBranchTrampoline/near_trampoline_arm64.cc - source/InterceptRouting/RoutingPlugin/NearBranchTrampoline/NearBranchTrampoline.cc - source/MemoryAllocator/NearMemoryAllocator.cc) -endif () - -# --- - -# add logging library -add_subdirectory(external/logging) -get_target_property(logging.SOURCE_FILE_LIST logging SOURCES) - -# add osbase library -add_subdirectory(external/osbase) - -# --- - -if (Plugin.SymbolResolver) - include_directories(builtin-plugin/SymbolResolver) - add_subdirectory(builtin-plugin/SymbolResolver) - get_target_property(symbol_resolver.SOURCE_FILE_LIST dobby_symbol_resolver SOURCES) - set(dobby.plugin.SOURCE_FILE_LIST ${dobby.plugin.SOURCE_FILE_LIST} - ${symbol_resolver.SOURCE_FILE_LIST} - ) -endif () - -# --- - -set(dobby.HEADER_FILE_LIST - include/dobby.h - ) - -# --- - -# add build version -string(TIMESTAMP TODAY "%Y%m%d") -set(VERSION_REVISION "-${TODAY}") -if (EXISTS "${CMAKE_SOURCE_DIR}/.git") - execute_process( - COMMAND git rev-parse --short --verify HEAD - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} - OUTPUT_VARIABLE VERSION_COMMIT_HASH - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - if (VERSION_COMMIT_HASH) - set(VERSION_REVISION "${VERSION_REVISION}-${VERSION_COMMIT_HASH}") - endif () -endif () -set(DOBBY_BUILD_VERSION "Dobby${VERSION_REVISION}") -set(compile_definitions "${compile_definitions} -D__DOBBY_BUILD_VERSION__=\"${DOBBY_BUILD_VERSION}\"") -message(STATUS "[Dobby] ${DOBBY_BUILD_VERSION}") - -# --- - -set(SOURCE_FILE_LIST - ${dobby.HEADER_FILE_LIST} - ${dobby.SOURCE_FILE_LIST} - ${logging.SOURCE_FILE_LIST} - ${dobby.plugin.SOURCE_FILE_LIST} - ) - -get_absolute_path_list(SOURCE_FILE_LIST SOURCE_FILE_LIST_) -set(SOURCE_FILE_LIST ${SOURCE_FILE_LIST_}) - -add_library(dobby SHARED - ${SOURCE_FILE_LIST} - ) - -target_include_directories(dobby PUBLIC - include - ) - -# --- - -add_library(dobby_static STATIC - ${SOURCE_FILE_LIST} - ) - -target_include_directories(dobby_static PUBLIC - include - ) - -set_target_properties(dobby_static - PROPERTIES OUTPUT_NAME "dobby" - ) - -# --- - -set_target_properties(dobby - PROPERTIES - LINK_FLAGS "${linker_flags}" - COMPILE_FLAGS "${compiler_flags}" - ) - -set_target_properties(dobby_static - PROPERTIES - COMPILE_FLAGS "${compiler_flags}" - ) - -target_compile_definitions(dobby PRIVATE - "COMPILE_DEFINITIONS ${compile_definitions}" - ) -target_compile_definitions(dobby_static PRIVATE - "COMPILE_DEFINITIONS ${compile_definitions}" - ) - -# --- - -if (Private.Obfuscation) - set(linker_flags "${linker_flags} -Wl,-mllvm -Wl,-obfuscator-conf=all") -endif () - -# --- - -if (SYSTEM.Android) - target_link_libraries(dobby log) - if (PROCESSOR.ARM) - set_target_properties(dobby - PROPERTIES - ANDROID_ARM_MODE arm - ) - set_target_properties(dobby_static - PROPERTIES - ANDROID_ARM_MODE arm - ) - endif () -endif () - -if (SYSTEM.Linux) - target_link_libraries(dobby dl) -endif () - -# --- - -if (DOBBY_BUILD_EXAMPLE AND (NOT DOBBY_BUILD_KERNEL_MODE)) - add_subdirectory(examples) -endif () - -if (DOBBY_BUILD_TEST AND (NOT DOBBY_BUILD_KERNEL_MODE)) - add_subdirectory(tests) -endif () - -# --- - -if (SYSTEM.Darwin AND (NOT DOBBY_BUILD_KERNEL_MODE)) - include(cmake/platform/platform-darwin.cmake) -endif () \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/LICENSE b/app/src/main/cpp/Dobby/LICENSE deleted file mode 100644 index f49a4e16..00000000 --- a/app/src/main/cpp/Dobby/LICENSE +++ /dev/null @@ -1,201 +0,0 @@ - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/README.md b/app/src/main/cpp/Dobby/README.md deleted file mode 100644 index c0c0195f..00000000 --- a/app/src/main/cpp/Dobby/README.md +++ /dev/null @@ -1,26 +0,0 @@ -## Dobby - -[![Contact me Telegram](https://img.shields.io/badge/Contact%20me-Telegram-blue.svg)](https://t.me/IOFramebuffer) [![Join group Telegram](https://img.shields.io/badge/Join%20group-Telegram-brightgreen.svg)](https://t.me/dobby_group) - -Dobby a lightweight, multi-platform, multi-architecture exploit hook framework. - -- Minimal and modular library -- Multi-platform support(Windows/macOS/iOS/Android/Linux) -- Multiple architecture support(X86, X86-64, ARM, ARM64) - -## Compile - -[docs/compile.md](docs/compile.md) - -## Download - -[download latest library](https://github.com/jmpews/Dobby/releases/tag/latest) - -## Credits - -1. [frida-gum](https://github.com/frida/frida-gum) -2. [minhook](https://github.com/TsudaKageyu/minhook) -3. [substrate](https://github.com/jevinskie/substrate). -4. [v8](https://github.com/v8/v8) -5. [dart](https://github.com/dart-lang/sdk) -6. [vixl](https://git.linaro.org/arm/vixl.git) diff --git a/app/src/main/cpp/Dobby/README_zh-cn.md b/app/src/main/cpp/Dobby/README_zh-cn.md deleted file mode 100644 index 2f528b45..00000000 --- a/app/src/main/cpp/Dobby/README_zh-cn.md +++ /dev/null @@ -1,3 +0,0 @@ -## Dobby - -**待更新** \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/MGCopyAnswerMonitor.cc b/app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/MGCopyAnswerMonitor.cc deleted file mode 100644 index ddf2ee2c..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/MGCopyAnswerMonitor.cc +++ /dev/null @@ -1,46 +0,0 @@ -#include "./dobby_monitor.h" - -#include -#include - -#define LOG_TAG "MGCopyAnswer" - -static uintptr_t getCallFirstArg(DobbyRegisterContext *ctx) { - uintptr_t result; -#if defined(_M_X64) || defined(__x86_64__) -#if defined(_WIN32) - result = ctx->general.regs.rcx; -#else - result = ctx->general.regs.rdi; -#endif -#elif defined(__arm64__) || defined(__aarch64__) - result = ctx->general.regs.x0; -#elif defined(__arm__) - result = ctx->general.regs.r0; -#else -#error "Not Support Architecture." -#endif - return result; -} - -void common_handler(DobbyRegisterContext *ctx, const InterceptEntry *info) { - CFStringRef key_ = 0; - key_ = (CFStringRef)getCallFirstArg(ctx); - - char str_key[256] = {0}; - CFStringGetCString(key_, str_key, 256, kCFStringEncodingUTF8); - LOG("[#] MGCopyAnswer:: %s\n", str_key); -} - -#if 0 -__attribute__((constructor)) static void ctor() { - void *lib = dlopen("/usr/lib/libMobileGestalt.dylib", RTLD_NOW); - void *MGCopyAnswer_addr = DobbySymbolResolver("libMobileGestalt.dylib", "MGCopyAnswer"); - - sleep(1); - - dobby_enable_near_branch_trampoline(); - DobbyInstrument((void *)MGCopyAnswer_addr, common_handler); - dobby_disable_near_branch_trampoline(); -} -#endif diff --git a/app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/dynamic_loader_monitor.cc b/app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/dynamic_loader_monitor.cc deleted file mode 100644 index 3a9764d3..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/dynamic_loader_monitor.cc +++ /dev/null @@ -1,94 +0,0 @@ -#include /* getenv */ -#include -#include - -#include -#include - -#include -#include - -#include -#include - -#include "dobby.h" - -#include "dobby/common.h" - -#define LOG_TAG "DynamicLoaderMonitor" - -std::unordered_map traced_dlopen_handle_list; - -static void *(*orig_dlopen)(const char *__file, int __mode); -static void *fake_dlopen(const char *__file, int __mode) { - void *result = orig_dlopen(__file, __mode); - if (result != NULL && __file) { - char *traced_filename = (char *)malloc(MAXPATHLEN); - // FIXME: strncpy - strcpy(traced_filename, __file); - INFO_LOG("[-] dlopen handle: %s", __file); - traced_dlopen_handle_list.insert(std::make_pair(result, (const char *)traced_filename)); - } - return result; -} - -static void *(*orig_loader_dlopen)(const char *filename, int flags, const void *caller_addr); -static void *fake_loader_dlopen(const char *filename, int flags, const void *caller_addr) { - void *result = orig_loader_dlopen(filename, flags, caller_addr); - if (result != NULL) { - char *traced_filename = (char *)malloc(MAXPATHLEN); - // FIXME: strncpy - strcpy(traced_filename, filename); - INFO_LOG("[-] dlopen handle: %s", filename); - traced_dlopen_handle_list.insert(std::make_pair(result, (const char *)traced_filename)); - } - return result; -} - -static const char *get_traced_filename(void *handle, bool removed) { - std::unordered_map::iterator it; - it = traced_dlopen_handle_list.find(handle); - if (it != traced_dlopen_handle_list.end()) { - if (removed) - traced_dlopen_handle_list.erase(it); - return it->second; - } - return NULL; -} - -static void *(*orig_dlsym)(void *__handle, const char *__symbol); -static void *fake_dlsym(void *__handle, const char *__symbol) { - const char *traced_filename = get_traced_filename(__handle, false); - if (traced_filename) { - INFO_LOG("[-] dlsym: %s, symbol: %s", traced_filename, __symbol); - } - return orig_dlsym(__handle, __symbol); -} - -static int (*orig_dlclose)(void *__handle); -static int fake_dlclose(void *__handle) { - const char *traced_filename = get_traced_filename(__handle, true); - if (traced_filename) { - INFO_LOG("[-] dlclose: %s", traced_filename); - free((void *)traced_filename); - } - return orig_dlclose(__handle); -} - -#if 0 -__attribute__((constructor)) static void ctor() { -#if defined(__ANDROID__) -#if 0 - void *dl = dlopen("libdl.so", RTLD_LAZY); - void *__loader_dlopen = dlsym(dl, "__loader_dlopen"); -#endif - DobbyHook((void *)DobbySymbolResolver(NULL, "__loader_dlopen"), (void *)fake_loader_dlopen, - (void **)&orig_loader_dlopen); -#else - DobbyHook((void *)DobbySymbolResolver(NULL, "dlopen"), (void *)fake_dlopen, (void **)&orig_dlopen); -#endif - - DobbyHook((void *)dlsym, (void *)fake_dlsym, (void **)&orig_dlsym); - DobbyHook((void *)dlclose, (void *)fake_dlclose, (void **)&orig_dlclose); -} -#endif diff --git a/app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/file_operation_monitor.cc b/app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/file_operation_monitor.cc deleted file mode 100644 index d4f09ca5..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/file_operation_monitor.cc +++ /dev/null @@ -1,97 +0,0 @@ -#include /* getenv */ -#include -#include - -#include -#include - -#include -#include - -#include - -#include "./dobby_monitor.h" - -std::unordered_map *TracedFopenFileList; - -FILE *(*orig_fopen)(const char *filename, const char *mode); -FILE *fake_fopen(const char *filename, const char *mode) { - FILE *result = NULL; - result = orig_fopen(filename, mode); - if (result != NULL) { - char *traced_filename = (char *)malloc(MAXPATHLEN); - // FIXME: strncpy - strcpy(traced_filename, filename); - std::cout << "[-] trace file: " << filename << std::endl; - TracedFopenFileList->insert(std::make_pair(result, traced_filename)); - } - return result; -} - -static const char *GetFileDescriptorTraced(FILE *stream, bool removed) { - std::unordered_map::iterator it; - it = TracedFopenFileList->find(stream); - if (it != TracedFopenFileList->end()) { - if (removed) - TracedFopenFileList->erase(it); - return it->second; - } - return NULL; -} - -size_t (*orig_fread)(void *ptr, size_t size, size_t count, FILE *stream); -size_t fake_fread(void *ptr, size_t size, size_t count, FILE *stream) { - const char *file_name = GetFileDescriptorTraced(stream, false); - if (file_name) { - LOG("[-] fread: %s, buffer: %p\n", file_name, ptr); - } - return orig_fread(ptr, size, count, stream); -} - -size_t (*orig_fwrite)(const void *ptr, size_t size, size_t count, FILE *stream); -size_t fake_fwrite(void *ptr, size_t size, size_t count, FILE *stream) { - const char *file_name = GetFileDescriptorTraced(stream, false); - if (file_name) { - LOG("[-] fwrite %s\n from %p\n", file_name, ptr); - } - return orig_fwrite(ptr, size, count, stream); -} - -__attribute__((constructor)) void __main() { - - TracedFopenFileList = new std::unordered_map(); - -#if defined(__APPLE__) -#include -#if (TARGET_OS_IPHONE || TARGET_OS_MAC) - std::ifstream file; - file.open("/System/Library/CoreServices/SystemVersion.plist"); - std::cout << file.rdbuf(); -#endif -#endif - - // DobbyHook((void *)fopen, (void *)fake_fopen, (void **)&orig_fopen); - // DobbyHook((void *)fwrite, (void *)fake_fwrite, (void **)&orig_fwrite); - // DobbyHook((void *)fread, (void *)fake_fread, (void **)&orig_fread); - - char *home = getenv("HOME"); - char *subdir = (char *)"/Library/Caches/"; - - std::string filePath = std::string(home) + std::string(subdir) + "temp.log"; - - char buffer[64]; - memset(buffer, 'B', 64); - - FILE *fd = fopen(filePath.c_str(), "w+"); - if (!fd) - std::cout << "[!] open " << filePath << "failed!\n"; - - fwrite(buffer, 64, 1, fd); - fflush(fd); - fseek(fd, 0, SEEK_SET); - memset(buffer, 0, 64); - - fread(buffer, 64, 1, fd); - - return; -} diff --git a/app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/memory_operation_instrument.cc b/app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/memory_operation_instrument.cc deleted file mode 100644 index 0298275d..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/memory_operation_instrument.cc +++ /dev/null @@ -1,58 +0,0 @@ -#include "./dobby_monitor.h" - -#include -#include -#include - -static uintptr_t getCallFirstArg(DobbyRegisterContext *ctx) { - uintptr_t result; -#if defined(_M_X64) || defined(__x86_64__) -#if defined(_WIN32) - result = ctx->general.regs.rcx; -#else - result = ctx->general.regs.rdi; -#endif -#elif defined(__arm64__) || defined(__aarch64__) - result = ctx->general.regs.x0; -#elif defined(__arm__) - result = ctx->general.regs.r0; -#else -#error "Not Support Architecture." -#endif - return result; -} - -void format_integer_manually(char *buf, uint64_t integer) { - int tmp = 0; - for (tmp = (int)integer; tmp > 0; tmp = (tmp >> 4)) { - buf += (tmp % 16); - buf--; - } -} - -// [ATTENTION]: -// printf will call 'malloc' internally, and will crash in a loop. -// so, use 'puts' is a better choice. -void malloc_handler(DobbyRegisterContext *ctx, const InterceptEntry *info) { - size_t size_ = 0; - size_ = getCallFirstArg(ctx); - char *buffer_ = (char *)"[-] function malloc first arg: 0x00000000.\n"; - format_integer_manually(strchr(buffer_, '.') - 1, size_); - puts(buffer_); -} - -void free_handler(DobbyRegisterContext *ctx, const InterceptEntry *info) { - uintptr_t mem_ptr; - - mem_ptr = getCallFirstArg(ctx); - - char *buffer = (char *)"[-] function free first arg: 0x00000000.\n"; - format_integer_manually(strchr(buffer, '.') - 1, mem_ptr); - puts(buffer); -} - -__attribute__((constructor)) static void ctor() { - // DobbyInstrument((void *)mmap, malloc_handler); - // DobbyInstrument((void *)free, free_handler); - return; -} diff --git a/app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/posix_file_descriptor_operation_monitor.cc b/app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/posix_file_descriptor_operation_monitor.cc deleted file mode 100644 index 4c0db6c5..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/posix_file_descriptor_operation_monitor.cc +++ /dev/null @@ -1,120 +0,0 @@ -#include /* getenv */ -#include -#include - -#include -#include -#include - -#include - -#include -#include - -#include -#include - -#include - -#include "dobby.h" -#include "dobby/common.h" - -#define LOG_TAG "PosixFileOperationMonitor" - -std::unordered_map *posix_file_descriptors; - -int (*orig_open)(const char *pathname, int flags, ...); -int fake_open(const char *pathname, int flags, ...) { - mode_t mode = 0; - if (flags & O_CREAT) { - va_list args; - va_start(args, flags); - mode = (mode_t)va_arg(args, int); - va_end(args); - } - - int result = orig_open(pathname, flags, mode); - if (result != -1) { - char *traced_filename = (char *)malloc(MAXPATHLEN); - // FIXME: strncpy - strcpy(traced_filename, pathname); - INFO_LOG("[-] trace open handle: %s", pathname); - - if (posix_file_descriptors == NULL) { - posix_file_descriptors = new std::unordered_map(); - } - posix_file_descriptors->insert(std::make_pair(result, (const char *)traced_filename)); - } - return result; -} - -int (*orig___open)(const char *pathname, int flags, int mode); -int fake___open(const char *pathname, int flags, int mode) { - char *traced_filename = NULL; - if (pathname) { - traced_filename = (char *)malloc(MAXPATHLEN); - // FIXME: strncpy - strcpy(traced_filename, pathname); - INFO_LOG("[-] trace open handle: ", pathname); - } - int result = orig___open(pathname, flags, mode); - if (result != -1) { - if (posix_file_descriptors == NULL) { - posix_file_descriptors = new std::unordered_map(); - } - posix_file_descriptors->insert(std::make_pair(result, (const char *)traced_filename)); - } - return result; -} - -static const char *get_traced_filename(int fd, bool removed) { - if (posix_file_descriptors == NULL) - return NULL; - std::unordered_map::iterator it; - it = posix_file_descriptors->find(fd); - if (it != posix_file_descriptors->end()) { - if (removed) - posix_file_descriptors->erase(it); - return it->second; - } - return NULL; -} - -ssize_t (*orig_read)(int fd, void *buf, size_t count); -ssize_t fake_read(int fd, void *buf, size_t count) { - const char *traced_filename = get_traced_filename(fd, false); - if (traced_filename) { - INFO_LOG("[-] read: %s, buffer: %p, size: %zu", traced_filename, buf, count); - } - return orig_read(fd, buf, count); -} - -ssize_t (*orig_write)(int fd, const void *buf, size_t count); -ssize_t fake_write(int fd, const void *buf, size_t count) { - const char *traced_filename = get_traced_filename(fd, false); - if (traced_filename) { - INFO_LOG("[-] write: %s, buffer: %p, size: %zu", traced_filename, buf, count); - } - return orig_write(fd, buf, count); -} -int (*orig_close)(int fd); -int fake_close(int fd) { - const char *traced_filename = get_traced_filename(fd, true); - if (traced_filename) { - INFO_LOG("[-] close: %s", traced_filename); - free((void *)traced_filename); - } - return orig_close(fd); -} - -#if 0 -__attribute__((constructor)) static void ctor() { - DobbyHook((void *)DobbySymbolResolver(NULL, "open"), (void *)fake_open, (void **)&orig_open); - - DobbyHook((void *)DobbySymbolResolver(NULL, "write"), (void *)fake_write, (void **)&orig_write); - - DobbyHook((void *)DobbySymbolResolver(NULL, "read"), (void *)fake_read, (void **)&orig_read); - - DobbyHook((void *)DobbySymbolResolver(NULL, "close"), (void *)fake_close, (void **)&orig_close); -} -#endif diff --git a/app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/posix_socket_network_monitor.cc b/app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/posix_socket_network_monitor.cc deleted file mode 100644 index a6e6e6c2..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/posix_socket_network_monitor.cc +++ /dev/null @@ -1,57 +0,0 @@ -#include /* getenv */ -#include -#include - -#include -#include - -#include - -#include - -#include -#include - -std::unordered_map posix_socket_file_descriptors; - -int (*orig_bind)(int sockfd, const struct sockaddr *addr, socklen_t addrlen); -int fake_bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { -} - -static const char *get_traced_socket(int fd, bool removed) { - std::unordered_map::iterator it; - it = posix_socket_file_descriptors.find(fd); - if (it != posix_socket_file_descriptors.end()) { - if (removed) - posix_socket_file_descriptors.erase(it); - return it->second; - } - return NULL; -} - -int (*orig_connect)(int sockfd, const struct sockaddr *addr, socklen_t addrlen); -int fake_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) { - const char *traced_socket = get_traced_socket(sockfd, false); - if (traced_socket) { - INFO_LOG("[-] connect: %s\n", traced_socket); - } - return orig_connect(sockfd, addr, addrlen); -} - -ssize_t (*orig_send)(int sockfd, const void *buf, size_t len, int flags); -ssize_t fake_send(int sockfd, const void *buf, size_t len, int flags) { - const char *traced_socket = get_traced_socket(sockfd, false); - if (traced_socket) { - INFO_LOG("[-] send: %s, buf: %p, len: %zu\n", traced_socket, buf, len); - } - return orig_send(sockfd, buf, len, flags); -} - -ssize_t (*orig_recv)(int sockfd, void *buf, size_t len, int flags); -ssize_t fake_recv(int sockfd, void *buf, size_t len, int flags) { - const char *traced_socket = get_traced_socket(sockfd, false); - if (traced_socket) { - INFO_LOG("[-] recv: %s, buf: %p, len: %zu\n", traced_socket, buf, len); - } - return orig_recv(sockfd, buf, len, flags); -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/builtin-plugin/BionicLinkerUtil/bionic_linker_demo.cc b/app/src/main/cpp/Dobby/builtin-plugin/BionicLinkerUtil/bionic_linker_demo.cc deleted file mode 100644 index f68264c3..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/BionicLinkerUtil/bionic_linker_demo.cc +++ /dev/null @@ -1,36 +0,0 @@ -#include "dobby.h" - -#include "bionic_linker_util.h" - -#include "logging/logging.h" - -#include - -#define LOG_TAG "BionicLinkerUtil" - -__attribute__((constructor)) static void ctor() { - const char *lib = NULL; - -#if defined(__LP64__) - lib = "/system/lib64/libandroid_runtime.so"; -#else - lib = "/system/lib/libandroid_runtime.so"; -#endif - - void *vm = NULL; - - vm = DobbySymbolResolver(lib, "_ZN7android14AndroidRuntime7mJavaVME"); - INFO_LOG("DobbySymbolResolver::vm %p", vm); - -#if 0 - linker_disable_namespace_restriction(); - void *handle = NULL; - handle = dlopen(lib, RTLD_LAZY); - vm = dlsym(handle, "_ZN7android14AndroidRuntime7mJavaVME"); -#else - void *handle = NULL; - handle = linker_dlopen(lib, RTLD_LAZY); - vm = dlsym(handle, "_ZN7android14AndroidRuntime7mJavaVME"); -#endif - INFO_LOG("vm %p", vm); -} diff --git a/app/src/main/cpp/Dobby/builtin-plugin/BionicLinkerUtil/bionic_linker_util.cc b/app/src/main/cpp/Dobby/builtin-plugin/BionicLinkerUtil/bionic_linker_util.cc deleted file mode 100644 index f3c9f0b3..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/BionicLinkerUtil/bionic_linker_util.cc +++ /dev/null @@ -1,197 +0,0 @@ -#include "bionic_linker_util.h" - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include - -#include "dobby.h" -#include "dobby_symbol_resolver.h" - -#include "dobby/common.h" - -#undef LOG_TAG -#define LOG_TAG "BionicLinkerUtil" - -#undef Q -#define Q 29 -// impl at "dobby_symbol_resolver.cc" -extern void *resolve_elf_internal_symbol(const char *library_name, const char *symbol_name); - -#include -static int get_android_system_version() { - char os_version_str[PROP_VALUE_MAX + 1]; - __system_property_get("ro.build.version.sdk", os_version_str); - int os_version_int = atoi(os_version_str); - return os_version_int; -} - -static const char *get_android_linker_path() { -#if __LP64__ - if (get_android_system_version() >= Q) { - return (const char *)"/apex/com.android.runtime/bin/linker64"; - } else { - return (const char *)"/system/bin/linker64"; - } -#else - if (get_android_system_version() >= Q) { - return (const char *)"/apex/com.android.runtime/bin/linker"; - } else { - return (const char *)"/system/bin/linker"; - } -#endif -} - -PUBLIC void *linker_dlopen(const char *filename, int flag) { - typedef void *(*__loader_dlopen_t)(const char *filename, int flags, const void *caller_addr); - static __loader_dlopen_t __loader_dlopen = NULL; - if (!__loader_dlopen) - __loader_dlopen = (__loader_dlopen_t)DobbySymbolResolver(NULL, "__loader_dlopen"); - - // fake caller address - void *open_ptr = dlsym(RTLD_DEFAULT, "open"); - return __loader_dlopen(filename, flag, (const void *)open_ptr); -} - -std::vector linker_solist; -std::vector linker_get_solist() { - if (!linker_solist.empty()) { - linker_solist.clear(); - } - - static soinfo_t (*solist_get_head)() = NULL; - if (!solist_get_head) - solist_get_head = - (soinfo_t(*)())resolve_elf_internal_symbol(get_android_linker_path(), "__dl__Z15solist_get_headv"); - - static soinfo_t (*solist_get_somain)() = NULL; - if (!solist_get_somain) - solist_get_somain = - (soinfo_t(*)())resolve_elf_internal_symbol(get_android_linker_path(), "__dl__Z17solist_get_somainv"); - - static addr_t *solist_head = NULL; - if (!solist_head) - solist_head = (addr_t *)solist_get_head(); - - static addr_t somain = 0; - if (!somain) - somain = (addr_t)solist_get_somain(); - - // Generate the name for an offset. -#define PARAM_OFFSET(type_, member_) __##type_##__##member_##__offset_ -#define STRUCT_OFFSET PARAM_OFFSET - int STRUCT_OFFSET(solist, next) = 0; - for (size_t i = 0; i < 1024 / sizeof(void *); i++) { - if (*(addr_t *)((addr_t)solist_head + i * sizeof(void *)) == somain) { - STRUCT_OFFSET(solist, next) = i * sizeof(void *); - break; - } - } - - linker_solist.push_back(solist_head); - - addr_t sonext = 0; - sonext = *(addr_t *)((addr_t)solist_head + STRUCT_OFFSET(solist, next)); - while (sonext) { - linker_solist.push_back((void *)sonext); - sonext = *(addr_t *)((addr_t)sonext + STRUCT_OFFSET(solist, next)); - } - - return linker_solist; -} - -char *linker_soinfo_get_realpath(soinfo_t soinfo) { - static char *(*_get_realpath)(soinfo_t) = NULL; - if (!_get_realpath) - _get_realpath = - (char *(*)(soinfo_t))resolve_elf_internal_symbol(get_android_linker_path(), "__dl__ZNK6soinfo12get_realpathEv"); - return _get_realpath(soinfo); -} - -uintptr_t linker_soinfo_to_handle(soinfo_t soinfo) { - static uintptr_t (*_linker_soinfo_to_handle)(soinfo_t) = NULL; - if (!_linker_soinfo_to_handle) - _linker_soinfo_to_handle = - (uintptr_t(*)(soinfo_t))resolve_elf_internal_symbol(get_android_linker_path(), "__dl__ZN6soinfo9to_handleEv"); - return _linker_soinfo_to_handle(soinfo); -} - -typedef void *android_namespace_t; -android_namespace_t linker_soinfo_get_primary_namespace(soinfo_t soinfo) { - static android_namespace_t (*_get_primary_namespace)(soinfo_t) = NULL; - if (!_get_primary_namespace) - _get_primary_namespace = (android_namespace_t(*)(soinfo_t))resolve_elf_internal_symbol( - get_android_linker_path(), "__dl__ZN6soinfo21get_primary_namespaceEv"); - return _get_primary_namespace(soinfo); -} - -void linker_iterate_soinfo(int (*cb)(soinfo_t soinfo)) { - auto solist = linker_get_solist(); - for (auto it = solist.begin(); it != solist.end(); it++) { - int ret = cb(*it); - if (ret != 0) - break; - } -} - -static int iterate_soinfo_cb(soinfo_t soinfo) { - android_namespace_t ns = NULL; - ns = linker_soinfo_get_primary_namespace(soinfo); - INFO_LOG("lib: %s", linker_soinfo_get_realpath(soinfo)); - - // set is_isolated_ as false - // no need for this actually - int STRUCT_OFFSET(android_namespace_t, is_isolated_) = 0x8; - *(uint8_t *)((addr_t)ns + STRUCT_OFFSET(android_namespace_t, is_isolated_)) = false; - - std::vector ld_library_paths = {"/system/lib64", "/sytem/lib"}; - if (get_android_system_version() >= Q) { - ld_library_paths.push_back("/apex/com.android.runtime/lib64"); - ld_library_paths.push_back("/apex/com.android.runtime/lib"); - } - int STRUCT_OFFSET(android_namespace_t, ld_library_paths_) = 0x10; - if (*(void **)((addr_t)ns + STRUCT_OFFSET(android_namespace_t, ld_library_paths_))) { - std::vector orig_ld_library_paths = - *(std::vector *)((addr_t)ns + STRUCT_OFFSET(android_namespace_t, ld_library_paths_)); - orig_ld_library_paths.insert(orig_ld_library_paths.end(), ld_library_paths.begin(), ld_library_paths.end()); - - // remove duplicates - { - std::set paths(orig_ld_library_paths.begin(), orig_ld_library_paths.end()); - orig_ld_library_paths.assign(paths.begin(), paths.end()); - } - } else { - *(std::vector *)((addr_t)ns + STRUCT_OFFSET(android_namespace_t, ld_library_paths_)) = - std::move(ld_library_paths); - } - return 0; -} - -bool (*orig_linker_namespace_is_is_accessible)(android_namespace_t ns, const std::string &file); -bool linker_namespace_is_is_accessible(android_namespace_t ns, const std::string &file) { - INFO_LOG("check %s", file.c_str()); - return true; - return orig_linker_namespace_is_is_accessible(ns, file); -} - -void linker_disable_namespace_restriction() { - linker_iterate_soinfo(iterate_soinfo_cb); - - // no need for this actually - void *linker_namespace_is_is_accessible_ptr = resolve_elf_internal_symbol( - get_android_linker_path(), "__dl__ZN19android_namespace_t13is_accessibleERKNSt3__112basic_" - "stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE"); - DobbyHook(linker_namespace_is_is_accessible_ptr, (void *)linker_namespace_is_is_accessible, - (void **)&orig_linker_namespace_is_is_accessible); - - INFO_LOG("disable namespace restriction done"); -} diff --git a/app/src/main/cpp/Dobby/builtin-plugin/BionicLinkerUtil/bionic_linker_util.h b/app/src/main/cpp/Dobby/builtin-plugin/BionicLinkerUtil/bionic_linker_util.h deleted file mode 100644 index 55c29111..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/BionicLinkerUtil/bionic_linker_util.h +++ /dev/null @@ -1,23 +0,0 @@ -#pragma once - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -typedef void *soinfo_t; - -soinfo_t linker_dlopen(const char *filename, int flag); - -char *linker_soinfo_get_realpath(soinfo_t soinfo); - -uintptr_t linker_soinfo_to_handle(soinfo_t soinfo); - -void linker_iterate_soinfo(int (*cb)(soinfo_t soinfo)); - -void linker_disable_namespace_restriction(); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/builtin-plugin/CMakeLists.txt b/app/src/main/cpp/Dobby/builtin-plugin/CMakeLists.txt deleted file mode 100644 index 3730cb93..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/CMakeLists.txt +++ /dev/null @@ -1,15 +0,0 @@ -if (Plugin.ImportTableReplace AND SYSTEM.Darwin) - message(STATUS "[Dobby] Enable got hook") - include_directories(builtin-plugin/ImportTableReplace) - add_subdirectory(builtin-plugin/ImportTableReplace) -endif () - -if (Plugin.Android.BionicLinkerUtil) - if (NOT SYSTEM.Android) - message(FATAL_ERROR "[!] Plugin.Android.BionicLinkerUtil only works on Android.") - endif () - message(STATUS "[Dobby] Enable Plugin.Android.BionicLinkerUtil") - set(dobby.plugin.SOURCE_FILE_LIST ${dobby.plugin.SOURCE_FILE_LIST} - BionicLinkerUtil/bionic_linker_util.cc - ) -endif () \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/builtin-plugin/ImportTableReplace/CMakeLists.txt b/app/src/main/cpp/Dobby/builtin-plugin/ImportTableReplace/CMakeLists.txt deleted file mode 100644 index 1a2b4b3c..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/ImportTableReplace/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -add_library(dobby_import_replace INTERFACE - dobby_import_replace.cc - ) \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/builtin-plugin/ImportTableReplace/dobby_import_replace.cc b/app/src/main/cpp/Dobby/builtin-plugin/ImportTableReplace/dobby_import_replace.cc deleted file mode 100644 index eab1af93..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/ImportTableReplace/dobby_import_replace.cc +++ /dev/null @@ -1,192 +0,0 @@ -#include "dobby_import_replace.h" - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include - -#include - -#include "dobby/common.h" - -#include "logging/logging.h" - -#include "PlatformUtil/ProcessRuntimeUtility.h" - -#if defined(__LP64__) -typedef struct mach_header_64 mach_header_t; -typedef struct segment_command_64 segment_command_t; -typedef struct section_64 section_t; -typedef struct nlist_64 nlist_t; -#define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT_64 -#else -typedef struct mach_header mach_header_t; -typedef struct segment_command segment_command_t; -typedef struct section section_t; -typedef struct nlist nlist_t; -#define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT -#endif - -static void *iterate_indirect_symtab(char *symbol_name, section_t *section, intptr_t slide, nlist_t *symtab, - char *strtab, uint32_t *indirect_symtab) { - const bool is_data_const = strcmp(section->segname, "__DATA_CONST") == 0; - uint32_t *indirect_symbol_indices = indirect_symtab + section->reserved1; - void **indirect_symbol_bindings = (void **)((uintptr_t)slide + section->addr); - - vm_prot_t old_protection = VM_PROT_READ; - if (is_data_const) { - mprotect(indirect_symbol_bindings, section->size, PROT_READ | PROT_WRITE); - } - - for (uint i = 0; i < section->size / sizeof(void *); i++) { - uint32_t symtab_index = indirect_symbol_indices[i]; - if (symtab_index == INDIRECT_SYMBOL_ABS || symtab_index == INDIRECT_SYMBOL_LOCAL || - symtab_index == (INDIRECT_SYMBOL_LOCAL | INDIRECT_SYMBOL_ABS)) { - continue; - } - uint32_t strtab_offset = symtab[symtab_index].n_un.n_strx; - char *local_symbol_name = strtab + strtab_offset; - bool symbol_name_longer_than_1 = symbol_name[0] && symbol_name[1]; - if (strcmp(local_symbol_name, symbol_name) == 0) { - return &indirect_symbol_bindings[i]; - } - if (local_symbol_name[0] == '_') { - if (strcmp(symbol_name, &local_symbol_name[1]) == 0) { - return &indirect_symbol_bindings[i]; - } - } - } - - if (is_data_const && 0) { - int protection = 0; - if (old_protection & VM_PROT_READ) { - protection |= PROT_READ; - } - if (old_protection & VM_PROT_WRITE) { - protection |= PROT_WRITE; - } - if (old_protection & VM_PROT_EXECUTE) { - protection |= PROT_EXEC; - } - mprotect(indirect_symbol_bindings, section->size, protection); - } - return NULL; -} - -static void *get_global_offset_table_stub(mach_header_t *header, char *symbol_name) { - segment_command_t *curr_seg_cmd; - segment_command_t *text_segment, *data_segment, *linkedit_segment; - struct symtab_command *symtab_cmd = NULL; - struct dysymtab_command *dysymtab_cmd = NULL; - - uintptr_t cur = (uintptr_t)header + sizeof(mach_header_t); - for (uint i = 0; i < header->ncmds; i++, cur += curr_seg_cmd->cmdsize) { - curr_seg_cmd = (segment_command_t *)cur; - if (curr_seg_cmd->cmd == LC_SEGMENT_ARCH_DEPENDENT) { - if (strcmp(curr_seg_cmd->segname, "__LINKEDIT") == 0) { - linkedit_segment = curr_seg_cmd; - } else if (strcmp(curr_seg_cmd->segname, "__DATA") == 0) { - data_segment = curr_seg_cmd; - } else if (strcmp(curr_seg_cmd->segname, "__TEXT") == 0) { - text_segment = curr_seg_cmd; - } - } else if (curr_seg_cmd->cmd == LC_SYMTAB) { - symtab_cmd = (struct symtab_command *)curr_seg_cmd; - } else if (curr_seg_cmd->cmd == LC_DYSYMTAB) { - dysymtab_cmd = (struct dysymtab_command *)curr_seg_cmd; - } - } - - if (!symtab_cmd || !linkedit_segment || !linkedit_segment) { - return NULL; - } - - uintptr_t slide = (uintptr_t)header - (uintptr_t)text_segment->vmaddr; - uintptr_t linkedit_base = (uintptr_t)slide + linkedit_segment->vmaddr - linkedit_segment->fileoff; - nlist_t *symtab = (nlist_t *)(linkedit_base + symtab_cmd->symoff); - char *strtab = (char *)(linkedit_base + symtab_cmd->stroff); - uint32_t symtab_count = symtab_cmd->nsyms; - - uint32_t *indirect_symtab = (uint32_t *)(linkedit_base + dysymtab_cmd->indirectsymoff); - - cur = (uintptr_t)header + sizeof(mach_header_t); - for (uint i = 0; i < header->ncmds; i++, cur += curr_seg_cmd->cmdsize) { - curr_seg_cmd = (segment_command_t *)cur; - if (curr_seg_cmd->cmd == LC_SEGMENT_ARCH_DEPENDENT) { - if (strcmp(curr_seg_cmd->segname, "__DATA") != 0 && strcmp(curr_seg_cmd->segname, "__DATA_CONST") != 0) { - continue; - } - for (uint j = 0; j < curr_seg_cmd->nsects; j++) { - section_t *sect = (section_t *)(cur + sizeof(segment_command_t)) + j; - if ((sect->flags & SECTION_TYPE) == S_LAZY_SYMBOL_POINTERS) { - void *stub = iterate_indirect_symtab(symbol_name, sect, slide, symtab, strtab, indirect_symtab); - if (stub) - return stub; - } - if ((sect->flags & SECTION_TYPE) == S_NON_LAZY_SYMBOL_POINTERS) { - void *stub = iterate_indirect_symtab(symbol_name, sect, slide, symtab, strtab, indirect_symtab); - if (stub) - return stub; - } - } - } - } - - return NULL; -} - -PUBLIC int DobbyImportTableReplace(char *image_name, char *symbol_name, void *fake_func, void **orig_func_ptr) { - std::vector ProcessModuleMap = ProcessRuntimeUtility::GetProcessModuleMap(); - - for (auto module : ProcessModuleMap) { - if (image_name != NULL && strstr(module.path, image_name) == NULL) - continue; - - addr_t header = (addr_t)module.load_address; - size_t slide = 0; - -#if 0 - if (header) { - if (((struct mach_header *)header)->magic == MH_MAGIC_64) - slide = macho_kit_get_slide64(header); - } -#endif - -#if 0 - INFO_LOG("resolve image: %s", module.path); -#endif - - uint32_t nlist_count = 0; - nlist_t *nlist_array = 0; - char *string_pool = 0; - - void *stub = get_global_offset_table_stub((mach_header_t *)header, symbol_name); - if (stub) { - void *orig_func; - orig_func = *(void **)stub; -#if __has_feature(ptrauth_calls) - orig_func = ptrauth_strip(orig_func, ptrauth_key_asia); - orig_func = ptrauth_sign_unauthenticated(orig_func, ptrauth_key_asia, 0); -#endif - *orig_func_ptr = orig_func; - -#if __has_feature(ptrauth_calls) - fake_func = (void *)ptrauth_strip(fake_func, ptrauth_key_asia); - fake_func = ptrauth_sign_unauthenticated(fake_func, ptrauth_key_asia, stub); -#endif - *(void **)stub = fake_func; - } - - if (image_name) - return 0; - } - return -1; -} diff --git a/app/src/main/cpp/Dobby/builtin-plugin/ImportTableReplace/dobby_import_replace.h b/app/src/main/cpp/Dobby/builtin-plugin/ImportTableReplace/dobby_import_replace.h deleted file mode 100644 index c51b0f7e..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/ImportTableReplace/dobby_import_replace.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -// int DobbyImportTableReplace(char *image_name, char *symbol_name, void *fake_func, void **orig_func); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/builtin-plugin/ObjcRuntimeReplace/CMakeLists.txt b/app/src/main/cpp/Dobby/builtin-plugin/ObjcRuntimeReplace/CMakeLists.txt deleted file mode 100644 index 5430d9f0..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/ObjcRuntimeReplace/CMakeLists.txt +++ /dev/null @@ -1,7 +0,0 @@ -add_library(objc_runtime_replace - dobby_objc_runtime_replace.mm - ) - -target_link_libraries(objc_runtime_replace - "-framework Foundation" - ) \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/builtin-plugin/ObjcRuntimeReplace/dobby_objc_runtime_repalce.h b/app/src/main/cpp/Dobby/builtin-plugin/ObjcRuntimeReplace/dobby_objc_runtime_repalce.h deleted file mode 100644 index da959e74..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/ObjcRuntimeReplace/dobby_objc_runtime_repalce.h +++ /dev/null @@ -1,18 +0,0 @@ -#pragma once - -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -IMP DobbyObjcReplace(Class _class, SEL _selector, IMP replacement); - -void DobbyObjcReplaceEx(const char *class_name, const char *selector_name, void *fake_impl, void **orig_impl); - -void *DobbyObjcResolveMethodImp(const char *class_name, const char *selector_name); - -#ifdef __cplusplus -} -#endif diff --git a/app/src/main/cpp/Dobby/builtin-plugin/ObjcRuntimeReplace/dobby_objc_runtime_replace.mm b/app/src/main/cpp/Dobby/builtin-plugin/ObjcRuntimeReplace/dobby_objc_runtime_replace.mm deleted file mode 100644 index d7948800..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/ObjcRuntimeReplace/dobby_objc_runtime_replace.mm +++ /dev/null @@ -1,54 +0,0 @@ -#include "dobby_objc_runtime_repalce.h" - -#include -#include - -/* clang -rewrite-objc main.m */ - -IMP DobbyObjcReplace(Class class_, SEL sel_, IMP fake_impl) { - Method method_ = class_getInstanceMethod(class_, sel_); - if (!method_) - method_ = class_getClassMethod(class_, sel_); - - if (!method_) { - // DEBUG_LOG("Not found class: %s, selector: %s method\n", class_getName(class_), sel_getName(sel_)); - return NULL; - } - - return method_setImplementation(method_, (IMP)fake_impl); -} - -void DobbyObjcReplaceEx(const char *class_name, const char *selector_name, void *fake_impl, void **out_orig_impl) { - Class class_ = objc_getClass(class_name); - SEL sel_ = sel_registerName(selector_name); - - Method method_ = class_getInstanceMethod(class_, sel_); - if (!method_) { - method_ = class_getClassMethod(class_, sel_); - if (!method_) { - // ERROR_LOG("Not found class: %s, selector: %s method\n", class_name, selector_name); - return; - } - } - - auto orig_impl = (void *)method_setImplementation(method_, (IMP)fake_impl); - if (out_orig_impl) { - *out_orig_impl = orig_impl; - } - return; -} - -void *DobbyObjcResolveMethodImp(const char *class_name, const char *selector_name) { - Class class_ = objc_getClass(class_name); - SEL sel_ = sel_registerName(selector_name); - - Method method_ = class_getInstanceMethod(class_, sel_); - if (!method_) - method_ = class_getClassMethod(class_, sel_); - - if (!method_) { - // DEBUG_LOG("Not found class: %s, selector: %s method\n", class_name, selector_name); - return NULL; - } - return (void *)method_getImplementation(method_); -} diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/CMakeLists.txt b/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/CMakeLists.txt deleted file mode 100644 index ddddfd76..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/CMakeLists.txt +++ /dev/null @@ -1,23 +0,0 @@ -add_library(supervisor_call_monitor STATIC - mach_system_call_log_handler.cc - system_call_log_handler.cc - supervisor_call_monitor.cc - sensitive_api_monitor.cc - misc_utility.cc - ) -target_link_libraries(supervisor_call_monitor - misc_helper - dobby - ) - -add_library(test_supervisor_call_monitor SHARED - test_supervisor_call_monitor.cc - ) -target_link_libraries(test_supervisor_call_monitor - supervisor_call_monitor -) - -include_directories( - . -) - diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/README b/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/README deleted file mode 100644 index 3832eb51..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/README +++ /dev/null @@ -1 +0,0 @@ -Monitor all supervisor call \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/mach_system_call_log_handler.cc b/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/mach_system_call_log_handler.cc deleted file mode 100644 index 970a1bef..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/mach_system_call_log_handler.cc +++ /dev/null @@ -1,193 +0,0 @@ -#include "dobby/dobby_internal.h" - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "misc-helper/async_logger.h" -#include "PlatformUtil/ProcessRuntimeUtility.h" -#include "SupervisorCallMonitor/misc_utility.h" -#include "SupervisorCallMonitor/supervisor_call_monitor.h" - -#include "XnuInternal/syscall_sw.c" - -#include "XnuInternal/mach/clock_priv.h" -#include "XnuInternal/mach/clock_reply.h" -#include "XnuInternal/mach/clock.h" -#include "XnuInternal/mach/exc.h" -#include "XnuInternal/mach/host_priv.h" -#include "XnuInternal/mach/host_security.h" -#include "XnuInternal/mach/lock_set.h" -#include "XnuInternal/mach/mach_host.h" -#include "XnuInternal/mach/mach_port.h" -#include "XnuInternal/mach/mach_vm.h" -#include "XnuInternal/mach/mach_voucher.h" -#include "XnuInternal/mach/memory_entry.h" -#include "XnuInternal/mach/processor_set.h" -#include "XnuInternal/mach/processor.h" -#include "XnuInternal/mach/task.h" -#include "XnuInternal/mach/thread_act.h" -#include "XnuInternal/mach/vm_map.h" - -typedef struct { - char *mach_msg_name; - int mach_msg_id; -} mach_msg_entry_t; - -// clang-format off -mach_msg_entry_t mach_msg_array[] = { - subsystem_to_name_map_clock_priv, - subsystem_to_name_map_clock_reply, - subsystem_to_name_map_clock, - subsystem_to_name_map_exc, - subsystem_to_name_map_host_priv, - subsystem_to_name_map_host_security, - subsystem_to_name_map_lock_set, - subsystem_to_name_map_mach_host, - subsystem_to_name_map_mach_port, - subsystem_to_name_map_mach_vm, - subsystem_to_name_map_mach_voucher, - subsystem_to_name_map_memory_entry, - subsystem_to_name_map_processor_set, - subsystem_to_name_map_processor, - subsystem_to_name_map_task, - subsystem_to_name_map_thread_act, - subsystem_to_name_map_vm_map, -}; -// clang-format on - -#define PRIME_NUMBER 8387 -char *mach_msg_name_table[PRIME_NUMBER] = {0}; -static int hash_mach_msg_num_to_ndx(int mach_msg_num) { - return mach_msg_num % PRIME_NUMBER; -} -static void mach_msg_id_hash_table_init() { - static bool initialized = false; - if (initialized == true) { - return; - } - initialized = true; - - int count = sizeof(mach_msg_array) / sizeof(mach_msg_array[0]); - for (size_t i = 0; i < count; i++) { - mach_msg_entry_t entry = mach_msg_array[i]; - int ndx = hash_mach_msg_num_to_ndx(entry.mach_msg_id); - mach_msg_name_table[ndx] = entry.mach_msg_name; - } -} - -const char *mach_syscall_num_to_str(int num) { - return mach_syscall_name_table[0 - num]; -} - -char *mach_msg_id_to_str(int msgh_id) { - int ndx = hash_mach_msg_num_to_ndx(msgh_id); - return mach_msg_name_table[ndx]; -} - -char *mach_msg_to_str(mach_msg_header_t *msg) { - static mach_port_t self_port = MACH_PORT_NULL; - - if (self_port == MACH_PORT_NULL) { - self_port = mach_task_self(); - } - - if (msg->msgh_remote_port == self_port) { - return mach_msg_id_to_str(msg->msgh_id); - } - return NULL; -} - -static addr_t getCallFirstArg(DobbyRegisterContext *ctx) { - addr_t result; -#if defined(_M_X64) || defined(__x86_64__) -#if defined(_WIN32) - result = ctx->general.regs.rcx; -#else - result = ctx->general.regs.rdi; -#endif -#elif defined(__arm64__) || defined(__aarch64__) - result = ctx->general.regs.x0; -#elif defined(__arm__) - result = ctx->general.regs.r0; -#else -#error "Not Support Architecture." -#endif - return result; -} - -static addr_t getRealLr(DobbyRegisterContext *ctx) { - addr_t closure_trampoline_reserved_stack = ctx->sp - sizeof(addr_t); - return *(addr_t *)closure_trampoline_reserved_stack; -} - -static addr_t fast_get_caller_from_main_binary(DobbyRegisterContext *ctx) { - static addr_t text_section_start = 0, text_section_end = 0; - static addr_t slide = 0; - if (text_section_start == 0 || text_section_end == 0) { - auto main = ProcessRuntimeUtility::GetProcessModule("mobilex"); - addr_t main_header = (addr_t)main.load_address; - - auto text_segment = macho_kit_get_segment_by_name((mach_header_t *)main_header, "__TEXT"); - slide = main_header - text_segment->vmaddr; - - auto text_section = macho_kit_get_section_by_name((mach_header_t *)main_header, "__TEXT", "__text"); - text_section_start = main_header + (addr_t)text_section->offset; - text_section_end = text_section_start + text_section->size; - } - - if (ctx == NULL) - return 0; - - addr_t lr = getRealLr(ctx); - if (lr > text_section_start && lr < text_section_end) - return lr - slide; - -#define MAX_STACK_ITERATE_LEVEL 8 - addr_t fp = ctx->fp; - if (fp == 0) - return 0; - for (int i = 0; i < MAX_STACK_ITERATE_LEVEL; i++) { - addr_t lr = *(addr_t *)(fp + sizeof(addr_t)); - if (lr > text_section_start && lr < text_section_end) - return lr - slide; - fp = *(addr_t *)fp; - if (fp == 0) - return 0; - } - return 0; -} - -static void mach_syscall_log_handler(DobbyRegisterContext *ctx, const InterceptEntry *info) { - addr_t caller = fast_get_caller_from_main_binary(ctx); - if (caller == 0) - return; - - char buffer[256] = {0}; - int syscall_rum = ctx->general.regs.x16; - if (syscall_rum == -31) { - // mach_msg_trap - mach_msg_header_t *msg = (typeof(msg))getCallFirstArg(ctx); - char *mach_msg_name = mach_msg_to_str(msg); - if (mach_msg_name) { - sprintf(buffer, "[mach msg svc] %s\n", mach_msg_name); - } else { - buffer[0] = 0; - } - } else if (syscall_rum < 0) { - sprintf(buffer, "[mach svc-%d] %s\n", syscall_rum, mach_syscall_num_to_str(syscall_rum)); - } - async_logger_print(buffer); -} - -void supervisor_call_monitor_register_mach_syscall_call_log_handler() { - mach_msg_id_hash_table_init(); - fast_get_caller_from_main_binary(NULL); - supervisor_call_monitor_register_handler(mach_syscall_log_handler); -} diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/misc_utility.cc b/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/misc_utility.cc deleted file mode 100644 index 2a0a05bc..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/misc_utility.cc +++ /dev/null @@ -1,44 +0,0 @@ -#include "misc_utility.h" - -#include - -segment_command_t *macho_kit_get_segment_by_name(mach_header_t *header, const char *segname) { - segment_command_t *curr_seg_cmd = NULL; - - curr_seg_cmd = (segment_command_t *)((addr_t)header + sizeof(mach_header_t)); - for (int i = 0; i < header->ncmds; i++) { - if (curr_seg_cmd->cmd == LC_SEGMENT_ARCH_DEPENDENT) { - if (!strncmp(curr_seg_cmd->segname, segname, sizeof(curr_seg_cmd->segname))) { - break; - } - } - curr_seg_cmd = (segment_command_t *)((addr_t)curr_seg_cmd + curr_seg_cmd->cmdsize); - } - - return curr_seg_cmd; -} - -section_t *macho_kit_get_section_by_name(mach_header_t *header, const char *segname, const char *sectname) { - section_t *section = NULL; - segment_command_t *segment = NULL; - - int i = 0; - - segment = macho_kit_get_segment_by_name(header, segname); - if (!segment) - goto finish; - - section = (section_t *)((addr_t)segment + sizeof(segment_command_t)); - for (i = 0; i < segment->nsects; ++i) { - if (!strncmp(section->sectname, sectname, sizeof(section->sectname))) { - break; - } - section += 1; - } - if (i == segment->nsects) { - section = NULL; - } - -finish: - return section; -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/misc_utility.h b/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/misc_utility.h deleted file mode 100644 index 1c356c03..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/misc_utility.h +++ /dev/null @@ -1,28 +0,0 @@ -#pragma once - -#include -typedef uintptr_t addr_t; - -#include -#include -#include - -#if defined(__LP64__) -typedef struct mach_header_64 mach_header_t; -typedef struct segment_command_64 segment_command_t; -typedef struct section_64 section_t; -typedef struct nlist_64 nlist_t; -#define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT_64 -#else -typedef struct mach_header mach_header_t; -typedef struct segment_command segment_command_t; -typedef struct section section_t; -typedef struct nlist nlist_t; -#define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT -#endif - -// get macho segment by segment name -segment_command_t *macho_kit_get_segment_by_name(mach_header_t *mach_header, const char *segname); - -// get macho section by segment name and section name -section_t *macho_kit_get_section_by_name(mach_header_t *mach_header, const char *segname, const char *sectname); diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/sensitive_api_monitor.cc b/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/sensitive_api_monitor.cc deleted file mode 100644 index 6ab0765b..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/sensitive_api_monitor.cc +++ /dev/null @@ -1,95 +0,0 @@ -#include "dobby/dobby_internal.h" - -#include -#include -#include - -#include "SupervisorCallMonitor/supervisor_call_monitor.h" -#include "misc-helper/async_logger.h" - -#define PT_DENY_ATTACH 31 - -static void sensitive_api_handler(DobbyRegisterContext *ctx, const InterceptEntry *info) { - char buffer[256] = {0}; - int syscall_rum = ctx->general.regs.x16; - if (syscall_rum == 0) { - syscall_rum = (int)ctx->general.x[0]; - if (syscall_rum == SYS_ptrace) { - int request = ctx->general.x[1]; - if (request == PT_DENY_ATTACH) { - ctx->general.x[1] = 0; - // INFO_LOG("syscall svc ptrace deny"); - } - } - if (syscall_rum == SYS_exit) { - // INFO_LOG("syscall svc exit"); - } - } else if (syscall_rum > 0) { - if (syscall_rum == SYS_ptrace) { - int request = ctx->general.x[0]; - if (request == PT_DENY_ATTACH) { - ctx->general.x[0] = 0; - // INFO_LOG("svc ptrace deny"); - } - } - if (syscall_rum == SYS_exit) { - // INFO_LOG("svc exit"); - } - } - async_logger_print(buffer); -} - -static int get_func_svc_offset(addr_t func_addr) { - typedef int32_t arm64_instr_t; - for (int i = 0; i < 8; i++) { - arm64_instr_t *insn = (arm64_instr_t *)func_addr + i; - if (*insn == 0xd4001001) { - return i * sizeof(arm64_instr_t); - } - } - return 0; -} - -#include -__typeof(sysctl) *orig_sysctl; -int fake_sysctl(int *name, u_int namelen, void *oldp, size_t *oldlenp, void *newp, size_t newlen) { - struct kinfo_proc *info = NULL; - int ret = orig_sysctl(name, namelen, oldp, oldlenp, newp, newlen); - if (name[0] == CTL_KERN && name[1] == KERN_PROC && name[2] == KERN_PROC_PID) { - info = (struct kinfo_proc *)oldp; - info->kp_proc.p_flag &= ~(P_TRACED); - } - return ret; -} - -void supervisor_call_monitor_register_sensitive_api_handler() { - char *sensitive_func_array[] = {"ptrace", "exit"}; - size_t count = sizeof(sensitive_func_array) / sizeof(char *); - for (size_t i = 0; i < count; i++) { - - addr_t func_addr = 0; - - char func_name[64] = {0}; - sprintf(func_name, "__%s", sensitive_func_array[i]); - func_addr = (addr_t)DobbySymbolResolver("libsystem_kernel.dylib", func_name); - if (func_addr == 0) { - func_addr = (addr_t)DobbySymbolResolver("libsystem_kernel.dylib", sensitive_func_array[i]); - } - if (func_addr == 0) { - INFO_LOG("not found func %s", sensitive_func_array[i]); - continue; - } - int func_svc_offset = get_func_svc_offset(func_addr); - if (func_svc_offset == 0) { - INFO_LOG("not found svc %s", sensitive_func_array[i]); - continue; - } - addr_t func_svc_addr = func_addr + func_svc_offset; - supervisor_call_monitor_register_svc(func_svc_addr); - } - - // =============== - DobbyHook((void *)sysctl, (void *)fake_sysctl, (void **)&orig_sysctl); - - supervisor_call_monitor_register_handler(sensitive_api_handler); -} diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/supervisor_call_monitor.cc b/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/supervisor_call_monitor.cc deleted file mode 100644 index c97b111d..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/supervisor_call_monitor.cc +++ /dev/null @@ -1,138 +0,0 @@ -#include "SupervisorCallMonitor/misc_utility.h" -#include "dobby/dobby_internal.h" -#include "PlatformUtil/ProcessRuntimeUtility.h" - -#include "misc-helper/async_logger.h" - -#include -std::vector *g_supervisor_call_handlers; - -static const char *fast_get_main_app_bundle_udid() { - static char *main_app_bundle_udid = NULL; - if (main_app_bundle_udid) - return main_app_bundle_udid; - - auto main = ProcessRuntimeUtility::GetProcessModuleMap()[0]; - char main_binary_path[2048] = {0}; - if (realpath(main.path, main_binary_path) == NULL) - return NULL; - - char *bundle_udid_ndx = main_binary_path + strlen("/private/var/containers/Bundle/Application/"); - main_app_bundle_udid = (char *)malloc(36 + 1); - strncpy(main_app_bundle_udid, bundle_udid_ndx, 36); - main_app_bundle_udid[36] = 0; - return main_app_bundle_udid; -} - -static void common_supervisor_call_monitor_handler(DobbyRegisterContext *ctx, const InterceptEntry *info) { - if (g_supervisor_call_handlers == NULL) { - return; - } - for (auto handler : *g_supervisor_call_handlers) { - handler(ctx, info); - } -} - -void supervisor_call_monitor_register_handler(DBICallTy handler) { - if (g_supervisor_call_handlers == NULL) { - g_supervisor_call_handlers = new std::vector(); - } - g_supervisor_call_handlers->push_back(handler); -} - -std::vector *g_svc_addr_array; - -void supervisor_call_monitor_register_svc(addr_t svc_addr) { - if (g_svc_addr_array == NULL) { - g_svc_addr_array = new std::vector(); - } - - if (g_svc_addr_array) { - auto iter = g_svc_addr_array->begin(); - for (; iter != g_svc_addr_array->end(); iter++) { - if (*iter == svc_addr) - return; - } - } - - g_svc_addr_array->push_back(svc_addr); - DobbyInstrument((void *)svc_addr, common_supervisor_call_monitor_handler); - DLOG(2, "register supervisor_call_monitor at %p", svc_addr); -} - -void supervisor_call_monitor_register_image(void *header) { - auto text_section = macho_kit_get_section_by_name((mach_header_t *)header, "__TEXT", "__text"); - - addr_t insn_addr = (addr_t)header + (addr_t)text_section->offset; - addr_t insn_addr_end = insn_addr + text_section->size; - - for (; insn_addr < insn_addr_end; insn_addr += sizeof(uint32_t)) { - if (*(uint32_t *)insn_addr == 0xd4001001) { - supervisor_call_monitor_register_svc((addr_t)insn_addr); - } - } -} - -void supervisor_call_monitor_register_main_app() { - const char *main_bundle_udid = fast_get_main_app_bundle_udid(); - auto module_map = ProcessRuntimeUtility::GetProcessModuleMap(); - for (auto module : module_map) { - if (strstr(module.path, main_bundle_udid)) { - INFO_LOG("[supervisor_call_monitor] %s", module.path); - supervisor_call_monitor_register_image((void *)module.load_address); - } - } -} - -extern "C" int __shared_region_check_np(uint64_t *startaddress); - -struct dyld_cache_header *shared_cache_get_load_addr() { - static struct dyld_cache_header *shared_cache_load_addr = 0; - if (shared_cache_load_addr) - return shared_cache_load_addr; -#if 0 - if (syscall(294, &shared_cache_load_addr) == 0) { -#else - // FIXME: - if (__shared_region_check_np((uint64_t *)&shared_cache_load_addr) != 0) { -#endif - shared_cache_load_addr = 0; -} -return shared_cache_load_addr; -} -void supervisor_call_monitor_register_system_kernel() { - auto libsystem = ProcessRuntimeUtility::GetProcessModule("libsystem_kernel.dylib"); - addr_t libsystem_header = (addr_t)libsystem.load_address; - auto text_section = macho_kit_get_section_by_name((mach_header_t *)libsystem_header, "__TEXT", "__text"); - - addr_t shared_cache_load_addr = (addr_t)shared_cache_get_load_addr(); - addr_t insn_addr = shared_cache_load_addr + (addr_t)text_section->offset; - addr_t insn_addr_end = insn_addr + text_section->size; - - addr_t write_svc_addr = (addr_t)DobbySymbolResolver("libsystem_kernel.dylib", "write"); - write_svc_addr += 4; - - addr_t __psynch_mutexwait_svc_addr = (addr_t)DobbySymbolResolver("libsystem_kernel.dylib", "__psynch_mutexwait"); - __psynch_mutexwait_svc_addr += 4; - - for (; insn_addr < insn_addr_end; insn_addr += sizeof(uint32_t)) { - if (*(uint32_t *)insn_addr == 0xd4001001) { - if (insn_addr == write_svc_addr) - continue; - - if (insn_addr == __psynch_mutexwait_svc_addr) - continue; - supervisor_call_monitor_register_svc((addr_t)insn_addr); - } - } -} - -void supervisor_call_monitor_init() { - // create logger file - char logger_path[1024] = {0}; - sprintf(logger_path, "%s%s", getenv("HOME"), "/Documents/svc_monitor.txt"); - INFO_LOG("HOME: %s", logger_path); - async_logger_init(logger_path); - - dobby_enable_near_branch_trampoline(); -} diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/supervisor_call_monitor.h b/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/supervisor_call_monitor.h deleted file mode 100644 index 45bde0a4..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/supervisor_call_monitor.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once - -#include -typedef uintptr_t addr_t; - -#include "dobby.h" - -void supervisor_call_monitor_init(); - -void supervisor_call_monitor_register_handler(DBICallTy handler); - -void supervisor_call_monitor_register_svc(addr_t svc_addr); - -void supervisor_call_monitor_register_image(void *header); - -void supervisor_call_monitor_register_main_app(); - -void supervisor_call_monitor_register_system_kernel(); - -void supervisor_call_monitor_register_syscall_call_log_handler(); - -void supervisor_call_monitor_register_mach_syscall_call_log_handler(); - -void supervisor_call_monitor_register_sensitive_api_handler(); \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/system_call_log_handler.cc b/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/system_call_log_handler.cc deleted file mode 100644 index d1ca0137..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/system_call_log_handler.cc +++ /dev/null @@ -1,98 +0,0 @@ -#include "dobby/dobby_internal.h" - -#include - -#include "misc-helper/async_logger.h" -#include "PlatformUtil/ProcessRuntimeUtility.h" -#include "SupervisorCallMonitor/misc_utility.h" -#include "SupervisorCallMonitor/supervisor_call_monitor.h" - -#include "XnuInternal/syscalls.c" - -static const char *syscall_num_to_str(int num) { - return syscallnames[num]; -} - -static addr_t getCallFirstArg(DobbyRegisterContext *ctx) { - addr_t result; -#if defined(_M_X64) || defined(__x86_64__) -#if defined(_WIN32) - result = ctx->general.regs.rcx; -#else - result = ctx->general.regs.rdi; -#endif -#elif defined(__arm64__) || defined(__aarch64__) - result = ctx->general.regs.x0; -#elif defined(__arm__) - result = ctx->general.regs.r0; -#else -#error "Not Support Architecture." -#endif - return result; -} - -static addr_t getRealLr(DobbyRegisterContext *ctx) { - addr_t closure_trampoline_reserved_stack = ctx->sp - sizeof(addr_t); - return *(addr_t *)closure_trampoline_reserved_stack; -} - -static addr_t fast_get_caller_from_main_binary(DobbyRegisterContext *ctx) { - static addr_t text_section_start = 0, text_section_end = 0; - static addr_t slide = 0; - if (text_section_start == 0 || text_section_end == 0) { - auto main = ProcessRuntimeUtility::GetProcessModule(""); - addr_t main_header = (addr_t)main.load_address; - - auto text_segment = macho_kit_get_segment_by_name((mach_header_t *)main_header, "__TEXT"); - slide = main_header - text_segment->vmaddr; - - auto text_section = macho_kit_get_section_by_name((mach_header_t *)main_header, "__TEXT", "__text"); - text_section_start = main_header + (addr_t)text_section->offset; - text_section_end = text_section_start + text_section->size; - } - - if (ctx == NULL) - return 0; - - addr_t lr = getRealLr(ctx); - if (lr > text_section_start && lr < text_section_end) - return lr - slide; - -#define MAX_STACK_ITERATE_LEVEL 8 - addr_t fp = ctx->fp; - if (fp == 0) - return 0; - for (int i = 0; i < MAX_STACK_ITERATE_LEVEL; i++) { - addr_t lr = *(addr_t *)(fp + sizeof(addr_t)); - if (lr > text_section_start && lr < text_section_end) - return lr - slide; - fp = *(addr_t *)fp; - if (fp == 0) - return 0; - } - return 0; -} - -static void syscall_log_handler(DobbyRegisterContext *ctx, const InterceptEntry *info) { - addr_t caller = fast_get_caller_from_main_binary(ctx); - if (caller == 0) - return; - - char buffer[2048] = {0}; - int syscall_rum = ctx->general.regs.x16; - if (syscall_rum == 0) { - syscall_rum = (int)getCallFirstArg(ctx); - sprintf(buffer, "[syscall svc-%d] %s\n", syscall_rum, syscall_num_to_str(syscall_rum)); - } else if (syscall_rum > 0) { - sprintf(buffer, "[svc-%d] %s\n", syscall_rum, syscall_num_to_str(syscall_rum)); - if (syscall_rum == 5) { - sprintf(buffer, "[svc-%d] %s:%s\n", syscall_rum, syscall_num_to_str(syscall_rum), (char *)ctx->general.regs.x0); - } - } - async_logger_print(buffer); -} - -void supervisor_call_monitor_register_syscall_call_log_handler() { - fast_get_caller_from_main_binary(NULL); - supervisor_call_monitor_register_handler(syscall_log_handler); -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/test_supervisor_call_monitor.cc b/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/test_supervisor_call_monitor.cc deleted file mode 100644 index 394a8c83..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/test_supervisor_call_monitor.cc +++ /dev/null @@ -1,16 +0,0 @@ - -#include "dobby/dobby_internal.h" - -#include "SupervisorCallMonitor/supervisor_call_monitor.h" - -#if 1 -__attribute__((constructor)) static void ctor() { - log_set_level(2); - log_switch_to_syslog(); - - supervisor_call_monitor_init(); - supervisor_call_monitor_register_main_app(); - supervisor_call_monitor_register_syscall_call_log_handler(); - supervisor_call_monitor_register_mach_syscall_call_log_handler(); -} -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/CMakeLists.txt b/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/CMakeLists.txt deleted file mode 100644 index 65285920..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/CMakeLists.txt +++ /dev/null @@ -1,55 +0,0 @@ -set(SOURCE_FILE_LIST) - -include_directories( - . -) - -if (NOT DEFINED DOBBY_DIR) - message(FATAL_ERROR "DOBBY_DIR must be set!") -endif () - -if (SYSTEM.Darwin) - add_library(macho_ctx_kit - ${CMAKE_CURRENT_SOURCE_DIR}/macho/macho_ctx.h - ${CMAKE_CURRENT_SOURCE_DIR}/macho/macho_ctx.cc - ) - - add_library(shared_cache_ctx_kit - ${CMAKE_CURRENT_SOURCE_DIR}/macho/shared_cache_ctx.h - ${CMAKE_CURRENT_SOURCE_DIR}/macho/shared_cache_ctx.cpp - ) - - set(SOURCE_FILE_LIST ${SOURCE_FILE_LIST} - macho/macho_ctx.cc - macho/dobby_symbol_resolver.cc - ) - - if (NOT DOBBY_BUILD_KERNEL_MODE) - set(SOURCE_FILE_LIST ${SOURCE_FILE_LIST} - macho/macho_file_symbol_resolver.cpp - macho/shared_cache_ctx.cpp - ${DOBBY_DIR}/source/Backend/UserMode/PlatformUtil/Darwin/ProcessRuntimeUtility.cc - ) - endif () -elseif (SYSTEM.Linux OR SYSTEM.Android) - set(SOURCE_FILE_LIST ${SOURCE_FILE_LIST} - elf/dobby_symbol_resolver.cc - - ${DOBBY_DIR}/source/Backend/UserMode/PlatformUtil/Linux/ProcessRuntimeUtility.cc - ) -elseif (SYSTEM.Windows) - set(SOURCE_FILE_LIST ${SOURCE_FILE_LIST} - pe/dobby_symbol_resolver.cc - - ${DOBBY_DIR}/source/Backend/UserMode/PlatformUtil/Windows/ProcessRuntimeUtility.cc - ) -endif () - -get_absolute_path_list(SOURCE_FILE_LIST SOURCE_FILE_LIST_) -set(SOURCE_FILE_LIST ${SOURCE_FILE_LIST_}) - -add_library(dobby_symbol_resolver - ${SOURCE_FILE_LIST} - ) - - diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/dobby_symbol_resolver.h b/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/dobby_symbol_resolver.h deleted file mode 100644 index 22dee3ce..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/dobby_symbol_resolver.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#if defined(BUILDING_INTERNAL) -#include "macho/dobby_symbol_resolver_priv.h" -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -void *DobbySymbolResolver(const char *image_name, const char *symbol_name); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/elf/dobby_symbol_resolver.cc b/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/elf/dobby_symbol_resolver.cc deleted file mode 100644 index bf45ea94..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/elf/dobby_symbol_resolver.cc +++ /dev/null @@ -1,238 +0,0 @@ -#include "SymbolResolver/dobby_symbol_resolver.h" -#include "dobby/common.h" - -#include -#include -#include -#include - -#include "mmap_file_util.h" - -#include "PlatformUtil/ProcessRuntimeUtility.h" - -#include - -#undef LOG_TAG -#define LOG_TAG "DobbySymbolResolver" - -typedef struct elf_ctx { - void *header; - - uintptr_t load_bias; - - ElfW(Shdr) * sym_sh_; - ElfW(Shdr) * dynsym_sh_; - - const char *strtab_; - ElfW(Sym) * symtab_; - - const char *dynstrtab_; - ElfW(Sym) * dynsymtab_; - - size_t nbucket_; - size_t nchain_; - uint32_t *bucket_; - uint32_t *chain_; - - size_t gnu_nbucket_; - uint32_t *gnu_bucket_; - uint32_t *gnu_chain_; - uint32_t gnu_maskwords_; - uint32_t gnu_shift2_; - ElfW(Addr) * gnu_bloom_filter_; -} elf_ctx_t; - -static void get_syms(ElfW(Ehdr) * header, ElfW(Sym) * *symtab_ptr, char **strtab_ptr, int *count_ptr) { - ElfW(Shdr) *section_header = NULL; - section_header = (ElfW(Shdr) *)((addr_t)header + header->e_shoff); - - ElfW(Shdr) *section_strtab_section_header = NULL; - section_strtab_section_header = (ElfW(Shdr) *)((addr_t)section_header + header->e_shstrndx * header->e_shentsize); - char *section_strtab = NULL; - section_strtab = (char *)((addr_t)header + section_strtab_section_header->sh_offset); - - for (int i = 0; i < header->e_shnum; ++i) { - const char *section_name = (const char *)(section_strtab + section_header->sh_name); - if (section_header->sh_type == SHT_SYMTAB && strcmp(section_name, ".symtab") == 0) { - *symtab_ptr = (ElfW(Sym) *)((addr_t)header + section_header->sh_offset); - *count_ptr = section_header->sh_size / sizeof(ElfW(Sym)); - } - - if (section_header->sh_type == SHT_STRTAB && strcmp(section_name, ".strtab") == 0) { - *strtab_ptr = (char *)((addr_t)header + section_header->sh_offset); - } - section_header = (ElfW(Shdr) *)((addr_t)section_header + header->e_shentsize); - } -} - -int elf_ctx_init(elf_ctx_t *ctx, void *header_) { - ElfW(Ehdr) *ehdr = (ElfW(Ehdr) *)header_; - ctx->header = ehdr; - - ElfW(Addr) ehdr_addr = (ElfW(Addr))ehdr; - - // Handle dynamic segment - { - ElfW(Addr) addr = 0; - ElfW(Dyn) *dyn = NULL; - ElfW(Phdr) *phdr = reinterpret_cast(ehdr_addr + ehdr->e_phoff); - for (size_t i = 0; i < ehdr->e_phnum; i++) { - if (phdr[i].p_type == PT_DYNAMIC) { - dyn = reinterpret_cast(ehdr_addr + phdr[i].p_offset); - } else if (phdr[i].p_type == PT_LOAD) { - addr = ehdr_addr + phdr[i].p_offset - phdr[i].p_vaddr; - if (ctx->load_bias == 0) - ctx->load_bias = ehdr_addr - (phdr[i].p_vaddr - phdr[i].p_offset); - } else if (phdr[i].p_type == PT_PHDR) { - ctx->load_bias = (ElfW(Addr))phdr - phdr[i].p_vaddr; - } - } -// ctx->load_bias = -#if 0 - const char *strtab = nullptr; - ElfW(Sym) *symtab = nullptr; - for (ElfW(Dyn) *d = dyn; d->d_tag != DT_NULL; ++d) { - if (d->d_tag == DT_STRTAB) { - strtab = reinterpret_cast(addr + d->d_un.d_ptr); - } else if (d->d_tag == DT_SYMTAB) { - symtab = reinterpret_cast(addr + d->d_un.d_ptr); - } - } -#endif - } - - // Handle section - { - ElfW(Shdr) * dynsym_sh, *dynstr_sh; - ElfW(Shdr) * sym_sh, *str_sh; - - ElfW(Shdr) *shdr = reinterpret_cast(ehdr_addr + ehdr->e_shoff); - - ElfW(Shdr) *shstr_sh = NULL; - shstr_sh = &shdr[ehdr->e_shstrndx]; - char *shstrtab = NULL; - shstrtab = (char *)((addr_t)ehdr_addr + shstr_sh->sh_offset); - - for (size_t i = 0; i < ehdr->e_shnum; i++) { - if (shdr[i].sh_type == SHT_SYMTAB) { - sym_sh = &shdr[i]; - ctx->sym_sh_ = sym_sh; - ctx->symtab_ = (ElfW(Sym) *)(ehdr_addr + shdr[i].sh_offset); - } else if (shdr[i].sh_type == SHT_STRTAB && strcmp(shstrtab + shdr[i].sh_name, ".strtab") == 0) { - str_sh = &shdr[i]; - ctx->strtab_ = (const char *)(ehdr_addr + shdr[i].sh_offset); - } else if (shdr[i].sh_type == SHT_DYNSYM) { - dynsym_sh = &shdr[i]; - ctx->dynsym_sh_ = dynsym_sh; - ctx->dynsymtab_ = (ElfW(Sym) *)(ehdr_addr + shdr[i].sh_offset); - } else if (shdr[i].sh_type == SHT_STRTAB && strcmp(shstrtab + shdr[i].sh_name, ".dynstr") == 0) { - dynstr_sh = &shdr[i]; - ctx->dynstrtab_ = (const char *)(ehdr_addr + shdr[i].sh_offset); - } - } - } - - return 0; -} - -static void *iterate_symbol_table_impl(const char *symbol_name, ElfW(Sym) * symtab, const char *strtab, int count) { - for (int i = 0; i < count; ++i) { - ElfW(Sym) *sym = symtab + i; - const char *symbol_name_ = strtab + sym->st_name; - if (strcmp(symbol_name_, symbol_name) == 0) { - return (void *)sym->st_value; - } - } - return NULL; -} - -void *elf_ctx_iterate_symbol_table(elf_ctx_t *ctx, const char *symbol_name) { - void *result = NULL; - if (ctx->symtab_ && ctx->strtab_) { - size_t count = ctx->sym_sh_->sh_size / sizeof(ElfW(Sym)); - result = iterate_symbol_table_impl(symbol_name, ctx->symtab_, ctx->strtab_, count); - if (result) - return result; - } - - if (ctx->dynsymtab_ && ctx->dynstrtab_) { - size_t count = ctx->dynsym_sh_->sh_size / sizeof(ElfW(Sym)); - result = iterate_symbol_table_impl(symbol_name, ctx->dynsymtab_, ctx->dynstrtab_, count); - if (result) - return result; - } - return NULL; -} - -void *resolve_elf_internal_symbol(const char *library_name, const char *symbol_name) { - void *result = NULL; - - if (library_name) { - RuntimeModule module = ProcessRuntimeUtility::GetProcessModule(library_name); - - if (module.load_address) { - auto mmapFileMng = MmapFileManager(module.path); - auto file_mem = mmapFileMng.map(); - - elf_ctx_t ctx; - memset(&ctx, 0, sizeof(elf_ctx_t)); - if (file_mem) { - elf_ctx_init(&ctx, file_mem); - result = elf_ctx_iterate_symbol_table(&ctx, symbol_name); - } - - if (result) - result = (void *)((addr_t)result + (addr_t)module.load_address - ((addr_t)file_mem - (addr_t)ctx.load_bias)); - } - } - - if (!result) { - auto ProcessModuleMap = ProcessRuntimeUtility::GetProcessModuleMap(); - for (auto module : ProcessModuleMap) { - - if (module.load_address) { - auto mmapFileMng = MmapFileManager(module.path); - auto file_mem = mmapFileMng.map(); - - elf_ctx_t ctx; - memset(&ctx, 0, sizeof(elf_ctx_t)); - if (file_mem) { - elf_ctx_init(&ctx, file_mem); - result = elf_ctx_iterate_symbol_table(&ctx, symbol_name); - } - - if (result) - result = (void *)((addr_t)result + (addr_t)module.load_address - ((addr_t)file_mem - (addr_t)ctx.load_bias)); - } - - if (result) - break; - } - } - return result; -} - -// impl at "android_restriction.cc" -extern std::vector linker_get_solist(); - -PUBLIC void *DobbySymbolResolver(const char *image_name, const char *symbol_name_pattern) { - void *result = NULL; - -#if 0 - auto solist = linker_get_solist(); - for (auto soinfo : solist) { - uintptr_t handle = linker_soinfo_to_handle(soinfo); - if (image_name == NULL || strstr(linker_soinfo_get_realpath(soinfo), image_name) != 0) { - result = dlsym((void *)handle, symbol_name_pattern); - if (result) - return result; - } - } -#endif - result = dlsym(RTLD_DEFAULT, symbol_name_pattern); - if (result) - return result; - - result = resolve_elf_internal_symbol(image_name, symbol_name_pattern); - return result; -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/dobby_symbol_resolver.cc b/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/dobby_symbol_resolver.cc deleted file mode 100644 index bd5c9933..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/dobby_symbol_resolver.cc +++ /dev/null @@ -1,114 +0,0 @@ -#include "dobby_symbol_resolver.h" -#include "macho/dobby_symbol_resolver_priv.h" -#include "macho_file_symbol_resolver.h" - -#include "dobby/common.h" - -#include -#include - -#include "PlatformUtil/ProcessRuntimeUtility.h" - -#include "macho_ctx.h" -#include "shared_cache_ctx.h" - -#if !defined(BUILDING_KERNEL) -#include -#include -#endif - -#undef LOG_TAG -#define LOG_TAG "DobbySymbolResolver" - -PUBLIC void *DobbySymbolResolver(const char *image_name, const char *symbol_name_pattern) { - uintptr_t result = 0; - auto modules = ProcessRuntimeUtility::GetProcessModuleMap(); - - for (auto iter = modules.begin(); iter != modules.end(); iter++) { - auto module = *iter; - - // image filter - if (image_name && !strstr(module.path, image_name)) - continue; - - // dyld in shared cached at new os version - // ignore dyld, as some functions as own implementation in dyld - if (!image_name && strstr(module.path, "dyld")) - continue; - - auto header = (mach_header_t *)module.load_address; - if (header == nullptr) - continue; - -#if 0 - DEBUG_LOG("resolve image: %s", module.path); -#endif - - nlist_t *symtab = NULL; - uint32_t symtab_count = 0; - char *strtab = NULL; - -#if !defined(BUILDING_KERNEL) -#if defined(__arm__) || defined(__aarch64__) - static int shared_cache_ctx_init_once = 0; - static shared_cache_ctx_t shared_cache_ctx; - if (shared_cache_ctx_init_once == 0) { - shared_cache_ctx_init_once = 1; - shared_cache_ctx_init(&shared_cache_ctx); - shared_cache_load_symbols(&shared_cache_ctx); - } - if (shared_cache_ctx.mmap_shared_cache) { - // shared cache library - if (shared_cache_is_contain(&shared_cache_ctx, (addr_t)header, 0)) { - shared_cache_get_symbol_table(&shared_cache_ctx, header, &symtab, &symtab_count, &strtab); - } - } - if (symtab && strtab) { - result = macho_iterate_symbol_table((char *)symbol_name_pattern, symtab, symtab_count, strtab); - } - if (result) { - result = result + shared_cache_ctx.runtime_slide; - return (void *)result; - } -#endif -#endif - - macho_ctx_t macho_ctx(header); - result = macho_ctx.symbol_resolve(symbol_name_pattern); - if (result) { - return (void *)result; - } - } - -#if !defined(BUILDING_KERNEL) - mach_header_t *dyld_header = NULL; - if (image_name != NULL && strcmp(image_name, "dyld") == 0) { - // task info - task_dyld_info_data_t task_dyld_info; - mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT; - if (task_info(mach_task_self(), TASK_DYLD_INFO, (task_info_t)&task_dyld_info, &count)) { - return NULL; - } - - // get dyld load address - const struct dyld_all_image_infos *infos = - (struct dyld_all_image_infos *)(uintptr_t)task_dyld_info.all_image_info_addr; - dyld_header = (mach_header_t *)infos->dyldImageLoadAddress; - macho_ctx_t dyld_ctx(dyld_header); - result = dyld_ctx.symbol_resolve(symbol_name_pattern); - - bool is_dyld_in_cache = ((mach_header_t *)dyld_header)->flags & MH_DYLIB_IN_CACHE; - if (!is_dyld_in_cache && result == 0) { - result = macho_file_symbol_resolve(dyld_header->cputype, dyld_header->cpusubtype, "/usr/lib/dyld", - (char *)symbol_name_pattern); - result += (uintptr_t)dyld_header; - } - } -#endif - - if (result == 0) { - DEBUG_LOG("symbol resolver failed: %s", symbol_name_pattern); - } - - return (void *)result; -} diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/dobby_symbol_resolver_priv.h b/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/dobby_symbol_resolver_priv.h deleted file mode 100644 index c6b42442..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/dobby_symbol_resolver_priv.h +++ /dev/null @@ -1,6 +0,0 @@ -#include -#include -#include - -#include "macho_ctx.h" - diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/macho_ctx.cc b/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/macho_ctx.cc deleted file mode 100644 index 92188ead..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/macho_ctx.cc +++ /dev/null @@ -1,358 +0,0 @@ -#include "macho_ctx.h" - -#include -#include -#include -#include -#include - -#define ASSERT(x) - -uintptr_t macho_iterate_symbol_table(char *symbol_name_pattern, nlist_t *symtab, uint32_t symtab_count, char *strtab) { - for (uint32_t i = 0; i < symtab_count; i++) { - if (symtab[i].n_value) { - uint32_t strtab_offset = symtab[i].n_un.n_strx; - char *symbol_name = strtab + strtab_offset; -#if 0 - printf("> %s", symbol_name); -#endif - if (strcmp(symbol_name_pattern, symbol_name) == 0) { - return symtab[i].n_value; - } - if (symbol_name[0] == '_') { - if (strcmp(symbol_name_pattern, &symbol_name[1]) == 0) { - return symtab[i].n_value; - } - } - } - } - return 0; -} - -// --- - -void macho_ctx_t::init(mach_header_t *header, bool is_runtime_mode) { - memset(this, 0, sizeof(macho_ctx_t)); - - this->is_runtime_mode = is_runtime_mode; - - this->header = header; - segment_command_t *curr_seg_cmd; - segment_command_t *text_segment = 0, *text_exec_segment = 0, *data_segment = 0, *data_const_segment = 0, - *linkedit_segment = 0; - struct symtab_command *symtab_cmd = 0; - struct dysymtab_command *dysymtab_cmd = 0; - struct dyld_info_command *dyld_info_cmd = 0; - struct linkedit_data_command *exports_trie_cmd = 0; - struct linkedit_data_command *chained_fixups_cmd = NULL; - - curr_seg_cmd = (segment_command_t *)((uintptr_t)header + sizeof(mach_header_t)); - for (int i = 0; i < header->ncmds; i++) { - if (curr_seg_cmd->cmd == LC_SEGMENT_ARCH_DEPENDENT) { - // BIND_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB and REBASE_OPCODE_SET_SEGMENT_AND_OFFSET_ULEB - this->segments[this->segments_count++] = curr_seg_cmd; - - if (strcmp(curr_seg_cmd->segname, "__LINKEDIT") == 0) { - linkedit_segment = curr_seg_cmd; - } else if (strcmp(curr_seg_cmd->segname, "__DATA") == 0) { - data_segment = curr_seg_cmd; - } else if (strcmp(curr_seg_cmd->segname, "__DATA_CONST") == 0) { - data_const_segment = curr_seg_cmd; - } else if (strcmp(curr_seg_cmd->segname, "__TEXT") == 0) { - text_segment = curr_seg_cmd; - } else if (strcmp(curr_seg_cmd->segname, "__TEXT_EXEC") == 0) { - text_exec_segment = curr_seg_cmd; - } - } else if (curr_seg_cmd->cmd == LC_SYMTAB) { - symtab_cmd = (struct symtab_command *)curr_seg_cmd; - } else if (curr_seg_cmd->cmd == LC_DYSYMTAB) { - dysymtab_cmd = (struct dysymtab_command *)curr_seg_cmd; - } else if (curr_seg_cmd->cmd == LC_DYLD_INFO || curr_seg_cmd->cmd == LC_DYLD_INFO_ONLY) { - dyld_info_cmd = (struct dyld_info_command *)curr_seg_cmd; - } else if (curr_seg_cmd->cmd == LC_DYLD_EXPORTS_TRIE) { - exports_trie_cmd = (struct linkedit_data_command *)curr_seg_cmd; - } else if (curr_seg_cmd->cmd == LC_DYLD_CHAINED_FIXUPS) { - chained_fixups_cmd = (struct linkedit_data_command *)curr_seg_cmd; - } - curr_seg_cmd = (segment_command_t *)((uintptr_t)curr_seg_cmd + curr_seg_cmd->cmdsize); - } - - uintptr_t slide = (uintptr_t)header - (uintptr_t)text_segment->vmaddr; - uintptr_t linkedit_base = (uintptr_t)slide + linkedit_segment->vmaddr - linkedit_segment->fileoff; - if (!is_runtime_mode) { - // as mmap, all segment is close - uintptr_t linkedit_segment_vmaddr = linkedit_segment->fileoff; - linkedit_base = (uintptr_t)slide + linkedit_segment_vmaddr - linkedit_segment->fileoff; - } - - vm_region_start = segments[0]->vmaddr; - // skip __LINKEDIT - if (strcmp(segments[0]->segname, "__LINKEDIT") == 0) { - vm_region_start = segments[1]->vmaddr; - } - vm_region_end = segments[segments_count - 1]->vmaddr + segments[segments_count - 1]->vmsize; - vmaddr = vm_region_start; - vmsize = vm_region_end - vm_region_start; - - this->text_seg = text_segment; - this->text_exec_seg = text_exec_segment; - this->data_seg = data_segment; - this->data_const_seg = data_const_segment; - this->linkedit_seg = linkedit_segment; - - this->symtab_cmd = symtab_cmd; - this->dysymtab_cmd = dysymtab_cmd; - this->dyld_info_cmd = dyld_info_cmd; - this->exports_trie_cmd = exports_trie_cmd; - this->chained_fixups_cmd = chained_fixups_cmd; - - this->slide = slide; - this->linkedit_base = linkedit_base; - - this->symtab = (nlist_t *)(this->linkedit_base + this->symtab_cmd->symoff); - this->strtab = (char *)(this->linkedit_base + this->symtab_cmd->stroff); - this->indirect_symtab = (uint32_t *)(this->linkedit_base + this->dysymtab_cmd->indirectsymoff); -} - -uintptr_t macho_ctx_t::iterate_symbol_table(const char *symbol_name_pattern) { - nlist_t *symtab = this->symtab; - uint32_t symtab_count = this->symtab_cmd->nsyms; - char *strtab = this->strtab; - - for (uint32_t i = 0; i < symtab_count; i++) { - if (symtab[i].n_value) { - uint32_t strtab_offset = symtab[i].n_un.n_strx; - char *symbol_name = strtab + strtab_offset; -#if 0 - printf("> %s", symbol_name); -#endif - if (strcmp(symbol_name_pattern, symbol_name) == 0) { - return symtab[i].n_value; - } - if (symbol_name[0] == '_') { - if (strcmp(symbol_name_pattern, &symbol_name[1]) == 0) { - return symtab[i].n_value; - } - } - } - } - return 0; -} - -uintptr_t read_uleb128(const uint8_t **pp, const uint8_t *end) { - uint8_t *p = (uint8_t *)*pp; - uint64_t result = 0; - int bit = 0; - do { - if (p == end) - ASSERT(p == end); - - uint64_t slice = *p & 0x7f; - - if (bit > 63) - ASSERT(bit > 63); - else { - result |= (slice << bit); - bit += 7; - } - } while (*p++ & 0x80); - - *pp = p; - - return (uintptr_t)result; -} - -intptr_t read_sleb128(const uint8_t **pp, const uint8_t *end) { - uint8_t *p = (uint8_t *)*pp; - - int64_t result = 0; - int bit = 0; - uint8_t byte; - do { - if (p == end) - ASSERT(p == end); - byte = *p++; - result |= (((int64_t)(byte & 0x7f)) << bit); - bit += 7; - } while (byte & 0x80); - // sign extend negative numbers - if ((byte & 0x40) != 0) - result |= (~0ULL) << bit; - - *pp = p; - - return (intptr_t)result; -} - -// dyld -// bool MachOLoaded::findExportedSymbol -// MachOLoaded::trieWalk -uint8_t *tail_walk(const uint8_t *start, const uint8_t *end, const char *symbol) { - uint32_t visitedNodeOffsets[128]; - int visitedNodeOffsetCount = 0; - visitedNodeOffsets[visitedNodeOffsetCount++] = 0; - const uint8_t *p = start; - while (p < end) { - uint64_t terminalSize = *p++; - if (terminalSize > 127) { - // except for re-export-with-rename, all terminal sizes fit in one byte - --p; - terminalSize = read_uleb128(&p, end); - } - if ((*symbol == '\0') && (terminalSize != 0)) { - return (uint8_t *)p; - } - const uint8_t *children = p + terminalSize; - if (children > end) { - // diag.error("malformed trie node, terminalSize=0x%llX extends past end of trie\n", terminalSize); - return NULL; - } - uint8_t childrenRemaining = *children++; - p = children; - uint64_t nodeOffset = 0; - - for (; childrenRemaining > 0; --childrenRemaining) { - const char *ss = symbol; - bool wrongEdge = false; - // scan whole edge to get to next edge - // if edge is longer than target symbol name, don't read past end of symbol name - char c = *p; - while (c != '\0') { - if (!wrongEdge) { - if (c != *ss) - wrongEdge = true; - ++ss; - } - ++p; - c = *p; - } - if (wrongEdge) { - // advance to next child - ++p; // skip over zero terminator - // skip over uleb128 until last byte is found - while ((*p & 0x80) != 0) - ++p; - ++p; // skip over last byte of uleb128 - if (p > end) { - // diag.error("malformed trie node, child node extends past end of trie\n"); - return nullptr; - } - } else { - // the symbol so far matches this edge (child) - // so advance to the child's node - ++p; - nodeOffset = read_uleb128(&p, end); - if ((nodeOffset == 0) || (&start[nodeOffset] > end)) { - // diag.error("malformed trie child, nodeOffset=0x%llX out of range\n", nodeOffset); - return nullptr; - } - symbol = ss; - break; - } - } - - if (nodeOffset != 0) { - if (nodeOffset > (uint64_t)(end - start)) { - // diag.error("malformed trie child, nodeOffset=0x%llX out of range\n", nodeOffset); - return NULL; - } - for (int i = 0; i < visitedNodeOffsetCount; ++i) { - if (visitedNodeOffsets[i] == nodeOffset) { - // diag.error("malformed trie child, cycle to nodeOffset=0x%llX\n", nodeOffset); - return NULL; - } - } - visitedNodeOffsets[visitedNodeOffsetCount++] = (uint32_t)nodeOffset; - p = &start[nodeOffset]; - } else - p = end; - } - return NULL; -} - -uintptr_t macho_ctx_t::iterate_exported_symbol(const char *symbol_name, uint64_t *out_flags) { - if (this->text_seg == NULL || this->linkedit_seg == NULL) { - return 0; - } - - struct dyld_info_command *dyld_info_cmd = this->dyld_info_cmd; - struct linkedit_data_command *exports_trie_cmd = this->exports_trie_cmd; - if (exports_trie_cmd == NULL && dyld_info_cmd == NULL) - return 0; - - uint32_t trieFileOffset = dyld_info_cmd ? dyld_info_cmd->export_off : exports_trie_cmd->dataoff; - uint32_t trieFileSize = dyld_info_cmd ? dyld_info_cmd->export_size : exports_trie_cmd->datasize; - - void *exports = (void *)(this->linkedit_base + trieFileOffset); - if (exports == NULL) - return 0; - - uint8_t *exports_start = (uint8_t *)exports; - uint8_t *exports_end = exports_start + trieFileSize; - uint8_t *node = (uint8_t *)tail_walk(exports_start, exports_end, symbol_name); - if (node == NULL) - return 0; - const uint8_t *p = node; - const uintptr_t flags = read_uleb128(&p, exports_end); - if (out_flags) - *out_flags = flags; - if (flags & EXPORT_SYMBOL_FLAGS_REEXPORT) { - const uint64_t ordinal = read_uleb128(&p, exports_end); - const char *importedName = (const char *)p; - if (importedName[0] == '\0') { - importedName = symbol_name; - return 0; - } - // trick - // printf("reexported symbol: %s\n", importedName); - return (uintptr_t)importedName; - } - uint64_t trieValue = read_uleb128(&p, exports_end); - return trieValue; -#if 0 - if (off == (void *)0) { - if (symbol_name[0] != '_' && strlen(&symbol_name[1]) >= 1) { - char _symbol_name[1024] = {0}; - _symbol_name[0] = '_'; - strcpy(&_symbol_name[1], symbol_name); - off = (void *)walk_exported_trie((const uint8_t *)exports, (const uint8_t *)exports + trieFileSize, _symbol_name); - } - } -#endif -} - -uintptr_t macho_ctx_t::symbol_resolve_options(const char *symbol_name_pattern, resolve_symbol_type_t type) { - if (type & RESOLVE_SYMBOL_TYPE_SYMBOL_TABLE) { - uintptr_t result = iterate_symbol_table(symbol_name_pattern); - if (result) { - result = result + (this->is_runtime_mode ? this->slide : 0); - return result; - } - } - - if (type & RESOLVE_SYMBOL_TYPE_EXPORTED) { - // binary exported table(uleb128) - uint64_t flags; - uintptr_t result = iterate_exported_symbol(symbol_name_pattern, &flags); - if (result) { - switch (flags & EXPORT_SYMBOL_FLAGS_KIND_MASK) { - case EXPORT_SYMBOL_FLAGS_KIND_REGULAR: { - result += (uintptr_t)this->header; - } break; - case EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL: { - result += (uintptr_t)this->header; - } break; - case EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE: { - } break; - default: - break; - } - return result; - } - } - return 0; -} - -uintptr_t macho_ctx_t::symbol_resolve(const char *symbol_name_pattern) { - return symbol_resolve_options(symbol_name_pattern, RESOLVE_SYMBOL_TYPE_ALL); -} diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/macho_ctx.h b/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/macho_ctx.h deleted file mode 100644 index 82f41cd9..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/macho_ctx.h +++ /dev/null @@ -1,86 +0,0 @@ -#pragma once - -#include -#include -#include - -#if defined(__LP64__) -typedef struct mach_header_64 mach_header_t; -typedef struct segment_command_64 segment_command_t; -typedef struct section_64 section_t; -typedef struct nlist_64 nlist_t; -#define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT_64 -#else -typedef struct mach_header mach_header_t; -typedef struct segment_command segment_command_t; -typedef struct section section_t; -typedef struct nlist nlist_t; -#define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT -#endif - -intptr_t read_sleb128(const uint8_t **pp, const uint8_t *end); - -uintptr_t read_uleb128(const uint8_t **pp, const uint8_t *end); - -typedef enum { - RESOLVE_SYMBOL_TYPE_SYMBOL_TABLE = 1 << 0, - RESOLVE_SYMBOL_TYPE_EXPORTED = 1 << 1, - RESOLVE_SYMBOL_TYPE_ALL = RESOLVE_SYMBOL_TYPE_SYMBOL_TABLE | RESOLVE_SYMBOL_TYPE_EXPORTED -} resolve_symbol_type_t; - -struct macho_ctx_t { - bool is_runtime_mode; - - mach_header_t *header; - - uintptr_t vmaddr; - size_t vmsize; - uintptr_t vm_region_start; - uintptr_t vm_region_end; - - uintptr_t slide; - uintptr_t linkedit_base; - - segment_command_t *segments[64]; - int segments_count; - - segment_command_t *text_seg; - segment_command_t *data_seg; - segment_command_t *text_exec_seg; - segment_command_t *data_const_seg; - segment_command_t *linkedit_seg; - - struct symtab_command *symtab_cmd; - struct dysymtab_command *dysymtab_cmd; - struct dyld_info_command *dyld_info_cmd; - struct linkedit_data_command *exports_trie_cmd; - struct linkedit_data_command *chained_fixups_cmd; - - nlist_t *symtab; - char *strtab; - uint32_t *indirect_symtab; - - explicit macho_ctx_t(mach_header_t *header, bool is_runtime_mode = true) { - init(header, is_runtime_mode); - } - - void init(mach_header_t *header, bool is_runtime_mode); - - uintptr_t iterate_symbol_table(const char *symbol_name_pattern); - - uintptr_t iterate_exported_symbol(const char *symbol_name, uint64_t *out_flags); - - uintptr_t symbol_resolve_options(const char *symbol_name_pattern, resolve_symbol_type_t type); - - uintptr_t symbol_resolve(const char *symbol_name_pattern); -}; - -#ifdef __cplusplus -extern "C" { -#endif - -uintptr_t macho_iterate_symbol_table(char *name_pattern, nlist_t *symtab, uint32_t symtab_count, char *strtab); - -#ifdef __cplusplus -} -#endif diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/macho_file_symbol_resolver.cpp b/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/macho_file_symbol_resolver.cpp deleted file mode 100644 index 541afd23..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/macho_file_symbol_resolver.cpp +++ /dev/null @@ -1,68 +0,0 @@ -#include "macho_file_symbol_resolver.h" - -#include "SymbolResolver/mmap_file_util.h" - -#include -#include -#include - -uintptr_t macho_file_memory_symbol_resolve(cpu_type_t in_cputype, cpu_subtype_t in_cpusubtype, const uint8_t *file_mem, - char *symbol_name_pattern) { - - mach_header_t *header = (mach_header_t *)file_mem; - struct fat_header *fh = (struct fat_header *)file_mem; - if (fh->magic == OSSwapBigToHostInt32(FAT_MAGIC)) { - const struct fat_arch *archs = (struct fat_arch *)(((uintptr_t)fh) + sizeof(fat_header)); - mach_header_t *header_arm64 = NULL; - mach_header_t *header_arm64e = NULL; - mach_header_t *header_x64 = NULL; - for (size_t i = 0; i < OSSwapBigToHostInt32(fh->nfat_arch); i++) { - uint64_t offset; - uint64_t len; - cpu_type_t cputype = (cpu_type_t)OSSwapBigToHostInt32(archs[i].cputype); - cpu_subtype_t cpusubtype = (cpu_subtype_t)OSSwapBigToHostInt32(archs[i].cpusubtype); - offset = OSSwapBigToHostInt32(archs[i].offset); - len = OSSwapBigToHostInt32(archs[i].size); - if (cputype == CPU_TYPE_X86_64) { - header_x64 = (mach_header_t *)&file_mem[offset]; - } else if (cputype == CPU_TYPE_ARM64 && (cpusubtype & ~CPU_SUBTYPE_MASK) == CPU_SUBTYPE_ARM64E) { - header_arm64e = (mach_header_t *)&file_mem[offset]; - } else if (cputype == CPU_TYPE_ARM64) { - header_arm64 = (mach_header_t *)&file_mem[offset]; - } - - if ((cputype == in_cputype) && ((cpusubtype & in_cpusubtype) == in_cpusubtype)) { - header = (mach_header_t *)&file_mem[offset]; - break; - } - } - - if (header == (mach_header_t *)file_mem) { - if (in_cputype == 0 && in_cpusubtype == 0) { -#if defined(__arm64__) || defined(__aarch64__) - header = header_arm64e ? header_arm64e : header_arm64; -#else - header = header_x64; -#endif - } - } - } - - macho_ctx_t ctx(header, false); - return ctx.symbol_resolve_options(symbol_name_pattern, RESOLVE_SYMBOL_TYPE_SYMBOL_TABLE); -} - -uintptr_t macho_file_symbol_resolve(cpu_type_t cpu, cpu_subtype_t subtype, const char *file, - char *symbol_name_pattern) { - -#if defined(COMPILE_WITH_NO_STDLIB) - return 0; -#endif - MmapFileManager mng(file); - auto mmap_buffer = mng.map(); - if (!mmap_buffer) { - return 0; - } - - return macho_file_memory_symbol_resolve(cpu, subtype, mmap_buffer, symbol_name_pattern); -} diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/macho_file_symbol_resolver.h b/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/macho_file_symbol_resolver.h deleted file mode 100644 index 81700c98..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/macho_file_symbol_resolver.h +++ /dev/null @@ -1,8 +0,0 @@ -#pragma once - -#include "macho_ctx.h" - -uintptr_t macho_file_memory_symbol_resolve(cpu_type_t cpu, cpu_subtype_t subtype, const uint8_t *file_mem, - char *symbol_name_pattern); - -uintptr_t macho_file_symbol_resolve(cpu_type_t cpu, cpu_subtype_t subtype, const char *file, char *symbol_name_pattern); diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/shared-cache/dyld_cache_format.h b/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/shared-cache/dyld_cache_format.h deleted file mode 100644 index 92092930..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/shared-cache/dyld_cache_format.h +++ /dev/null @@ -1,560 +0,0 @@ -/* -*- mode: C++; c-basic-offset: 4; tab-width: 4 -*- - * - * Copyright (c) 2006-2015 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ -#ifndef __DYLD_CACHE_FORMAT__ -#define __DYLD_CACHE_FORMAT__ - -#include -#include -#include - - -struct dyld_cache_header -{ - char magic[16]; // e.g. "dyld_v0 i386" - uint32_t mappingOffset; // file offset to first dyld_cache_mapping_info - uint32_t mappingCount; // number of dyld_cache_mapping_info entries - uint32_t imagesOffsetOld; // UNUSED: moved to imagesOffset to prevent older dsc_extarctors from crashing - uint32_t imagesCountOld; // UNUSED: moved to imagesCount to prevent older dsc_extarctors from crashing - uint64_t dyldBaseAddress; // base address of dyld when cache was built - uint64_t codeSignatureOffset; // file offset of code signature blob - uint64_t codeSignatureSize; // size of code signature blob (zero means to end of file) - uint64_t slideInfoOffsetUnused; // unused. Used to be file offset of kernel slid info - uint64_t slideInfoSizeUnused; // unused. Used to be size of kernel slid info - uint64_t localSymbolsOffset; // file offset of where local symbols are stored - uint64_t localSymbolsSize; // size of local symbols information - uint8_t uuid[16]; // unique value for each shared cache file - uint64_t cacheType; // 0 for development, 1 for production, 2 for multi-cache - uint32_t branchPoolsOffset; // file offset to table of uint64_t pool addresses - uint32_t branchPoolsCount; // number of uint64_t entries - uint64_t dyldInCacheMH; // (unslid) address of mach_header of dyld in cache - uint64_t dyldInCacheEntry; // (unslid) address of entry point (_dyld_start) of dyld in cache - uint64_t imagesTextOffset; // file offset to first dyld_cache_image_text_info - uint64_t imagesTextCount; // number of dyld_cache_image_text_info entries - uint64_t patchInfoAddr; // (unslid) address of dyld_cache_patch_info - uint64_t patchInfoSize; // Size of all of the patch information pointed to via the dyld_cache_patch_info - uint64_t otherImageGroupAddrUnused; // unused - uint64_t otherImageGroupSizeUnused; // unused - uint64_t progClosuresAddr; // (unslid) address of list of program launch closures - uint64_t progClosuresSize; // size of list of program launch closures - uint64_t progClosuresTrieAddr; // (unslid) address of trie of indexes into program launch closures - uint64_t progClosuresTrieSize; // size of trie of indexes into program launch closures - uint32_t platform; // platform number (macOS=1, etc) - uint32_t formatVersion : 8, // dyld3::closure::kFormatVersion - dylibsExpectedOnDisk : 1, // dyld should expect the dylib exists on disk and to compare inode/mtime to see if cache is valid - simulator : 1, // for simulator of specified platform - locallyBuiltCache : 1, // 0 for B&I built cache, 1 for locally built cache - builtFromChainedFixups : 1, // some dylib in cache was built using chained fixups, so patch tables must be used for overrides - padding : 20; // TBD - uint64_t sharedRegionStart; // base load address of cache if not slid - uint64_t sharedRegionSize; // overall size required to map the cache and all subCaches, if any - uint64_t maxSlide; // runtime slide of cache can be between zero and this value - uint64_t dylibsImageArrayAddr; // (unslid) address of ImageArray for dylibs in this cache - uint64_t dylibsImageArraySize; // size of ImageArray for dylibs in this cache - uint64_t dylibsTrieAddr; // (unslid) address of trie of indexes of all cached dylibs - uint64_t dylibsTrieSize; // size of trie of cached dylib paths - uint64_t otherImageArrayAddr; // (unslid) address of ImageArray for dylibs and bundles with dlopen closures - uint64_t otherImageArraySize; // size of ImageArray for dylibs and bundles with dlopen closures - uint64_t otherTrieAddr; // (unslid) address of trie of indexes of all dylibs and bundles with dlopen closures - uint64_t otherTrieSize; // size of trie of dylibs and bundles with dlopen closures - uint32_t mappingWithSlideOffset; // file offset to first dyld_cache_mapping_and_slide_info - uint32_t mappingWithSlideCount; // number of dyld_cache_mapping_and_slide_info entries - uint64_t dylibsPBLStateArrayAddrUnused; // unused - uint64_t dylibsPBLSetAddr; // (unslid) address of PrebuiltLoaderSet of all cached dylibs - uint64_t programsPBLSetPoolAddr; // (unslid) address of pool of PrebuiltLoaderSet for each program - uint64_t programsPBLSetPoolSize; // size of pool of PrebuiltLoaderSet for each program - uint64_t programTrieAddr; // (unslid) address of trie mapping program path to PrebuiltLoaderSet - uint32_t programTrieSize; - uint32_t osVersion; // OS Version of dylibs in this cache for the main platform - uint32_t altPlatform; // e.g. iOSMac on macOS - uint32_t altOsVersion; // e.g. 14.0 for iOSMac - uint64_t swiftOptsOffset; // VM offset from cache_header* to Swift optimizations header - uint64_t swiftOptsSize; // size of Swift optimizations header - uint32_t subCacheArrayOffset; // file offset to first dyld_subcache_entry - uint32_t subCacheArrayCount; // number of subCache entries - uint8_t symbolFileUUID[16]; // unique value for the shared cache file containing unmapped local symbols - uint64_t rosettaReadOnlyAddr; // (unslid) address of the start of where Rosetta can add read-only/executable data - uint64_t rosettaReadOnlySize; // maximum size of the Rosetta read-only/executable region - uint64_t rosettaReadWriteAddr; // (unslid) address of the start of where Rosetta can add read-write data - uint64_t rosettaReadWriteSize; // maximum size of the Rosetta read-write region - uint32_t imagesOffset; // file offset to first dyld_cache_image_info - uint32_t imagesCount; // number of dyld_cache_image_info entries - uint32_t cacheSubType; // 0 for development, 1 for production, when cacheType is multi-cache(2) - uint64_t objcOptsOffset; // VM offset from cache_header* to ObjC optimizations header - uint64_t objcOptsSize; // size of ObjC optimizations header - uint64_t cacheAtlasOffset; // VM offset from cache_header* to embedded cache atlas for process introspection - uint64_t cacheAtlasSize; // size of embedded cache atlas - uint64_t dynamicDataOffset; // VM offset from cache_header* to the location of dyld_cache_dynamic_data_header - uint64_t dynamicDataMaxSize; // maximum size of space reserved from dynamic data -}; - -// Uncomment this and check the build errors for the current mapping offset to check against when adding new fields. -// template class A { int x[-size]; }; A a; - - -struct dyld_cache_mapping_info { - uint64_t address; - uint64_t size; - uint64_t fileOffset; - uint32_t maxProt; - uint32_t initProt; -}; - -// Contains the flags for the dyld_cache_mapping_and_slide_info flgs field -enum { - DYLD_CACHE_MAPPING_AUTH_DATA = 1 << 0U, - DYLD_CACHE_MAPPING_DIRTY_DATA = 1 << 1U, - DYLD_CACHE_MAPPING_CONST_DATA = 1 << 2U, - DYLD_CACHE_MAPPING_TEXT_STUBS = 1 << 3U, - DYLD_CACHE_DYNAMIC_CONFIG_DATA = 1 << 4U, -}; - -struct dyld_cache_mapping_and_slide_info { - uint64_t address; - uint64_t size; - uint64_t fileOffset; - uint64_t slideInfoFileOffset; - uint64_t slideInfoFileSize; - uint64_t flags; - uint32_t maxProt; - uint32_t initProt; -}; - -struct dyld_cache_image_info -{ - uint64_t address; - uint64_t modTime; - uint64_t inode; - uint32_t pathFileOffset; - uint32_t pad; -}; - -struct dyld_cache_image_info_extra -{ - uint64_t exportsTrieAddr; // address of trie in unslid cache - uint64_t weakBindingsAddr; - uint32_t exportsTrieSize; - uint32_t weakBindingsSize; - uint32_t dependentsStartArrayIndex; - uint32_t reExportsStartArrayIndex; -}; - - -struct dyld_cache_accelerator_info -{ - uint32_t version; // currently 1 - uint32_t imageExtrasCount; // does not include aliases - uint32_t imagesExtrasOffset; // offset into this chunk of first dyld_cache_image_info_extra - uint32_t bottomUpListOffset; // offset into this chunk to start of 16-bit array of sorted image indexes - uint32_t dylibTrieOffset; // offset into this chunk to start of trie containing all dylib paths - uint32_t dylibTrieSize; // size of trie containing all dylib paths - uint32_t initializersOffset; // offset into this chunk to start of initializers list - uint32_t initializersCount; // size of initializers list - uint32_t dofSectionsOffset; // offset into this chunk to start of DOF sections list - uint32_t dofSectionsCount; // size of initializers list - uint32_t reExportListOffset; // offset into this chunk to start of 16-bit array of re-exports - uint32_t reExportCount; // size of re-exports - uint32_t depListOffset; // offset into this chunk to start of 16-bit array of dependencies (0x8000 bit set if upward) - uint32_t depListCount; // size of dependencies - uint32_t rangeTableOffset; // offset into this chunk to start of ss - uint32_t rangeTableCount; // size of dependencies - uint64_t dyldSectionAddr; // address of libdyld's __dyld section in unslid cache -}; - -struct dyld_cache_accelerator_initializer -{ - uint32_t functionOffset; // address offset from start of cache mapping - uint32_t imageIndex; -}; - -struct dyld_cache_range_entry -{ - uint64_t startAddress; // unslid address of start of region - uint32_t size; - uint32_t imageIndex; -}; - -struct dyld_cache_accelerator_dof -{ - uint64_t sectionAddress; // unslid address of start of region - uint32_t sectionSize; - uint32_t imageIndex; -}; - -struct dyld_cache_image_text_info -{ - uuid_t uuid; - uint64_t loadAddress; // unslid address of start of __TEXT - uint32_t textSegmentSize; - uint32_t pathOffset; // offset from start of cache file -}; - - -// The rebasing info is to allow the kernel to lazily rebase DATA pages of the -// dyld shared cache. Rebasing is adding the slide to interior pointers. -struct dyld_cache_slide_info -{ - uint32_t version; // currently 1 - uint32_t toc_offset; - uint32_t toc_count; - uint32_t entries_offset; - uint32_t entries_count; - uint32_t entries_size; // currently 128 - // uint16_t toc[toc_count]; - // entrybitmap entries[entries_count]; -}; - -struct dyld_cache_slide_info_entry { - uint8_t bits[4096/(8*4)]; // 128-byte bitmap -}; - - -// The version 2 of the slide info uses a different compression scheme. Since -// only interior pointers (pointers that point within the cache) are rebased -// (slid), we know the possible range of the pointers and thus know there are -// unused bits in each pointer. We use those bits to form a linked list of -// locations needing rebasing in each page. -// -// Definitions: -// -// pageIndex = (pageAddress - startOfAllDataAddress)/info->page_size -// pageStarts[] = info + info->page_starts_offset -// pageExtras[] = info + info->page_extras_offset -// valueMask = ~(info->delta_mask) -// deltaShift = __builtin_ctzll(info->delta_mask) - 2 -// -// There are three cases: -// -// 1) pageStarts[pageIndex] == DYLD_CACHE_SLIDE_PAGE_ATTR_NO_REBASE -// The page contains no values that need rebasing. -// -// 2) (pageStarts[pageIndex] & DYLD_CACHE_SLIDE_PAGE_ATTR_EXTRA) == 0 -// All rebase locations are in one linked list. The offset of the first -// rebase location in the page is pageStarts[pageIndex] * 4. -// -// 3) pageStarts[pageIndex] & DYLD_CACHE_SLIDE_PAGE_ATTR_EXTRA -// Multiple linked lists are needed for all rebase locations in a page. -// The pagesExtras array contains 2 or more entries each of which is the -// start of a new linked list in the page. The first is at: -// extrasStartIndex = (pageStarts[pageIndex] & 0x3FFF) -// The next is at extrasStartIndex+1. The last is denoted by -// having the high bit (DYLD_CACHE_SLIDE_PAGE_ATTR_END) of the pageExtras[] -// set. -// -// For 64-bit architectures, there is always enough free bits to encode all -// possible deltas. The info->delta_mask field shows where the delta is located -// in the pointer. That value must be masked off (valueMask) before the slide -// is added to the pointer. -// -// For 32-bit architectures, there are only three bits free (the three most -// significant bits). To extract the delta, you must first subtract value_add -// from the pointer value, then AND with delta_mask, then shift by deltaShift. -// That still leaves a maximum delta to the next rebase location of 28 bytes. -// To reduce the number or chains needed, an optimization was added. Turns -// out zero is common in the DATA region. A zero can be turned into a -// non-rebasing entry in the linked list. The can be done because nothing -// in the shared cache should point out of its dylib to the start of the shared -// cache. -// -// The code for processing a linked list (chain) is: -// -// uint32_t delta = 1; -// while ( delta != 0 ) { -// uint8_t* loc = pageStart + pageOffset; -// uintptr_t rawValue = *((uintptr_t*)loc); -// delta = ((rawValue & deltaMask) >> deltaShift); -// uintptr_t newValue = (rawValue & valueMask); -// if ( newValue != 0 ) { -// newValue += valueAdd; -// newValue += slideAmount; -// } -// *((uintptr_t*)loc) = newValue; -// pageOffset += delta; -// } -// -// -struct dyld_cache_slide_info2 -{ - uint32_t version; // currently 2 - uint32_t page_size; // currently 4096 (may also be 16384) - uint32_t page_starts_offset; - uint32_t page_starts_count; - uint32_t page_extras_offset; - uint32_t page_extras_count; - uint64_t delta_mask; // which (contiguous) set of bits contains the delta to the next rebase location - uint64_t value_add; - //uint16_t page_starts[page_starts_count]; - //uint16_t page_extras[page_extras_count]; -}; -#define DYLD_CACHE_SLIDE_PAGE_ATTRS 0xC000 // high bits of uint16_t are flags -#define DYLD_CACHE_SLIDE_PAGE_ATTR_EXTRA 0x8000 // index is into extras array (not starts array) -#define DYLD_CACHE_SLIDE_PAGE_ATTR_NO_REBASE 0x4000 // page has no rebasing -#define DYLD_CACHE_SLIDE_PAGE_ATTR_END 0x8000 // last chain entry for page - - - -// The version 3 of the slide info uses a different compression scheme. Since -// only interior pointers (pointers that point within the cache) are rebased -// (slid), we know the possible range of the pointers and thus know there are -// unused bits in each pointer. We use those bits to form a linked list of -// locations needing rebasing in each page. -// -// Definitions: -// -// pageIndex = (pageAddress - startOfAllDataAddress)/info->page_size -// pageStarts[] = info + info->page_starts_offset -// -// There are two cases: -// -// 1) pageStarts[pageIndex] == DYLD_CACHE_SLIDE_V3_PAGE_ATTR_NO_REBASE -// The page contains no values that need rebasing. -// -// 2) otherwise... -// All rebase locations are in one linked list. The offset of the first -// rebase location in the page is pageStarts[pageIndex]. -// -// A pointer is one of of the variants in dyld_cache_slide_pointer3 -// -// The code for processing a linked list (chain) is: -// -// uint32_t delta = pageStarts[pageIndex]; -// dyld_cache_slide_pointer3* loc = pageStart; -// do { -// loc += delta; -// delta = loc->offsetToNextPointer; -// if ( loc->auth.authenticated ) { -// newValue = loc->offsetFromSharedCacheBase + results->slide + auth_value_add; -// newValue = sign_using_the_various_bits(newValue); -// } -// else { -// uint64_t value51 = loc->pointerValue; -// uint64_t top8Bits = value51 & 0x0007F80000000000ULL; -// uint64_t bottom43Bits = value51 & 0x000007FFFFFFFFFFULL; -// uint64_t targetValue = ( top8Bits << 13 ) | bottom43Bits; -// newValue = targetValue + results->slide; -// } -// loc->raw = newValue; -// } while (delta != 0); -// -// -struct dyld_cache_slide_info3 -{ - uint32_t version; // currently 3 - uint32_t page_size; // currently 4096 (may also be 16384) - uint32_t page_starts_count; - uint64_t auth_value_add; - uint16_t page_starts[/* page_starts_count */]; -}; - -#define DYLD_CACHE_SLIDE_V3_PAGE_ATTR_NO_REBASE 0xFFFF // page has no rebasing - -union dyld_cache_slide_pointer3 -{ - uint64_t raw; - struct { - uint64_t pointerValue : 51, - offsetToNextPointer : 11, - unused : 2; - } plain; - - struct { - uint64_t offsetFromSharedCacheBase : 32, - diversityData : 16, - hasAddressDiversity : 1, - key : 2, - offsetToNextPointer : 11, - unused : 1, - authenticated : 1; // = 1; - } auth; -}; - - - -// The version 4 of the slide info is optimized for 32-bit caches up to 1GB. -// Since only interior pointers (pointers that point within the cache) are rebased -// (slid), we know the possible range of the pointers takes 30 bits. That -// gives us two bits to use to chain to the next rebase. -// -// Definitions: -// -// pageIndex = (pageAddress - startOfAllDataAddress)/info->page_size -// pageStarts[] = info + info->page_starts_offset -// pageExtras[] = info + info->page_extras_offset -// valueMask = ~(info->delta_mask) -// deltaShift = __builtin_ctzll(info->delta_mask) - 2 -// -// There are three cases: -// -// 1) pageStarts[pageIndex] == DYLD_CACHE_SLIDE4_PAGE_NO_REBASE -// The page contains no values that need rebasing. -// -// 2) (pageStarts[pageIndex] & DYLD_CACHE_SLIDE4_PAGE_USE_EXTRA) == 0 -// All rebase locations are in one linked list. The offset of the first -// rebase location in the page is pageStarts[pageIndex] * 4. -// -// 3) pageStarts[pageIndex] & DYLD_CACHE_SLIDE4_PAGE_USE_EXTRA -// Multiple chains are needed for all rebase locations in a page. -// The pagesExtras array contains 2 or more entries each of which is the -// start of a new chain in the page. The first is at: -// extrasStartIndex = (pageStarts[pageIndex] & DYLD_CACHE_SLIDE4_PAGE_INDEX) -// The next is at extrasStartIndex+1. The last is denoted by -// having the high bit (DYLD_CACHE_SLIDE4_PAGE_EXTRA_END) of the pageExtras[]. -// -// For 32-bit architectures, there are only two bits free (the two most -// significant bits). To extract the delta, you must first subtract value_add -// from the pointer value, then AND with delta_mask, then shift by deltaShift. -// That still leaves a maximum delta to the next rebase location of 12 bytes. -// To reduce the number or chains needed, an optimization was added. Turns -// most of the non-rebased data are small values and can be co-opt'ed into -// being used in the chain. The can be done because nothing -// in the shared cache should point to the first 64KB which are in the shared -// cache header information. So if the resulting pointer points to the -// start of the cache +/-32KB, then it is actually a small number that should -// not be rebased, but just reconstituted. -// -// The code for processing a linked list (chain) is: -// -// uint32_t delta = 1; -// while ( delta != 0 ) { -// uint8_t* loc = pageStart + pageOffset; -// uint32_t rawValue = *((uint32_t*)loc); -// delta = ((rawValue & deltaMask) >> deltaShift); -// uintptr_t newValue = (rawValue & valueMask); -// if ( (newValue & 0xFFFF8000) == 0 ) { -// // small positive non-pointer, use as-is -// } -// else if ( (newValue & 0x3FFF8000) == 0x3FFF8000 ) { -// // small negative non-pointer -// newValue |= 0xC0000000; -// } -// else { -// // pointer that needs rebasing -// newValue += valueAdd; -// newValue += slideAmount; -// } -// *((uint32_t*)loc) = newValue; -// pageOffset += delta; -// } -// -// -struct dyld_cache_slide_info4 -{ - uint32_t version; // currently 4 - uint32_t page_size; // currently 4096 (may also be 16384) - uint32_t page_starts_offset; - uint32_t page_starts_count; - uint32_t page_extras_offset; - uint32_t page_extras_count; - uint64_t delta_mask; // which (contiguous) set of bits contains the delta to the next rebase location (0xC0000000) - uint64_t value_add; // base address of cache - //uint16_t page_starts[page_starts_count]; - //uint16_t page_extras[page_extras_count]; -}; -#define DYLD_CACHE_SLIDE4_PAGE_NO_REBASE 0xFFFF // page has no rebasing -#define DYLD_CACHE_SLIDE4_PAGE_INDEX 0x7FFF // mask of page_starts[] values -#define DYLD_CACHE_SLIDE4_PAGE_USE_EXTRA 0x8000 // index is into extras array (not a chain start offset) -#define DYLD_CACHE_SLIDE4_PAGE_EXTRA_END 0x8000 // last chain entry for page - - -struct dyld_cache_local_symbols_info -{ - uint32_t nlistOffset; // offset into this chunk of nlist entries - uint32_t nlistCount; // count of nlist entries - uint32_t stringsOffset; // offset into this chunk of string pool - uint32_t stringsSize; // byte count of string pool - uint32_t entriesOffset; // offset into this chunk of array of dyld_cache_local_symbols_entry - uint32_t entriesCount; // number of elements in dyld_cache_local_symbols_entry array -}; - -struct dyld_cache_local_symbols_entry -{ - uint32_t dylibOffset; // offset in cache file of start of dylib - uint32_t nlistStartIndex; // start index of locals for this dylib - uint32_t nlistCount; // number of local symbols for this dylib -}; - -struct dyld_cache_local_symbols_entry_64 -{ - uint64_t dylibOffset; // offset in cache buffer of start of dylib - uint32_t nlistStartIndex; // start index of locals for this dylib - uint32_t nlistCount; // number of local symbols for this dylib -}; - -struct dyld_subcache_entry_v1 -{ - uint8_t uuid[16]; // The UUID of the subCache file - uint64_t cacheVMOffset; // The offset of this subcache from the main cache base address -}; - -struct dyld_subcache_entry -{ - uint8_t uuid[16]; // The UUID of the subCache file - uint64_t cacheVMOffset; // The offset of this subcache from the main cache base address - char fileSuffix[32]; // The file name suffix of the subCache file e.g. ".25.data", ".03.development" -}; - -// This struct is a small piece of dynamic data that can be included in the shared region, and contains configuration -// data about the shared cache in use by the process. It is located -struct dyld_cache_dynamic_data_header -{ - char magic[16]; // e.g. "dyld_data v0" - uint64_t fsId; // The fsid_t of the shared cache being used by a process - uint64_t fsObjId; // The fs_obj_id_t of the shared cache being used by a process -}; - -// This is the location of the macOS shared cache on macOS 11.0 and later -#define MACOSX_MRM_DYLD_SHARED_CACHE_DIR "/System/Library/dyld/" - -// This is old define for the old location of the dyld cache -#define MACOSX_DYLD_SHARED_CACHE_DIR MACOSX_MRM_DYLD_SHARED_CACHE_DIR - -#define IPHONE_DYLD_SHARED_CACHE_DIR "/System/Library/Caches/com.apple.dyld/" - -#define DRIVERKIT_DYLD_SHARED_CACHE_DIR "/System/DriverKit/System/Library/dyld/" - -#if !TARGET_OS_SIMULATOR - #define DYLD_SHARED_CACHE_BASE_NAME "dyld_shared_cache_" -#else - #define DYLD_SHARED_CACHE_BASE_NAME "dyld_sim_shared_cache_" -#endif -#define DYLD_SHARED_CACHE_DEVELOPMENT_EXT ".development" - -#define DYLD_SHARED_CACHE_DYNAMIC_DATA_MAGIC "dyld_data v0" - -static const char* cryptexPrefixes[] = { - "/System/Volumes/Preboot/Cryptexes/OS/", - "/private/preboot/Cryptexes/OS/", - "/System/Cryptexes/OS" -}; - -static const uint64_t kDyldSharedCacheTypeDevelopment = 0; -static const uint64_t kDyldSharedCacheTypeProduction = 1; -static const uint64_t kDyldSharedCacheTypeUniversal = 2; - - - - - -#endif // __DYLD_CACHE_FORMAT__ - - diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/shared_cache_ctx.cpp b/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/shared_cache_ctx.cpp deleted file mode 100644 index 2c9db235..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/shared_cache_ctx.cpp +++ /dev/null @@ -1,183 +0,0 @@ -#include "shared_cache_ctx.h" - -#include -#include -#include - -#include "logging/logging.h" - -#include "mmap_file_util.h" - -typedef uintptr_t addr_t; - -extern "C" { -extern const char *dyld_shared_cache_file_path(); -extern int __shared_region_check_np(uint64_t *startaddress); -} - -const char *shared_cache_get_file_path() { - return dyld_shared_cache_file_path(); -} - -struct dyld_cache_header *shared_cache_get_load_addr() { - addr_t shared_cache_base = 0; - if (__shared_region_check_np((uint64_t *)&shared_cache_base) != 0) { - WARN_LOG("__shared_region_check_np failed"); - } - - if (shared_cache_base) - return (struct dyld_cache_header *)shared_cache_base; - - // task info - task_dyld_info_data_t task_dyld_info; - mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT; - kern_return_t ret = task_info(mach_task_self(), TASK_DYLD_INFO, (task_info_t)&task_dyld_info, &count); - if (ret != KERN_SUCCESS) { - ERROR_LOG("task_info failed, ret: %d", ret); - return NULL; - } - - // get dyld load address - auto *infos = (struct dyld_all_image_infos *)(uintptr_t)task_dyld_info.all_image_info_addr; - auto *shared_cache = (struct dyld_cache_header *)infos->sharedCacheBaseAddress; - return shared_cache; -} - -int shared_cache_load_symbols(shared_cache_ctx_t *ctx) { - uint64_t localSymbolsOffset = 0; - - bool latest_shared_cache_format = true; - - const char *shared_cache_path = shared_cache_get_file_path(); - char shared_cache_symbols_path[4096] = {0}; - { - strcat(shared_cache_symbols_path, shared_cache_path); - strcat(shared_cache_symbols_path, ".symbols"); - } - - auto mmapSharedCacheSymbolsMng = new MmapFileManager(shared_cache_symbols_path); - auto mmap_buffer = mmapSharedCacheSymbolsMng->map(); - if (mmap_buffer) { // iphoneos >= 15.0, which has .symbols file - ctx->mmap_shared_cache = (struct dyld_cache_header *)mmap_buffer; - - localSymbolsOffset = ctx->mmap_shared_cache->localSymbolsOffset; - } else { - // iphoneos < 15.0, which has no .symbols file - auto mmapSharedCacheMng = new MmapFileManager(shared_cache_symbols_path); - - auto runtime_shared_cache = ctx->runtime_shared_cache; - uint64_t mmap_length = runtime_shared_cache->localSymbolsSize; - uint64_t mmap_offset = runtime_shared_cache->localSymbolsOffset; - - if (mmap_length == 0) - return -1; - - auto mmap_buffer = mmapSharedCacheMng->map_options(mmap_length, mmap_offset); - if (!mmap_buffer) { - return -1; - } - - // fake shared cache header - auto mmap_shared_cache = - (struct dyld_cache_header *)((addr_t)mmap_buffer - runtime_shared_cache->localSymbolsOffset); - ctx->mmap_shared_cache = mmap_shared_cache; - - localSymbolsOffset = runtime_shared_cache->localSymbolsOffset; - - latest_shared_cache_format = false; - } - ctx->latest_shared_cache_format = latest_shared_cache_format; - - { - auto mmap_shared_cache = ctx->mmap_shared_cache; - auto localInfo = (struct dyld_cache_local_symbols_info *)((char *)mmap_shared_cache + localSymbolsOffset); - ctx->local_symbols_info = localInfo; - - if (ctx->latest_shared_cache_format) { - auto localEntries_64 = (struct dyld_cache_local_symbols_entry_64 *)((char *)localInfo + localInfo->entriesOffset); - ctx->local_symbols_entries_64 = localEntries_64; - } else { - auto localEntries = (struct dyld_cache_local_symbols_entry *)((char *)localInfo + localInfo->entriesOffset); - ctx->local_symbols_entries = localEntries; - } - - ctx->symtab = (nlist_t *)((char *)localInfo + localInfo->nlistOffset); - ctx->strtab = ((char *)localInfo) + localInfo->stringsOffset; - } - - return 0; -} - -int shared_cache_ctx_init(shared_cache_ctx_t *ctx) { - memset(ctx, 0, sizeof(shared_cache_ctx_t)); - - auto runtime_shared_cache = shared_cache_get_load_addr(); - if (!runtime_shared_cache) { - return -1; - } - ctx->runtime_shared_cache = runtime_shared_cache; - - // shared cache slide - auto mappings = - (struct dyld_cache_mapping_info *)((char *)runtime_shared_cache + runtime_shared_cache->mappingOffset); - uintptr_t slide = (uintptr_t)runtime_shared_cache - (uintptr_t)(mappings[0].address); - ctx->runtime_slide = slide; - - return 0; -} - -// refer: dyld -bool shared_cache_is_contain(shared_cache_ctx_t *ctx, addr_t addr, size_t length) { - struct dyld_cache_header *runtime_shared_cache; - if (ctx) { - runtime_shared_cache = ctx->runtime_shared_cache; - } else { - runtime_shared_cache = shared_cache_get_load_addr(); - } - - addr_t region_start = runtime_shared_cache->sharedRegionStart + ctx->runtime_slide; - addr_t region_end = region_start + runtime_shared_cache->sharedRegionSize; - if (addr >= region_start && addr < region_end) - return true; - - return false; -} - -int shared_cache_get_symbol_table(shared_cache_ctx_t *ctx, mach_header_t *image_header, nlist_t **out_symtab, - uint32_t *out_symtab_count, char **out_strtab) { - uint64_t textOffsetInCache = (uint64_t)image_header - (uint64_t)ctx->runtime_shared_cache; - - nlist_t *localNlists = NULL; - uint32_t localNlistCount = 0; - const char *localStrings = NULL; - - const uint32_t entriesCount = ctx->local_symbols_info->entriesCount; - for (uint32_t i = 0; i < entriesCount; ++i) { - if (ctx->latest_shared_cache_format) { - if (ctx->local_symbols_entries_64[i].dylibOffset == textOffsetInCache) { - uint32_t localNlistStart = ctx->local_symbols_entries_64[i].nlistStartIndex; - localNlistCount = ctx->local_symbols_entries_64[i].nlistCount; - localNlists = &ctx->symtab[localNlistStart]; - break; - } - } else { - if (ctx->local_symbols_entries[i].dylibOffset == textOffsetInCache) { - uint32_t localNlistStart = ctx->local_symbols_entries[i].nlistStartIndex; - localNlistCount = ctx->local_symbols_entries[i].nlistCount; - localNlists = &ctx->symtab[localNlistStart]; - break; - } - } - -#if 0 - static struct dyld_cache_image_info *imageInfos = NULL; - imageInfos = (struct dyld_cache_image_info *)((addr_t)g_mmap_shared_cache + g_mmap_shared_cache->imagesOffset); - char *image_name = (char *)g_mmap_shared_cache + imageInfos[i].pathFileOffset; - INFO_LOG("dyld image: %s", image_name); -#endif - } - *out_symtab = localNlists; - *out_symtab_count = (uint32_t)localNlistCount; - *out_strtab = (char *)ctx->strtab; - return 0; -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/shared_cache_ctx.h b/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/shared_cache_ctx.h deleted file mode 100644 index a17fdc54..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/shared_cache_ctx.h +++ /dev/null @@ -1,45 +0,0 @@ -#include -#include -#include - -#include "shared-cache/dyld_cache_format.h" - -#if defined(__LP64__) -typedef struct mach_header_64 mach_header_t; -typedef struct segment_command_64 segment_command_t; -typedef struct section_64 section_t; -typedef struct nlist_64 nlist_t; -#define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT_64 -#else -typedef struct mach_header mach_header_t; -typedef struct segment_command segment_command_t; -typedef struct section section_t; -typedef struct nlist nlist_t; -#define LC_SEGMENT_ARCH_DEPENDENT LC_SEGMENT -#endif - -typedef uintptr_t addr_t; - -typedef struct shared_cache_ctx { - struct dyld_cache_header *runtime_shared_cache; - struct dyld_cache_header *mmap_shared_cache; - - uintptr_t runtime_slide; - - bool latest_shared_cache_format; - struct dyld_cache_local_symbols_info *local_symbols_info; - struct dyld_cache_local_symbols_entry *local_symbols_entries; - struct dyld_cache_local_symbols_entry_64 *local_symbols_entries_64; - - nlist_t *symtab; - char *strtab; -} shared_cache_ctx_t; - -int shared_cache_ctx_init(shared_cache_ctx_t *ctx); - -int shared_cache_load_symbols(shared_cache_ctx_t *ctx); - -bool shared_cache_is_contain(shared_cache_ctx_t *ctx, addr_t addr, size_t length); - -int shared_cache_get_symbol_table(shared_cache_ctx_t *ctx, mach_header_t *image_header, nlist_t **out_symtab, - uint32_t *out_symtab_count, char **out_strtab); \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/mmap_file_util.h b/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/mmap_file_util.h deleted file mode 100644 index c5b05068..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/mmap_file_util.h +++ /dev/null @@ -1,63 +0,0 @@ -#pragma once - -#include -#include -#include -#include -#include -#include -#include -#include - -struct MmapFileManager { - const char *file_; - uint8_t *mmap_buffer; - size_t mmap_buffer_size; - - explicit MmapFileManager(const char *file) : file_(file), mmap_buffer(nullptr) { - } - - ~MmapFileManager() { - if (mmap_buffer) { - munmap((void *)mmap_buffer, mmap_buffer_size); - } - } - - uint8_t *map() { - size_t file_size = 0; - { - struct stat s; - int rt = stat(file_, &s); - if (rt != 0) { - // printf("mmap %s failed\n", file_); - return NULL; - } - file_size = s.st_size; - } - - return map_options(file_size, 0); - } - - uint8_t *map_options(size_t in_map_size, off_t in_map_off) { - if (!mmap_buffer) { - int fd = open(file_, O_RDONLY, 0); - if (fd < 0) { - // printf("%s open failed\n", file_); - return NULL; - } - - // auto align - auto mmap_buffer = (uint8_t *)mmap(0, in_map_size, PROT_READ | PROT_WRITE, MAP_FILE | MAP_PRIVATE, fd, in_map_off); - if (mmap_buffer == MAP_FAILED) { - // printf("mmap %s failed\n", file_); - return NULL; - } - - close(fd); - - this->mmap_buffer = mmap_buffer; - this->mmap_buffer_size = in_map_size; - } - return mmap_buffer; - } -}; diff --git a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/pe/dobby_symbol_resolver.cc b/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/pe/dobby_symbol_resolver.cc deleted file mode 100644 index e1d0502f..00000000 --- a/app/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/pe/dobby_symbol_resolver.cc +++ /dev/null @@ -1,26 +0,0 @@ -#include "SymbolResolver/dobby_symbol_resolver.h" -#include "dobby/common.h" - -#include - -#include -#include - -#include "PlatformUtil/ProcessRuntimeUtility.h" - -#include - -#undef LOG_TAG -#define LOG_TAG "DobbySymbolResolver" - -PUBLIC void *DobbySymbolResolver(const char *image_name, const char *symbol_name_pattern) { - void *result = NULL; - - HMODULE hMod = LoadLibraryExA(image_name, NULL, DONT_RESOLVE_DLL_REFERENCES); - result = GetProcAddress(hMod, symbol_name_pattern); - if (result) - return result; - - //result = resolve_elf_internal_symbol(image_name, symbol_name_pattern); - return result; -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/cmake/Macros.cmake b/app/src/main/cpp/Dobby/cmake/Macros.cmake deleted file mode 100644 index 5774bef5..00000000 --- a/app/src/main/cpp/Dobby/cmake/Macros.cmake +++ /dev/null @@ -1,3 +0,0 @@ -macro(SET_OPTION option value) - set(${option} ${value} CACHE INTERNAL "" FORCE) -endmacro() \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/cmake/Util.cmake b/app/src/main/cpp/Dobby/cmake/Util.cmake deleted file mode 100644 index fba658ef..00000000 --- a/app/src/main/cpp/Dobby/cmake/Util.cmake +++ /dev/null @@ -1,29 +0,0 @@ -# Check files list exist -function(check_files_exist CHECK_FILES) - foreach (file ${CHECK_FILES}) - if (NOT EXISTS "${file}") - message(FATAL_ERROR "${file} NOT EXISTS!") - endif () - endforeach () -endfunction(check_files_exist CHECK_FILES) - -# Search suffix files -function(search_suffix_files suffix INPUT_VARIABLE OUTPUT_VARIABLE) - set(ResultFiles) - foreach (filePath ${${INPUT_VARIABLE}}) - # message(STATUS "[*] searching *.${suffix} from ${filePath}") - file(GLOB files ${filePath}/*.${suffix}) - set(ResultFiles ${ResultFiles} ${files}) - endforeach () - set(${OUTPUT_VARIABLE} ${ResultFiles} PARENT_SCOPE) -endfunction() - - -function(get_absolute_path_list input_list output_list) - set(absolute_list) - foreach (file ${${input_list}}) - get_filename_component(absolute_file ${file} ABSOLUTE) - list(APPEND absolute_list ${absolute_file}) - endforeach () - set(${output_list} ${absolute_list} PARENT_SCOPE) -endfunction() \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/cmake/auto_source_group.cmake b/app/src/main/cpp/Dobby/cmake/auto_source_group.cmake deleted file mode 100644 index f5638362..00000000 --- a/app/src/main/cpp/Dobby/cmake/auto_source_group.cmake +++ /dev/null @@ -1,32 +0,0 @@ -function (auto_source_group _folder _base _pattern) - if (ARGC GREATER 3) - set(_exclude ${ARGN}) - else () - set(_exclude) - endif () - file (GLOB _files RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/ ${_folder}/*) - set (folder_files) - foreach (_fname ${_files}) - if (IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${_fname}) - auto_source_group ("${_fname}" "${_base}" "${_pattern}" "${_exclude}") - elseif (_fname MATCHES ${_pattern}) - if(_exclude) - if (NOT _fname MATCHES ${_exclude}) - set(folder_files ${folder_files} ${_fname}) - endif () - else () - set(folder_files ${folder_files} ${_fname}) - endif () - endif () - endforeach () - - string(REPLACE "./" "" _folder2 ${_folder}) - string(REPLACE "/" "\\" _folder2 ${_folder2}) - if (_folder2 STREQUAL ".") - source_group(${_base} FILES ${folder_files}) - else () - source_group(${_base}\\${_folder2} FILES ${folder_files}) - endif () - - set(AUTO_FILES_RESULT ${AUTO_FILES_RESULT} ${folder_files} PARENT_SCOPE) -endfunction () \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/cmake/build_environment_check.cmake b/app/src/main/cpp/Dobby/cmake/build_environment_check.cmake deleted file mode 100644 index 790309b4..00000000 --- a/app/src/main/cpp/Dobby/cmake/build_environment_check.cmake +++ /dev/null @@ -1,86 +0,0 @@ -if(__BUILD_ENVIRONMENT_CHECK) - return() -endif() -set(__BUILD_ENVIRONMENT_CHECK TRUE) - -message(STATUS "") -message(STATUS "********* build environment check ***********") - - -# The Compiler ID -if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "AppleClang") - set(COMPILER.Clang 1) -elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") - set(COMPILER.Gcc 1) -elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") -elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") - set(COMPILER.MSVC 1) -else() - message (FATAL_ERROR "Compiler ${CMAKE_CXX_COMPILER_ID} not configured") -endif() -message(STATUS "\tCompiler: \t ${CMAKE_CXX_COMPILER_ID}") - -if(MSVC) - string(TOLOWER ${MSVC_CXX_ARCHITECTURE_ID} CMAKE_SYSTEM_PROCESSOR) - set(CMAKE_SYSTEM_PROCESSOR ${MSVC_CXX_ARCHITECTURE_ID}) -endif() - - -if(DOBBY_BUILD_SILICON) - set(CMAKE_SYSTEM_PROCESSOR ${CMAKE_OSX_ARCHITECTURES}) -endif() - -string(TOLOWER ${CMAKE_SYSTEM_PROCESSOR} CMAKE_SYSTEM_PROCESSOR) - -# The Processor -if(CMAKE_SYSTEM_PROCESSOR MATCHES "amd64.*|x86_64.*|AMD64.*|x64.*") - set(PROCESSOR.X86_64 1) -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "i686.*|i386.*|x86.*|amd64.*|AMD64.*") - set(PROCESSOR.X86 1) -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^arm64.*") - set(PROCESSOR.AARCH64 1) -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(aarch64.*|AARCH64.*)") - set(PROCESSOR.AARCH64 1) -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(arm.*|ARM.*)") - set(PROCESSOR.ARM 1) -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)64le") - message(STATUS "NOT SUPPORT ${CMAKE_SYSTEM_PROCESSOR}") - set(PROCESSOR.PPC64LE 1) -elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "^(powerpc|ppc)64") - message(STATUS "NOT SUPPORT ${CMAKE_SYSTEM_PROCESSOR}") - set(PROCESSOR.PPC64 1) -else() - message (FATAL_ERROR "Processor ${CMAKE_SYSTEM_PROCESSOR} not configured") -endif() -message(STATUS "\tProcessor:\t ${CMAKE_SYSTEM_PROCESSOR}") - -# The System -if(CMAKE_SYSTEM_NAME MATCHES "^Android") - set(SYSTEM.Android 1) -elseif(CMAKE_SYSTEM_NAME MATCHES "^Windows") - set(SYSTEM.Windows 1) -elseif(CMAKE_SYSTEM_NAME MATCHES "^Linux") - set(SYSTEM.Linux 1) -elseif(CMAKE_SYSTEM_NAME MATCHES "^iOS") - set(SYSTEM.iOS 1) - set(SYSTEM.Darwin 1) -elseif(CMAKE_SYSTEM_NAME MATCHES "^macOS") - set(SYSTEM.macOS 1) - set(SYSTEM.Darwin 1) -elseif(CMAKE_SYSTEM_NAME MATCHES "^Darwin") - if(PROCESSOR.AARCH64 OR PROCESSOR.ARM) - set(CMAKE_SYSTEM_NAME "iOS or Silicon") - set(SYSTEM.iOS 1) - set(SYSTEM.Silicon 1) - elseif(PROCESSOR.X86 OR PROCESSOR.X86_64) - set(CMAKE_SYSTEM_NAME "macOS") - set(SYSTEM.macOS 1) - endif() - set(SYSTEM.Darwin 1) -else() - message (FATAL_ERROR "System ${CMAKE_SYSTEM_NAME} not configured") -endif() -message(STATUS "\tSystem: \t ${CMAKE_SYSTEM_NAME}") - -message(STATUS "***************************************") -message(STATUS "") diff --git a/app/src/main/cpp/Dobby/cmake/compiler_and_linker.cmake b/app/src/main/cpp/Dobby/cmake/compiler_and_linker.cmake deleted file mode 100644 index dd60f3e0..00000000 --- a/app/src/main/cpp/Dobby/cmake/compiler_and_linker.cmake +++ /dev/null @@ -1,55 +0,0 @@ -# :< You Shall Not Pass! -if (0) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Werror") -endif () - -set(linker_flags "") -if (NOT DOBBY_DEBUG) - set(linker_flags "${linker_flags} -Wl,-x -Wl,-S") -endif () - -set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-rtti -fno-exceptions -fno-stack-protector") - -if (SYSTEM.Darwin) - # set(compiler_flags "${compiler_flags} -nostdinc++") -elseif (SYSTEM.Android) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fomit-frame-pointer") - if (NOT DOBBY_DEBUG) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ffunction-sections -fdata-sections") - set(linker_flags "${linker_flags} -Wl,--gc-sections -Wl,--exclude-libs,ALL") - endif () -elseif (SYSTEM.Linux) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") - if (COMPILER.Clang) - if (PROCESSOR.ARM) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --target=armv7-unknown-linux-gnueabihf") - elseif (PROCESSOR.ARM64) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --target=aarch64-unknown-linux-gnu") - elseif (PROCESSOR.X86) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --target=i686-unknown-linux-gnu") - elseif (PROCESSOR.X86_64) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} --target=x86_64-unknown-linux-gnu") - endif () - endif () -elseif (SYSTEM.Windows) -endif () - -if (NOT DOBBY_DEBUG) - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3") - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fno-rtti -fvisibility=hidden -fvisibility-inlines-hidden") -endif () - -if (PROCESSOR.ARM) - set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -arch armv7 -x assembler-with-cpp") -elseif (PROCESSOR.AARCH64) - set(CMAKE_ASM_FLAGS "${CMAKE_ASM_FLAGS} -arch arm64 -x assembler-with-cpp") -endif () - -# sync cxx with c flags -set(CMAKE_CXX_FLAGS "${CMAKE_C_FLAGS} ${CMAKE_CXX_FLAGS}") - -message(STATUS "CMAKE_C_COMPILER: ${CMAKE_C_COMPILER}") -message(STATUS "CMAKE_CXX_COMPILER: ${CMAKE_CXX_COMPILER}") -message(STATUS "CMAKE_C_FLAGS: ${CMAKE_C_FLAGS}") -message(STATUS "CMAKE_CXX_FLAGS: ${CMAKE_CXX_FLAGS}") -message(STATUS "CMAKE_SHARED_LINKER_FLAGS: ${CMAKE_SHARED_LINKER_FLAGS}") diff --git a/app/src/main/cpp/Dobby/cmake/dobby.xcode.source.cmake b/app/src/main/cpp/Dobby/cmake/dobby.xcode.source.cmake deleted file mode 100644 index 64fb0e02..00000000 --- a/app/src/main/cpp/Dobby/cmake/dobby.xcode.source.cmake +++ /dev/null @@ -1,94 +0,0 @@ -set(dobby.SOURCE_FILE_LIST - # cpu - source/core/arch/CpuFeature.cc - source/core/arch/CpuRegister.cc - - # cpu - x86 - source/core/arch/x86/cpu-x86.cc - - # assembler - source/core/assembler/assembler.cc - source/core/assembler/assembler-arm.cc - source/core/assembler/assembler-arm64.cc - source/core/assembler/assembler-ia32.cc - source/core/assembler/assembler-x64.cc - - # codegen - source/core/codegen/codegen-arm.cc - source/core/codegen/codegen-arm64.cc - source/core/codegen/codegen-ia32.cc - source/core/codegen/codegen-x64.cc - - # executable memory - code buffer - source/MemoryAllocator/CodeBuffer/CodeBufferBase.cc - source/MemoryAllocator/CodeBuffer/code-buffer-x86.cc - - # executable memory - source/MemoryAllocator/AssemblyCodeBuilder.cc - source/MemoryAllocator/MemoryArena.cc - - # instruction relocation - source/InstructionRelocation/arm/InstructionRelocationARM.cc - source/InstructionRelocation/arm64/InstructionRelocationARM64.cc - source/InstructionRelocation/x86/X86InstructionRelocation.cc - source/InstructionRelocation/x64/InstructionRelocationX64.cc - - source/InstructionRelocation/x86/x86_insn_decode/x86_insn_decode.c - - # intercept routing - source/InterceptRouting/InterceptRouting.cpp - - # intercept routing trampoline - source/TrampolineBridge/Trampoline/arm/trampoline-arm.cc - source/TrampolineBridge/Trampoline/arm64/trampoline-arm64.cc - source/TrampolineBridge/Trampoline/x86/trampoline-x86.cc - source/TrampolineBridge/Trampoline/x64/trampoline-x64.cc - - # intercept routing plugin (buildin) - source/InterceptRouting/Routing/FunctionInlineReplace/function-inline-replace.cc - source/InterceptRouting/Routing/FunctionInlineReplace/FunctionInlineReplaceExport.cc - - # plugin register - source/InterceptRouting/RoutingPlugin/RoutingPlugin.cc - - # unified interface - - # platform util - source/UserMode/PlatformUtil/${platform2}/ProcessRuntimeUtility.cc - - # user mode - platform interface - source/UserMode/UnifiedInterface/platform-${platform1}.cc - - # user mode - executable memory - source/UserMode/ExecMemory/code-patch-tool-${platform1}.cc - source/UserMode/ExecMemory/clear-cache-tool-all.c - - # main - source/dobby.cpp - source/Interceptor.cpp - source/InterceptEntry.cpp - ) - -if(FunctionWrapper OR DynamicBinaryInstrument) - set(dobby.SOURCE_FILE_LIST ${dobby.SOURCE_FILE_LIST} - # closure trampoline bridge - source/TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.cc - - source/TrampolineBridge/ClosureTrampolineBridge/arm/helper-arm.cc - source/TrampolineBridge/ClosureTrampolineBridge/arm/closure-bridge-arm.cc - source/TrampolineBridge/ClosureTrampolineBridge/arm/ClosureTrampolineARM.cc - - source/TrampolineBridge/ClosureTrampolineBridge/arm64/helper-arm64.cc - source/TrampolineBridge/ClosureTrampolineBridge/arm64/closure-bridge-arm64.cc - source/TrampolineBridge/ClosureTrampolineBridge/arm64/ClosureTrampolineARM64.cc - - source/TrampolineBridge/ClosureTrampolineBridge/x64/helper-x64.cc - source/TrampolineBridge/ClosureTrampolineBridge/x64/closure-bridge-x64.cc - source/TrampolineBridge/ClosureTrampolineBridge/x64/ClosureTrampolineX64.cc - - # user mode - multi thread support - source/UserMode/MultiThreadSupport/ThreadSupport.cpp - source/UserMode/Thread/PlatformThread.cc - source/UserMode/Thread/platform-thread-${platform1}.cc - ) -endif() \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/cmake/platform/platform-darwin.cmake b/app/src/main/cpp/Dobby/cmake/platform/platform-darwin.cmake deleted file mode 100644 index 826c4183..00000000 --- a/app/src/main/cpp/Dobby/cmake/platform/platform-darwin.cmake +++ /dev/null @@ -1,30 +0,0 @@ -# set(CMAKE_BUILD_WITH_INSTALL_NAME_DIR TRUE) -set(CMAKE_INSTALL_NAME_DIR "@rpath") -set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG "-Wl,-rpath,") -add_library(DobbyX ${DOBBY_LIBRARY_TYPE} ${dobby.HEADER_FILE_LIST} ${dobby.SOURCE_FILE_LIST} ${logging.SOURCE_FILE_LIST} ${misc_helper.SOURCE_FILE_LIST} ${dobby.plugin.SOURCE_FILE_LIST}) - -set_target_properties(DobbyX - PROPERTIES - LINK_FLAGS "${linker_flags}" - COMPILE_FLAGS "${compiler_flags}" - ) - -# set framework property -set_target_properties(DobbyX PROPERTIES - FRAMEWORK TRUE - FRAMEWORK_VERSION A - MACOSX_FRAMEWORK_IDENTIFIER "com.dobby.dobby" - # MACOSX_FRAMEWORK_INFO_PLIST Info.plist - VERSION 1.0.0 # current version - SOVERSION 1.0.0 # compatibility version - PUBLIC_HEADER include/dobby.h - XCODE_ATTRIBUTE_CODE_SIGN_IDENTITY "Apple Development" - ) - -if ((SYSTEM.Darwin AND BUILDING_PLUGIN) AND (NOT DOBBY_BUILD_KERNEL_MODE)) -add_subdirectory(builtin-plugin/Dyld2HideLibrary) -add_subdirectory(builtin-plugin/ObjcRuntimeHook) -if (PROCESSOR.AARCH64) - add_subdirectory(builtin-plugin/SupervisorCallMonitor) -endif () -endif() \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/cmake/xcode_generator_helper.cmake b/app/src/main/cpp/Dobby/cmake/xcode_generator_helper.cmake deleted file mode 100644 index 243593dc..00000000 --- a/app/src/main/cpp/Dobby/cmake/xcode_generator_helper.cmake +++ /dev/null @@ -1,9 +0,0 @@ -if(CMAKE_GENERATOR STREQUAL Xcode) - message(STATUS "[*] Detect Xcode Project") - set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/build/Debug) - set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/build/Release) - set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/build/Debug) - set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/build/Release) - set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_BINARY_DIR}/build/Debug) - set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}/build/Release) -endif() \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/docs/compile.md b/app/src/main/cpp/Dobby/docs/compile.md deleted file mode 100644 index 002dba46..00000000 --- a/app/src/main/cpp/Dobby/docs/compile.md +++ /dev/null @@ -1,89 +0,0 @@ -# Build - -## CMake build options - -``` -option(DOBBY_GENERATE_SHARED "Build shared library" ON) - -option(DOBBY_DEBUG "Enable debug logging" OFF) - -option(NearBranch "Enable near branch trampoline" ON) - -option(FullFloatingPointRegisterPack "Save and pack all floating-point registers" OFF) - -option(Plugin.SymbolResolver "Enable symbol resolver" ON) - -option(Plugin.ImportTableReplace "Enable import table replace " OFF) - -option(Plugin.Android.BionicLinkerUtil "Enable android bionic linker util" OFF) - -option(DOBBY_BUILD_EXAMPLE "Build example" OFF) - -option(DOBBY_BUILD_TEST "Build test" OFF) -``` - -## Build with `scripts/platform_builder.py` - -#### Build for iphoneos - -```shell -python3 scripts/platform_builder.py --platform=iphoneos --arch=all -``` - -#### Build for macos - -``` -python3 scripts/platform_builder.py --platform=macos --arch=all -``` - -#### Build for linux - -``` -# prepare and download cmake/llvm -sh scripts/setup_linux_cross_compile.sh -python3 scripts/platform_builder.py --platform=linux --arch=all --cmake_dir=$HOME/opt/cmake-3.25.2 --llvm_dir=$HOME/opt/llvm-15.0.6 -``` - -#### Build for android - -``` -# prepare and download cmake/llvm/ndk -sh scripts/setup_linux_cross_compile.sh -python3 scripts/platform_builder.py --platform=android --arch=all --cmake_dir=$HOME/opt/cmake-3.25.2 --llvm_dir=$HOME/opt/llvm-15.0.6 --android_ndk_dir=$HOME/opt/ndk-r25b -``` - -## Build with CMake - -#### Build for host - -```shell -cd Dobby && mkdir cmake-build-host && cd cmake-build-host -cmake .. -make -j4 -``` - -## Build with Android Studio CMake - -``` -if(NOT TARGET dobby) -set(DOBBY_DIR /Users/jmpews/Workspace/Project.wrk/Dobby) -macro(SET_OPTION option value) - set(${option} ${value} CACHE INTERNAL "" FORCE) -endmacro() -SET_OPTION(DOBBY_DEBUG OFF) -SET_OPTION(DOBBY_GENERATE_SHARED OFF) -add_subdirectory(${DOBBY_DIR} dobby) -get_property(DOBBY_INCLUDE_DIRECTORIES - TARGET dobby - PROPERTY INCLUDE_DIRECTORIES) -include_directories( - . - ${DOBBY_INCLUDE_DIRECTORIES} - $ -) -endif() - -add_library(native-lib SHARED - ${DOBBY_DIR}/examples/socket_example.cc - native-lib.cpp) -``` diff --git a/app/src/main/cpp/Dobby/examples/CMakeLists.txt b/app/src/main/cpp/Dobby/examples/CMakeLists.txt deleted file mode 100644 index b461a1c6..00000000 --- a/app/src/main/cpp/Dobby/examples/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -add_executable(socket_example - main.cc - socket_example.cc - ) - -target_link_libraries(socket_example - dobby - logging - ) - - -add_library(socket_example_lib SHARED - socket_example.cc - ) - -target_link_libraries(socket_example_lib - dobby - ) \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/examples/main.cc b/app/src/main/cpp/Dobby/examples/main.cc deleted file mode 100644 index 33eeddf5..00000000 --- a/app/src/main/cpp/Dobby/examples/main.cc +++ /dev/null @@ -1,14 +0,0 @@ -#include -#include -#include -#include -#include -#include - -int main(int argc, char const *argv[]) { - - std::cout << "Start..." << std::endl; - - sleep(100); - return 0; -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/examples/socket_example.cc b/app/src/main/cpp/Dobby/examples/socket_example.cc deleted file mode 100644 index 1377fa3d..00000000 --- a/app/src/main/cpp/Dobby/examples/socket_example.cc +++ /dev/null @@ -1,212 +0,0 @@ -#include "dobby.h" - -#include "logging/logging.h" - -#include -#include -#include -#include -#include - -#include -#include -#include - -std::map *func_map; - -// clang-format off -const char *func_array[] = { -// "__loader_dlopen", - - "dlsym", - "dlclose", - - "open", - "write", - "read", - "close", - - "socket", - "connect", - "bind", - "listen", - "accept", - "send", - "recv", - - // "pthread_create" -}; - -const char *func_short_array[] = { - "accept", -}; -// clang-format on - -#define pac_strip(symbol) -#if defined(__APPLE__) && __arm64e__ -#if __has_feature(ptrauth_calls) -#define pac_strip(symbol) -//#define pac_strip(symbol) *(void **)&symbol = (void *)ptrauth_sign_unauthenticated((void *)symbol, ptrauth_key_asia, 0) -#endif -#endif - -#define install_hook(name, fn_ret_t, fn_args_t...) \ - fn_ret_t (*orig_##name)(fn_args_t); \ - fn_ret_t fake_##name(fn_args_t); \ - /* __attribute__((constructor)) */ static void install_hook_##name() { \ - void *sym_addr = DobbySymbolResolver(NULL, #name); \ - DobbyHook(sym_addr, (dobby_dummy_func_t)fake_##name, (dobby_dummy_func_t *)&orig_##name); \ - pac_strip(orig_##name); \ - printf("install hook %s:%p:%p\n", #name, sym_addr, orig_##name); \ - } \ - fn_ret_t fake_##name(fn_args_t) - -install_hook(pthread_create, int, pthread_t *thread, const pthread_attr_t *attrs, void *(*start_routine)(void *), - void *arg, unsigned int create_flags) { - INFO_LOG("pthread_create: %p", start_routine); - return orig_pthread_create(thread, attrs, start_routine, arg, create_flags); -} - -void common_handler(void *address, DobbyRegisterContext *ctx) { - auto iter = func_map->find(address); - if (iter != func_map->end()) { - INFO_LOG("func %s:%p invoke", iter->second, iter->first); - } -} - -uint64_t socket_demo_server(void *ctx); - -uint64_t socket_demo_client(void *ctx); - -#if 1 - -__attribute__((constructor)) static void ctor() { - logger_set_options(0, 0, 0, LOG_LEVEL_DEBUG, false, false); - - void *func = NULL; - func_map = new std::map(); - for (int i = 0; i < sizeof(func_array) / sizeof(char *); ++i) { - func = DobbySymbolResolver(NULL, func_array[i]); - if (func == NULL) { - INFO_LOG("func %s not resolve", func_array[i]); - continue; - } - func_map->insert(std::pair(func, func_array[i])); - } - - for (auto iter = func_map->begin(), e = func_map->end(); iter != e; iter++) { - bool is_short = false; - for (int i = 0; i < sizeof(func_short_array) / sizeof(char *); ++i) { - if (strcmp(func_short_array[i], iter->second) == 0) { - is_short = true; - break; - } - } - if (is_short) { - dobby_enable_near_branch_trampoline(); - DobbyInstrument(iter->first, common_handler); - dobby_disable_near_branch_trampoline(); - } else { - DobbyInstrument(iter->first, common_handler); - } - } - -#if defined(__APPLE__) - // DobbyImportTableReplace(NULL, "_pthread_create", (void *)fake_pthread_create, (void **)&orig_pthread_create); -#endif - - // install_hook_pthread_create(); - - pthread_t socket_server; - pthread_create(&socket_server, NULL, (void *(*)(void *))socket_demo_server, NULL); - - usleep(10000); - pthread_t socket_client; - pthread_create(&socket_client, NULL, (void *(*)(void *))socket_demo_client, NULL); - - // pthread_join(socket_client, 0); - // pthread_join(socket_server, 0); -} - -#include -#include -#include - -#define PORT 49494 - -uint64_t socket_demo_server(void *ctx) { - int server_fd, new_socket; - struct sockaddr_in address; - int opt = 1; - int addrlen = sizeof(address); - char buffer[1024] = {0}; - char *hello = "Hello from server"; - - if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { - ERROR_LOG("socket failed: %s", strerror(errno)); - return -1; - } - - if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) { - ERROR_LOG("setsockopt: %s", strerror(errno)); - return -1; - } - - address.sin_family = AF_INET; - address.sin_port = htons(PORT); - address.sin_addr.s_addr = INADDR_ANY; - - if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { - ERROR_LOG("bind failed: %s", strerror(errno)); - return -1; - } - if (listen(server_fd, 3) < 0) { - ERROR_LOG("listen failed: %s", strerror(errno)); - return -1; - } - if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t *)&addrlen)) < 0) { - ERROR_LOG("accept failed: %s", strerror(errno)); - return -1; - } - - int ret = recv(new_socket, buffer, 1024, 0); - INFO_LOG("[server] %s", buffer); - - send(new_socket, hello, strlen(hello), 0); - INFO_LOG("[server] Hello message sent"); - return 0; -} - -uint64_t socket_demo_client(void *ctx) { - int sock = 0; - struct sockaddr_in serv_addr; - char *hello = "Hello from client"; - char buffer[1024] = {0}; - if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - ERROR_LOG("socket failed"); - return -1; - } - - serv_addr.sin_family = AF_INET; - serv_addr.sin_port = htons(PORT); - - // Convert IPv4 and IPv6 addresses from text to binary form - if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) { - ERROR_LOG("inet_pton failed"); - return -1; - } - - if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { - ERROR_LOG("connect failed"); - return -1; - } - - send(sock, hello, strlen(hello), 0); - INFO_LOG("[client] Hello message sent"); - - int ret = recv(sock, buffer, 1024, 0); - INFO_LOG("[client] %s", buffer); - return 0; -} - -#endif diff --git a/app/src/main/cpp/Dobby/external/TINYSTL/README b/app/src/main/cpp/Dobby/external/TINYSTL/README deleted file mode 100644 index b6d58797..00000000 --- a/app/src/main/cpp/Dobby/external/TINYSTL/README +++ /dev/null @@ -1 +0,0 @@ -ref: https://github.com/mendsley/tinystl \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/external/TINYSTL/algorithm.h b/app/src/main/cpp/Dobby/external/TINYSTL/algorithm.h deleted file mode 100644 index 7b9637ef..00000000 --- a/app/src/main/cpp/Dobby/external/TINYSTL/algorithm.h +++ /dev/null @@ -1 +0,0 @@ -#pragma once \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/external/TINYSTL/allocator.h b/app/src/main/cpp/Dobby/external/TINYSTL/allocator.h deleted file mode 100644 index 685d98cb..00000000 --- a/app/src/main/cpp/Dobby/external/TINYSTL/allocator.h +++ /dev/null @@ -1,49 +0,0 @@ -/*- - * Copyright 2012-2018 Matthew Endsley - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TINYSTL_ALLOCATOR_H -#define TINYSTL_ALLOCATOR_H - -#include - -namespace tinystl { - - struct allocator { - static void* static_allocate(size_t bytes) { - return operator new(bytes); - } - - static void static_deallocate(void* ptr, size_t /*bytes*/) { - operator delete(ptr); - } - }; -} - -#ifndef TINYSTL_ALLOCATOR -# define TINYSTL_ALLOCATOR ::tinystl::allocator -#endif - -#endif diff --git a/app/src/main/cpp/Dobby/external/TINYSTL/buffer.h b/app/src/main/cpp/Dobby/external/TINYSTL/buffer.h deleted file mode 100644 index 7ec5d199..00000000 --- a/app/src/main/cpp/Dobby/external/TINYSTL/buffer.h +++ /dev/null @@ -1,310 +0,0 @@ -/*- - * Copyright 2012-2018 Matthew Endsley - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TINYSTL_BUFFER_H -#define TINYSTL_BUFFER_H - -#include -#include -#include - -namespace tinystl { - - template - struct buffer { - T* first; - T* last; - T* capacity; - }; - - template - static inline void buffer_destroy_range_traits(T* first, T* last, pod_traits) { - for (; first < last; ++first) - first->~T(); - } - - template - static inline void buffer_destroy_range_traits(T*, T*, pod_traits) { - } - - template - static inline void buffer_destroy_range(T* first, T* last) { - buffer_destroy_range_traits(first, last, pod_traits()); - } - - template - static inline void buffer_fill_urange_traits(T* first, T* last, pod_traits) { - for (; first < last; ++first) - new(placeholder(), first) T(); - } - - template - static inline void buffer_fill_urange_traits(T* first, T* last, pod_traits) { - for (; first < last; ++first) - *first = T(); - } - - template - static inline void buffer_fill_urange_traits(T* first, T* last, const T& value, pod_traits) { - for (; first < last; ++first) - new(placeholder(), first) T(value); - } - - template - static inline void buffer_fill_urange_traits(T* first, T* last, const T& value, pod_traits) { - for (; first < last; ++first) - *first = value; - } - - template - static inline void buffer_move_urange_traits(T* dest, T* first, T* last, pod_traits) { - for (T* it = first; it != last; ++it, ++dest) - move_construct(dest, *it); - buffer_destroy_range(first, last); - } - - template - static inline void buffer_move_urange_traits(T* dest, T* first, T* last, pod_traits) { - for (; first != last; ++first, ++dest) - *dest = *first; - } - - template - static inline void buffer_bmove_urange_traits(T* dest, T* first, T* last, pod_traits) { - dest += (last - first); - for (T* it = last; it != first; --it, --dest) { - move_construct(dest - 1, *(it - 1)); - buffer_destroy_range(it - 1, it); - } - } - - template - static inline void buffer_bmove_urange_traits(T* dest, T* first, T* last, pod_traits) { - dest += (last - first); - for (T* it = last; it != first; --it, --dest) - *(dest - 1) = *(it - 1); - } - - template - static inline void buffer_move_urange(T* dest, T* first, T* last) { - buffer_move_urange_traits(dest, first, last, pod_traits()); - } - - template - static inline void buffer_bmove_urange(T* dest, T* first, T* last) { - buffer_bmove_urange_traits(dest, first, last, pod_traits()); - } - - template - static inline void buffer_fill_urange(T* first, T* last) { - buffer_fill_urange_traits(first, last, pod_traits()); - } - - template - static inline void buffer_fill_urange(T* first, T* last, const T& value) { - buffer_fill_urange_traits(first, last, value, pod_traits()); - } - - template - static inline void buffer_init(buffer* b) { - b->first = b->last = b->capacity = 0; - } - - template - static inline void buffer_destroy(buffer* b) { - buffer_destroy_range(b->first, b->last); - Alloc::static_deallocate(b->first, (size_t)((char*)b->capacity - (char*)b->first)); - } - - template - static inline void buffer_reserve(buffer* b, size_t capacity) { - if (b->first + capacity <= b->capacity) - return; - - typedef T* pointer; - const size_t size = (size_t)(b->last - b->first); - pointer newfirst = (pointer)Alloc::static_allocate(sizeof(T) * capacity); - buffer_move_urange(newfirst, b->first, b->last); - Alloc::static_deallocate(b->first, sizeof(T) * capacity); - - b->first = newfirst; - b->last = newfirst + size; - b->capacity = newfirst + capacity; - } - - template - static inline void buffer_resize(buffer* b, size_t size) { - buffer_reserve(b, size); - - buffer_fill_urange(b->last, b->first + size); - buffer_destroy_range(b->first + size, b->last); - b->last = b->first + size; - } - - template - static inline void buffer_resize(buffer* b, size_t size, const T& value) { - buffer_reserve(b, size); - - buffer_fill_urange(b->last, b->first + size, value); - buffer_destroy_range(b->first + size, b->last); - b->last = b->first + size; - } - - template - static inline void buffer_shrink_to_fit(buffer* b) { - if (b->capacity != b->last) { - if (b->last == b->first) { - const size_t capacity = (size_t)(b->capacity - b->first); - Alloc::static_deallocate(b->first, sizeof(T)*capacity); - b->capacity = b->first = b->last = nullptr; - } else { - const size_t capacity = (size_t)(b->capacity - b->first); - const size_t size = (size_t)(b->last - b->first); - T* newfirst = (T*)Alloc::static_allocate(sizeof(T) * size); - buffer_move_urange(newfirst, b->first, b->last); - Alloc::static_deallocate(b->first, sizeof(T) * capacity); - b->first = newfirst; - b->last = newfirst + size; - b->capacity = b->last; - } - } - } - - template - static inline void buffer_clear(buffer* b) { - buffer_destroy_range(b->first, b->last); - b->last = b->first; - } - - template - static inline T* buffer_insert_common(buffer* b, T* where, size_t count) { - const size_t offset = (size_t)(where - b->first); - const size_t newsize = (size_t)((b->last - b->first) + count); - if (b->first + newsize > b->capacity) - buffer_reserve(b, (newsize * 3) / 2); - - where = b->first + offset; - - if (where != b->last) - buffer_bmove_urange(where + count, where, b->last); - - b->last = b->first + newsize; - - return where; - } - - template - static inline void buffer_insert(buffer* b, T* where, const Param* first, const Param* last) { - typedef const char* pointer; - const size_t count = last - first; - const bool frombuf = ((pointer)b->first <= (pointer)first && (pointer)b->last >= (pointer)last); - size_t offset; - if (frombuf) { - offset = (pointer)first - (pointer)b->first; - if ((pointer)where <= (pointer)first) - offset += count * sizeof(T); - where = buffer_insert_common(b, where, count); - first = (Param*)((pointer)b->first + offset); - last = first + count; - } - else { - where = buffer_insert_common(b, where, count); - } - for (; first != last; ++first, ++where) - new(placeholder(), where) T(*first); - } - - template - static inline void buffer_insert(buffer* b, T* where, size_t count) { - where = buffer_insert_common(b, where, count); - for (T* end = where+count; where != end; ++where) - new(placeholder(), where) T(); - } - - template - static inline void buffer_append(buffer* b, const Param* param) { - if (b->capacity != b->last) { - new(placeholder(), b->last) T(*param); - ++b->last; - } else { - buffer_insert(b, b->last, param, param + 1); - } - } - - template - static inline void buffer_append(buffer* b) { - if (b->capacity != b->last) { - new(placeholder(), b->last) T(); - ++b->last; - } else { - buffer_insert(b, b->last, 1); - } - } - - template - static inline T* buffer_erase(buffer* b, T* first, T* last) { - typedef T* pointer; - const size_t count = (last - first); - for (pointer it = last, end = b->last, dest = first; it != end; ++it, ++dest) - move(*dest, *it); - - buffer_destroy_range(b->last - count, b->last); - - b->last -= count; - return first; - } - - template - static inline T* buffer_erase_unordered(buffer* b, T* first, T* last) { - typedef T* pointer; - const size_t count = (last - first); - const size_t tail = (b->last - last); - pointer it = b->last - ((count < tail) ? count : tail); - for (pointer end = b->last, dest = first; it != end; ++it, ++dest) - move(*dest, *it); - - buffer_destroy_range(b->last - count, b->last); - - b->last -= count; - return first; - } - - template - static inline void buffer_swap(buffer* b, buffer* other) { - typedef T* pointer; - const pointer tfirst = b->first, tlast = b->last, tcapacity = b->capacity; - b->first = other->first, b->last = other->last, b->capacity = other->capacity; - other->first = tfirst, other->last = tlast, other->capacity = tcapacity; - } - - template - static inline void buffer_move(buffer* dst, buffer* src) { - dst->first = src->first, dst->last = src->last, dst->capacity = src->capacity; - src->first = src->last = src->capacity = nullptr; - } -} - -#endif //TINYSTL_BUFFER_H diff --git a/app/src/main/cpp/Dobby/external/TINYSTL/function.h b/app/src/main/cpp/Dobby/external/TINYSTL/function.h deleted file mode 100644 index fd8c6dec..00000000 --- a/app/src/main/cpp/Dobby/external/TINYSTL/function.h +++ /dev/null @@ -1,48 +0,0 @@ -#pragma once - -namespace tinystl { - -template class function; - -template class function { -public: - function() { - } - - template function(T functor) { - m_func = [](const void *user, Args... args) -> Return { - const T &func = *static_cast(user); - return func(static_cast(args)...); - }; - - m_dtor = [](void *user) { - T &func = *static_cast(user); - func.~T(); - }; - - new (tinystl::placeholder(), m_storage) T(static_cast(functor)); - } - - ~function() { - if (m_dtor) - m_dtor(m_storage); - } - - Return operator()(Args... args) const { - return m_func(m_storage, static_cast(args)...); - } - - explicit operator bool() { - return m_func != nullptr; - } - - using Func = Return (*)(const void *, Args...); - Func m_func = nullptr; - using Dtor = void (*)(void *); - Dtor m_dtor = nullptr; - union { - void *m_storage[8]; - }; -}; - -} // namespace tinystl \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/external/TINYSTL/hash.h b/app/src/main/cpp/Dobby/external/TINYSTL/hash.h deleted file mode 100644 index c03b326e..00000000 --- a/app/src/main/cpp/Dobby/external/TINYSTL/hash.h +++ /dev/null @@ -1,53 +0,0 @@ -/*- - * Copyright 2012-2018 Matthew Endsley - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TINYSTL_STRINGHASH_H -#define TINYSTL_STRINGHASH_H - -#include - -namespace tinystl { - - static inline size_t hash_string(const char* str, size_t len) { - // Implementation of sdbm a public domain string hash from Ozan Yigit - // see: http://www.eecs.harvard.edu/margo/papers/usenix91/paper.ps - - size_t hash = 0; - typedef const char* pointer; - for (pointer it = str, end = str + len; it != end; ++it) - hash = *it + (hash << 6) + (hash << 16) - hash; - - return hash; - } - - template - inline size_t hash(const T& value) { - const size_t asint = (size_t)value; - return hash_string((const char*)&asint, sizeof(asint)); - } -} - -#endif diff --git a/app/src/main/cpp/Dobby/external/TINYSTL/hash_base.h b/app/src/main/cpp/Dobby/external/TINYSTL/hash_base.h deleted file mode 100644 index 30f449b6..00000000 --- a/app/src/main/cpp/Dobby/external/TINYSTL/hash_base.h +++ /dev/null @@ -1,292 +0,0 @@ -/*- - * Copyright 2012-2018 Matthew Endsley - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TINYSTL_HASH_BASE_H -#define TINYSTL_HASH_BASE_H - -#include -#include - -namespace tinystl { - - template - struct pair { - pair(); - pair(const pair& other); - pair(pair&& other); - pair(const Key& key, const Value& value); - pair(Key&& key, Value&& value); - - pair& operator=(const pair& other); - pair& operator=(pair&& other); - - Key first; - Value second; - }; - - template - inline pair::pair() { - } - - template - inline pair::pair(const pair& other) - : first(other.first) - , second(other.second) - { - } - - template - inline pair::pair(pair&& other) - : first(static_cast(other.first)) - , second(static_cast(other.second)) - { - } - - template - inline pair::pair(const Key& key, const Value& value) - : first(key) - , second(value) - { - } - - template - inline pair::pair(Key&& key, Value&& value) - : first(static_cast(key)) - , second(static_cast(value)) - { - } - - template - inline pair& pair::operator=(const pair& other) { - first = other.first; - second = other.second; - return *this; - } - - template - inline pair& pair::operator=(pair&& other) { - first = static_cast(other.first); - second = static_cast(other.second); - return *this; - } - - template - static inline pair::type, typename remove_reference::type> - make_pair(Key&& key, Value&& value) { - return pair::type, typename remove_reference::type>( - static_cast(key) - , static_cast(value) - ); - } - - - template - struct unordered_hash_node { - unordered_hash_node(const Key& key, const Value& value); - unordered_hash_node(Key&& key, Value&& value); - - const Key first; - Value second; - unordered_hash_node* next; - unordered_hash_node* prev; - - private: - unordered_hash_node& operator=(const unordered_hash_node&); - }; - - template - inline unordered_hash_node::unordered_hash_node(const Key& key, const Value& value) - : first(key) - , second(value) - { - } - - template - inline unordered_hash_node::unordered_hash_node(Key&& key, Value&& value) - : first(static_cast(key)) - , second(static_cast(value)) - { - } - - template - struct unordered_hash_node { - explicit unordered_hash_node(const Key& key); - explicit unordered_hash_node(Key&& key); - - const Key first; - unordered_hash_node* next; - unordered_hash_node* prev; - - private: - unordered_hash_node& operator=(const unordered_hash_node&); - }; - - template - inline unordered_hash_node::unordered_hash_node(const Key& key) - : first(key) - { - } - - template - inline unordered_hash_node::unordered_hash_node(Key&& key) - : first(static_cast(key)) - { - } - - template - static inline void unordered_hash_node_insert(unordered_hash_node* node, size_t hash, unordered_hash_node** buckets, size_t nbuckets) { - size_t bucket = hash & (nbuckets - 1); - - unordered_hash_node* it = buckets[bucket + 1]; - node->next = it; - if (it) { - node->prev = it->prev; - it->prev = node; - if (node->prev) - node->prev->next = node; - } else { - size_t newbucket = bucket; - while (newbucket && !buckets[newbucket]) - --newbucket; - - unordered_hash_node* prev = buckets[newbucket]; - while (prev && prev->next) - prev = prev->next; - - node->prev = prev; - if (prev) - prev->next = node; - } - - // propagate node through buckets - for (; it == buckets[bucket]; --bucket) { - buckets[bucket] = node; - if (!bucket) - break; - } - } - - template - static inline void unordered_hash_node_erase(const unordered_hash_node* where, size_t hash, unordered_hash_node** buckets, size_t nbuckets) { - size_t bucket = hash & (nbuckets - 1); - - unordered_hash_node* next = where->next; - for (; buckets[bucket] == where; --bucket) { - buckets[bucket] = next; - if (!bucket) - break; - } - - if (where->prev) - where->prev->next = where->next; - if (next) - next->prev = where->prev; - } - - template - struct unordered_hash_iterator { - Node* operator->() const; - Node& operator*() const; - Node* node; - }; - - template - struct unordered_hash_iterator { - - unordered_hash_iterator() {} - unordered_hash_iterator(unordered_hash_iterator other) - : node(other.node) - { - } - - const Node* operator->() const; - const Node& operator*() const; - const Node* node; - }; - - template - struct unordered_hash_iterator > { - const Key* operator->() const; - const Key& operator*() const; - unordered_hash_node* node; - }; - - template - static inline bool operator==(const unordered_hash_iterator& lhs, const unordered_hash_iterator& rhs) { - return lhs.node == rhs.node; - } - - template - static inline bool operator!=(const unordered_hash_iterator& lhs, const unordered_hash_iterator& rhs) { - return lhs.node != rhs.node; - } - - template - static inline void operator++(unordered_hash_iterator& lhs) { - lhs.node = lhs.node->next; - } - - template - inline Node* unordered_hash_iterator::operator->() const { - return node; - } - - template - inline Node& unordered_hash_iterator::operator*() const { - return *node; - } - - template - inline const Node* unordered_hash_iterator::operator->() const { - return node; - } - - template - inline const Node& unordered_hash_iterator::operator*() const { - return *node; - } - - template - inline const Key* unordered_hash_iterator >::operator->() const { - return &node->first; - } - - template - inline const Key& unordered_hash_iterator >::operator*() const { - return node->first; - } - - template - static inline Node unordered_hash_find(const Key& key, Node* buckets, size_t nbuckets) { - const size_t bucket = hash(key) & (nbuckets - 2); - for (Node it = buckets[bucket], end = buckets[bucket+1]; it != end; it = it->next) - if (it->first == key) - return it; - - return 0; - } -} -#endif diff --git a/app/src/main/cpp/Dobby/external/TINYSTL/new.h b/app/src/main/cpp/Dobby/external/TINYSTL/new.h deleted file mode 100644 index cca0016d..00000000 --- a/app/src/main/cpp/Dobby/external/TINYSTL/new.h +++ /dev/null @@ -1,44 +0,0 @@ -/*- - * Copyright 2012-2018 Matthew Endsley - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TINYSTL_NEW_H -#define TINYSTL_NEW_H - -#include - -namespace tinystl { - -struct placeholder {}; -} // namespace tinystl - -inline void *operator new(size_t, tinystl::placeholder, void *ptr) { - return ptr; -} - -inline void operator delete(void *, tinystl::placeholder, void *) throw() { -} - -#endif diff --git a/app/src/main/cpp/Dobby/external/TINYSTL/stddef.h b/app/src/main/cpp/Dobby/external/TINYSTL/stddef.h deleted file mode 100644 index a31dd347..00000000 --- a/app/src/main/cpp/Dobby/external/TINYSTL/stddef.h +++ /dev/null @@ -1,43 +0,0 @@ -/*- - * Copyright 2012-2018 Matthew Endsley - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TINYSTL_STDDEF_H -#define TINYSTL_STDDEF_H - -#if defined(_WIN64) - typedef long long unsigned int size_t; - typedef long long int ptrdiff_t; -#elif defined(_WIN32) - typedef unsigned int size_t; - typedef int ptrdiff_t; -#elif defined (__linux__) && defined(__SIZE_TYPE__) && defined(__PTRDIFF_TYPE__) - typedef __SIZE_TYPE__ size_t; - typedef __PTRDIFF_TYPE__ ptrdiff_t; -#else -# include -#endif - -#endif diff --git a/app/src/main/cpp/Dobby/external/TINYSTL/string.h b/app/src/main/cpp/Dobby/external/TINYSTL/string.h deleted file mode 100644 index 3fe45d14..00000000 --- a/app/src/main/cpp/Dobby/external/TINYSTL/string.h +++ /dev/null @@ -1,295 +0,0 @@ -/*- - * Copyright 2012-2018 Matthew Endsley - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TINYSTL_STRING_H -#define TINYSTL_STRING_H - -#include -#include -#include - -namespace tinystl { - - template - class basic_string { - public: - basic_string(); - basic_string(const basic_string& other); - basic_string(basic_string&& other); - basic_string(const char* sz); - basic_string(const char* sz, size_t len); - ~basic_string(); - - basic_string& operator=(const basic_string& other); - basic_string& operator=(basic_string&& other); - - const char* c_str() const; - size_t size() const; - - void reserve(size_t size); - void resize(size_t size); - - void clear(); - void append(const char* first, const char* last); - void assign(const char* s, size_t n); - - void shrink_to_fit(); - void swap(basic_string& other); - - private: - typedef char* pointer; - pointer m_first; - pointer m_last; - pointer m_capacity; - - static const size_t c_nbuffer = 12; - char m_buffer[12]; - }; - - template - inline basic_string::basic_string() - : m_first(m_buffer) - , m_last(m_buffer) - , m_capacity(m_buffer + c_nbuffer) - { - resize(0); - } - - template - inline basic_string::basic_string(const basic_string& other) - : m_first(m_buffer) - , m_last(m_buffer) - , m_capacity(m_buffer + c_nbuffer) - { - reserve(other.size()); - append(other.m_first, other.m_last); - } - - template - inline basic_string::basic_string(basic_string&& other) - { - if (other.m_first == other.m_buffer) { - m_first = m_buffer; - m_last = m_buffer; - m_capacity = m_buffer + c_nbuffer; - reserve(other.size()); - append(other.m_first, other.m_last); - } else { - m_first = other.m_first; - m_last = other.m_last; - m_capacity = other.m_capacity; - } - other.m_first = other.m_last = other.m_buffer; - other.m_capacity = other.m_buffer + c_nbuffer; - other.resize(0); - } - - template - inline basic_string::basic_string(const char* sz) - : m_first(m_buffer) - , m_last(m_buffer) - , m_capacity(m_buffer + c_nbuffer) - { - size_t len = 0; - for (const char* it = sz; *it; ++it) - ++len; - - reserve(len); - append(sz, sz + len); - } - - template - inline basic_string::basic_string(const char* sz, size_t len) - : m_first(m_buffer) - , m_last(m_buffer) - , m_capacity(m_buffer + c_nbuffer) - { - reserve(len); - append(sz, sz + len); - } - - template - inline basic_string::~basic_string() { - if (m_first != m_buffer) - allocator::static_deallocate(m_first, m_capacity - m_first); - } - - template - inline basic_string& basic_string::operator=(const basic_string& other) { - basic_string(other).swap(*this); - return *this; - } - - template - inline basic_string& basic_string::operator=(basic_string&& other) { - basic_string(static_cast(other)).swap(*this); - return *this; - } - - template - inline const char* basic_string::c_str() const { - return m_first; - } - - template - inline size_t basic_string::size() const - { - return (size_t)(m_last - m_first); - } - - template - inline void basic_string::reserve(size_t capacity) { - if (m_first + capacity + 1 <= m_capacity) - return; - - const size_t size = (size_t)(m_last - m_first); - - pointer newfirst = (pointer)allocator::static_allocate(capacity + 1); - for (pointer it = m_first, newit = newfirst, end = m_last; it != end; ++it, ++newit) - *newit = *it; - if (m_first != m_buffer) - allocator::static_deallocate(m_first, m_capacity - m_first); - - m_first = newfirst; - m_last = newfirst + size; - m_capacity = m_first + capacity; - } - - template - inline void basic_string::resize(size_t size) { - const size_t prevSize = m_last-m_first; - reserve(size); - if (size > prevSize) - for (pointer it = m_last, end = m_first + size + 1; it < end; ++it) - *it = 0; - else if (m_last != m_first) - m_first[size] = 0; - - m_last = m_first + size; - } - - template - inline void basic_string::clear() { - resize(0); - } - - template - inline void basic_string::append(const char* first, const char* last) { - const size_t newsize = (size_t)((m_last - m_first) + (last - first) + 1); - if (m_first + newsize > m_capacity) - reserve((newsize * 3) / 2); - - for (; first != last; ++m_last, ++first) - *m_last = *first; - *m_last = 0; - } - - template - inline void basic_string::assign(const char* sz, size_t n) { - clear(); - append(sz, sz+n); - } - - template - inline void basic_string::shrink_to_fit() { - if (m_first == m_buffer) { - } else if (m_last == m_first) { - const size_t capacity = (size_t)(m_capacity - m_first); - if (capacity) - allocator::static_deallocate(m_first, capacity+1); - m_capacity = m_first; - } else if (m_capacity != m_last) { - const size_t size = (size_t)(m_last - m_first); - char* newfirst = (pointer)allocator::static_allocate(size+1); - for (pointer in = m_first, out = newfirst; in != m_last + 1; ++in, ++out) - *out = *in; - if (m_first != m_capacity) - allocator::static_deallocate(m_first, m_capacity+1-m_first); - m_first = newfirst; - m_last = newfirst+size; - m_capacity = m_last; - } - } - - template - inline void basic_string::swap(basic_string& other) { - const pointer tfirst = m_first, tlast = m_last, tcapacity = m_capacity; - m_first = other.m_first, m_last = other.m_last, m_capacity = other.m_capacity; - other.m_first = tfirst, other.m_last = tlast, other.m_capacity = tcapacity; - - char tbuffer[c_nbuffer]; - - if (m_first == other.m_buffer) - for (pointer it = other.m_buffer, end = m_last, out = tbuffer; it != end; ++it, ++out) - *out = *it; - - if (other.m_first == m_buffer) { - other.m_last = other.m_last - other.m_first + other.m_buffer; - other.m_first = other.m_buffer; - other.m_capacity = other.m_buffer + c_nbuffer; - - for (pointer it = other.m_first, end = other.m_last, in = m_buffer; it != end; ++it, ++in) - *it = *in; - *other.m_last = 0; - } - - if (m_first == other.m_buffer) { - m_last = m_last - m_first + m_buffer; - m_first = m_buffer; - m_capacity = m_buffer + c_nbuffer; - - for (pointer it = m_first, end = m_last, in = tbuffer; it != end; ++it, ++in) - *it = *in; - *m_last = 0; - } - } - - template - inline bool operator==(const basic_string& lhs, const basic_string& rhs) { - typedef const char* pointer; - - const size_t lsize = lhs.size(), rsize = rhs.size(); - if (lsize != rsize) - return false; - - pointer lit = lhs.c_str(), rit = rhs.c_str(); - pointer lend = lit + lsize; - while (lit != lend) - if (*lit++ != *rit++) - return false; - - return true; - } - - template - static inline size_t hash(const basic_string& value) { - return hash_string(value.c_str(), value.size()); - } - - typedef basic_string string; -} - -#endif diff --git a/app/src/main/cpp/Dobby/external/TINYSTL/string_view.h b/app/src/main/cpp/Dobby/external/TINYSTL/string_view.h deleted file mode 100644 index fabc6333..00000000 --- a/app/src/main/cpp/Dobby/external/TINYSTL/string_view.h +++ /dev/null @@ -1,147 +0,0 @@ -/*- - * Copyright 2012-1017 Matthew Endsley - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TINYSTL_STRING_VIEW_H -#define TINYSTL_STRING_VIEW_H - -#include - -namespace tinystl { - - class string_view - { - public: - typedef char value_type; - typedef char* pointer; - typedef const char* const_pointer; - typedef char& reference; - typedef const char& const_reference; - typedef const_pointer iterator; - typedef const_pointer const_iterator; - typedef size_t size_type; - typedef ptrdiff_t difference_type; - - static constexpr size_type npos = size_type(-1); - - constexpr string_view(); - constexpr string_view(const char* s, size_type count); - constexpr string_view(const char* s); - constexpr string_view(const string_view&) = default; - string_view& operator=(const string_view&) = default; - - constexpr const char* data() const; - constexpr char operator[](size_type pos) const; - constexpr size_type size() const; - constexpr bool empty() const; - constexpr iterator begin() const; - constexpr const_iterator cbegin() const; - constexpr iterator end() const; - constexpr const_iterator cend() const; - constexpr string_view substr(size_type pos = 0, size_type count = npos) const; - constexpr void swap(string_view& v); - - private: - string_view(decltype(nullptr)) = delete; - - static constexpr size_type strlen(const char*); - - const char* m_str; - size_type m_size; - }; - - constexpr string_view::string_view() - : m_str(nullptr) - , m_size(0) - { - } - - constexpr string_view::string_view(const char* s, size_type count) - : m_str(s) - , m_size(count) - { - } - - constexpr string_view::string_view(const char* s) - : m_str(s) - , m_size(strlen(s)) - { - } - - constexpr const char* string_view::data() const { - return m_str; - } - - constexpr char string_view::operator[](size_type pos) const { - return m_str[pos]; - } - - constexpr string_view::size_type string_view::size() const { - return m_size; - } - - constexpr bool string_view::empty() const { - return 0 == m_size; - } - - constexpr string_view::iterator string_view::begin() const { - return m_str; - } - - constexpr string_view::const_iterator string_view::cbegin() const { - return m_str; - } - - constexpr string_view::iterator string_view::end() const { - return m_str + m_size; - } - - constexpr string_view::const_iterator string_view::cend() const { - return m_str + m_size; - } - - constexpr string_view string_view::substr(size_type pos, size_type count) const { - return string_view(m_str + pos, npos == count ? m_size - pos : count); - } - - constexpr void string_view::swap(string_view& v) { - const char* strtmp = m_str; - size_type sizetmp = m_size; - m_str = v.m_str; - m_size = v.m_size; - v.m_str = strtmp; - v.m_size = sizetmp; - } - - constexpr string_view::size_type string_view::strlen(const char* s) { - for (size_t len = 0; ; ++len) { - if (0 == s[len]) { - return len; - } - } - } -} - -#endif // TINYSTL_STRING_VIEW_H diff --git a/app/src/main/cpp/Dobby/external/TINYSTL/traits.h b/app/src/main/cpp/Dobby/external/TINYSTL/traits.h deleted file mode 100644 index 84574ee7..00000000 --- a/app/src/main/cpp/Dobby/external/TINYSTL/traits.h +++ /dev/null @@ -1,100 +0,0 @@ -/*- - * Copyright 2012-2018 Matthew Endsley - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TINYSTL_TRAITS_H -#define TINYSTL_TRAITS_H - -#include - -#if defined(__GNUC__) -# define TINYSTL_TRY_POD_OPTIMIZATION(t) __is_pod(t) -#elif defined(_MSC_VER) -# define TINYSTL_TRY_POD_OPTIMIZATION(t) (!__is_class(t) || __is_pod(t)) -#else -# define TINYSTL_TRY_POD_OPTIMIZATION(t) false -#endif - -namespace tinystl { - template struct pod_traits {}; - - template struct swap_holder; - - template - static inline void move_impl(T& a, T& b, ...) { - a = b; - } - - template - static inline void move_impl(T& a, T& b, T*, swap_holder* = 0) { - a.swap(b); - } - - template - static inline void move(T& a, T&b) { - move_impl(a, b, (T*)0); - } - - template - static inline void move_construct_impl(T* a, T& b, ...) { - new(placeholder(), a) T(b); - } - - template - static inline void move_construct_impl(T* a, T& b, void*, swap_holder* = 0) { - // If your type T does not have a default constructor, simply insert: - // struct tinystl_nomove_construct; - // in the class definition - new(placeholder(), a) T; - a->swap(b); - } - - template - static inline void move_construct_impl(T* a, T& b, T*, typename T::tinystl_nomove_construct* = 0) { - new(placeholder(), a) T(b); - } - - template - static inline void move_construct(T* a, T& b) { - move_construct_impl(a, b, (T*)0); - } - - template - struct remove_reference { - typedef T type; - }; - - template - struct remove_reference { - typedef T type; - }; - - template - struct remove_reference { - typedef T type; - }; -} - -#endif diff --git a/app/src/main/cpp/Dobby/external/TINYSTL/unordered_map.h b/app/src/main/cpp/Dobby/external/TINYSTL/unordered_map.h deleted file mode 100644 index 4be6a78d..00000000 --- a/app/src/main/cpp/Dobby/external/TINYSTL/unordered_map.h +++ /dev/null @@ -1,289 +0,0 @@ -/*- - * Copyright 2012-2018 Matthew Endsley - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TINYSTL_UNORDERED_MAP_H -#define TINYSTL_UNORDERED_MAP_H - -#include -#include -#include -#include - -namespace tinystl { - - template - class unordered_map { - public: - unordered_map(); - unordered_map(const unordered_map& other); - unordered_map(unordered_map&& other); - ~unordered_map(); - - unordered_map& operator=(const unordered_map& other); - unordered_map& operator=(unordered_map&& other); - - typedef pair value_type; - - typedef unordered_hash_iterator > const_iterator; - typedef unordered_hash_iterator > iterator; - - iterator begin(); - iterator end(); - - const_iterator begin() const; - const_iterator end() const; - - void clear(); - bool empty() const; - size_t size() const; - - const_iterator find(const Key& key) const; - iterator find(const Key& key); - pair insert(const pair& p); - pair emplace(pair&& p); - void erase(const_iterator where); - - Value& operator[](const Key& key); - - void swap(unordered_map& other); - - private: - - void rehash(size_t nbuckets); - - typedef unordered_hash_node* pointer; - - size_t m_size; - tinystl::buffer m_buckets; - }; - - template - inline unordered_map::unordered_map() - : m_size(0) - { - buffer_init(&m_buckets); - buffer_resize(&m_buckets, 9, 0); - } - - template - inline unordered_map::unordered_map(const unordered_map& other) - : m_size(other.m_size) - { - const size_t nbuckets = (size_t)(other.m_buckets.last - other.m_buckets.first); - buffer_init(&m_buckets); - buffer_resize(&m_buckets, nbuckets, 0); - - for (pointer it = *other.m_buckets.first; it; it = it->next) { - unordered_hash_node* newnode = new(placeholder(), Alloc::static_allocate(sizeof(unordered_hash_node))) unordered_hash_node(it->first, it->second); - newnode->next = newnode->prev = 0; - - unordered_hash_node_insert(newnode, hash(it->first), m_buckets.first, nbuckets - 1); - } - } - - template - inline unordered_map::unordered_map(unordered_map&& other) - : m_size(other.m_size) - { - buffer_move(&m_buckets, &other.m_buckets); - other.m_size = 0; - } - - template - inline unordered_map::~unordered_map() { - if (m_buckets.first != m_buckets.last) - clear(); - buffer_destroy(&m_buckets); - } - - template - inline unordered_map& unordered_map::operator=(const unordered_map& other) { - unordered_map(other).swap(*this); - return *this; - } - - template - inline unordered_map& unordered_map::operator=(unordered_map&& other) { - unordered_map(static_cast(other)).swap(*this); - return *this; - } - - template - inline typename unordered_map::iterator unordered_map::begin() { - iterator it; - it.node = *m_buckets.first; - return it; - } - - template - inline typename unordered_map::iterator unordered_map::end() { - iterator it; - it.node = 0; - return it; - } - - template - inline typename unordered_map::const_iterator unordered_map::begin() const { - const_iterator cit; - cit.node = *m_buckets.first; - return cit; - } - - template - inline typename unordered_map::const_iterator unordered_map::end() const { - const_iterator cit; - cit.node = 0; - return cit; - } - - template - inline bool unordered_map::empty() const { - return m_size == 0; - } - - template - inline size_t unordered_map::size() const { - return m_size; - } - - template - inline void unordered_map::clear() { - pointer it = *m_buckets.first; - while (it) { - const pointer next = it->next; - it->~unordered_hash_node(); - Alloc::static_deallocate(it, sizeof(unordered_hash_node)); - - it = next; - } - - m_buckets.last = m_buckets.first; - buffer_resize(&m_buckets, 9, 0); - m_size = 0; - } - - template - inline typename unordered_map::iterator unordered_map::find(const Key& key) { - iterator result; - result.node = unordered_hash_find(key, m_buckets.first, (size_t)(m_buckets.last - m_buckets.first)); - return result; - } - - template - inline typename unordered_map::const_iterator unordered_map::find(const Key& key) const { - iterator result; - result.node = unordered_hash_find(key, m_buckets.first, (size_t)(m_buckets.last - m_buckets.first)); - return result; - } - - template - inline void unordered_map::rehash(size_t nbuckets) { - if (m_size + 1 > 4 * nbuckets) { - pointer root = *m_buckets.first; - - const size_t newnbuckets = ((size_t)(m_buckets.last - m_buckets.first) - 1) * 8; - m_buckets.last = m_buckets.first; - buffer_resize(&m_buckets, newnbuckets + 1, 0); - unordered_hash_node** buckets = m_buckets.first; - - while (root) { - const pointer next = root->next; - root->next = root->prev = 0; - unordered_hash_node_insert(root, hash(root->first), buckets, newnbuckets); - root = next; - } - } - } - - template - inline pair::iterator, bool> unordered_map::insert(const pair& p) { - pair result; - result.second = false; - - result.first = find(p.first); - if (result.first.node != 0) - return result; - - unordered_hash_node* newnode = new(placeholder(), Alloc::static_allocate(sizeof(unordered_hash_node))) unordered_hash_node(p.first, p.second); - newnode->next = newnode->prev = 0; - - const size_t nbuckets = (size_t)(m_buckets.last - m_buckets.first); - unordered_hash_node_insert(newnode, hash(p.first), m_buckets.first, nbuckets - 1); - - ++m_size; - rehash(nbuckets); - - result.first.node = newnode; - result.second = true; - return result; - } - - template - inline pair::iterator, bool> unordered_map::emplace(pair&& p) { - pair result; - result.second = false; - - result.first = find(p.first); - if (result.first.node != 0) - return result; - - const size_t keyhash = hash(p.first); - unordered_hash_node* newnode = new(placeholder(), Alloc::static_allocate(sizeof(unordered_hash_node))) unordered_hash_node(static_cast(p.first), static_cast(p.second)); - newnode->next = newnode->prev = 0; - - const size_t nbuckets = (size_t)(m_buckets.last - m_buckets.first); - unordered_hash_node_insert(newnode, keyhash, m_buckets.first, nbuckets - 1); - - ++m_size; - rehash(nbuckets); - - result.first.node = newnode; - result.second = true; - return result; - } - - template - inline void unordered_map::erase(const_iterator where) { - unordered_hash_node_erase(where.node, hash(where->first), m_buckets.first, (size_t)(m_buckets.last - m_buckets.first) - 1); - - where->~unordered_hash_node(); - Alloc::static_deallocate((void*)where.node, sizeof(unordered_hash_node)); - --m_size; - } - - template - inline Value& unordered_map::operator[](const Key& key) { - return insert(pair(key, Value())).first->second; - } - - template - inline void unordered_map::swap(unordered_map& other) { - size_t tsize = other.m_size; - other.m_size = m_size, m_size = tsize; - buffer_swap(&m_buckets, &other.m_buckets); - } -} -#endif diff --git a/app/src/main/cpp/Dobby/external/TINYSTL/unordered_set.h b/app/src/main/cpp/Dobby/external/TINYSTL/unordered_set.h deleted file mode 100644 index 450fbc5c..00000000 --- a/app/src/main/cpp/Dobby/external/TINYSTL/unordered_set.h +++ /dev/null @@ -1,265 +0,0 @@ -/*- - * Copyright 2012-2018 Matthew Endsley - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TINYSTL_UNORDERED_SET_H -#define TINYSTL_UNORDERED_SET_H - -#include -#include -#include -#include - -namespace tinystl { - - template - class unordered_set { - public: - unordered_set(); - unordered_set(const unordered_set& other); - unordered_set(unordered_set&& other); - ~unordered_set(); - - unordered_set& operator=(const unordered_set& other); - unordered_set& operator=(unordered_set&& other); - - typedef unordered_hash_iterator > const_iterator; - typedef const_iterator iterator; - - iterator begin() const; - iterator end() const; - - void clear(); - bool empty() const; - size_t size() const; - - iterator find(const Key& key) const; - pair insert(const Key& key); - pair emplace(Key&& key); - void erase(iterator where); - size_t erase(const Key& key); - - void swap(unordered_set& other); - - private: - - void rehash(size_t nbuckets); - - typedef unordered_hash_node* pointer; - - size_t m_size; - tinystl::buffer m_buckets; - }; - - template - inline unordered_set::unordered_set() - : m_size(0) - { - buffer_init(&m_buckets); - buffer_resize(&m_buckets, 9, 0); - } - - template - inline unordered_set::unordered_set(const unordered_set& other) - : m_size(other.m_size) - { - const size_t nbuckets = (size_t)(other.m_buckets.last - other.m_buckets.first); - buffer_init(&m_buckets); - buffer_resize(&m_buckets, nbuckets, 0); - - for (pointer it = *other.m_buckets.first; it; it = it->next) { - unordered_hash_node* newnode = new(placeholder(), Alloc::static_allocate(sizeof(unordered_hash_node))) unordered_hash_node(*it); - newnode->next = newnode->prev = 0; - unordered_hash_node_insert(newnode, hash(it->first), m_buckets.first, nbuckets - 1); - } - } - - template - inline unordered_set::unordered_set(unordered_set&& other) - : m_size(other.m_size) - { - buffer_move(&m_buckets, &other.m_buckets); - other.m_size = 0; - } - - template - inline unordered_set::~unordered_set() { - if (m_buckets.first != m_buckets.last) - clear(); - buffer_destroy(&m_buckets); - } - - template - inline unordered_set& unordered_set::operator=(const unordered_set& other) { - unordered_set(other).swap(*this); - return *this; - } - - template - inline unordered_set& unordered_set::operator=(unordered_set&& other) { - unordered_set(static_cast(other)).swap(*this); - return *this; - } - - template - inline typename unordered_set::iterator unordered_set::begin() const { - iterator cit; - cit.node = *m_buckets.first; - return cit; - } - - template - inline typename unordered_set::iterator unordered_set::end() const { - iterator cit; - cit.node = 0; - return cit; - } - - template - inline bool unordered_set::empty() const { - return m_size == 0; - } - - template - inline size_t unordered_set::size() const { - return m_size; - } - - template - inline void unordered_set::clear() { - pointer it = *m_buckets.first; - while (it) { - const pointer next = it->next; - it->~unordered_hash_node(); - Alloc::static_deallocate(it, sizeof(unordered_hash_node)); - - it = next; - } - - m_buckets.last = m_buckets.first; - buffer_resize(&m_buckets, 9, 0); - m_size = 0; - } - - template - inline typename unordered_set::iterator unordered_set::find(const Key& key) const { - iterator result; - result.node = unordered_hash_find(key, m_buckets.first, (size_t)(m_buckets.last - m_buckets.first)); - return result; - } - - template - inline void unordered_set::rehash(size_t nbuckets) { - if (m_size + 1 > 4 * nbuckets) { - pointer root = *m_buckets.first; - - const size_t newnbuckets = ((size_t)(m_buckets.last - m_buckets.first) - 1) * 8; - m_buckets.last = m_buckets.first; - buffer_resize(&m_buckets, newnbuckets + 1, 0); - unordered_hash_node** buckets = m_buckets.first; - - while (root) { - const pointer next = root->next; - root->next = root->prev = 0; - unordered_hash_node_insert(root, hash(root->first), buckets, newnbuckets); - root = next; - } - } - } - - template - inline pair::iterator, bool> unordered_set::insert(const Key& key) { - pair result; - result.second = false; - - result.first = find(key); - if (result.first.node != 0) - return result; - - unordered_hash_node* newnode = new(placeholder(), Alloc::static_allocate(sizeof(unordered_hash_node))) unordered_hash_node(key); - newnode->next = newnode->prev = 0; - - const size_t nbuckets = (size_t)(m_buckets.last - m_buckets.first); - unordered_hash_node_insert(newnode, hash(key), m_buckets.first, nbuckets - 1); - - ++m_size; - rehash(nbuckets); - - result.first.node = newnode; - result.second = true; - return result; - } - - template - inline pair::iterator, bool> unordered_set::emplace(Key&& key) { - pair result; - result.second = false; - - result.first = find(key); - if (result.first.node != 0) - return result; - - const size_t keyhash = hash(key); - unordered_hash_node* newnode = new(placeholder(), Alloc::static_allocate(sizeof(unordered_hash_node))) unordered_hash_node(static_cast(key)); - newnode->next = newnode->prev = 0; - - const size_t nbuckets = (size_t)(m_buckets.last - m_buckets.first); - unordered_hash_node_insert(newnode, keyhash, m_buckets.first, nbuckets - 1); - - ++m_size; - rehash(nbuckets); - - result.first.node = newnode; - result.second = true; - return result; - } - - template - inline void unordered_set::erase(iterator where) { - unordered_hash_node_erase(where.node, hash(where.node->first), m_buckets.first, (size_t)(m_buckets.last - m_buckets.first) - 1); - - where.node->~unordered_hash_node(); - Alloc::static_deallocate((void*)where.node, sizeof(unordered_hash_node)); - --m_size; - } - - template - inline size_t unordered_set::erase(const Key& key) { - const iterator it = find(key); - if (it.node == 0) - return 0; - - erase(it); - return 1; - } - - template - void unordered_set::swap(unordered_set& other) { - size_t tsize = other.m_size; - other.m_size = m_size, m_size = tsize; - buffer_swap(&m_buckets, &other.m_buckets); - } -} -#endif diff --git a/app/src/main/cpp/Dobby/external/TINYSTL/vector.h b/app/src/main/cpp/Dobby/external/TINYSTL/vector.h deleted file mode 100644 index 6e3b0e15..00000000 --- a/app/src/main/cpp/Dobby/external/TINYSTL/vector.h +++ /dev/null @@ -1,353 +0,0 @@ -/*- - * Copyright 2012-2018 Matthew Endsley - * All rights reserved - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted providing that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING - * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef TINYSTL_VECTOR_H -#define TINYSTL_VECTOR_H - -#include -#include -#include -#include - -namespace tinystl { -template class vector { - using iterator = T *; - -public: - vector(); - vector(const vector &other); - vector(vector &&other); - vector(size_t size); - vector(size_t size, const T &value); - vector(const T *first, const T *last); - ~vector(); - - vector &operator=(const vector &other); - vector &operator=(vector &&other); - - void assign(const T *first, const T *last); - - const T *data() const; - T *data(); - size_t size() const; - size_t capacity() const; - bool empty() const; - - T &operator[](size_t idx); - const T &operator[](size_t idx) const; - - const T &front() const; - T &front(); - const T &back() const; - T &back(); - - void resize(size_t size); - void resize(size_t size, const T &value); - void clear(); - void reserve(size_t capacity); - - void push_back(const T &t); - void pop_back(); - - void emplace_back(); - template void emplace_back(const Param ¶m); - - void shrink_to_fit(); - - void swap(vector &other); - - typedef T value_type; - - iterator begin(); - iterator end(); - - typedef const T *const_iterator; - const_iterator begin() const; - const_iterator end() const; - - void insert(iterator where); - void insert(iterator where, const T &value); - void insert(iterator where, const T *first, const T *last); - - template void emplace(iterator where, const Param ¶m); - - iterator erase(iterator where); - iterator erase(iterator first, iterator last); - - iterator erase_unordered(iterator where); - iterator erase_unordered(iterator first, iterator last); - - iterator find(const T &other) const; - void sort(int (*compare)(const T &elem0, const T &elem1)); - void sort(unsigned begin, unsigned end, int (*compare)(const T &elem0, const T &elem1)); - -private: - int partition(int (*compare)(const T &elem0, const T &elem1), int p, int r); - void quick_sort(int (*compare)(const T &elem0, const T &elem1), int p, int r); - -private: - buffer m_buffer; -}; - -template inline vector::vector() { - buffer_init(&m_buffer); -} - -template inline vector::vector(const vector &other) { - buffer_init(&m_buffer); - buffer_reserve(&m_buffer, other.size()); - buffer_insert(&m_buffer, m_buffer.last, other.m_buffer.first, other.m_buffer.last); -} - -template inline vector::vector(vector &&other) { - buffer_move(&m_buffer, &other.m_buffer); -} - -template inline vector::vector(size_t size) { - buffer_init(&m_buffer); - buffer_resize(&m_buffer, size); -} - -template inline vector::vector(size_t size, const T &value) { - buffer_init(&m_buffer); - buffer_resize(&m_buffer, size, value); -} - -template inline vector::vector(const T *first, const T *last) { - buffer_init(&m_buffer); - buffer_insert(&m_buffer, m_buffer.last, first, last); -} - -template inline vector::~vector() { - buffer_destroy(&m_buffer); -} - -template inline vector &vector::operator=(const vector &other) { - vector(other).swap(*this); - return *this; -} - -template vector &vector::operator=(vector &&other) { - buffer_destroy(&m_buffer); - buffer_move(&m_buffer, &other.m_buffer); - return *this; -} - -template inline void vector::assign(const T *first, const T *last) { - buffer_clear(&m_buffer); - buffer_insert(&m_buffer, m_buffer.last, first, last); -} - -template inline const T *vector::data() const { - return m_buffer.first; -} - -template inline T *vector::data() { - return m_buffer.first; -} - -template inline size_t vector::size() const { - return (size_t)(m_buffer.last - m_buffer.first); -} - -template inline size_t vector::capacity() const { - return (size_t)(m_buffer.capacity - m_buffer.first); -} - -template inline bool vector::empty() const { - return m_buffer.last == m_buffer.first; -} - -template inline T &vector::operator[](size_t idx) { - return m_buffer.first[idx]; -} - -template inline const T &vector::operator[](size_t idx) const { - return m_buffer.first[idx]; -} - -template inline const T &vector::front() const { - return m_buffer.first[0]; -} - -template inline T &vector::front() { - return m_buffer.first[0]; -} - -template inline const T &vector::back() const { - return m_buffer.last[-1]; -} - -template inline T &vector::back() { - return m_buffer.last[-1]; -} - -template inline void vector::resize(size_t size) { - buffer_resize(&m_buffer, size); -} - -template inline void vector::resize(size_t size, const T &value) { - buffer_resize(&m_buffer, size, value); -} - -template inline void vector::clear() { - buffer_clear(&m_buffer); -} - -template inline void vector::reserve(size_t capacity) { - buffer_reserve(&m_buffer, capacity); -} - -template inline void vector::push_back(const T &t) { - buffer_append(&m_buffer, &t); -} - -template inline void vector::emplace_back() { - buffer_append(&m_buffer); -} - -template -template -inline void vector::emplace_back(const Param ¶m) { - buffer_append(&m_buffer, ¶m); -} - -template inline void vector::pop_back() { - buffer_erase(&m_buffer, m_buffer.last - 1, m_buffer.last); -} - -template inline void vector::shrink_to_fit() { - buffer_shrink_to_fit(&m_buffer); -} - -template inline void vector::swap(vector &other) { - buffer_swap(&m_buffer, &other.m_buffer); -} - -template inline typename vector::iterator vector::begin() { - return m_buffer.first; -} - -template inline typename vector::iterator vector::end() { - return m_buffer.last; -} - -template inline typename vector::const_iterator vector::begin() const { - return m_buffer.first; -} - -template inline typename vector::const_iterator vector::end() const { - return m_buffer.last; -} - -template inline void vector::insert(typename vector::iterator where) { - buffer_insert(&m_buffer, where, 1); -} - -template inline void vector::insert(iterator where, const T &value) { - buffer_insert(&m_buffer, where, &value, &value + 1); -} - -template -inline void vector::insert(iterator where, const T *first, const T *last) { - buffer_insert(&m_buffer, where, first, last); -} - -template -inline typename vector::iterator vector::erase(iterator where) { - return buffer_erase(&m_buffer, where, where + 1); -} - -template -inline typename vector::iterator vector::erase(iterator first, iterator last) { - return buffer_erase(&m_buffer, first, last); -} - -template -inline typename vector::iterator vector::erase_unordered(iterator where) { - return buffer_erase_unordered(&m_buffer, where, where + 1); -} - -template -inline typename vector::iterator vector::erase_unordered(iterator first, iterator last) { - return buffer_erase_unordered(&m_buffer, first, last); -} - -template -template -void vector::emplace(typename vector::iterator where, const Param ¶m) { - buffer_insert(&m_buffer, where, ¶m, ¶m + 1); -} - -template -inline typename vector::iterator vector::find(const T &other) const { - for (unsigned i = 0; i < size(); ++i) - if (m_buffer.first[i] == other) - return &m_buffer.first[i]; - - return m_buffer.last; -} - -template -inline int vector::partition(int (*compare)(const T &elem0, const T &elem1), int p, int r) { - T tmp, pivot = m_buffer.first[p]; - int left = p; - - for (int i = p + 1; i <= r; i++) { - if (compare(m_buffer.first[i], pivot) < 0) { - left++; - tmp = m_buffer.first[i]; - m_buffer.first[i] = m_buffer.first[left]; - m_buffer.first[left] = tmp; - } - } - tmp = m_buffer.first[p]; - m_buffer.first[p] = m_buffer.first[left]; - m_buffer.first[left] = tmp; - return left; -} - -template -inline void vector::quick_sort(int (*compare)(const T &elem0, const T &elem1), int p, int r) { - if (p < r) { - int q = partition(compare, p, r); - quick_sort(compare, p, q - 1); - quick_sort(compare, q + 1, r); - } -} - -template -inline void vector::sort(int (*compare)(const T &elem0, const T &elem1)) { - quick_sort(compare, 0, (int)size() - 1); -} - -template -inline void vector::sort(unsigned begin, unsigned end, int (*compare)(const T &elem0, const T &elem1)) { - quick_sort(compare, (int)begin, (int)end); -} -} // namespace tinystl - -#endif // TINYSTL_VECTOR_H diff --git a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/CMakeLists.txt b/app/src/main/cpp/Dobby/external/deprecated/misc-helper/CMakeLists.txt deleted file mode 100644 index fca13b62..00000000 --- a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -include_directories(.) - -if(NOT DOBBY_BUILD_KERNEL_MODE) - set(SOURCE_FILE_LIST - ${CMAKE_CURRENT_SOURCE_DIR}/variable_cache.c - ${CMAKE_CURRENT_SOURCE_DIR}/async_logger.cc - ${CMAKE_CURRENT_SOURCE_DIR}/format_printer.cc - ) -else() - set(SOURCE_FILE_LIST - ${CMAKE_CURRENT_SOURCE_DIR}/format_printer.cc - ) -endif() - -add_library(misc_helper - ${SOURCE_FILE_LIST} - ${SOURCE_HEADER_LIST} -) \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/async_logger.cc b/app/src/main/cpp/Dobby/external/deprecated/misc-helper/async_logger.cc deleted file mode 100644 index 49b11cb2..00000000 --- a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/async_logger.cc +++ /dev/null @@ -1,65 +0,0 @@ -#include -#include -#include -#include - -#include - -#include -#include -#include - -#define aync_logger_buffer_size (20 * 1024 * 1024) -int async_logger_buffer_cursor = 0; -char async_logger_buffer[aync_logger_buffer_size]; - -static pthread_mutex_t async_logger_mutex = PTHREAD_MUTEX_INITIALIZER; - -static int output_fd = -1; - -void async_logger_print(char *str) { - pthread_mutex_lock(&async_logger_mutex); -#if 0 - { - write(STDOUT_FILENO, str, strlen(str) + 1); - } -#endif - memcpy(async_logger_buffer + async_logger_buffer_cursor, str, strlen(str)); - async_logger_buffer_cursor += strlen(str); - pthread_mutex_unlock(&async_logger_mutex); - return; -} - -static void *async_logger_print_impl(void *ctx) { - while (1) { - pthread_mutex_lock(&async_logger_mutex); - if (async_logger_buffer_cursor > 0) { - write(output_fd, async_logger_buffer, async_logger_buffer_cursor); - async_logger_buffer_cursor = 0; - } - pthread_mutex_unlock(&async_logger_mutex); - sleep(1); - } -} - -void async_logger_init(char *logger_path) { - static int async_logger_initialized = 0; - if (async_logger_initialized) - return; - async_logger_initialized = 1; - - // init stdout write lock - pthread_mutex_t write_mutex; - pthread_mutex_init(&write_mutex, NULL); - - output_fd = STDOUT_FILENO; - if (logger_path) { - int fd = open(logger_path, O_CREAT | O_WRONLY | O_TRUNC, 0644); - output_fd = fd; - } - - // init async logger - pthread_mutex_init(&async_logger_mutex, NULL); - pthread_t async_logger_thread; - int ret = pthread_create(&async_logger_thread, NULL, async_logger_print_impl, NULL); -} diff --git a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/deprecated/pthread_helper.cc b/app/src/main/cpp/Dobby/external/deprecated/misc-helper/deprecated/pthread_helper.cc deleted file mode 100644 index bc080f69..00000000 --- a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/deprecated/pthread_helper.cc +++ /dev/null @@ -1,129 +0,0 @@ -#include "pthread_helper.h" -#include -#ifdef _WIN32 - -typedef void (*windows_thread)(void *); - -int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) { - uintptr_t handle = _beginthread((windows_thread)start_routine, 0, arg); - thread->handle = (HANDLE)handle; - if (thread->handle == (HANDLE)-1) { - return 1; - } else { - return 0; - } -} - -int pthread_detach(pthread_t thread) { - /* Do nothing */ - return 0; -} - -void pthread_exit(void *value_ptr) { - _endthread(); -} - -int pthread_join(pthread_t thread, void **value_ptr) { - DWORD retvalue = WaitForSingleObject(thread.handle, INFINITE); - if (retvalue == WAIT_OBJECT_0) { - return 0; - } else { - return EINVAL; - } -} - -pthread_t pthread_self(void) { - pthread_t pt; - pt.handle = GetCurrentThread(); - return pt; -} - -int pthread_cancel(pthread_t thread) { - fprintf(stderr, "DO NOT USE THIS FUNCTION. pthread_cancel\n"); - abort(); - return 0; -} - -/* --------------------- MUTEX --------------------*/ - -int pthread_mutexattr_destroy(pthread_mutexattr_t *attr) { - /* do nothing */ - return 0; -} - -int pthread_mutexattr_init(pthread_mutexattr_t *attr) { - /* do nothing */ - return 0; -} - -int pthread_mutex_destroy(pthread_mutex_t *mutex) { - return !CloseHandle(mutex->handle); -} - -int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr) { - HANDLE handle = CreateMutex(NULL, FALSE, NULL); - if (handle != NULL) { - mutex->handle = handle; - return 0; - } else { - return 1; - } -} - -int pthread_mutex_lock(pthread_mutex_t *mutex) { - DWORD retvalue = WaitForSingleObject(mutex->handle, INFINITE); - if (retvalue == WAIT_OBJECT_0) { - return 0; - } else { - return EINVAL; - } -} - -int pthread_mutex_trylock(pthread_mutex_t *mutex) { - DWORD retvalue = WaitForSingleObject(mutex->handle, 0); - if (retvalue == WAIT_OBJECT_0) { - return 0; - } else if (retvalue == WAIT_TIMEOUT) { - return EBUSY; - } else { - return EINVAL; - } -} - -int pthread_mutex_unlock(pthread_mutex_t *mutex) { - return !ReleaseMutex(mutex->handle); -} - -/* ------------------- Thead Specific Data ------------------ */ - -int pthread_key_create(pthread_key_t *key, void (*destr_function)(void *)) { - DWORD dkey = TlsAlloc(); - if (dkey != 0xFFFFFFFF) { - *key = dkey; - return 0; - } else { - return EAGAIN; - } -} - -int pthread_key_delete(pthread_key_t key) { - if (TlsFree(key)) { - return 0; - } else { - return EINVAL; - } -} - -int pthread_setspecific(pthread_key_t key, const void *pointer) { - if (TlsSetValue(key, (LPVOID)pointer)) { - return 0; - } else { - return EINVAL; - } -} - -void *pthread_getspecific(pthread_key_t key) { - return TlsGetValue(key); -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/deprecated/pthread_helper.h b/app/src/main/cpp/Dobby/external/deprecated/misc-helper/deprecated/pthread_helper.h deleted file mode 100644 index 3ed01f63..00000000 --- a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/deprecated/pthread_helper.h +++ /dev/null @@ -1,85 +0,0 @@ -/* - * light weight pthread compatible library for Windows - * (C) 2009 Okamura Yasunobu - * - * WARNING This library does NOT support all future of pthread - * - */ - -#ifndef CROSS_THREAD_H -#define CROSS_THREAD_H - -#ifdef _WIN32 - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include -#include - -typedef struct pthread_tag { - HANDLE handle; -} pthread_t; - -typedef struct pthread_mutex_tag { - HANDLE handle; -} pthread_mutex_t; - -/* stub */ -typedef struct pthread_attr_tag { - int attr; -} pthread_attr_t; - -typedef struct pthread_mutexattr_tag { - int attr; -} pthread_mutexattr_t; - -typedef DWORD pthread_key_t; - -/* ignore attribute */ -int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg); - -/* ignore value_ptr */ -void pthread_exit(void *value_ptr); - -/* ignore value_ptr */ -int pthread_join(pthread_t thread, void **value_ptr); - -pthread_t pthread_self(void); - -/* do nothing */ -int pthread_detach(pthread_t thread); - -/* DO NOT USE */ -int pthread_cancel(pthread_t thread); - -int pthread_mutexattr_destroy(pthread_mutexattr_t *attr); /* do nothing */ -int pthread_mutexattr_init(pthread_mutexattr_t *attr); /* do nothing */ - -int pthread_mutex_destroy(pthread_mutex_t *mutex); -int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr); -int pthread_mutex_lock(pthread_mutex_t *mutex); -int pthread_mutex_trylock(pthread_mutex_t *mutex); -int pthread_mutex_unlock(pthread_mutex_t *mutex); - -/* ignore deconstructor */ -int pthread_key_create(pthread_key_t *key, void (*destr_function)(void *)); -int pthread_key_delete(pthread_key_t key); -int pthread_setspecific(pthread_key_t key, const void *pointer); -void *pthread_getspecific(pthread_key_t key); - -#define sleep(num) Sleep(1000 * (num)) - -#ifdef __cplusplus -} -#endif - -#else -#include -#include -#define Sleep(num) usleep(num * 1000) -#endif - -#endif /* CROSS_THREAD_H */ diff --git a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/deprecated/unistd_helper.h b/app/src/main/cpp/Dobby/external/deprecated/misc-helper/deprecated/unistd_helper.h deleted file mode 100644 index d990fa33..00000000 --- a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/deprecated/unistd_helper.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifdef _WIN32 - -#include -#define open _open -#define read _read -#define O_RDONLY _O_RDONLY -#define O_WRONLY _O_WRONLY -#define O_CREAT _O_CREAT -#define O_TRUNC _O_TRUNC - -#define ssize_t int - -#define STDIN_FILENO 0 -#define STDOUT_FILENO 1 -#define STDERR_FILENO 2 -/* should be in some equivalent to */ -typedef __int8 int8_t; -typedef __int16 int16_t; -typedef __int32 int32_t; -typedef __int64 int64_t; -typedef unsigned __int8 uint8_t; -typedef unsigned __int16 uint16_t; -typedef unsigned __int32 uint32_t; -typedef unsigned __int64 uint64_t; - -#else - -#include - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/format_printer.cc b/app/src/main/cpp/Dobby/external/deprecated/misc-helper/format_printer.cc deleted file mode 100644 index 47c8b8f5..00000000 --- a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/format_printer.cc +++ /dev/null @@ -1,11 +0,0 @@ -#include "misc-helper/format_printer.h" - -void hexdump(const uint8_t *bytes, size_t len) { - size_t ix; - for (ix = 0; ix < len; ++ix) { - if (ix != 0 && !(ix % 16)) - LOG_FUNCTION_IMPL(0, "\n"); - LOG_FUNCTION_IMPL(0, "%02X ", bytes[ix]); - } - LOG_FUNCTION_IMPL(0, "\n"); -} diff --git a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/misc-helper/async_logger.h b/app/src/main/cpp/Dobby/external/deprecated/misc-helper/misc-helper/async_logger.h deleted file mode 100644 index 03e0d4e1..00000000 --- a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/misc-helper/async_logger.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef ASYNC_LOGGER_H -#define ASYNC_LOGGER_H - -void async_logger_print(char *str); - -void async_logger_init(char *logger_path); - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/misc-helper/format_printer.h b/app/src/main/cpp/Dobby/external/deprecated/misc-helper/misc-helper/format_printer.h deleted file mode 100644 index 11239088..00000000 --- a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/misc-helper/format_printer.h +++ /dev/null @@ -1,3 +0,0 @@ -#include "dobby/common.h" - -void hexdump(const uint8_t *bytes, size_t len); \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/misc-helper/variable_cache.h b/app/src/main/cpp/Dobby/external/deprecated/misc-helper/misc-helper/variable_cache.h deleted file mode 100644 index bf490fd8..00000000 --- a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/misc-helper/variable_cache.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef VARIABLE_CACHE_H -#define VARIABLE_CACHE_H - -#include - -#define cache_set stash -void cache_set(const char *name, uint64_t value); - -#define cache_get(x) cache(x) -#define assert_cache(x) (assert(cache(x)), cache(x)) -uint64_t cache_get(const char *name); - -int serialized_to_file(const char *filepath); - -int unserialized_from_file(const char *filepath); - -#endif diff --git a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/variable_cache.c b/app/src/main/cpp/Dobby/external/deprecated/misc-helper/variable_cache.c deleted file mode 100644 index 895a2cbb..00000000 --- a/app/src/main/cpp/Dobby/external/deprecated/misc-helper/variable_cache.c +++ /dev/null @@ -1,118 +0,0 @@ -#include "misc-helper/variable_cache.h" - -#include -#include -#include - -#include -#include "deprecated/unistd_helper.h" - -#include - -typedef struct queue_entry_t { - struct queue_entry *next; - struct queue_entry *prev; -} queue_entry_t; - -/* TODO: add a property or attribute indicate not serialized */ -typedef struct var_entry_t { - queue_entry_t entry_; - char key[128]; - uint64_t value; -} var_entry_t; - -var_entry_t *root = NULL; - -static var_entry_t *cache_get_entry_internal(const char *name) { - var_entry_t *entry; - entry = root; - while (entry != NULL) { - if (strcmp(name, entry->key) == 0) { - return entry; - } - entry = (var_entry_t *)entry->entry_.next; - } - return NULL; -} - -void cache_set(const char *name, uint64_t value) { - var_entry_t *entry = cache_get_entry_internal(name); - if (entry) { - entry->value = value; - return; - } - - entry = (var_entry_t *)malloc(sizeof(var_entry_t)); - strcpy(entry->key, name); - entry->value = value; - - entry->entry_.next = (struct queue_entry *)root; - root = entry; -} - -uint64_t cache_get(const char *name) { - var_entry_t *entry = cache_get_entry_internal(name); - if (entry) { - return entry->value; - } - return 0; -} - -typedef struct entry_block { - int key_length; - int value_length; -} entry_block_t; - -int serialized_to_file(const char *filepath) { - int fd = open(filepath, O_WRONLY | O_CREAT | O_TRUNC, 0660); - if (fd == -1) { - printf("open %s failed: %s\n", filepath, strerror(errno)); - return -1; - } - - var_entry_t *entry; - entry = root; - while (entry != NULL) { - entry_block_t block = {0}; - { - block.key_length = strlen(entry->key) + 1; - block.value_length = sizeof(uint64_t); - write(fd, &block, sizeof(block)); - } - - write(fd, entry->key, block.key_length); - write(fd, &entry->value, block.value_length); - - entry = (var_entry_t *)entry->entry_.next; - } - close(fd); - return 0; -} - -int unserialized_from_file(const char *filepath) { - int fd = open(filepath, O_RDONLY); - if (fd == -1) { - printf("open %s failed: %s\n", filepath, strerror(errno)); - return -1; - } - - entry_block_t block = {0}; - while (read(fd, &block, sizeof(block)) > 0) { - char key[128] = {0}; - uint64_t value = 0; - - read(fd, (void *)&key, block.key_length); - read(fd, (void *)&value, block.value_length); - - { - var_entry_t *entry = (var_entry_t *)malloc(sizeof(var_entry_t)); - strcpy(entry->key, key); - entry->value = value; - - entry->entry_.next = (struct queue_entry *)root; - root = entry; - } - } - - return 0; -} diff --git a/app/src/main/cpp/Dobby/external/logging/CMakeLists.txt b/app/src/main/cpp/Dobby/external/logging/CMakeLists.txt deleted file mode 100644 index aa1a0b72..00000000 --- a/app/src/main/cpp/Dobby/external/logging/CMakeLists.txt +++ /dev/null @@ -1,18 +0,0 @@ -include_directories(.) - -set(SOURCE_FILE_LIST - logging.cc - ) - -if (DOBBY_BUILD_KERNEL_MODE) - set(SOURCE_FILE_LIST - logging_kern.cc - ) -endif () - -get_absolute_path_list(SOURCE_FILE_LIST SOURCE_FILE_LIST_) -set(SOURCE_FILE_LIST ${SOURCE_FILE_LIST_}) - -add_library(logging - ${SOURCE_FILE_LIST} - ) \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/external/logging/logging.cc b/app/src/main/cpp/Dobby/external/logging/logging.cc deleted file mode 100644 index fb57c0ed..00000000 --- a/app/src/main/cpp/Dobby/external/logging/logging.cc +++ /dev/null @@ -1,137 +0,0 @@ -#include "logging/logging.h" - -#include -#include -#include -#include -#include -#include - -#if defined(__linux__) || defined(__APPLE__) -#include -#include -#include -#include -#include -#endif - -#if defined(__APPLE__) -#include -#include -#include -#include -#include -#include "./priv_headers/_simple.h" -#endif - -#if defined(_WIN32) -#define PUBLIC -#else -#define PUBLIC __attribute__((visibility("default"))) -#define INTERNAL __attribute__((visibility("internal"))) -#endif - -#if defined(__ANDROID__) -#include -#endif - -#pragma clang diagnostic ignored "-Wformat" - -Logger *Logger::g_logger = nullptr; - -void Logger::logv(LogLevel level, const char *_fmt, va_list ap) { - if (level < log_level_) - return; - - char fmt_buffer[4096] = {0}; - - if (log_tag_ != nullptr) { - snprintf(fmt_buffer + strlen(fmt_buffer), sizeof(fmt_buffer) - strlen(fmt_buffer), "%s ", log_tag_); - } - - if (enable_time_tag_) { - time_t now = time(NULL); - struct tm *tm = localtime(&now); - snprintf(fmt_buffer + strlen(fmt_buffer), sizeof(fmt_buffer) - strlen(fmt_buffer), "%04d-%02d-%02d %02d:%02d:%02d ", - tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); - } - - snprintf(fmt_buffer + strlen(fmt_buffer), sizeof(fmt_buffer) - strlen(fmt_buffer), "%s\n", _fmt); - - if (enable_syslog_) { -#if defined(__APPLE__) - extern void *_os_log_default; - static void (*os_log_with_args)(void *oslog, char type, const char *format, va_list args, void *ret_addr) = 0; - if (!os_log_with_args) - os_log_with_args = (__typeof(os_log_with_args))dlsym((void *)-2, "os_log_with_args"); - // os_log_with_args(&_os_log_default, 0x10, fmt_buffer, ap, (void *)&os_log_with_args); - vsyslog(LOG_ALERT, fmt_buffer, ap); - - static int _logDescriptor = 0; - if (_logDescriptor == 0) { - _logDescriptor = socket(AF_UNIX, SOCK_DGRAM, 0); - if (_logDescriptor != -1) { - fcntl(_logDescriptor, F_SETFD, FD_CLOEXEC); - struct sockaddr_un addr; - addr.sun_family = AF_UNIX; - strncpy(addr.sun_path, _PATH_LOG, sizeof(addr.sun_path)); - if (connect(_logDescriptor, (struct sockaddr *)&addr, sizeof(addr)) == -1) { - close(_logDescriptor); - _logDescriptor = -1; - ERROR_LOG("Failed to connect to syslogd: %s", strerror(errno)); - } - } - } - if (_logDescriptor > 0) { - vdprintf(_logDescriptor, fmt_buffer, ap); - } -#elif defined(_POSIX_VERSION) - vsyslog(LOG_ERR, fmt_buffer, ap); -#endif - } - - if (log_file_ != nullptr) { - char buffer[0x4000] = {0}; - vsnprintf(buffer, sizeof(buffer) - 1, fmt_buffer, ap); -#if defined(USER_CXX_FILESTREAM) - log_file_stream_->write(buffer, strlen(buffer)); - log_file_stream_->flush(); -#else - fwrite(buffer, strlen(buffer), 1, log_file_stream_); - fflush(log_file_stream_); -#endif - } - - if (1 || !enable_syslog_ && log_file_ == nullptr) { -#if defined(__ANDROID__) - __android_log_vprint(ANDROID_LOG_INFO, NULL, fmt_buffer, ap); -#else - vprintf(fmt_buffer, ap); -#endif - } -} - -#pragma clang diagnostic warning "-Wformat" - -void *logger_create(const char *tag, const char *file, LogLevel level, bool enable_time_tag, bool enable_syslog) { - Logger *logger = new Logger(tag, file, level, enable_time_tag, enable_syslog); - return logger; -} - -void logger_set_options(void *logger, const char *tag, const char *file, LogLevel level, bool enable_time_tag, - bool enable_syslog) { - if (logger == nullptr) { - logger = Logger::Shared(); - } - ((Logger *)logger)->setOptions(tag, file, level, enable_time_tag, enable_syslog); -} - -void logger_log_impl(void *logger, LogLevel level, const char *fmt, ...) { - if (logger == nullptr) { - logger = Logger::Shared(); - } - va_list ap; - va_start(ap, fmt); - ((Logger *)logger)->logv(level, fmt, ap); - va_end(ap); -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/external/logging/logging/check_logging.h b/app/src/main/cpp/Dobby/external/logging/logging/check_logging.h deleted file mode 100644 index 571c2c73..00000000 --- a/app/src/main/cpp/Dobby/external/logging/logging/check_logging.h +++ /dev/null @@ -1,87 +0,0 @@ - -#ifndef CHECK_LOGGING_H_ -#define CHECK_LOGGING_H_ - -#include "logging.h" - -#define CHECK_WITH_MSG(condition, message) \ - do { \ - if (!(condition)) { \ - FATAL_LOG("Check failed: %s.\n", message); \ - } \ - } while (0) -#define CHECK(condition) CHECK_WITH_MSG(condition, #condition) - -#ifdef LOGGING_DEBUG - -#define DCHECK_WITH_MSG(condition, message) \ - do { \ - if (!(condition)) { \ - FATAL_LOG("%s", message); \ - } \ - } while (0) -#define DCHECK(condition) DCHECK_WITH_MSG(condition, #condition) - -// Helper macro for binary operators. -// Don't use this macro directly in your code, use CHECK_EQ et al below. -#define CHECK_OP(name, op, lhs, rhs) \ - do { \ - if (!(lhs op rhs)) { \ - FATAL_LOG(" Check failed: %s.\n", #lhs " " #op " " #rhs); \ - } \ - } while (0) - -#define DCHECK_OP(name, op, lhs, rhs) \ - do { \ - if (!((lhs)op(rhs))) { \ - FATAL_LOG("%s", ""); \ - } \ - } while (0) - -#else - -// Make all CHECK functions discard their log strings to reduce code -// bloat for official release builds. -#define CHECK_OP(name, op, lhs, rhs) \ - do { \ - bool _cond = lhs op rhs; \ - CHECK_WITH_MSG(_cond, #lhs " " #op " " #rhs "\n"); \ - } while (0) - -#define DCHECK_WITH_MSG(condition, msg) void(0); - -#endif - -#define CHECK_EQ(lhs, rhs) CHECK_OP(EQ, ==, lhs, rhs) -#define CHECK_NE(lhs, rhs) CHECK_OP(NE, !=, lhs, rhs) -#define CHECK_LE(lhs, rhs) CHECK_OP(LE, <=, lhs, rhs) -#define CHECK_LT(lhs, rhs) CHECK_OP(LT, <, lhs, rhs) -#define CHECK_GE(lhs, rhs) CHECK_OP(GE, >=, lhs, rhs) -#define CHECK_GT(lhs, rhs) CHECK_OP(GT, >, lhs, rhs) -#define CHECK_NULL(val) CHECK((val) == NULL) -#define CHECK_NOT_NULL(val) CHECK((val) != NULL) - -#ifdef LOGGING_DEBUG -#define DCHECK_EQ(lhs, rhs) DCHECK_OP(EQ, ==, lhs, rhs) -#define DCHECK_NE(lhs, rhs) DCHECK_OP(NE, !=, lhs, rhs) -#define DCHECK_GT(lhs, rhs) DCHECK_OP(GT, >, lhs, rhs) -#define DCHECK_GE(lhs, rhs) DCHECK_OP(GE, >=, lhs, rhs) -#define DCHECK_LT(lhs, rhs) DCHECK_OP(LT, <, lhs, rhs) -#define DCHECK_LE(lhs, rhs) DCHECK_OP(LE, <=, lhs, rhs) -#define DCHECK_NULL(val) DCHECK((val) == nullptr) -#define DCHECK_NOT_NULL(val) DCHECK((val) != nullptr) -#define DCHECK_IMPLIES(lhs, rhs) DCHECK_WITH_MSG(!(lhs) || (rhs), #lhs " implies " #rhs) -#else -#define DCHECK(condition) ((void)0) -#define DCHECK_EQ(v1, v2) ((void)0) -#define DCHECK_NE(v1, v2) ((void)0) -#define DCHECK_GT(v1, v2) ((void)0) -#define DCHECK_GE(v1, v2) ((void)0) -#define DCHECK_LT(v1, v2) ((void)0) -#define DCHECK_LE(v1, v2) ((void)0) -#define DCHECK_NULL(val) ((void)0) -#define DCHECK_NOT_NULL(val) ((void)0) -#define DCHECK_IMPLIES(v1, v2) ((void)0) -#endif - -#endif diff --git a/app/src/main/cpp/Dobby/external/logging/logging/logging.h b/app/src/main/cpp/Dobby/external/logging/logging/logging.h deleted file mode 100644 index d53b7ac2..00000000 --- a/app/src/main/cpp/Dobby/external/logging/logging/logging.h +++ /dev/null @@ -1,202 +0,0 @@ -#pragma once - -#include -#include -#include -#include - -#define LOG_TAG NULL - -typedef enum { - LOG_LEVEL_DEBUG = 0, - LOG_LEVEL_INFO = 1, - LOG_LEVEL_WARN = 2, - LOG_LEVEL_ERROR = 3, - LOG_LEVEL_FATAL = 4 -} LogLevel; - -#ifdef __cplusplus - -#if defined(USE_CXX_FILESTREAM) -#include -#endif - -class Logger { -public: - LogLevel log_level_; - - const char *log_tag_; - - const char *log_file_; -#if defined(USE_CXX_FILESTREAM) - std::fstream *log_file_stream_; -#else - FILE *log_file_stream_; -#endif - - bool enable_time_tag_; - bool enable_syslog_; - - static Logger *g_logger; - static Logger *Shared() { - if (g_logger == nullptr) { - g_logger = new Logger(); - } - return g_logger; - } - - Logger() { - log_tag_ = nullptr; - log_file_ = nullptr; - log_level_ = LOG_LEVEL_DEBUG; - enable_time_tag_ = false; - enable_syslog_ = false; - } - - Logger(const char *tag, const char *file, LogLevel level, bool enable_time_tag, bool enable_syslog) { - setTag(tag); - setLogFile(file); - setLogLevel(level); - enable_time_tag_ = enable_time_tag; - enable_syslog_ = enable_syslog; - } - - void setOptions(const char *tag, const char *file, LogLevel level, bool enable_time_tag, bool enable_syslog) { - if (tag) - setTag(tag); - if (file) - setLogFile(file); - setLogLevel(level); - enable_time_tag_ = enable_time_tag; - enable_syslog_ = enable_syslog; - } - - void setTag(const char *tag) { - log_tag_ = tag; - } - - void setLogFile(const char *file) { - log_file_ = file; -#if defined(USE_CXX_FILESTREAM) - log_file_stream_ = new std::fstream(); - log_file_stream_->open(log_file_, std::ios::out | std::ios::app); -#else - log_file_stream_ = fopen(log_file_, "a"); -#endif - } - - void setLogLevel(LogLevel level) { - log_level_ = level; - } - - void enableTimeTag() { - enable_time_tag_ = true; - } - - void enableSyslog() { - enable_syslog_ = true; - } - - void logv(LogLevel level, const char *fmt, va_list ap); - - void log(LogLevel level, const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - logv(level, fmt, ap); - va_end(ap); - } - - void debug(const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - logv(LOG_LEVEL_DEBUG, fmt, ap); - va_end(ap); - } - - void info(const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - logv(LOG_LEVEL_INFO, fmt, ap); - va_end(ap); - } - - void warn(const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - logv(LOG_LEVEL_WARN, fmt, ap); - va_end(ap); - } - - void error(const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - logv(LOG_LEVEL_ERROR, fmt, ap); - va_end(ap); - } - - void fatal(const char *fmt, ...) { - va_list ap; - va_start(ap, fmt); - logv(LOG_LEVEL_FATAL, fmt, ap); - va_end(ap); - } -}; - -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined(DOBBY_LOGGING_DISABLE) -#define LOG_FUNCTION_IMPL(...) -#else -#if !defined(LOG_FUNCTION_IMPL) -#define LOG_FUNCTION_IMPL logger_log_impl -#endif -#endif - -void *logger_create(const char *tag, const char *file, LogLevel level, bool enable_time_tag, bool enable_syslog); -void logger_set_options(void *logger, const char *tag, const char *file, LogLevel level, bool enable_time_tag, - bool enable_syslog); -void logger_log_impl(void *logger, LogLevel level, const char *fmt, ...); - -#ifdef __cplusplus -} -#endif - -#define LOG(level, fmt, ...) \ - do { \ - if (LOG_TAG) \ - LOG_FUNCTION_IMPL(NULL, level, "[%s] " fmt, LOG_TAG, ##__VA_ARGS__); \ - else \ - LOG_FUNCTION_IMPL(NULL, level, fmt, ##__VA_ARGS__); \ - } while (0) - -#define DEBUG_LOG(fmt, ...) \ - do { \ - LOG(LOG_LEVEL_DEBUG, fmt, ##__VA_ARGS__); \ - } while (0) - -#define INFO_LOG(fmt, ...) \ - do { \ - LOG(LOG_LEVEL_INFO, fmt, ##__VA_ARGS__); \ - } while (0) - -#define WARN_LOG(fmt, ...) \ - do { \ - LOG(LOG_LEVEL_WARN, fmt, ##__VA_ARGS__); \ - } while (0) - -#define ERROR_LOG(fmt, ...) \ - do { \ - LOG(LOG_LEVEL_ERROR, "[!] [%s:%d:%s]" fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__); \ - } while (0) - -#define FATAL_LOG(fmt, ...) \ - do { \ - LOG(LOG_LEVEL_FATAL, "[!] [%s:%d:%s]" fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__); \ - } while (0) - -#define UNIMPLEMENTED() FATAL_LOG("%s\n", "unimplemented code!!!") -#define UNREACHABLE() FATAL_LOG("%s\n", "unreachable code!!!") \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/external/logging/logging_kern.cc b/app/src/main/cpp/Dobby/external/logging/logging_kern.cc deleted file mode 100644 index e69de29b..00000000 diff --git a/app/src/main/cpp/Dobby/external/logging/priv_headers/_simple.h b/app/src/main/cpp/Dobby/external/logging/priv_headers/_simple.h deleted file mode 100644 index 2ae83848..00000000 --- a/app/src/main/cpp/Dobby/external/logging/priv_headers/_simple.h +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (c) 2006, 2010, 2013 Apple Inc. All rights reserved. - * - * @APPLE_LICENSE_HEADER_START@ - * - * This file contains Original Code and/or Modifications of Original Code - * as defined in and that are subject to the Apple Public Source License - * Version 2.0 (the 'License'). You may not use this file except in - * compliance with the License. Please obtain a copy of the License at - * http://www.opensource.apple.com/apsl/ and read it before using this - * file. - * - * The Original Code and all software distributed under the License are - * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER - * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, - * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. - * Please see the License for the specific language governing rights and - * limitations under the License. - * - * @APPLE_LICENSE_HEADER_END@ - */ - -#ifndef _SYSTEM_SIMPLE_H_ -#define _SYSTEM_SIMPLE_H_ - -#include -#include - -#include - -typedef void *_SIMPLE_STRING; -typedef const char *_esc_func(unsigned char); - -__BEGIN_DECLS -/* - * A simplified vfprintf variant. The format string is interpreted with - * arguments from the va_list, and the results are written to the given - * file descriptor. - */ -void _simple_vdprintf(int __fd, const char *__fmt, va_list __ap) __printflike(2, 0); - -/* - * A simplified fprintf variant. The format string is interpreted with - * arguments from the variable argument list, and the results are written - * to the given file descriptor. - */ -void _simple_dprintf(int __fd, const char *__fmt, ...) __printflike(2, 3); - -/* - * A simplified string allocate routine. Pass the opaque pointer to structure - * to _simple_*sprintf() routines. Use _simple_string() to retrieve the - * current string (the string is guaranteed to be null terminated only on - * the call to _simple_string()). Use _simple_sfree() to free the structure - * and string memory. - */ -_SIMPLE_STRING _simple_salloc(void); - -/* - * The format string is interpreted with arguments from the va_list, and the - * results are appended to the string maintained by the opaque structure, as - * returned by a previous call to _simple_salloc(). Non-zero is returned on - * out-of-memory error. - */ -int _simple_vsprintf(_SIMPLE_STRING __b, const char *__fmt, va_list __ap) __printflike(2, 0); - -/* - * The format string is interpreted with arguments from the variable argument - * list, and the results are appended to the string maintained by the opaque - * structure, as returned by a previous call to _simple_salloc(). Non-zero is - * returned on out-of-memory error. - */ -int _simple_sprintf(_SIMPLE_STRING __b, const char *__fmt, ...) __printflike(2, 3); - -/* - * Like _simple_vsprintf(), except __esc is a function to call on each - * character; the function returns NULL if the character should be passed - * as is, otherwise, the returned character string is used instead. - */ -int _simple_vesprintf(_SIMPLE_STRING __b, _esc_func __esc, const char *__fmt, va_list __ap) __printflike(3, 0); - -/* - * Like _simple_sprintf(), except __esc is a function to call on each - * character; the function returns NULL if the character should be passed - * as is, otherwise, the returned character string is used instead. - */ -int _simple_esprintf(_SIMPLE_STRING __b, _esc_func __esc, const char *__fmt, ...) __printflike(3, 4); - -/* - * Return the null terminated string from the opaque structure, as returned - * by a previous call to _simple_salloc(). - */ -char *_simple_string(_SIMPLE_STRING __b); - -/* - * Reposition the pointer to the first null in the buffer. After a call to - * _simple_string, the buffer can be modified, and shrunk. - */ -void _simple_sresize(_SIMPLE_STRING __b); - -/* - * Append the null-terminated string to the string associated with the opaque - * structure. Non-zero is returned on out-of-memory error. - */ -int _simple_sappend(_SIMPLE_STRING __b, const char *__str); - -/* - * Like _simple_sappend(), except __esc is a function to call on each - * character; the function returns NULL if the character should be passed - * as is, otherwise, the returned character string is used instead. - */ -int _simple_esappend(_SIMPLE_STRING __b, _esc_func __esc, const char *__str); - -/* - * Write the string associated with the opaque structure to the file descriptor. - */ -void _simple_put(_SIMPLE_STRING __b, int __fd); - -/* - * Write the string associated with the opaque structure and a trailing newline, - * to the file descriptor. - */ -void _simple_putline(_SIMPLE_STRING __b, int __fd); - -/* - * Free the opaque structure, and the associated string. - */ -void _simple_sfree(_SIMPLE_STRING __b); - -/* - * Simplified ASL log interface; does not use malloc. Unfortunately, this - * requires knowledge of the format used by ASL. - */ -#ifndef ASL_LEVEL_DEBUG -#define ASL_LEVEL_EMERG 0 -#define ASL_LEVEL_ALERT 1 -#define ASL_LEVEL_CRIT 2 -#define ASL_LEVEL_ERR 3 -#define ASL_LEVEL_WARNING 4 -#define ASL_LEVEL_NOTICE 5 -#define ASL_LEVEL_INFO 6 -#define ASL_LEVEL_DEBUG 7 -#endif - -void _simple_asl_log(int __level, const char *__facility, const char *__message); -void _simple_asl_log_prog(int level, const char *facility, const char *message, const char *progname); - -__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0) -_SIMPLE_STRING _simple_asl_msg_new(void); - -__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0) -void _simple_asl_msg_set(_SIMPLE_STRING __b, const char *__key, const char *__val); - -__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0) -void _simple_asl_send(_SIMPLE_STRING __b); - -__OSX_AVAILABLE_STARTING(__MAC_10_9,__IPHONE_7_0) -const char *_simple_getenv(const char *envp[], const char *var); - -__END_DECLS - -#endif /* _SYSTEM_SIMPLE_H_ */ diff --git a/app/src/main/cpp/Dobby/external/osbase/CMakeLists.txt b/app/src/main/cpp/Dobby/external/osbase/CMakeLists.txt deleted file mode 100644 index ef7ce409..00000000 --- a/app/src/main/cpp/Dobby/external/osbase/CMakeLists.txt +++ /dev/null @@ -1,3 +0,0 @@ -add_library(osbase STATIC - ${PROJECT_SOURCE_DIR}/source/Backend/UserMode/UnifiedInterface/platform-posix.cc - ) \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/include/dobby.h b/app/src/main/cpp/Dobby/include/dobby.h deleted file mode 100644 index 745b7986..00000000 --- a/app/src/main/cpp/Dobby/include/dobby.h +++ /dev/null @@ -1,152 +0,0 @@ -#ifndef dobby_h -#define dobby_h - -#ifdef __cplusplus -extern "C" { -#endif - -#include -#include - -typedef uintptr_t addr_t; -typedef uint32_t addr32_t; -typedef uint64_t addr64_t; - -typedef void *dobby_dummy_func_t; -typedef void *asm_func_t; - -#if defined(__arm__) -typedef struct { - uint32_t dummy_0; - uint32_t dummy_1; - - uint32_t dummy_2; - uint32_t sp; - - union { - uint32_t r[13]; - struct { - uint32_t r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12; - } regs; - } general; - - uint32_t lr; -} DobbyRegisterContext; -#elif defined(__arm64__) || defined(__aarch64__) -#define ARM64_TMP_REG_NDX_0 17 - -typedef union _FPReg { - __int128_t q; - struct { - double d1; - double d2; - } d; - struct { - float f1; - float f2; - float f3; - float f4; - } f; -} FPReg; - -// register context -typedef struct { - uint64_t dmmpy_0; // dummy placeholder - uint64_t sp; - - uint64_t dmmpy_1; // dummy placeholder - union { - uint64_t x[29]; - struct { - uint64_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15, x16, x17, x18, x19, x20, x21, x22, - x23, x24, x25, x26, x27, x28; - } regs; - } general; - - uint64_t fp; - uint64_t lr; - - union { - FPReg q[32]; - struct { - FPReg q0, q1, q2, q3, q4, q5, q6, q7; - // [!!! READ ME !!!] - // for Arm64, can't access q8 - q31, unless you enable full floating-point register pack - FPReg q8, q9, q10, q11, q12, q13, q14, q15, q16, q17, q18, q19, q20, q21, q22, q23, q24, q25, q26, q27, q28, q29, - q30, q31; - } regs; - } floating; -} DobbyRegisterContext; -#elif defined(_M_IX86) || defined(__i386__) -typedef struct _RegisterContext { - uint32_t dummy_0; - uint32_t esp; - - uint32_t dummy_1; - uint32_t flags; - - union { - struct { - uint32_t eax, ebx, ecx, edx, ebp, esp, edi, esi; - } regs; - } general; - -} DobbyRegisterContext; -#elif defined(_M_X64) || defined(__x86_64__) -typedef struct { - uint64_t dummy_0; - uint64_t rsp; - - union { - struct { - uint64_t rax, rbx, rcx, rdx, rbp, rsp, rdi, rsi, r8, r9, r10, r11, r12, r13, r14, r15; - } regs; - } general; - - uint64_t dummy_1; - uint64_t flags; -} DobbyRegisterContext; -#endif - -#define install_hook_name(name, fn_ret_t, fn_args_t...) \ - static fn_ret_t fake_##name(fn_args_t); \ - static fn_ret_t (*orig_##name)(fn_args_t); \ - /* __attribute__((constructor)) */ static void install_hook_##name(void *sym_addr) { \ - DobbyHook(sym_addr, (dobby_dummy_func_t)fake_##name, (dobby_dummy_func_t *)&orig_##name); \ - return; \ - } \ - fn_ret_t fake_##name(fn_args_t) - -// memory code patch -int DobbyCodePatch(void *address, uint8_t *buffer, uint32_t buffer_size); - -// function inline hook -int DobbyHook(void *address, dobby_dummy_func_t replace_func, dobby_dummy_func_t *origin_func); - -// dynamic binary instruction instrument -// for Arm64, can't access q8 - q31, unless enable full floating-point register pack -typedef void (*dobby_instrument_callback_t)(void *address, DobbyRegisterContext *ctx); -int DobbyInstrument(void *address, dobby_instrument_callback_t pre_handler); - -// destroy and restore code patch -int DobbyDestroy(void *address); - -const char *DobbyGetVersion(); - -// symbol resolver -void *DobbySymbolResolver(const char *image_name, const char *symbol_name); - -// import table replace -int DobbyImportTableReplace(char *image_name, char *symbol_name, dobby_dummy_func_t fake_func, - dobby_dummy_func_t *orig_func); - -// for arm, Arm64, try use b xxx instead of ldr absolute indirect branch -// for x86, x64, always use absolute indirect jump -void dobby_enable_near_branch_trampoline(); -void dobby_disable_near_branch_trampoline(); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/app/src/main/cpp/Dobby/scripts/Dockerfile b/app/src/main/cpp/Dobby/scripts/Dockerfile deleted file mode 100644 index 149f448c..00000000 --- a/app/src/main/cpp/Dobby/scripts/Dockerfile +++ /dev/null @@ -1,10 +0,0 @@ -FROM ubuntu:focal - -ARG DEBIAN_FRONTEND='noninteractive' - -RUN apt-key adv --keyserver 'keyserver.ubuntu.com' --recv-key 'C99B11DEB97541F0' && - apt-add-repository -y -u 'https://cli.github.com/packages' && - apt-add-repository 'deb https://apt.kitware.com/ubuntu/ focal main' - -ADD setup_linux_cross_compile.sh /root/setup_linux_cross_compile.sh -RUN sh /root/setup_linux_cross_compile.sh diff --git a/app/src/main/cpp/Dobby/scripts/platform_builder.py b/app/src/main/cpp/Dobby/scripts/platform_builder.py deleted file mode 100644 index b31b4c95..00000000 --- a/app/src/main/cpp/Dobby/scripts/platform_builder.py +++ /dev/null @@ -1,242 +0,0 @@ -import os -import pipes -import re -import shutil -import subprocess -import sys -import logging - -import argparse - -platforms = { - "macos": ["x86_64", "arm64", "arm64e"], - "iphoneos": ["arm64", "arm64e"], - "linux": ["x86", "x86_64", "arm", "arm64"], - "android": ["x86", "x86_64", "armeabi-v7a", "arm64-v8a"] -} - - -class PlatformBuilder(object): - cmake_args = list() - cmake_build_type = "Release" - cmake_build_verbose = False - cmake_build_dir = "" - - library_build_type = "static" - - project_dir = "" - output_dir = "" - - shared_output_name = "" - static_output_name = "" - - platform = "" - arch = "" - - def __init__(self, project_dir, library_build_type, platform, arch): - self.project_dir = project_dir - self.library_build_type = library_build_type - self.platform = platform - self.arch = arch - - self.cmake_build_dir = f"{self.project_dir}/build/cmake-build-{platform}-{arch}" - self.output_dir = f"{self.project_dir}/build/{platform}/{arch}" - - self.cmake = "cmake" if PlatformBuilder.cmake_dir is None else f"{PlatformBuilder.cmake_dir}/bin/cmake" - self.clang = "clang" if PlatformBuilder.llvm_dir is None else f"{PlatformBuilder.llvm_dir}/bin/clang" - self.clangxx = "clang++" if PlatformBuilder.llvm_dir is None else f"{PlatformBuilder.llvm_dir}/bin/clang++" - - self.setup_common_args() - - def cmake_generate_build_system(self): - cmake_cmd_options = ["-S {}".format(self.project_dir), "-B {}".format(self.cmake_build_dir)] - cmd = [f"{self.cmake}"] + cmake_cmd_options + self.cmake_args - # subprocess.run(cmd, check=True) - cmd_line = " ".join(cmd) - print(cmd_line) - os.system(cmd_line) - - def setup_common_args(self): - self.cmake_args += [f"-DCMAKE_C_COMPILER={self.clang}", f"-DCMAKE_CXX_COMPILER={self.clangxx}"] - - self.cmake_args += ["-DCMAKE_BUILD_TYPE={}".format(self.cmake_build_type)] - - if self.library_build_type == "shared": - pass - # self.cmake_args += ["-DDOBBY_GENERATE_SHARED=ON"] - elif self.library_build_type == "static": - pass - # self.cmake_args += ["-DDOBBY_GENERATE_SHARED=OFF"] - - def build(self): - subprocess.run(["mkdir", "-p", "{}".format(self.output_dir)], check=True) - self.cmake_generate_build_system() - - subprocess.run("cmake --build . --clean-first --target dobby --target dobby_static -- -j8", cwd=self.cmake_build_dir, shell=True, check=True) - - os.system(f"mkdir -p {self.output_dir}") - os.system(f"cp {self.cmake_build_dir}/{self.shared_output_name} {self.output_dir}") - os.system(f"cp {self.cmake_build_dir}/{self.static_output_name} {self.output_dir}") - - -class WindowsPlatformBuilder(PlatformBuilder): - - def __init__(self, project_dir, library_build_type, platform, arch): - super().__init__(project_dir, library_build_type, platform, arch) - - if self.library_build_type == "shared": - self.output_name = "libdobby.dll" - else: - self.output_name = "libdobby.lib" - - triples = { - "x86": "i686-pc-windows-msvc", - "x64": "x86_64-pc-windows-msvc", - # "arm": "arm-pc-windows-msvc", - "arm64": "arm64-pc-windows-msvc", - } - - # self.cmake_args += ["--target {}".format(triples[arch])] - self.cmake_args += [ - "-DCMAKE_SYSTEM_PROCESSOR={}".format(arch), - ] - - -class LinuxPlatformBuilder(PlatformBuilder): - - def __init__(self, project_dir, library_build_type, arch): - super().__init__(project_dir, library_build_type, "linux", arch) - - self.shared_output_name = "libdobby.so" - self.static_output_name = "libdobby.a" - - targets = { - "x86": "i686-linux-gnu", - "x86_64": "x86_64-linux-gnu", - "arm": "arm-linux-gnueabi", - "aarch64": "aarch64-linux-gnu", - } - - # self.cmake_args += ["--target={}".format(targets[arch])] - self.cmake_args += [ - "-DCMAKE_SYSTEM_NAME=Linux", - "-DCMAKE_SYSTEM_PROCESSOR={}".format(arch), - ] - - -class AndroidPlatformBuilder(PlatformBuilder): - - def __init__(self, android_nkd_dir, project_dir, library_build_type, arch): - super().__init__(project_dir, library_build_type, "android", arch) - - self.shared_output_name = "libdobby.so" - self.static_output_name = "libdobby.a" - - android_api_level = 21 - if arch == "armeabi-v7a" or arch == "x86": - android_api_level = 19 - - self.cmake_args += [ - "-DCMAKE_SYSTEM_NAME=Android", f"-DCMAKE_ANDROID_NDK={android_nkd_dir}", f"-DCMAKE_ANDROID_ARCH_ABI={arch}", - f"-DCMAKE_SYSTEM_VERSION={android_api_level}" - ] - - -class DarwinPlatformBuilder(PlatformBuilder): - - def __init__(self, project_dir, library_build_type, platform, arch): - super().__init__(project_dir, library_build_type, platform, arch) - - self.cmake_args += [ - "-DCMAKE_OSX_ARCHITECTURES={}".format(arch), - "-DCMAKE_SYSTEM_PROCESSOR={}".format(arch), - ] - - if platform == "macos": - self.cmake_args += ["-DCMAKE_SYSTEM_NAME=Darwin"] - elif platform == "iphoneos": - self.cmake_args += ["-DCMAKE_SYSTEM_NAME=iOS", "-DCMAKE_OSX_DEPLOYMENT_TARGET=9.3"] - - self.shared_output_name = "libdobby.dylib" - self.static_output_name = "libdobby.a" - - @classmethod - def lipo_create_fat(cls, project_dir, platform, output_name): - files = list() - archs = platforms[platform] - for arch in archs: - file = f"{project_dir}/build/{platform}/{arch}/{output_name}" - files.append(file) - - fat_output_dir = f"{project_dir}/build/{platform}/universal" - subprocess.run(["mkdir", "-p", "{}".format(fat_output_dir)], check=True) - cmd = ["lipo", "-create"] + files + ["-output", f"{fat_output_dir}/{output_name}"] - subprocess.run(cmd, check=True) - - -if __name__ == "__main__": - parser = argparse.ArgumentParser() - parser.add_argument("--platform", type=str, required=True) - parser.add_argument("--arch", type=str, required=True) - parser.add_argument("--library_build_type", type=str, default="static") - parser.add_argument("--android_ndk_dir", type=str) - parser.add_argument("--cmake_dir", type=str) - parser.add_argument("--llvm_dir", type=str) - args = parser.parse_args() - - logging.basicConfig(level=logging.INFO, format="%(asctime)s - %(levelname)s - %(message)s") - - platform = args.platform - arch = args.arch - library_build_type = args.library_build_type - - PlatformBuilder.cmake_dir = args.cmake_dir - PlatformBuilder.llvm_dir = args.llvm_dir - - project_dir = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) - logging.info("project dir: {}".format(project_dir)) - if not os.path.exists(f"{project_dir}/CMakeLists.txt"): - logging.error("Please run this script in Dobby project root directory") - sys.exit(1) - - if platform not in platforms: - logging.error("invalid platform {}".format(platform)) - sys.exit(-1) - - if arch != "all" and arch not in platforms[platform]: - logging.error("invalid arch {} for platform {}".format(arch, platform)) - sys.exit(-1) - - if platform == "android": - if args.android_ndk_dir is None: - logging.error("ndk dir is required for android platform") - sys.exit(-1) - - archs = list() - if arch == "all": - archs = platforms[platform] - else: - archs.append(arch) - logging.info("build platform: {}, archs: {}".format(platform, archs)) - - builder: PlatformBuilder = None - for arch_ in archs: - if platform == "macos": - builder = DarwinPlatformBuilder(project_dir, library_build_type, platform, arch_) - elif platform == "iphoneos": - builder = DarwinPlatformBuilder(project_dir, library_build_type, platform, arch_) - elif platform == "android": - builder = AndroidPlatformBuilder(args.android_ndk_dir, project_dir, library_build_type, arch_) - elif platform == "linux": - builder = LinuxPlatformBuilder(project_dir, library_build_type, arch_) - else: - logging.error("invalid platform {}".format(platform)) - sys.exit(-1) - logging.info( - f"build platform: {platform}, arch: {arch_}, cmake_build_dir: {builder.cmake_build_dir}, output_dir: {builder.output_dir}" - ) - builder.build() - - if platform in ["iphoneos", "macos"] and arch == "all": - DarwinPlatformBuilder.lipo_create_fat(project_dir, platform, builder.shared_output_name) - DarwinPlatformBuilder.lipo_create_fat(project_dir, platform, builder.static_output_name) diff --git a/app/src/main/cpp/Dobby/scripts/setup_linux_cross_compile.sh b/app/src/main/cpp/Dobby/scripts/setup_linux_cross_compile.sh deleted file mode 100644 index e2034b62..00000000 --- a/app/src/main/cpp/Dobby/scripts/setup_linux_cross_compile.sh +++ /dev/null @@ -1,61 +0,0 @@ -#!/bin/sh - -set -x -set -e - -# sudo dpkg --add-architecture armhf -# sudo dpkg --add-architecture i386 -# sudo dpkg --add-architecture arm64 -# sudo apt-get -y update -# sudo apt-get -y dist-upgrade -# sudo apt-get -y install git build-essential libssl-dev pkg-config unzip gcc-multilib -# sudo apt-get -y install libc6-armhf-cross libc6-dev-armhf-cross gcc-arm-linux-gnueabihf libssl-dev:armhf -# sudo apt-get -y install libc6-i386-cross libc6-dev-i386-cross gcc-i686-linux-gnu libssl-dev:i386 -# sudo apt-get -y install libc6-arm64-cross libc6-dev-arm64-cross gcc-aarch64-linux-gnu libssl-dev:arm64 - -sudo apt-get -y update -sudo apt-get -y install aptitude -sudo apt-get -f -y install \ - apt-utils \ - binutils \ - build-essential \ - curl \ - wget \ - unzip \ - gcc-multilib \ - g++-multilib \ - make \ - zsh - -sudo apt-get -f -y install gcc g++ libc6-dev -sudo apt-get -f -y install gcc-i686-linux-gnu g++-i686-linux-gnu -sudo apt-get -f -y install gcc-arm-linux-gnueabihf g++-arm-linux-gnueabihf -sudo apt-get -f -y install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu - -mkdir -p ~/opt - -cd ~/opt -CMAKE_VERSION=3.25.2 -CMAKE_DOWNLOAD_PACKAGE=cmake-$CMAKE_VERSION-linux-x86_64 -wget https://github.com/Kitware/CMake/releases/download/v$CMAKE_VERSION/$CMAKE_DOWNLOAD_PACKAGE.tar.gz && - tar -zxf $CMAKE_DOWNLOAD_PACKAGE.tar.gz >/dev/null && - mv $CMAKE_DOWNLOAD_PACKAGE cmake-$CMAKE_VERSION -CMAKE_HOME=~/opt/cmake-$CMAKE_VERSION - -cd ~/opt -LLVM_VERSION=15.0.6 -LLVM_DOWNLOAD_PACKAGE=clang+llvm-$LLVM_VERSION-x86_64-linux-gnu-ubuntu-18.04 -wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/$LLVM_DOWNLOAD_PACKAGE.tar.xz && - tar -xf $LLVM_DOWNLOAD_PACKAGE.tar.xz >/dev/null && - mv $LLVM_DOWNLOAD_PACKAGE llvm-$LLVM_VERSION -LLVM_HOME=~/opt/llvm-$LLVM_VERSION - -cd ~/opt -NDK_VERSION=r25b -NDK_DOWNLOAD_PACKAGE=android-ndk-$NDK_VERSION-linux -NDK_DOWNLOAD_UNZIP_PACKAGE=android-ndk-$NDK_VERSION -wget https://dl.google.com/android/repository/$NDK_DOWNLOAD_PACKAGE.zip && - unzip -q $NDK_DOWNLOAD_PACKAGE.zip >/dev/null && - mv $NDK_DOWNLOAD_UNZIP_PACKAGE ndk-$NDK_VERSION && - rm $NDK_DOWNLOAD_PACKAGE.zip -ANDROID_NDK_HOME=~/opt/android-ndk-$NDK_VERSION diff --git a/app/src/main/cpp/Dobby/scripts/setup_macos_cross_compile.sh b/app/src/main/cpp/Dobby/scripts/setup_macos_cross_compile.sh deleted file mode 100644 index fb904b05..00000000 --- a/app/src/main/cpp/Dobby/scripts/setup_macos_cross_compile.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh - -set -x -set -e - -mkdir -p ~/opt - -cd ~/opt -CMAKE_VERSION=3.25.2 -CMAKE_DOWNLOAD_PACKAGE=cmake-$CMAKE_VERSION-macos-universal -wget https://github.com/Kitware/CMake/releases/download/v$CMAKE_VERSION/$CMAKE_DOWNLOAD_PACKAGE.tar.gz && - tar -zxf $CMAKE_DOWNLOAD_PACKAGE.tar.gz >/dev/null && - mv $CMAKE_DOWNLOAD_PACKAGE cmake-$CMAKE_VERSION -CMAKE_HOME=~/opt/cmake-$CMAKE_VERSION - -cd ~/opt -LLVM_VERSION=15.0.6 -LLVM_DOWNLOAD_PACKAGE=clang+llvm-$LLVM_VERSION-x86_64-apple-darwin -wget https://github.com/llvm/llvm-project/releases/download/llvmorg-$LLVM_VERSION/$LLVM_DOWNLOAD_PACKAGE.tar.xz && - tar -xf $LLVM_DOWNLOAD_PACKAGE.tar.xz >/dev/null && - mv $LLVM_DOWNLOAD_PACKAGE llvm-$LLVM_VERSION -LLVM_HOME=~/opt/llvm-$LLVM_VERSION diff --git a/app/src/main/cpp/Dobby/source/Backend/KernelMode/ExecMemory/clear-cache-tool-all.c b/app/src/main/cpp/Dobby/source/Backend/KernelMode/ExecMemory/clear-cache-tool-all.c deleted file mode 100644 index 495257f8..00000000 --- a/app/src/main/cpp/Dobby/source/Backend/KernelMode/ExecMemory/clear-cache-tool-all.c +++ /dev/null @@ -1,3 +0,0 @@ -void ClearCache(void *start, void *end) { - return; -} diff --git a/app/src/main/cpp/Dobby/source/Backend/KernelMode/ExecMemory/code-patch-tool-darwin.cc b/app/src/main/cpp/Dobby/source/Backend/KernelMode/ExecMemory/code-patch-tool-darwin.cc deleted file mode 100644 index e69de29b..00000000 diff --git a/app/src/main/cpp/Dobby/source/Backend/KernelMode/PlatformUtil/Darwin/ProcessRuntimeUtility.cc b/app/src/main/cpp/Dobby/source/Backend/KernelMode/PlatformUtil/Darwin/ProcessRuntimeUtility.cc deleted file mode 100644 index e69de29b..00000000 diff --git a/app/src/main/cpp/Dobby/source/Backend/KernelMode/UnifiedInterface/platform-darwin.cc b/app/src/main/cpp/Dobby/source/Backend/KernelMode/UnifiedInterface/platform-darwin.cc deleted file mode 100644 index e69de29b..00000000 diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/clear-cache-tool-all.c b/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/clear-cache-tool-all.c deleted file mode 100644 index 413ef48f..00000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/clear-cache-tool-all.c +++ /dev/null @@ -1,145 +0,0 @@ -//===-- clear_cache.c - Implement __clear_cache ---------------------------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include -#include -#include - -#if __APPLE__ -#include -#endif - -#if defined(_WIN32) -// Forward declare Win32 APIs since the GCC mode driver does not handle the -// newer SDKs as well as needed. -uint32_t FlushInstructionCache(uintptr_t hProcess, void *lpBaseAddress, uintptr_t dwSize); -uintptr_t GetCurrentProcess(void); -#endif - -// The compiler generates calls to __clear_cache() when creating -// trampoline functions on the stack for use with nested functions. -// It is expected to invalidate the instruction cache for the -// specified range. - -void _clear_cache(void *start, void *end) { -#if __i386__ || __x86_64__ || defined(_M_IX86) || defined(_M_X64) -// Intel processors have a unified instruction and data cache -// so there is nothing to do -#elif defined(_WIN32) && (defined(__arm__) || defined(__aarch64__)) - FlushInstructionCache(GetCurrentProcess(), start, end - start); -#elif defined(__arm__) && !defined(__APPLE__) -#if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) - struct arm_sync_icache_args arg; - - arg.addr = (uintptr_t)start; - arg.len = (uintptr_t)end - (uintptr_t)start; - - sysarch(ARM_SYNC_ICACHE, &arg); -#elif defined(__linux__) -// We used to include asm/unistd.h for the __ARM_NR_cacheflush define, but -// it also brought many other unused defines, as well as a dependency on -// kernel headers to be installed. -// -// This value is stable at least since Linux 3.13 and should remain so for -// compatibility reasons, warranting it's re-definition here. -#define __ARM_NR_cacheflush 0x0f0002 - register int start_reg __asm("r0") = (int)(intptr_t)start; - const register int end_reg __asm("r1") = (int)(intptr_t)end; - const register int flags __asm("r2") = 0; - const register int syscall_nr __asm("r7") = __ARM_NR_cacheflush; - __asm __volatile("svc 0x0" : "=r"(start_reg) : "r"(syscall_nr), "r"(start_reg), "r"(end_reg), "r"(flags)); - assert(start_reg == 0 && "Cache flush syscall failed."); -#else - compilerrt_abort(); -#endif -#elif defined(__linux__) && defined(__mips__) - const uintptr_t start_int = (uintptr_t)start; - const uintptr_t end_int = (uintptr_t)end; - syscall(__NR_cacheflush, start, (end_int - start_int), BCACHE); -#elif defined(__mips__) && defined(__OpenBSD__) - cacheflush(start, (uintptr_t)end - (uintptr_t)start, BCACHE); -#elif defined(__aarch64__) && !defined(__APPLE__) - uint64_t xstart = (uint64_t)(uintptr_t)start; - uint64_t xend = (uint64_t)(uintptr_t)end; - - // Get Cache Type Info. - static uint64_t ctr_el0 = 0; - if (ctr_el0 == 0) - __asm __volatile("mrs %0, ctr_el0" : "=r"(ctr_el0)); - - // The DC and IC instructions must use 64-bit registers so we don't use - // uintptr_t in case this runs in an IPL32 environment. - uint64_t addr; - - // If CTR_EL0.IDC is set, data cache cleaning to the point of unification - // is not required for instruction to data coherence. - if (((ctr_el0 >> 28) & 0x1) == 0x0) { - const size_t dcache_line_size = 4 << ((ctr_el0 >> 16) & 15); - for (addr = xstart & ~(dcache_line_size - 1); addr < xend; addr += dcache_line_size) - __asm __volatile("dc cvau, %0" ::"r"(addr)); - } - __asm __volatile("dsb ish"); - - // If CTR_EL0.DIC is set, instruction cache invalidation to the point of - // unification is not required for instruction to data coherence. - if (((ctr_el0 >> 29) & 0x1) == 0x0) { - const size_t icache_line_size = 4 << ((ctr_el0 >> 0) & 15); - for (addr = xstart & ~(icache_line_size - 1); addr < xend; addr += icache_line_size) - __asm __volatile("ic ivau, %0" ::"r"(addr)); - __asm __volatile("dsb ish"); - } - __asm __volatile("isb sy"); -#elif defined(__powerpc64__) - const size_t line_size = 32; - const size_t len = (uintptr_t)end - (uintptr_t)start; - - const uintptr_t mask = ~(line_size - 1); - const uintptr_t start_line = ((uintptr_t)start) & mask; - const uintptr_t end_line = ((uintptr_t)start + len + line_size - 1) & mask; - - for (uintptr_t line = start_line; line < end_line; line += line_size) - __asm__ volatile("dcbf 0, %0" : : "r"(line)); - __asm__ volatile("sync"); - - for (uintptr_t line = start_line; line < end_line; line += line_size) - __asm__ volatile("icbi 0, %0" : : "r"(line)); - __asm__ volatile("isync"); -#elif defined(__sparc__) - const size_t dword_size = 8; - const size_t len = (uintptr_t)end - (uintptr_t)start; - - const uintptr_t mask = ~(dword_size - 1); - const uintptr_t start_dword = ((uintptr_t)start) & mask; - const uintptr_t end_dword = ((uintptr_t)start + len + dword_size - 1) & mask; - - for (uintptr_t dword = start_dword; dword < end_dword; dword += dword_size) - __asm__ volatile("flush %0" : : "r"(dword)); -#elif defined(__riscv) && defined(__linux__) - // See: arch/riscv/include/asm/cacheflush.h, arch/riscv/kernel/sys_riscv.c - register void *start_reg __asm("a0") = start; - const register void *end_reg __asm("a1") = end; - // "0" means that we clear cache for all threads (SYS_RISCV_FLUSH_ICACHE_ALL) - const register long flags __asm("a2") = 0; - const register long syscall_nr __asm("a7") = __NR_riscv_flush_icache; - __asm __volatile("ecall" : "=r"(start_reg) : "r"(start_reg), "r"(end_reg), "r"(flags), "r"(syscall_nr)); - assert(start_reg == 0 && "Cache flush syscall failed."); -#else -#if __APPLE__ - // On Darwin, sys_icache_invalidate() provides this functionality - sys_icache_invalidate(start, end - start); -#elif defined(__ve__) - __asm__ volatile("fencec 2"); -#else - compilerrt_abort(); -#endif -#endif -} - -void ClearCache(void *start, void *end) { - return _clear_cache(start, end); -} diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/clear-cache-tool/clear-cache-tool-arm-dummy.cc b/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/clear-cache-tool/clear-cache-tool-arm-dummy.cc deleted file mode 100644 index abe26c45..00000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/clear-cache-tool/clear-cache-tool-arm-dummy.cc +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef USER_MODE_CLEAR_CACHE_TOOL_H -#define USER_MODE_CLEAR_CACHE_TOOL_H - -#include "core/arch/Cpu.h" - -#include "PlatformInterface/globals.h" - -#if !HOST_OS_IOS -#include // for cache flushing. -#endif - -void CpuFeatures::FlushICache(void *startp, void *endp) { - -#if HOST_OS_IOS - // Precompilation never patches code so there should be no I cache flushes. - CpuFeatures::ClearCache(startp, endp); - -#else - - register uint32_t beg asm("r0") = reinterpret_cast(startp); - register uint32_t end asm("r1") = reinterpret_cast(endp); - register uint32_t flg asm("r2") = 0; - -#ifdef __clang__ - // This variant of the asm avoids a constant pool entry, which can be - // problematic when LTO'ing. It is also slightly shorter. - register uint32_t scno asm("r7") = __ARM_NR_cacheflush; - - asm volatile("svc 0\n" : : "r"(beg), "r"(end), "r"(flg), "r"(scno) : "memory"); -#else - // Use a different variant of the asm with GCC because some versions doesn't - // support r7 as an asm input. - asm volatile( - // This assembly works for both ARM and Thumb targets. - - // Preserve r7; it is callee-saved, and GCC uses it as a frame pointer for - // Thumb targets. - " push {r7}\n" - // r0 = beg - // r1 = end - // r2 = flags (0) - " ldr r7, =%c[scno]\n" // r7 = syscall number - " svc 0\n" - - " pop {r7}\n" - : - : "r"(beg), "r"(end), "r"(flg), [scno] "i"(__ARM_NR_cacheflush) - : "memory"); -#endif -#endif -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/clear-cache-tool/clear-cache-tool-arm64-dummy.cc b/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/clear-cache-tool/clear-cache-tool-arm64-dummy.cc deleted file mode 100644 index 60580a5c..00000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/clear-cache-tool/clear-cache-tool-arm64-dummy.cc +++ /dev/null @@ -1,103 +0,0 @@ -#ifndef USER_MODE_CLEAR_CACHE_TOOL_ARM64_H -#define USER_MODE_CLEAR_CACHE_TOOL_ARM64_H - -#include "core/arch/Cpu.h" - -#include "PlatformInterface/globals.h" - -class CacheLineSizes { -public: - CacheLineSizes() { - // Copy the content of the cache type register to a core register. - __asm__ __volatile__("mrs %x[ctr], ctr_el0" // NOLINT - : [ctr] "=r"(cache_type_register_)); - } - - uint32_t icache_line_size() const { - return ExtractCacheLineSize(0); - } - uint32_t dcache_line_size() const { - return ExtractCacheLineSize(16); - } - -private: - uint32_t ExtractCacheLineSize(int cache_line_size_shift) const { - // The cache type register holds the size of cache lines in words as a - // power of two. - return 4 << ((cache_type_register_ >> cache_line_size_shift) & 0xF); - } - - uint32_t cache_type_register_; -}; - -void CpuFeatures::FlushICache(void *startp, void *endp) { - // The code below assumes user space cache operations are allowed. The goal - // of this routine is to make sure the code generated is visible to the I - // side of the CPU. - -#if HOST_OS_IOS - // Precompilation never patches code so there should be no I cache flushes. - CpuFeatures::ClearCache(startp, endp); -#else - uintptr_t start = reinterpret_cast(startp); - // Sizes will be used to generate a mask big enough to cover a pointer. - CacheLineSizes sizes; - uintptr_t dsize = sizes.dcache_line_size(); - uintptr_t isize = sizes.icache_line_size(); - // Cache line sizes are always a power of 2. - uintptr_t dstart = start & ~(dsize - 1); - uintptr_t istart = start & ~(isize - 1); - uintptr_t end = reinterpret_cast(endp); - - __asm__ __volatile__( // NOLINT - // Clean every line of the D cache containing the target data. - "0: \n\t" - // dc : Data Cache maintenance - // c : Clean - // i : Invalidate - // va : by (Virtual) Address - // c : to the point of Coherency - // See ARM DDI 0406B page B2-12 for more information. - // We would prefer to use "cvau" (clean to the point of unification) here - // but we use "civac" to work around Cortex-A53 errata 819472, 826319, - // 827319 and 824069. - "dc civac, %[dline] \n\t" - "add %[dline], %[dline], %[dsize] \n\t" - "cmp %[dline], %[end] \n\t" - "b.lt 0b \n\t" - // Barrier to make sure the effect of the code above is visible to the rest - // of the world. - // dsb : Data Synchronisation Barrier - // ish : Inner SHareable domain - // The point of unification for an Inner Shareable shareability domain is - // the point by which the instruction and data caches of all the processors - // in that Inner Shareable shareability domain are guaranteed to see the - // same copy of a memory location. See ARM DDI 0406B page B2-12 for more - // information. - "dsb ish \n\t" - // Invalidate every line of the I cache containing the target data. - "1: \n\t" - // ic : instruction cache maintenance - // i : invalidate - // va : by address - // u : to the point of unification - "ic ivau, %[iline] \n\t" - "add %[iline], %[iline], %[isize] \n\t" - "cmp %[iline], %[end] \n\t" - "b.lt 1b \n\t" - // Barrier to make sure the effect of the code above is visible to the rest - // of the world. - "dsb ish \n\t" - // Barrier to ensure any prefetching which happened before this code is - // discarded. - // isb : Instruction Synchronisation Barrier - "isb \n\t" - : [dline] "+r"(dstart), [iline] "+r"(istart) - : [dsize] "r"(dsize), [isize] "r"(isize), [end] "r"(end) - // This code does not write to memory but without the dependency gcc might - // move this code before the code is generated. - : "cc", "memory"); // NOLINT -#endif -} - -#endif diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/code-patch-tool-darwin.cc b/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/code-patch-tool-darwin.cc deleted file mode 100644 index f277d721..00000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/code-patch-tool-darwin.cc +++ /dev/null @@ -1,172 +0,0 @@ -#include "dobby/dobby_internal.h" - -#include "PlatformUnifiedInterface/ExecMemory/ClearCacheTool.h" - -#include - -#include -#include "UnifiedInterface/platform-darwin/mach_vm.h" - -#if defined(__APPLE__) -#include -#include -#endif - -#define KERN_RETURN_ERROR(kr, failure) \ - do { \ - if (kr != KERN_SUCCESS) { \ - ERROR_LOG("mach error: %s", mach_error_string(kr)); \ - return failure; \ - } \ - } while (0); - -#include - -#if defined(TARGET_ARCH_ARM64) -#define SYS_mprotect 74 -int mprotect_impl(void *addr, size_t len, int prot) { - int ret = 0; - __asm__ __volatile__("mov x16, %[_SYS_mprotect]\n" - "svc 0x80\n" - "mov %w[_ret], w0\n" - "add %w[_ret], %w[_ret], #0x0\n" - : [_ret] "=r"(ret) - : [_SYS_mprotect] "n"(SYS_mprotect) - :); - return ret; -} -#endif - -PUBLIC int DobbyCodePatch(void *address, uint8_t *buffer, uint32_t buffer_size) { - if (address == nullptr || buffer == nullptr || buffer_size == 0) { - ERROR_LOG("invalid argument"); - return -1; - } - - size_t page_size = PAGE_SIZE; - addr_t patch_page = ALIGN_FLOOR(address, page_size); - - // cross over page - if ((addr_t)address + buffer_size > patch_page + page_size) { - void *address_a = address; - uint8_t *buffer_a = buffer; - uint32_t buffer_size_a = (patch_page + page_size - (addr_t)address); - auto ret = DobbyCodePatch(address_a, buffer_a, buffer_size_a); - if (ret == -1) { - return ret; - } - - void *address_b = (void *)((addr_t)address + buffer_size_a); - uint8_t *buffer_b = buffer + buffer_size_a; - uint32_t buffer_size_b = buffer_size - buffer_size_a; - ret = DobbyCodePatch(address_b, buffer_b, buffer_size_b); - return ret; - } - - addr_t remap_dest_page = patch_page; - mach_vm_address_t remap_dummy_page = 0; - - auto self_task = mach_task_self(); - kern_return_t kr; - - int orig_prot = 0; - int orig_max_prot = 0; - int share_mode = 0; - int is_enable_remap = -1; - if (is_enable_remap == -1) { - auto get_region_info = [&](addr_t region_start) -> void { - vm_region_submap_info_64 region_submap_info; - mach_msg_type_number_t count = VM_REGION_SUBMAP_INFO_COUNT_64; - mach_vm_address_t addr = region_start; - mach_vm_size_t size = 0; - natural_t depth = 0; - while (1) { - kr = mach_vm_region_recurse(mach_task_self(), (mach_vm_address_t *)&addr, (mach_vm_size_t *)&size, &depth, - (vm_region_recurse_info_t)®ion_submap_info, &count); - if (region_submap_info.is_submap) { - depth++; - } else { - orig_prot = region_submap_info.protection; - orig_max_prot = region_submap_info.max_protection; - share_mode = region_submap_info.share_mode; - return; - } - } - }; - get_region_info(remap_dest_page); - if (orig_max_prot != 5 && share_mode != 2) { - is_enable_remap = 1; - } else { - is_enable_remap = 0; - DEBUG_LOG("code patch %p won't use remap", address); - } - } - if (is_enable_remap == 1) { - addr_t remap_dummy_page = 0; - { - kr = mach_vm_allocate(self_task, (mach_vm_address_t *)&remap_dummy_page, page_size, VM_FLAGS_ANYWHERE); - KERN_RETURN_ERROR(kr, -1); - - memcpy((void *)remap_dummy_page, (void *)patch_page, page_size); - - int offset = (int)((addr_t)address - patch_page); - memcpy((void *)(remap_dummy_page + offset), buffer, buffer_size); - - kr = mach_vm_protect(self_task, remap_dummy_page, page_size, false, VM_PROT_READ | VM_PROT_EXECUTE); - KERN_RETURN_ERROR(kr, -1); - } - - vm_prot_t prot, max_prot; - kr = mach_vm_remap(self_task, (mach_vm_address_t *)&remap_dest_page, page_size, 0, - VM_FLAGS_OVERWRITE | VM_FLAGS_FIXED, self_task, remap_dummy_page, true, &prot, &max_prot, - VM_INHERIT_COPY); - KERN_RETURN_ERROR(kr, -1); - - kr = mach_vm_deallocate(self_task, remap_dummy_page, page_size); - KERN_RETURN_ERROR(kr, -1); - } else { - - if (0) { - { - auto kr = mach_vm_allocate(self_task, &remap_dummy_page, page_size, VM_FLAGS_ANYWHERE); - KERN_RETURN_ERROR(kr, -1); - - kr = mach_vm_deallocate(self_task, remap_dummy_page, page_size); - KERN_RETURN_ERROR(kr, -1); - } - - vm_prot_t prot, max_prot; - kr = mach_vm_remap(self_task, &remap_dummy_page, page_size, 0, VM_FLAGS_ANYWHERE, self_task, remap_dest_page, - false, &prot, &max_prot, VM_INHERIT_SHARE); - KERN_RETURN_ERROR(kr, -1); - - kr = mach_vm_protect(self_task, remap_dummy_page, page_size, false, VM_PROT_READ | VM_PROT_WRITE); - // the kr always return KERN_PROTECTION_FAILURE - kr = KERN_PROTECTION_FAILURE; - - memcpy((void *)(remap_dummy_page + ((uint64_t)address - remap_dest_page)), buffer, buffer_size); - } - - static __typeof(vm_protect) *vm_protect_impl = nullptr; - if (vm_protect_impl == nullptr) { - vm_protect_impl = (__typeof(vm_protect) *)DobbySymbolResolver("dyld", "vm_protect"); - if (vm_protect_impl == nullptr) { - vm_protect_impl = (__typeof(vm_protect) *)DobbySymbolResolver("libsystem_kernel.dylib", "_vm_protect"); - } - vm_protect_impl = (__typeof(vm_protect) *)pac_sign((void *)vm_protect_impl); - } - { - kr = vm_protect_impl(self_task, remap_dest_page, page_size, false, VM_PROT_READ | VM_PROT_WRITE | VM_PROT_COPY); - KERN_RETURN_ERROR(kr, -1); - - memcpy((void *)(patch_page + ((uint64_t)address - remap_dest_page)), buffer, buffer_size); - - kr = vm_protect_impl(self_task, remap_dest_page, page_size, false, orig_prot); - KERN_RETURN_ERROR(kr, -1); - } - } - - ClearCache(address, (void *)((addr_t)address + buffer_size)); - - return 0; -} diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/code-patch-tool-posix.cc b/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/code-patch-tool-posix.cc deleted file mode 100644 index bfe7361b..00000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/code-patch-tool-posix.cc +++ /dev/null @@ -1,37 +0,0 @@ - -#include "dobby/dobby_internal.h" -#include "core/arch/Cpu.h" - -#include -#include -#include - -#if !defined(__APPLE__) -PUBLIC int DobbyCodePatch(void *address, uint8_t *buffer, uint32_t buffer_size) { -#if defined(__ANDROID__) || defined(__linux__) - int page_size = (int)sysconf(_SC_PAGESIZE); - uintptr_t patch_page = ALIGN_FLOOR(address, page_size); - uintptr_t patch_end_page = ALIGN_FLOOR((uintptr_t)address + buffer_size, page_size); - - // change page permission as rwx - mprotect((void *)patch_page, page_size, PROT_READ | PROT_WRITE | PROT_EXEC); - if (patch_page != patch_end_page) { - mprotect((void *)patch_end_page, page_size, PROT_READ | PROT_WRITE | PROT_EXEC); - } - - // patch buffer - memcpy(address, buffer, buffer_size); - - // restore page permission - mprotect((void *)patch_page, page_size, PROT_READ | PROT_EXEC); - if (patch_page != patch_end_page) { - mprotect((void *)patch_end_page, page_size, PROT_READ | PROT_EXEC); - } - - addr_t clear_start_ = (addr_t)address; - ClearCache((void *)clear_start_, (void *)(clear_start_ + buffer_size)); -#endif - return 0; -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/code-patch-tool-windows.cc b/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/code-patch-tool-windows.cc deleted file mode 100644 index 471a4672..00000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/code-patch-tool-windows.cc +++ /dev/null @@ -1,27 +0,0 @@ -#include "dobby/dobby_internal.h" - -#include - -using namespace zz; - -PUBLIC int DobbyCodePatch(void *address, uint8_t *buffer, uint32_t buffer_size) { - DWORD oldProtect; - int page_size; - - // Get page size - SYSTEM_INFO si; - GetSystemInfo(&si); - page_size = si.dwPageSize; - - void *addressPageAlign = (void *)ALIGN(address, page_size); - - if (!VirtualProtect(addressPageAlign, page_size, PAGE_EXECUTE_READWRITE, &oldProtect)) - return kMemoryOperationError; - - memcpy(address, buffer, buffer_size); - - if (!VirtualProtect(addressPageAlign, page_size, oldProtect, &oldProtect)) - return kMemoryOperationError; - - return 0; -} diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/substrated/mach_interface_support/substrated.defs b/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/substrated/mach_interface_support/substrated.defs deleted file mode 100644 index 3871f7af..00000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/ExecMemory/substrated/mach_interface_support/substrated.defs +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Regenerate with: - * - * $(xcrun --sdk macosx -f mig) \ - * -isysroot $(xcrun --sdk macosx --show-sdk-path) \ - * -sheader substratedserver.h \ - * -server substratedserver.c \ - * -header substratedclient.h \ - * -user substratedclient.c \ - * substrated.defs - */ - -subsystem substrated 9000; - -#include -#include - -routine substrated_mark(server - : mach_port_t; - task - : vm_task_entry_t; - source_address - : mach_vm_address_t; - source_size - : mach_vm_size_t; - inout target_address - : mach_vm_address_t); diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/MultiThreadSupport/ThreadSupport.cpp b/app/src/main/cpp/Dobby/source/Backend/UserMode/MultiThreadSupport/ThreadSupport.cpp deleted file mode 100644 index 30be99c8..00000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/MultiThreadSupport/ThreadSupport.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "MultiThreadSupport/ThreadSupport.h" - -using namespace zz; - -OSThread::LocalStorageKey ThreadSupport::thread_callstack_key_ = 0; - -// Get current CallStack -CallStack *ThreadSupport::CurrentThreadCallStack() { - - // TODO: __attribute__((destructor)) is better ? - if (!thread_callstack_key_) { - thread_callstack_key_ = OSThread::CreateThreadLocalKey(); - } - - if (OSThread::HasThreadLocal(thread_callstack_key_)) { - return static_cast(OSThread::GetThreadLocal(thread_callstack_key_)); - } else { - CallStack *callstack = new CallStack(); - OSThread::SetThreadLocal(thread_callstack_key_, callstack); - return callstack; - } -} diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/MultiThreadSupport/ThreadSupport.h b/app/src/main/cpp/Dobby/source/Backend/UserMode/MultiThreadSupport/ThreadSupport.h deleted file mode 100644 index ed02a794..00000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/MultiThreadSupport/ThreadSupport.h +++ /dev/null @@ -1,63 +0,0 @@ -#ifndef USER_MODE_MULTI_THREAD_SUPPORT_H -#define USER_MODE_MULTI_THREAD_SUPPORT_H - -#include -#include - -#include "dobby/dobby_internal.h" - -#include "source/Backend/UserMode/Thread/PlatformThread.h" - -// StackFrame base in CallStack -typedef struct _StackFrame { - // context between `pre_call` and `post_call` - std::map kv_context; - // origin function ret address - void *orig_ret; -} StackFrame; - -// (thead) CallStack base in thread -typedef struct _CallStack { - tinystl::vector stackframes; -} CallStack; - -// ThreadSupport base on vm_core, support mutipl platforms. -class ThreadSupport { -public: - // Push stack frame - static void PushStackFrame(StackFrame *stackframe) { - CallStack *callstack = ThreadSupport::CurrentThreadCallStack(); - callstack->stackframes.push_back(stackframe); - } - - // Pop stack frame - static StackFrame *PopStackFrame() { - CallStack *callstack = ThreadSupport::CurrentThreadCallStack(); - StackFrame *stackframe = callstack->stackframes.back(); - callstack->stackframes.pop_back(); - return stackframe; - } - - // ===== - static void SetStackFrameContextValue(StackFrame *stackframe, char *key, void *value) { - std::map *kv_context = &stackframe->kv_context; - kv_context->insert(std::pair(key, value)); - }; - - static void *GetStackFrameContextValue(StackFrame *stackframe, char *key) { - std::map kv_context = stackframe->kv_context; - std::map::iterator it; - it = kv_context.find(key); - if (it != kv_context.end()) { - return (void *)it->second; - } - return NULL; - }; - - static CallStack *CurrentThreadCallStack(); - -private: - static zz::OSThread::LocalStorageKey thread_callstack_key_; -}; - -#endif diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/PlatformUtil/Darwin/ProcessRuntimeUtility.cc b/app/src/main/cpp/Dobby/source/Backend/UserMode/PlatformUtil/Darwin/ProcessRuntimeUtility.cc deleted file mode 100644 index 988c1aac..00000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/PlatformUtil/Darwin/ProcessRuntimeUtility.cc +++ /dev/null @@ -1,143 +0,0 @@ -#include "dobby/dobby_internal.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "UnifiedInterface/platform-darwin/mach_vm.h" -#include "PlatformUtil/ProcessRuntimeUtility.h" - -static bool memory_region_comparator(MemRegion a, MemRegion b) { - return (a.start < b.start); -} - -tinystl::vector *regions; - -const tinystl::vector &ProcessRuntimeUtility::GetProcessMemoryLayout() { - if (regions == nullptr) { - regions = new tinystl::vector(); - } - - regions->clear(); - - vm_region_submap_info_64 region_submap_info; - mach_msg_type_number_t count = VM_REGION_SUBMAP_INFO_COUNT_64; - mach_vm_address_t addr = 0; - mach_vm_size_t size = 0; - natural_t depth = 0; - while (true) { - count = VM_REGION_SUBMAP_INFO_COUNT_64; - kern_return_t kr = mach_vm_region_recurse(mach_task_self(), (mach_vm_address_t *)&addr, (mach_vm_size_t *)&size, - &depth, (vm_region_recurse_info_t)®ion_submap_info, &count); - if (kr != KERN_SUCCESS) { - if (kr == KERN_INVALID_ADDRESS) { - break; - } else { - break; - } - } - - if (region_submap_info.is_submap) { - depth++; - } else { - MemoryPermission permission; - if ((region_submap_info.protection & PROT_READ) && (region_submap_info.protection & PROT_WRITE)) { - permission = MemoryPermission::kReadWrite; - } else if ((region_submap_info.protection & PROT_READ) == region_submap_info.protection) { - permission = MemoryPermission::kRead; - } else if ((region_submap_info.protection & PROT_READ) && (region_submap_info.protection & PROT_EXEC)) { - permission = MemoryPermission::kReadExecute; - } else { - permission = MemoryPermission::kNoAccess; - } -#if 0 - DEBUG_LOG("%p --- %p", addr, addr + size); -#endif - MemRegion region = MemRegion(addr, size, permission); - regions->push_back(region); - addr += size; - } - } - - // std::sort(ProcessMemoryLayout.begin(), ProcessMemoryLayout.end(), memory_region_comparator); - - return *regions; -} - -static tinystl::vector *modules; - -const tinystl::vector &ProcessRuntimeUtility::GetProcessModuleMap() { - if (modules == nullptr) { - modules = new tinystl::vector(); - } - modules->clear(); - - kern_return_t kr; - task_dyld_info_data_t task_dyld_info; - mach_msg_type_number_t count = TASK_DYLD_INFO_COUNT; - kr = task_info(mach_task_self_, TASK_DYLD_INFO, (task_info_t)&task_dyld_info, &count); - if (kr != KERN_SUCCESS) { - return *modules; - } - - struct dyld_all_image_infos *infos = (struct dyld_all_image_infos *)task_dyld_info.all_image_info_addr; - const struct dyld_image_info *infoArray = infos->infoArray; - uint32_t infoArrayCount = infos->infoArrayCount; - - RuntimeModule module = {0}; - strncpy(module.path, "dummy-placeholder-module", sizeof(module.path) - 1); - module.load_address = 0; - modules->push_back(module); - - strncpy(module.path, infos->dyldPath, sizeof(module.path) - 1); - module.load_address = (void *)infos->dyldImageLoadAddress; - modules->push_back(module); - - for (int i = 0; i < infoArrayCount; ++i) { - const struct dyld_image_info *info = &infoArray[i]; - - { - strncpy(module.path, info->imageFilePath, sizeof(module.path) - 1); - module.load_address = (void *)info->imageLoadAddress; - modules->push_back(module); - } - } - - modules->sort([](const RuntimeModule &a, const RuntimeModule &b) -> int { return a.load_address < b.load_address; }); - - return *modules; -} - -RuntimeModule ProcessRuntimeUtility::GetProcessModule(const char *name) { - auto modules = GetProcessModuleMap(); - for (auto module : modules) { - if (strstr(module.path, name) != 0) { - return module; - } - } - return RuntimeModule{0}; -} diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/PlatformUtil/Linux/ProcessRuntimeUtility.cc b/app/src/main/cpp/Dobby/source/Backend/UserMode/PlatformUtil/Linux/ProcessRuntimeUtility.cc deleted file mode 100644 index 862c29fb..00000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/PlatformUtil/Linux/ProcessRuntimeUtility.cc +++ /dev/null @@ -1,237 +0,0 @@ -#include "PlatformUtil/ProcessRuntimeUtility.h" - -#include -#include -#include -#include - -#include -#include - -#include -#include - -#define LINE_MAX 2048 - -// ================================================================ -// GetProcessMemoryLayout - -static bool memory_region_comparator(MemRange a, MemRange b) { - return (a.start < b.start); -} - -tinystl::vector regions; -const tinystl::vector &ProcessRuntimeUtility::GetProcessMemoryLayout() { - regions.clear(); - - FILE *fp = fopen("/proc/self/maps", "r"); - if (fp == nullptr) - return regions; - - while (!feof(fp)) { - char line_buffer[LINE_MAX + 1]; - fgets(line_buffer, LINE_MAX, fp); - - // ignore the rest of characters - if (strlen(line_buffer) == LINE_MAX && line_buffer[LINE_MAX] != '\n') { - // Entry not describing executable data. Skip to end of line to set up - // reading the next entry. - int c; - do { - c = getc(fp); - } while ((c != EOF) && (c != '\n')); - if (c == EOF) - break; - } - - addr_t region_start, region_end; - addr_t region_offset; - char permissions[5] = {'\0'}; // Ensure NUL-terminated string. - uint8_t dev_major = 0; - uint8_t dev_minor = 0; - long inode = 0; - int path_index = 0; - - // Sample format from man 5 proc: - // - // address perms offset dev inode pathname - // 08048000-08056000 r-xp 00000000 03:0c 64593 /usr/sbin/gpm - // - // The final %n term captures the offset in the input string, which is used - // to determine the path name. It *does not* increment the return value. - // Refer to man 3 sscanf for details. - if (sscanf(line_buffer, - "%" PRIxPTR "-%" PRIxPTR " %4c " - "%" PRIxPTR " %hhx:%hhx %ld %n", - ®ion_start, ®ion_end, permissions, ®ion_offset, &dev_major, &dev_minor, &inode, - &path_index) < 7) { - ERROR_LOG("/proc/self/maps parse failed!"); - fclose(fp); - return regions; - } - - MemoryPermission permission; - if (permissions[0] == 'r' && permissions[1] == 'w') { - permission = MemoryPermission::kReadWrite; - } else if (permissions[0] == 'r' && permissions[2] == 'x') { - permission = MemoryPermission::kReadExecute; - } else if (permissions[0] == 'r' && permissions[1] == 'w' && permissions[2] == 'x') { - permission = MemoryPermission::kReadWriteExecute; - } else { - permission = MemoryPermission::kNoAccess; - } - -#if 0 - DEBUG_LOG("%p --- %p", region_start, region_end); -#endif - - MemRegion region = MemRegion(region_start, region_end - region_start, permission); - regions.push_back(region); - } - std::sort(regions.begin(), regions.end(), memory_region_comparator); - - fclose(fp); - return regions; -} - -// ================================================================ -// GetProcessModuleMap - -static tinystl::vector *modules; -static tinystl::vector &get_process_map_with_proc_maps() { - if (modules == nullptr) { - modules = new tinystl::vector(); - } - - FILE *fp = fopen("/proc/self/maps", "r"); - if (fp == nullptr) - return *modules; - - while (!feof(fp)) { - char line_buffer[LINE_MAX + 1]; - fgets(line_buffer, LINE_MAX, fp); - - // ignore the rest of characters - if (strlen(line_buffer) == LINE_MAX && line_buffer[LINE_MAX] != '\n') { - // Entry not describing executable data. Skip to end of line to set up - // reading the next entry. - int c; - do { - c = getc(fp); - } while ((c != EOF) && (c != '\n')); - if (c == EOF) - break; - } - - addr_t region_start, region_end; - addr_t region_offset; - char permissions[5] = {'\0'}; // Ensure NUL-terminated string. - uint8_t dev_major = 0; - uint8_t dev_minor = 0; - long inode = 0; - int path_index = 0; - - // Sample format from man 5 proc: - // - // address perms offset dev inode pathname - // 08048000-08056000 r-xp 00000000 03:0c 64593 /usr/sbin/gpm - // - // The final %n term captures the offset in the input string, which is used - // to determine the path name. It *does not* increment the return value. - // Refer to man 3 sscanf for details. - if (sscanf(line_buffer, - "%" PRIxPTR "-%" PRIxPTR " %4c " - "%" PRIxPTR " %hhx:%hhx %ld %n", - ®ion_start, ®ion_end, permissions, ®ion_offset, &dev_major, &dev_minor, &inode, - &path_index) < 7) { - ERROR_LOG("/proc/self/maps parse failed!"); - fclose(fp); - return *modules; - } - - // check header section permission - if (strcmp(permissions, "r--p") != 0 && strcmp(permissions, "r-xp") != 0) - continue; - - // check elf magic number - ElfW(Ehdr) *header = (ElfW(Ehdr) *)region_start; - if (memcmp(header->e_ident, ELFMAG, SELFMAG) != 0) { - continue; - } - - char *path_buffer = line_buffer + path_index; - if (*path_buffer == 0 || *path_buffer == '\n' || *path_buffer == '[') - continue; - RuntimeModule module; - - // strip - if (path_buffer[strlen(path_buffer) - 1] == '\n') { - path_buffer[strlen(path_buffer) - 1] = 0; - } - strncpy(module.path, path_buffer, sizeof(module.path) - 1); - module.load_address = (void *)region_start; - modules->push_back(module); - -#if 0 - DEBUG_LOG("module: %s", module.path); -#endif - } - - fclose(fp); - return *modules; -} - -#if defined(__LP64__) -static tinystl::vector get_process_map_with_linker_iterator() { - tinystl::vector ProcessModuleMap; - - static int (*dl_iterate_phdr_ptr)(int (*)(struct dl_phdr_info *, size_t, void *), void *); - dl_iterate_phdr_ptr = (__typeof(dl_iterate_phdr_ptr))dlsym(RTLD_DEFAULT, "dl_iterate_phdr"); - if (dl_iterate_phdr_ptr == NULL) { - return ProcessModuleMap; - } - - dl_iterate_phdr_ptr( - [](dl_phdr_info *info, size_t size, void *data) { - RuntimeModule module = {0}; - if (info->dlpi_name && info->dlpi_name[0] == '/') - strcpy(module.path, info->dlpi_name); - - module.load_address = (void *)info->dlpi_addr; - for (size_t i = 0; i < info->dlpi_phnum; ++i) { - if (info->dlpi_phdr[i].p_type == PT_LOAD) { - uintptr_t load_bias = (info->dlpi_phdr[i].p_vaddr - info->dlpi_phdr[i].p_offset); - module.load_address = (void *)((addr_t)module.load_address + load_bias); - break; - } - } - - // push to vector - auto ProcessModuleMap = reinterpret_cast *>(data); - ProcessModuleMap->push_back(module); - return 0; - }, - (void *)&ProcessModuleMap); - - return ProcessModuleMap; -} -#endif - -const tinystl::vector &ProcessRuntimeUtility::GetProcessModuleMap() { -#if defined(__LP64__) && 0 - // TODO: won't resolve main binary - return get_process_map_with_linker_iterator(); -#else - return get_process_map_with_proc_maps(); -#endif -} - -RuntimeModule ProcessRuntimeUtility::GetProcessModule(const char *name) { - auto modules = GetProcessModuleMap(); - for (auto module : modules) { - if (strstr(module.path, name) != 0) { - return module; - } - } - return RuntimeModule{0}; -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/PlatformUtil/Windows/ProcessRuntimeUtility.cc b/app/src/main/cpp/Dobby/source/Backend/UserMode/PlatformUtil/Windows/ProcessRuntimeUtility.cc deleted file mode 100644 index 632bfc55..00000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/PlatformUtil/Windows/ProcessRuntimeUtility.cc +++ /dev/null @@ -1,81 +0,0 @@ -#include "PlatformUtil/ProcessRuntimeUtility.h" - -#include - -#include - -#define LINE_MAX 2048 - -// ================================================================ -// GetProcessMemoryLayout - -static bool memory_region_comparator(MemRange a, MemRange b) { - return (a.address > b.address); -} - -// https://gist.github.com/jedwardsol/9d4fe1fd806043a5767affbd200088ca - -tinystl::vector ProcessMemoryLayout; -tinystl::vector ProcessRuntimeUtility::GetProcessMemoryLayout() { - if (!ProcessMemoryLayout.empty()) { - ProcessMemoryLayout.clear(); - } - - char *address{nullptr}; - MEMORY_BASIC_INFORMATION region; - - while (VirtualQuery(address, ®ion, sizeof(region))) { - address += region.RegionSize; - if (!(region.State & (MEM_COMMIT | MEM_RESERVE))) { - continue; - } - - MemoryPermission permission = MemoryPermission::kNoAccess; - auto mask = PAGE_GUARD | PAGE_NOCACHE | PAGE_WRITECOMBINE; - switch (region.Protect & ~mask) { - case PAGE_NOACCESS: - case PAGE_READONLY: - break; - - case PAGE_EXECUTE: - case PAGE_EXECUTE_READ: - permission = MemoryPermission::kReadExecute; - break; - - case PAGE_READWRITE: - case PAGE_WRITECOPY: - permission = MemoryPermission::kReadWrite; - break; - - case PAGE_EXECUTE_READWRITE: - case PAGE_EXECUTE_WRITECOPY: - permission = MemoryPermission::kReadWriteExecute; - break; - } - - ProcessMemoryLayout.push_back(MemRange{(void *)region.BaseAddress, region.RegionSize, permission}); - } - return ProcessMemoryLayout; -} - -// ================================================================ -// GetProcessModuleMap - -tinystl::vector ProcessModuleMap; - -tinystl::vector ProcessRuntimeUtility::GetProcessModuleMap() { - if (!ProcessMemoryLayout.empty()) { - ProcessMemoryLayout.clear(); - } - return ProcessModuleMap; -} - -RuntimeModule ProcessRuntimeUtility::GetProcessModule(const char *name) { - tinystl::vector ProcessModuleMap = GetProcessModuleMap(); - for (auto module : ProcessModuleMap) { - if (strstr(module.path, name) != 0) { - return module; - } - } - return RuntimeModule{0}; -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/Thread/PlatformThread.cc b/app/src/main/cpp/Dobby/source/Backend/UserMode/Thread/PlatformThread.cc deleted file mode 100644 index 827d1250..00000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/Thread/PlatformThread.cc +++ /dev/null @@ -1,19 +0,0 @@ -#include "./PlatformThread.h" - -namespace zz { -int OSThread::GetThreadLocalInt(LocalStorageKey key) { - return static_cast(reinterpret_cast(GetThreadLocal(key))); -} - -void OSThread::SetThreadLocalInt(LocalStorageKey key, int value) { - SetThreadLocal(key, reinterpret_cast(static_cast(value))); -} - -bool OSThread::HasThreadLocal(LocalStorageKey key) { - return GetThreadLocal(key) != nullptr; -} - -void *OSThread::GetExistingThreadLocal(LocalStorageKey key) { - return GetThreadLocal(key); -} -} // namespace zz \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/Thread/PlatformThread.h b/app/src/main/cpp/Dobby/source/Backend/UserMode/Thread/PlatformThread.h deleted file mode 100644 index 5a46c6c9..00000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/Thread/PlatformThread.h +++ /dev/null @@ -1,32 +0,0 @@ -#pragma once - -#include "dobby/common.h" - -namespace zz { - -class OSThread { -public: - typedef int LocalStorageKey; - - static int GetCurrentProcessId(); - - static int GetCurrentThreadId(); - - static LocalStorageKey CreateThreadLocalKey(); - - static void DeleteThreadLocalKey(LocalStorageKey key); - - static void *GetThreadLocal(LocalStorageKey key); - - static int GetThreadLocalInt(LocalStorageKey key); - - static void SetThreadLocal(LocalStorageKey key, void *value); - - static void SetThreadLocalInt(LocalStorageKey key, int value); - - static bool HasThreadLocal(LocalStorageKey key); - - static void *GetExistingThreadLocal(LocalStorageKey key); -}; - -} // namespace zz \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/Thread/platform-thread-posix.cc b/app/src/main/cpp/Dobby/source/Backend/UserMode/Thread/platform-thread-posix.cc deleted file mode 100644 index 486618c7..00000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/Thread/platform-thread-posix.cc +++ /dev/null @@ -1,71 +0,0 @@ -#include "Thread/PlatformThread.h" - -#include // getpid -#include // pthread -#include - -using namespace zz; - -int OSThread::GetCurrentProcessId() { - return static_cast(getpid()); -} - -int OSThread::GetCurrentThreadId() { -#if defined(__APPLE__) - return static_cast(pthread_mach_thread_np(pthread_self())); -#elif defined(__ANDROID__) - return static_cast(gettid()); -#elif defined(__linux__) - return static_cast(syscall(__NR_gettid)); -#else - return static_cast(reinterpret_cast(pthread_self())); -#endif -} - -static OSThread::LocalStorageKey PthreadKeyToLocalKey(pthread_key_t pthread_key) { -#if defined(__cygwin__) - // We need to cast pthread_key_t to OSThread::LocalStorageKey in two steps - // because pthread_key_t is a pointer type on Cygwin. This will probably not - // work on 64-bit platforms, but Cygwin doesn't support 64-bit anyway. - assert(sizeof(OSThread::LocalStorageKey) == sizeof(pthread_key_t)); - intptr_t ptr_key = reinterpret_cast(pthread_key); - return static_cast(ptr_key); -#else - return static_cast(pthread_key); -#endif -} - -static pthread_key_t LocalKeyToPthreadKey(OSThread::LocalStorageKey local_key) { -#if defined(__cygwin__) - assert(sizeof(OSThread::LocalStorageKey) == sizeof(pthread_key_t)); - intptr_t ptr_key = static_cast(local_key); - return reinterpret_cast(ptr_key); -#else - return static_cast(local_key); -#endif -} - -OSThread::LocalStorageKey OSThread::CreateThreadLocalKey() { - pthread_key_t key; - int result = pthread_key_create(&key, nullptr); - DCHECK_EQ(0, result); - LocalStorageKey local_key = PthreadKeyToLocalKey(key); - return local_key; -} - -void OSThread::DeleteThreadLocalKey(LocalStorageKey key) { - pthread_key_t pthread_key = LocalKeyToPthreadKey(key); - int result = pthread_key_delete(pthread_key); - DCHECK_EQ(0, result); -} - -void *OSThread::GetThreadLocal(LocalStorageKey key) { - pthread_key_t pthread_key = LocalKeyToPthreadKey(key); - return pthread_getspecific(pthread_key); -} - -void OSThread::SetThreadLocal(LocalStorageKey key, void *value) { - pthread_key_t pthread_key = LocalKeyToPthreadKey(key); - int result = pthread_setspecific(pthread_key, value); - DCHECK_EQ(0, result); -} diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/Thread/platform-thread-windows.cc b/app/src/main/cpp/Dobby/source/Backend/UserMode/Thread/platform-thread-windows.cc deleted file mode 100644 index 1428bb06..00000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/Thread/platform-thread-windows.cc +++ /dev/null @@ -1,25 +0,0 @@ -#include "PlatformThread.h" - -using namespace zz; - -int OSThread::GetCurrentProcessId() { - return 0; -} - -int OSThread::GetCurrentThreadId() { - return 0; -} - -OSThread::LocalStorageKey OSThread::CreateThreadLocalKey() { - return 0; -} - -void OSThread::DeleteThreadLocalKey(LocalStorageKey key) { -} - -void *OSThread::GetThreadLocal(LocalStorageKey key) { - return NULL; -} - -void OSThread::SetThreadLocal(LocalStorageKey key, void *value) { -} diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/platform-darwin/mach_vm.h b/app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/platform-darwin/mach_vm.h deleted file mode 100644 index a9cab322..00000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/platform-darwin/mach_vm.h +++ /dev/null @@ -1,933 +0,0 @@ -#ifndef _mach_vm_user_ -#define _mach_vm_user_ - -/* Module mach_vm */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* BEGIN MIG_STRNCPY_ZEROFILL CODE */ - -#if defined(__has_include) -#if __has_include() -#ifndef USING_MIG_STRNCPY_ZEROFILL -#define USING_MIG_STRNCPY_ZEROFILL -#endif -#ifndef __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ -#define __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ -#ifdef __cplusplus -extern "C" { -#endif -extern int mig_strncpy_zerofill(char *dest, const char *src, int len) __attribute__((weak_import)); -#ifdef __cplusplus -} -#endif -#endif /* __MIG_STRNCPY_ZEROFILL_FORWARD_TYPE_DECLS__ */ -#endif /* __has_include() */ -#endif /* __has_include */ - -/* END MIG_STRNCPY_ZEROFILL CODE */ - -#ifdef AUTOTEST -#ifndef FUNCTION_PTR_T -#define FUNCTION_PTR_T -typedef void (*function_ptr_t)(mach_port_t, char *, mach_msg_type_number_t); -typedef struct { - char *name; - function_ptr_t function; -} function_table_entry; -typedef function_table_entry *function_table_t; -#endif /* FUNCTION_PTR_T */ -#endif /* AUTOTEST */ - -#ifndef mach_vm_MSG_COUNT -#define mach_vm_MSG_COUNT 20 -#endif /* mach_vm_MSG_COUNT */ - -#include -#include -#include -#include - -#ifdef __BeforeMigUserHeader -__BeforeMigUserHeader -#endif /* __BeforeMigUserHeader */ - -#include - - __BEGIN_DECLS - -/* Routine mach_vm_allocate */ -#ifdef mig_external - mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_allocate(vm_map_t target, mach_vm_address_t *address, mach_vm_size_t size, int flags); - -/* Routine mach_vm_deallocate */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_deallocate(vm_map_t target, mach_vm_address_t address, mach_vm_size_t size); - -/* Routine mach_vm_protect */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_protect(vm_map_t target_task, mach_vm_address_t address, mach_vm_size_t size, boolean_t set_maximum, - vm_prot_t new_protection); - -/* Routine mach_vm_inherit */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_inherit(vm_map_t target_task, mach_vm_address_t address, mach_vm_size_t size, vm_inherit_t new_inheritance); - -/* Routine mach_vm_read */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_read(vm_map_t target_task, mach_vm_address_t address, mach_vm_size_t size, vm_offset_t *data, - mach_msg_type_number_t *dataCnt); - -/* Routine mach_vm_read_list */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_read_list(vm_map_t target_task, mach_vm_read_entry_t data_list, natural_t count); - -/* Routine mach_vm_write */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_write(vm_map_t target_task, mach_vm_address_t address, vm_offset_t data, mach_msg_type_number_t dataCnt); - -/* Routine mach_vm_copy */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_copy(vm_map_t target_task, mach_vm_address_t source_address, mach_vm_size_t size, - mach_vm_address_t dest_address); - -/* Routine mach_vm_read_overwrite */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_read_overwrite(vm_map_t target_task, mach_vm_address_t address, mach_vm_size_t size, mach_vm_address_t data, - mach_vm_size_t *outsize); - -/* Routine mach_vm_msync */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_msync(vm_map_t target_task, mach_vm_address_t address, mach_vm_size_t size, vm_sync_t sync_flags); - -/* Routine mach_vm_behavior_set */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_behavior_set(vm_map_t target_task, mach_vm_address_t address, mach_vm_size_t size, - vm_behavior_t new_behavior); - -/* Routine mach_vm_map */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_map(vm_map_t target_task, mach_vm_address_t *address, mach_vm_size_t size, mach_vm_offset_t mask, int flags, - mem_entry_name_port_t object, memory_object_offset_t offset, boolean_t copy, vm_prot_t curr_protection, - vm_prot_t max_protection, vm_inherit_t inheritance); - -/* Routine mach_vm_machine_attribute */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_machine_attribute(vm_map_t target_task, mach_vm_address_t address, mach_vm_size_t size, - vm_machine_attribute_t attribute, vm_machine_attribute_val_t *value); - -/* Routine mach_vm_remap */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_remap(vm_map_t target_task, mach_vm_address_t *target_address, mach_vm_size_t size, mach_vm_offset_t mask, - int flags, vm_map_t src_task, mach_vm_address_t src_address, boolean_t copy, - vm_prot_t *curr_protection, vm_prot_t *max_protection, vm_inherit_t inheritance); - -/* Routine mach_vm_page_query */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_page_query(vm_map_t target_map, mach_vm_offset_t offset, integer_t *disposition, integer_t *ref_count); - -/* Routine mach_vm_region_recurse */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_region_recurse(vm_map_t target_task, mach_vm_address_t *address, mach_vm_size_t *size, - natural_t *nesting_depth, vm_region_recurse_info_t info, mach_msg_type_number_t *infoCnt); - -/* Routine mach_vm_region */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_region(vm_map_t target_task, mach_vm_address_t *address, mach_vm_size_t *size, vm_region_flavor_t flavor, - vm_region_info_t info, mach_msg_type_number_t *infoCnt, mach_port_t *object_name); - -/* Routine _mach_make_memory_entry */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - _mach_make_memory_entry(vm_map_t target_task, memory_object_size_t *size, memory_object_offset_t offset, - vm_prot_t permission, mem_entry_name_port_t *object_handle, - mem_entry_name_port_t parent_handle); - -/* Routine mach_vm_purgable_control */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_purgable_control(vm_map_t target_task, mach_vm_address_t address, vm_purgable_t control, int *state); - -/* Routine mach_vm_page_info */ -#ifdef mig_external -mig_external -#else -extern -#endif /* mig_external */ - kern_return_t - mach_vm_page_info(vm_map_t target_task, mach_vm_address_t address, vm_page_info_flavor_t flavor, - vm_page_info_t info, mach_msg_type_number_t *infoCnt); - -__END_DECLS - -/********************** Caution **************************/ -/* The following data types should be used to calculate */ -/* maximum message sizes only. The actual message may be */ -/* smaller, and the position of the arguments within the */ -/* message layout may vary from what is presented here. */ -/* For example, if any of the arguments are variable- */ -/* sized, and less than the maximum is sent, the data */ -/* will be packed tight in the actual message to reduce */ -/* the presence of holes. */ -/********************** Caution **************************/ - -/* typedefs for all requests */ - -#ifndef __Request__mach_vm_subsystem__defined -#define __Request__mach_vm_subsystem__defined - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_vm_address_t address; - mach_vm_size_t size; - int flags; -} __Request__mach_vm_allocate_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_vm_address_t address; - mach_vm_size_t size; -} __Request__mach_vm_deallocate_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_vm_address_t address; - mach_vm_size_t size; - boolean_t set_maximum; - vm_prot_t new_protection; -} __Request__mach_vm_protect_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_vm_address_t address; - mach_vm_size_t size; - vm_inherit_t new_inheritance; -} __Request__mach_vm_inherit_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_vm_address_t address; - mach_vm_size_t size; -} __Request__mach_vm_read_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_vm_read_entry_t data_list; - natural_t count; -} __Request__mach_vm_read_list_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_ool_descriptor_t data; - /* end of the kernel processed data */ - NDR_record_t NDR; - mach_vm_address_t address; - mach_msg_type_number_t dataCnt; -} __Request__mach_vm_write_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_vm_address_t source_address; - mach_vm_size_t size; - mach_vm_address_t dest_address; -} __Request__mach_vm_copy_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_vm_address_t address; - mach_vm_size_t size; - mach_vm_address_t data; -} __Request__mach_vm_read_overwrite_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_vm_address_t address; - mach_vm_size_t size; - vm_sync_t sync_flags; -} __Request__mach_vm_msync_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_vm_address_t address; - mach_vm_size_t size; - vm_behavior_t new_behavior; -} __Request__mach_vm_behavior_set_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_port_descriptor_t object; - /* end of the kernel processed data */ - NDR_record_t NDR; - mach_vm_address_t address; - mach_vm_size_t size; - mach_vm_offset_t mask; - int flags; - memory_object_offset_t offset; - boolean_t copy; - vm_prot_t curr_protection; - vm_prot_t max_protection; - vm_inherit_t inheritance; -} __Request__mach_vm_map_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_vm_address_t address; - mach_vm_size_t size; - vm_machine_attribute_t attribute; - vm_machine_attribute_val_t value; -} __Request__mach_vm_machine_attribute_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_port_descriptor_t src_task; - /* end of the kernel processed data */ - NDR_record_t NDR; - mach_vm_address_t target_address; - mach_vm_size_t size; - mach_vm_offset_t mask; - int flags; - mach_vm_address_t src_address; - boolean_t copy; - vm_inherit_t inheritance; -} __Request__mach_vm_remap_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_vm_offset_t offset; -} __Request__mach_vm_page_query_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_vm_address_t address; - natural_t nesting_depth; - mach_msg_type_number_t infoCnt; -} __Request__mach_vm_region_recurse_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_vm_address_t address; - vm_region_flavor_t flavor; - mach_msg_type_number_t infoCnt; -} __Request__mach_vm_region_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_port_descriptor_t parent_handle; - /* end of the kernel processed data */ - NDR_record_t NDR; - memory_object_size_t size; - memory_object_offset_t offset; - vm_prot_t permission; -} __Request___mach_make_memory_entry_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_vm_address_t address; - vm_purgable_t control; - int state; -} __Request__mach_vm_purgable_control_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - mach_vm_address_t address; - vm_page_info_flavor_t flavor; - mach_msg_type_number_t infoCnt; -} __Request__mach_vm_page_info_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif -#endif /* !__Request__mach_vm_subsystem__defined */ - -/* union of all requests */ - -#ifndef __RequestUnion__mach_vm_subsystem__defined -#define __RequestUnion__mach_vm_subsystem__defined -union __RequestUnion__mach_vm_subsystem { - __Request__mach_vm_allocate_t Request_mach_vm_allocate; - __Request__mach_vm_deallocate_t Request_mach_vm_deallocate; - __Request__mach_vm_protect_t Request_mach_vm_protect; - __Request__mach_vm_inherit_t Request_mach_vm_inherit; - __Request__mach_vm_read_t Request_mach_vm_read; - __Request__mach_vm_read_list_t Request_mach_vm_read_list; - __Request__mach_vm_write_t Request_mach_vm_write; - __Request__mach_vm_copy_t Request_mach_vm_copy; - __Request__mach_vm_read_overwrite_t Request_mach_vm_read_overwrite; - __Request__mach_vm_msync_t Request_mach_vm_msync; - __Request__mach_vm_behavior_set_t Request_mach_vm_behavior_set; - __Request__mach_vm_map_t Request_mach_vm_map; - __Request__mach_vm_machine_attribute_t Request_mach_vm_machine_attribute; - __Request__mach_vm_remap_t Request_mach_vm_remap; - __Request__mach_vm_page_query_t Request_mach_vm_page_query; - __Request__mach_vm_region_recurse_t Request_mach_vm_region_recurse; - __Request__mach_vm_region_t Request_mach_vm_region; - __Request___mach_make_memory_entry_t Request__mach_make_memory_entry; - __Request__mach_vm_purgable_control_t Request_mach_vm_purgable_control; - __Request__mach_vm_page_info_t Request_mach_vm_page_info; -}; -#endif /* !__RequestUnion__mach_vm_subsystem__defined */ -/* typedefs for all replies */ - -#ifndef __Reply__mach_vm_subsystem__defined -#define __Reply__mach_vm_subsystem__defined - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - mach_vm_address_t address; -} __Reply__mach_vm_allocate_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; -} __Reply__mach_vm_deallocate_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; -} __Reply__mach_vm_protect_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; -} __Reply__mach_vm_inherit_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_ool_descriptor_t data; - /* end of the kernel processed data */ - NDR_record_t NDR; - mach_msg_type_number_t dataCnt; -} __Reply__mach_vm_read_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - mach_vm_read_entry_t data_list; -} __Reply__mach_vm_read_list_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; -} __Reply__mach_vm_write_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; -} __Reply__mach_vm_copy_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - mach_vm_size_t outsize; -} __Reply__mach_vm_read_overwrite_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; -} __Reply__mach_vm_msync_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; -} __Reply__mach_vm_behavior_set_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - mach_vm_address_t address; -} __Reply__mach_vm_map_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - vm_machine_attribute_val_t value; -} __Reply__mach_vm_machine_attribute_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - mach_vm_address_t target_address; - vm_prot_t curr_protection; - vm_prot_t max_protection; -} __Reply__mach_vm_remap_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - integer_t disposition; - integer_t ref_count; -} __Reply__mach_vm_page_query_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - mach_vm_address_t address; - mach_vm_size_t size; - natural_t nesting_depth; - mach_msg_type_number_t infoCnt; - int info[19]; -} __Reply__mach_vm_region_recurse_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_port_descriptor_t object_name; - /* end of the kernel processed data */ - NDR_record_t NDR; - mach_vm_address_t address; - mach_vm_size_t size; - mach_msg_type_number_t infoCnt; - int info[10]; -} __Reply__mach_vm_region_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - /* start of the kernel processed data */ - mach_msg_body_t msgh_body; - mach_msg_port_descriptor_t object_handle; - /* end of the kernel processed data */ - NDR_record_t NDR; - memory_object_size_t size; -} __Reply___mach_make_memory_entry_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - int state; -} __Reply__mach_vm_purgable_control_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif - -#ifdef __MigPackStructs -#pragma pack(4) -#endif -typedef struct { - mach_msg_header_t Head; - NDR_record_t NDR; - kern_return_t RetCode; - mach_msg_type_number_t infoCnt; - int info[32]; -} __Reply__mach_vm_page_info_t __attribute__((unused)); -#ifdef __MigPackStructs -#pragma pack() -#endif -#endif /* !__Reply__mach_vm_subsystem__defined */ - -/* union of all replies */ - -#ifndef __ReplyUnion__mach_vm_subsystem__defined -#define __ReplyUnion__mach_vm_subsystem__defined -union __ReplyUnion__mach_vm_subsystem { - __Reply__mach_vm_allocate_t Reply_mach_vm_allocate; - __Reply__mach_vm_deallocate_t Reply_mach_vm_deallocate; - __Reply__mach_vm_protect_t Reply_mach_vm_protect; - __Reply__mach_vm_inherit_t Reply_mach_vm_inherit; - __Reply__mach_vm_read_t Reply_mach_vm_read; - __Reply__mach_vm_read_list_t Reply_mach_vm_read_list; - __Reply__mach_vm_write_t Reply_mach_vm_write; - __Reply__mach_vm_copy_t Reply_mach_vm_copy; - __Reply__mach_vm_read_overwrite_t Reply_mach_vm_read_overwrite; - __Reply__mach_vm_msync_t Reply_mach_vm_msync; - __Reply__mach_vm_behavior_set_t Reply_mach_vm_behavior_set; - __Reply__mach_vm_map_t Reply_mach_vm_map; - __Reply__mach_vm_machine_attribute_t Reply_mach_vm_machine_attribute; - __Reply__mach_vm_remap_t Reply_mach_vm_remap; - __Reply__mach_vm_page_query_t Reply_mach_vm_page_query; - __Reply__mach_vm_region_recurse_t Reply_mach_vm_region_recurse; - __Reply__mach_vm_region_t Reply_mach_vm_region; - __Reply___mach_make_memory_entry_t Reply__mach_make_memory_entry; - __Reply__mach_vm_purgable_control_t Reply_mach_vm_purgable_control; - __Reply__mach_vm_page_info_t Reply_mach_vm_page_info; -}; -#endif /* !__RequestUnion__mach_vm_subsystem__defined */ - -#ifndef subsystem_to_name_map_mach_vm -#define subsystem_to_name_map_mach_vm \ - {"mach_vm_allocate", 4800}, {"mach_vm_deallocate", 4801}, {"mach_vm_protect", 4802}, {"mach_vm_inherit", 4803}, \ - {"mach_vm_read", 4804}, {"mach_vm_read_list", 4805}, {"mach_vm_write", 4806}, {"mach_vm_copy", 4807}, \ - {"mach_vm_read_overwrite", 4808}, {"mach_vm_msync", 4809}, {"mach_vm_behavior_set", 4810}, \ - {"mach_vm_map", 4811}, {"mach_vm_machine_attribute", 4812}, {"mach_vm_remap", 4813}, \ - {"mach_vm_page_query", 4814}, {"mach_vm_region_recurse", 4815}, {"mach_vm_region", 4816}, \ - {"_mach_make_memory_entry", 4817}, {"mach_vm_purgable_control", 4818}, { \ - "mach_vm_page_info", 4819 \ - } -#endif - -#ifdef __AfterMigUserHeader -__AfterMigUserHeader -#endif /* __AfterMigUserHeader */ - -#endif /* _mach_vm_user_ */ diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/platform-posix.cc b/app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/platform-posix.cc deleted file mode 100644 index 5894ae82..00000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/platform-posix.cc +++ /dev/null @@ -1,183 +0,0 @@ -#include -#include -#include -#include - -#if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__) -#include // for pthread_set_name_np -#endif - -#include // for sched_yield -#include -#include -#include - -#include -#include -#include -#include -#include - -#if defined(__APPLE__) || defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) -#include // NOLINT, for sysctl -#endif - -#include "logging/logging.h" -#include "logging/check_logging.h" -#include "PlatformUnifiedInterface/platform.h" - -#if defined(__APPLE__) -#include -#include -#include -#endif - -#if defined(ANDROID) && !defined(ANDROID_LOG_STDOUT) -#define ANDROID_LOG_TAG "Dobby" - -#include - -#endif - -#include - -#if defined(__APPLE__) -const int kMmapFd = VM_MAKE_TAG(255); -#else -const int kMmapFd = -1; -#endif - -const int kMmapFdOffset = 0; - -using namespace base; - -typedef struct thread_handle_t { - pthread_t thread; -} thread_handle_t; - -void ThreadInterface::SetName(const char *name) { -#if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__OpenBSD__) - pthread_set_name_np(pthread_self(), name); -#elif defined(__APPLE__) - pthread_setname_np(name); -#endif -} - -int ThreadInterface::CurrentId() { -#if defined(__APPLE__) - mach_port_t port = mach_thread_self(); - mach_port_deallocate(mach_task_self(), port); - return port; -#elif defined(_POSIX_VERSION) - return syscall(__NR_gettid); -#endif -} - -static void *thread_handler_wrapper(void *ctx) { - ThreadInterface::Delegate *d = (ThreadInterface::Delegate *)ctx; - d->ThreadMain(); - return nullptr; -} - -bool ThreadInterface::Create(ThreadInterface::Delegate *delegate, ThreadHandle *handle) { - thread_handle_t *handle_impl = new thread_handle_t; - - int err = 0; - err = pthread_create(&(handle_impl->thread), nullptr, thread_handler_wrapper, delegate); - if (err != 0) { - ERROR_LOG("pthread create failed"); - return false; - } - return true; -} - -OSThread::OSThread(const char *name) { - strncpy(name_, name, sizeof(name_) -1); -} - -bool OSThread::Start() { - if (ThreadInterface::Create(this, &handle_) == false) { - return false; - } - return true; -} - -static int GetProtectionFromMemoryPermission(MemoryPermission access) { - switch (access) { - case MemoryPermission::kNoAccess: - return PROT_NONE; - case MemoryPermission::kRead: - return PROT_READ; - case MemoryPermission::kReadWrite: - return PROT_READ | PROT_WRITE; - case MemoryPermission::kReadWriteExecute: - return PROT_READ | PROT_WRITE | PROT_EXEC; - case MemoryPermission::kReadExecute: - return PROT_READ | PROT_EXEC; - } - UNREACHABLE(); -} - -int OSMemory::PageSize() { - return static_cast(sysconf(_SC_PAGESIZE)); -} - -void *OSMemory::Allocate(size_t size, MemoryPermission access) { - return OSMemory::Allocate(size, access, nullptr); -} - -void *OSMemory::Allocate(size_t size, MemoryPermission access, void *fixed_address) { - int prot = GetProtectionFromMemoryPermission(access); - - int flags = MAP_PRIVATE | MAP_ANONYMOUS; - if (fixed_address != nullptr) { - flags = flags | MAP_FIXED; - } - void *result = mmap(fixed_address, size, prot, flags, kMmapFd, kMmapFdOffset); - if (result == MAP_FAILED) - return nullptr; - - return result; -} - -bool OSMemory::Free(void *address, size_t size) { - DCHECK_EQ(0, reinterpret_cast(address) % PageSize()); - DCHECK_EQ(0, size % PageSize()); - - return munmap(address, size) == 0; -} - -bool OSMemory::Release(void *address, size_t size) { - DCHECK_EQ(0, reinterpret_cast(address) % PageSize()); - DCHECK_EQ(0, size % PageSize()); - - return munmap(address, size) == 0; -} - -bool OSMemory::SetPermission(void *address, size_t size, MemoryPermission access) { - DCHECK_EQ(0, reinterpret_cast(address) % PageSize()); - DCHECK_EQ(0, size % PageSize()); - - int prot = GetProtectionFromMemoryPermission(access); - int ret = mprotect(address, size, prot); - if (ret) { - ERROR_LOG("OSMemory::SetPermission: %s\n", ((const char *)strerror(errno))); - } - - return ret == 0; -} - -void OSPrint::Print(const char *format, ...) { - va_list args; - va_start(args, format); - VPrint(format, args); - va_end(args); -} - -void OSPrint::VPrint(const char *format, va_list args) { -#if defined(ANDROID) && !defined(ANDROID_LOG_STDOUT) - __android_log_vprint(ANDROID_LOG_INFO, ANDROID_LOG_TAG, format, args); -#else - vprintf(format, args); -#endif -} diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/platform-windows.cc b/app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/platform-windows.cc deleted file mode 100644 index 30af5b84..00000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/platform-windows.cc +++ /dev/null @@ -1,86 +0,0 @@ -#include - -#include - -#include "logging/logging.h" -#include "logging/check_logging.h" -#include "PlatformUnifiedInterface/platform.h" - -int GetProtectionFromMemoryPermission(MemoryPermission access) { - if (kReadWriteExecute == access) - return PAGE_EXECUTE_READWRITE; - else if (kReadExecute == access) - return PAGE_EXECUTE_READ; -} - -int OSMemory::AllocPageSize() { - static int lastRet = -1; - if (lastRet == -1) { - SYSTEM_INFO si; - GetSystemInfo(&si); - lastRet = si.dwAllocationGranularity; // should be used with VirtualAlloc(MEM_RESERVE) - } - return lastRet; -} - -int OSMemory::PageSize() { - static int lastRet = -1; - if (lastRet == -1) { - SYSTEM_INFO si; - GetSystemInfo(&si); - lastRet = si.dwPageSize; // should be used with VirtualAlloc(MEM_RESERVE) - } - return lastRet; -} - -void *OSMemory::Allocate(void *address, int size, MemoryPermission access) { - DCHECK_EQ(0, reinterpret_cast(address) % AllocPageSize()); - DCHECK_EQ(0, size % PageSize()); - - void *result = VirtualAlloc(address, size, MEM_COMMIT | MEM_RESERVE, PAGE_NOACCESS); - OSMemory::SetPermission(result, size, kReadWriteExecute); - if (result == nullptr) - return nullptr; - - // TODO: if need align - void *aligned_base = result; - return static_cast(aligned_base); -} - -// static -bool OSMemory::Free(void *address, const int size) { - DCHECK_EQ(0, reinterpret_cast(address) % PageSize()); - DCHECK_EQ(0, size % PageSize()); - - return VirtualFree(address, size, MEM_RELEASE); -} - -bool OSMemory::Release(void *address, int size) { - DCHECK_EQ(0, reinterpret_cast(address) % PageSize()); - DCHECK_EQ(0, size % PageSize()); - - return OSMemory::Free(address, size); -} - -bool OSMemory::SetPermission(void *address, int size, MemoryPermission access) { - DCHECK_EQ(0, reinterpret_cast(address) % PageSize()); - DCHECK_EQ(0, size % PageSize()); - - int prot = GetProtectionFromMemoryPermission(access); - - DWORD oldProtect; - return VirtualProtect(address, size, prot, &oldProtect); -} - -// ===== - -void OSPrint::Print(const char *format, ...) { - va_list args; - va_start(args, format); - VPrint(format, args); - va_end(args); -} - -void OSPrint::VPrint(const char *format, va_list args) { - vprintf(format, args); -} diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/semaphore.cc b/app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/semaphore.cc deleted file mode 100644 index b454c6e3..00000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/semaphore.cc +++ /dev/null @@ -1,160 +0,0 @@ -// Copyright 2013 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "src/base/platform/semaphore.h" - -#if V8_OS_MACOSX -#include -#endif - -#include - -#include "src/base/logging.h" -#include "src/base/platform/elapsed-timer.h" -#include "src/base/platform/time.h" - -namespace v8 { -namespace base { - -#if V8_OS_MACOSX - -Semaphore::Semaphore(int count) { - native_handle_ = dispatch_semaphore_create(count); - DCHECK(native_handle_); -} - -Semaphore::~Semaphore() { - dispatch_release(native_handle_); -} - -void Semaphore::Signal() { - dispatch_semaphore_signal(native_handle_); -} - -void Semaphore::Wait() { - dispatch_semaphore_wait(native_handle_, DISPATCH_TIME_FOREVER); -} - -bool Semaphore::WaitFor(const TimeDelta &rel_time) { - dispatch_time_t timeout = dispatch_time(DISPATCH_TIME_NOW, rel_time.InNanoseconds()); - return dispatch_semaphore_wait(native_handle_, timeout) == 0; -} - -#elif V8_OS_POSIX - -Semaphore::Semaphore(int count) { - DCHECK_GE(count, 0); - int result = sem_init(&native_handle_, 0, count); - DCHECK_EQ(0, result); - USE(result); -} - -Semaphore::~Semaphore() { - int result = sem_destroy(&native_handle_); - DCHECK_EQ(0, result); - USE(result); -} - -void Semaphore::Signal() { - int result = sem_post(&native_handle_); - // This check may fail with 0) { - // sem_timedwait in glibc prior to 2.3.4 returns the errno instead of -1. - errno = result; - result = -1; - } -#endif - if (result == -1 && errno == ETIMEDOUT) { - // Timed out while waiting for semaphore. - return false; - } - // Signal caused spurious wakeup. - DCHECK_EQ(-1, result); - DCHECK_EQ(EINTR, errno); - } -} - -#elif V8_OS_WIN - -Semaphore::Semaphore(int count) { - DCHECK_GE(count, 0); - native_handle_ = ::CreateSemaphoreA(nullptr, count, 0x7FFFFFFF, nullptr); - DCHECK_NOT_NULL(native_handle_); -} - -Semaphore::~Semaphore() { - BOOL result = CloseHandle(native_handle_); - DCHECK(result); - USE(result); -} - -void Semaphore::Signal() { - LONG dummy; - BOOL result = ReleaseSemaphore(native_handle_, 1, &dummy); - DCHECK(result); - USE(result); -} - -void Semaphore::Wait() { - DWORD result = WaitForSingleObject(native_handle_, INFINITE); - DCHECK(result == WAIT_OBJECT_0); - USE(result); -} - -bool Semaphore::WaitFor(const TimeDelta &rel_time) { - TimeTicks now = TimeTicks::Now(); - TimeTicks end = now + rel_time; - while (true) { - int64_t msec = (end - now).InMilliseconds(); - if (msec >= static_cast(INFINITE)) { - DWORD result = WaitForSingleObject(native_handle_, INFINITE - 1); - if (result == WAIT_OBJECT_0) { - return true; - } - DCHECK(result == WAIT_TIMEOUT); - now = TimeTicks::Now(); - } else { - DWORD result = WaitForSingleObject(native_handle_, (msec < 0) ? 0 : static_cast(msec)); - if (result == WAIT_TIMEOUT) { - return false; - } - DCHECK(result == WAIT_OBJECT_0); - return true; - } - } -} - -#endif // V8_OS_MACOSX - -} // namespace base -} // namespace v8 diff --git a/app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/semaphore.h b/app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/semaphore.h deleted file mode 100644 index cff4cd47..00000000 --- a/app/src/main/cpp/Dobby/source/Backend/UserMode/UnifiedInterface/semaphore.h +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2013 the V8 project authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef V8_BASE_PLATFORM_SEMAPHORE_H_ -#define V8_BASE_PLATFORM_SEMAPHORE_H_ - -#include "src/base/base-export.h" -#include "src/base/lazy-instance.h" -#if V8_OS_WIN -#include "src/base/win32-headers.h" -#endif - -#if V8_OS_MACOSX -#include // NOLINT -#elif V8_OS_POSIX -#include // NOLINT -#endif - -namespace v8 { -namespace base { - -// Forward declarations. -class TimeDelta; - -// ---------------------------------------------------------------------------- -// Semaphore -// -// A semaphore object is a synchronization object that maintains a count. The -// count is decremented each time a thread completes a wait for the semaphore -// object and incremented each time a thread signals the semaphore. When the -// count reaches zero, threads waiting for the semaphore blocks until the -// count becomes non-zero. - -class V8_BASE_EXPORT Semaphore final { -public: - explicit Semaphore(int count); - ~Semaphore(); - - // Increments the semaphore counter. - void Signal(); - - // Decrements the semaphore counter if it is positive, or blocks until it - // becomes positive and then decrements the counter. - void Wait(); - - // Like Wait() but returns after rel_time time has passed. If the timeout - // happens the return value is false and the counter is unchanged. Otherwise - // the semaphore counter is decremented and true is returned. - bool WaitFor(const TimeDelta &rel_time) V8_WARN_UNUSED_RESULT; - -#if V8_OS_MACOSX - using NativeHandle = dispatch_semaphore_t; -#elif V8_OS_POSIX - using NativeHandle = sem_t; -#elif V8_OS_WIN - using NativeHandle = HANDLE; -#endif - - NativeHandle &native_handle() { - return native_handle_; - } - const NativeHandle &native_handle() const { - return native_handle_; - } - -private: - NativeHandle native_handle_; - - DISALLOW_COPY_AND_ASSIGN(Semaphore); -}; - -// POD Semaphore initialized lazily (i.e. the first time Pointer() is called). -// Usage: -// // The following semaphore starts at 0. -// static LazySemaphore<0>::type my_semaphore = LAZY_SEMAPHORE_INITIALIZER; -// -// void my_function() { -// // Do something with my_semaphore.Pointer(). -// } -// - -template struct CreateSemaphoreTrait { - static Semaphore *Create() { - return new Semaphore(N); - } -}; - -template struct LazySemaphore { - using typename LazyDynamicInstance, ThreadSafeInitOnceTrait>::type; -}; - -#define LAZY_SEMAPHORE_INITIALIZER LAZY_DYNAMIC_INSTANCE_INITIALIZER - -} // namespace base -} // namespace v8 - -#endif // V8_BASE_PLATFORM_SEMAPHORE_H_ diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/InstructionRelocation.h b/app/src/main/cpp/Dobby/source/InstructionRelocation/InstructionRelocation.h deleted file mode 100644 index 079fc78e..00000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/InstructionRelocation.h +++ /dev/null @@ -1,5 +0,0 @@ -#include "dobby/dobby_internal.h" - -void GenRelocateCode(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated, bool branch); - -void GenRelocateCodeAndBranch(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated); diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/arm/InstructionRelocationARM.cc b/app/src/main/cpp/Dobby/source/InstructionRelocation/arm/InstructionRelocationARM.cc deleted file mode 100644 index 1e8f15eb..00000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/arm/InstructionRelocationARM.cc +++ /dev/null @@ -1,895 +0,0 @@ -#include "platform_detect_macro.h" - -#if defined(TARGET_ARCH_ARM) - -#include "dobby/dobby_internal.h" - -#include "InstructionRelocation/arm/InstructionRelocationARM.h" - -#include "core/arch/arm/registers-arm.h" -#include "core/assembler/assembler-arm.h" -#include "core/codegen/codegen-arm.h" - -using namespace zz; -using namespace zz::arm; - -typedef struct { - addr_t mapped_addr; - - bool thumb_mode; - - uint8_t *buffer; - uint8_t *buffer_cursor; - size_t buffer_size; - - addr_t src_vmaddr; - addr_t dst_vmaddr; - - CodeMemBlock *relocated; - CodeBuffer *relocated_buffer; - - ExecuteState start_state; - ExecuteState curr_state; - Assembler *curr_assembler; - ThumbTurboAssembler *thumb_assembler; - TurboAssembler *arm_assembler; - - tinystl::unordered_map execute_state_map; - - tinystl::unordered_map relocated_offset_map; - - tinystl::unordered_map label_map; -} relo_ctx_t; - -// --- - -addr_t relo_cur_src_vmaddr(relo_ctx_t *ctx) { - int relocated_len = ctx->buffer_cursor - ctx->buffer; - if (ctx->curr_state == zz::arm::ARMExecuteState) { - return ctx->src_vmaddr + relocated_len + ARM_PC_OFFSET; - } else { - return ctx->src_vmaddr + relocated_len + Thumb_PC_OFFSET; - } -} - -static bool is_thumb2(uint32_t insn) { - uint16_t insn1, insn2; - insn1 = insn & 0x0000ffff; - insn2 = (insn & 0xffff0000) >> 16; - // refer: Top level T32 instruction set encoding - uint32_t op0 = bits(insn1, 13, 15); - uint32_t op1 = bits(insn1, 11, 12); - - if (op0 == 0b111 && op1 != 0b00) { - return true; - } - return false; -} - -bool check_execute_state_changed(relo_ctx_t *ctx, addr_t insn_addr) { - for (auto iter = ctx->execute_state_map.begin(); iter != ctx->execute_state_map.end(); ++iter) { - addr_t execute_state_changed_pc = iter->first; - auto state = iter->second; - if (execute_state_changed_pc == insn_addr) { - return true; - } - } - return false; -} - -static inline int32_t SignExtend(unsigned x, int M, int N) { -#if 1 - char sign_bit = bit(x, M - 1); - unsigned sign_mask = 0 - sign_bit; - x |= ((sign_mask >> M) << M); -#else - x = (long)((long)x << (N - M)) >> (N - M); -#endif - return (int32_t)x; -} - -enum arm_shift_type { arm_shift_lsl, arm_shift_lsr, arm_shift_asr, arm_shift_ror, arm_shift_rrx }; - -uint32_t arm_shift_c(uint32_t val, uint32_t shift_type, uint32_t shift_count, uint32_t carry_in, uint32_t *carry_out) { - if (shift_count == 0) - return val; - uint32_t r_val; - uint32_t carry = carry_in; - switch (shift_type) { - case arm_shift_lsl: - r_val = val; - r_val = r_val << shift_count; - carry = (r_val >> 32) & 0x1; - val = r_val; - break; - case arm_shift_lsr: - r_val = val; - r_val = r_val >> (shift_count - 1); - carry = r_val & 0x1; - val = (r_val >> 1); - break; - case arm_shift_asr: - r_val = val; - if (val & 0x80000000) { - r_val |= 0xFFFFFFFF00000000ULL; - } - r_val = r_val >> (shift_count - 1); - carry = r_val & 0x1; - val = (r_val >> 1); - break; - case arm_shift_ror: - val = (val >> (shift_count % 32)) | (val << (32 - (shift_count % 32))); - carry = (val >> 31); - break; - case arm_shift_rrx: - carry = val & 0x1; - val = (carry_in << 31) | (val >> 1); - break; - break; - } - return val; -} - -uint32_t arm_expand_imm_c(uint32_t imm12) { - uint32_t unrotated_value = bits(imm12, 0, 7); - return arm_shift_c(unrotated_value, arm_shift_ror, 2 * bits(imm12, 8, 11), 0, 0); -} - -uint32_t A32ExpandImm(uint32_t imm12) { - return arm_expand_imm_c(imm12); -} - -static void ARMRelocateSingleInsn(relo_ctx_t *ctx, int32_t insn) { - auto turbo_assembler_ = static_cast(ctx->curr_assembler); -#define _ turbo_assembler_-> - - bool is_insn_relocated = false; - - // top level encoding - uint32_t cond, op0, op1; - cond = bits(insn, 28, 31); - op0 = bits(insn, 25, 27); - op1 = bit(insn, 4); - // Load/Store Word, Unsigned byte (immediate, literal) - if (cond != 0b1111 && op0 == 0b010) { - uint32_t P, U, o2, W, o1, Rn, Rt, imm12; - P = bit(insn, 24); - U = bit(insn, 23); - W = bit(insn, 21); - imm12 = bits(insn, 0, 11); - Rn = bits(insn, 16, 19); - Rt = bits(insn, 12, 15); - o1 = bit(insn, 20); - o2 = bit(insn, 22); - uint32_t P_W = (P << 1) | W; - do { - // LDR (literal) - DEBUG_LOG("%d:relo at %p", ctx->relocated_offset_map.size(), relo_cur_src_vmaddr(ctx)); - if (o1 == 1 && o2 == 0 && P_W != 0b01 && Rn == 0b1111) { - goto load_literal_fix_scheme; - } - if (o1 == 1 && o2 == 1 && P_W != 0b01 && Rn == 0b1111) { - goto load_literal_fix_scheme; - } - break; - load_literal_fix_scheme: - addr32_t dst_vmaddr = 0; - if (U == 0b1) - dst_vmaddr = relo_cur_src_vmaddr(ctx) + imm12; - else - dst_vmaddr = relo_cur_src_vmaddr(ctx) - imm12; - Register regRt = Register::R(Rt); - - auto label = RelocLabel::withData(dst_vmaddr); - _ AppendRelocLabel(label); - - if (regRt.code() == pc.code()) { - _ Ldr(VOLATILE_REGISTER, label); - _ ldr(regRt, MemOperand(VOLATILE_REGISTER)); - } else { - _ Ldr(regRt, label); - _ ldr(regRt, MemOperand(regRt)); - } - - is_insn_relocated = true; - } while (0); - } - - // Data-processing and miscellaneous instructions - if (cond != 0b1111 && (op0 & 0b110) == 0b000) { - uint32_t op0, op1, op2, op3, op4; - op0 = bit(insn, 25); - // Data-processing immediate - if (op0 == 1) { - uint32_t op0, op1; - op0 = bits(insn, 23, 24); - op1 = bits(insn, 20, 21); - // Integer Data Processing (two register and immediate) - if ((op0 & 0b10) == 0b00) { - DEBUG_LOG("%d:relo at %p", ctx->relocated_offset_map.size(), relo_cur_src_vmaddr(ctx)); - - uint32_t opc, S, Rn; - opc = bits(insn, 21, 23); - S = bit(insn, 20); - Rn = bits(insn, 16, 19); - - uint32_t dst_vmaddr = -1; - int Rd = bits(insn, 12, 15); - int imm12 = bits(insn, 0, 11); - uint32_t imm = arm_expand_imm_c(imm12); - if (opc == 0b010 && S == 0b0 && Rn == 0b1111) { // ADR - A2 variant - dst_vmaddr = relo_cur_src_vmaddr(ctx) - imm; - } else if (opc == 0b100 && S == 0b0 && Rn == 0b1111) { // ADR - A1 variant - dst_vmaddr = relo_cur_src_vmaddr(ctx) + imm; - } - - if (dst_vmaddr != -1) { - Register regRd = Register::R(Rd); - auto dst_label = RelocLabel::withData(dst_vmaddr); - _ AppendRelocLabel(dst_label); - - _ Ldr(regRd, dst_label); - - is_insn_relocated = true; - } - } - } - } - - // Branch, branch with link, and block data transfer - if ((op0 & 0b110) == 0b100) { - uint32_t cond, op0; - cond = bits(insn, 28, 31); - op0 = bit(insn, 25); - // Branch (immediate) on page F4-4034 - if (op0 == 1) { - DEBUG_LOG("%d:relo at %p", ctx->relocated_offset_map.size(), relo_cur_src_vmaddr(ctx)); - - uint32_t H = 0, imm24 = 0; - H = bit(insn, 24); - imm24 = bits(insn, 0, 23); - int32_t label = SignExtend(imm24 << 2, 2 + 24, 32); - uint32_t dst_vmaddr = relo_cur_src_vmaddr(ctx) + label; - bool branch_link; - if (cond != 0b1111 && H == 0) { // B - branch_link = false; - } else if (cond != 0b1111 && H == 1) { // BL, BLX (immediate) - A1 on page F5-4135 - branch_link = true; - } else if (cond == 0b1111) { // BL, BLX (immediate) - A2 on page F5-4135 - branch_link = true; - cond = AL; - dst_vmaddr |= 1; - } else - UNREACHABLE(); - - if (branch_link) - _ bl((Condition)cond, 0); // goto [dst_vmaddr] - else - _ b((Condition)cond, 0); // goto [dst_vmaddr] - _ b(4); // goto [rest_flow] - // [dst_vmaddr] - _ ldr(pc, MemOperand(pc, -4)); - _ EmitAddress(dst_vmaddr); - // [rest_flow] - _ mov(r8, r8); - - is_insn_relocated = true; - } - } - - // if the insn do not needed relocate, just rewrite the origin - if (!is_insn_relocated) { - _ EmitARMInst(insn); - } -} - -// relocate thumb-1 instructions -static void Thumb1RelocateSingleInsn(relo_ctx_t *ctx, int16_t insn) { - auto turbo_assembler_ = static_cast(ctx->curr_assembler); -#define _ turbo_assembler_-> - - bool is_insn_relocated = false; - - _ AlignThumbNop(); - - uint32_t op = 0, rt = 0, rm = 0, rn = 0, rd = 0, shift = 0, cond = 0; - int32_t offset = 0; - - int32_t op0 = 0, op1 = 0; - op0 = bits(insn, 10, 15); - // Special data instructions and branch and exchange on page F3-3942 - if (op0 == 0b010001) { - op0 = bits(insn, 8, 9); - // Add, subtract, compare, move (two high registers) - if (op0 != 0b11) { - int rs = bits(insn, 3, 6); - // rs is PC register - if (rs == 15) { - DEBUG_LOG("%d:relo at %p", ctx->relocated_offset_map.size(), - relo_cur_src_vmaddr(ctx)); - - thumb1_inst_t rewrite_inst = insn; - set_bits(rewrite_inst, 3, 6, VOLATILE_REGISTER.code()); - - auto label = ThumbRelocLabelEntry::withData(relo_cur_src_vmaddr(ctx), false); - _ AppendRelocLabel(label); - - _ T2_Ldr(VOLATILE_REGISTER, label); - _ EmitInt16(rewrite_inst); - - is_insn_relocated = true; - } - } - - // Branch and exchange - if (op0 == 0b11) { - int32_t L = bit(insn, 7); - rm = bits(insn, 3, 6); - // BX - if (L == 0b0) { - if (rm == pc.code()) { - DEBUG_LOG("%d:relo at %p", ctx->relocated_offset_map.size(), relo_cur_src_vmaddr(ctx)); - - addr_t dst_vmaddr = relo_cur_src_vmaddr(ctx); - auto label = ThumbRelocLabelEntry::withData(dst_vmaddr, true); - _ AppendRelocLabel(label); - - _ T2_Ldr(pc, label); - - ctx->execute_state_map[dst_vmaddr] = ARMExecuteState; - - is_insn_relocated = true; - } - } - // BLX - if (L == 0b1) { - if (rm == pc.code()) { - DEBUG_LOG("%d:relo at %p", ctx->relocated_offset_map.size(), relo_cur_src_vmaddr(ctx)); - - addr_t dst_vmaddr = relo_cur_src_vmaddr(ctx); - auto label = ThumbRelocLabelEntry::withData(dst_vmaddr, true); - _ AppendRelocLabel(label); - - _ t2_bl(4); - _ t2_b(4); // goto [rest flow] - _ T2_Ldr(pc, label); // goto [dst_vmaddr] - // [rest flow] - - ctx->execute_state_map[dst_vmaddr] = ARMExecuteState; - - is_insn_relocated = true; - } - } - } - } - - // LDR (literal) - T1 variant on page F5-4243 - // ldr literal - if ((insn & 0xf800) == 0x4800) { - DEBUG_LOG("%d:relo at %p", ctx->relocated_offset_map.size(), relo_cur_src_vmaddr(ctx)); - - uint32_t imm8 = bits(insn, 0, 7); - uint32_t imm = imm8 << 2; - addr_t dst_vmaddr = relo_cur_src_vmaddr(ctx) + imm; - dst_vmaddr = ALIGN_FLOOR(dst_vmaddr, 4); - rt = bits(insn, 8, 10); - - auto label = ThumbRelocLabelEntry::withData(dst_vmaddr, false); - _ AppendRelocLabel(label); - - _ T2_Ldr(Register::R(rt), label); - _ t2_ldr(Register::R(rt), MemOperand(Register::R(rt), 0)); - - is_insn_relocated = true; - } - - // Add PC/SP (immediate) on page F3-3939 - // adr - if ((insn & 0xf800) == 0xa000) { - DEBUG_LOG("%d:relo at %p", ctx->relocated_offset_map.size(), relo_cur_src_vmaddr(ctx)); - - rd = bits(insn, 8, 10); - uint32_t imm8 = bits(insn, 0, 7); - int32_t imm32 = imm8 << 2; - addr_t dst_vmaddr = relo_cur_src_vmaddr(ctx) + imm32; - - auto label = ThumbRelocLabelEntry::withData(dst_vmaddr, false); - _ AppendRelocLabel(label); - - _ T2_Ldr(Register::R(rd), label); - - is_insn_relocated = true; - } - - // Conditional branch, and Supervisor Call on page F3-3946 - // b - if ((insn & 0xf000) == 0xd000) { - DEBUG_LOG("%d:relo at %p", ctx->relocated_offset_map.size(), relo_cur_src_vmaddr(ctx)); - - uint16_t cond = bits(insn, 8, 11); - // cond != 111x - if (cond >= 0b1110) { - UNREACHABLE(); - } - uint32_t imm8 = bits(insn, 0, 7); - int32_t imm = SignExtend(imm8 << 1, 8 + 1, 32); - addr_t dst_vmaddr = relo_cur_src_vmaddr(ctx) + imm; - dst_vmaddr |= 1; - - auto label = ThumbRelocLabelEntry::withData(dst_vmaddr, true); - _ AppendRelocLabel(label); - - thumb1_inst_t b_cond_insn = 0xe000; - set_bits(b_cond_insn, 8, 11, cond); - _ EmitInt16(b_cond_insn | (4 >> 1)); - _ t1_nop(); // align - _ t2_b(4); - _ T2_Ldr(pc, label); - - is_insn_relocated = true; - } - - // Miscellaneous 16-bit instructions on page F3-3943 - // CBNZ, CBZ - if ((insn & 0xf500) == 0xb100) { - DEBUG_LOG("%d:relo at %p", ctx->relocated_offset_map.size(), relo_cur_src_vmaddr(ctx)); - - uint32_t imm5 = bits(insn, 3, 7); - uint32_t i = bit(insn, 9); - uint32_t imm = (i << 6) | (imm5 << 1); - addr_t dst_vmaddr = relo_cur_src_vmaddr(ctx) + imm; - - rn = bits(insn, 0, 2); - - auto label = ThumbRelocLabelEntry::withData(dst_vmaddr + 1, true); - _ AppendRelocLabel(label); - - imm5 = bits(0x4, 1, 5); - set_bits(insn, 3, 7, imm5); - i = bit(0x4, 6); - set_bit(insn, 9, i); - _ EmitInt16(insn); - _ t1_nop(); // align - _ t2_b(4); // goto [rest flow] - _ T2_Ldr(pc, label); - // [rest flow] - - is_insn_relocated = true; - } - - // F3.1 - // T32 instruction set encoding - // b - if ((insn & 0xf800) == 0xe000) { - DEBUG_LOG("%d:relo at %p", ctx->relocated_offset_map.size(), relo_cur_src_vmaddr(ctx)); - - uint32_t imm11 = bits(insn, 0, 10); - int32_t imm = SignExtend(imm11 << 1, 11 + 1, 32); - addr_t dst_vmaddr = relo_cur_src_vmaddr(ctx) + imm; - - auto label = ThumbRelocLabelEntry::withData(dst_vmaddr + 1, true); - _ AppendRelocLabel(label); - - _ T2_Ldr(pc, label); - - is_insn_relocated = true; - } - - // if the insn do not needed relocate, just rewrite the origin - if (!is_insn_relocated) { -#if 0 - if (relo_cur_src_vmaddr(ctx) % Thumb2_INST_LEN) - _ t1_nop(); -#endif - _ EmitInt16(insn); - } -} - -static void Thumb2RelocateSingleInsn(relo_ctx_t *ctx, thumb1_inst_t insn1, thumb1_inst_t insn2) { - auto turbo_assembler_ = static_cast(ctx->curr_assembler); -#define _ turbo_assembler_-> - - bool is_insn_relocated = false; - - // if (turbo_assembler->pc_offset() % 4) { - // _ t1_nop(); - // } - - _ AlignThumbNop(); - - // Branches and miscellaneous control on page F3-3979 - if ((insn1 & 0xf800) == 0xf000 && (insn2 & 0x8000) == 0x8000) { - uint32_t op1 = 0, op3 = 0; - op1 = bits(insn1, 6, 9); - op3 = bits(insn2, 12, 14); - - // B - T3 variant on page F5-4118 - if (((op1 & 0b1110) != 0b1110) && ((op3 & 0b101) == 0b000)) { - DEBUG_LOG("%d:relo at %p", ctx->relocated_offset_map.size(), relo_cur_src_vmaddr(ctx)); - - uint32_t S = bit(insn1, 10); - uint32_t J1 = bit(insn2, 13); - uint32_t J2 = bit(insn2, 11); - uint32_t imm6 = bits(insn1, 0, 5); - uint32_t imm11 = bits(insn2, 0, 10); - - int32_t imm = - SignExtend((S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1), 1 + 1 + 1 + 6 + 11 + 1, 32); - addr_t dst_vmaddr = relo_cur_src_vmaddr(ctx) + imm; - dst_vmaddr |= 1; - - uint32_t cond = bits(insn1, 6, 9); - thumb1_inst_t b_cond_insn = 0xe000; - set_bits(b_cond_insn, 8, 11, cond); - _ EmitInt16(b_cond_insn | (4 >> 1)); - _ t1_nop(); // align - _ t2_b(8); - _ t2_ldr(pc, MemOperand(pc, 0)); - _ EmitAddress(dst_vmaddr); - - is_insn_relocated = true; - } - - // B - T4 variant on page F5-4118 - if ((op3 & 0b101) == 0b001) { - DEBUG_LOG("%d:relo at %p", ctx->relocated_offset_map.size(), relo_cur_src_vmaddr(ctx)); - - uint32_t S = bit(insn1, 10); - uint32_t J1 = bit(insn2, 13); - uint32_t J2 = bit(insn2, 11); - uint32_t imm10 = bits(insn1, 0, 9); - uint32_t imm11 = bits(insn2, 0, 10); - uint32_t i1 = !(J1 ^ S); - uint32_t i2 = !(J2 ^ S); - - int32_t imm = - SignExtend((S << 24) | (i1 << 23) | (i2 << 22) | (imm10 << 12) | (imm11 << 1), 1 + 1 + 1 + 10 + 11 + 1, 32); - addr_t dst_vmaddr = relo_cur_src_vmaddr(ctx) + imm; - dst_vmaddr |= 1; - - _ t2_ldr(pc, MemOperand(pc, 0)); - _ EmitAddress(dst_vmaddr); - - is_insn_relocated = true; - } - - // BL, BLX (immediate) - T1 variant on page F5-4135 - if ((op3 & 0b101) == 0b101) { - DEBUG_LOG("%d:relo at %p", ctx->relocated_offset_map.size(), relo_cur_src_vmaddr(ctx)); - - uint32_t S = bit(insn1, 10); - uint32_t J1 = bit(insn2, 13); - uint32_t J2 = bit(insn2, 11); - uint32_t i1 = !(J1 ^ S); - uint32_t i2 = !(J2 ^ S); - uint32_t imm11 = bits(insn2, 0, 10); - uint32_t imm10 = bits(insn1, 0, 9); - int32_t imm = - SignExtend((S << 24) | (i1 << 23) | (i2 << 22) | (imm10 << 12) | (imm11 << 1), 1 + 1 + 1 + 10 + 11 + 1, 32); - addr_t dst_vmaddr = relo_cur_src_vmaddr(ctx) + imm; - dst_vmaddr |= 1; - - _ t2_bl(4); - _ t2_b(8); - _ t2_ldr(pc, MemOperand(pc, 0)); - _ EmitAddress(dst_vmaddr); - - is_insn_relocated = true; - } - - // BL, BLX (immediate) - T2 variant on page F5-4136 - if ((op3 & 0b101) == 0b100) { - DEBUG_LOG("%d:relo at %p", ctx->relocated_offset_map.size(), relo_cur_src_vmaddr(ctx)); - - uint32_t S = bit(insn1, 10); - uint32_t J1 = bit(insn2, 13); - uint32_t J2 = bit(insn2, 11); - uint32_t i1 = !(J1 ^ S); - uint32_t i2 = !(J2 ^ S); - uint32_t imm10h = bits(insn1, 0, 9); - uint32_t imm10l = bits(insn2, 1, 10); - int32_t imm = - SignExtend((S << 24) | (i1 << 23) | (i2 << 22) | (imm10h << 12) | (imm10l << 2), 1 + 1 + 1 + 10 + 10 + 1, 32); - addr_t dst_vmaddr = relo_cur_src_vmaddr(ctx); - dst_vmaddr = ALIGN_FLOOR(dst_vmaddr, 4); - dst_vmaddr += imm; - - _ t2_bl(4); - _ t2_b(8); - _ t2_ldr(pc, MemOperand(pc, 0)); - _ EmitAddress(dst_vmaddr); - - is_insn_relocated = true; - } - } - - // Data-processing (plain binary immediate) on page F3-3983 - if ((insn1 & (0xfa10)) == 0xf200 & (insn2 & 0x8000) == 0) { - uint32_t op0 = 0, op1 = 0; - op0 = bit(insn1, 8); - op1 = bits(insn2, 5, 6); - - // Data-processing (simple immediate) - if (op0 == 0 && (op1 & 0b10) == 0b00) { - int o1 = bit(insn1, 7); - int o2 = bit(insn1, 5); - int rn = bits(insn1, 0, 3); - - // ADR - if (((o1 == 0 && o2 == 0) || (o1 == 1 && o2 == 1)) && rn == 0b1111) { - uint32_t i = bit(insn1, 10); - uint32_t imm3 = bits(insn2, 12, 14); - uint32_t imm8 = bits(insn2, 0, 7); - uint32_t rd = bits(insn2, 8, 11); - uint32_t imm = (i << 11) | (imm3 << 8) | imm8; - - addr_t dst_vmaddr = 0; - if (o1 == 0 && o2 == 0) { // ADR - T3 on page F5-4098 - dst_vmaddr = relo_cur_src_vmaddr(ctx) + imm; - } else if (o1 == 1 && o2 == 1) { // ADR - T2 on page F5-4097 - dst_vmaddr = relo_cur_src_vmaddr(ctx) - imm; - } else { - UNREACHABLE(); - } - - _ t2_ldr(Register::R(rd), MemOperand(pc, 4)); - _ t2_b(0); - _ EmitAddress(dst_vmaddr); - - is_insn_relocated = true; - } - } - } - - // Load/store single on page F3-3988 - // Load, unsigned (literal) on page F3-3992 - // Load, signed (literal) on page F3-3996 - // LDR literal (T2) - if ((insn1 & 0xff7f) == 0xf85f) { - uint32_t U = bit(insn1, 7); - uint32_t imm12 = bits(insn2, 0, 11); - uint16_t rt = bits(insn2, 12, 15); - - uint32_t imm = imm12; - - addr_t dst_vmaddr = 0; - if (U == 1) { - dst_vmaddr = relo_cur_src_vmaddr(ctx) + imm; - } else { - dst_vmaddr = relo_cur_src_vmaddr(ctx) - imm; - } - - Register regRt = Register::R(rt); - - _ t2_ldr(regRt, MemOperand(pc, 8)); - _ t2_ldr(regRt, MemOperand(regRt, 0)); - _ t2_b(4); - _ EmitAddress(dst_vmaddr); - - is_insn_relocated = true; - } - - // if the insn not needed relocate, just rewrite the origin - if (!is_insn_relocated) { -#if 0 - if (relo_cur_src_vmaddr(ctx) % Thumb2_INST_LEN) - _ t1_nop(); -#endif - _ EmitInt16(insn1); - _ EmitInt16(insn2); - } -} - -void gen_arm_relocate_code(relo_ctx_t *ctx) { - -#undef _ -#define _ turbo_assembler_-> - auto turbo_assembler_ = static_cast(ctx->curr_assembler); -#define _ turbo_assembler_-> - - auto relocated_buffer = turbo_assembler_->GetCodeBuffer(); - - DEBUG_LOG("[arm] ARM relocate %d start >>>>>", ctx->buffer_size); - - while (ctx->buffer_cursor < ctx->buffer + ctx->buffer_size) { - uint32_t orig_off = ctx->buffer_cursor - ctx->buffer; - uint32_t relocated_off = relocated_buffer->GetBufferSize(); - ctx->relocated_offset_map[orig_off] = relocated_off; - - arm_inst_t insn = *(arm_inst_t *)ctx->buffer_cursor; - - int last_relo_offset = turbo_assembler_->GetCodeBuffer()->GetBufferSize(); - - ARMRelocateSingleInsn(ctx, insn); - DEBUG_LOG("[arm] Relocate arm insn: 0x%x", insn); - - // move to next instruction - ctx->buffer_cursor += ARM_INST_LEN; - - // execute state changed - addr32_t next_insn_addr = relo_cur_src_vmaddr(ctx) - ARM_PC_OFFSET; - if (check_execute_state_changed(ctx, next_insn_addr)) { - break; - } - } - - bool is_relocate_interrupted = ctx->buffer_cursor < ctx->buffer + ctx->buffer_size; - if (is_relocate_interrupted) { - turbo_assembler_->SetExecuteState(ThumbExecuteState); - } -} - -void gen_thumb_relocate_code(relo_ctx_t *ctx) { - int relocated_insn_count = 0; - - auto turbo_assembler_ = static_cast(ctx->curr_assembler); -#define _ turbo_assembler_-> - - auto relocated_buffer = turbo_assembler_->GetCodeBuffer(); - - DEBUG_LOG("[arm] Thumb relocate %d start >>>>>", ctx->buffer_size); - - while (ctx->buffer_cursor < ctx->buffer + ctx->buffer_size) { - uint32_t orig_off = ctx->buffer_cursor - ctx->buffer; - uint32_t relocated_off = relocated_buffer->GetBufferSize(); - ctx->relocated_offset_map[orig_off] = relocated_off; - - // align nop - _ t1_nop(); - - thumb2_inst_t insn = *(thumb2_inst_t *)ctx->buffer_cursor; - - int last_relo_offset = relocated_buffer->GetBufferSize(); - if (is_thumb2(insn)) { - Thumb2RelocateSingleInsn(ctx, (uint16_t)insn, (uint16_t)(insn >> 16)); - DEBUG_LOG("[arm] Relocate thumb2 insn: 0x%x", insn); - } else { - Thumb1RelocateSingleInsn(ctx, (uint16_t)insn); - DEBUG_LOG("[arm] Relocate thumb1 insn: 0x%x", (uint16_t)insn); - } - - // Move to next instruction - if (is_thumb2(insn)) { - ctx->buffer_cursor += Thumb2_INST_LEN; - } else { - ctx->buffer_cursor += Thumb1_INST_LEN; - } - - // execute state changed - addr32_t next_insn_addr = relo_cur_src_vmaddr(ctx) - Thumb_PC_OFFSET; - if (check_execute_state_changed(ctx, next_insn_addr)) { - break; - } - } - - // .thumb1 bx pc - // .thumb1 mov r8, r8 - // .arm ldr pc, [pc, #-4] - - bool is_relocate_interrupted = ctx->buffer_cursor < ctx->buffer + ctx->buffer_size; - if (is_relocate_interrupted) { - turbo_assembler_->SetExecuteState(ARMExecuteState); - } -} - -void GenRelocateCode(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated, bool branch) { - relo_ctx_t ctx; - - if ((addr_t)buffer % 2) { - ctx.start_state = ThumbExecuteState; - ctx.curr_state = ThumbExecuteState; - // remove thumb address flag - buffer = (void *)((addr_t)buffer - 1); - } else { - ctx.start_state = ARMExecuteState; - ctx.curr_state = ARMExecuteState; - } - - ctx.buffer = ctx.buffer_cursor = (uint8_t *)buffer; - ctx.buffer_size = origin->size; - - ctx.src_vmaddr = (addr_t)origin->addr; - ctx.dst_vmaddr = 0; - - auto *relocated_buffer = new CodeBuffer(); - ctx.relocated_buffer = relocated_buffer; - - ThumbTurboAssembler thumb_turbo_assembler_(0, ctx.relocated_buffer); -#define thumb_ thumb_turbo_assembler_. - TurboAssembler arm_turbo_assembler_(0, ctx.relocated_buffer); -#define arm_ arm_turbo_assembler_. - - if (ctx.start_state == ThumbExecuteState) - ctx.curr_assembler = &thumb_turbo_assembler_; - else - ctx.curr_assembler = &arm_turbo_assembler_; - -relocate_remain: - if (ctx.curr_state == ThumbExecuteState) { - ctx.curr_assembler = &thumb_turbo_assembler_; - gen_thumb_relocate_code(&ctx); - if (thumb_turbo_assembler_.GetExecuteState() == ARMExecuteState) { - // translate interrupt as execute state changed - bool is_translate_interrupted = ctx.buffer_cursor < ctx.buffer + ctx.buffer_size; - if (is_translate_interrupted) { - // add nop to align ARM - if (thumb_turbo_assembler_.pc_offset() % 4) - thumb_turbo_assembler_.t1_nop(); - goto relocate_remain; - } - } - } else { - ctx.curr_assembler = &arm_turbo_assembler_; - gen_arm_relocate_code(&ctx); - if (arm_turbo_assembler_.GetExecuteState() == ThumbExecuteState) { - bool is_translate_interrupted = ctx.buffer_cursor < ctx.buffer + ctx.buffer_size; - // translate interrupt as execute state changed - if (is_translate_interrupted) { - goto relocate_remain; - } - } - } - - // update origin - int new_origin_len = (addr_t)ctx.buffer_cursor - (addr_t)ctx.buffer; - origin->reset(origin->addr, new_origin_len); - - // TODO: if last insn is unlink branch, skip - if (branch) { - if (ctx.curr_state == ThumbExecuteState) { - // branch to the rest of instructions - thumb_ AlignThumbNop(); - thumb_ t2_ldr(pc, MemOperand(pc, 0)); - // get the real branch address - thumb_ EmitAddress(origin->addr + origin->size + THUMB_ADDRESS_FLAG); - } else { - // branch to the rest of instructions - CodeGen codegen(&arm_turbo_assembler_); - // get the real branch address - codegen.LiteralLdrBranch(origin->addr + origin->size); - } - } - - // fixup the insn branch into trampoline(has been modified) - arm_turbo_assembler_.RelocLabelFixup(&ctx.relocated_offset_map); - thumb_turbo_assembler_.RelocLabelFixup(&ctx.relocated_offset_map); - - // realize all the pseudo data label - thumb_turbo_assembler_.RelocBind(); - arm_turbo_assembler_.RelocBind(); - - // generate executable code - { - // assembler without specific memory address - auto relocated_mem = MemoryAllocator::SharedAllocator()->allocateExecMemory(relocated_buffer->GetBufferSize()); - if (relocated_mem == nullptr) - return; - - thumb_turbo_assembler_.SetRealizedAddress((void *)relocated_mem); - arm_turbo_assembler_.SetRealizedAddress((void *)relocated_mem); - - AssemblyCode *code = NULL; - code = AssemblyCodeBuilder::FinalizeFromTurboAssembler(ctx.curr_assembler); - relocated->reset(code->addr, code->size); - } - - // thumb - if (ctx.start_state == ThumbExecuteState) { - // add thumb address flag - relocated->reset(relocated->addr + THUMB_ADDRESS_FLAG, relocated->size); - } - - // clean - { - thumb_turbo_assembler_.ClearCodeBuffer(); - arm_turbo_assembler_.ClearCodeBuffer(); - - delete relocated_buffer; - } -} - -void GenRelocateCodeAndBranch(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated) { - GenRelocateCode(buffer, origin, relocated, true); -} - -#endif diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/arm/InstructionRelocationARM.h b/app/src/main/cpp/Dobby/source/InstructionRelocation/arm/InstructionRelocationARM.h deleted file mode 100644 index ed289aa8..00000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/arm/InstructionRelocationARM.h +++ /dev/null @@ -1,307 +0,0 @@ -#pragma once -#include "dobby/dobby_internal.h" - -#include "core/arch/arm/constants-arm.h" -#include "core/assembler/assembler-arm.h" - -namespace zz { -namespace arm { - -// thumb1/thumb2 pseudo label type, only support Thumb1-Ldr | Thumb2-Ldr -enum ref_label_type_t { kThumb1Ldr, kThumb2LiteralLdr }; - -// custom thumb pseudo label for thumb/thumb2 -class ThumbPseudoLabel : public AssemblerPseudoLabel { -public: - ThumbPseudoLabel(addr_t addr) : AssemblerPseudoLabel(addr) { - } - - // fix the instruction which not link to the label yet. - void link_confused_instructions(CodeBuffer *buffer) { - CodeBuffer *_buffer; - if (buffer) - _buffer = buffer; - - for (auto &ref_label_insn : ref_label_insns_) { - // instruction offset to label - thumb2_inst_t insn = _buffer->LoadThumb2Inst(ref_label_insn.pc_offset); - thumb1_inst_t insn1 = _buffer->LoadThumb1Inst(ref_label_insn.pc_offset); - thumb1_inst_t insn2 = _buffer->LoadThumb1Inst(ref_label_insn.pc_offset + sizeof(thumb1_inst_t)); - - switch (ref_label_insn.link_type) { - case kThumb1Ldr: { - UNREACHABLE(); - } break; - case kThumb2LiteralLdr: { - int64_t pc = ref_label_insn.pc_offset + Thumb_PC_OFFSET; - assert(pc % 4 == 0); - int32_t imm12 = pos() - pc; - - if (imm12 > 0) { - set_bit(insn1, 7, 1); - } else { - set_bit(insn1, 7, 0); - imm12 = -imm12; - } - set_bits(insn2, 0, 11, imm12); - _buffer->RewriteThumb1Inst(ref_label_insn.pc_offset, insn1); - _buffer->RewriteThumb1Inst(ref_label_insn.pc_offset + Thumb1_INST_LEN, insn2); - - DEBUG_LOG("[thumb label link] insn offset %d link offset %d", ref_label_insn.pc_offset, imm12); - } break; - default: - UNREACHABLE(); - break; - } - } - } -}; - -class ThumbRelocLabelEntry : public ThumbPseudoLabel, public RelocLabel { -public: - ThumbRelocLabelEntry(bool is_pc_register) : RelocLabel(), ThumbPseudoLabel(0), is_pc_register_(is_pc_register) { - } - - template static ThumbRelocLabelEntry *withData(T value, bool is_pc_register) { - auto label = new ThumbRelocLabelEntry(is_pc_register); - label->setData(value); - return label; - } - - bool is_pc_register() { - return is_pc_register_; - } - -private: - bool is_pc_register_; -}; - -// --- - -class ThumbAssembler : public Assembler { -public: - ThumbAssembler(void *address) : Assembler(address) { - this->SetExecuteState(ThumbExecuteState); - } - - ThumbAssembler(void *address, CodeBuffer *buffer) : Assembler(address, buffer) { - this->SetExecuteState(ThumbExecuteState); - } - - void EmitInt16(int16_t val) { - buffer_->Emit16(val); - } - - void Emit2Int16(int16_t val1, int16_t val2) { - EmitInt16(val1); - EmitInt16(val2); - } - - void EmitAddress(uint32_t value) { - buffer_->Emit32(value); - } - - // ===== - void t1_nop() { - EmitInt16(0xbf00); - } - void t1_b(int32_t imm) { - ASSERT(CheckSignLength(imm, 12)); - ASSERT(CheckAlign(imm, 2)); - - int32_t imm11 = bits(imm >> 1, 0, 10); - EmitInt16(0xe000 | imm11); - } - - // ===== - void t2_b(uint32_t imm) { - EmitThumb2Branch(AL, imm, false); - } - void t2_bl(uint32_t imm) { - EmitThumb2Branch(AL, imm, true); - } - void t2_blx(uint32_t imm) { - UNIMPLEMENTED(); - } - - // ===== - void t2_ldr(Register dst, const MemOperand &src) { - // WARNNING: literal ldr, base = ALIGN(pc, 4) - EmitThumb2LoadStore(true, dst, src); - } - -private: - void EmitThumb2LoadLiteral(Register rt, const MemOperand x) { - bool add = true; - uint32_t U, imm12; - int32_t offset = x.offset(); - -#if 0 - // literal ldr, base = ALIGN(pc, 4) - if (rt.Is(pc)) { - // TODO: convert to `GetRealizedAddress()` ??? - addr_t curr_pc = pc_offset() + (addr_t)GetRealizedAddress(); - if (curr_pc % 4) { - t1_nop(); - } - } -#endif - - if (offset > 0) { - U = B7; - imm12 = offset; - } else { - U = 0; - imm12 = -offset; - } - EmitInt16(0xf85f | U); - EmitInt16(0x0 | (rt.code() << 12) | imm12); - } - void EmitThumb2LoadStore(bool load, Register rt, const MemOperand x) { - if (x.rn().Is(pc)) { - EmitThumb2LoadLiteral(rt, x); - return; - } - - bool index, add, wback; - if (x.IsRegisterOffset() && x.offset() >= 0) { - index = true, add = true, wback = false; - uint32_t imm12 = x.offset(); - EmitInt16(0xf8d0 | (x.rn().code() << 0)); - EmitInt16(0x0 | (rt.code() << 12) | imm12); - } else { - // use bit accelerate - uint32_t P = 0, W = 0, U = 0; - uint32_t imm8 = x.offset() > 0 ? x.offset() : -x.offset(); - U = x.offset() > 0 ? 0 : B9; - if (x.IsPostIndex()) { - P = 0, W = B8; - } else if (x.IsPreIndex()) { - P = B10, W = B8; - } - index = (P == B10); - add = (U == B9); - wback = (W == B8); - EmitInt16(0xf850 | (x.rn().code() << 0)); - EmitInt16(0x0800 | (rt.code() << 12) | P | U | W | imm8); - } - } - - void EmitThumb2Branch(Condition cond, int32_t imm, bool link) { - uint32_t operand = imm >> 1; - ASSERT(CheckSignLength(operand, 25)); - ASSERT(CheckAlign(operand, 2)); - - uint32_t signbit = (imm >> 31) & 0x1; - uint32_t i1 = (operand >> 22) & 0x1; - uint32_t i2 = (operand >> 21) & 0x1; - uint32_t imm10 = (operand >> 11) & 0x03ff; - uint32_t imm11 = operand & 0x07ff; - uint32_t j1 = (!(i1 ^ signbit)); - uint32_t j2 = (!(i2 ^ signbit)); - - if (cond != AL) { - UNIMPLEMENTED(); - } - - EmitInt16(0xf000 | LeftShift(signbit, 1, 10) | LeftShift(imm10, 10, 0)); - if (link) { - // Not use LeftShift(1, 1, 14), and use B14 for accelerate - EmitInt16(0x9000 | LeftShift(j1, 1, 13) | (LeftShift(j2, 1, 11)) | LeftShift(imm11, 11, 0) | B14); - } else { - EmitInt16(0x9000 | LeftShift(j1, 1, 13) | (LeftShift(j2, 1, 11)) | LeftShift(imm11, 11, 0)); - } - } -}; - -// --- - -class ThumbTurboAssembler : public ThumbAssembler { -public: - ThumbTurboAssembler(void *address) : ThumbAssembler(address) { - } - - ThumbTurboAssembler(void *address, CodeBuffer *buffer) : ThumbAssembler(address, buffer) { - } - - ~ThumbTurboAssembler() { - } - - void T1_Ldr(Register rt, ThumbPseudoLabel *label) { - UNREACHABLE(); - -// t1_ldr: rt can't be PC register -// === -#if 0 - if (label->is_bound()) { - const int64_t dest = label->pos() - buffer_.Size(); - ldr(rt, MemOperand(pc, dest)); - } else { - // record this ldr, and fix later. - label->link_to(buffer_.Size(), ThumbPseudoLabel::kThumb1Ldr); - ldr(rt, MemOperand(pc, 0)); - } -#endif - } - - void T2_Ldr(Register rt, ThumbPseudoLabel *label) { - if (label->pos()) { - int offset = label->pos() - buffer_->GetBufferSize(); - t2_ldr(rt, MemOperand(pc, offset)); - } else { - // record this ldr, and fix later. - label->link_to(kThumb2LiteralLdr, buffer_->GetBufferSize()); - t2_ldr(rt, MemOperand(pc, 0)); - } - } - - void AlignThumbNop() { - addr32_t pc = this->GetCodeBuffer()->GetBufferSize() + (uintptr_t)GetRealizedAddress(); - if (pc % Thumb2_INST_LEN) { - t1_nop(); - } else { - } - } - - // --- - - void PseudoBind(ThumbPseudoLabel *label) { - const addr_t bound_pc = buffer_->GetBufferSize(); - label->bind_to(bound_pc); - // If some instructions have been wrote, before the label bound, we need link these `confused` instructions - if (label->has_confused_instructions()) { - label->link_confused_instructions(GetCodeBuffer()); - } - } - - void RelocBind() { - for (auto *data_label : data_labels_) { - PseudoBind(data_label); - reinterpret_cast(buffer_)->EmitBuffer(data_label->data_, data_label->data_size_); - } - } - - void AppendRelocLabel(ThumbRelocLabelEntry *label) { - data_labels_.push_back(label); - } - - void RelocLabelFixup(tinystl::unordered_map *relocated_offset_map) { - for (auto *data_label : data_labels_) { - auto val = data_label->data(); - auto iter = relocated_offset_map->find(val); - if (iter != relocated_offset_map->end()) { - data_label->fixupData(iter->second); - } - } - } - -private: - tinystl::vector data_labels_; -}; - -#if 0 -void GenRelocateCodeAndBranch(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated); -#endif - -} // namespace arm -} // namespace zz diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/arm64/InstructionRelocationARM64.cc b/app/src/main/cpp/Dobby/source/InstructionRelocation/arm64/InstructionRelocationARM64.cc deleted file mode 100644 index 899ac9e4..00000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/arm64/InstructionRelocationARM64.cc +++ /dev/null @@ -1,366 +0,0 @@ -#include "platform_detect_macro.h" - -#if defined(TARGET_ARCH_ARM64) - -#include "InstructionRelocation/arm64/InstructionRelocationARM64.h" - -#include "dobby/dobby_internal.h" - -#include "core/arch/arm64/registers-arm64.h" -#include "core/assembler/assembler-arm64.h" -#include "core/codegen/codegen-arm64.h" - -#include "inst_constants.h" -#include "inst_decode_encode_kit.h" - -using namespace zz::arm64; - -#if defined(DOBBY_DEBUG) -#define debug_nop() _ nop() -#else -#define debug_nop() -#endif - -#define arm64_trunc_page(x) ((x) & (~(0x1000 - 1))) -#define arm64_round_page(x) trunc_page((x) + (0x1000 - 1)) - -typedef struct { - addr_t mapped_addr; - - uint8_t *buffer; - uint8_t *buffer_cursor; - size_t buffer_size; - - addr_t src_vmaddr; - addr_t dst_vmaddr; - - CodeMemBlock *origin; - CodeMemBlock *relocated; - - tinystl::unordered_map relocated_offset_map; - - tinystl::unordered_map label_map; - -} relo_ctx_t; - -// --- - -addr_t relo_cur_src_vmaddr(relo_ctx_t *ctx) { - return ctx->src_vmaddr + (ctx->buffer_cursor - ctx->buffer); -} - -addr_t relo_cur_dst_vmaddr(relo_ctx_t *ctx, TurboAssembler *assembler) { - return ctx->dst_vmaddr + assembler->GetCodeBuffer()->GetBufferSize(); -} - -addr_t relo_src_offset_to_vmaddr(relo_ctx_t *ctx, off_t offset) { - return ctx->src_vmaddr + offset; -} - -addr_t relo_dst_offset_to_vmaddr(relo_ctx_t *ctx, off_t offset) { - return ctx->dst_vmaddr + offset; -} - -// --- - -#if 0 -bool has_relo_label_at(relo_ctx_t *ctx, addr_t addr) { - if (ctx->label_map.count(addr)) { - return true; - } - return false; -} - -AssemblerPseudoLabel *relo_label_create_or_get(relo_ctx_t *ctx, addr_t addr) { - if (!ctx->label_map.count(addr)) { - auto *label = new AssemblerPseudoLabel(addr); - ctx->label_map[addr] = label; - } - return ctx->label_map[addr]; -} - -int64_t relo_label_link_offset(relo_ctx_t *ctx, pcrel_type_t pcrel_type, int64_t offset) { - auto is_offset_undefined = [ctx](int64_t offset) -> bool { - if (ctx->buffer_cursor + offset < ctx->buffer || ctx->buffer_cursor + offset > ctx->buffer + ctx->buffer_size) { - return true; - } - return false; - }; - - auto is_offset_uninitialized = [ctx](int64_t offset) -> bool { - if (ctx->buffer_cursor + offset > ctx->buffer && ctx->buffer_cursor + offset < ctx->buffer + ctx->buffer_size) { - if (!ctx->relocated_offset_map.count(ctx->buffer_cursor + offset - ctx->buffer_cursor)) - return true; - } - return false; - }; - - addr_t label_vmaddr = relo_cur_src_vmaddr(ctx) + offset; - if (pcrel_type == RELO_ARM64_RELOC_PAGE21) { - label_vmaddr = arm64_trunc_page(label_vmaddr); - } - - auto *label = relo_label_create_or_get(ctx, label_vmaddr); - if (is_offset_undefined(offset)) { // pc relative target is beyond our scope - label->link_to(AssemblerPseudoLabel::kLabelImm19, relo_cur_src_vmaddr(ctx), (addr_t)ctx->buffer_cursor - ctx->mapped_addr); - return 0; - } else if (is_offset_uninitialized(offset)) { // pc relative target is in our control, but not handle yet - label->link_to(AssemblerPseudoLabel::kLabelImm19, relo_cur_src_vmaddr(ctx), (addr_t)ctx->buffer_cursor - ctx->mapped_addr); - return 0; - } else { // pc relative target is already handled - off_t off = ctx->buffer_cursor + offset - ctx->buffer; - off_t relocated_off = label->pos(); - int64_t new_offset = relo_dst_offset_to_vmaddr(ctx, relocated_off) - relo_src_offset_to_vmaddr(ctx, off); - return new_offset; - } -} -#endif - -// --- - -static inline bool inst_is_b_bl(uint32_t instr) { - return (instr & UnconditionalBranchFixedMask) == UnconditionalBranchFixed; -} - -static inline bool inst_is_ldr_literal(uint32_t instr) { - return ((instr & LoadRegLiteralFixedMask) == LoadRegLiteralFixed); -} - -static inline bool inst_is_adr(uint32_t instr) { - return (instr & PCRelAddressingFixedMask) == PCRelAddressingFixed && (instr & PCRelAddressingMask) == ADR; -} - -static inline bool inst_is_adrp(uint32_t instr) { - return (instr & PCRelAddressingFixedMask) == PCRelAddressingFixed && (instr & PCRelAddressingMask) == ADRP; -} - -static inline bool inst_is_b_cond(uint32_t instr) { - return (instr & ConditionalBranchFixedMask) == ConditionalBranchFixed; -} - -static inline bool inst_is_compare_b(uint32_t instr) { - return (instr & CompareBranchFixedMask) == CompareBranchFixed; -} - -static inline bool inst_is_test_b(uint32_t instr) { - return (instr & TestBranchFixedMask) == TestBranchFixed; -} - -// --- - -int relo_relocate(relo_ctx_t *ctx, bool branch) { - int relocated_insn_count = 0; - - TurboAssembler turbo_assembler_(0); -#define _ turbo_assembler_. - - auto relocated_buffer = turbo_assembler_.GetCodeBuffer(); - - while (ctx->buffer_cursor < ctx->buffer + ctx->buffer_size) { - uint32_t orig_off = ctx->buffer_cursor - ctx->buffer; - uint32_t relocated_off = relocated_buffer->GetBufferSize(); - ctx->relocated_offset_map[orig_off] = relocated_off; - -#if 0 - addr_t inst_vmaddr = 0; - inst_vmaddr = relo_cur_src_vmaddr(ctx); - if (has_relo_label_at(ctx, inst_vmaddr)) { - auto *label = relo_label_create_or_get(ctx, inst_vmaddr); - label->bind_to(inst_vmaddr); - } -#endif - - arm64_inst_t inst = *(arm64_inst_t *)ctx->buffer_cursor; - if (inst_is_b_bl(inst)) { - DEBUG_LOG("%d:relo at %p", relocated_insn_count++, relo_cur_src_vmaddr(ctx)); - - int64_t offset = decode_imm26_offset(inst); - addr_t dst_vmaddr = relo_cur_src_vmaddr(ctx) + offset; - - auto dst_label = RelocLabel::withData(dst_vmaddr); - _ AppendRelocLabel(dst_label); - - { - _ Ldr(TMP_REG_0, dst_label); - if ((inst & UnconditionalBranchMask) == BL) { - _ blr(TMP_REG_0); - } else { - _ br(TMP_REG_0); - } - } - - } else if (inst_is_ldr_literal(inst)) { - DEBUG_LOG("%d:relo at %p", relocated_insn_count++, relo_cur_src_vmaddr(ctx)); - - int64_t offset = decode_imm19_offset(inst); - addr_t dst_vmaddr = relo_cur_src_vmaddr(ctx) + offset; - - int rt = decode_rt(inst); - char opc = bits(inst, 30, 31); - - { - _ Mov(TMP_REG_0, dst_vmaddr); - if (opc == 0b00) - _ ldr(W(rt), MemOperand(TMP_REG_0, 0)); - else if (opc == 0b01) - _ ldr(X(rt), MemOperand(TMP_REG_0, 0)); - else { - UNIMPLEMENTED(); - } - } - } else if (inst_is_adr(inst)) { - DEBUG_LOG("%d:relo at %p", relocated_insn_count++, relo_cur_src_vmaddr(ctx)); - - int64_t offset = decode_immhi_immlo_offset(inst); - addr_t dst_vmaddr = relo_cur_src_vmaddr(ctx) + offset; - - int rd = decode_rd(inst); - - { - _ Mov(X(rd), dst_vmaddr); - ; - } - } else if (inst_is_adrp(inst)) { - DEBUG_LOG("%d:relo at %p", relocated_insn_count++, relo_cur_src_vmaddr(ctx)); - - int64_t offset = decode_immhi_immlo_zero12_offset(inst); - addr_t dst_vmaddr = relo_cur_src_vmaddr(ctx) + offset; - dst_vmaddr = arm64_trunc_page(dst_vmaddr); - - int rd = decode_rd(inst); - - { - _ Mov(X(rd), dst_vmaddr); - ; - } - } else if (inst_is_b_cond(inst)) { - DEBUG_LOG("%d:relo at %p", relocated_insn_count++, relo_cur_src_vmaddr(ctx)); - - int64_t offset = decode_imm19_offset(inst); - addr_t dst_vmaddr = relo_cur_src_vmaddr(ctx) + offset; - - arm64_inst_t branch_instr = inst; - { - char cond = bits(inst, 0, 3); - cond = cond ^ 1; - set_bits(branch_instr, 0, 3, cond); - - int64_t offset = 4 * 3; - uint32_t imm19 = offset >> 2; - set_bits(branch_instr, 5, 23, imm19); - } - - auto dst_label = RelocLabel::withData(dst_vmaddr); - _ AppendRelocLabel(dst_label); - - { - _ Emit(branch_instr); - { - _ Ldr(TMP_REG_0, dst_label); - _ br(TMP_REG_0); - } - } - } else if (inst_is_compare_b(inst)) { - DEBUG_LOG("%d:relo at %p", relocated_insn_count++, relo_cur_src_vmaddr(ctx)); - - int64_t offset = decode_imm19_offset(inst); - addr_t dst_vmaddr = relo_cur_src_vmaddr(ctx) + offset; - - arm64_inst_t branch_instr = inst; - { - char op = bit(inst, 24); - op = op ^ 1; - set_bit(branch_instr, 24, op); - - int64_t offset = 4 * 3; - uint32_t imm19 = offset >> 2; - set_bits(branch_instr, 5, 23, imm19); - } - - auto dst_label = RelocLabel::withData(dst_vmaddr); - _ AppendRelocLabel(dst_label); - - { - _ Emit(branch_instr); - { - _ Ldr(TMP_REG_0, dst_label); - _ br(TMP_REG_0); - } - } - } else if (inst_is_test_b(inst)) { - DEBUG_LOG("%d:relo at %p", relocated_insn_count++, relo_cur_src_vmaddr(ctx)); - - int64_t offset = decode_imm14_offset(inst); - addr_t dst_vmaddr = relo_cur_src_vmaddr(ctx) + offset; - - arm64_inst_t branch_instr = inst; - { - char op = bit(inst, 24); - op = op ^ 1; - set_bit(branch_instr, 24, op); - - int64_t offset = 4 * 3; - uint32_t imm14 = offset >> 2; - set_bits(branch_instr, 5, 18, imm14); - } - - auto dst_label = RelocLabel::withData(dst_vmaddr); - _ AppendRelocLabel(dst_label); - - { - _ Emit(branch_instr); - { - _ Ldr(TMP_REG_0, dst_label); - _ br(TMP_REG_0); - } - } - } else { - _ Emit(inst); - } - - ctx->buffer_cursor += sizeof(arm64_inst_t); - } -#undef _ - - // update origin - int new_origin_len = (addr_t)ctx->buffer_cursor - (addr_t)ctx->buffer; - ctx->origin->reset(ctx->origin->addr, new_origin_len); - - // TODO: if last instr is unlink branch, ignore it - if (branch) { - CodeGen codegen(&turbo_assembler_); - codegen.LiteralLdrBranch(ctx->origin->addr + ctx->origin->size); - } - - // Bind all labels - turbo_assembler_.RelocBind(); - - // Generate executable code - { - auto code = AssemblyCodeBuilder::FinalizeFromTurboAssembler(&turbo_assembler_); - ctx->relocated = code; - } - return 0; -} - -void GenRelocateCode(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated, bool branch) { - relo_ctx_t ctx = {0}; - - ctx.buffer = ctx.buffer_cursor = (uint8_t *)buffer; - ctx.buffer_size = origin->size; - - ctx.src_vmaddr = (addr_t)origin->addr; - ctx.dst_vmaddr = (addr_t)relocated->addr; - - ctx.origin = origin; - - relo_relocate(&ctx, branch); - - relocated->reset(ctx.relocated->addr, ctx.relocated->size); -} - -void GenRelocateCodeAndBranch(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated) { - GenRelocateCode(buffer, origin, relocated, true); -} - -#endif diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/arm64/InstructionRelocationARM64.h b/app/src/main/cpp/Dobby/source/InstructionRelocation/arm64/InstructionRelocationARM64.h deleted file mode 100644 index 226d3ad2..00000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/arm64/InstructionRelocationARM64.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "dobby/dobby_internal.h" - -#include "core/arch/arm64/constants-arm64.h" - -#if 0 -namespace zz { -namespace arm64 { -void GenRelocateCodeAndBranch(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated); -} // namespace arm64 -} // namespace zz -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/arm64/inst_constants.h b/app/src/main/cpp/Dobby/source/InstructionRelocation/arm64/inst_constants.h deleted file mode 100644 index 228a952f..00000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/arm64/inst_constants.h +++ /dev/null @@ -1,49 +0,0 @@ -#pragma once - -#if 0 -enum LoadRegLiteralOp { - LoadRegLiteralFixed = 0x18000000, - LoadRegLiteralFixedMask = 0x3B000000, - LoadRegLiteralMask = 0xFF000000, -}; - -// PC relative addressing. -enum PCRelAddressingOp { - PCRelAddressingFixed = 0x10000000, - PCRelAddressingFixedMask = 0x1F000000, - PCRelAddressingMask = 0x9F000000, - ADR = PCRelAddressingFixed | 0x00000000, - ADRP = PCRelAddressingFixed | 0x80000000 -}; - -// Unconditional branch. -enum UnconditionalBranchOp { - UnconditionalBranchFixed = 0x14000000, - UnconditionalBranchFixedMask = 0x7C000000, - UnconditionalBranchMask = 0xFC000000, - - B = UnconditionalBranchFixed | 0x00000000, - BL = UnconditionalBranchFixed | 0x80000000 -}; -#endif - -// Compare and branch. -enum CompareBranchOp { - CompareBranchFixed = 0x34000000, - CompareBranchFixedMask = 0x7E000000, - CompareBranchMask = 0xFF000000, -}; - -// Conditional branch. -enum ConditionalBranchOp { - ConditionalBranchFixed = 0x54000000, - ConditionalBranchFixedMask = 0xFE000000, - ConditionalBranchMask = 0xFF000010, -}; - -// Test and branch. -enum TestBranchOp { - TestBranchFixed = 0x36000000, - TestBranchFixedMask = 0x7E000000, - TestBranchMask = 0x7F000000, -}; \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/arm64/inst_decode_encode_kit.h b/app/src/main/cpp/Dobby/source/InstructionRelocation/arm64/inst_decode_encode_kit.h deleted file mode 100644 index cfae8896..00000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/arm64/inst_decode_encode_kit.h +++ /dev/null @@ -1,110 +0,0 @@ -#pragma once - -#include "dobby/common.h" - -static inline int64_t SignExtend(unsigned long x, int M, int N) { -#if 1 - char sign_bit = bit(x, M - 1); - unsigned long sign_mask = 0 - sign_bit; - x |= ((sign_mask >> M) << M); -#else - x = (long)((long)x << (N - M)) >> (N - M); -#endif - return (int64_t)x; -} - -static inline int64_t decode_imm14_offset(uint32_t instr) { - int64_t offset; - { - int64_t imm14 = bits(instr, 5, 18); - offset = (imm14 << 2); - } - offset = SignExtend(offset, 2 + 14, 64); - return offset; -} -static inline uint32_t encode_imm14_offset(uint32_t instr, int64_t offset) { - uint32_t imm14 = bits((offset >> 2), 0, 13); - set_bits(instr, 5, 18, imm14); - return instr; -} - -static inline int64_t decode_imm19_offset(uint32_t instr) { - int64_t offset; - { - int64_t imm19 = bits(instr, 5, 23); - offset = (imm19 << 2); - } - offset = SignExtend(offset, 2 + 19, 64); - return offset; -} - -static inline uint32_t encode_imm19_offset(uint32_t instr, int64_t offset) { - uint32_t imm19 = bits((offset >> 2), 0, 18); - set_bits(instr, 5, 23, imm19); - return instr; -} - -static inline int64_t decode_imm26_offset(uint32_t instr) { - int64_t offset; - { - int64_t imm26 = bits(instr, 0, 25); - offset = (imm26 << 2); - } - offset = SignExtend(offset, 2 + 26, 64); - return offset; -} -static inline uint32_t encode_imm26_offset(uint32_t instr, int64_t offset) { - uint32_t imm26 = bits((offset >> 2), 0, 25); - set_bits(instr, 0, 25, imm26); - return instr; -} - -static inline int64_t decode_immhi_immlo_offset(uint32_t instr) { - typedef uint32_t instr_t; - struct { - instr_t Rd : 5; // Destination register - instr_t immhi : 19; // 19-bit upper immediate - instr_t dummy_0 : 5; // Must be 10000 == 0x10 - instr_t immlo : 2; // 2-bit lower immediate - instr_t op : 1; // 0 = ADR, 1 = ADRP - } instr_decode; - - *(instr_t *)&instr_decode = instr; - - int64_t imm = instr_decode.immlo + (instr_decode.immhi << 2); - imm = SignExtend(imm, 2 + 19, 64); - return imm; -} -static inline uint32_t encode_immhi_immlo_offset(uint32_t instr, int64_t offset) { - struct { - uint32_t Rd : 5; // Destination register - uint32_t immhi : 19; // 19-bit upper immediate - uint32_t dummy_0 : 5; // Must be 10000 == 0x10 - uint32_t immlo : 2; // 2-bit lower immediate - uint32_t op : 1; // 0 = ADR, 1 = ADRP - } instr_decode; - - *(uint32_t *)&instr_decode = instr; - instr_decode.immlo = bits(offset, 0, 2); - instr_decode.immhi = bits(offset, 2, 2 + 19); - - return *(uint32_t *)&instr_decode; -} - -static inline int64_t decode_immhi_immlo_zero12_offset(uint32_t instr) { - int64_t imm = decode_immhi_immlo_offset(instr); - imm = imm << 12; - return imm; -} -static inline uint32_t encode_immhi_immlo_zero12_offset(uint32_t instr, int64_t offset) { - offset = (offset >> 12); - return encode_immhi_immlo_offset(instr, offset); -} - -static inline int decode_rt(uint32_t instr) { - return bits(instr, 0, 4); -} - -static inline int decode_rd(uint32_t instr) { - return bits(instr, 0, 4); -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/x64/InstructionRelocationX64.cc b/app/src/main/cpp/Dobby/source/InstructionRelocation/x64/InstructionRelocationX64.cc deleted file mode 100644 index d9d78fdf..00000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/x64/InstructionRelocationX64.cc +++ /dev/null @@ -1,79 +0,0 @@ -#include "platform_detect_macro.h" - -#if defined(TARGET_ARCH_X64) - -#include "dobby/dobby_internal.h" - -#include "InstructionRelocation/x64/InstructionRelocationX64.h" -#include "InstructionRelocation/x86/x86_insn_decode/x86_insn_decode.h" - -#include "core/arch/x64/registers-x64.h" -#include "core/assembler/assembler-x64.h" -#include "core/codegen/codegen-x64.h" - -using namespace zz::x64; - -int GenRelocateCodeFixed(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated, bool branch) { - TurboAssembler turbo_assembler_(0); - // Set fixed executable code chunk address - turbo_assembler_.SetRealizedAddress((void *)relocated->addr); -#define _ turbo_assembler_. -#define __ turbo_assembler_.GetCodeBuffer()-> - - auto curr_orig_ip = (addr64_t)origin->addr; - auto curr_relo_ip = (addr64_t)relocated->addr; - - auto buffer_cursor = (uint8_t *)buffer; - - int predefined_relocate_size = origin->size; - - while ((buffer_cursor < ((uint8_t *)buffer + predefined_relocate_size))) { - x86_insn_decode_t insn = {0}; - memset(&insn, 0, sizeof(insn)); - GenRelocateSingleX86Insn(curr_orig_ip, curr_relo_ip, buffer_cursor, &turbo_assembler_, - turbo_assembler_.GetCodeBuffer(), insn, 64); - - // go next - curr_orig_ip += insn.length; - buffer_cursor += insn.length; - curr_relo_ip = (addr64_t)relocated->addr + turbo_assembler_.ip_offset(); - } - - // jmp to the origin rest instructions - if (branch) { - CodeGen codegen(&turbo_assembler_); - // TODO: 6 == jmp [RIP + disp32] instruction size - addr64_t stub_addr = curr_relo_ip + 6; - codegen.JmpNearIndirect(stub_addr); - turbo_assembler_.GetCodeBuffer()->Emit64(curr_orig_ip); - } - - // update origin - int new_origin_len = curr_orig_ip - (addr_t)origin->addr; - origin->reset(origin->addr, new_origin_len); - - int relo_len = turbo_assembler_.GetCodeBuffer()->GetBufferSize(); - if (relo_len > relocated->size) { - DEBUG_LOG("pre-alloc code chunk not enough"); - return -1; - } - - // generate executable code - { - auto code = AssemblyCodeBuilder::FinalizeFromTurboAssembler(&turbo_assembler_); - relocated->reset(code->addr, code->size); - delete code; - } - - return 0; -} - -void GenRelocateCodeAndBranch(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated) { - GenRelocateCode(buffer, origin, relocated, true); -} - -void GenRelocateCode(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated, bool branch) { - GenRelocateCodeX86Shared(buffer, origin, relocated, branch); -} - -#endif diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/x64/InstructionRelocationX64.h b/app/src/main/cpp/Dobby/source/InstructionRelocation/x64/InstructionRelocationX64.h deleted file mode 100644 index bad483c7..00000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/x64/InstructionRelocationX64.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include "dobby/common.h" - -#include "core/arch/x64/constants-x64.h" - -#include "MemoryAllocator/AssemblyCodeBuilder.h" - -#include "InstructionRelocation/x86/InstructionRelocationX86Shared.h" diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/InstructionRelocationX86.cc b/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/InstructionRelocationX86.cc deleted file mode 100644 index 2e845522..00000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/InstructionRelocationX86.cc +++ /dev/null @@ -1,80 +0,0 @@ -#include "platform_detect_macro.h" - -#if defined(TARGET_ARCH_IA32) - -#include "dobby/dobby_internal.h" - -#include "InstructionRelocation/x86/InstructionRelocationX86.h" -#include "InstructionRelocation/x86/x86_insn_decode/x86_insn_decode.h" - -#include "core/arch/x86/registers-x86.h" -#include "core/assembler/assembler-ia32.h" -#include "core/codegen/codegen-ia32.h" - -using namespace zz::x86; - -int GenRelocateCodeFixed(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated, bool branch) { - TurboAssembler turbo_assembler_(0); - // Set fixed executable code chunk address - turbo_assembler_.SetRealizedAddress((void *)relocated->addr); -#define _ turbo_assembler_. -#define __ turbo_assembler_.GetCodeBuffer()-> - - auto curr_orig_ip = (addr32_t)origin->addr; - auto curr_relo_ip = (addr32_t)relocated->addr; - - uint8_t *buffer_cursor = (uint8_t *)buffer; - - x86_options_t conf = {0}; - conf.mode = 32; - - int predefined_relocate_size = origin->size; - - while ((buffer_cursor < ((uint8_t *)buffer + predefined_relocate_size))) { - x86_insn_decode_t insn = {0}; - memset(&insn, 0, sizeof(insn)); - GenRelocateSingleX86Insn(curr_orig_ip, curr_relo_ip, buffer_cursor, &turbo_assembler_, - turbo_assembler_.GetCodeBuffer(), insn, 64); - - // go next - curr_orig_ip += insn.length; - buffer_cursor += insn.length; - curr_relo_ip = (addr32_t)relocated->addr + turbo_assembler_.ip_offset(); - } - - // jmp to the origin rest instructions - if (branch) { - CodeGen codegen(&turbo_assembler_); - addr32_t stub_addr = curr_relo_ip + 6; - codegen.JmpNear(curr_orig_ip); - } - - // update origin - int new_origin_len = curr_orig_ip - (addr_t)origin->addr; - origin->reset(origin->addr, new_origin_len); - - int relo_len = turbo_assembler_.GetCodeBuffer()->GetBufferSize(); - if (relo_len > relocated->size) { - DEBUG_LOG("pre-alloc code chunk not enough"); - return -1; - } - - // generate executable code - { - auto code = AssemblyCodeBuilder::FinalizeFromTurboAssembler(&turbo_assembler_); - relocated->reset(code->addr, code->size); - delete code; - } - - return 0; -} - -void GenRelocateCodeAndBranch(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated) { - GenRelocateCode(buffer, origin, relocated, true); -} - -void GenRelocateCode(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated, bool branch) { - GenRelocateCodeX86Shared(buffer, origin, relocated, branch); -} - -#endif diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/InstructionRelocationX86.h b/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/InstructionRelocationX86.h deleted file mode 100644 index b554e486..00000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/InstructionRelocationX86.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include "dobby/common.h" - -#include "core/arch/x86/constants-x86.h" - -#include "MemoryAllocator/AssemblyCodeBuilder.h" - -#include "InstructionRelocation/x86/InstructionRelocationX86Shared.h" diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/InstructionRelocationX86Shared.cc b/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/InstructionRelocationX86Shared.cc deleted file mode 100644 index 7df7038b..00000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/InstructionRelocationX86Shared.cc +++ /dev/null @@ -1,218 +0,0 @@ -#include "platform_detect_macro.h" - -#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) - -#include "dobby/dobby_internal.h" - -#include "InstructionRelocation/x86/InstructionRelocationX86.h" -#include "InstructionRelocation/x86/x86_insn_decode/x86_insn_decode.h" -#include "MemoryAllocator/NearMemoryAllocator.h" - -using namespace zz::x86; - -// x64 jmp absolute address -inline void codegen_x64_jmp_absolute_addr(CodeBufferBase *buffer, addr_t target) { - // jmp *(rip) - buffer->Emit8(0xFF); - buffer->Emit8(0x25); // ModR/M: 00 100 101 - buffer->Emit32(0x00); - // .long target - buffer->Emit64(target); -} - -// simple impl for ReloLabel -inline void emit_rel32_label(CodeBufferBase *buffer, uint32_t last_offset, addr_t curr_relo_ip, addr_t orig_dst_ip) { - addr_t curr_offset = buffer->GetBufferSize(); - uint32_t relo_insn_len = curr_offset + sizeof(uint32_t) - last_offset; - addr_t relo_ip = curr_relo_ip + relo_insn_len; - int32_t new_offset = orig_dst_ip - relo_ip; - buffer->Emit32(new_offset); -} - -int GenRelocateSingleX86Insn(addr_t curr_orig_ip, addr_t curr_relo_ip, uint8_t *buffer_cursor, AssemblerBase *assembler, - CodeBufferBase *code_buffer, x86_insn_decode_t &insn, int8_t mode) { -#define __ code_buffer-> - - int relocated_insn_len = -1; - - x86_options_t conf = {0}; - conf.mode = mode; - - // decode x86/x64 insn - x86_insn_decode(&insn, (uint8_t *)buffer_cursor, &conf); - - // x86 ip register == next instruction address - curr_orig_ip = curr_orig_ip + insn.length; - - auto last_relo_offset = code_buffer->GetBufferSize(); - - static auto x86_insn_encode_start = 0; - static auto x86_insn_encoded_len = 0; - auto x86_insn_encode_begin = [&] { x86_insn_encode_start = code_buffer->GetBufferSize(); }; - auto x86_insn_encode_end = [&] { x86_insn_encoded_len = code_buffer->GetBufferSize() - x86_insn_encode_start; }; - - if (insn.primary_opcode >= 0x70 && insn.primary_opcode <= 0x7F) { // jcc rel8 - DEBUG_LOG("[x86 relo] %p: jc rel8", buffer_cursor); - - int8_t offset = insn.immediate; - addr_t orig_dst_ip = curr_orig_ip + offset; -#if defined(TARGET_ARCH_IA32) - uint8_t opcode = 0x80 | (insn.primary_opcode & 0x0f); - - x86_insn_encode_begin(); - __ Emit8(0x0F); - __ Emit8(opcode); - emit_rel32_label(code_buffer, x86_insn_encode_start, curr_relo_ip, orig_dst_ip); -#else - // jcc_true stage 1 - const uint8_t label_jcc_cond_true_stage2 = 2; - __ Emit8(insn.primary_opcode); - __ Emit8(label_jcc_cond_true_stage2); - - // jcc_false - const uint8_t label_cond_false = 6 + 8; - __ Emit8(0xEB); - __ Emit8(label_cond_false); - - // jcc_true stage 2, jmp to orig dst - codegen_x64_jmp_absolute_addr(code_buffer, orig_dst_ip); -#endif - - } else if (mode == 64 && (insn.flags & X86_INSN_DECODE_FLAG_IP_RELATIVE) && - (insn.operands[1].mem.base == RIP)) { // RIP - DEBUG_LOG("[x86 relo] %p: rip", buffer_cursor); - - int32_t orig_disp = insn.operands[1].mem.disp; - addr_t orig_dst_ip = curr_orig_ip + orig_disp; - - addr_t rip_insn_seq_addr = 0; - { - - uint32_t jmp_near_range = (uint32_t)2 * 1024 * 1024 * 1024; - auto rip_insn_seq = (addr_t)NearMemoryAllocator::SharedAllocator()->allocateNearExecMemory( - insn.length + 6 + 8, orig_dst_ip, jmp_near_range); - - rip_insn_seq_addr = rip_insn_seq; - } - - // jmp *(rip) => jmp to [rip insn seq] - x86_insn_encode_begin(); - __ Emit8(0xFF); - __ Emit8(0x25); // ModR/M: 00 100 101 - __ Emit32(0); - __ Emit64(rip_insn_seq_addr); - x86_insn_encode_end(); - - { - auto rip_insn_seq_buffer = CodeBufferBase(); -#define ___ rip_insn_seq_buffer. - - auto rip_insn_req_ip = rip_insn_seq_addr; - rip_insn_req_ip = rip_insn_req_ip + insn.length; // next insn addr - int32_t new_disp = (int32_t)(orig_dst_ip - rip_insn_req_ip); - - // keep orig insn opcode - ___ EmitBuffer(buffer_cursor, insn.displacement_offset); - ___ Emit32(new_disp); - // keep orig insn immediate - if (insn.immediate_offset) { - ___ EmitBuffer((buffer_cursor + insn.immediate_offset), insn.length - insn.immediate_offset); - } - - // jmp *(rip) => back to relo process - auto relo_next_ip = curr_relo_ip + x86_insn_encoded_len; - codegen_x64_jmp_absolute_addr(&rip_insn_seq_buffer, relo_next_ip); - - DobbyCodePatch((void *)rip_insn_seq_addr, rip_insn_seq_buffer.GetBuffer(), rip_insn_seq_buffer.GetBufferSize()); - } - - } else if (insn.primary_opcode == 0xEB) { // jmp rel8 - DEBUG_LOG("[x86 relo] %p: jmp rel8", buffer_cursor); - - int8_t offset = insn.immediate; - addr_t orig_dst_ip = curr_orig_ip + offset; - -#if defined(TARGET_ARCH_IA32) - x86_insn_encode_begin(); - __ Emit8(0xE9); - emit_rel32_label(code_buffer, x86_insn_encode_start, curr_relo_ip, orig_dst_ip); -#else - // jmp *(rip) - codegen_x64_jmp_absolute_addr(code_buffer, orig_dst_ip); -#endif - } else if (insn.primary_opcode == 0xE8 || insn.primary_opcode == 0xE9) { // call or jmp rel32 - DEBUG_LOG("[x86 relo] %p:jmp or call rel32", buffer_cursor); - - int32_t offset = insn.immediate; - addr_t orig_dst_ip = curr_orig_ip + offset; - - assert(insn.immediate_offset == 1); - -#if defined(TARGET_ARCH_IA32) - x86_insn_encode_begin(); - - __ EmitBuffer(buffer_cursor, insn.immediate_offset); - emit_rel32_label(code_buffer, x86_insn_encode_start, curr_relo_ip, orig_dst_ip); -#else - __ Emit8(0xFF); - if (insn.primary_opcode == 0xE8) { - // call *(rip + 2) - __ Emit8(0x15); // ModR/M: 00 010 101 - __ Emit32(2); - - // jmp 8 - __ Emit8(0xEB); - __ Emit8(0x08); - - // dst - __ Emit64(orig_dst_ip); - } else { - // jmp *(rip) - __ Emit8(0x25); // ModR/M: 00 100 101 - __ Emit32(0); - - // dst - __ Emit64(orig_dst_ip); - } -#endif - } else if (insn.primary_opcode >= 0xE0 && insn.primary_opcode <= 0xE2) { // LOOPNZ/LOOPZ/LOOP/JECXZ - // LOOP/LOOPcc - UNIMPLEMENTED(); - } else if (insn.primary_opcode == 0xE3) { - // JCXZ JCEXZ JCRXZ - UNIMPLEMENTED(); - } else { - __ EmitBuffer(buffer_cursor, insn.length); - } - - // insn -> relocated insn - { - int relo_offset = code_buffer->GetBufferSize(); - int relo_len = relo_offset - last_relo_offset; - DEBUG_LOG("insn -> relocated insn: %d -> %d", insn.length, relo_len); - } - return relocated_insn_len; -} - -void GenRelocateCodeX86Shared(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated, bool branch) { - int expected_relocated_mem_size = 32; -x86_try_again: - if (!relocated->addr) { - auto relocated_mem = MemoryAllocator::SharedAllocator()->allocateExecMemory(expected_relocated_mem_size); - if (relocated_mem == nullptr) { - return; - } - relocated->reset((addr_t)relocated_mem, expected_relocated_mem_size); - } - - int ret = GenRelocateCodeFixed(buffer, origin, relocated, branch); - if (ret != 0) { - const int step_size = 16; - expected_relocated_mem_size += step_size; - relocated->reset(0, 0); - - goto x86_try_again; - } -} - -#endif diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/InstructionRelocationX86Shared.h b/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/InstructionRelocationX86Shared.h deleted file mode 100644 index 0df35e38..00000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/InstructionRelocationX86Shared.h +++ /dev/null @@ -1,16 +0,0 @@ -#pragma once - -#include "dobby/common.h" - -#include "MemoryAllocator/AssemblyCodeBuilder.h" - -#include "x86_insn_decode/x86_insn_decode.h" - -#include "X86DecodeKit.h" - -int GenRelocateCodeFixed(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated, bool branch); - -void GenRelocateCodeX86Shared(void *buffer, CodeMemBlock *origin, CodeMemBlock *relocated, bool branch); - -int GenRelocateSingleX86Insn(addr_t curr_orig_ip, addr_t curr_relo_ip, uint8_t *buffer_cursor, AssemblerBase *assembler, - CodeBufferBase *code_buffer, x86_insn_decode_t &insn, int8_t mode); \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/X86DecodeKit.h b/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/X86DecodeKit.h deleted file mode 100644 index 2a4195cf..00000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/X86DecodeKit.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -struct x86_insn_t {}; - -struct x86_insn_decoder_t { - uint8_t *buffer; - uint32_t buffer_size; - - uint8_t mode = 64; - - x86_insn_t insn; - explicit x86_insn_decoder_t(uint8_t *buffer, uint32_t buffer_size) : buffer(buffer), buffer_size(buffer_size) { - } - - uint8_t peak_byte() const { - return *buffer; - } - - void decode_prefix() { - } -}; \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/deprecated/Ia32Disassembler.cc b/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/deprecated/Ia32Disassembler.cc deleted file mode 100644 index f1bb1ae6..00000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/deprecated/Ia32Disassembler.cc +++ /dev/null @@ -1,388 +0,0 @@ -#include -#include - -#include "logging/logging.h" - -enum SegmentPrefix { - kCs = 0x2e, - kSs = 0x36, - kDs = 0x3e, - kEs = 0x26, - kFs = 0x64, - kGs = 0x65, -}; - -bool supports_rex_ = false; - -void DecodeInstruction(uint8_t *instr) { - bool have_prefixes = true; - uint8_t prefix[4] = {0, 0, 0, 0}; - - // decode legacy prefix - do { - switch (*instr) { - // Group 1 - lock and repeat prefixes: - case 0xF0: - case 0xF2: - case 0xF3: - prefix[0] = *instr; - break; - // Group 2 - segment override prefixes: - case kCs: - case kSs: - case kDs: - case kEs: - case kFs: - case kGs: - prefix[1] = *instr; - break; - // Group 3 - operand size override: - case 0x66: - prefix[2] = *instr; - break; - // Group 4 - address size override: - case 0x67: - prefix[3] = *instr; - break; - default: - have_prefixes = false; - break; - } - if (have_prefixes) { - instr++; - } - } while (have_prefixes); - - // x64 rex - uint8_t rex = (supports_rex_ && (*instr >= 0x40) && (*instr <= 0x4F)) ? *instr : 0; - if (rex != 0) { - instr++; - } - - bool has_modrm = false; - bool reg_is_opcode = false; - - size_t immediate_bytes = 0; - -#define OpEn_MR \ - do { \ - has_modrm = true; \ - } while (0); \ - break; - -#define OpEn_RM \ - do { \ - has_modrm = true; \ - } while (0); \ - break; - -#define OpEn_I(immediate_size) \ - do { \ - immediate_bytes = immediate_size; \ - } while (0); \ - break; - -#define OpEn_RMI(immediate_size) \ - do { \ - immediate_bytes = immediate_size; \ - } while (0); \ - break; - -#define OpEn_O \ - do { \ - reg_is_opcode = true; \ - } while (0); \ - break; - -#define OpEn_D \ - do { \ - reg_is_opcode = true; \ - } while (0); \ - break; - -#define OpEn_ZO \ - do { \ - reg_is_opcode = true; \ - } while (0); \ - break; - -#define Op_Prefix \ - do { \ - reg_is_opcode = true; \ - } while (0); \ - break; - -#define UnImplOpcode \ - do { \ - DEBUG_LOG("opcode unreachable"); \ - } while (0); \ - break; - - typedef enum { - MR, - } OpEnTy; - - // decode opcode - switch (*instr) { - case 0x00: - OpEn_MR; - case 0x01: - OpEn_MR; - case 0x02: - OpEn_RM; - case 0x03: - OpEn_RM; - case 0x04: - OpEn_I(8); - case 0x05: - OpEn_I(16 | 32); - - case 0x06: - case 0x07: - UnImplOpcode; - - case 0x08: - OpEn_MR; - case 0x09: - OpEn_MR; - case 0x0a: - OpEn_RM; - case 0x0b: - OpEn_RM; - case 0x0c: - OpEn_I(8); - case 0x0d: - OpEn_I(16 | 32); - - case 0x0e: - case 0x0f: - UnImplOpcode; - - case 0x10: - OpEn_MR; - case 0x11: - OpEn_MR; - case 0x12: - OpEn_RM; - case 0x13: - OpEn_RM; - case 0x14: - OpEn_I(8); - case 0x15: - OpEn_I(16 | 32); - - case 0x16: - case 0x17: - UnImplOpcode; - - case 0x18: - OpEn_MR; - case 0x19: - OpEn_MR; - case 0x1a: - OpEn_RM; - case 0x1b: - OpEn_RM; - case 0x1c: - OpEn_I(8); - case 0x1d: - OpEn_I(16 | 32); - - case 0x1e: - case 0x1f: - UnImplOpcode; - - case 0x20: - OpEn_MR; - case 0x21: - OpEn_MR; - case 0x22: - OpEn_RM; - case 0x23: - OpEn_RM; - case 0x24: - OpEn_I(8); - case 0x25: - OpEn_I(16 | 32); - - case 0x26: - case 0x27: - UnImplOpcode; - - case 0x28: - OpEn_MR; - case 0x29: - OpEn_MR; - case 0x2a: - OpEn_RM; - case 0x2b: - OpEn_RM; - case 0x2c: - OpEn_I(8); - case 0x2d: - OpEn_I(16 | 32); - - case 0x2e: - case 0x2f: - UnImplOpcode; - - case 0x30: - OpEn_MR; - case 0x31: - OpEn_MR; - case 0x32: - OpEn_RM; - case 0x33: - OpEn_RM; - case 0x34: - OpEn_I(8); - case 0x35: - OpEn_I(16 | 32); - - case 0x36: - case 0x37: - UnImplOpcode; - - case 0x38: - OpEn_MR; - case 0x39: - OpEn_MR; - case 0x3a: - OpEn_RM; - case 0x3b: - OpEn_RM; - case 0x3c: - OpEn_I(8); - case 0x3d: - OpEn_I(16 | 32); - - case 0x40: - case 0x41: - case 0x42: - case 0x43: - case 0x44: - case 0x45: - case 0x46: - case 0x47: - case 0x48: - case 0x49: - case 0x4a: - case 0x4b: - case 0x4c: - case 0x4d: - case 0x4e: - case 0x4f: - UnImplOpcode; - - case 0x50: - case 0x51: - case 0x52: - case 0x53: - case 0x54: - case 0x55: - case 0x56: - case 0x57: - case 0x58: - case 0x59: - case 0x5A: - case 0x5B: - case 0x5C: - case 0x5D: - case 0x5E: - case 0x5F: - OpEn_O; - - case 0x60: - case 0x61: - case 0x62: - UnImplOpcode; - - case 0x63: - if ((rex & REX_W) != 0) { - OpEn_RM; - }; - break; - - case 0x64: - case 0x65: - case 0x66: - case 0x67: - Op_Prefix; - - case 0x68: - OpEn_I(16 | 32); - - case 0x69: - OpEn_RMI(16 | 32); - - case 0x6a: - OpEn_I(8); - - case 0x6b: - OpEn_RMI(8); - - case 0x70: - case 0x71: - case 0x72: - case 0x73: - case 0x74: - case 0x75: - case 0x76: - case 0x77: - case 0x78: - case 0x79: - case 0x7A: - case 0x7B: - case 0x7C: - case 0x7D: - case 0x7E: - case 0x7F: - OpEn_D; - - case 0x80: - case 0x81: - case 0x82: - case 0x83: - case 0x84: - case 0x85: - UnImplOpcode; - - case 0x86: - case 0x87: - OpEn_RM; - - case 0x88: - case 0x89: - case 0x8a: - case 0x8b: - OpEn_RM; - - case 0x8c: - case 0x8d: - case 0x8e: - case 0x8f: - case 0x90: - case 0x91: - case 0x92: - case 0x93: - case 0x94: - case 0x95: - case 0x96: - case 0x97: - case 0x98: - case 0x99: - case 0x9a: - case 0x9b: - case 0x9c: - UnImplOpcode; - - case 0x9d: - OpEn_ZO; - - case 0x0f: - DecodeExtendedOpcode - } -} - -void DecodeExtendedOpcode(uint8_t *instr) { -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/deprecated/X86OpcodoDecodeTable.cc b/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/deprecated/X86OpcodoDecodeTable.cc deleted file mode 100644 index 800badf3..00000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/deprecated/X86OpcodoDecodeTable.cc +++ /dev/null @@ -1,604 +0,0 @@ -#include "platform_detect_macro.h" -#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) - -#include "./X86OpcodoDecodeTable.h" - -// clang-format on - -#define _xUnknownOpHanlder -1, -1, OpSz_0, ImmSz_0, _UnknownOpHanlder -void _UnknownOpHanlder(InstrMnemonic *instr, addr_t p) { - // printf("Unknown Operand\n"); - return; -} - -#define _xInvalidOpHanlder -1, -1, OpSz_0, ImmSz_0, _InValidOpHanlder -void _InValidOpHanlder(InstrMnemonic *instr, addr_t p) { - // printf("Invalid Operand\n"); - return; -} - -inline void _ContinueDispatch(InstrMnemonic *instr, addr_t p) { - OpcodeDecodeItem *item = &OpcodeDecodeTable[*(unsigned char *)p]; - item->DecodeHandler(instr, p); -} - -// ===== Decode LegacyPrefix and REXPrefix ===== - -// clang-format off -#define _xDecodePrefix_0F 1, OpEn_NONE, OpSz_0, ImmSz_0, _DecodeLegacyPrefix -#define _xDecodePrefix_66 1, OpEn_NONE, OpSz_0, ImmSz_0, _DecodePrefix_66 -#define _xDecodePrefix_67 1, OpEn_NONE, OpSz_0, ImmSz_0, _DecodeLegacyPrefix -#define _xDecodeREXPrefix 1, OpEn_NONE, OpSz_0, ImmSz_0, _DecodeREXPrefix -#define _xDecodePrefix 1, OpEn_NONE, OpSz_0, ImmSz_0, _DecodeLegacyPrefix -#define _xDecodeSegPrefix 1, OpEn_NONE, OpSz_0, ImmSz_0, _DecodeLegacyPrefix -// clang-format on - -void _DecodeREXPrefix(InstrMnemonic *instr, addr_t p) { - instr->instr.REX = *(byte_t *)p; - instr->len++; - instr->OperandSz = OpSz_64; - - _ContinueDispatch(instr, p + 1); // continue decode -} - -void _DecodeLegacyPrefix(InstrMnemonic *instr, addr_t p) { - instr->instr.prefix = *(byte_t *)p; - instr->len++; - - _ContinueDispatch(instr, p + 1); // continue decode -} - -void _DecodePrefix_66(InstrMnemonic *instr, addr_t p) { - instr->OperandSz = OpSz_16; - _DecodeLegacyPrefix(instr, p); -} - -// ===== Decode Opcode ===== - -static void _DecodeOp(InstrMnemonic *instr, addr_t p) { - instr->instr.opcode1 = *(byte_t *)p; - instr->len++; -} - -static void _DecodeOpExtraOp(InstrMnemonic *instr, addr_t p) { - _DecodeOp(instr, p); -} - -static void _DecodeOpWithReg(InstrMnemonic *instr, addr_t p) { - _DecodeOp(instr, p); -} - -#define _xDecodeOpEn_ZO 1, OpEn_ZO, OpSz_0, ImmSz_0, _DecodeOpEn_ZO -void _DecodeOpEn_ZO(InstrMnemonic *instr, addr_t p) { - _DecodeOp(instr, p); -} - -#define _xDecodeOpEn_O 1, OpEn_O, OpSz_0, ImmSz_0, _DecodeOpEn_O -void _DecodeOpEn_O(InstrMnemonic *instr, addr_t p) { - _DecodeOpWithReg(instr, p); -} - -// ===== Decode Operand ===== - -// ===== Decode ModRM Operand ===== - -#define REX_W(byte) ((byte & 0b00001000) >> 3) -#define REX_R(byte) ((byte & 0b00000100) >> 2) -#define REX_X(byte) ((byte & 0b00000010) >> 1) -#define REX_B(byte) ((byte & 0b00000001) >> 0) - -#define ModRM_Mod(byte) ((byte & 0b11000000) >> 6) -#define ModRM_RegOpcode(byte) ((byte & 0b00111000) >> 3) -#define ModRM_RM(byte) (byte & 0b00000111) - -#define SIB_Scale(sib) ((sib & 0b11000000) >> 6) -#define SIB_Index(sib) ((sib & 0b00111000) >> 3) -#define SIB_Base(sib) ((sib & 0b00000111) >> 0) - -#define REX_SIB_Base(rex, sib) ((REX_B(rex) << 3) | SIB_Base(sib)) - -void _DecodeDisplacement8(InstrMnemonic *instr, addr_t p) { - *(byte_t *)&instr->instr.Displacement = *(byte_t *)p; - instr->len += 1; -} - -void _DecodeDisplacement32(InstrMnemonic *instr, addr_t p) { - instr->instr.DisplacementOffset = instr->len; - *(dword *)&instr->instr.Displacement = *(byte_t *)p; - instr->len += 4; -} - -void _DecodeSIB(InstrMnemonic *instr, addr_t p) { - instr->instr.SIB = *(byte_t *)p; - instr->len++; -} - -void _DecodeModRM(InstrMnemonic *instr, addr_t p) { - int init_len = instr->len; - - instr->instr.ModRM = *(byte_t *)p; - instr->len++; - -#if defined(_M_X64) || defined(__x86_64__) - if (ModRM_Mod(instr->instr.ModRM) == 0b00 && ModRM_RM(instr->instr.ModRM) == 0b101) { - // RIP-Relative Addressing - instr->flag = instr->flag | kIPRelativeAddress; - _DecodeDisplacement32(instr, p + (instr->len - init_len)); - return; - } -#endif - - // Addressing Forms with the SIB Byte - if (ModRM_Mod(instr->instr.ModRM) != 0b11 && ModRM_RM(instr->instr.ModRM) == 0b100) { - _DecodeSIB(instr, p + (instr->len - init_len)); - } - - // [REG] - if (ModRM_Mod(instr->instr.ModRM) == 0b00) { - if (ModRM_RM(instr->instr.ModRM) == 0b101) { - _DecodeDisplacement32(instr, p + (instr->len - init_len)); - return; - } - } - - // [REG+disp8} - if (ModRM_Mod(instr->instr.ModRM) == 0b01) { - _DecodeDisplacement8(instr, p + (instr->len - init_len)); - return; - } - - // [REG+disp32} - if (ModRM_Mod(instr->instr.ModRM) == 0b10) { - _DecodeDisplacement32(instr, p + (instr->len - init_len)); - return; - } - - // REG - if (ModRM_Mod(instr->instr.ModRM) == 0b11) { - } -} - -void _DecodeOpEn_M(InstrMnemonic *instr, addr_t p) { - _DecodeOp(instr, p); - _DecodeModRM(instr, p + 1); -} - -void _DecodeOpEn_RM(InstrMnemonic *instr, addr_t p) { - _DecodeOp(instr, p); - _DecodeModRM(instr, p + 1); -} - -void _DecodeOpEn_MR(InstrMnemonic *instr, addr_t p) { - _DecodeOp(instr, p); - _DecodeModRM(instr, p + 1); -} - -void _DecodeOpEn_M1(InstrMnemonic *instr, addr_t p) { - _DecodeOp(instr, p); - _DecodeModRM(instr, p + 1); -} - -void _DecodeOpEn_MC(InstrMnemonic *instr, addr_t p) { - _DecodeOp(instr, p); - _DecodeModRM(instr, p + 1); -} - -// ===== Decode Immediate Operand ===== - -void _DecodeImmedite(InstrMnemonic *instr, addr_t p, int sz) { - - instr->instr.ImmediateOffset = instr->len; - - OpcodeDecodeItem *item = &OpcodeDecodeTable[instr->instr.opcode1]; - if (sz == ImmSz_0) { - sz = item->ImmediteSz; - if (sz == (ImmSz_16 | ImmSz_32)) { - if (instr->instr.prefix == 0x66) { - sz = ImmSz_16; - } else { - sz = ImmSz_32; // Default Immedite Size - } - } - } - - if (sz == ImmSz_8) { - *(byte_t *)&instr->instr.Immediate = *(byte_t *)p; - instr->len += 1; - } else if (sz == ImmSz_16) { - *(word *)&instr->instr.Immediate = *(dword *)p; - instr->len += 2; - } else if (sz == ImmSz_32) { - *(dword *)&instr->instr.Immediate = *(dword *)p; - instr->len += 4; - } -} - -void _DecodeOpEn_I(InstrMnemonic *instr, addr_t p) { - _DecodeOp(instr, p); - _DecodeImmedite(instr, p + 1, instr->ImmediteSz); -} - -void _DecodeOpEn_OI(InstrMnemonic *instr, addr_t p) { - _DecodeOpWithReg(instr, p); - _DecodeImmedite(instr, p + 1, instr->ImmediteSz); -} - -void _DecodeOpEn_D(InstrMnemonic *instr, addr_t p) { - _DecodeOp(instr, p); - _DecodeImmedite(instr, p + 1, instr->ImmediteSz); -} - -// ===== Decode ModRM Immediate Operand ===== - -void _DecodeOpEn_RMI(InstrMnemonic *instr, addr_t p) { - _DecodeOp(instr, p); - _DecodeModRM(instr, p + 1); - _DecodeImmedite(instr, p + 2, instr->ImmediteSz); -} - -void _DecodeOpEn_MI(InstrMnemonic *instr, addr_t p) { - _DecodeOpExtraOp(instr, p); - _DecodeModRM(instr, p + 1); - _DecodeImmedite(instr, p + 2, instr->ImmediteSz); -} - -// ===== Decode Specific Opcode ===== - -#define _xDecodeOpC8 1, 0, OpSz_0, ImmSz_0, _DecodeOpC8 -void _DecodeOpC8(InstrMnemonic *instr, addr_t p) { - _DecodeOp(instr, p); - - instr->len = instr->len + 2 + 1; -} - -// http://ref.x86asm.net/coder.html#x04 -OpcodeDecodeItem OpcodeDecodeTable[257] = { - - {0x00, 2, OpEn_MR, OpSz_8, ImmSz_0, _DecodeOpEn_MR}, - {0x01, 2, OpEn_MR, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_MR}, - {0x02, 2, OpEn_RM, OpSz_8, ImmSz_0, _DecodeOpEn_RM}, - {0x03, 2, OpEn_RM, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_RM}, - {0x04, 1, OpEn_I, OpSz_0, ImmSz_8, _DecodeOpEn_I}, - {0x05, 1, OpEn_I, OpSz_16 | OpSz_32, ImmSz_16 | ImmSz_32, _DecodeOpEn_I}, -#if defined(_M_X64) || defined(__x86_64__) - {0x06, _xInvalidOpHanlder}, - {0x07, _xInvalidOpHanlder}, -#else - {0x06, _xDecodeOpEn_ZO}, - {0x07, _xDecodeOpEn_ZO}, -#endif - {0x08, 2, OpEn_MR, OpSz_8, ImmSz_0, _DecodeOpEn_MR}, - {0x09, 2, OpEn_MR, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_MR}, - {0x0A, 2, OpEn_RM, OpSz_8, ImmSz_0, _DecodeOpEn_RM}, - {0x0B, 2, OpEn_RM, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_RM}, - {0x0C, 1, OpEn_I, OpSz_0, ImmSz_8, _DecodeOpEn_I}, - {0x0D, 1, OpEn_I, OpSz_16 | OpSz_32, ImmSz_16 | ImmSz_32, _DecodeOpEn_I}, -#if defined(_M_X64) || defined(__x86_64__) - {0x0E, _xInvalidOpHanlder}, -#else - {0x0E, _xDecodeOpEn_ZO}, -#endif - {0x0F, _xDecodePrefix_0F}, - {0x10, 2, OpEn_MR, OpSz_8, ImmSz_0, _DecodeOpEn_MR}, - {0x11, 2, OpEn_MR, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_MR}, - {0x12, 2, OpEn_RM, OpSz_8, ImmSz_0, _DecodeOpEn_RM}, - {0x13, 2, OpEn_RM, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_RM}, - {0x14, 1, OpEn_I, OpSz_0, ImmSz_8, _DecodeOpEn_I}, - {0x15, 1, OpEn_I, OpSz_16 | OpSz_32, ImmSz_16 | ImmSz_32, _DecodeOpEn_I}, -#if defined(_M_X64) || defined(__x86_64__) - {0x16, _xInvalidOpHanlder}, - {0x17, _xInvalidOpHanlder}, -#else - {0x16, _xDecodeOpEn_ZO}, - {0x17, _xDecodeOpEn_ZO}, -#endif - {0x18, 2, OpEn_MR, OpSz_8, ImmSz_0, _DecodeOpEn_MR}, - {0x19, 2, OpEn_MR, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_MR}, - {0x1A, 2, OpEn_RM, OpSz_8, ImmSz_0, _DecodeOpEn_RM}, - {0x1B, 2, OpEn_RM, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_RM}, - {0x1C, 1, OpEn_I, OpSz_0, ImmSz_8, _DecodeOpEn_I}, - {0x1D, 1, OpEn_I, OpSz_16 | OpSz_32, ImmSz_16 | ImmSz_32, _DecodeOpEn_I}, -#if defined(_M_X64) || defined(__x86_64__) - {0x1E, _xInvalidOpHanlder}, - {0x1F, _xInvalidOpHanlder}, -#else - {0x1E, _xDecodeOpEn_ZO}, - {0x1F, _xDecodeOpEn_ZO}, -#endif - {0x20, 2, OpEn_MR, OpSz_8, ImmSz_0, _DecodeOpEn_MR}, - {0x21, 2, OpEn_MR, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_MR}, - {0x22, 2, OpEn_RM, OpSz_8, ImmSz_0, _DecodeOpEn_RM}, - {0x23, 2, OpEn_RM, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_RM}, - {0x24, 1, OpEn_I, OpSz_0, ImmSz_8, _DecodeOpEn_I}, - {0x25, 1, OpEn_I, OpSz_16 | OpSz_32, ImmSz_16 | ImmSz_32, _DecodeOpEn_I}, - {0x26, _xDecodeSegPrefix}, -#if defined(_M_X64) || defined(__x86_64__) - {0x27, _xInvalidOpHanlder}, -#else - {0x27, _xDecodeOpEn_ZO}, -#endif - {0x28, 2, OpEn_MR, OpSz_8, ImmSz_0, _DecodeOpEn_MR}, - {0x29, 2, OpEn_MR, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_MR}, - {0x2A, 2, OpEn_RM, OpSz_8, ImmSz_0, _DecodeOpEn_RM}, - {0x2B, 2, OpEn_RM, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_RM}, - {0x2C, 1, OpEn_I, OpSz_0, ImmSz_8, _DecodeOpEn_I}, - {0x2D, 1, OpEn_I, OpSz_16 | OpSz_32, ImmSz_16 | ImmSz_32, _DecodeOpEn_I}, - {0x2E, _xDecodeSegPrefix}, -#if defined(_M_X64) || defined(__x86_64__) - {0x2F, _xInvalidOpHanlder}, -#else - {0x2F, _xDecodeOpEn_ZO}, -#endif - {0x30, 2, OpEn_MR, OpSz_8, ImmSz_0, _DecodeOpEn_MR}, - {0x31, 2, OpEn_MR, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_MR}, - {0x32, 2, OpEn_RM, OpSz_8, ImmSz_0, _DecodeOpEn_RM}, - {0x33, 2, OpEn_RM, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_RM}, - {0x34, 1, OpEn_I, OpSz_0, ImmSz_8, _DecodeOpEn_I}, - {0x35, 1, OpEn_I, OpSz_16 | OpSz_32, ImmSz_16 | ImmSz_32, _DecodeOpEn_I}, - {0x36, _xDecodeSegPrefix}, -#if defined(_M_X64) || defined(__x86_64__) - {0x37, _xInvalidOpHanlder}, -#else - {0x37, _xDecodeOpEn_ZO}, -#endif - {0x38, 2, OpEn_MR, OpSz_8, ImmSz_0, _DecodeOpEn_MR}, - {0x39, 2, OpEn_MR, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_MR}, - {0x3A, 2, OpEn_RM, OpSz_8, ImmSz_0, _DecodeOpEn_RM}, - {0x3B, 2, OpEn_RM, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_RM}, - {0x3C, 1, OpEn_I, OpSz_0, ImmSz_8, _DecodeOpEn_I}, - {0x3D, 1, OpEn_I, OpSz_16 | OpSz_32, ImmSz_16 | ImmSz_32, _DecodeOpEn_I}, - {0x3E, _xDecodeSegPrefix}, -#if defined(_M_X64) || defined(__x86_64__) - {0x3F, _xInvalidOpHanlder}, -#else - {0x3F, _xDecodeOpEn_ZO}, -#endif -#if defined(_M_X64) || defined(__x86_64__) // For REX Prefix - {0x40, _xDecodeREXPrefix}, - {0x41, _xDecodeREXPrefix}, - {0x42, _xDecodeREXPrefix}, - {0x43, _xDecodeREXPrefix}, - {0x44, _xDecodeREXPrefix}, - {0x45, _xDecodeREXPrefix}, - {0x46, _xDecodeREXPrefix}, - {0x47, _xDecodeREXPrefix}, - {0x48, _xDecodeREXPrefix}, - {0x49, _xDecodeREXPrefix}, - {0x4A, _xDecodeREXPrefix}, - {0x4B, _xDecodeREXPrefix}, - {0x4C, _xDecodeREXPrefix}, - {0x4D, _xDecodeREXPrefix}, - {0x4E, _xDecodeREXPrefix}, - {0x4F, _xDecodeREXPrefix}, -#else - {0x40, _xDecodeOpEn_O}, - {0x41, _xDecodeOpEn_O}, - {0x42, _xDecodeOpEn_O}, - {0x43, _xDecodeOpEn_O}, - {0x44, _xDecodeOpEn_O}, - {0x45, _xDecodeOpEn_O}, - {0x46, _xDecodeOpEn_O}, - {0x47, _xDecodeOpEn_O}, - {0x48, _xDecodeOpEn_O}, - {0x49, _xDecodeOpEn_O}, - {0x4A, _xDecodeOpEn_O}, - {0x4B, _xDecodeOpEn_O}, - {0x4C, _xDecodeOpEn_O}, - {0x4D, _xDecodeOpEn_O}, - {0x4E, _xDecodeOpEn_O}, - {0x4F, _xDecodeOpEn_O}, -#endif - {0x50, _xDecodeOpEn_O}, - {0x51, _xDecodeOpEn_O}, - {0x52, _xDecodeOpEn_O}, - {0x53, _xDecodeOpEn_O}, - {0x54, _xDecodeOpEn_O}, - {0x55, _xDecodeOpEn_O}, - {0x56, _xDecodeOpEn_O}, - {0x57, _xDecodeOpEn_O}, - {0x58, _xDecodeOpEn_O}, - {0x59, _xDecodeOpEn_O}, - {0x5A, _xDecodeOpEn_O}, - {0x5B, _xDecodeOpEn_O}, - {0x5C, _xDecodeOpEn_O}, - {0x5D, _xDecodeOpEn_O}, - {0x5E, _xDecodeOpEn_O}, - {0x5F, _xDecodeOpEn_O}, -#if defined(_M_X64) || defined(__x86_64__) - {0x60, _xInvalidOpHanlder}, - {0x61, _xInvalidOpHanlder}, - {0x62, _xInvalidOpHanlder}, -#else - {0x60, _xDecodeOpEn_ZO}, - {0x61, _xDecodeOpEn_ZO}, - {0x62, 2, OpEn_RM, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_RM}, -#endif - {0x63, 2, OpEn_RM, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_RM}, - {0x64, _xDecodeSegPrefix}, - {0x65, _xDecodeSegPrefix}, - {0x66, _xDecodePrefix_66}, - {0x67, _xDecodePrefix_67}, - {0x68, 1, OpEn_I, OpSz_16 | OpSz_32, ImmSz_16 | ImmSz_32, _DecodeOpEn_I}, - {0x69, 2, OpEn_RMI, OpSz_16 | OpSz_32, ImmSz_16 | ImmSz_32, _DecodeOpEn_RMI}, - {0x6A, 1, OpEn_I, OpSz_0, ImmSz_8, _DecodeOpEn_I}, - {0x6B, 1, OpEn_RMI, OpSz_16 | OpSz_32, ImmSz_8, _DecodeOpEn_RMI}, - {0x6C, _xDecodeOpEn_ZO}, - {0x6D, _xDecodeOpEn_ZO}, - {0x6E, _xDecodeOpEn_ZO}, - {0x6F, _xDecodeOpEn_ZO}, - {0x70, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0x71, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0x72, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0x73, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0x74, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0x75, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0x76, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0x77, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0x78, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0x79, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0x7A, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0x7B, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0x7C, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0x7D, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0x7E, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0x7F, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0x80, 2, OpEn_MI, OpSz_8, ImmSz_8, _DecodeOpEn_MI}, - {0x81, 2, OpEn_MI, OpSz_16 | OpSz_32, ImmSz_16 | ImmSz_32, _DecodeOpEn_MI}, -#if defined(_M_X64) || defined(__x86_64__) - {0x82, _xInvalidOpHanlder}, -#else - {0x82, _xUnknownOpHanlder}, -#endif - {0x83, 2, OpEn_MI, OpSz_16 | OpSz_32, ImmSz_8, _DecodeOpEn_MI}, - {0x84, 2, OpEn_MR, OpSz_8, ImmSz_0, _DecodeOpEn_MR}, - {0x85, 2, OpEn_MR, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_MR}, - {0x86, 2, OpEn_RM, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_RM}, - {0x87, 2, OpEn_RM, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_RM}, - {0x88, 2, OpEn_MR, OpSz_8, ImmSz_0, _DecodeOpEn_MR}, - {0x89, 2, OpEn_MR, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_MR}, - {0x8A, 2, OpEn_RM, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_RM}, - {0x8B, 2, OpEn_RM, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_RM}, - {0x8C, 2, OpEn_MR, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_MR}, - {0x8D, 2, OpEn_RM, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_RM}, - {0x8E, 2, OpEn_RM, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_RM}, - {0x8F, 2, OpEn_M, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_M}, - {0x90, _xDecodeOpEn_ZO}, - {0x91, _xInvalidOpHanlder}, - {0x92, _xInvalidOpHanlder}, - {0x93, _xInvalidOpHanlder}, - {0x94, _xInvalidOpHanlder}, - {0x95, _xInvalidOpHanlder}, - {0x96, _xInvalidOpHanlder}, - {0x97, _xInvalidOpHanlder}, - {0x98, _xDecodeOpEn_ZO}, - {0x99, _xDecodeOpEn_ZO}, -#if defined(_M_X64) || defined(__x86_64__) - {0x9A, _xInvalidOpHanlder}, -#else - {0x9A, _xDecodeOpEn_ZO}, -#endif - {0x9B, _xDecodeOpEn_ZO}, - {0x9C, _xDecodeOpEn_ZO}, - {0x9D, _xDecodeOpEn_ZO}, - {0x9E, _xDecodeOpEn_ZO}, - {0x9F, _xDecodeOpEn_ZO}, - {0xA0, _xUnknownOpHanlder}, - {0xA1, _xUnknownOpHanlder}, - {0xA2, _xUnknownOpHanlder}, - {0xA3, _xUnknownOpHanlder}, - {0xA4, _xDecodeOpEn_ZO}, - {0xA5, _xDecodeOpEn_ZO}, - {0xA6, _xDecodeOpEn_ZO}, - {0xA7, _xDecodeOpEn_ZO}, - {0xA8, 1, OpEn_I, OpSz_0, ImmSz_8, _DecodeOpEn_I}, - {0xA9, 1, OpEn_I, OpSz_16 | OpSz_32, ImmSz_16 | ImmSz_32, _DecodeOpEn_I}, - {0xAA, _xDecodeOpEn_ZO}, - {0xAB, _xDecodeOpEn_ZO}, - {0xAC, _xDecodeOpEn_ZO}, - {0xAD, _xDecodeOpEn_ZO}, - {0xAE, _xDecodeOpEn_ZO}, - {0xAF, _xDecodeOpEn_ZO}, -#undef SAME_ITEM_LAZY -#define SAME_ITEM_LAZY 1, OpEn_OI, OpSz_0, ImmSz_8, _DecodeOpEn_OI - {0xB0, SAME_ITEM_LAZY}, - {0xB1, SAME_ITEM_LAZY}, - {0xB2, SAME_ITEM_LAZY}, - {0xB3, SAME_ITEM_LAZY}, - {0xB4, SAME_ITEM_LAZY}, - {0xB5, SAME_ITEM_LAZY}, - {0xB6, SAME_ITEM_LAZY}, - {0xB7, SAME_ITEM_LAZY}, -#undef SAME_ITEM_LAZY -#define SAME_ITEM_LAZY 1, OpEn_OI, OpSz_16 | OpSz_32, ImmSz_16 | ImmSz_32, _DecodeOpEn_OI - {0xB8, SAME_ITEM_LAZY}, - {0xB9, SAME_ITEM_LAZY}, - {0xBA, SAME_ITEM_LAZY}, - {0xBB, SAME_ITEM_LAZY}, - {0xBC, SAME_ITEM_LAZY}, - {0xBD, SAME_ITEM_LAZY}, - {0xBE, SAME_ITEM_LAZY}, - {0xBF, SAME_ITEM_LAZY}, - {0xC0, 2, OpEn_MI, OpSz_8, ImmSz_8, _DecodeOpEn_MI}, - {0xC1, 2, OpEn_MI, OpSz_16 | OpSz_32, ImmSz_16 | ImmSz_32, _DecodeOpEn_MI}, - {0xC2, 1, OpEn_I, OpSz_0, ImmSz_16, _DecodeOpEn_I}, - {0xC3, _xDecodeOpEn_ZO}, - {0xC4, _xInvalidOpHanlder}, - {0xC5, _xInvalidOpHanlder}, - {0xC6, _xUnknownOpHanlder}, - {0xC7, 2, OpEn_MI, OpSz_16 | OpSz_32, ImmSz_16 | ImmSz_32, _DecodeOpEn_MI}, - {0xC8, _xDecodeOpC8}, - {0xC9, _xDecodeOpEn_ZO}, - {0xCA, 1, OpEn_I, OpSz_0, ImmSz_16, _DecodeOpEn_I}, - {0xCB, _xDecodeOpEn_ZO}, - {0xCC, _xDecodeOpEn_ZO}, - {0xCD, 1, OpEn_I, OpSz_0, ImmSz_8, _DecodeOpEn_I}, -#if defined(_M_X64) || defined(__x86_64__) - {0xCE, _xInvalidOpHanlder}, -#else - {0xCE, _xDecodeOpEn_ZO}, -#endif - {0xCF, _xDecodeOpEn_ZO}, - {0xD0, 1, OpEn_M1, OpSz_8, ImmSz_0, _DecodeOpEn_M1}, - {0xD1, 1, OpEn_M1, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_M1}, - {0xD2, 1, OpEn_MC, OpSz_8, ImmSz_0, _DecodeOpEn_MC}, - {0xD3, 1, OpEn_MC, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_MC}, -#if defined(_M_X64) || defined(__x86_64__) - {0xD4, _xInvalidOpHanlder}, - {0xD5, _xInvalidOpHanlder}, -#else - {0xD4, 1, OpEn_I, OpSz_0, ImmSz_8, _DecodeOpEn_I}, - {0xD5, 1, OpEn_I, OpSz_0, ImmSz_8, _DecodeOpEn_I}, -#endif - {0xD6, _xInvalidOpHanlder}, - {0xD7, _xDecodeOpEn_ZO}, - {0xD8, _xUnknownOpHanlder}, - {0xD9, _xUnknownOpHanlder}, - {0xDA, _xUnknownOpHanlder}, - {0xDB, _xUnknownOpHanlder}, - {0xDC, _xUnknownOpHanlder}, - {0xDD, _xUnknownOpHanlder}, - {0xDE, _xUnknownOpHanlder}, - {0xDF, _xUnknownOpHanlder}, - {0xE0, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0xE1, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0xE2, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0xE3, 1, OpEn_D, OpSz_0, ImmSz_8, _DecodeOpEn_D}, - {0xE4, 1, OpEn_I, OpSz_0, ImmSz_8, _DecodeOpEn_I}, - {0xE5, 1, OpEn_I, OpSz_0, ImmSz_8, _DecodeOpEn_I}, - {0xE6, 1, OpEn_I, OpSz_0, ImmSz_8, _DecodeOpEn_I}, - {0xE7, 1, OpEn_I, OpSz_0, ImmSz_8, _DecodeOpEn_I}, - {0xE8, 1, OpEn_I, OpSz_16 | OpSz_32, ImmSz_16 | ImmSz_32, _DecodeOpEn_I}, - {0xE9, 1, OpEn_I, OpSz_16 | OpSz_32, ImmSz_16 | ImmSz_32, _DecodeOpEn_I}, -#if defined(_M_X64) || defined(__x86_64__) - {0xEA, _xInvalidOpHanlder}, -#else - {0xEA, _xUnknownOpHanlder}, -#endif - {0xEB, 1, OpEn_I, OpSz_0, ImmSz_8, _DecodeOpEn_I}, - {0xEC, _xDecodeOpEn_ZO}, - {0xED, _xDecodeOpEn_ZO}, - {0xEE, _xDecodeOpEn_ZO}, - {0xEF, _xDecodeOpEn_ZO}, - {0xF0, _xDecodePrefix}, - {0xF1, _xDecodeOpEn_ZO}, - {0xF2, _xDecodeOpEn_ZO}, -#ifdef DETOURS_X86 - {0xF3, _CopyF3}, -#else - {0xF3, _xDecodeOpEn_ZO}, -#endif - {0xF4, _xDecodeOpEn_ZO}, - {0xF5, _xDecodeOpEn_ZO}, - {0xF6, 2, OpEn_MI, OpSz_8, ImmSz_8, _DecodeOpEn_MI}, - {0xF7, 2, OpEn_MI, OpSz_16 | OpSz_32, ImmSz_16 | ImmSz_32, _DecodeOpEn_MI}, - {0xF8, _xDecodeOpEn_ZO}, - {0xF9, _xDecodeOpEn_ZO}, - {0xFA, _xDecodeOpEn_ZO}, - {0xFB, _xDecodeOpEn_ZO}, - {0xFC, _xDecodeOpEn_ZO}, - {0xFD, _xDecodeOpEn_ZO}, - {0xFE, 2, OpEn_M, OpSz_8, ImmSz_0, _DecodeOpEn_M}, - {0xFF, 2, OpEn_M, OpSz_16 | OpSz_32, ImmSz_0, _DecodeOpEn_M}, - {0, 0, 0, 0, 0}}; - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/deprecated/X86OpcodoDecodeTable.h b/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/deprecated/X86OpcodoDecodeTable.h deleted file mode 100644 index 778fdb30..00000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/deprecated/X86OpcodoDecodeTable.h +++ /dev/null @@ -1,142 +0,0 @@ -#ifndef X86_OPCODE_DECODE_TABLE_H -#define X86_OPCODE_DECODE_TABLE_H - -#ifndef __addr_t_defined -#define __addr_t_defined -typedef unsigned long long addr_t; -#endif - -#ifndef __byte_defined -#define __byte_defined -typedef unsigned char byte_t; -#endif - -#ifndef __uint_defined -#define __uint_defined -typedef unsigned int uint; -#endif - -#ifndef __word_defined -#define __word_defined -typedef short word; -#endif - -#ifndef __dword_defined -#define __dword_defined -typedef int dword; -#endif - -enum OpcodeType { OpTy_Op1, OpTy_RegInOp1, OpTy_Op1ExtraOp }; - -struct Instr { - byte_t prefix; - - byte_t REX; - - union { - byte_t opcode[3]; - struct { - byte_t opcode1; - byte_t opcode2; - byte_t opcode3; - }; - }; - - union { - byte_t ModRM; - struct { - byte_t Mod : 2; - byte_t RegOpcode : 3; - byte_t RM : 3; - }; - }; - - union { - byte_t SIB; - struct { - byte_t base : 2; - byte_t index : 3; - byte_t scale : 3; - }; - }; - - byte_t Displacement[4]; - int DisplacementOffset; - - byte_t Immediate[4]; - int ImmediateOffset; -}; - -// clang-format off -enum OperandSize { - OpSz_0 = 0, - OpSz_8=1, - OpSz_16=2, - OpSz_32=4, - OpSz_64=8 -}; - -enum ImmediteSize { - ImmSz_0 = 0, - ImmSz_8=1, - ImmSz_16=2, - ImmSz_32=4, - ImmSz_64=8 -}; - -enum InstrFlag { - kNoFlag = 0, - kIPRelativeAddress = 1 -}; -// clang-format on - -struct InstrMnemonic { - uint len; - - int flag; - - OperandSize OperandSz; - - ImmediteSize ImmediteSz; - - struct Instr instr; -}; - -struct OpcodeDecodeItem { - unsigned char opcode; - - int FixedSize; - - int OpEn; - - int OperandSz; - - int ImmediteSz; - - void (*DecodeHandler)(InstrMnemonic *, addr_t); -}; - -// clang-format off -enum OperandEncodingType { - OpEn_NONE =0, - OpEn_ZO, - OpEn_M, - OpEn_I, - OpEn_D, - OpEn_O, - OpEn_RM, - OpEn_MR, - OpEn_MI, - OpEn_OI, - OpEn_M1, - OpEn_MC, - OpEn_RMI -}; - -// clang-format on - -extern OpcodeDecodeItem OpcodeDecodeTable[257]; - -void _DecodePrefix(InstrMnemonic *instr, addr_t p); - -#endif diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/build_config.h b/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/build_config.h deleted file mode 100644 index 6206267e..00000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/build_config.h +++ /dev/null @@ -1,144 +0,0 @@ -#ifndef BUILD_CONFIG_H -#define BUILD_CONFIG_H - -#if defined(__APPLE__) -// only include TargetConditions after testing ANDROID as some android builds -// on mac don't have this header available and it's not needed unless the target -// is really mac/ios. -#include -#define OS_MACOSX 1 -#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE -#define OS_IOS 1 -#endif // defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE -#elif defined(__linux__) -#define OS_LINUX 1 -// include a system header to pull in features.h for glibc/uclibc macros. -#include -#if defined(__GLIBC__) && !defined(__UCLIBC__) -// we really are using glibc, not uClibc pretending to be glibc -#define LIBC_GLIBC 1 -#endif -#elif defined(_WIN32) -#define OS_WIN 1 -#elif defined(__Fuchsia__) -#define OS_FUCHSIA 1 -#elif defined(__FreeBSD__) -#define OS_FREEBSD 1 -#elif defined(__NetBSD__) -#define OS_NETBSD 1 -#elif defined(__OpenBSD__) -#define OS_OPENBSD 1 -#elif defined(__sun) -#define OS_SOLARIS 1 -#elif defined(__QNXNTO__) -#define OS_QNX 1 -#elif defined(_AIX) -#define OS_AIX 1 -#elif defined(__asmjs__) || defined(__wasm__) -#define OS_ASMJS -#else -#error Please add support for your platform in build/build_config.h -#endif -// NOTE: Adding a new port? Please follow -// https://chromium.googlesource.com/chromium/src/+/master/docs/new_port_policy.md - -// For access to standard BSD features, use OS_BSD instead of a -// more specific macro. -#if defined(OS_FREEBSD) || defined(OS_NETBSD) || defined(OS_OPENBSD) -#define OS_BSD 1 -#endif - -// For access to standard POSIXish features, use OS_POSIX instead of a -// more specific macro. -#if defined(OS_AIX) || defined(OS_ANDROID) || defined(OS_ASMJS) || defined(OS_FREEBSD) || defined(OS_LINUX) || \ - defined(OS_MACOSX) || defined(OS_NACL) || defined(OS_NETBSD) || defined(OS_OPENBSD) || defined(OS_QNX) || \ - defined(OS_SOLARIS) -#define OS_POSIX 1 -#endif - -// Compiler detection. Note: clang masquerades as GCC on POSIX and as MSVC on -// Windows. -#if defined(__GNUC__) -#define COMPILER_GCC 1 -#elif defined(_MSC_VER) -#define COMPILER_MSVC 1 -#else -#error Please add support for your compiler in build/build_config.h -#endif - -// Processor architecture detection. For more info on what's defined, see: -// http://msdn.microsoft.com/en-us/library/b0084kay.aspx -// http://www.agner.org/optimize/calling_conventions.pdf -// or with gcc, run: "echo | gcc -E -dM -" -#if defined(_M_X64) || defined(__x86_64__) -#define ARCH_CPU_X86_FAMILY 1 -#define ARCH_CPU_X86_64 1 -#define ARCH_CPU_64_BITS 1 -#define ARCH_CPU_LITTLE_ENDIAN 1 -#elif defined(_M_IX86) || defined(__i386__) -#define ARCH_CPU_X86_FAMILY 1 -#define ARCH_CPU_X86 1 -#define ARCH_CPU_32_BITS 1 -#define ARCH_CPU_LITTLE_ENDIAN 1 -#elif defined(__s390x__) -#define ARCH_CPU_S390_FAMILY 1 -#define ARCH_CPU_S390X 1 -#define ARCH_CPU_64_BITS 1 -#define ARCH_CPU_BIG_ENDIAN 1 -#elif defined(__s390__) -#define ARCH_CPU_S390_FAMILY 1 -#define ARCH_CPU_S390 1 -#define ARCH_CPU_31_BITS 1 -#define ARCH_CPU_BIG_ENDIAN 1 -#elif (defined(__PPC64__) || defined(__PPC__)) && defined(__BIG_ENDIAN__) -#define ARCH_CPU_PPC64_FAMILY 1 -#define ARCH_CPU_PPC64 1 -#define ARCH_CPU_64_BITS 1 -#define ARCH_CPU_BIG_ENDIAN 1 -#elif defined(__PPC64__) -#define ARCH_CPU_PPC64_FAMILY 1 -#define ARCH_CPU_PPC64 1 -#define ARCH_CPU_64_BITS 1 -#define ARCH_CPU_LITTLE_ENDIAN 1 -#elif defined(__ARMEL__) -#define ARCH_CPU_ARM_FAMILY 1 -#define ARCH_CPU_ARMEL 1 -#define ARCH_CPU_32_BITS 1 -#define ARCH_CPU_LITTLE_ENDIAN 1 -#elif defined(__aarch64__) || defined(_M_ARM64) -#define ARCH_CPU_ARM_FAMILY 1 -#define ARCH_CPU_ARM64 1 -#define ARCH_CPU_64_BITS 1 -#define ARCH_CPU_LITTLE_ENDIAN 1 -#elif defined(__pnacl__) || defined(__asmjs__) || defined(__wasm__) -#define ARCH_CPU_32_BITS 1 -#define ARCH_CPU_LITTLE_ENDIAN 1 -#elif defined(__MIPSEL__) -#if defined(__LP64__) -#define ARCH_CPU_MIPS_FAMILY 1 -#define ARCH_CPU_MIPS64EL 1 -#define ARCH_CPU_64_BITS 1 -#define ARCH_CPU_LITTLE_ENDIAN 1 -#else -#define ARCH_CPU_MIPS_FAMILY 1 -#define ARCH_CPU_MIPSEL 1 -#define ARCH_CPU_32_BITS 1 -#define ARCH_CPU_LITTLE_ENDIAN 1 -#endif -#elif defined(__MIPSEB__) -#if defined(__LP64__) -#define ARCH_CPU_MIPS_FAMILY 1 -#define ARCH_CPU_MIPS64 1 -#define ARCH_CPU_64_BITS 1 -#define ARCH_CPU_BIG_ENDIAN 1 -#else -#define ARCH_CPU_MIPS_FAMILY 1 -#define ARCH_CPU_MIPS 1 -#define ARCH_CPU_32_BITS 1 -#define ARCH_CPU_BIG_ENDIAN 1 -#endif -#else -#error Please add support for your architecture in build/build_config.h -#endif - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_insn_decode.c b/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_insn_decode.c deleted file mode 100644 index 5b8fc32a..00000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_insn_decode.c +++ /dev/null @@ -1,564 +0,0 @@ -#include "platform_detect_macro.h" -#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) - -#include "x86_insn_decode.h" - -#include "logging/logging.h" - -#define REX_W(byte) ((byte & 0b00001000) >> 3) -#define REX_R(byte) ((byte & 0b00000100) >> 2) -#define REX_X(byte) ((byte & 0b00000010) >> 1) -#define REX_B(byte) ((byte & 0b00000001) >> 0) - -#define ModRM_Mod(byte) ((byte & 0b11000000) >> 6) -#define ModRM_RegOpcode(byte) ((byte & 0b00111000) >> 3) -#define ModRM_RM(byte) (byte & 0b00000111) - -#define SIB_Scale(sib) ((sib & 0b11000000) >> 6) -#define SIB_Index(sib) ((sib & 0b00111000) >> 3) -#define SIB_Base(sib) ((sib & 0b00000111) >> 0) - -#if 0 -/* Build an encoding specification from scratch. */ -#define SPEC_MAKE(op, opr1, opr2, opr3, opr4) \ - ((uint64_t)(uint16_t)(int16_t)(op) | ((uint64_t)(opr1) << 16) | ((uint64_t)(opr2) << 24) | \ - ((uint64_t)(opr3) << 32) | ((uint64_t)(opr4) << 40)) - -/* Get the operation in an encoding specification. */ -#define SPEC_INSN(spec) ((int16_t)((spec)&0xffff)) - -/* Get the given operand (zero-based) in an encoding specification. */ -#define SPEC_OPERAND(spec, i) ((uint8_t)(((spec) >> (16 + (i)*8)) & 0xff)) - -/* Get the operands part of an encoding specification. */ -#define SPEC_OPERANDS(spec) ((spec)&0xffffffffffff0000ULL) - -/* Merges two encoding specifications. */ -#define SPEC_MERGE(spec1, spec2) ((spec1) | (spec2)) - -#define OP4(insn, oper1, oper2, oper3, oper4) SPEC_MAKE(I_##insn, O_##oper1, O_##oper2, O_##oper3, O_##oper4) -#define OP3(insn, oper1, oper2, oper3) OP4(insn, oper1, oper2, oper3, NONE) -#define OP2(insn, oper1, oper2) OP3(insn, oper1, oper2, NONE) -#define OP1(insn, oper1) OP2(insn, oper1, NONE) -#define OP0(insn) OP1(insn, NONE) -#define OP_EMPTY OP0(NONE) -#define OP_EMPTY_4 OP_EMPTY, OP_EMPTY, OP_EMPTY, OP_EMPTY -#define OP_EMPTY_8 OP_EMPTY_4, OP_EMPTY_4 -#endif - -#define op3_flag(x, f, o0, o1, o2) \ - { \ - .name = #x, .flags = (f), .operands[0] = {.data = #o0}, .operands[1] = {.data = #o1}, \ - .operands[2] = {.data = #o2}, \ - } -#define op2_flag(x, f, o0, o1) op3_flag(x, f, o0, o1, __) -#define op1_flag(x, f, o0) op2_flag(x, f, o0, __) -#define op0_flag(x, f) op1_flag(x, f, __) - -#define op3f op3_flag -#define op2f op2_flag -#define op1f op1_flag -#define op0f op0_flag - -#define op3(x, o0, o1, o2) op3f(x, 0, o0, o1, o2) -#define op2(x, o0, o1) op2f(x, 0, o0, o1) -#define op1(x, o0) op1f(x, 0, o0) -#define op0(x) op0f(x, 0) - -/* Opcode extension in modrm byte reg field. */ -#define foreach_x86_insn_modrm_reg_group \ - _(1) _(1a) _(2) _(3) _(4) _(5) _(6) _(7) _(8) _(9) _(10) _(11) _(12) _(13) _(14) _(15) _(16) _(p) -#define foreach_x86_insn_sse_group \ - _(10) _(28) _(50) _(58) _(60) _(68) _(70) _(78) _(c0) _(d0) _(d8) _(e0) _(e8) _(f0) _(f8) -enum { - X86_INSN_GROUP_START = 0, - -#define _(x) X86_INSN_MODRM_REG_GROUP_##x, - foreach_x86_insn_modrm_reg_group -#undef _ - - X86_INSN_SSE_GROUP_START = 19, -#define _(x) X86_INSN_SSE_GROUP_##x, - foreach_x86_insn_sse_group -#undef _ - - X86_INSN_GROUP_END = 35 -}; - -#define X86_INSN_GROUP_END_MASK ((1 << 6) - 1) -#define X86_INSN_FLAG_SET_GROUP(n) ((n) << 5) -#define X86_INSN_FLAG_GET_GROUP(f) (((f) >> 5) & X86_INSN_GROUP_END_MASK) - -enum { -#define _(x) X86_INSN_FLAG_MODRM_REG_GROUP_##x = X86_INSN_FLAG_SET_GROUP(X86_INSN_MODRM_REG_GROUP_##x), - foreach_x86_insn_modrm_reg_group -#undef _ - -#define _(x) X86_INSN_FLAG_SSE_GROUP_##x = X86_INSN_FLAG_SET_GROUP(X86_INSN_SSE_GROUP_##x), - foreach_x86_insn_sse_group -#undef _ -}; - -// clang-format off - -#define foreach_x86_operand_combine(x, op1_type, op2_type) op2(x, Eb, Gb), op2(x, Ev, Gv), op2(x, Gb, Eb), op2(x, Gv, Ev), op2(x, AL, Ib), op2(x, AX, Iz) - -#define foreach_x86_gp_reg _(AX) _(CX) _(DX) _(BX) _(SP) _(BP) _(SI) _(DI) - -#define foreach_x86_condition _(o) _(no) _(b) _(nb) _(z) _(nz) _(be) _(nbe) _(s) _(ns) _(p) _(np) _(l) _(nl) _(le) _(nle) - -// clang-format on - -#include "./x86_opcode_one_byte.c" -#include "./x86_opcode_two_byte.c" - -typedef struct { - x86_insn_spec_t insns[8]; -} x86_insn_group8_t; - -#include "./x86_opcode_modrm_reg_group.c" -#include "./x86_opcode_sse_group.c" - -#include "./x86_insn_reader.c" - -static x86_insn_prefix_t x86_insn_decode_prefix(x86_insn_reader_t *rd, x86_insn_decode_t *insn, x86_options_t *conf) { - /* Decode each byte until the byte is not a prefix or is an REX prefix, - * because an REX prefix is required to immediately preceed the opcode. - */ - x86_insn_prefix_t insn_prefix = 0; - for (;;) { - uint8_t c = peek_byte(rd); - x86_insn_prefix_t t = 0; - - /* Check for REX prefix if we're in 64-bit mode. */ - if (conf->mode == 64) { - if (c >= 0x40 && c <= 0x4f) { - uint8_t rex = read_byte(rd); - - if (REX_W(rex)) { - insn->flags |= X86_INSN_DECODE_FLAG_OPERAND_SIZE_64; - } - - insn->rex = rex; - - break; - } - } - - /* Check for legacy prefixes. */ - switch (c) { - case 0xF0: - t = INSN_PREFIX_LOCK; - break; - case 0xF2: - t = INSN_PREFIX_REPNE; - break; - case 0xF3: - t = INSN_PREFIX_REPE; - break; - case 0x2E: - t = INSN_PREFIX_CS; - break; - case 0x36: - t = INSN_PREFIX_SS; - break; - case 0x3E: - t = INSN_PREFIX_DS; - break; - case 0x26: - t = INSN_PREFIX_ES; - break; - case 0x64: - t = INSN_PREFIX_FS; - break; - case 0x65: - t = INSN_PREFIX_GS; - break; - case 0x66: - t = INSN_PREFIX_OPERAND_SIZE; - break; - case 0x67: - t = INSN_PREFIX_ADDRESS_SIZE; - break; - } - if (t == 0) - break; - - /* Consume 1 byte. */ - read_byte(rd); - insn_prefix |= t; - } - - return insn_prefix; -} - -int x86_insn_has_modrm_byte(x86_insn_spec_t *insn) { - int i; - for (i = 0; i < sizeof(insn->operands) / sizeof(x86_insn_operand_spec_t); i++) - switch (insn->operands[i].code) { - case 'G': - case 'E': - case 'M': - case 'R': - return 1; - } - return 0; -} - -int x86_insn_immediate_type(x86_insn_spec_t *insn) { - int i; - for (i = 0; i < sizeof(insn->operands); i++) { - switch (insn->operands[i].code) { - case 'J': - case 'I': - case 'O': - return insn->operands[i].type; - } - } - return 0; -} - -int x86_insn_has_immediate(x86_insn_spec_t *insn) { - int i; - for (i = 0; i < sizeof(insn->operands) / sizeof(x86_insn_operand_spec_t); i++) { - switch (insn->operands[i].code) { - case 'J': - case 'I': - case 'O': - return 1; - } - } - return 0; -} - -static uint8_t *x86_insn_decode_number(x86_insn_reader_t *rd, uint8_t number_bits, int64_t *out_number) { - int64_t disp = 0; - switch (number_bits) { - case 64: - disp = read_uint64(rd); - break; - case 32: - disp = read_uint32(rd); - break; - case 16: - disp = read_uint16(rd); - break; - case 8: - disp = read_uint8(rd); - break; - default: - UNREACHABLE(); - } - - *out_number = disp; - return NULL; -} - -void x86_insn_decode_modrm_sib(x86_insn_reader_t *rd, x86_insn_decode_t *insn, x86_options_t *conf) { - uint8_t mod, rm, reg; - - x86_insn_modrm_t modrm; - modrm.byte = read_byte(rd); - insn->modrm = modrm; - - mod = modrm.mode; - rm = (uint8_t)((REX_B(insn->rex) << 3) | modrm.rm); - reg = (uint8_t)((REX_R(insn->rex) << 3) | modrm.reg); - - x86_insn_operand_t *reg_op = &insn->operands[0]; - x86_insn_operand_t *mem_op = &insn->operands[1]; - - reg_op->reg = reg; - - if (mod == 3) { - mem_op->reg = rm; - return; - } - - uint8_t disp_bits = -1; - - insn->flags |= X86_INSN_DECODE_FLAG_IS_ADDRESS; - - uint8_t effective_address_bits; - if (conf->mode == 64) - effective_address_bits = (insn->prefix & INSN_PREFIX_ADDRESS_SIZE) ? 32 : 64; - else if (conf->mode == 32) - effective_address_bits = (insn->prefix & INSN_PREFIX_ADDRESS_SIZE) ? 16 : 32; - else { - ERROR_LOG("16-bit address mode not supported"); - } - - if (effective_address_bits == 32 || effective_address_bits == 64) { - mem_op->mem.base = rm; - - insn->flags |= X86_INSN_DECODE_FLAG_HAS_BASE; - - if (mod == 0 && (rm & 7) == 5) { - insn->flags = X86_INSN_DECODE_FLAG_IP_RELATIVE; - mem_op->mem.base = RIP; - disp_bits = 32; - } else if (mod == 0) { - disp_bits = 0; - } else if (mod == 1) { - disp_bits = 8; - } else if (mod == 2) { - disp_bits = 32; - } else { - disp_bits = 0; - } - - uint8_t has_sib = 0; - if ((rm & 7) == 4) { - ASSERT(modrm.rm == (rm & 7)); - has_sib = 1; - } - - if (has_sib) { - x86_insn_sib_t sib = {0}; - sib.byte = read_byte(rd); - insn->sib = sib; - - uint8_t base = (uint8_t)(sib.base | (REX_B(insn->rex) << 3)); - uint8_t index = (uint8_t)(sib.index | (REX_X(insn->rex) << 3)); - uint8_t scale = (uint8_t)(1 << sib.log2_scale); - - insn->flags |= X86_INSN_DECODE_FLAG_HAS_BASE; - - if (sib.index != X86_INSN_GP_REG_SP) { - insn->flags |= X86_INSN_DECODE_FLAG_HAS_INDEX; - } - - insn->operands[1].mem.base = base; - insn->operands[1].mem.index = index; - insn->operands[1].mem.scale = scale; - - if (sib.index == X86_INSN_GP_REG_SP) { - insn->operands[1].mem.index = RNone; - insn->operands[1].mem.scale = 0; - } - - // for 64 bit - if (effective_address_bits == 64) { - if (mem_op->mem.base == RBP || mem_op->mem.base == R13) { - if (mod == 0) { - mem_op->mem.base = RNone; - } - if (mod == 1) { - disp_bits = 8; - } else { - disp_bits = 32; - } - } - - if (sib.index != X86_INSN_GP_REG_SP) { - insn->flags |= X86_INSN_DECODE_FLAG_HAS_INDEX; - } - } - - // for 32 bit - if (effective_address_bits == 32) { - if (mem_op->mem.base == RBP) { - if (mod == 0) { - mem_op->mem.base = RNone; - } - if (mod == 1) { - disp_bits = 8; - } else { - disp_bits = 32; - } - } - } - } - } - - // for 16 bit - if (effective_address_bits == 16) { - switch (modrm.mode) { - case 0: - if (modrm.rm == 6) { - /* [disp16] */ - disp_bits = 16; - break; - } - /* fall through */ - case 1: - case 2: - switch (modrm.rm) { - case 0: /* [bx + si/di] */ - case 1: - mem_op->mem.base = X86_INSN_GP_REG_BX; - mem_op->mem.index = X86_INSN_GP_REG_SI + (modrm.rm & 1); - insn->flags |= X86_INSN_DECODE_FLAG_HAS_BASE | X86_INSN_DECODE_FLAG_HAS_INDEX; - break; - - case 2: /* [bp + si/di] */ - case 3: - mem_op->mem.base = X86_INSN_GP_REG_BP; - mem_op->mem.index = X86_INSN_GP_REG_SI + (modrm.rm & 1); - insn->flags |= X86_INSN_DECODE_FLAG_HAS_BASE | X86_INSN_DECODE_FLAG_HAS_INDEX; - break; - - case 4: /* [si/di] */ - case 5: - mem_op->mem.base = X86_INSN_GP_REG_SI + (modrm.rm & 1); - insn->flags |= X86_INSN_DECODE_FLAG_HAS_BASE; - break; - - case 6: /* [bp + disp] */ - mem_op->mem.base = X86_INSN_GP_REG_BP; - insn->flags |= X86_INSN_DECODE_FLAG_HAS_BASE; - break; - - case 7: /* [bx + disp] */ - mem_op->mem.base = X86_INSN_GP_REG_BX; - insn->flags |= X86_INSN_DECODE_FLAG_HAS_BASE; - break; - } - - if (modrm.mode != 0) - disp_bits = modrm.mode == 1 ? 8 : 16; - break; - } - } - - if (disp_bits != 0) { - // update displacement offset - insn->displacement_offset = (uint8_t)reader_offset(rd); - - int64_t disp; - x86_insn_decode_number(rd, disp_bits, &disp); - mem_op->mem.disp = disp; - } -} - -/* Decodes the opcode of an instruction and returns its encoding - * specification. - */ -static void x86_insn_decode_opcode(x86_insn_reader_t *rd, x86_insn_decode_t *insn, x86_options_t *conf) { - uint8_t opcode = read_byte(rd); - - x86_insn_spec_t insn_spec; - if (opcode == 0x0f) { - opcode = read_byte(rd); - insn_spec = x86_opcode_map_two_byte[opcode]; - } else { - insn_spec = x86_opcode_map_one_byte[opcode]; - } - - // check sse group - if (X86_INSN_FLAG_GET_GROUP(insn_spec.flags) > X86_INSN_SSE_GROUP_START) { - UNIMPLEMENTED(); - } - - if (X86_INSN_FLAG_GET_GROUP(insn_spec.flags) > X86_INSN_GROUP_START && - X86_INSN_FLAG_GET_GROUP(insn_spec.flags) < X86_INSN_SSE_GROUP_START) { - // get group index - int group_ndx = X86_INSN_FLAG_GET_GROUP(insn_spec.flags); - - // get gp insn index in group - x86_insn_modrm_t modrm; - modrm.byte = peek_byte(rd); - int insn_ndx = modrm.reg; - - // get insn in group - x86_insn_spec_t *group_insn = NULL; - group_insn = &x86_insn_modrm_reg_groups[group_ndx].insns[insn_ndx]; - - // update the insn spec - insn_spec.name = group_insn->name; - insn_spec.flags = group_insn->flags; - } - - insn->primary_opcode = opcode; - insn->insn_spec = insn_spec; -} - -uint8_t x86_insn_imm_bits(x86_insn_spec_t *insn, uint8_t operand_bits) { - uint8_t imm_bits = 0; - switch (x86_insn_immediate_type(insn)) { - case 'b': - imm_bits = 8; - break; - case 'w': - imm_bits = 16; - break; - case 'd': - imm_bits = 32; - break; - case 'q': - imm_bits = 64; - break; - - case 'z': - imm_bits = operand_bits; - if (imm_bits == 64) - imm_bits = 32; - break; - - case 'v': - imm_bits = operand_bits; - break; - - default: - imm_bits = 0; - break; - } - - return imm_bits; -} - -void x86_insn_decode_immediate(x86_insn_reader_t *rd, x86_insn_decode_t *insn, x86_options_t *conf) { - uint8_t effective_operand_bits; - if (conf->mode == 64 || conf->mode == 32) { - effective_operand_bits = (insn->prefix & INSN_PREFIX_OPERAND_SIZE) ? 16 : 32; - } - effective_operand_bits = (insn->prefix & INSN_PREFIX_OPERAND_SIZE) ? 16 : 32; - - if (insn->flags & X86_INSN_DECODE_FLAG_OPERAND_SIZE_64) - effective_operand_bits = 64; - - if (conf->mode == 64 && insn->insn_spec.flags & X86_INSN_SPEC_DEFAULT_64_BIT) - effective_operand_bits = 64; - - int64_t immediate = 0; - uint8_t imm_bits = x86_insn_imm_bits(&insn->insn_spec, effective_operand_bits); - if (imm_bits == 0) - return; - - // update immediate offset - insn->immediate_offset = (uint8_t)reader_offset(rd); - - x86_insn_decode_number(rd, imm_bits, &immediate); - insn->immediate = immediate; -} - -void x86_insn_decode(x86_insn_decode_t *insn, uint8_t *buffer, x86_options_t *conf) { - // init reader - x86_insn_reader_t rd; - init_reader(&rd, buffer, buffer + 15); - - // decode prefix - insn->prefix = x86_insn_decode_prefix(&rd, insn, conf); - - // decode insn specp/x in - x86_insn_decode_opcode(&rd, insn, conf); - - if (x86_insn_has_modrm_byte(&insn->insn_spec)) { - // decode insn modrm sib (operand register, disp) - x86_insn_decode_modrm_sib(&rd, insn, conf); - } - - if (x86_insn_has_immediate(&insn->insn_spec)) { - // decode insn immeidate - x86_insn_decode_immediate(&rd, insn, conf); - } - -#if 1 - DEBUG_LOG("[x86 insn] %s", insn->insn_spec.name); -#endif - - // set insn length - insn->length = rd.buffer_cursor - rd.buffer; -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_insn_decode.h b/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_insn_decode.h deleted file mode 100644 index b08ee9b4..00000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_insn_decode.h +++ /dev/null @@ -1,200 +0,0 @@ -#ifndef X86_INSN_DECODE_H -#define X86_INSN_DECODE_H - -#include -#include "dobby/common.h" - -typedef enum { - X86_INSN_SPEC_DEFAULT_64_BIT = 1 << 0, -} x86_insn_spec_flag_t; - -typedef enum { - X86_INSN_DECODE_FLAG_HAS_BASE = 1 << 0, - - X86_INSN_DECODE_FLAG_HAS_INDEX = 1 << 1, - - X86_INSN_DECODE_FLAG_IS_ADDRESS = 1 << 2, - - X86_INSN_DECODE_FLAG_IP_RELATIVE = 1 << 3, - - X86_INSN_DECODE_FLAG_OPERAND_SIZE_64 = 1 << 4, -} x86_insn_decode_flag_t; - -typedef enum { - INSN_PREFIX_NONE = 0, - - /* Group 1: lock and repeat prefixes */ - INSN_PREFIX_GROUP1 = 0x07, - INSN_PREFIX_LOCK = 0x01, /* F0 */ - INSN_PREFIX_REPNZ = 0x02, /* F2 */ - INSN_PREFIX_REPNE = INSN_PREFIX_REPNZ, - INSN_PREFIX_REP = 0x04, /* F3 */ - INSN_PREFIX_REPZ = INSN_PREFIX_REP, - INSN_PREFIX_REPE = INSN_PREFIX_REPZ, - - /* Group 2: segment override or branch hints */ - INSN_PREFIX_GROUP2 = 0x01f8, - INSN_PREFIX_ES = 0x0008, /* 26 */ - INSN_PREFIX_CS = 0x0010, /* 2E */ - INSN_PREFIX_SS = 0x0020, /* 36 */ - INSN_PREFIX_DS = 0x0040, /* 3E */ - INSN_PREFIX_FS = 0x0080, /* 64 */ - INSN_PREFIX_GS = 0x0100, /* 65 */ - INSN_PREFIX_BRANCH_TAKEN = INSN_PREFIX_CS, /* 2E */ - INSN_PREFIX_BRANCH_NOT_TAKEN = INSN_PREFIX_DS, /* 3E */ - - /* Group 3: operand-size override */ - INSN_PREFIX_OPERAND_SIZE = 0x0200, /* 66 */ - - /* Group 4: address-size override */ - INSN_PREFIX_ADDRESS_SIZE = 0x0400 /* 67 */ -} x86_insn_prefix_t; - -typedef union { - struct { - uint8_t code; - uint8_t type; - }; - uint8_t data[2]; -} x86_insn_operand_spec_t; - -typedef struct { - // insn name - char *name; - - // insn max 3 operands - x86_insn_operand_spec_t operands[3]; - - // insn flag - uint16_t flags; -#define X86_INSN_FLAG_SET_SSE_GROUP(n) ((n) << 5) -#define X86_INSN_FLAG_GET_SSE_GROUP(f) (((f) >> 5) & 0x1f) -#define X86_INSN_FLAG_SET_MODRM_REG_GROUP(n) (((n)&0x3f) << 10) -#define X86_INSN_FLAG_GET_MODRM_REG_GROUP(f) (((f) >> 10) & 0x3f) -} x86_insn_spec_t; - -#define foreach_x86_gp_register _(AX) _(CX) _(DX) _(BX) _(SP) _(BP) _(SI) _(DI) - -typedef enum { -#define _(r) X86_INSN_GP_REG_##r, - foreach_x86_gp_register -#undef _ -} x86_insn_gp_register_t; - -typedef enum { - RNone = 0, - RAX, - RBX, - RCX, - RDX, - RDI, - RSI, - RBP, - RSP, - R8, - R9, - R10, - R11, - R12, - R13, - R14, - R15, - RIP -} x86_ia32e_register_t; - -typedef union { - struct { - uint8_t rm : 3; - uint8_t reg : 3; - uint8_t mode : 2; - }; - uint8_t byte; -} x86_insn_modrm_t; - -typedef union { - struct { - uint8_t base : 3; - uint8_t index : 3; - uint8_t log2_scale : 2; - }; - uint8_t byte; -} x86_insn_sib_t; - -typedef struct { - uint8_t reg; - - struct { - uint8_t base; - uint8_t index; - uint8_t scale; - uint32_t disp; - } mem; -} x86_insn_operand_t; - -typedef struct x86_insn_decode_t { - // insn flag - uint32_t flags; - - // insn length - uint32_t length; - - // insn displacement offset - uint8_t displacement_offset; - - // insn immediate offset - uint8_t immediate_offset; - - // Registers in instruction - // [0] is modrm reg field - // [1] is base reg - // [2] is index reg - // union { - // struct { - // uint8_t modrm_reg; - // uint8_t op_base_reg; - // uint8_t op_index_reg; - // }; - // uint8_t regs[3]; - // }; - - x86_insn_operand_t operands[3]; - - struct { // insn field combine - // insn prefix - x86_insn_prefix_t prefix; - - // insn rex - uint8_t rex; - - // insn primary opcode - uint8_t primary_opcode; - - // insn modrm - x86_insn_modrm_t modrm; - - // insn sib - x86_insn_sib_t sib; - - // insn operand imm - int64_t immediate; - }; - - // insn pre-spec - x86_insn_spec_t insn_spec; -} x86_insn_decode_t; - -typedef struct x86_options_t { - int mode; /* 16, 32 or 64 bit */ -} x86_options_t; - -#ifdef __cplusplus -extern "C" { -#endif - -void x86_insn_decode(x86_insn_decode_t *insn, uint8_t *buffer, x86_options_t *conf); - -#ifdef __cplusplus -} -#endif - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_insn_reader.c b/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_insn_reader.c deleted file mode 100644 index 214c060b..00000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_insn_reader.c +++ /dev/null @@ -1,87 +0,0 @@ -/* Specialized instruction reader. */ -typedef struct x86_insn_reader_t { - const unsigned char *prefix; /* pointer to beginning of instruction */ - const unsigned char *opcode; /* pointer to opcode */ - const unsigned char *modrm; /* pointer to modrm byte */ - - unsigned char buffer[20]; /* buffer used when few bytes left */ - const unsigned char *buffer_cursor; /* pointer to buffer_cursor of insn + 1 */ -} x86_insn_reader_t; - -/* Initializes a bytecode reader to read code from a given part of memory. */ -static void init_reader(x86_insn_reader_t *rd, const unsigned char *begin, const unsigned char *buffer_cursor) { - if (buffer_cursor - begin < sizeof(rd->buffer)) { - memset(rd->buffer, 0xcc, sizeof(rd->buffer)); /* debug token */ - memcpy(rd->buffer, begin, buffer_cursor - begin); - rd->prefix = rd->buffer; - } else { - rd->prefix = begin; - } - rd->opcode = rd->modrm = rd->buffer_cursor = rd->prefix; -} - -uint32_t reader_offset(x86_insn_reader_t *rd) { - return rd->buffer_cursor - rd->buffer; -} - -static uint8_t peek_byte(const x86_insn_reader_t *rd) { - return *rd->buffer_cursor; -} - -#define read_uint8 read_byte -static uint8_t read_byte(x86_insn_reader_t *rd) { - DEBUG_LOG("[x86 insn reader] %p - 1", rd->buffer_cursor); - - const unsigned char *p = rd->buffer_cursor; - rd->buffer_cursor++; - return *p; -} - -#define read_uint16 read_word -static uint16_t read_word(x86_insn_reader_t *rd) { - DEBUG_LOG("[x86 insn reader] %p - 2", rd->buffer_cursor); - - const unsigned char *p = rd->buffer_cursor; - rd->buffer_cursor += 2; - return (uint16_t)((uint16_t)p[0] | ((uint16_t)p[1] << 8)); -} - -#define read_uint32 read_dword -static uint32_t read_dword(x86_insn_reader_t *rd) { - DEBUG_LOG("[x86 insn reader] %p - 4", rd->buffer_cursor); - - const unsigned char *p = rd->buffer_cursor; - rd->buffer_cursor += 4; - return (uint32_t)p[0] | ((uint32_t)p[1] << 8) | ((uint32_t)p[2] << 16) | ((uint32_t)p[3] << 24); -} - -#define read_uint64 read_qword -static uint64_t read_qword(x86_insn_reader_t *rd) { - DEBUG_LOG("[x86 insn reader] %p - 8", rd->buffer_cursor); - - uint64_t *p = (uint64_t *)rd->buffer_cursor; - rd->buffer_cursor += 4; - return p[0]; -} - -static uint32_t read_imm(x86_insn_reader_t *rd, int size) { - DEBUG_LOG("[x86 insn reader] %p", rd->buffer_cursor); - - return (size == 8) ? read_byte(rd) : (size == 16) ? read_word(rd) : (size == 32) ? read_dword(rd) : 0; -} - -static unsigned char read_modrm(x86_insn_reader_t *rd) { - if (rd->buffer_cursor == rd->modrm) - rd->buffer_cursor++; - return *rd->modrm; -} - -/* Marks the next byte as ModR/M. */ -static void continue_modrm(x86_insn_reader_t *rd) { - rd->modrm = rd->buffer_cursor; -} - -/* Marks the next byte as opcode. */ -static void continue_opcode(x86_insn_reader_t *rd) { - rd->modrm = rd->opcode = rd->buffer_cursor; -} diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_modrm_reg_group.c b/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_modrm_reg_group.c deleted file mode 100644 index 352ea1a1..00000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_modrm_reg_group.c +++ /dev/null @@ -1,218 +0,0 @@ -/* Escape groups are indexed by modrm reg field. */ -static x86_insn_group8_t x86_insn_modrm_reg_groups[] = { - [X86_INSN_MODRM_REG_GROUP_1].insns = - { - op0(add), - op0(or), - op0(adc), - op0(sbb), - op0(and), - op0(sub), - op0(xor), - op0(cmp), - }, - - [X86_INSN_MODRM_REG_GROUP_1a].insns = - { - op0f(pop, X86_INSN_SPEC_DEFAULT_64_BIT), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_MODRM_REG_GROUP_2].insns = - { - op0(rol), - op0(ror), - op0(rcl), - op0(rcr), - op0(shl), - op0(shr), - op0(sal), - op0(sar), - }, - - [X86_INSN_MODRM_REG_GROUP_3].insns = - { - op0(test), - op0(test), - op0(not ), - op0(neg), - op0(mul), - op0(imul), - op0(div), - op0(idiv), - }, - - [X86_INSN_MODRM_REG_GROUP_4].insns = - { - op0(inc), - op0(dec), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_MODRM_REG_GROUP_5].insns = - { - op1(inc, Ev), - op1(dec, Ev), - op1f(call, X86_INSN_SPEC_DEFAULT_64_BIT, Ev), - op1(call, Mp), - op1f(jmp, X86_INSN_SPEC_DEFAULT_64_BIT, Ev), - op1(jmp, Mp), - op1f(push, X86_INSN_SPEC_DEFAULT_64_BIT, Ev), - op0(bad), - }, - - [X86_INSN_MODRM_REG_GROUP_6].insns = - { - op1(sldt, Ev), - op1(str, Ev), - op1(lldt, Ev), - op1(ltr, Ev), - op1(verr, Ev), - op1(verw, Ev), - op0(bad), - op0(bad), - }, - - [X86_INSN_MODRM_REG_GROUP_7].insns = - { - op1(sgdt, Mv), - op1(sidt, Mv), - op1(lgdt, Mv), - op1(lidt, Mv), - op1(smsw, Ev), - op0(bad), - op1(lmsw, Ew), - op1(invlpg, Mv), - }, - - [X86_INSN_MODRM_REG_GROUP_8].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op2(bt, Ev, Ib), - op2(bts, Ev, Ib), - op2(btr, Ev, Ib), - op2(btc, Ev, Ib), - }, - - [X86_INSN_MODRM_REG_GROUP_9].insns = - { - op0(bad), - op1(cmpxchg, Mx), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_MODRM_REG_GROUP_10].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_MODRM_REG_GROUP_11].insns = - { - op0(mov), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_MODRM_REG_GROUP_12].insns = - { - op0(bad), - op0(bad), - op2(psrlw, Rm, Ib), - op0(bad), - op2(psraw, Rm, Ib), - op0(bad), - op2(psllw, Rm, Ib), - op0(bad), - }, - - [X86_INSN_MODRM_REG_GROUP_13].insns = - { - op0(bad), - op0(bad), - op2(psrld, Rm, Ib), - op0(bad), - op2(psrad, Rm, Ib), - op0(bad), - op2(pslld, Rm, Ib), - op0(bad), - }, - - [X86_INSN_MODRM_REG_GROUP_14].insns = - { - op0(bad), - op0(bad), - op2(psrlq, Rm, Ib), - op0f(bad, 0), - op0(bad), - op0(bad), - op2(psllq, Rm, Ib), - op0f(bad, 0), - }, - - [X86_INSN_MODRM_REG_GROUP_15].insns = - { - op1(fxsave, Mv), - op1(fxrstor, Mv), - op1(ldmxcsr, Mv), - op1(stmxcsr, Mv), - op0(bad), - op1(lfence, Mv), - op1(mfence, Mv), - op1(sfence, Mv), - }, - - [X86_INSN_MODRM_REG_GROUP_16].insns = - { - op1(prefetch_nta, Mv), - op1(prefetch_t0, Mv), - op1(prefetch_t1, Mv), - op1(prefetch_t2, Mv), - op1(prefetch_nop, Mv), - op1(prefetch_nop, Mv), - op1(prefetch_nop, Mv), - op1(prefetch_nop, Mv), - }, - - [X86_INSN_MODRM_REG_GROUP_p].insns = - { - op1(prefetch_exclusive, Mv), - op1(prefetch_modified, Mv), - op1(prefetch_nop, Mv), - op1(prefetch_modified, Mv), - op1(prefetch_nop, Mv), - op1(prefetch_nop, Mv), - op1(prefetch_nop, Mv), - op1(prefetch_nop, Mv), - }, -}; diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_one_byte.c b/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_one_byte.c deleted file mode 100644 index 44b14627..00000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_one_byte.c +++ /dev/null @@ -1,215 +0,0 @@ -// clang-format off -static x86_insn_spec_t x86_opcode_map_one_byte[256] = { - /* 0x00 */ - foreach_x86_operand_combine(add, op_dst, op_src), - op0(push_es), - op0f(pop_es, X86_INSN_SPEC_DEFAULT_64_BIT), - foreach_x86_operand_combine(or, op_dst, op_src), - op0f(push_cs, X86_INSN_SPEC_DEFAULT_64_BIT), - op0(escape_two_byte), - - /* 0x10 */ - foreach_x86_operand_combine(adc, op_dst, op_src), - op0(push_ss), - op0(pop_ss), - foreach_x86_operand_combine(sbb, op_dst, op_src), - op0(push_ds), - op0(pop_ds), - - /* 0x20 */ - foreach_x86_operand_combine(and, op_dst, op_src), - op0(segment_es), - op0(daa), - foreach_x86_operand_combine(sub, op_dst, op_src), - op0(segment_cs), - op0(das), - - /* 0x30 */ - foreach_x86_operand_combine(xor, op_dst, op_src), - op0(segment_ss), - op0(aaa), - foreach_x86_operand_combine(cmp, op_src, op_src), - op0(segment_ds), - op0(aas), - -/* 0x40 */ -#define _(r) op1(inc, r), - foreach_x86_gp_reg -#undef _ -#define _(r) op1(dec, r), - foreach_x86_gp_reg -#undef _ - -/* 0x50 */ -#define _(r) op1f(push, X86_INSN_SPEC_DEFAULT_64_BIT, r), - foreach_x86_gp_reg -#undef _ -#define _(r) op1f(pop, X86_INSN_SPEC_DEFAULT_64_BIT, r), - foreach_x86_gp_reg -#undef _ - - /* 0x60 */ - op0(pusha), - op0(popa), - op2(bound, Gv, Ma), - op2(movsxd, Gv, Ed), - op0(segment_fs), - op0(segment_gs), - op0(operand_type), - op0(address_size), - op1f(push, X86_INSN_SPEC_DEFAULT_64_BIT, Iz), - op3(imul, Gv, Ev, Iz), - op1f(push, X86_INSN_SPEC_DEFAULT_64_BIT, Ib), - op3(imul, Gv, Ev, Ib), - op1(insb, DX), - op1(insw, DX), - op1(outsb, DX), - op1(outsw, DX), - -/* 0x70 */ -#define _(x) op1(j##x, Jb), - foreach_x86_condition -#undef _ - - /* 0x80 */ - op2f(modrm_group_1, X86_INSN_FLAG_MODRM_REG_GROUP_1, Eb, Ib), - op2f(modrm_group_1, X86_INSN_FLAG_MODRM_REG_GROUP_1, Ev, Iz), - op2f(modrm_group_1, X86_INSN_FLAG_MODRM_REG_GROUP_1, Eb, Ib), - op2f(modrm_group_1, X86_INSN_FLAG_MODRM_REG_GROUP_1, Ev, Ib), - op2(test, Eb, Gb), - op2(test, Ev, Gv), - op2(xchg, Eb, Gb), - op2(xchg, Ev, Gv), - op2(mov, Eb, Gb), - op2(mov, Ev, Gv), - op2(mov, Gb, Eb), - op2(mov, Gv, Ev), - op2(mov, Ev, Sw), - op2(lea, Gv, Ev), - op2(mov, Sw, Ew), - op1f(modrm_group_1a, X86_INSN_FLAG_MODRM_REG_GROUP_1a, Ev), - - /* 0x90 */ - op0(nop), - op1(xchg, CX), - op1(xchg, DX), - op1(xchg, BX), - op1(xchg, SP), - op1(xchg, BP), - op1(xchg, SI), - op1(xchg, DI), - op0(cbw), - op0(cwd), - op1(call, Ap), - op0(wait), - op0(pushf), - op0(popf), - op0(sahf), - op0(lahf), - - /* 0xa0 */ - op2(mov, AL, Ob), - op2(mov, AX, Ov), - op2(mov, Ob, AL), - op2(mov, Ov, AX), - op0(movsb), - op0(movsw), - op0(cmpsb), - op0(cmpsw), - op2(test, AL, Ib), - op2(test, AX, Iz), - op1(stosb, AL), - op1(stosw, AX), - op1(lodsb, AL), - op1(lodsw, AX), - op1(scasb, AL), - op1(scasw, AX), - - /* 0xb0 */ - op2(mov, AL, Ib), - op2(mov, CL, Ib), - op2(mov, DL, Ib), - op2(mov, BL, Ib), - op2(mov, AH, Ib), - op2(mov, CH, Ib), - op2(mov, DH, Ib), - op2(mov, BH, Ib), -#define _(r) op2(mov, r, Iv), - foreach_x86_gp_reg -#undef _ - - /* 0xc0 */ - op2f(modrm_group_2, X86_INSN_FLAG_MODRM_REG_GROUP_2, Eb, Ib), - op2f(modrm_group_2, X86_INSN_FLAG_MODRM_REG_GROUP_2, Ev, Ib), - op1(ret, Iw), - op0(ret), - op2(les, Gz, Mp), - op2(lds, Gz, Mp), - op2f(modrm_group_11, X86_INSN_FLAG_MODRM_REG_GROUP_11, Eb, Ib), - op2f(modrm_group_11, X86_INSN_FLAG_MODRM_REG_GROUP_11, Ev, Iz), - op2(enter, Iw, Ib), - op0(leave), - op1(ret, Iw), - op0(ret), - op0(int3), - op1(int, Ib), - op0(into), - op0(iret), - - /* 0xd0 */ - op2f(modrm_group_2, X86_INSN_FLAG_MODRM_REG_GROUP_2, Eb, 1b), - op2f(modrm_group_2, X86_INSN_FLAG_MODRM_REG_GROUP_2, Ev, 1b), - op2f(modrm_group_2, X86_INSN_FLAG_MODRM_REG_GROUP_2, Eb, CL), - op2f(modrm_group_2, X86_INSN_FLAG_MODRM_REG_GROUP_2, Ev, CL), - op0(aam), - op0(aad), - op0(salc), - op0(xlat), - /* FIXME x87 */ - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - - /* 0xe0 */ - op1(loopnz, Jb), - op1(loopz, Jb), - op1(loop, Jb), - op1(jcxz, Jb), - op2(in, AL, Ib), - op2(in, AX, Ib), - op2(out, Ib, AL), - op2(out, Ib, AX), - op1f(call, X86_INSN_SPEC_DEFAULT_64_BIT, Jz), - op1f(jmp, X86_INSN_SPEC_DEFAULT_64_BIT, Jz), - op1(jmp, Ap), - op1(jmp, Jb), - op2(in, AL, DX), - op2(in, AX, DX), - op2(out, DX, AL), - op2(out, DX, AX), - - /* 0xf0 */ - op0(lock), - op0(int1), - op0(repne), - op0(rep), - op0(hlt), - op0(cmc), - op0f(modrm_group_3, X86_INSN_FLAG_MODRM_REG_GROUP_3), - op0f(modrm_group_3, X86_INSN_FLAG_MODRM_REG_GROUP_3), - op0(clc), - op0(stc), - op0(cli), - op0(sti), - op0(cld), - op0(std), - op1f(modrm_group_4, X86_INSN_FLAG_MODRM_REG_GROUP_4, Eb), - op0f(modrm_group_5, X86_INSN_FLAG_MODRM_REG_GROUP_5), -}; - -// clang-format on \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_sse_group.c b/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_sse_group.c deleted file mode 100644 index 8e56a9b3..00000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_sse_group.c +++ /dev/null @@ -1,545 +0,0 @@ -static x86_insn_group8_t x86_insn_sse_groups_repz[] = { - [X86_INSN_SSE_GROUP_10].insns = - { - op2(movss, Gx, Ex), - op2(movss, Ex, Gx), - op2(movsldup, Gx, Ex), - op0(bad), - op0(bad), - op0(bad), - op2(movshdup, Gx, Ex), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_28].insns = - { - op0(bad), - op0(bad), - op2(cvtsi2ss, Gx, Ev), - op0(bad), - op2(cvttss2si, Gv, Ex), - op2(cvtss2si, Gv, Ex), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_50].insns = - { - op0(bad), - op2(sqrtss, Gx, Ex), - op2(rsqrtps, Gx, Ex), - op2(rcpss, Gx, Ex), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_58].insns = - { - op2(addss, Gx, Ex), - op2(mulss, Gx, Ex), - op2(cvtss2sd, Gx, Ex), - op2(cvttps2dq, Gx, Ex), - op2(subss, Gx, Ex), - op2(minss, Gx, Ex), - op2(divss, Gx, Ex), - op2(maxss, Gx, Ex), - }, - - [X86_INSN_SSE_GROUP_60].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_68].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op2(movdqu, Gx, Ex), - }, - - [X86_INSN_SSE_GROUP_70].insns = - { - op3(pshufhw, Gx, Ex, Ib), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_78].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op2(movq, Gx, Ex), - op2(movdqu, Ex, Gx), - }, - - [X86_INSN_SSE_GROUP_c0].insns = - { - op0(bad), - op0(bad), - op3(cmpss, Gx, Ex, Ib), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_d0].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op2(movq2dq, Gx, Em), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_d8].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_e0].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op2(cvtdq2pd, Gx, Ex), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_e8].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_f0].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_f8].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, -}; - -static x86_insn_group8_t x86_insn_sse_groups_operand_size[] = { - [X86_INSN_SSE_GROUP_10].insns = - { - op2(movupd, Gx, Ex), - op2(movupd, Ex, Gx), - op2(movlpd, Gx, Ex), - op2(movlpd, Ex, Gx), - op2(unpcklpd, Gx, Ex), - op2(unpckhpd, Gx, Ex), - op2(movhpd, Gx, Mx), - op2(movhpd, Mx, Gx), - }, - - [X86_INSN_SSE_GROUP_28].insns = - { - op2(movapd, Gx, Ex), - op2(movapd, Ex, Gx), - op2(cvtpi2pd, Gx, Ex), - op2(movntpd, Mx, Gx), - op2(cvttpd2pi, Gx, Mx), - op2(cvtpd2pi, Gx, Mx), - op2(ucomisd, Gx, Ex), - op2(comisd, Gx, Ex), - }, - - [X86_INSN_SSE_GROUP_50].insns = - { - op2(movmskpd, Gd, Rx), - op2(sqrtpd, Gx, Ex), - op0(bad), - op0(bad), - op2(andpd, Gx, Ex), - op2(andnpd, Gx, Ex), - op2(orpd, Gx, Ex), - op2(xorpd, Gx, Ex), - }, - - [X86_INSN_SSE_GROUP_58].insns = - { - op2(addpd, Gx, Ex), - op2(mulpd, Gx, Ex), - op2(cvtpd2ps, Gx, Ex), - op2(cvtps2dq, Gx, Ex), - op2(subpd, Gx, Ex), - op2(minpd, Gx, Ex), - op2(divpd, Gx, Ex), - op2(maxpd, Gx, Ex), - }, - - [X86_INSN_SSE_GROUP_60].insns = - { - op2(punpcklbw, Gx, Ex), - op2(punpcklwd, Gx, Ex), - op2(punpckldq, Gx, Ex), - op2(packsswb, Gx, Ex), - op2(pcmpgtb, Gx, Ex), - op2(pcmpgtw, Gx, Ex), - op2(pcmpgtd, Gx, Ex), - op2(packuswb, Gx, Ex), - }, - - [X86_INSN_SSE_GROUP_68].insns = - { - op2(punpckhbw, Gx, Ex), - op2(punpckhwd, Gx, Ex), - op2(punpckhdq, Gx, Ex), - op2(packssdw, Gx, Ex), - op2(punpcklqdq, Gx, Ex), - op2(punpckhqdq, Gx, Ex), - op2(movd, Gx, Ev), - op2(movdqa, Gx, Ex), - }, - - [X86_INSN_SSE_GROUP_70].insns = - { - op3(pshufd, Gx, Ex, Ib), - op0f(modrm_group_12, X86_INSN_FLAG_MODRM_REG_GROUP_12), - op0f(modrm_group_13, X86_INSN_FLAG_MODRM_REG_GROUP_13), - op0f(modrm_group_14, X86_INSN_FLAG_MODRM_REG_GROUP_14), - op2(pcmpeqb, Gx, Ex), - op2(pcmpeqw, Gx, Ex), - op2(pcmpeqd, Gx, Ex), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_78].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op2(haddpd, Gx, Ex), - op2(hsubpd, Gx, Ex), - op2(movd, Ev, Gx), - op2(movdqa, Ex, Gx), - }, - - [X86_INSN_SSE_GROUP_c0].insns = - { - op0(bad), - op0(bad), - op3(cmppd, Gx, Ex, Ib), - op0(bad), - op3(pinsrw, Gx, Ew, Ib), - op3(pextrw, Gd, Gx, Ib), - op3(shufpd, Gx, Ex, Ib), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_d0].insns = - { - op2(addsubpd, Gx, Ex), - op2(psrlw, Gx, Ex), - op2(psrld, Gx, Ex), - op2(psrlq, Gx, Ex), - op2(paddq, Gx, Ex), - op2(pmullw, Gx, Ex), - op2(movq, Ex, Gx), - op2(pmovmskb, Gd, Rx), - }, - - [X86_INSN_SSE_GROUP_d8].insns = - { - op2(psubusb, Gx, Ex), - op2(psubusw, Gx, Ex), - op2(pminub, Gx, Ex), - op2(pand, Gx, Ex), - op2(paddusb, Gx, Ex), - op2(paddusw, Gx, Ex), - op2(pmaxub, Gx, Ex), - op2(pandn, Gx, Ex), - }, - - [X86_INSN_SSE_GROUP_e0].insns = - { - op2(pavgb, Gx, Ex), - op2(psraw, Gx, Ex), - op2(psrad, Gx, Ex), - op2(pavgw, Gx, Ex), - op2(pmulhuw, Gx, Ex), - op2(pmulhw, Gx, Ex), - op2(cvttpd2dq, Gx, Ex), - op2(movntdq, Mx, Gx), - }, - - [X86_INSN_SSE_GROUP_e8].insns = - { - op2(psubsb, Gx, Ex), - op2(psubsw, Gx, Ex), - op2(pminsw, Gx, Ex), - op2(por, Gx, Ex), - op2(paddsb, Gx, Ex), - op2(paddsw, Gx, Ex), - op2(pmaxsw, Gx, Ex), - op2(pxor, Gx, Ex), - }, - - [X86_INSN_SSE_GROUP_f0].insns = - { - op0(bad), - op2(psllw, Gx, Ex), - op2(pslld, Gx, Ex), - op2(psllq, Gx, Ex), - op2(pmuludq, Gx, Ex), - op2(pmaddwd, Gx, Ex), - op2(psadbw, Gx, Ex), - op2(maskmovdqu, Gx, Ex), - }, - - [X86_INSN_SSE_GROUP_f8].insns = - { - op2(psubb, Gx, Ex), - op2(psubw, Gx, Ex), - op2(psubd, Gx, Ex), - op2(psubq, Gx, Ex), - op2(paddb, Gx, Ex), - op2(paddw, Gx, Ex), - op2(paddd, Gx, Ex), - op0(bad), - }, -}; - -static x86_insn_group8_t x86_insn_sse_groups_repnz[] = { - [X86_INSN_SSE_GROUP_10].insns = - { - op2(movsd, Gx, Ex), - op2(movsd, Ex, Gx), - op2(movddup, Gx, Ex), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_28].insns = - { - op0(bad), - op0(bad), - op2(cvtsi2sd, Gx, Ev), - op0(bad), - op2(cvttsd2si, Gv, Ex), - op2(cvtsd2si, Gv, Ex), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_50].insns = - { - op0(bad), - op2(sqrtsd, Gx, Ex), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_58].insns = - { - op2(addsd, Gx, Ex), - op2(mulsd, Gx, Ex), - op2(cvtsd2ss, Gx, Ex), - op0(bad), - op2(subsd, Gx, Ex), - op2(minsd, Gx, Ex), - op2(divsd, Gx, Ex), - op2(maxsd, Gx, Ex), - }, - - [X86_INSN_SSE_GROUP_60].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_68].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_70].insns = - { - op3(pshuflw, Gx, Ex, Ib), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_78].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op2(haddps, Gx, Ex), - op2(hsubps, Gx, Ex), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_c0].insns = - { - op0(bad), - op0(bad), - op3(cmpsd, Gx, Ex, Ib), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_d0].insns = - { - op2(addsubps, Gx, Ex), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op2(movdq2q, Gm, Ex), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_d8].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_e0].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op2(cvtpd2dq, Gx, Ex), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_e8].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_f0].insns = - { - op2(lddqu, Gx, Mx), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, - - [X86_INSN_SSE_GROUP_f8].insns = - { - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - }, -}; \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_two_byte.c b/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_two_byte.c deleted file mode 100644 index 900d0b3a..00000000 --- a/app/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_two_byte.c +++ /dev/null @@ -1,249 +0,0 @@ - -// clang-format off -static x86_insn_spec_t x86_opcode_map_two_byte[256] = { - /* 0x00 */ - op0f(modrm_group_6, X86_INSN_FLAG_MODRM_REG_GROUP_6), - op0f(modrm_group_7, X86_INSN_FLAG_MODRM_REG_GROUP_7), - op2(lar, Gv, Ew), - op2(lsl, Gv, Ew), - op0(bad), - op0(syscall), - op0(clts), - op0(sysret), - op0(invd), - op0(wbinvd), - op0(bad), - op0(ud2), - op0(bad), - op0f(modrm_group_p, X86_INSN_FLAG_MODRM_REG_GROUP_p), - op0(femms), - op0(escape_3dnow), - - /* 0x10 */ - op2f(movups, X86_INSN_FLAG_SSE_GROUP_10, Gx, Ex), - op2f(movups, X86_INSN_FLAG_SSE_GROUP_10, Ex, Gx), - op2f(movlps, X86_INSN_FLAG_SSE_GROUP_10, Ex, Gx), - op2f(movlps, X86_INSN_FLAG_SSE_GROUP_10, Gx, Ex), - op2f(unpcklps, X86_INSN_FLAG_SSE_GROUP_10, Gx, Ex), - op2f(unpckhps, X86_INSN_FLAG_SSE_GROUP_10, Gx, Ex), - op2f(movhps, X86_INSN_FLAG_SSE_GROUP_10, Ex, Gx), - op2f(movhps, X86_INSN_FLAG_SSE_GROUP_10, Gx, Ex), - op0f(modrm_group_16, X86_INSN_FLAG_MODRM_REG_GROUP_16), - op0(nop), - op0(nop), - op0(nop), - op0(nop), - op0(nop), - op0(nop), - op0(nop), - - /* 0x20 */ - op2(mov, Rv, Cv), - op2(mov, Rv, Dv), - op2(mov, Cv, Rv), - op2(mov, Dv, Rv), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op2f(movaps, X86_INSN_FLAG_SSE_GROUP_28, Gx, Ex), - op2f(movaps, X86_INSN_FLAG_SSE_GROUP_28, Ex, Gx), - op2f(cvtpi2ps, X86_INSN_FLAG_SSE_GROUP_28, Gx, Ex), - op2f(movntps, X86_INSN_FLAG_SSE_GROUP_28, Mx, Gx), - op2f(cvttps2pi, X86_INSN_FLAG_SSE_GROUP_28, Gx, Ex), - op2f(cvtps2pi, X86_INSN_FLAG_SSE_GROUP_28, Gx, Ex), - op2f(ucomiss, X86_INSN_FLAG_SSE_GROUP_28, Gx, Ex), - op2f(comiss, X86_INSN_FLAG_SSE_GROUP_28, Gx, Ex), - - /* 0x30 */ - op0(wrmsr), - op0(rdtsc), - op0(rdmsr), - op0(rdpmc), - op0(sysenter), - op0(sysexit), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - op0(bad), - -/* 0x40 */ -#define _(x) op2(cmov##x, Gv, Ev), - foreach_x86_condition -#undef _ - - /* 0x50 */ - op2f(movmskps, X86_INSN_FLAG_SSE_GROUP_50, Gd, Rx), - op2f(sqrtps, X86_INSN_FLAG_SSE_GROUP_50, Gx, Ex), - op2f(rsqrtps, X86_INSN_FLAG_SSE_GROUP_50, Gx, Ex), - op2f(rcpps, X86_INSN_FLAG_SSE_GROUP_50, Gx, Ex), - op2f(andps, X86_INSN_FLAG_SSE_GROUP_50, Gx, Ex), - op2f(andnps, X86_INSN_FLAG_SSE_GROUP_50, Gx, Ex), - op2f(orps, X86_INSN_FLAG_SSE_GROUP_50, Gx, Ex), - op2f(xorps, X86_INSN_FLAG_SSE_GROUP_50, Gx, Ex), - op2f(addps, X86_INSN_FLAG_SSE_GROUP_58, Gx, Ex), - op2f(mulps, X86_INSN_FLAG_SSE_GROUP_58, Gx, Ex), - op2f(cvtps2pd, X86_INSN_FLAG_SSE_GROUP_58, Gx, Ex), - op2f(cvtdq2ps, X86_INSN_FLAG_SSE_GROUP_58, Gx, Ex), - op2f(subps, X86_INSN_FLAG_SSE_GROUP_58, Gx, Ex), - op2f(minps, X86_INSN_FLAG_SSE_GROUP_58, Gx, Ex), - op2f(divps, X86_INSN_FLAG_SSE_GROUP_58, Gx, Ex), - op2f(maxps, X86_INSN_FLAG_SSE_GROUP_58, Gx, Ex), - - /* 0x60 */ - op2f(punpcklbw, X86_INSN_FLAG_SSE_GROUP_60, Gm, Em), - op2f(punpcklwd, X86_INSN_FLAG_SSE_GROUP_60, Gm, Em), - op2f(punpckldq, X86_INSN_FLAG_SSE_GROUP_60, Gm, Em), - op2f(packsswb, X86_INSN_FLAG_SSE_GROUP_60, Gm, Em), - op2f(pcmpgtb, X86_INSN_FLAG_SSE_GROUP_60, Gm, Em), - op2f(pcmpgtw, X86_INSN_FLAG_SSE_GROUP_60, Gm, Em), - op2f(pcmpgtd, X86_INSN_FLAG_SSE_GROUP_60, Gm, Em), - op2f(packuswb, X86_INSN_FLAG_SSE_GROUP_60, Gm, Em), - op2f(punpckhbw, X86_INSN_FLAG_SSE_GROUP_68, Gm, Em), - op2f(punpckhwd, X86_INSN_FLAG_SSE_GROUP_68, Gm, Em), - op2f(punpckhdq, X86_INSN_FLAG_SSE_GROUP_68, Gm, Em), - op2f(packssdw, X86_INSN_FLAG_SSE_GROUP_68, Gm, Em), - op0f(bad, X86_INSN_FLAG_SSE_GROUP_68), - op0f(bad, X86_INSN_FLAG_SSE_GROUP_68), - op2f(movd, X86_INSN_FLAG_SSE_GROUP_68, Gm, Em), - op2f(movq, X86_INSN_FLAG_SSE_GROUP_68, Gm, Em), - - /* 0x70 */ - op3f(pshufw, X86_INSN_FLAG_SSE_GROUP_70, Gm, Em, Ib), - op0f(modrm_group_12, X86_INSN_FLAG_MODRM_REG_GROUP_12), - op0f(modrm_group_13, X86_INSN_FLAG_MODRM_REG_GROUP_13), - op0f(modrm_group_14, X86_INSN_FLAG_MODRM_REG_GROUP_14), - op2f(pcmpeqb, X86_INSN_FLAG_SSE_GROUP_70, Gm, Em), - op2f(pcmpeqw, X86_INSN_FLAG_SSE_GROUP_70, Gm, Em), - op2f(pcmpeqd, X86_INSN_FLAG_SSE_GROUP_70, Gm, Em), - op0f(emms, X86_INSN_FLAG_SSE_GROUP_70), - op0f(bad, X86_INSN_FLAG_SSE_GROUP_78), - op0f(bad, X86_INSN_FLAG_SSE_GROUP_78), - op0f(bad, X86_INSN_FLAG_SSE_GROUP_78), - op0f(bad, X86_INSN_FLAG_SSE_GROUP_78), - op0f(bad, X86_INSN_FLAG_SSE_GROUP_78), - op0f(bad, X86_INSN_FLAG_SSE_GROUP_78), - op2f(movd, X86_INSN_FLAG_SSE_GROUP_78, Em, Gm), - op2f(movq, X86_INSN_FLAG_SSE_GROUP_78, Em, Gm), - -/* 0x80 */ -#define _(x) op1(jmp##x, Jz), - foreach_x86_condition -#undef _ - -/* 0x90 */ -#define _(x) op1(set##x, Eb), - foreach_x86_condition -#undef _ - - /* 0xa0 */ - op0(push_fs), - op0(pop_fs), - op0(cpuid), - op2(bt, Ev, Gv), - op3(shld, Ev, Gv, Ib), - op3(shld, Ev, Gv, CL), - op0(bad), - op0(bad), - op0(push_gs), - op0(pop_gs), - op0(rsm), - op2(bts, Ev, Gv), - op3(shrd, Ev, Gv, Ib), - op3(shrd, Ev, Gv, CL), - op0f(modrm_group_15, X86_INSN_FLAG_MODRM_REG_GROUP_15), - op2(imul, Gv, Ev), - - /* 0xb0 */ - op2(cmpxchg, Eb, Gb), - op2(cmpxchg, Ev, Gv), - op2(lss, Gz, Mp), - op2(btr, Ev, Gv), - op2(lfs, Gz, Mp), - op2(lgs, Gz, Mp), - op2(movzbl, Gv, Eb), - op2(movzwl, Gv, Ew), - op0(bad), - op0f(modrm_group_10, X86_INSN_FLAG_MODRM_REG_GROUP_10), - op2f(modrm_group_8, X86_INSN_FLAG_MODRM_REG_GROUP_8, Ev, Ib), - op2(btc, Ev, Gv), - op2(bsf, Gv, Ev), - op2(bsr, Gv, Ev), - op2(movsx, Gv, Eb), - op2(movsx, Gv, Ew), - - /* 0xc0 */ - op2(xadd, Eb, Gb), - op2(xadd, Ev, Gv), - op3f(cmpps, X86_INSN_FLAG_SSE_GROUP_c0, Gx, Ex, Ib), - op2(movnti, Mv, Gv), - op3f(pinsrw, X86_INSN_FLAG_SSE_GROUP_c0, Gm, Ew, Ib), - op3f(pextrw, X86_INSN_FLAG_SSE_GROUP_c0, Gd, Rm, Ib), - op3f(shufps, X86_INSN_FLAG_SSE_GROUP_c0, Gx, Ex, Ib), - op1f(modrm_group_9, X86_INSN_FLAG_MODRM_REG_GROUP_9, Mx), -#define _(r) op1(bswap, r), - foreach_x86_gp_reg -#undef _ - - /* 0xd0 */ - op0f(bad, X86_INSN_FLAG_SSE_GROUP_d0), - op2f(psrlw, X86_INSN_FLAG_SSE_GROUP_d0, Gm, Em), - op2f(psrld, X86_INSN_FLAG_SSE_GROUP_d0, Gm, Em), - op2f(psrlq, X86_INSN_FLAG_SSE_GROUP_d0, Gm, Em), - op2f(paddq, X86_INSN_FLAG_SSE_GROUP_d0, Gm, Em), - op2f(pmullw, X86_INSN_FLAG_SSE_GROUP_d0, Gm, Em), - op0f(bad, X86_INSN_FLAG_SSE_GROUP_d0), - op2f(pmovmskb, X86_INSN_FLAG_SSE_GROUP_d0, Gd, Rm), - op2f(psubusb, X86_INSN_FLAG_SSE_GROUP_d8, Gm, Em), - op2f(psubusw, X86_INSN_FLAG_SSE_GROUP_d8, Gm, Em), - op2f(pminub, X86_INSN_FLAG_SSE_GROUP_d8, Gm, Em), - op2f(pand, X86_INSN_FLAG_SSE_GROUP_d8, Gm, Em), - op2f(paddusb, X86_INSN_FLAG_SSE_GROUP_d8, Gm, Em), - op2f(paddusw, X86_INSN_FLAG_SSE_GROUP_d8, Gm, Em), - op2f(pmaxub, X86_INSN_FLAG_SSE_GROUP_d8, Gm, Em), - op2f(pandn, X86_INSN_FLAG_SSE_GROUP_d8, Gm, Em), - - /* 0xe0 */ - op2f(pavgb, X86_INSN_FLAG_SSE_GROUP_e0, Gm, Em), - op2f(psraw, X86_INSN_FLAG_SSE_GROUP_e0, Gm, Em), - op2f(psrad, X86_INSN_FLAG_SSE_GROUP_e0, Gm, Em), - op2f(pavgw, X86_INSN_FLAG_SSE_GROUP_e0, Gm, Em), - op2f(pmulhuw, X86_INSN_FLAG_SSE_GROUP_e0, Gm, Em), - op2f(pmulhw, X86_INSN_FLAG_SSE_GROUP_e0, Gm, Em), - op2f(bad, X86_INSN_FLAG_SSE_GROUP_e0, Gm, Em), - op2f(movntq, X86_INSN_FLAG_SSE_GROUP_e0, Mm, Gm), - op2f(psubsb, X86_INSN_FLAG_SSE_GROUP_e8, Gm, Em), - op2f(psubsw, X86_INSN_FLAG_SSE_GROUP_e8, Gm, Em), - op2f(pminsw, X86_INSN_FLAG_SSE_GROUP_e8, Gm, Em), - op2f(por, X86_INSN_FLAG_SSE_GROUP_e8, Gm, Em), - op2f(paddsb, X86_INSN_FLAG_SSE_GROUP_e8, Gm, Em), - op2f(paddsw, X86_INSN_FLAG_SSE_GROUP_e8, Gm, Em), - op2f(pmaxsw, X86_INSN_FLAG_SSE_GROUP_e8, Gm, Em), - op2f(pxor, X86_INSN_FLAG_SSE_GROUP_e8, Gm, Em), - - /* 0xf0 */ - op0f(bad, X86_INSN_FLAG_SSE_GROUP_f0), - op2f(psllw, X86_INSN_FLAG_SSE_GROUP_f0, Gm, Em), - op2f(pslld, X86_INSN_FLAG_SSE_GROUP_f0, Gm, Em), - op2f(psllq, X86_INSN_FLAG_SSE_GROUP_f0, Gm, Em), - op2f(pmuludq, X86_INSN_FLAG_SSE_GROUP_f0, Gm, Em), - op2f(pmaddwd, X86_INSN_FLAG_SSE_GROUP_f0, Gm, Em), - op2f(psadbw, X86_INSN_FLAG_SSE_GROUP_f0, Gm, Em), - op2f(maskmovq, X86_INSN_FLAG_SSE_GROUP_f0, Gm, Em), - op2f(psubb, X86_INSN_FLAG_SSE_GROUP_f8, Gm, Em), - op2f(psubw, X86_INSN_FLAG_SSE_GROUP_f8, Gm, Em), - op2f(psubd, X86_INSN_FLAG_SSE_GROUP_f8, Gm, Em), - op2f(psubq, X86_INSN_FLAG_SSE_GROUP_f8, Gm, Em), - op2f(paddb, X86_INSN_FLAG_SSE_GROUP_f8, Gm, Em), - op2f(paddw, X86_INSN_FLAG_SSE_GROUP_f8, Gm, Em), - op2f(paddd, X86_INSN_FLAG_SSE_GROUP_f8, Gm, Em), - op0f(bad, X86_INSN_FLAG_SSE_GROUP_f8), -}; - -// clang-format on \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InterceptEntry.cpp b/app/src/main/cpp/Dobby/source/InterceptEntry.cpp deleted file mode 100644 index 9a844053..00000000 --- a/app/src/main/cpp/Dobby/source/InterceptEntry.cpp +++ /dev/null @@ -1,16 +0,0 @@ -#include "InterceptEntry.h" -#include "Interceptor.h" - -InterceptEntry::InterceptEntry(InterceptEntryType type, addr_t address) { - this->type = type; - -#if defined(TARGET_ARCH_ARM) - if (address % 2) { - address -= 1; - this->thumb_mode = true; - } -#endif - - this->patched_addr = address; - this->id = Interceptor::SharedInstance()->count(); -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InterceptEntry.h b/app/src/main/cpp/Dobby/source/InterceptEntry.h deleted file mode 100644 index 29556356..00000000 --- a/app/src/main/cpp/Dobby/source/InterceptEntry.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include -#include "dobby/common.h" - -typedef enum { kFunctionInlineHook, kInstructionInstrument } InterceptEntryType; - -class InterceptRouting; - -typedef struct InterceptEntry { - uint32_t id; - InterceptEntryType type; - InterceptRouting *routing; - - union { - addr_t addr; - addr_t patched_addr; - }; - uint32_t patched_size; - - addr_t relocated_addr; - uint32_t relocated_size; - - uint8_t origin_insns[256]; - uint32_t origin_insn_size; - - bool thumb_mode; - - InterceptEntry(InterceptEntryType type, addr_t address); -} InterceptEntry; \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/InterceptRouting.cpp b/app/src/main/cpp/Dobby/source/InterceptRouting/InterceptRouting.cpp deleted file mode 100644 index 5299e624..00000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/InterceptRouting.cpp +++ /dev/null @@ -1,97 +0,0 @@ -#include "dobby/dobby_internal.h" - -#include "InterceptRouting/InterceptRouting.h" -#include "InterceptRouting/RoutingPlugin/RoutingPlugin.h" - -using namespace zz; - -void log_hex_format(uint8_t *buffer, uint32_t buffer_size) { - char output[1024] = {0}; - for (int i = 0; i < buffer_size && i < sizeof(output); i++) { - snprintf(output + strlen(output), 3, "%02x ", *((uint8_t *)buffer + i)); - } - DEBUG_LOG("%s", output); -}; - -void InterceptRouting::Prepare() { -} - -// generate relocated code -bool InterceptRouting::GenerateRelocatedCode() { - uint32_t tramp_size = GetTrampolineBuffer()->GetBufferSize(); - origin_ = new CodeMemBlock(entry_->patched_addr, tramp_size); - relocated_ = new CodeMemBlock(); - - auto buffer = (void *)entry_->patched_addr; -#if defined(TARGET_ARCH_ARM) - if (entry_->thumb_mode) { - buffer = (void *)((addr_t)buffer + 1); - } -#endif - GenRelocateCodeAndBranch(buffer, origin_, relocated_); - if (relocated_->size == 0) { - ERROR_LOG("[insn relocate]] failed"); - return false; - } - - // set the relocated instruction address - entry_->relocated_addr = relocated_->addr; - - // save original prologue - memcpy((void *)entry_->origin_insns, (void *)origin_->addr, origin_->size); - entry_->origin_insn_size = origin_->size; - - // log - DEBUG_LOG("[insn relocate] origin %p - %d", origin_->addr, origin_->size); - log_hex_format((uint8_t *)origin_->addr, origin_->size); - - DEBUG_LOG("[insn relocate] relocated %p - %d", relocated_->addr, relocated_->size); - log_hex_format((uint8_t *)relocated_->addr, relocated_->size); - - return true; -} - -bool InterceptRouting::GenerateTrampolineBuffer(addr_t src, addr_t dst) { - // if near branch trampoline plugin enabled - if (RoutingPluginManager::near_branch_trampoline) { - auto plugin = static_cast(RoutingPluginManager::near_branch_trampoline); - if (plugin->GenerateTrampolineBuffer(this, src, dst) == false) { - DEBUG_LOG("Failed enable near branch trampoline plugin"); - } - } - - if (GetTrampolineBuffer() == nullptr) { - auto tramp_buffer = GenerateNormalTrampolineBuffer(src, dst); - SetTrampolineBuffer(tramp_buffer); - } - return true; -} - -// active routing, patch origin instructions as trampoline -void InterceptRouting::Active() { - auto ret = DobbyCodePatch((void *)entry_->patched_addr, trampoline_buffer_->GetBuffer(), - trampoline_buffer_->GetBufferSize()); - if (ret == -1) { - ERROR_LOG("[intercept routing] active failed"); - return; - } - DEBUG_LOG("[intercept routing] active"); -} - -void InterceptRouting::Commit() { - this->Active(); -} - -#if 0 -int InterceptRouting::PredefinedTrampolineSize() { -#if __arm64__ - return 12; -#elif __arm__ - return 8; -#endif -} -#endif - -InterceptEntry *InterceptRouting::GetInterceptEntry() { - return entry_; -}; diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/InterceptRouting.h b/app/src/main/cpp/Dobby/source/InterceptRouting/InterceptRouting.h deleted file mode 100644 index e21ca322..00000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/InterceptRouting.h +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -#include "InterceptEntry.h" -#include "MemoryAllocator/AssemblyCodeBuilder.h" -#include "InstructionRelocation/InstructionRelocation.h" -#include "TrampolineBridge/Trampoline/Trampoline.h" - -class InterceptRouting { -public: - explicit InterceptRouting(InterceptEntry *entry) : entry_(entry) { - entry->routing = this; - - origin_ = nullptr; - relocated_ = nullptr; - - trampoline_ = nullptr; - trampoline_buffer_ = nullptr; - trampoline_target_ = 0; - } - - virtual void DispatchRouting() = 0; - - virtual void Prepare(); - - virtual void Active(); - - void Commit(); - - InterceptEntry *GetInterceptEntry(); - - void SetTrampolineBuffer(CodeBufferBase *buffer) { - trampoline_buffer_ = buffer; - } - - CodeBufferBase *GetTrampolineBuffer() { - return trampoline_buffer_; - } - - void SetTrampolineTarget(addr_t address) { - trampoline_target_ = address; - } - - addr_t GetTrampolineTarget() { - return trampoline_target_; - } - -protected: - bool GenerateRelocatedCode(); - - bool GenerateTrampolineBuffer(addr_t src, addr_t dst); - -protected: - InterceptEntry *entry_; - - CodeMemBlock *origin_; - CodeMemBlock *relocated_; - - CodeMemBlock *trampoline_; - // trampoline buffer before active - CodeBufferBase *trampoline_buffer_; - addr_t trampoline_target_; -}; diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionInlineHook/FunctionInlineHook.cc b/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionInlineHook/FunctionInlineHook.cc deleted file mode 100644 index 8694f01d..00000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionInlineHook/FunctionInlineHook.cc +++ /dev/null @@ -1,52 +0,0 @@ -#include "dobby/dobby_internal.h" - -#include "Interceptor.h" -#include "InterceptRouting/Routing/FunctionInlineHook/FunctionInlineHookRouting.h" - -PUBLIC int DobbyHook(void *address, dobby_dummy_func_t replace_func, dobby_dummy_func_t *origin_func) { - if (!address) { - ERROR_LOG("function address is 0x0"); - return -1; - } - -#if defined(__APPLE__) && defined(__arm64__) - address = pac_strip(address); - replace_func = pac_strip(replace_func); -#endif - -#if defined(ANDROID) - void *page_align_address = (void *)ALIGN_FLOOR(address, OSMemory::PageSize()); - if (!OSMemory::SetPermission(page_align_address, OSMemory::PageSize(), kReadExecute)) { - return -1; - } -#endif - - DEBUG_LOG("----- [DobbyHook:%p] -----", address); - - // check if already register - auto entry = Interceptor::SharedInstance()->find((addr_t)address); - if (entry) { - ERROR_LOG("%p already been hooked.", address); - return -1; - } - - entry = new InterceptEntry(kFunctionInlineHook, (addr_t)address); - - auto *routing = new FunctionInlineHookRouting(entry, replace_func); - routing->Prepare(); - routing->DispatchRouting(); - - // set origin func entry with as relocated instructions - if (origin_func) { - *origin_func = (dobby_dummy_func_t)entry->relocated_addr; -#if defined(__APPLE__) && defined(__arm64__) - *origin_func = pac_sign(*origin_func); -#endif - } - - routing->Commit(); - - Interceptor::SharedInstance()->add(entry); - - return 0; -} diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionInlineHook/FunctionInlineHookRouting.h b/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionInlineHook/FunctionInlineHookRouting.h deleted file mode 100644 index 65722c27..00000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionInlineHook/FunctionInlineHookRouting.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#include "dobby/dobby_internal.h" - -#include "InterceptRouting/InterceptRouting.h" - -#include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" - -class FunctionInlineHookRouting : public InterceptRouting { -public: - FunctionInlineHookRouting(InterceptEntry *entry, dobby_dummy_func_t replace_func) : InterceptRouting(entry) { - this->replace_func = replace_func; - } - - void DispatchRouting() override; - -private: - void BuildRouting(); - -private: - dobby_dummy_func_t replace_func; -}; diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionInlineHook/RoutingImpl.cc b/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionInlineHook/RoutingImpl.cc deleted file mode 100644 index 4408d554..00000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionInlineHook/RoutingImpl.cc +++ /dev/null @@ -1,22 +0,0 @@ -#include "dobby/dobby_internal.h" -#include "InterceptRouting/Routing/FunctionInlineHook/FunctionInlineHookRouting.h" - -void FunctionInlineHookRouting::BuildRouting() { - SetTrampolineTarget((addr_t)replace_func); - - // generate trampoline buffer, run before GenerateRelocatedCode - addr_t from = entry_->patched_addr; -#if defined(TARGET_ARCH_ARM) - if (entry_->thumb_mode) - from += 1; -#endif - addr_t to = GetTrampolineTarget(); - GenerateTrampolineBuffer(from, to); -} - -void FunctionInlineHookRouting::DispatchRouting() { - BuildRouting(); - - // generate relocated code which size == trampoline size - GenerateRelocatedCode(); -} diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/FunctionWrapperExport.cc b/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/FunctionWrapperExport.cc deleted file mode 100644 index 20232b05..00000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/FunctionWrapperExport.cc +++ /dev/null @@ -1,27 +0,0 @@ -#include "dobby/dobby_internal.h" - -#include "logging/logging.h" - -#include "Interceptor.h" -#include "InterceptRouting/InterceptRouting.h" - -#include "function-wrapper.h" - -PUBLIC int DobbyWrap(void *function_address, PreCallTy pre_call, PostCallTy post_call) { - DEBUG_LOG("Initialize 'DobbyWrap' hook at %p", function_address); - - Interceptor *interceptor = Interceptor::SharedInstance(); - - InterceptEntry *entry = new InterceptEntry(); - entry->id = interceptor->entries->getCount(); - entry->type = kFunctionWrapper; - entry->function_address = function_address; - - FunctionWrapperRouting *routing = new FunctionWrapperRouting(entry); - routing->DispatchRouting(); - interceptor->addHookEntry(entry); - routing->Commit(); - - DEBUG_LOG("Finalize %p", function_address); - return 0; -} diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/function-wrapper.cc b/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/function-wrapper.cc deleted file mode 100644 index 6a8a2941..00000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/function-wrapper.cc +++ /dev/null @@ -1,38 +0,0 @@ -#include "dobby/dobby_internal.h" - -#include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" - -#include "intercept_routing_handler.h" - -#include "function-wrapper.h" - -void FunctionWrapperRouting::DispatchRouting() { - Prepare(); - BuildPreCallRouting(); - BuildPostCallRouting(); -} - -// Add pre_call(prologue) handler before running the origin function, -void FunctionWrapperRouting::BuildPreCallRouting() { - // create closure trampoline jump to prologue_routing_dispath with the `entry_` data - ClosureTrampolineEntry *cte = ClosureTrampoline::CreateClosureTrampoline(entry_, (void *)prologue_routing_dispatch); - this->prologue_dispatch_bridge = cte->address; - - DEBUG_LOG("Create pre call closure trampoline to 'prologue_routing_dispatch' at %p", cte->address); -} - -// Add post_call(epilogue) handler before `Return` of the origin function, as implementation is replace the origin -// `Return Address` of the function. -void FunctionWrapperRouting::BuildPostCallRouting() { - // create closure trampoline jump to prologue_routing_dispath with the `entry_` data - ClosureTrampolineEntry *closure_trampoline_entry; - // format trampoline - closure_trampoline_entry = ClosureTrampoline::CreateClosureTrampoline(entry_, (void *)epilogue_routing_dispatch); - DEBUG_LOG("Create post call closure trampoline to 'prologue_routing_dispatch' at %p", - closure_trampoline_entry->address); - - this->SetTrampolineTarget(closure_trampoline_entry->address); - this->epilogue_dispatch_bridge = closure_trampoline_entry->address; - - GenerateTrampolineBuffer(entry_->target_address, GetTrampolineTarget()); -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/function-wrapper.h b/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/function-wrapper.h deleted file mode 100644 index 362b7506..00000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/function-wrapper.h +++ /dev/null @@ -1,40 +0,0 @@ -#ifndef FUNCTION_WRAPPER_H -#define FUNCTION_WRAPPER_H - -#include "dobby/dobby_internal.h" - -#include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" -#include "InterceptRouting/InterceptRouting.h" -#include "Interceptor.h" - -#if TARGET_ARCH_IA32 -#elif TARGET_ARCH_X64 -#include "InterceptRouting/x64/X64InterceptRouting.h" -#elif TARGET_ARCH_ARM64 -#include "InterceptRouting/arm64/ARM64InterceptRouting.h" -#elif TARGET_ARCH_ARM -#else -#error "unsupported architecture" -#endif - -class FunctionWrapperRouting : public InterceptRouting { -public: - FunctionWrapperRouting(InterceptEntry *entry) : InterceptRouting(entry) { - } - - void DispatchRouting(); - - void *GetTrampolineTarget(); - -private: - void BuildPreCallRouting(); - - void BuildPostCallRouting(); - -private: - void *prologue_dispatch_bridge; - - void *epilogue_dispatch_bridge; -}; - -#endif diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/intercept_routing_handler.cc b/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/intercept_routing_handler.cc deleted file mode 100644 index 55de2fbd..00000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/intercept_routing_handler.cc +++ /dev/null @@ -1,79 +0,0 @@ - -#include "dobby/dobby_internal.h" - -#include "logging/logging.h" - -#include "intercept_routing_handler.h" - -#include "function-wrapper.h" -#include "intercept_routing_handler.h" - -#include "MultiThreadSupport/ThreadSupport.h" - -#include "TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.h" - -void pre_call_forward_handler(DobbyRegisterContext *ctx, InterceptEntry *entry) { - FunctionWrapperRouting *routing = (FunctionWrapperRouting *)entry->routing; - - StackFrame *stackframe = new StackFrame(); - // create stack frame as common variable between pre_call and post_call - ThreadSupport::PushStackFrame(stackframe); - - // run the `pre_call` before execute origin function which has been relocated(fixed) - if (routing->pre_call) { - PreCallTy pre_call; - InterceptEntry entry; - entry.hook_id = entry->id; - entry.target_address = entry->target_address; - pre_call = routing->pre_call; - // run the pre_call with the power of accessing all registers - (*pre_call)(ctx, (const InterceptEntry *)&entry); - } - - // save the origin ret address, and use in `post_call_forword_handler` - stackframe->orig_ret = get_func_ret_address(ctx); - - // set the prologue bridge next hop address with the patched instructions has been relocated - set_routing_bridge_next_hop(ctx, entry->relocated_origin_function); - - // replace the function ret address with our epilogue_routing_dispatch - set_func_ret_address(ctx, entry->epilogue_dispatch_bridge); -} - -void post_call_forward_handler(DobbyRegisterContext *ctx, InterceptEntry *entry) { - FunctionWrapperRouting *routing = (FunctionWrapperRouting *)entry->routing; - - // pop stack frame as common variable between pre_call and post_call - StackFrame *stackframe = ThreadSupport::PopStackFrame(); - - // run the `post_call`, and access all the register value, as the origin function done, - if (routing->post_call) { - PostCallTy post_call; - InterceptEntry entry; - entry.hook_id = entry->id; - entry.target_address = entry->target_address; - post_call = routing->post_call; - - // run the post_call with the power of accessing all registers - (*post_call)(ctx, (const InterceptEntry *)&entry); - } - - // set epilogue bridge next hop address with origin ret address, restore the call. - set_routing_bridge_next_hop(ctx, stackframe->orig_ret); -} - -// run the user handler **before run the origin-instructions(which have been relocated)** -void prologue_routing_dispatch(DobbyRegisterContext *ctx, ClosureTrampolineEntry *closure_trampoline_entry) { - DEBUG_LOG("Catch prologue dispatch"); - InterceptEntry *entry = static_cast(closure_trampoline_entry->carry_data); - pre_call_forward_handler(ctx, entry); - return; -} - -// run the user handler **before the function return** by replace the lr register -void epilogue_routing_dispatch(DobbyRegisterContext *ctx, ClosureTrampolineEntry *closure_trampoline_entry) { - DEBUG_LOG("Catch epilogue dispatch"); - InterceptEntry *entry = static_cast(closure_trampoline_entry->carry_data); - post_call_forward_handler(ctx, entry); - return; -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/intercept_routing_handler.h b/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/intercept_routing_handler.h deleted file mode 100644 index 6aaea3f3..00000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/intercept_routing_handler.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef FUNCTION_WRAPPER_INTERCEPT_ROUTING_HANDLER_H -#define FUNCTION_WRAPPER_INTERCEPT_ROUTING_HANDLER_H - -#include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" -#include "Interceptor.h" -#include "dobby/dobby_internal.h" - -#ifdef __cplusplus -extern "C" { -#endif //__cplusplus - -// Dispatch the routing befor running the origin function -void prologue_routing_dispatch(DobbyRegisterContext *ctx, ClosureTrampolineEntry *entry); - -// Dispatch the routing before the function return . (as it's implementation by relpace `return address` in the stack -// ,or LR register) -void epilogue_routing_dispatch(DobbyRegisterContext *ctx, ClosureTrampolineEntry *entry); - -void pre_call_forward_handler(DobbyRegisterContext *ctx, InterceptEntry *entry); - -void post_call_forward_handler(DobbyRegisterContext *ctx, InterceptEntry *entry); - -#ifdef __cplusplus -} -#endif //__cplusplus - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/InstructionInstrument.cc b/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/InstructionInstrument.cc deleted file mode 100644 index 9c28ca35..00000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/InstructionInstrument.cc +++ /dev/null @@ -1,42 +0,0 @@ -#include "dobby/dobby_internal.h" - -#include "Interceptor.h" -#include "InterceptRouting/InterceptRouting.h" -#include "InterceptRouting/Routing/InstructionInstrument/InstructionInstrumentRouting.h" - -PUBLIC int DobbyInstrument(void *address, dobby_instrument_callback_t pre_handler) { - if (!address) { - ERROR_LOG("address is 0x0.\n"); - return -1; - } - -#if defined(__APPLE__) && defined(__arm64__) - address = pac_strip(address); -#endif - -#if defined(ANDROID) - void *page_align_address = (void *)ALIGN_FLOOR(address, OSMemory::PageSize()); - if (!OSMemory::SetPermission(page_align_address, OSMemory::PageSize(), kReadExecute)) { - return -1; - } -#endif - - DEBUG_LOG("\n\n----- [DobbyInstrument:%p] -----", address); - - auto entry = Interceptor::SharedInstance()->find((addr_t)address); - if (entry) { - ERROR_LOG("%s already been instrumented.", address); - return -1; - } - - entry = new InterceptEntry(kInstructionInstrument, (addr_t)address); - - auto routing = new InstructionInstrumentRouting(entry, pre_handler, nullptr); - routing->Prepare(); - routing->DispatchRouting(); - routing->Commit(); - - Interceptor::SharedInstance()->add(entry); - - return 0; -} diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/InstructionInstrumentRouting.h b/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/InstructionInstrumentRouting.h deleted file mode 100644 index 60a9a2e4..00000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/InstructionInstrumentRouting.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include "dobby/dobby_internal.h" - -#include "InterceptRouting/InterceptRouting.h" - -#include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" - -class InstructionInstrumentRouting : public InterceptRouting { -public: - InstructionInstrumentRouting(InterceptEntry *entry, dobby_instrument_callback_t pre_handler, - dobby_instrument_callback_t post_handler) - : InterceptRouting(entry) { - this->prologue_dispatch_bridge = nullptr; - this->pre_handler = pre_handler; - this->post_handler = post_handler; - } - - void DispatchRouting() override; - -private: - void BuildRouting(); - -public: - dobby_instrument_callback_t pre_handler; - dobby_instrument_callback_t post_handler; - -private: - void *prologue_dispatch_bridge; -}; diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/RoutingImpl.cc b/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/RoutingImpl.cc deleted file mode 100644 index bd12545d..00000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/RoutingImpl.cc +++ /dev/null @@ -1,40 +0,0 @@ - -#include "dobby/dobby_internal.h" - -#include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" - -#include "InterceptRouting/Routing/InstructionInstrument/InstructionInstrumentRouting.h" -#include "InterceptRouting/Routing/InstructionInstrument/instrument_routing_handler.h" - -// create closure trampoline jump to prologue_routing_dispatch with the `entry_` data -void InstructionInstrumentRouting::BuildRouting() { - void *handler = (void *)instrument_routing_dispatch; -#if defined(__APPLE__) && defined(__arm64__) - handler = pac_strip(handler); -#endif - auto closure_trampoline = ClosureTrampoline::CreateClosureTrampoline(entry_, handler); - this->SetTrampolineTarget((addr_t)closure_trampoline->address); - DEBUG_LOG("[closure trampoline] closure trampoline: %p, data: %p", closure_trampoline->address, entry_); - - // generate trampoline buffer, before `GenerateRelocatedCode` - addr_t from = entry_->patched_addr; -#if defined(TARGET_ARCH_ARM) - if (entry_->thumb_mode) - from += 1; -#endif - addr_t to = GetTrampolineTarget(); - GenerateTrampolineBuffer(from, to); -} - -void InstructionInstrumentRouting::DispatchRouting() { - BuildRouting(); - - // generate relocated code which size == trampoline size - GenerateRelocatedCode(); -} - -#if 0 -void *InstructionInstrumentRouting::GetTrampolineTarget() { - return this->prologue_dispatch_bridge; -} -#endif diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/instrument_routing_handler.cc b/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/instrument_routing_handler.cc deleted file mode 100644 index 3e381224..00000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/instrument_routing_handler.cc +++ /dev/null @@ -1,21 +0,0 @@ -#include "dobby/dobby_internal.h" - -#include "InterceptRouting/Routing/InstructionInstrument/InstructionInstrumentRouting.h" -#include "InterceptRouting/Routing/InstructionInstrument/instrument_routing_handler.h" - -#include "TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.h" - -void instrument_forward_handler(InterceptEntry *entry, DobbyRegisterContext *ctx) { - auto routing = static_cast(entry->routing); - if (routing->pre_handler) { - auto handler = (dobby_instrument_callback_t)routing->pre_handler; - (*handler)((void *)entry->patched_addr, ctx); - } - - // set prologue bridge next hop address as relocated instructions - set_routing_bridge_next_hop(ctx, (void *)entry->relocated_addr); -} - -void instrument_routing_dispatch(InterceptEntry *entry, DobbyRegisterContext *ctx) { - instrument_forward_handler(entry, ctx); -} diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/instrument_routing_handler.h b/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/instrument_routing_handler.h deleted file mode 100644 index 640bfec7..00000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/Routing/InstructionInstrument/instrument_routing_handler.h +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "dobby/dobby_internal.h" - -extern "C" { -void instrument_routing_dispatch(InterceptEntry *entry, DobbyRegisterContext *ctx); -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/NearBranchTrampoline/NearBranchTrampoline.cc b/app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/NearBranchTrampoline/NearBranchTrampoline.cc deleted file mode 100644 index fab0a124..00000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/NearBranchTrampoline/NearBranchTrampoline.cc +++ /dev/null @@ -1,50 +0,0 @@ -#include "InterceptRouting/RoutingPlugin/NearBranchTrampoline/NearBranchTrampoline.h" - -#include "dobby/dobby_internal.h" - -#include "MemoryAllocator/NearMemoryAllocator.h" - -#include "InterceptRouting/RoutingPlugin/RoutingPlugin.h" - -using namespace zz; - -PUBLIC void dobby_enable_near_branch_trampoline() { - RoutingPluginInterface *plugin = new NearBranchTrampolinePlugin; - RoutingPluginManager::registerPlugin("near_branch_trampoline", plugin); - RoutingPluginManager::near_branch_trampoline = plugin; -} - -PUBLIC void dobby_disable_near_branch_trampoline() { - NearBranchTrampolinePlugin *plugin = (NearBranchTrampolinePlugin *)RoutingPluginManager::near_branch_trampoline; - delete plugin; - RoutingPluginManager::near_branch_trampoline = NULL; -} - -#if 0 -int NearBranchTrampolinePlugin::PredefinedTrampolineSize() { -#if __arm64__ - return 4; -#elif __arm__ - return 4; -#endif -} -#endif - -extern CodeBufferBase *GenerateNearTrampolineBuffer(InterceptRouting *routing, addr_t from, addr_t to); -bool NearBranchTrampolinePlugin::GenerateTrampolineBuffer(InterceptRouting *routing, addr_t src, addr_t dst) { - CodeBufferBase *trampoline_buffer; - trampoline_buffer = GenerateNearTrampolineBuffer(routing, src, dst); - if (trampoline_buffer == NULL) - return false; - routing->SetTrampolineBuffer(trampoline_buffer); - return true; -} - -// generate trampoline, patch the original entry -bool NearBranchTrampolinePlugin::Active(InterceptRouting *routing) { - addr_t src, dst; - InterceptEntry *entry = routing->GetInterceptEntry(); - src = (addr_t)entry->patched_addr; - dst = (addr_t)routing->GetTrampolineTarget(); - return true; -} diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/NearBranchTrampoline/NearBranchTrampoline.h b/app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/NearBranchTrampoline/NearBranchTrampoline.h deleted file mode 100644 index 58bee514..00000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/NearBranchTrampoline/NearBranchTrampoline.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#include "dobby/dobby_internal.h" - -#include "InterceptRouting/RoutingPlugin/RoutingPlugin.h" - -class NearBranchTrampolinePlugin : public RoutingPluginInterface { - bool Prepare(InterceptRouting *routing) { - return false; - }; - - bool Active(InterceptRouting *routing); - - bool GenerateTrampolineBuffer(InterceptRouting *routing, addr_t src, addr_t dst); -}; diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/NearBranchTrampoline/near_trampoline_arm64.cc b/app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/NearBranchTrampoline/near_trampoline_arm64.cc deleted file mode 100644 index 4b16c92b..00000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/NearBranchTrampoline/near_trampoline_arm64.cc +++ /dev/null @@ -1,81 +0,0 @@ -#include "platform_detect_macro.h" -#if defined(TARGET_ARCH_ARM64) - -#include "dobby/dobby_internal.h" - -#include "core/assembler/assembler-arm64.h" -#include "core/codegen/codegen-arm64.h" - -#include "MemoryAllocator/NearMemoryAllocator.h" -#include "InstructionRelocation/arm64/InstructionRelocationARM64.h" -#include "InterceptRouting/RoutingPlugin/RoutingPlugin.h" - -using namespace zz::arm64; - -#define ARM64_B_XXX_RANGE ((1 << 25) << 2) // signed - -// If BranchType is B_Branch and the branch_range of `B` is not enough -// build the transfer to forward the b branch -static AssemblyCode *GenerateFastForwardTrampoline(addr_t src, addr_t dst) { - TurboAssembler turbo_assembler_(nullptr); -#define _ turbo_assembler_. - - // [adrp + add + br branch] - auto tramp_size = 3 * 4; - auto tramp_mem = NearMemoryAllocator::SharedAllocator()->allocateNearExecMemory(tramp_size, src, ARM64_B_XXX_RANGE); - if (tramp_mem == nullptr) { - ERROR_LOG("search near code block failed"); - return nullptr; - } - - // Use adrp + add branch - uint64_t distance = llabs((int64_t)(tramp_mem - dst)); - uint64_t adrp_range = ((uint64_t)1 << (2 + 19 + 12 - 1)); - if (distance < adrp_range) { - // use adrp + add + br branch == (3 * 4) trampoline size - _ AdrpAdd(TMP_REG_0, (uint64_t)tramp_mem, dst); - _ br(TMP_REG_0); - DEBUG_LOG("forward trampoline use [adrp, add, br]"); - } else { - // use mov + br == (4 * 5) trampoline size - _ Mov(TMP_REG_0, dst); - _ br(TMP_REG_0); - DEBUG_LOG("forward trampoline use [mov, br]"); - - auto tramp_size = turbo_assembler_.GetCodeBuffer()->GetBufferSize(); - tramp_mem = NearMemoryAllocator::SharedAllocator()->allocateNearExecMemory(tramp_size, src, ARM64_B_XXX_RANGE); - if (tramp_mem == nullptr) { - ERROR_LOG("Can't found near code chunk"); - return nullptr; - } - } - - turbo_assembler_.SetRealizedAddress((void *)tramp_mem); - - AssemblyCode *code = nullptr; - code = AssemblyCodeBuilder::FinalizeFromTurboAssembler(&turbo_assembler_); - return code; -} - -CodeBufferBase *GenerateNearTrampolineBuffer(InterceptRouting *routing, addr_t src, addr_t dst) { - CodeBufferBase *result = nullptr; - - TurboAssembler turbo_assembler_((void *)src); -#define _ turbo_assembler_. - - // branch to trampoline_target directly - if (llabs((long long)dst - (long long)src) < ARM64_B_XXX_RANGE) { - _ b(dst - src); - } else { - auto fast_forward_trampoline = GenerateFastForwardTrampoline(src, dst); - if (!fast_forward_trampoline) - return nullptr; - _ b(fast_forward_trampoline->addr - src); - } - - // free the original trampoline - result = turbo_assembler_.GetCodeBuffer()->Copy(); - return result; -} - -#endif diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/RoutingPlugin.cc b/app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/RoutingPlugin.cc deleted file mode 100644 index e6e8ffd8..00000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/RoutingPlugin.cc +++ /dev/null @@ -1,11 +0,0 @@ -#include "InterceptRouting/RoutingPlugin/RoutingPlugin.h" - -tinystl::vector RoutingPluginManager::plugins; - -RoutingPluginInterface *RoutingPluginManager::near_branch_trampoline = NULL; - -void RoutingPluginManager::registerPlugin(const char *name, RoutingPluginInterface *plugin) { - DEBUG_LOG("register %s plugin", name); - - RoutingPluginManager::plugins.push_back(plugin); -} diff --git a/app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/RoutingPlugin.h b/app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/RoutingPlugin.h deleted file mode 100644 index 17ac97e4..00000000 --- a/app/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/RoutingPlugin.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include "dobby/dobby_internal.h" - -#include "InterceptRouting/InterceptRouting.h" - -class RoutingPluginInterface { -public: - // @Return: if false will continue to iter next plugin - virtual bool Prepare(InterceptRouting *routing) = 0; - - // @Return: if false will continue to iter next plugin - virtual bool Active(InterceptRouting *routing) = 0; - - // @Return: if false will continue to iter next plugin - virtual bool GenerateTrampolineBuffer(InterceptRouting *routing, addr_t src, addr_t dst) = 0; - -private: - char name_[256]; -}; - -class RoutingPluginManager { -public: - static void registerPlugin(const char *name, RoutingPluginInterface *plugin); - -public: - static tinystl::vector plugins; - - static RoutingPluginInterface *near_branch_trampoline; -}; diff --git a/app/src/main/cpp/Dobby/source/Interceptor.cpp b/app/src/main/cpp/Dobby/source/Interceptor.cpp deleted file mode 100644 index 7cfe1137..00000000 --- a/app/src/main/cpp/Dobby/source/Interceptor.cpp +++ /dev/null @@ -1,40 +0,0 @@ -#include "Interceptor.h" - -Interceptor *Interceptor::instance = nullptr; - -Interceptor *Interceptor::SharedInstance() { - if (Interceptor::instance == nullptr) { - Interceptor::instance = new Interceptor(); - } - return Interceptor::instance; -} - -InterceptEntry *Interceptor::find(addr_t addr) { - for (auto *entry : entries) { - if (entry->patched_addr == addr) { - return entry; - } - } - return nullptr; -} - -void Interceptor::add(InterceptEntry *entry) { - entries.push_back(entry); -} - -void Interceptor::remove(addr_t addr) { - for (auto iter = entries.begin(); iter != entries.end(); iter++) { - if ((*iter)->patched_addr == addr) { - entries.erase(iter); - break; - } - } -} - -const InterceptEntry *Interceptor::getEntry(int i) { - return entries[i]; -} - -int Interceptor::count() { - return entries.size(); -} diff --git a/app/src/main/cpp/Dobby/source/Interceptor.h b/app/src/main/cpp/Dobby/source/Interceptor.h deleted file mode 100644 index 467a2297..00000000 --- a/app/src/main/cpp/Dobby/source/Interceptor.h +++ /dev/null @@ -1,25 +0,0 @@ -#pragma once - -#include "dobby/dobby_internal.h" -#include "InterceptEntry.h" - -class Interceptor { -public: - static Interceptor *SharedInstance(); - -public: - InterceptEntry *find(addr_t addr); - - void remove(addr_t addr); - - void add(InterceptEntry *entry); - - const InterceptEntry *getEntry(int i); - - int count(); - -private: - static Interceptor *instance; - - tinystl::vector entries; -}; \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/MemoryAllocator/AssemblyCodeBuilder.cc b/app/src/main/cpp/Dobby/source/MemoryAllocator/AssemblyCodeBuilder.cc deleted file mode 100644 index f0bffead..00000000 --- a/app/src/main/cpp/Dobby/source/MemoryAllocator/AssemblyCodeBuilder.cc +++ /dev/null @@ -1,34 +0,0 @@ -#include "MemoryAllocator/AssemblyCodeBuilder.h" - -#include "dobby/dobby_internal.h" -#include "PlatformUnifiedInterface/ExecMemory/CodePatchTool.h" - -AssemblyCode *AssemblyCodeBuilder::FinalizeFromTurboAssembler(AssemblerBase *assembler) { - auto buffer = (CodeBufferBase *)assembler->GetCodeBuffer(); - auto realized_addr = (addr_t)assembler->GetRealizedAddress(); -#if defined(TEST_WITH_UNICORN) - // impl: unicorn emulator map memory - realized_addr = 0; -#endif - if (!realized_addr) { - size_t buffer_size = 0; - buffer_size = buffer->GetBufferSize(); -#if TARGET_ARCH_ARM - // extra bytes for align needed - buffer_size += 4; -#endif - - auto block = MemoryAllocator::SharedAllocator()->allocateExecBlock(buffer_size); - if (block == nullptr) - return nullptr; - - realized_addr = block->addr; - assembler->SetRealizedAddress((void *)realized_addr); - } - - // Realize the buffer code to the executable memory address, remove the external label, etc - DobbyCodePatch((void *)realized_addr, buffer->GetBuffer(), buffer->GetBufferSize()); - - auto block = new AssemblyCode(realized_addr, buffer->GetBufferSize()); - return block; -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/MemoryAllocator/AssemblyCodeBuilder.h b/app/src/main/cpp/Dobby/source/MemoryAllocator/AssemblyCodeBuilder.h deleted file mode 100644 index d704c56e..00000000 --- a/app/src/main/cpp/Dobby/source/MemoryAllocator/AssemblyCodeBuilder.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "PlatformUnifiedInterface/MemoryAllocator.h" - -#include "core/assembler/assembler.h" - -using namespace zz; - -using AssemblyCode = CodeMemBlock; - -class AssemblyCodeBuilder { -public: - static AssemblyCode *FinalizeFromTurboAssembler(AssemblerBase *assembler); -}; diff --git a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/CodeBufferBase.cc b/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/CodeBufferBase.cc deleted file mode 100644 index eab96224..00000000 --- a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/CodeBufferBase.cc +++ /dev/null @@ -1,53 +0,0 @@ -#include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" - -CodeBufferBase *CodeBufferBase::Copy() { - CodeBufferBase *result = new CodeBufferBase(); - result->EmitBuffer(GetBuffer(), GetBufferSize()); - return result; -} - -void CodeBufferBase::Emit8(uint8_t data) { - Emit(data); -} - -void CodeBufferBase::Emit16(uint16_t data) { - Emit(data); -} - -void CodeBufferBase::Emit32(uint32_t data) { - Emit(data); -} - -void CodeBufferBase::Emit64(uint64_t data) { - Emit(data); -} - -void CodeBufferBase::EmitBuffer(uint8_t *buffer, int buffer_size) { - buffer_.insert(buffer_.end(), buffer, buffer + buffer_size); -} - -uint8_t *CodeBufferBase::GetBuffer() { - return buffer_.data(); -} - -size_t CodeBufferBase::GetBufferSize() { - return buffer_.size(); -} - -#if 0 // Template Advanced won't enable even in userspace -template T CodeBufferBase::Load(int offset) { - return *reinterpret_cast(buffer + offset); -} - -template void CodeBufferBase::Store(int offset, T value) { - *reinterpret_cast(buffer + offset) = value; -} - -template void CodeBufferBase::Emit(T value) { - // Ensure the free space enough for the template T value - ensureCapacity(sizeof(T) + GetBufferSize()); - - *reinterpret_cast(buffer_cursor) = value; - buffer_cursor += sizeof(T); -} -#endif diff --git a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/CodeBufferBase.h b/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/CodeBufferBase.h deleted file mode 100644 index 61b58892..00000000 --- a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/CodeBufferBase.h +++ /dev/null @@ -1,40 +0,0 @@ -#pragma once - -#include "dobby/common.h" - -class CodeBufferBase { -public: - CodeBufferBase() { - } - -public: - virtual CodeBufferBase *Copy(); - - void Emit8(uint8_t data); - - void Emit16(uint16_t data); - - void Emit32(uint32_t data); - - void Emit64(uint64_t data); - - template T Load(int offset) { - return *(T *)(buffer_.data() + offset); - } - - template void Store(int offset, T value) { - *(T *)(buffer_.data() + offset) = value; - } - - template void Emit(T value) { - EmitBuffer((uint8_t *)&value, sizeof(value)); - } - - void EmitBuffer(uint8_t *buffer, int len); - - uint8_t *GetBuffer(); - size_t GetBufferSize(); - -private: - tinystl::vector buffer_; -}; diff --git a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-arm.h b/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-arm.h deleted file mode 100644 index 0255947e..00000000 --- a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-arm.h +++ /dev/null @@ -1,59 +0,0 @@ -#ifndef CODE_BUFFER_ARM_H -#define CODE_BUFFER_ARM_H - -#include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" - -typedef int32_t arm_inst_t; -typedef int16_t thumb1_inst_t; -typedef int32_t thumb2_inst_t; - -class CodeBuffer : public CodeBufferBase { - enum ExecuteState { ARMExecuteState, ThumbExecuteState }; - -public: - CodeBuffer() : CodeBufferBase() { - } - -public: - arm_inst_t LoadARMInst(uint32_t offset) { - return *reinterpret_cast(GetBuffer() + offset); - } - - thumb1_inst_t LoadThumb1Inst(uint32_t offset) { - return *reinterpret_cast(GetBuffer() + offset); - } - - thumb2_inst_t LoadThumb2Inst(uint32_t offset) { - return *reinterpret_cast(GetBuffer() + offset); - } - - void RewriteAddr(uint32_t offset, addr32_t addr) { - memcpy(GetBuffer() + offset, &addr, sizeof(addr)); - } - - void RewriteARMInst(uint32_t offset, arm_inst_t instr) { - *reinterpret_cast(GetBuffer() + offset) = instr; - } - - void RewriteThumb1Inst(uint32_t offset, thumb1_inst_t instr) { - *reinterpret_cast(GetBuffer() + offset) = instr; - } - - void RewriteThumb2Inst(uint32_t offset, thumb2_inst_t instr) { - memcpy(GetBuffer() + offset, &instr, sizeof(instr)); - } - - void EmitARMInst(arm_inst_t instr) { - Emit(instr); - } - - void EmitThumb1Inst(thumb1_inst_t instr) { - Emit(instr); - } - - void EmitThumb2Inst(thumb2_inst_t instr) { - Emit(instr); - } -}; - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-arm64.h b/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-arm64.h deleted file mode 100644 index 266e10b3..00000000 --- a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-arm64.h +++ /dev/null @@ -1,24 +0,0 @@ -#ifndef CODE_BUFFER_ARM64_H -#define CODE_BUFFER_ARM64_H - -#include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" - -typedef int32_t arm64_inst_t; - -class CodeBuffer : public CodeBufferBase { - -public: - CodeBuffer() : CodeBufferBase() { - } - -public: - arm64_inst_t LoadInst(uint32_t offset) { - return *reinterpret_cast(GetBuffer() + offset); - } - - void RewriteInst(uint32_t offset, arm64_inst_t instr) { - *reinterpret_cast(GetBuffer() + offset) = instr; - } -}; - -#endif diff --git a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-x64.h b/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-x64.h deleted file mode 100644 index 913ee8a2..00000000 --- a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-x64.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef CODE_BUFFER_X64_H -#define CODE_BUFFER_X64_H - -#include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" - -class CodeBuffer : public CodeBufferBase { -public: - CodeBuffer() : CodeBufferBase() { - } - -public: - void FixBindLabel(int offset, int32_t disp) { - Store(offset, disp); - } -}; - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-x86.cc b/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-x86.cc deleted file mode 100644 index e7e07347..00000000 --- a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-x86.cc +++ /dev/null @@ -1,18 +0,0 @@ -#include "platform_detect_macro.h" -#if defined(TARGET_ARCH_IA32) - -#include "MemoryAllocator/CodeBuffer/code-buffer-x86.h" - -void CodeBuffer::Emit32(int32_t data) { - ensureCapacity(GetBufferSize() + sizeof(int32_t)); - *reinterpret_cast(getCursor()) = data; - buffer_cursor += sizeof(int32_t); - return; -} - -void CodeBuffer::FixBindLabel(int offset, int32_t disp) { - *reinterpret_cast(buffer + offset) = disp; - return; -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-x86.h b/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-x86.h deleted file mode 100644 index 43b2f359..00000000 --- a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-x86.h +++ /dev/null @@ -1,12 +0,0 @@ -#pragma once - -#include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" - -class CodeBuffer : public CodeBufferBase { -public: - CodeBuffer() : CodeBufferBase() { - } - -public: - void FixBindLabel(int offset, int32_t disp); -}; \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code_buffer_arm.h b/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code_buffer_arm.h deleted file mode 100644 index 0fe8346a..00000000 --- a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code_buffer_arm.h +++ /dev/null @@ -1,56 +0,0 @@ -#pragma once - -#include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" - -typedef int32_t arm_inst_t; -typedef int16_t thumb1_inst_t; -typedef int32_t thumb2_inst_t; - -class CodeBuffer : public CodeBufferBase { - enum ExecuteState { ARMExecuteState, ThumbExecuteState }; - -public: - CodeBuffer() : CodeBufferBase() { - } - -public: - arm_inst_t LoadARMInst(uint32_t offset) { - return *reinterpret_cast(GetBuffer() + offset); - } - - thumb1_inst_t LoadThumb1Inst(uint32_t offset) { - return *reinterpret_cast(GetBuffer() + offset); - } - - thumb2_inst_t LoadThumb2Inst(uint32_t offset) { - return *reinterpret_cast(GetBuffer() + offset); - } - - void RewriteAddr(uint32_t offset, addr32_t addr) { - memcpy(GetBuffer() + offset, &addr, sizeof(addr)); - } - - void RewriteARMInst(uint32_t offset, arm_inst_t instr) { - *reinterpret_cast(GetBuffer() + offset) = instr; - } - - void RewriteThumb1Inst(uint32_t offset, thumb1_inst_t instr) { - *reinterpret_cast(GetBuffer() + offset) = instr; - } - - void RewriteThumb2Inst(uint32_t offset, thumb2_inst_t instr) { - memcpy(GetBuffer() + offset, &instr, sizeof(instr)); - } - - void EmitARMInst(arm_inst_t instr) { - Emit(instr); - } - - void EmitThumb1Inst(thumb1_inst_t instr) { - Emit(instr); - } - - void EmitThumb2Inst(thumb2_inst_t instr) { - Emit(instr); - } -}; \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code_buffer_arm64.h b/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code_buffer_arm64.h deleted file mode 100644 index 4c8d8037..00000000 --- a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code_buffer_arm64.h +++ /dev/null @@ -1,21 +0,0 @@ -#pragma once - -#include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" - -typedef int32_t arm64_inst_t; - -class CodeBuffer : public CodeBufferBase { - -public: - CodeBuffer() : CodeBufferBase() { - } - -public: - arm64_inst_t LoadInst(uint32_t offset) { - return *reinterpret_cast(GetBuffer() + offset); - } - - void RewriteInst(uint32_t offset, arm64_inst_t instr) { - *reinterpret_cast(GetBuffer() + offset) = instr; - } -}; \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code_buffer_x64.h b/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code_buffer_x64.h deleted file mode 100644 index d80dfb80..00000000 --- a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code_buffer_x64.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" - -class CodeBuffer : public CodeBufferBase { -public: - CodeBuffer() : CodeBufferBase() { - } - -public: - void FixBindLabel(int offset, int32_t disp) { - Store(offset, disp); - } -}; \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code_buffer_x86.h b/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code_buffer_x86.h deleted file mode 100644 index d80dfb80..00000000 --- a/app/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code_buffer_x86.h +++ /dev/null @@ -1,14 +0,0 @@ -#pragma once - -#include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" - -class CodeBuffer : public CodeBufferBase { -public: - CodeBuffer() : CodeBufferBase() { - } - -public: - void FixBindLabel(int offset, int32_t disp) { - Store(offset, disp); - } -}; \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/MemoryAllocator/MemoryAllocator.cc b/app/src/main/cpp/Dobby/source/MemoryAllocator/MemoryAllocator.cc deleted file mode 100644 index 13ff04af..00000000 --- a/app/src/main/cpp/Dobby/source/MemoryAllocator/MemoryAllocator.cc +++ /dev/null @@ -1,106 +0,0 @@ -#include "dobby/dobby_internal.h" - -#include "PlatformUnifiedInterface/MemoryAllocator.h" - -MemBlock *MemoryArena::allocMemBlock(size_t size) { - // insufficient memory - if (this->end - this->cursor_addr < size) { - return nullptr; - } - - auto result = new MemBlock(cursor_addr, size); - cursor_addr += size; - return result; -} - -MemoryAllocator *MemoryAllocator::shared_allocator = nullptr; -MemoryAllocator *MemoryAllocator::SharedAllocator() { - if (MemoryAllocator::shared_allocator == nullptr) { - MemoryAllocator::shared_allocator = new MemoryAllocator(); - } - return MemoryAllocator::shared_allocator; -} - -CodeMemoryArena *MemoryAllocator::allocateCodeMemoryArena(uint32_t size) { - CHECK_EQ(size % OSMemory::PageSize(), 0); - uint32_t arena_size = size; - auto arena_addr = OSMemory::Allocate(arena_size, kNoAccess); - OSMemory::SetPermission(arena_addr, arena_size, kReadExecute); - - auto result = new CodeMemoryArena((addr_t)arena_addr, (size_t)arena_size); - code_arenas.push_back(result); - return result; -} - -CodeMemBlock *MemoryAllocator::allocateExecBlock(uint32_t size) { - CodeMemBlock *block = nullptr; - for (auto iter = code_arenas.begin(); iter != code_arenas.end(); iter++) { - auto arena = static_cast(*iter); - block = arena->allocMemBlock(size); - if (block) - break; - } - if (!block) { - // allocate new arena - auto arena_size = ALIGN_CEIL(size, OSMemory::PageSize()); - auto arena = allocateCodeMemoryArena(arena_size); - block = arena->allocMemBlock(size); - CHECK_NOT_NULL(block); - } - - DEBUG_LOG("[memory allocator] allocate exec memory at: %p, size: %p", block->addr, block->size); - return block; -} - -uint8_t *MemoryAllocator::allocateExecMemory(uint32_t size) { - auto block = allocateExecBlock(size); - return (uint8_t *)block->addr; -} -uint8_t *MemoryAllocator::allocateExecMemory(uint8_t *buffer, uint32_t buffer_size) { - auto mem = allocateExecMemory(buffer_size); - auto ret = DobbyCodePatch(mem, buffer, buffer_size); - CHECK_EQ(ret, 0); - return mem; -} - -DataMemoryArena *MemoryAllocator::allocateDataMemoryArena(uint32_t size) { - DataMemoryArena *result = nullptr; - - uint32_t buffer_size = ALIGN_CEIL(size, OSMemory::PageSize()); - void *buffer = OSMemory::Allocate(buffer_size, kNoAccess); - OSMemory::SetPermission(buffer, buffer_size, kReadWrite); - - result = new DataMemoryArena((addr_t)buffer, (size_t)buffer_size); - data_arenas.push_back(result); - return result; -} - -DataMemBlock *MemoryAllocator::allocateDataBlock(uint32_t size) { - CodeMemBlock *block = nullptr; - for (auto iter = data_arenas.begin(); iter != data_arenas.end(); iter++) { - auto arena = static_cast(*iter); - block = arena->allocMemBlock(size); - if (block) - break; - } - if (!block) { - // allocate new arena - auto arena = allocateCodeMemoryArena(size); - block = arena->allocMemBlock(size); - CHECK_NOT_NULL(block); - } - - DEBUG_LOG("[memory allocator] allocate data memory at: %p, size: %p", block->addr, block->size); - return block; -} - -uint8_t *MemoryAllocator::allocateDataMemory(uint32_t size) { - auto block = allocateDataBlock(size); - return (uint8_t *)block->addr; -} - -uint8_t *MemoryAllocator::allocateDataMemory(uint8_t *buffer, uint32_t buffer_size) { - auto mem = allocateDataMemory(buffer_size); - memcpy(mem, buffer, buffer_size); - return mem; -} diff --git a/app/src/main/cpp/Dobby/source/MemoryAllocator/NearMemoryAllocator.cc b/app/src/main/cpp/Dobby/source/MemoryAllocator/NearMemoryAllocator.cc deleted file mode 100644 index 27b5cf7b..00000000 --- a/app/src/main/cpp/Dobby/source/MemoryAllocator/NearMemoryAllocator.cc +++ /dev/null @@ -1,235 +0,0 @@ -#include "NearMemoryAllocator.h" - -#include "dobby/dobby_internal.h" - -#include "PlatformUtil/ProcessRuntimeUtility.h" - -using namespace zz; - -#define KB (1024uLL) -#define MB (1024uLL * KB) -#define GB (1024uLL * MB) - -#if defined(WIN32) -static const void *memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen) { - if (!haystack || !needle) { - return haystack; - } else { - const char *h = (const char *)haystack; - const char *n = (const char *)needle; - size_t l = needlelen; - const char *r = h; - while (l && (l <= haystacklen)) { - if (*n++ != *h++) { - r = h; - n = (const char *)needle; - l = needlelen; - } else { - --l; - } - --haystacklen; - } - return l ? nullptr : r; - } -} -#endif - -#define min(a, b) (((a) < (b)) ? (a) : (b)) -#define max(a, b) (((a) > (b)) ? (a) : (b)) - -NearMemoryAllocator *NearMemoryAllocator::shared_allocator = nullptr; -NearMemoryAllocator *NearMemoryAllocator::SharedAllocator() { - if (NearMemoryAllocator::shared_allocator == nullptr) { - NearMemoryAllocator::shared_allocator = new NearMemoryAllocator(); - } - return NearMemoryAllocator::shared_allocator; -} - -MemBlock *NearMemoryAllocator::allocateNearBlockFromDefaultAllocator(uint32_t size, addr_t pos, size_t search_range, - bool executable) { - addr_t min_valid_addr, max_valid_addr; - min_valid_addr = pos - search_range; - max_valid_addr = pos + search_range; - - auto allocateFromDefaultArena = [&](MemoryArena *arena, uint32_t size) -> addr_t { - addr_t unused_mem_start = arena->cursor_addr; - addr_t unused_mem_end = arena->addr + arena->size; - - // check if unused region total out of search range - if (unused_mem_end < min_valid_addr || unused_mem_start > max_valid_addr) - return 0; - - unused_mem_start = max(unused_mem_start, min_valid_addr); - unused_mem_end = min(unused_mem_end, max_valid_addr); - - // check if invalid - if (unused_mem_start >= unused_mem_end) - return 0; - - // check if has sufficient memory - if (unused_mem_end - unused_mem_start < size) - return 0; - - DEBUG_LOG("[near memory allocator] unused memory from default allocator %p(%p), within pos: %p, serach_range: %p", - unused_mem_start, size, pos, search_range); - return unused_mem_start; - }; - - MemoryArena *arena = nullptr; - addr_t unused_mem = 0; - if (executable) { - for (auto iter = default_allocator->code_arenas.begin(); iter != default_allocator->code_arenas.end(); iter++) { - arena = *iter; - unused_mem = allocateFromDefaultArena(arena, size); - if (!unused_mem) - continue; - - break; - } - } else { - for (auto iter = default_allocator->data_arenas.begin(); iter != default_allocator->data_arenas.end(); iter++) { - arena = *iter; - unused_mem = allocateFromDefaultArena(arena, size); - if (unused_mem) - continue; - } - } - - if (!unused_mem) - return nullptr; - - // skip placeholder block - // FIXME: allocate the placeholder but mark it as freed - auto placeholder_block_size = unused_mem - arena->cursor_addr; - arena->allocMemBlock(placeholder_block_size); - - auto block = arena->allocMemBlock(size); - return block; -} - -MemBlock *NearMemoryAllocator::allocateNearBlockFromUnusedRegion(uint32_t size, addr_t pos, size_t search_range, - bool executable) { - - addr_t min_valid_addr, max_valid_addr; - min_valid_addr = pos - search_range; - max_valid_addr = pos + search_range; - - auto check_has_sufficient_memory_between_region = [&](MemRegion region, MemRegion next_region, - uint32_t size) -> addr_t { - addr_t unused_mem_start = region.start + region.size; - addr_t unused_mem_end = next_region.start; - - // check if unused region total out of search range - if (unused_mem_end < min_valid_addr || unused_mem_start > max_valid_addr) - return 0; - - // align - unused_mem_start = ALIGN_FLOOR(unused_mem_start, 4); - - unused_mem_start = max(unused_mem_start, min_valid_addr); - unused_mem_end = min(unused_mem_end, max_valid_addr); - - // check if invalid - if (unused_mem_start >= unused_mem_end) - return 0; - - // check if has sufficient memory - if (unused_mem_end - unused_mem_start < size) - return 0; - - DEBUG_LOG("[near memory allocator] unused memory from unused region %p(%p), within pos: %p, serach_range: %p", - unused_mem_start, size, pos, search_range); - return unused_mem_start; - }; - - addr_t unused_mem = 0; - auto regions = ProcessRuntimeUtility::GetProcessMemoryLayout(); - for (size_t i = 0; i + 1 < regions.size(); i++) { - unused_mem = check_has_sufficient_memory_between_region(regions[i], regions[i + 1], size); - if (unused_mem == 0) - continue; - break; - } - - if (!unused_mem) - return nullptr; - - auto unused_arena_first_page_addr = (addr_t)ALIGN_FLOOR(unused_mem, OSMemory::PageSize()); - auto unused_arena_end_page_addr = ALIGN_FLOOR(unused_mem + size, OSMemory::PageSize()); - auto unused_arena_size = unused_arena_end_page_addr - unused_arena_first_page_addr + OSMemory::PageSize(); - auto unused_arena_addr = unused_arena_first_page_addr; - - if (OSMemory::Allocate(unused_arena_size, kNoAccess, (void *)unused_arena_addr) == nullptr) { - ERROR_LOG("[near memory allocator] allocate fixed page failed %p", unused_arena_addr); - return nullptr; - } - - auto register_near_arena = [&](addr_t arena_addr, size_t arena_size) -> MemoryArena * { - MemoryArena *arena = nullptr; - if (executable) { - arena = new CodeMemoryArena(arena_addr, arena_size); - default_allocator->code_arenas.push_back(arena); - } else { - arena = new DataMemoryArena(arena_addr, arena_size); - default_allocator->data_arenas.push_back(arena); - } - OSMemory::SetPermission((void *)arena->addr, arena->size, executable ? kReadExecute : kReadWrite); - return arena; - }; - - auto unused_arena = register_near_arena(unused_arena_addr, unused_arena_size); - - // skip placeholder block - // FIXME: allocate the placeholder but mark it as freed - auto placeholder_block_size = unused_mem - unused_arena->cursor_addr; - unused_arena->allocMemBlock(placeholder_block_size); - - auto block = unused_arena->allocMemBlock(size); - return block; -} - -MemBlock *NearMemoryAllocator::allocateNearBlock(uint32_t size, addr_t pos, size_t search_range, bool executable) { - MemBlock *result = nullptr; - result = allocateNearBlockFromDefaultAllocator(size, pos, search_range, executable); - if (!result) { - result = allocateNearBlockFromUnusedRegion(size, pos, search_range, executable); - } - - if (!result) { - ERROR_LOG("[near memory allocator] allocate near block failed (%p, %p, %p)", size, pos, search_range); - } - return result; -} - -uint8_t *NearMemoryAllocator::allocateNearExecMemory(uint32_t size, addr_t pos, size_t search_range) { - auto block = allocateNearBlock(size, pos, search_range, true); - if (!block) - return nullptr; - - DEBUG_LOG("[near memory allocator] allocate exec memory at: %p, size: %p", block->addr, block->size); - return (uint8_t *)block->addr; -} - -uint8_t *NearMemoryAllocator::allocateNearExecMemory(uint8_t *buffer, uint32_t buffer_size, addr_t pos, - size_t search_range) { - auto mem = allocateNearExecMemory(buffer_size, pos, search_range); - auto ret = DobbyCodePatch(mem, buffer, buffer_size); - CHECK_EQ(ret, 0); - return mem; -} - -uint8_t *NearMemoryAllocator::allocateNearDataMemory(uint32_t size, addr_t pos, size_t search_range) { - auto block = allocateNearBlock(size, pos, search_range, false); - if (!block) - return nullptr; - - DEBUG_LOG("[near memory allocator] allocate data memory at: %p, size: %p", block->addr, block->size); - return (uint8_t *)block->addr; -} - -uint8_t *NearMemoryAllocator::allocateNearDataMemory(uint8_t *buffer, uint32_t buffer_size, addr_t pos, - size_t search_range) { - auto mem = allocateNearExecMemory(buffer_size, pos, search_range); - memcpy(mem, buffer, buffer_size); - return mem; -} diff --git a/app/src/main/cpp/Dobby/source/MemoryAllocator/NearMemoryAllocator.h b/app/src/main/cpp/Dobby/source/MemoryAllocator/NearMemoryAllocator.h deleted file mode 100644 index 701cba8d..00000000 --- a/app/src/main/cpp/Dobby/source/MemoryAllocator/NearMemoryAllocator.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -#include "PlatformUnifiedInterface/MemoryAllocator.h" - -#include "dobby/common.h" - -class NearMemoryAllocator { -public: - MemoryAllocator *default_allocator; - NearMemoryAllocator() { - default_allocator = MemoryAllocator::SharedAllocator(); - } - -private: - static NearMemoryAllocator *shared_allocator; - -public: - static NearMemoryAllocator *SharedAllocator(); - -public: - MemBlock *allocateNearBlock(uint32_t size, addr_t pos, size_t search_range, bool executable); - MemBlock *allocateNearBlockFromDefaultAllocator(uint32_t size, addr_t pos, size_t search_range, bool executable); - MemBlock *allocateNearBlockFromUnusedRegion(uint32_t size, addr_t pos, size_t search_range, bool executable); - - uint8_t *allocateNearExecMemory(uint32_t size, addr_t pos, size_t search_range); - uint8_t *allocateNearExecMemory(uint8_t *buffer, uint32_t buffer_size, addr_t pos, size_t search_range); - - uint8_t *allocateNearDataMemory(uint32_t size, addr_t pos, size_t search_range); - uint8_t *allocateNearDataMemory(uint8_t *buffer, uint32_t buffer_size, addr_t pos, size_t search_range); -}; \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/PlatformUnifiedInterface/ExecMemory/ClearCacheTool.h b/app/src/main/cpp/Dobby/source/PlatformUnifiedInterface/ExecMemory/ClearCacheTool.h deleted file mode 100644 index ee407cb9..00000000 --- a/app/src/main/cpp/Dobby/source/PlatformUnifiedInterface/ExecMemory/ClearCacheTool.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#ifdef __cplusplus -extern "C" { -#endif - -void ClearCache(void *start, void *end); - -#ifdef __cplusplus -} -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/PlatformUnifiedInterface/ExecMemory/CodePatchTool.h b/app/src/main/cpp/Dobby/source/PlatformUnifiedInterface/ExecMemory/CodePatchTool.h deleted file mode 100644 index 410f0d81..00000000 --- a/app/src/main/cpp/Dobby/source/PlatformUnifiedInterface/ExecMemory/CodePatchTool.h +++ /dev/null @@ -1,3 +0,0 @@ -#pragma once - -int DobbyCodePatch(void *address, uint8_t *buffer, uint32_t buffer_size); \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/PlatformUnifiedInterface/MemoryAllocator.h b/app/src/main/cpp/Dobby/source/PlatformUnifiedInterface/MemoryAllocator.h deleted file mode 100644 index 56da2e5d..00000000 --- a/app/src/main/cpp/Dobby/source/PlatformUnifiedInterface/MemoryAllocator.h +++ /dev/null @@ -1,101 +0,0 @@ -#pragma once - -#include "dobby/common.h" - -struct MemRange { - addr_t start; - addr_t end; - size_t size; - - MemRange(addr_t start, size_t size) : start(start), end(0), size(size) { - end = start + size; - } - - void reset(addr_t start, size_t size) { - this->start = start; - this->size = size; - end = start + size; - } -}; - -struct MemBlock : MemRange { - addr_t addr; - - MemBlock() : MemRange(0, 0), addr(0) { - } - - MemBlock(addr_t addr, size_t size) : MemRange(addr, size), addr(addr) { - } - - void reset(addr_t addr, size_t size) { - MemRange::reset(addr, size); - this->addr = addr; - } -}; - -struct MemoryArena : MemRange { - addr_t addr; - addr_t cursor_addr; - - tinystl::vector memory_blocks; - - MemoryArena(addr_t addr, size_t size) : MemRange(addr, size), addr(addr), cursor_addr(addr) { - } - - virtual MemBlock *allocMemBlock(size_t size); -}; - -using CodeMemBlock = MemBlock; -using CodeMemoryArena = MemoryArena; - -#if 0 -struct CodeMemoryArena : MemoryArena { - CodeMemoryArena(addr_t addr, size_t size) : MemoryArena(addr, size) { - } - - CodeMemBlock *allocateCodeMemBlock(size_t size) { - return allocMemBlock(size); - } -}; -#endif - -using DataMemBlock = MemBlock; -using DataMemoryArena = MemoryArena; - -#if 0 -struct DataMemoryArena : MemoryArena { -public: - DataMemoryArena(addr_t addr, size_t size) : MemoryArena(addr, size) { - } - - DataMemBlock *allocateDataMemBlock(size_t size) { - return allocMemBlock(size); - } -}; -#endif - -class NearMemoryAllocator; -class MemoryAllocator { - friend class NearMemoryAllocator; - -private: - tinystl::vector code_arenas; - tinystl::vector data_arenas; - -private: - static MemoryAllocator *shared_allocator; - -public: - static MemoryAllocator *SharedAllocator(); - -public: - CodeMemoryArena *allocateCodeMemoryArena(uint32_t size); - CodeMemBlock *allocateExecBlock(uint32_t size); - uint8_t *allocateExecMemory(uint32_t size); - uint8_t *allocateExecMemory(uint8_t *buffer, uint32_t buffer_size); - - DataMemoryArena *allocateDataMemoryArena(uint32_t size); - DataMemBlock *allocateDataBlock(uint32_t size); - uint8_t *allocateDataMemory(uint32_t size); - uint8_t *allocateDataMemory(uint8_t *buffer, uint32_t buffer_size); -}; \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/PlatformUnifiedInterface/platform.h b/app/src/main/cpp/Dobby/source/PlatformUnifiedInterface/platform.h deleted file mode 100644 index 77a05ff9..00000000 --- a/app/src/main/cpp/Dobby/source/PlatformUnifiedInterface/platform.h +++ /dev/null @@ -1,82 +0,0 @@ -#pragma once - -#include "dobby/common.h" - -namespace base { - -class ThreadLocalStorageInterface { - using LocalStorageKey = int32_t; - - static LocalStorageKey CreateThreadLocalKey(); - - static void DeleteThreadLocalKey(LocalStorageKey key); - - static void *GetThreadLocal(LocalStorageKey key); - - static int GetThreadLocalInt(LocalStorageKey key) { - return static_cast(reinterpret_cast(GetThreadLocal(key))); - } - - static void SetThreadLocal(LocalStorageKey key, void *value); - - static void SetThreadLocalInt(LocalStorageKey key, int value) { - SetThreadLocal(key, reinterpret_cast(static_cast(value))); - } - - static bool HasThreadLocal(LocalStorageKey key) { - return GetThreadLocal(key) != nullptr; - } -}; - -typedef void *ThreadHandle; - -class ThreadInterface { -public: - class Delegate { - public: - virtual void ThreadMain() = 0; - }; - -public: - static bool Create(Delegate *delegate, ThreadHandle *handle); - - static int CurrentId(); - - static void SetName(const char *); -}; -} // namespace base - -class OSThread : public base::ThreadInterface, public base::ThreadInterface::Delegate { - base::ThreadHandle handle_; - - char name_[256]; - -public: - OSThread(const char *name); - - bool Start(); -}; - -enum MemoryPermission { kNoAccess, kRead, kReadWrite, kReadWriteExecute, kReadExecute }; - -class OSMemory { -public: - static int PageSize(); - - static void *Allocate(size_t size, MemoryPermission access); - - static void *Allocate(size_t size, MemoryPermission access, void *fixed_address); - - static bool Free(void *address, size_t size); - - static bool Release(void *address, size_t size); - - static bool SetPermission(void *address, size_t size, MemoryPermission access); -}; - -class OSPrint { -public: - static void Print(const char *format, ...); - - static void VPrint(const char *format, va_list args); -}; \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/PlatformUtil/ProcessRuntimeUtility.h b/app/src/main/cpp/Dobby/source/PlatformUtil/ProcessRuntimeUtility.h deleted file mode 100644 index 7f85a462..00000000 --- a/app/src/main/cpp/Dobby/source/PlatformUtil/ProcessRuntimeUtility.h +++ /dev/null @@ -1,26 +0,0 @@ -#pragma once - -#include "PlatformUnifiedInterface/MemoryAllocator.h" - -#include "PlatformUnifiedInterface/platform.h" - -typedef struct _RuntimeModule { - char path[1024]; - void *load_address; -} RuntimeModule; - -struct MemRegion : MemRange { - MemoryPermission permission; - - MemRegion(addr_t addr, size_t size, MemoryPermission perm) : MemRange(addr, size), permission(perm) { - } -}; - -class ProcessRuntimeUtility { -public: - static const tinystl::vector &GetProcessMemoryLayout(); - - static const tinystl::vector &GetProcessModuleMap(); - - static RuntimeModule GetProcessModule(const char *name); -}; \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h deleted file mode 100644 index 160ba0ab..00000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h +++ /dev/null @@ -1,39 +0,0 @@ -#pragma once - -#include "dobby/dobby_internal.h" - -#ifdef ENABLE_CLOSURE_TRAMPOLINE_TEMPLATE -#ifdef __cplusplus -extern "C" { -#endif //__cplusplus -void closure_trampoline_template(); -void closure_bridge_template(); -#ifdef __cplusplus -} -#endif //__cplusplus -#endif - -#ifdef __cplusplus -extern "C" { -#endif //__cplusplus - -typedef struct { - void *address; - int size; - void *carry_handler; - void *carry_data; -} ClosureTrampolineEntry; - -asm_func_t get_closure_bridge(); - -#ifdef __cplusplus -} -#endif //__cplusplus - -class ClosureTrampoline { -private: - static tinystl::vector *trampolines_; - -public: - static ClosureTrampolineEntry *CreateClosureTrampoline(void *carry_data, void *carry_handler); -}; diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/ClosureTrampolineARM.cc b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/ClosureTrampolineARM.cc deleted file mode 100644 index 76e2ea2a..00000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/ClosureTrampolineARM.cc +++ /dev/null @@ -1,49 +0,0 @@ -#include "platform_detect_macro.h" -#if defined(TARGET_ARCH_ARM) - -#include "dobby/dobby_internal.h" - -#include "core/assembler/assembler-arm.h" - -#include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" - -using namespace zz; -using namespace zz::arm; - -ClosureTrampolineEntry *ClosureTrampoline::CreateClosureTrampoline(void *carry_data, void *carry_handler) { - ClosureTrampolineEntry *tramp_entry = nullptr; - tramp_entry = new ClosureTrampolineEntry; - -#ifdef ENABLE_CLOSURE_TRAMPOLINE_TEMPLATE -#define CLOSURE_TRAMPOLINE_SIZE (7 * 4) - // use closure trampoline template code, find the executable memory and patch it. - auto code = AssemblyCodeBuilder::FinalizeCodeFromAddress(closure_trampoline_template, CLOSURE_TRAMPOLINE_SIZE); -#else -// use assembler and codegen modules instead of template_code -#include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" -#define _ turbo_assembler_. - TurboAssembler turbo_assembler_(0); - - AssemblerPseudoLabel entry_label(0); - AssemblerPseudoLabel forward_bridge_label(0); - - _ Ldr(r12, &entry_label); - _ Ldr(pc, &forward_bridge_label); - _ PseudoBind(&entry_label); - _ EmitAddress((uint32_t)(uintptr_t)tramp_entry); - _ PseudoBind(&forward_bridge_label); - _ EmitAddress((uint32_t)(uintptr_t)get_closure_bridge()); - - auto closure_tramp = AssemblyCodeBuilder::FinalizeFromTurboAssembler(&turbo_assembler_); - tramp_entry->address = (void *)closure_tramp->addr; - tramp_entry->size = closure_tramp->size; - tramp_entry->carry_data = carry_data; - tramp_entry->carry_handler = carry_handler; - - delete closure_tramp; - - return tramp_entry; -#endif -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/closure_bridge_arm.cc b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/closure_bridge_arm.cc deleted file mode 100644 index e41500da..00000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/closure_bridge_arm.cc +++ /dev/null @@ -1,90 +0,0 @@ -#include "platform_detect_macro.h" -#if defined(TARGET_ARCH_ARM) - -#include "dobby/dobby_internal.h" - -#include "core/assembler/assembler-arm.h" - -#include "TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.h" - -using namespace zz; -using namespace zz::arm; - -static asm_func_t closure_bridge = nullptr; - -asm_func_t get_closure_bridge() { - - // if already initialized, just return. - if (closure_bridge) - return closure_bridge; - -// check if enable the inline-assembly closure_bridge_template -#if ENABLE_CLOSURE_BRIDGE_TEMPLATE - extern void closure_bridge_tempate(); - closure_bridge = closure_bridge_template; -// otherwise, use the Assembler build the closure_bridge -#else -#define _ turbo_assembler_. - TurboAssembler turbo_assembler_(0); - - _ sub(sp, sp, Operand(14 * 4)); - _ str(lr, MemOperand(sp, 13 * 4)); - _ str(r12, MemOperand(sp, 12 * 4)); - _ str(r11, MemOperand(sp, 11 * 4)); - _ str(r10, MemOperand(sp, 10 * 4)); - _ str(r9, MemOperand(sp, 9 * 4)); - _ str(r8, MemOperand(sp, 8 * 4)); - _ str(r7, MemOperand(sp, 7 * 4)); - _ str(r6, MemOperand(sp, 6 * 4)); - _ str(r5, MemOperand(sp, 5 * 4)); - _ str(r4, MemOperand(sp, 4 * 4)); - _ str(r3, MemOperand(sp, 3 * 4)); - _ str(r2, MemOperand(sp, 2 * 4)); - _ str(r1, MemOperand(sp, 1 * 4)); - _ str(r0, MemOperand(sp, 0 * 4)); - - // store sp - _ add(r0, sp, Operand(14 * 4)); - _ sub(sp, sp, Operand(8)); - _ str(r0, MemOperand(sp, 4)); - - // stack align - _ sub(sp, sp, Operand(8)); - - _ mov(r0, Operand(sp)); - _ mov(r1, Operand(r12)); - _ CallFunction(ExternalReference((void *)common_closure_bridge_handler)); - - // stack align - _ add(sp, sp, Operand(8)); - - // restore sp placeholder stack - _ add(sp, sp, Operand(8)); - - _ ldr(r0, MemOperand(sp, 4, PostIndex)); - _ ldr(r1, MemOperand(sp, 4, PostIndex)); - _ ldr(r2, MemOperand(sp, 4, PostIndex)); - _ ldr(r3, MemOperand(sp, 4, PostIndex)); - _ ldr(r4, MemOperand(sp, 4, PostIndex)); - _ ldr(r5, MemOperand(sp, 4, PostIndex)); - _ ldr(r6, MemOperand(sp, 4, PostIndex)); - _ ldr(r7, MemOperand(sp, 4, PostIndex)); - _ ldr(r8, MemOperand(sp, 4, PostIndex)); - _ ldr(r9, MemOperand(sp, 4, PostIndex)); - _ ldr(r10, MemOperand(sp, 4, PostIndex)); - _ ldr(r11, MemOperand(sp, 4, PostIndex)); - _ ldr(r12, MemOperand(sp, 4, PostIndex)); - _ ldr(lr, MemOperand(sp, 4, PostIndex)); - - // auto switch A32 & T32 with `least significant bit`, refer `docs/A32_T32_states_switch.md` - _ mov(pc, Operand(r12)); - - auto code = AssemblyCodeBuilder::FinalizeFromTurboAssembler(&turbo_assembler_); - closure_bridge = (asm_func_t)code->addr; - - DEBUG_LOG("[closure bridge] closure bridge at %p", closure_bridge); -#endif - return closure_bridge; -} - -#endif diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/dummy/closure-bridge-template-arm.cc b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/dummy/closure-bridge-template-arm.cc deleted file mode 100644 index 8e415252..00000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/dummy/closure-bridge-template-arm.cc +++ /dev/null @@ -1,65 +0,0 @@ -// .section __TEXT,__text,regular,pure_instructions -// .ios_version_min 11, 0 - -#if defined(ENABLE_CLOSURE_BRIDGE_TEMPLATE) - -#if defined(__WIN32__) || defined(__APPLE__) -#define cdecl(s) "_" s -#else -#define cdecl(s) s -#endif - -#define xASM(x) __asm(x) - -__attribute__((naked)) void closure_bridge_template() { - xASM(".arm"); - xASM("sub sp, sp, #(14*4)"); - xASM("str lr, [sp, #(13*4)]"); - xASM("str r12, [sp, #(12*4)]"); - xASM("str r11, [sp, #(11*4)]"); - xASM("str r10, [sp, #(10*4)]"); - xASM("str r9, [sp, #(9*4)]"); - xASM("str r8, [sp, #(8*4)]"); - xASM("str r7, [sp, #(7*4)]"); - xASM("str r6, [sp, #(6*4)]"); - xASM("str r5, [sp, #(5*4)]"); - xASM("str r4, [sp, #(4*4)]"); - xASM("str r3, [sp, #(3*4)]"); - xASM("str r2, [sp, #(2*4)]"); - xASM("str r1, [sp, #(1*4)]"); - xASM("str r0, [sp, #(0*4)]"); - - // dummy align - xASM("sub sp, sp, #8"); - - xASM("mov r0, sp"); - xASM("mov r1, r12"); - xASM("bl " cdecl("common_closure_bridge_handler")); - - // dummy align - xASM("add sp, sp, #8"); - - xASM("ldr r0, [sp], #4"); - xASM("ldr r1, [sp], #4"); - xASM("ldr r2, [sp], #4"); - xASM("ldr r3, [sp], #4"); - xASM("ldr r4, [sp], #4"); - xASM("ldr r5, [sp], #4"); - xASM("ldr r6, [sp], #4"); - xASM("ldr r7, [sp], #4"); - xASM("ldr r8, [sp], #4"); - xASM("ldr r9, [sp], #4"); - xASM("ldr r10, [sp], #4"); - xASM("ldr r11, [sp], #4"); - xASM("ldr r12, [sp], #4"); - xASM("ldr lr, [sp], #4"); - -#if 1 - xASM("str r12, [sp, #-4]"); - xASM("ldr pc, [sp, #-4]"); -#else - xASM("mov pc, r12"); -#endif -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/dummy/closure-trampoline-template-arm.S b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/dummy/closure-trampoline-template-arm.S deleted file mode 100644 index 5be6ac86..00000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/dummy/closure-trampoline-template-arm.S +++ /dev/null @@ -1,34 +0,0 @@ -// .section __TEXT,__text,regular,pure_instructions - -#if defined(ENABLE_CLOSURE_BRIDGE_TEMPLATE) - -#if defined(__WIN32__) || defined(__APPLE__) -#define cdecl(s) _##s -#else -#define cdecl(s) s -#endif - -.align 4 - -#if !defined(ENABLE_CLOSURE_TRAMPOLINE_CARRY_OBJECT_PTR) - -// closure trampoline carray the object pointer, and fetch required members at the runtime assembly code. -// #include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" -// #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) -#define OFFSETOF_ClourseTrampolineEntry_carry_data 4 -#define OFFSETOF_ClourseTrampolineEntry_carry_handler 0 - .globl - cdecl(closure_trampoline_template) cdecl(closure_trampoline_template) - : ldr r12, -ClourseTrampolineEntryPtr ldr pc, [ r12, #0 ] ClourseTrampolineEntryPtr :.long 0 - -#else - - ; -closure trampoline just carray the required members from the object..globl cdecl(closure_trampoline_template) - cdecl(closure_trampoline_template) - : ldr r12, -= carry_data ldr pc, = carry_handler carry_data :.long 0 carry_handler :.long 0 -#endif - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/helper_arm.cc b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/helper_arm.cc deleted file mode 100644 index bf2123d1..00000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/helper_arm.cc +++ /dev/null @@ -1,13 +0,0 @@ -#include "platform_detect_macro.h" -#if defined(TARGET_ARCH_ARM) - -#include "dobby/dobby_internal.h" - -void set_routing_bridge_next_hop(DobbyRegisterContext *ctx, void *address) { - *reinterpret_cast(&ctx->general.regs.r12) = address; -} - -void get_routing_bridge_next_hop(DobbyRegisterContext *ctx, void *address) { -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/ClosureTrampolineARM64.cc b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/ClosureTrampolineARM64.cc deleted file mode 100644 index 9dfc44c0..00000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/ClosureTrampolineARM64.cc +++ /dev/null @@ -1,63 +0,0 @@ -#include "platform_detect_macro.h" -#if defined(TARGET_ARCH_ARM64) - -#include "dobby/dobby_internal.h" - -#include "core/assembler/assembler-arm64.h" - -#include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" - -using namespace zz; -using namespace zz::arm64; - -// // tips -// _ ldr(TMP_REG_1, OFFSETOF(ClosureTrampolineEntry, carry_data)); -// _ ldr(TMP_REG_0, OFFSETOF(ClosureTrampolineEntry, carry_handler)); - -// use assembler and codegen modules instead of template_code -ClosureTrampolineEntry *ClosureTrampoline::CreateClosureTrampoline(void *carry_data, void *carry_handler) { - ClosureTrampolineEntry *tramp_entry = nullptr; - tramp_entry = new ClosureTrampolineEntry; - -#define _ turbo_assembler_. - TurboAssembler turbo_assembler_(0); - - AssemblerPseudoLabel entry_label(0); - AssemblerPseudoLabel forward_bridge_label(0); - - // prologue: alloc stack, store lr - _ sub(SP, SP, 2 * 8); - _ str(x30, MemOperand(SP, 8)); - - // store data at stack - _ Ldr(TMP_REG_0, &entry_label); - _ str(TMP_REG_0, MemOperand(SP, 0)); - - _ Ldr(TMP_REG_0, &forward_bridge_label); - _ blr(TMP_REG_0); - - // epilogue: release stack(won't restore lr) - _ ldr(x30, MemOperand(SP, 8)); - _ add(SP, SP, 2 * 8); - - // branch to next hop - _ br(TMP_REG_0); - - _ PseudoBind(&entry_label); - _ EmitInt64((uint64_t)tramp_entry); - _ PseudoBind(&forward_bridge_label); - _ EmitInt64((uint64_t)get_closure_bridge()); - - auto closure_tramp = AssemblyCodeBuilder::FinalizeFromTurboAssembler(static_cast(&turbo_assembler_)); - - tramp_entry->address = (void *)closure_tramp->addr; - tramp_entry->size = closure_tramp->size; - tramp_entry->carry_data = carry_data; - tramp_entry->carry_handler = carry_handler; - - delete closure_tramp; - - return tramp_entry; -} - -#endif diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/closure_bridge_arm64.cc b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/closure_bridge_arm64.cc deleted file mode 100644 index 5e1bc0e7..00000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/closure_bridge_arm64.cc +++ /dev/null @@ -1,159 +0,0 @@ -#include "platform_detect_macro.h" -#if defined(TARGET_ARCH_ARM64) - -#include "dobby/dobby_internal.h" - -#include "core/assembler/assembler.h" -#include "core/assembler/assembler-arm64.h" - -#include "TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.h" - -using namespace zz; -using namespace zz::arm64; - -static asm_func_t closure_bridge = nullptr; - -asm_func_t get_closure_bridge() { - // if already initialized, just return. - if (closure_bridge) - return closure_bridge; - -// check if enable the inline-assembly closure_bridge_template -#if ENABLE_CLOSURE_BRIDGE_TEMPLATE - extern void closure_bridge_tempate(); - closure_bridge = closure_bridge_template; -// otherwise, use the Assembler build the closure_bridge -#else -#define _ turbo_assembler_. -#define MEM(reg, offset) MemOperand(reg, offset) - TurboAssembler turbo_assembler_(0); - -#if defined(FULL_FLOATING_POINT_REGISTER_PACK) - - _ sub(SP, SP, 24 * 16); - _ stp(Q(30), Q(31), MEM(SP, 22 * 16)); - _ stp(Q(28), Q(29), MEM(SP, 20 * 16)); - _ stp(Q(26), Q(27), MEM(SP, 18 * 16)); - _ stp(Q(24), Q(25), MEM(SP, 16 * 16)); - _ stp(Q(22), Q(23), MEM(SP, 14 * 16)); - _ stp(Q(20), Q(21), MEM(SP, 12 * 16)); - _ stp(Q(18), Q(19), MEM(SP, 10 * 16)); - _ stp(Q(16), Q(17), MEM(SP, 8 * 16)); - _ stp(Q(14), Q(15), MEM(SP, 6 * 16)); - _ stp(Q(12), Q(13), MEM(SP, 4 * 16)); - _ stp(Q(10), Q(11), MEM(SP, 2 * 16)); - _ stp(Q(8), Q(9), MEM(SP, 0 * 16)); - -#endif - - // save {q0-q7} - _ sub(SP, SP, 8 * 16); - _ stp(Q(6), Q(7), MEM(SP, 6 * 16)); - _ stp(Q(4), Q(5), MEM(SP, 4 * 16)); - _ stp(Q(2), Q(3), MEM(SP, 2 * 16)); - _ stp(Q(0), Q(1), MEM(SP, 0 * 16)); - - // save {x1-x30} - _ sub(SP, SP, 30 * 8); - _ stp(X(29), X(30), MEM(SP, 28 * 8)); - _ stp(X(27), X(28), MEM(SP, 26 * 8)); - _ stp(X(25), X(26), MEM(SP, 24 * 8)); - _ stp(X(23), X(24), MEM(SP, 22 * 8)); - _ stp(X(21), X(22), MEM(SP, 20 * 8)); - _ stp(X(19), X(20), MEM(SP, 18 * 8)); - _ stp(X(17), X(18), MEM(SP, 16 * 8)); - _ stp(X(15), X(16), MEM(SP, 14 * 8)); - _ stp(X(13), X(14), MEM(SP, 12 * 8)); - _ stp(X(11), X(12), MEM(SP, 10 * 8)); - _ stp(X(9), X(10), MEM(SP, 8 * 8)); - _ stp(X(7), X(8), MEM(SP, 6 * 8)); - _ stp(X(5), X(6), MEM(SP, 4 * 8)); - _ stp(X(3), X(4), MEM(SP, 2 * 8)); - _ stp(X(1), X(2), MEM(SP, 0 * 8)); - - // save {x0} - _ sub(SP, SP, 2 * 8); - _ str(x0, MEM(SP, 8)); - - // calculate original sp - _ add(TMP_REG_0, SP, 2 * 8); // closure trampoline reserved - _ add(TMP_REG_0, TMP_REG_0, 2 * 8 + 30 * 8 + 8 * 16); // x0, x1-x30, q0-q7 reserved -#if defined(FULL_FLOATING_POINT_REGISTER_PACK) - _ add(TMP_REG_0, TMP_REG_0, 24 * 16); // q8-q31 reserved -#endif - - // alloc stack, store original sp - _ sub(SP, SP, 2 * 8); - _ str(TMP_REG_0, MEM(SP, 8)); - -#if defined(FULL_FLOATING_POINT_REGISTER_PACK) -#define REGISTER_CONTEXT_SIZE (sizeof(DobbyRegisterContext)) -#else -#define REGISTER_CONTEXT_SIZE (sizeof(DobbyRegisterContext) - 24 * 16) -#endif - // create function arm64 call convention - _ mov(x0, SP); // arg1: register context - // load package(closure trampoline entry reserved) - _ ldr(x1, MEM(SP, REGISTER_CONTEXT_SIZE + 0)); // arg2: closure trampoline entry - _ CallFunction(ExternalReference((void *)common_closure_bridge_handler)); - - // restore sp placeholder stack - _ add(SP, SP, 2 * 8); - - // restore {x0} - _ ldr(X(0), MEM(SP, 8)); - _ add(SP, SP, 2 * 8); - -#define MEM_EXT(reg, offset, addrmode) MemOperand(reg, offset, addrmode) - // restore {x1-x30} - _ ldp(X(1), X(2), MEM_EXT(SP, 16, PostIndex)); - _ ldp(X(3), X(4), MEM_EXT(SP, 16, PostIndex)); - _ ldp(X(5), X(6), MEM_EXT(SP, 16, PostIndex)); - _ ldp(X(7), X(8), MEM_EXT(SP, 16, PostIndex)); - _ ldp(X(9), X(10), MEM_EXT(SP, 16, PostIndex)); - _ ldp(X(11), X(12), MEM_EXT(SP, 16, PostIndex)); - _ ldp(X(13), X(14), MEM_EXT(SP, 16, PostIndex)); - _ ldp(X(15), X(16), MEM_EXT(SP, 16, PostIndex)); - _ ldp(X(17), X(18), MEM_EXT(SP, 16, PostIndex)); - _ ldp(X(19), X(20), MEM_EXT(SP, 16, PostIndex)); - _ ldp(X(21), X(22), MEM_EXT(SP, 16, PostIndex)); - _ ldp(X(23), X(24), MEM_EXT(SP, 16, PostIndex)); - _ ldp(X(25), X(26), MEM_EXT(SP, 16, PostIndex)); - _ ldp(X(27), X(28), MEM_EXT(SP, 16, PostIndex)); - _ ldp(X(29), X(30), MEM_EXT(SP, 16, PostIndex)); - - // restore {q0-q7} - _ ldp(Q(0), Q(1), MEM_EXT(SP, 32, PostIndex)); - _ ldp(Q(2), Q(3), MEM_EXT(SP, 32, PostIndex)); - _ ldp(Q(4), Q(5), MEM_EXT(SP, 32, PostIndex)); - _ ldp(Q(6), Q(7), MEM_EXT(SP, 32, PostIndex)); - -#if defined(FULL_FLOATING_POINT_REGISTER_PACK) - _ ldp(Q(8), Q(9), MEM_EXT(SP, 32, PostIndex)); - _ ldp(Q(10), Q(11), MEM_EXT(SP, 32, PostIndex)); - _ ldp(Q(12), Q(13), MEM_EXT(SP, 32, PostIndex)); - _ ldp(Q(14), Q(15), MEM_EXT(SP, 32, PostIndex)); - _ ldp(Q(16), Q(17), MEM_EXT(SP, 32, PostIndex)); - _ ldp(Q(18), Q(19), MEM_EXT(SP, 32, PostIndex)); - _ ldp(Q(20), Q(21), MEM_EXT(SP, 32, PostIndex)); - _ ldp(Q(22), Q(23), MEM_EXT(SP, 32, PostIndex)); - _ ldp(Q(24), Q(25), MEM_EXT(SP, 32, PostIndex)); - _ ldp(Q(26), Q(27), MEM_EXT(SP, 32, PostIndex)); - _ ldp(Q(28), Q(29), MEM_EXT(SP, 32, PostIndex)); - _ ldp(Q(30), Q(31), MEM_EXT(SP, 32, PostIndex)); -#endif - - // _ brk(0); // for debug - - // return to closure trampoline, but TMP_REG_0, had been modified with next hop address - _ ret(); // AKA br x30 - - auto code = AssemblyCodeBuilder::FinalizeFromTurboAssembler(&turbo_assembler_); - closure_bridge = (asm_func_t)code->addr; - - DEBUG_LOG("[closure bridge] closure bridge at %p", closure_bridge); -#endif - return closure_bridge; -} - -#endif diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/dummy/closure-bridge-template-arm64.c b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/dummy/closure-bridge-template-arm64.c deleted file mode 100644 index ee5323ed..00000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/dummy/closure-bridge-template-arm64.c +++ /dev/null @@ -1,103 +0,0 @@ -#if defined(ENABLE_CLOSURE_BRIDGE_TEMPLATE) - -#if defined(__WIN32__) || defined(__APPLE__) -#define xcdecl(s) "_" s -#else -#define xcdecl(s) s -#endif - -#define xASM(x) __asm(x) - -__attribute__((naked)) void closure_bridge_template() { - // DO NOT USE prologue - // x29 == fp, x30 == lr - // xASM("stp x29, x30, [sp, #-16]!"); - // xASM("mov x29, sp"); - - // save {q0-q7} - xASM("sub sp, sp, #(8*16)"); - xASM("stp q6, q7, [sp, #(6*16)]"); - xASM("stp q4, q5, [sp, #(4*16)]"); - xASM("stp q2, q3, [sp, #(2*16)]"); - xASM("stp q0, q1, [sp, #(0*16)]"); - - // save {x1-x30} - xASM("sub sp, sp, #(30*8)"); - // stp fp, lr, [sp, #(28*8)]"); - xASM("stp x29, x30, [sp, #(28*8)]"); - xASM("stp x27, x28, [sp, #(26*8)]"); - xASM("stp x25, x26, [sp, #(24*8)]"); - xASM("stp x23, x24, [sp, #(22*8)]"); - xASM("stp x21, x22, [sp, #(20*8)]"); - xASM("stp x19, x20, [sp, #(18*8)]"); - xASM("stp x17, x18, [sp, #(16*8)]"); - xASM("stp x15, x16, [sp, #(14*8)]"); - xASM("stp x13, x14, [sp, #(12*8)]"); - xASM("stp x11, x12, [sp, #(10*8)]"); - xASM("stp x9, x10, [sp, #(8*8)]"); - xASM("stp x7, x8, [sp, #(6*8)]"); - xASM("stp x5, x6, [sp, #(4*8)]"); - xASM("stp x3, x4, [sp, #(2*8)]"); - xASM("stp x1, x2, [sp, #(0*8)]"); - -#if 1 - // save {x0} - xASM("sub sp, sp, #(2*8)"); - xASM("str x0, [sp, #8]"); -#else - // save {x0, sp} - // save x0 and reserve sp, but this is trick - xASM("sub sp, sp, #(2*8)"); - xASM("str x0, [sp, #8]"); - // save origin sp - xASM("add x1, sp, #0x190"); - xASM("str x1, [sp, #0]"); -#endif - - // ======= Jump to UnifiedInterface Bridge Handle ======= - - // prepare args - // @x0: data_address - // @x1: DobbyRegisterContext stack address - xASM("mov x0, sp"); - xASM("mov x1, x14"); - xASM("bl " xcdecl("common_closure_bridge_handler")); - - // ======= DobbyRegisterContext Restore ======= - // restore x0 - xASM("ldr x0, [sp, #8]"); - xASM("add sp, sp, #(2*8)"); - - // restore {x1-x30} - xASM("ldp x1, x2, [sp], #16"); - xASM("ldp x3, x4, [sp], #16"); - xASM("ldp x5, x6, [sp], #16"); - xASM("ldp x7, x8, [sp], #16"); - xASM("ldp x9, x10, [sp], #16"); - xASM("ldp x11, x12, [sp], #16"); - xASM("ldp x13, x14, [sp], #16"); - xASM("ldp x15, x16, [sp], #16"); - xASM("ldp x17, x18, [sp], #16"); - xASM("ldp x19, x20, [sp], #16"); - xASM("ldp x21, x22, [sp], #16"); - xASM("ldp x23, x24, [sp], #16"); - xASM("ldp x25, x26, [sp], #16"); - xASM("ldp x27, x28, [sp], #16"); - // ldp fp, lr, [sp], #16"); - xASM("ldp x29, x30, [sp], #16"); - - // restore {q0-q7} - xASM("ldp q0, q1, [sp], #32"); - xASM("ldp q2, q3, [sp], #32"); - xASM("ldp q4, q5, [sp], #32"); - xASM("ldp q6, q7, [sp], #32"); - - // DO NOT USE epilog - // x29 == fp, x30 == lr - // xASM("mov sp, x29"); - // xASM("ldp x29, x30, [sp], #16"); - - xASM("br x15"); -}; - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/dummy/closure-trampoline-template-arm64.S b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/dummy/closure-trampoline-template-arm64.S deleted file mode 100644 index 2d548682..00000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/dummy/closure-trampoline-template-arm64.S +++ /dev/null @@ -1,36 +0,0 @@ -// .section __TEXT,__text,regular,pure_instructions - -#if defined(ENABLE_CLOSURE_BRIDGE_TEMPLATE) - -#if defined(__WIN32__) || defined(__APPLE__) -#define cdecl(s) _##s -#else -#define cdecl(s) s -#endif - -.align 4 - -#if !defined(ENABLE_CLOSURE_TRAMPOLINE_CARRY_OBJECT_PTR) - -// closure trampoline carray the object pointer, and fetch required members at the runtime assembly code. -// #include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" -// #define OFFSETOF(TYPE, ELEMENT) ((size_t)&(((TYPE *)0)->ELEMENT)) -#define OFFSETOF_ClourseTrampolineEntry_carry_data 8 -#define OFFSETOF_ClourseTrampolineEntry_carry_handler 0 - .globl - cdecl(closure_trampoline_template) cdecl(closure_trampoline_template) - : ldr x17, -ClourseTrampolineEntryPtr ldr x16, OFFSETOF_ClourseTrampolineEntry_carry_data ldr x17, -OFFSETOF_ClourseTrampolineEntry_carry_handler br x17 ClourseTrampolineEntryPtr :.long 0.long 0 - -#else - - ; -closure trampoline just carray the required members from the object..globl cdecl(closure_trampoline_template) - cdecl(closure_trampoline_template) - : ldr x16, -= carry_data ldr x17, = carry_handler br x17 carry_data :.long 0.long 0 carry_handler :.long 0.long 0 - -#endif - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/dummy/dynamic-closure-trampoline-template-arm64.S b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/dummy/dynamic-closure-trampoline-template-arm64.S deleted file mode 100644 index a52032f2..00000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/dummy/dynamic-closure-trampoline-template-arm64.S +++ /dev/null @@ -1,33 +0,0 @@ -// .section __TEXT,__text,regular,pure_instructions - -// For iOS, we can't allocate executable memory, but we can use `remap` doing some trick. -// For details, please refer `libffi` - -#if defined(ENABLE_CLOSURE_BRIDGE_TEMPLATE) - -#if defined(__WIN32__) || defined(__APPLE__) -#define cdecl(s) _##s -#else -#define cdecl(s) s -#endif - -#define PAGE_MAX_SIZE 4096 -#define PAGE_MAX_SHIFT 14 - -.align PAGE_MAX_SHIFT.globl cdecl(dynamic_closure_trampoline_table_page) cdecl(dynamic_closure_trampoline_table_page) - :.rept(PAGE_MAX_SIZE - 4 * 4) / - 8 // sub dynamic_closure_trampoline_forward size - adr x16, -#0 b cdecl(dynamic_closure_trampoline_forward) - .endr - - cdecl(dynamic_closure_trampoline_forward) - : sub x16, -x16, #0x4000 // [DynamicClosureTrampoline **] - ldr x16, -[ x16, #0 ] // [DynamicClosureTrampoline *] - ldr x17, -[ x16, #0 ] // trampolineTo - br x17 - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/helper_arm64.cc b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/helper_arm64.cc deleted file mode 100644 index c0046d49..00000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/helper_arm64.cc +++ /dev/null @@ -1,17 +0,0 @@ -#include "platform_detect_macro.h" -#if defined(TARGET_ARCH_ARM64) - -#include "core/assembler/assembler-arm64.h" - -#include "dobby/dobby_internal.h" - -using namespace zz::arm64; - -void set_routing_bridge_next_hop(DobbyRegisterContext *ctx, void *address) { - *reinterpret_cast(&ctx->general.x[TMP_REG_0.code()]) = address; -} - -void get_routing_bridge_next_hop(DobbyRegisterContext *ctx, void *address) { -} - -#endif diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.cc b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.cc deleted file mode 100644 index b1be02a9..00000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.cc +++ /dev/null @@ -1,22 +0,0 @@ -#include "logging/logging.h" - -#include "TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.h" - -PUBLIC void common_closure_bridge_handler(DobbyRegisterContext *ctx, ClosureTrampolineEntry *entry) { - DEBUG_LOG("common bridge handler: carry data: %p, carry handler: %p", (InterceptEntry *)entry->carry_data, - entry->carry_handler); - - typedef void (*routing_handler_t)(InterceptEntry *, DobbyRegisterContext *); - auto routing_handler = (routing_handler_t)entry->carry_handler; - -#if defined(__APPLE__) && __arm64e__ -#if __has_feature(ptrauth_calls) - uint64_t discriminator = 0; - // discriminator = __builtin_ptrauth_type_discriminator(__typeof(routing_handler)); - routing_handler = (__typeof(routing_handler))__builtin_ptrauth_sign_unauthenticated((void *)routing_handler, - ptrauth_key_asia, discriminator); -#endif -#endif - - routing_handler((InterceptEntry *)entry->carry_data, ctx); -} diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.h b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.h deleted file mode 100644 index c02eca35..00000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef CLOSURE_TRAMPOLINE_COMMON_HANDLER_H -#define CLOSURE_TRAMPOLINE_COMMON_HANDLER_H - -#include "dobby/dobby_internal.h" - -#include "Interceptor.h" -#include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" - -extern "C" { -void common_closure_bridge_handler(DobbyRegisterContext *ctx, ClosureTrampolineEntry *entry); -} - -void get_routing_bridge_next_hop(DobbyRegisterContext *ctx, void *address); - -void set_routing_bridge_next_hop(DobbyRegisterContext *ctx, void *address); - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/ClosureTrampolineX64.cc b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/ClosureTrampolineX64.cc deleted file mode 100644 index f3abb2d4..00000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/ClosureTrampolineX64.cc +++ /dev/null @@ -1,45 +0,0 @@ -#include "platform_detect_macro.h" -#if defined(TARGET_ARCH_X64) - -#include "dobby/dobby_internal.h" - -#include "core/assembler/assembler-x64.h" - -#include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" - -using namespace zz; -using namespace zz::x64; - -ClosureTrampolineEntry *ClosureTrampoline::CreateClosureTrampoline(void *carry_data, void *carry_handler) { - ClosureTrampolineEntry *tramp_entry = nullptr; - tramp_entry = new ClosureTrampolineEntry; - - auto tramp_size = 32; - auto tramp_mem = MemoryAllocator::SharedAllocator()->allocateExecMemory(tramp_size); - if (tramp_mem == nullptr) { - return nullptr; - } -#define _ turbo_assembler_. -#define __ turbo_assembler_.GetCodeBuffer()-> - TurboAssembler turbo_assembler_(0); - - uint8_t *push_rip_6 = (uint8_t *)"\xff\x35\x06\x00\x00\x00"; - uint8_t *jmp_rip_8 = (uint8_t *)"\xff\x25\x08\x00\x00\x00"; - - __ EmitBuffer(push_rip_6, 6); - __ EmitBuffer(jmp_rip_8, 6); - __ Emit64((uint64_t)tramp_entry); - __ Emit64((uint64_t)get_closure_bridge()); - - tramp_entry->address = tramp_mem; - tramp_entry->size = tramp_size; - tramp_entry->carry_data = carry_data; - tramp_entry->carry_handler = carry_handler; - - auto closure_tramp_buffer = static_cast(turbo_assembler_.GetCodeBuffer()); - DobbyCodePatch(tramp_mem, (uint8_t *)closure_tramp_buffer->GetBuffer(), closure_tramp_buffer->GetBufferSize()); - - return tramp_entry; -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/closure_bridge_x64.cc b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/closure_bridge_x64.cc deleted file mode 100644 index c0c5ffc1..00000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/closure_bridge_x64.cc +++ /dev/null @@ -1,141 +0,0 @@ -#include "platform_detect_macro.h" -#if defined(TARGET_ARCH_X64) - -#include "dobby/dobby_internal.h" - -#include "core/assembler/assembler-x64.h" - -#include "TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.h" - -using namespace zz; -using namespace zz::x64; - -static asm_func_t closure_bridge = nullptr; - -asm_func_t get_closure_bridge() { - // if already initialized, just return. - if (closure_bridge) - return closure_bridge; - -// Check if enable the inline-assembly closure_bridge_template -#if ENABLE_CLOSURE_BRIDGE_TEMPLATE - - extern void closure_bridge_tempate(); - closure_bridge = closure_bridge_template; - -#else - -// otherwise, use the Assembler build the closure_bridge -#define _ turbo_assembler_. -#define __ turbo_assembler_.GetCodeBuffer()-> - - uint8_t *pushfq = (uint8_t *)"\x9c"; - uint8_t *popfq = (uint8_t *)"\x9d"; - - TurboAssembler turbo_assembler_(0); - - // save flags register - __ EmitBuffer(pushfq, 1); - // align rsp 16-byte - _ sub(rsp, Immediate(8, 32)); - - // general register - _ sub(rsp, Immediate(16 * 8, 32)); - _ mov(Address(rsp, 8 * 0), rax); - _ mov(Address(rsp, 8 * 1), rbx); - _ mov(Address(rsp, 8 * 2), rcx); - _ mov(Address(rsp, 8 * 3), rdx); - _ mov(Address(rsp, 8 * 4), rbp); - _ mov(Address(rsp, 8 * 5), rsp); - _ mov(Address(rsp, 8 * 6), rdi); - _ mov(Address(rsp, 8 * 7), rsi); - _ mov(Address(rsp, 8 * 8), r8); - _ mov(Address(rsp, 8 * 9), r9); - _ mov(Address(rsp, 8 * 10), r10); - _ mov(Address(rsp, 8 * 11), r11); - _ mov(Address(rsp, 8 * 12), r12); - _ mov(Address(rsp, 8 * 13), r13); - _ mov(Address(rsp, 8 * 14), r14); - _ mov(Address(rsp, 8 * 15), r15); - - // save origin sp - _ mov(rax, rsp); - _ add(rax, Immediate(8 + 8 + 8 + 16 * 8, 32)); - _ sub(rsp, Immediate(2 * 8, 32)); - _ mov(Address(rsp, 8), rax); - - // ======= Jump to UnifiedInterface Bridge Handle ======= - - // prepare args - // @rdi: data_address - // @rsi: DobbyRegisterContext stack address - _ mov(rdi, rsp); - _ mov(rsi, Address(rsp, 8 + 8 + 16 * 8 + 2 * 8)); - - // [!!!] As we can't detect the sp is aligned or not, check if need stack align - { - // mov rax, rsp - __ EmitBuffer((uint8_t *)"\x48\x89\xE0", 3); - // and rax, 0xF - __ EmitBuffer((uint8_t *)"\x48\x83\xE0\x0F", 4); - // cmp rax, 0x0 - __ EmitBuffer((uint8_t *)"\x48\x83\xF8\x00", 4); - // jnz [stack_align_call_bridge] - __ EmitBuffer((uint8_t *)"\x75\x15", 2); - } - - // LABEL: call_bridge - _ CallFunction(ExternalReference((void *)common_closure_bridge_handler)); - - // jmp [restore_stack_register] - __ EmitBuffer((uint8_t *)"\xE9\x12\x00\x00\x00", 5); - - // LABEL: stack_align_call_bridge - // push rax - __ EmitBuffer((uint8_t *)"\x50", 1); - _ CallFunction(ExternalReference((void *)common_closure_bridge_handler)); - // pop rax - __ EmitBuffer((uint8_t *)"\x58", 1); - - // ======= DobbyRegisterContext Restore ======= - - // restore sp placeholder stack - _ add(rsp, Immediate(2 * 8, 32)); - - // general register - _ pop(rax); - _ pop(rbx); - _ pop(rcx); - _ pop(rdx); - _ pop(rbp); - _ add(rsp, Immediate(8, 32)); // => pop rsp - _ pop(rdi); - _ pop(rsi); - _ pop(r8); - _ pop(r9); - _ pop(r10); - _ pop(r11); - _ pop(r12); - _ pop(r13); - _ pop(r14); - _ pop(r15); - - // align rsp 16-byte - _ add(rsp, Immediate(8, 32)); - // restore flags register - __ EmitBuffer(popfq, 1); - - // trick: use the 'carry_data' stack(remain at closure trampoline) placeholder, as the return address - _ ret(); - - _ RelocBind(); - - auto code = AssemblyCodeBuilder::FinalizeFromTurboAssembler(&turbo_assembler_); - closure_bridge = (asm_func_t)code->addr; - - DEBUG_LOG("[closure bridge] closure bridge at %p", closure_bridge); -#endif - return closure_bridge; -} - -#endif diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/dummy/closure-bridge-template-x64.c b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/dummy/closure-bridge-template-x64.c deleted file mode 100644 index d59dcdca..00000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/dummy/closure-bridge-template-x64.c +++ /dev/null @@ -1,70 +0,0 @@ -#if defined(ENABLE_CLOSURE_BRIDGE_TEMPLATE) - -#if defined(__WIN32__) || defined(__APPLE__) -#define xcdecl(s) "_" s -#else -#define xcdecl(s) s -#endif - -#define xASM(x) __asm(x) - -__attribute__((naked)) void closure_bridge_template() { - // flags register - xASM("pushfq"); - - // general register - xASM("sub rsp, #(16*8)"); - xASM("mov [rsp+16*0], rax"); - xASM("mov [rsp+16*1], rbx"); - xASM("mov [rsp+16*2], rcx"); - xASM("mov [rsp+16*3], rdx"); - xASM("mov [rsp+16*4], rbp"); - xASM("mov [rsp+16*5], rsp"); - xASM("mov [rsp+16*6], rdi"); - xASM("mov [rsp+16*7], rsi"); - xASM("mov [rsp+16*8], r8"); - xASM("mov [rsp+16*9], r9"); - xASM("mov [rsp+16*10], r10"); - xASM("mov [rsp+16*11], r11"); - xASM("mov [rsp+16*12], r12"); - xASM("mov [rsp+16*13], r13"); - xASM("mov [rsp+16*14], r14"); - xASM("mov [rsp+16*15], r15"); - - // ======= Jump to UnifiedInterface Bridge Handle ======= - - // prepare args - // @rdi: data_address - // @rsi: DobbyRegisterContext stack address - xASM("mov rdi, rsp"); - xASM("mov rsi, [rsp-16*8]"); - xASM("call " xcdecl("common_closure_bridge_handler")); - - // ======= DobbyRegisterContext Restore ======= - - // general register - xASM("pop r15"); - xASM("pop r14"); - xASM("pop r13"); - xASM("pop r12"); - xASM("pop r11"); - xASM("pop r10"); - xASM("pop r9"); - xASM("pop r8"); - xASM("pop rsi"); - xASM("pop rdi"); - xASM("pop rsp"); - xASM("pop rbp"); - xASM("pop rdx"); - xASM("pop rcx"); - xASM("pop rbx"); - xASM("pop rax"); - - // flags register - xASM("popfq"); - - // trick: use the 'carry_data' placeholder, as the return address - xASM("ret"); -}; - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/dummy/closure-trampoline-template-x64.S b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/dummy/closure-trampoline-template-x64.S deleted file mode 100644 index c544dc8b..00000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/dummy/closure-trampoline-template-x64.S +++ /dev/null @@ -1,17 +0,0 @@ -#if defined(ENABLE_CLOSURE_BRIDGE_TEMPLATE) - -#if defined(__WIN32__) || defined(__APPLE__) -#define cdecl(s) _##s -#else -#define cdecl(s) s -#endif - -.align 4 - - ; -closure trampoline just carray the required members from the object. - .globl - cdecl(closure_trampoline_template) cdecl(closure_trampoline_template) - : push[rip + 6 + 6] jmp[rip + 6 + 8] carry_data :.long 0.long 0 carry_handler :.long 0.long 0 - -#endif diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/helper_x64.cc b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/helper_x64.cc deleted file mode 100644 index 1f59357e..00000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/helper_x64.cc +++ /dev/null @@ -1,17 +0,0 @@ -#include "platform_detect_macro.h" -#if defined(TARGET_ARCH_X64) - -#include "dobby/dobby_internal.h" - -void set_routing_bridge_next_hop(DobbyRegisterContext *ctx, void *address) { - addr_t rsp = ctx->rsp; - - // ClosureTrampolineEntry reserved stack - addr_t entry_placeholder_stack_addr = rsp - 8; - *(addr_t *)entry_placeholder_stack_addr = (addr_t)address; -} - -void get_routing_bridge_next_hop(DobbyRegisterContext *ctx, void *address) { -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x86/ClosureTrampolineX86.cc b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x86/ClosureTrampolineX86.cc deleted file mode 100644 index c29b1908..00000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x86/ClosureTrampolineX86.cc +++ /dev/null @@ -1,44 +0,0 @@ -#include "platform_detect_macro.h" -#if defined(TARGET_ARCH_IA32) - -#include "dobby/dobby_internal.h" - -#include "core/assembler/assembler-ia32.h" - -#include "TrampolineBridge/ClosureTrampolineBridge/ClosureTrampoline.h" - -using namespace zz; -using namespace zz::x86; - -ClosureTrampolineEntry *ClosureTrampoline::CreateClosureTrampoline(void *carry_data, void *carry_handler) { - ClosureTrampolineEntry *tramp_entry = nullptr; - tramp_entry = new ClosureTrampolineEntry; - - auto tramp_size = 32; - auto tramp_mem = MemoryAllocator::SharedAllocator()->allocateExecMemory(tramp_size); - if (tramp_mem == nullptr) { - return nullptr; - } - -#define _ turbo_assembler_. -#define __ turbo_assembler_.GetCodeBuffer()-> - TurboAssembler turbo_assembler_(tramp_mem); - - int32_t offset = (int32_t)((uintptr_t)get_closure_bridge() - ((uintptr_t)tramp_mem + 18)); - - _ sub(esp, Immediate(4, 32)); - _ mov(Address(esp, 4 * 0), Immediate((int32_t)(uintptr_t)tramp_entry, 32)); - _ jmp(Immediate(offset, 32)); - - tramp_entry->address = tramp_mem; - tramp_entry->size = tramp_size; - tramp_entry->carry_data = carry_data; - tramp_entry->carry_handler = carry_handler; - - auto closure_tramp_buffer = static_cast(turbo_assembler_.GetCodeBuffer()); - DobbyCodePatch(tramp_mem, (uint8_t *)closure_tramp_buffer->GetBuffer(), closure_tramp_buffer->GetBufferSize()); - - return tramp_entry; -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x86/closure_bridge_x86.cc b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x86/closure_bridge_x86.cc deleted file mode 100644 index acc940a2..00000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x86/closure_bridge_x86.cc +++ /dev/null @@ -1,112 +0,0 @@ -#include "platform_detect_macro.h" -#if defined(TARGET_ARCH_IA32) - -#include "dobby/dobby_internal.h" - -#include "core/assembler/assembler-ia32.h" - -#include "TrampolineBridge/ClosureTrampolineBridge/common_bridge_handler.h" - -using namespace zz; -using namespace zz::x86; - -static asm_func_t closure_bridge = NULL; - -asm_func_t get_closure_bridge() { - // if already initialized, just return. - if (closure_bridge) - return closure_bridge; - -// Check if enable the inline-assembly closure_bridge_template -#if ENABLE_CLOSURE_BRIDGE_TEMPLATE - - extern void closure_bridge_tempate(); - closure_bridge = closure_bridge_template; - -#else - -// otherwise, use the Assembler build the closure_bridge -#define _ turbo_assembler_. -#define __ turbo_assembler_.GetCodeBuffer()-> - - auto pushfd = (uint8_t *)"\x9c"; - auto popfd = (uint8_t *)"\x9d"; - - TurboAssembler turbo_assembler_(0); - - // general register - _ sub(esp, Immediate(8 * 4, 32)); - _ mov(Address(esp, 4 * 0), eax); - _ mov(Address(esp, 4 * 1), ebx); - _ mov(Address(esp, 4 * 2), ecx); - _ mov(Address(esp, 4 * 3), edx); - _ mov(Address(esp, 4 * 4), ebp); - _ mov(Address(esp, 4 * 5), esp); - _ mov(Address(esp, 4 * 6), edi); - _ mov(Address(esp, 4 * 7), esi); - - // save flags register - __ EmitBuffer(pushfd, 1); - _ pop(eax); - { // save to stack - _ sub(esp, Immediate(2 * 4, 32)); - _ mov(Address(esp, 4), eax); - } - - // save origin sp - _ mov(eax, esp); - _ add(eax, Immediate(8 * 4 + 2 * 4 + 4, 32)); - { // save to stack - _ sub(esp, Immediate(2 * 4, 32)); - _ mov(Address(esp, 4), eax); - } - - // ======= Jump to UnifiedInterface Bridge Handle ======= - - // prepare args - _ sub(esp, Immediate(2 * 4, 32)); - _ mov(eax, Address(esp, 8 * 4 + 2 * 4 + 2 * 4 + 2 * 4)); - _ mov(Address(esp, 4), eax); - _ mov(eax, esp); - _ add(eax, Immediate(2 * 4, 32)); - _ mov(Address(esp, 0), eax); - - // LABEL: call_bridge - _ CallFunction(ExternalReference((void *)common_closure_bridge_handler)); - - // ======= DobbyRegisterContext Restore ======= - - // restore argument reserved stack - _ add(esp, Immediate(2 * 4, 32)); - - // restore sp placeholder stack - _ add(esp, Immediate(2 * 4, 32)); - - _ add(esp, Immediate(4, 32)); - // restore flags register - __ EmitBuffer(popfd, 1); - - // general register - _ pop(eax); - _ pop(ebx); - _ pop(ecx); - _ pop(edx); - _ pop(ebp); - _ add(esp, Immediate(4, 32)); // => pop rsp - _ pop(edi); - _ pop(esi); - - // trick: use the 'carry_data' stack(remain at closure trampoline) placeholder, as the return address - _ ret(); - - _ RelocBind(); - - auto code = AssemblyCodeBuilder::FinalizeFromTurboAssembler(&turbo_assembler_); - closure_bridge = (asm_func_t)code->addr; - - DEBUG_LOG("[closure bridge] closure bridge at %p", closure_bridge); -#endif - return closure_bridge; -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x86/helper_x86.cc b/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x86/helper_x86.cc deleted file mode 100644 index 3dac41c4..00000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x86/helper_x86.cc +++ /dev/null @@ -1,16 +0,0 @@ -#include "platform_detect_macro.h" -#if defined(TARGET_ARCH_IA32) - -#include "dobby/dobby_internal.h" - -void set_routing_bridge_next_hop(DobbyRegisterContext *ctx, void *address) { - addr_t esp = ctx->esp; - - addr_t entry_placeholder_stack_addr = esp - 4; - *(addr_t *)entry_placeholder_stack_addr = (addr_t)address; -} - -void get_routing_bridge_next_hop(DobbyRegisterContext *ctx, void *address) { -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/Trampoline.h b/app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/Trampoline.h deleted file mode 100644 index 53f3779b..00000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/Trampoline.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once - -#include "MemoryAllocator/AssemblyCodeBuilder.h" - -CodeBufferBase *GenerateNormalTrampolineBuffer(addr_t from, addr_t to); \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/arm/trampoline_arm.cc b/app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/arm/trampoline_arm.cc deleted file mode 100644 index c8c9033e..00000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/arm/trampoline_arm.cc +++ /dev/null @@ -1,62 +0,0 @@ -#include "platform_detect_macro.h" - -#if defined(TARGET_ARCH_ARM) - -#include "dobby/dobby_internal.h" - -#include "core/assembler/assembler-arm.h" -#include "core/codegen/codegen-arm.h" - -#include "InstructionRelocation/arm/InstructionRelocationARM.h" -#include "MemoryAllocator/NearMemoryAllocator.h" -#include "InterceptRouting/RoutingPlugin/RoutingPlugin.h" - -using namespace zz::arm; - -static CodeBufferBase *generate_arm_trampoline(addr32_t from, addr32_t to) { - TurboAssembler turbo_assembler_((void *)from); -#define _ turbo_assembler_. - - CodeGen codegen(&turbo_assembler_); - codegen.LiteralLdrBranch(to); - - return turbo_assembler_.GetCodeBuffer()->Copy(); -} - -CodeBufferBase *generate_thumb_trampoline(addr32_t from, addr32_t to) { - ThumbTurboAssembler thumb_turbo_assembler_((void *)from); -#undef _ -#define _ thumb_turbo_assembler_. - - _ AlignThumbNop(); - _ t2_ldr(pc, MemOperand(pc, 0)); - _ EmitAddress(to); - - return thumb_turbo_assembler_.GetCodeBuffer()->Copy(); -} - -CodeBufferBase *GenerateNormalTrampolineBuffer(addr_t from, addr_t to) { - enum ExecuteState { ARMExecuteState, ThumbExecuteState }; - - // set instruction running state - ExecuteState execute_state_; - execute_state_ = ARMExecuteState; - if ((addr_t)from % 2) { - execute_state_ = ThumbExecuteState; - } - - if (execute_state_ == ARMExecuteState) { - return generate_arm_trampoline(from, to); - } else { - // Check if needed pc align, (relative pc instructions needed 4 align) - from = from - THUMB_ADDRESS_FLAG; - return generate_thumb_trampoline(from, to); - } - return NULL; -} - -CodeBufferBase *GenerateNearTrampolineBuffer(InterceptRouting *routing, addr_t src, addr_t dst) { - return NULL; -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/arm64/trampoline_arm64.cc b/app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/arm64/trampoline_arm64.cc deleted file mode 100644 index 66eb63ce..00000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/arm64/trampoline_arm64.cc +++ /dev/null @@ -1,41 +0,0 @@ -#include "platform_detect_macro.h" -#if defined(TARGET_ARCH_ARM64) - -#include "dobby/dobby_internal.h" - -#include "core/assembler/assembler-arm64.h" -#include "core/codegen/codegen-arm64.h" - -#include "MemoryAllocator/NearMemoryAllocator.h" -#include "InstructionRelocation/arm64/InstructionRelocationARM64.h" -#include "InterceptRouting/RoutingPlugin/RoutingPlugin.h" - -using namespace zz::arm64; - -CodeBufferBase *GenerateNormalTrampolineBuffer(addr_t from, addr_t to) { - TurboAssembler turbo_assembler_((void *)from); -#define _ turbo_assembler_. - - uint64_t distance = llabs((int64_t)(from - to)); - uint64_t adrp_range = ((uint64_t)1 << (2 + 19 + 12 - 1)); - if (distance < adrp_range) { - // adrp, add, br - _ AdrpAdd(TMP_REG_0, from, to); - _ br(TMP_REG_0); - DEBUG_LOG("[trampoline] use [adrp, add, br]"); - } else { - // ldr, br, branch-address - CodeGen codegen(&turbo_assembler_); - codegen.LiteralLdrBranch((uint64_t)to); - DEBUG_LOG("[trampoline] use [ldr, br, #label]"); - } -#undef _ - - // Bind all labels - turbo_assembler_.RelocBind(); - - auto result = turbo_assembler_.GetCodeBuffer()->Copy(); - return result; -} - -#endif diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/x64/trampoline_x64.cc b/app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/x64/trampoline_x64.cc deleted file mode 100644 index 53afd439..00000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/x64/trampoline_x64.cc +++ /dev/null @@ -1,54 +0,0 @@ -#include "platform_detect_macro.h" - -#if defined(TARGET_ARCH_X64) - -#include "dobby/dobby_internal.h" - -#include "core/assembler/assembler-x64.h" -#include "core/codegen/codegen-x64.h" - -#include "InstructionRelocation/x64/InstructionRelocationX64.h" - -#include "MemoryAllocator/NearMemoryAllocator.h" -#include "InterceptRouting/RoutingPlugin/RoutingPlugin.h" - -using namespace zz::x64; - -static addr_t allocate_indirect_stub(addr_t jmp_insn_addr) { - uint32_t jmp_near_range = (uint32_t)2 * 1024 * 1024 * 1024; - auto stub_addr = (addr_t)NearMemoryAllocator::SharedAllocator()->allocateNearDataMemory(sizeof(void *), jmp_insn_addr, - jmp_near_range); - if (stub_addr == 0) { - ERROR_LOG("Not found near forward stub"); - return 0; - } - - DEBUG_LOG("forward stub: %p", stub_addr); - return stub_addr; -} - -CodeBufferBase *GenerateNormalTrampolineBuffer(addr_t from, addr_t to) { - TurboAssembler turbo_assembler_((void *)from); -#define _ turbo_assembler_. - - // allocate forward stub - auto jump_near_next_insn_addr = from + 6; - addr_t forward_stub = allocate_indirect_stub(jump_near_next_insn_addr); - if (forward_stub == 0) - return nullptr; - - *(addr_t *)forward_stub = to; - - CodeGen codegen(&turbo_assembler_); - codegen.JmpNearIndirect((addr_t)forward_stub); - - auto buffer = turbo_assembler_.GetCodeBuffer()->Copy(); - return buffer; -} - -CodeBufferBase *GenerateNearTrampolineBuffer(InterceptRouting *routing, addr_t src, addr_t dst) { - DEBUG_LOG("x64 near branch trampoline enable default"); - return nullptr; -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/x86/trampoline_x86.cc b/app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/x86/trampoline_x86.cc deleted file mode 100644 index 50b46415..00000000 --- a/app/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/x86/trampoline_x86.cc +++ /dev/null @@ -1,33 +0,0 @@ -#include "platform_detect_macro.h" -#if defined(TARGET_ARCH_IA32) - -#include "dobby/dobby_internal.h" - -#include "core/assembler/assembler-ia32.h" -#include "core/codegen/codegen-ia32.h" - -#include "InstructionRelocation/x86/InstructionRelocationX86.h" - -#include "MemoryAllocator/NearMemoryAllocator.h" -#include "InterceptRouting/RoutingPlugin/RoutingPlugin.h" - -using namespace zz::x86; - -CodeBufferBase *GenerateNormalTrampolineBuffer(addr_t from, addr_t to) { - TurboAssembler turbo_assembler_((void *)from); -#define _ turbo_assembler_. - - CodeGen codegen(&turbo_assembler_); - codegen.JmpNear((uint32_t)to); - - CodeBufferBase *result = NULL; - result = turbo_assembler_.GetCodeBuffer()->Copy(); - return result; -} - -CodeBufferBase *GenerateNearTrampolineBuffer(InterceptRouting *routing, addr_t src, addr_t dst) { - DEBUG_LOG("x86 near branch trampoline enable default"); - return NULL; -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/arch/Cpu.cc b/app/src/main/cpp/Dobby/source/core/arch/Cpu.cc deleted file mode 100644 index 07163616..00000000 --- a/app/src/main/cpp/Dobby/source/core/arch/Cpu.cc +++ /dev/null @@ -1,5 +0,0 @@ - -#include "core/arch/Cpu.h" -#include "core/arch/CpuUtils.h" - -#include "xnucxx/LiteMemOpt.h" diff --git a/app/src/main/cpp/Dobby/source/core/arch/Cpu.h b/app/src/main/cpp/Dobby/source/core/arch/Cpu.h deleted file mode 100644 index e0361a73..00000000 --- a/app/src/main/cpp/Dobby/source/core/arch/Cpu.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef CORE_ARCH_CPU_H -#define CORE_ARCH_CPU_H - -#include "CpuRegister.h" -#include "CpuFeature.h" - -#endif diff --git a/app/src/main/cpp/Dobby/source/core/arch/CpuFeature.cc b/app/src/main/cpp/Dobby/source/core/arch/CpuFeature.cc deleted file mode 100644 index d29f1761..00000000 --- a/app/src/main/cpp/Dobby/source/core/arch/CpuFeature.cc +++ /dev/null @@ -1,7 +0,0 @@ - -#include "core/arch/CpuFeature.h" -#include "logging/logging.h" - -void CpuFeatures::ClearCache(void *start, void *end) { - UNIMPLEMENTED(); -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/arch/CpuFeature.h b/app/src/main/cpp/Dobby/source/core/arch/CpuFeature.h deleted file mode 100644 index adb50ae6..00000000 --- a/app/src/main/cpp/Dobby/source/core/arch/CpuFeature.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef CORE_ARCH_CPU_FEATURE_H -#define CORE_ARCH_CPU_FEATURE_H - -#include "dobby/common.h" - -class CpuFeatures { -private: - static void FlushICache(void *start, size_t size) { - ClearCache(start, (void *)((addr_t)start + size)); - } - - static void FlushICache(void *start, void *end) { - ClearCache(start, end); - } - - static void ClearCache(void *start, void *end); -}; - -#endif diff --git a/app/src/main/cpp/Dobby/source/core/arch/CpuRegister.cc b/app/src/main/cpp/Dobby/source/core/arch/CpuRegister.cc deleted file mode 100644 index 3617e4ee..00000000 --- a/app/src/main/cpp/Dobby/source/core/arch/CpuRegister.cc +++ /dev/null @@ -1,10 +0,0 @@ - -#include "CpuRegister.h" - -constexpr RegisterBase RegisterBase::from_code(int code) { - return RegisterBase{code}; -} - -constexpr RegisterBase RegisterBase::no_reg() { - return RegisterBase{0}; -} \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/arch/CpuRegister.h b/app/src/main/cpp/Dobby/source/core/arch/CpuRegister.h deleted file mode 100644 index e12aff48..00000000 --- a/app/src/main/cpp/Dobby/source/core/arch/CpuRegister.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef CORE_ARCH_CPU_REGISTER_H -#define CORE_ARCH_CPU_REGISTER_H - -class RegisterBase { -public: - static constexpr RegisterBase from_code(int code); - - static constexpr RegisterBase no_reg(); - - virtual bool Is(const RegisterBase ®) const { - return (reg.reg_code_ == this->reg_code_); - } - - int code() const { - return reg_code_; - }; - -protected: - explicit constexpr RegisterBase(int code) : reg_code_(code) { - } - - int reg_code_; -}; - -#endif diff --git a/app/src/main/cpp/Dobby/source/core/arch/CpuUtils.h b/app/src/main/cpp/Dobby/source/core/arch/CpuUtils.h deleted file mode 100644 index 39423634..00000000 --- a/app/src/main/cpp/Dobby/source/core/arch/CpuUtils.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef CPU_UTILITY_H -#define CPU_UTILITY_H - -/* Define the default attributes for the functions in this file. */ -#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__)) - -#if defined(__i386__) || defined(__x86_64__) -static __inline__ void __DEFAULT_FN_ATTRS __cpuid(int __info[4], int __level) { - __asm__("cpuid" : "=a"(__info[0]), "=b"(__info[1]), "=c"(__info[2]), "=d"(__info[3]) : "a"(__level)); -} - -static __inline__ void __DEFAULT_FN_ATTRS __cpuidex(int __info[4], int __level, int __ecx) { - __asm__("cpuid" : "=a"(__info[0]), "=b"(__info[1]), "=c"(__info[2]), "=d"(__info[3]) : "a"(__level), "c"(__ecx)); -} -#endif - -#endif diff --git a/app/src/main/cpp/Dobby/source/core/arch/arm/constants-arm.h b/app/src/main/cpp/Dobby/source/core/arch/arm/constants-arm.h deleted file mode 100644 index b326d348..00000000 --- a/app/src/main/cpp/Dobby/source/core/arch/arm/constants-arm.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef CORE_ARCH_CONSTANTS_ARM_H -#define CORE_ARCH_CONSTANTS_ARM_H - -enum AddrMode { Offset = 0, PreIndex = 1, PostIndex = 2 }; - -enum Condition { - EQ = 0, // equal - NE = 1, // not equal - CS = 2, // carry set/unsigned higher or same - CC = 3, // carry clear/unsigned lower - MI = 4, // minus/negative - PL = 5, // plus/positive or zero - VS = 6, // overflow - VC = 7, // no overflow - HI = 8, // unsigned higher - LS = 9, // unsigned lower or same - GE = 10, // signed greater than or equal - LT = 11, // signed less than - GT = 12, // signed greater than - LE = 13, // signed less than or equal - AL = 14, // always (unconditional) - -}; - -enum Shift { - LSL = 0, // Logical shift left - LSR = 1, // Logical shift right - ASR = 2, // Arithmetic shift right - ROR = 3, // Rotate right -}; - -enum { - B0 = 1 << 0, - B4 = 1 << 4, - B5 = 1 << 5, - B6 = 1 << 6, - B7 = 1 << 7, - B8 = 1 << 8, - B9 = 1 << 9, - B10 = 1 << 10, - B12 = 1 << 12, - B14 = 1 << 14, - B15 = 1 << 15, - B16 = 1 << 16, - B17 = 1 << 17, - B18 = 1 << 18, - B19 = 1 << 19, - B20 = 1 << 20, - B21 = 1 << 21, - B22 = 1 << 22, - B23 = 1 << 23, - B24 = 1 << 24, - B25 = 1 << 25, - B26 = 1 << 26, - B27 = 1 << 27, - B28 = 1 << 28, -}; - -enum InstructionFields { - // Registers. - kRdShift = 12, - kRtShift = 12, - kRmShift = 10, - kRnShift = 16, - - // Condition - kConditionShift = 28, -}; - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/arch/arm/registers-arm.h b/app/src/main/cpp/Dobby/source/core/arch/arm/registers-arm.h deleted file mode 100644 index 88b7c2e1..00000000 --- a/app/src/main/cpp/Dobby/source/core/arch/arm/registers-arm.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef ARCH_ARM_REGISTERS -#define ARCH_ARM_REGISTERS - -#include "core/arch/arm/constants-arm.h" -#include "core/arch/Cpu.h" - -namespace zz { -namespace arm { - -#define GENERAL_REGISTERS(V) \ - V(r0) V(r1) V(r2) V(r3) V(r4) V(r5) V(r6) V(r7) V(r8) V(r9) V(r10) V(r11) V(r12) V(sp) V(lr) V(pc) - -enum RegisterCode { -#define REGISTER_CODE(R) kRegCode_##R, - GENERAL_REGISTERS(REGISTER_CODE) -#undef REGISTER_CODE - kRegAfterLast -}; - -class Register : public RegisterBase { -public: - explicit constexpr Register(int code) : RegisterBase(code) { - } - - static constexpr Register Create(int code) { - return Register(code); - } - - static constexpr Register R(int code) { - return Register(code); - } - - bool Is(const Register ®) const { - return (reg.reg_code_ == this->reg_code_); - } - - bool IsValid() const { - return (reg_code_ != 0); - } - - int code() const { - return reg_code_; - } - -private: -}; - -typedef Register CPURegister; - -#define DECLARE_REGISTER(R) constexpr Register R = Register::Create(kRegCode_##R); -GENERAL_REGISTERS(DECLARE_REGISTER) -#undef DECLARE_REGISTER - -constexpr Register no_reg = Register::Create(0); - -} // namespace arm -} // namespace zz -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/arch/arm64/constants-arm64.h b/app/src/main/cpp/Dobby/source/core/arch/arm64/constants-arm64.h deleted file mode 100644 index e72a6ed6..00000000 --- a/app/src/main/cpp/Dobby/source/core/arch/arm64/constants-arm64.h +++ /dev/null @@ -1,387 +0,0 @@ -#ifndef CORE_ARCH_CONSTANTS_ARM64_H -#define CORE_ARCH_CONSTANTS_ARM64_H - -#include "dobby/common.h" - -enum Shift { NO_SHIFT = -1, LSL = 0x0, LSR = 0x1, ASR = 0x2, ROR = 0x3, MSL = 0x4 }; - -enum Extend { NO_EXTEND = -1, UXTB = 0, UXTH = 1, UXTW = 2, UXTX = 3, SXTB = 4, SXTH = 5, SXTW = 6, SXTX = 7 }; - -enum AddrMode { Offset, PreIndex, PostIndex }; - -enum FlagsUpdate { SetFlags = 1, LeaveFlags = 0 }; - -enum InstructionFields { - - // Registers. - kRdShift = 0, - kRdBits = 5, - kRnShift = 5, - kRnBits = 5, - kRaShift = 10, - kRaBits = 5, - kRmShift = 16, - kRmBits = 5, - kRtShift = 0, - kRtBits = 5, - kRt2Shift = 10, - kRt2Bits = 5, - kRsShift = 16, - kRsBits = 5, - -}; - -#define OP(op) op -#define OP_W(op) op##_w -#define OP_X(op) op##_x -#define OP_B(op) op##_b -#define OP_H(op) op##_h -#define OP_S(op) op##_s -#define OP_D(op) op##_d -#define OP_Q(op) op##_q - -#define OPT(op, attribute) op##_##attribute -#define OPT_W(op, attribute) op##_w_##attribute -#define OPT_X(op, attribute) op##_x_##attribute -#define OPT_B(op, attribute) op##_b_##attribute -#define OPT_H(op, attribute) op##_h_##attribute -#define OPT_S(op, attribute) op##_s_##attribute -#define OPT_D(op, attribute) op##_d_##attribute -#define OPT_Q(op, attribute) op##_q_##attribute - -// ===== - -// Exception. -enum ExceptionOp { - ExceptionFixed = 0xD4000000, - ExceptionFMask = 0xFF000000, - ExceptionMask = 0xFFE0001F, - - HLT = ExceptionFixed | 0x00400000, - BRK = ExceptionFixed | 0x00200000, - SVC = ExceptionFixed | 0x00000001, - HVC = ExceptionFixed | 0x00000002, - SMC = ExceptionFixed | 0x00000003, - DCPS1 = ExceptionFixed | 0x00A00001, - DCPS2 = ExceptionFixed | 0x00A00002, - DCPS3 = ExceptionFixed | 0x00A00003 -}; - -// ===== - -// Unconditional branch. -enum UnconditionalBranchOp { - UnconditionalBranchFixed = 0x14000000, - UnconditionalBranchFixedMask = 0x7C000000, - UnconditionalBranchMask = 0xFC000000, - - B = UnconditionalBranchFixed | 0x00000000, - BL = UnconditionalBranchFixed | 0x80000000 -}; - -// ===== - -// Unconditional branch to register. -enum UnconditionalBranchToRegisterOp { - UnconditionalBranchToRegisterFixed = 0xD6000000, - UnconditionalBranchToRegisterFixedMask = 0xFE000000, - UnconditionalBranchToRegisterMask = 0xFFFFFC1F, - - BR = UnconditionalBranchToRegisterFixed | 0x001F0000, - BLR = UnconditionalBranchToRegisterFixed | 0x003F0000, - RET = UnconditionalBranchToRegisterFixed | 0x005F0000 -}; - -// ===== - -enum LoadRegLiteralOp { - LoadRegLiteralFixed = 0x18000000, - LoadRegLiteralFixedMask = 0x3B000000, - LoadRegLiteralMask = 0xFF000000, - -#define LoadRegLiteralSub(opc, V) LoadRegLiteralFixed | LeftShift(opc, 2, 30) | LeftShift(V, 1, 26) - OPT_W(LDR, literal) = LoadRegLiteralSub(0b00, 0), - OPT_X(LDR, literal) = LoadRegLiteralSub(0b01, 0), - OPT(LDRSW, literal) = LoadRegLiteralSub(0b10, 0), - OPT(PRFM, literal) = LoadRegLiteralSub(0b11, 0), - OPT_S(LDR, literal) = LoadRegLiteralSub(0b00, 1), - OPT_D(LDR, literal) = LoadRegLiteralSub(0b01, 1), - OPT_Q(LDR, literal) = LoadRegLiteralSub(0b10, 1), -}; - -// ===== - -// clang-format off -#define LOAD_STORE_OP_LIST(V) \ - V(OP_W(STRB), 0b00, 0, 0b00), \ - V(OP_W(LDRB), 0b00, 0, 0b01), \ - V(OP_X(LDRSB), 0b00, 0, 0b10), \ - V(OP_W(LDRSB), 0b00, 0, 0b11), \ - V(OP_B(STR), 0b00, 1, 0b00), \ - V(OP_B(LDR), 0b00, 1, 0b01), \ - V(OP_Q(STR), 0b00, 1, 0b10), \ - V(OP_Q(LDR), 0b00, 1, 0b11), \ - V(OP_W(STRH), 0b01, 0, 0b00), \ - V(OP_W(LDRH), 0b01, 0, 0b01), \ - V(OP_X(LDRSH), 0b01, 0, 0b10), \ - V(OP_W(LDRSH), 0b01, 0, 0b11), \ - V(OP_H(STR), 0b01, 1, 0b00), \ - V(OP_H(LDR), 0b01, 1, 0b01), \ - V(OP_W(STR), 0b10, 0, 0b00), \ - V(OP_W(LDR), 0b10, 0, 0b01), \ - V(OP(LDRSW), 0b10, 0, 0b10), \ - V(OP_S(STR), 0b10, 1, 0b00), \ - V(OP_S(LDR), 0b10, 1, 0b01), \ - V(OP_X(STR), 0b11, 0, 0b00), \ - V(OP_X(LDR), 0b11, 0, 0b01), \ - V(OP(PRFM), 0b11, 0, 0b10), \ - V(OP_D(STR), 0b11, 1, 0b00), \ - V(OP_D(LDR), 0b11, 1, 0b01), -// clang-format on - -// Load/store -enum LoadStoreOp { -#define LoadStoreOpSub(size, V, opc) LeftShift(size, 2, 30) | LeftShift(V, 1, 26) | LeftShift(opc, 2, 22) -#define LOAD_STORE(opname, size, V, opc) OP(opname) = LoadStoreOpSub(size, V, opc) - LOAD_STORE_OP_LIST(LOAD_STORE) -#undef LOAD_STORE -}; - -// Load/store register offset. -enum LoadStoreRegisterOffsetOp { - LoadStoreRegisterOffsetFixed = 0x38200800, - LoadStoreRegisterOffsetFixedMask = 0x3B200C00, - LoadStoreRegisterOffsetMask = 0xFFE00C00, - -#define LoadStoreRegisterOffsetOpSub(size, V, opc) \ - LoadStoreRegisterOffsetFixed | LeftShift(size, 2, 30) | LeftShift(V, 1, 26) | LeftShift(opc, 2, 22) -#define LOAD_STORE_REGISTER_OFFSET(opname, size, V, opc) \ - OPT(opname, register) = LoadStoreRegisterOffsetOpSub(size, V, opc) - LOAD_STORE_OP_LIST(LOAD_STORE_REGISTER_OFFSET) -#undef LOAD_STORE_REGISTER_OFFSET -}; - -// Load/store register (unscaled immediate) -enum LoadStoreUnscaledOffsetOp { - LoadStoreUnscaledOffsetFixed = 0x38000000, - LoadStoreUnscaledOffsetFixedMask = 0x3B200C00, - LoadStoreUnscaledOffsetMask = 0xFFE00C00, - -#define LoadStoreUnscaledOffsetOpSub(size, V, opc) \ - LoadStoreUnscaledOffsetFixed | LeftShift(size, 2, 30) | LeftShift(V, 1, 26) | LeftShift(opc, 2, 22) -#define LOAD_STORE_UNSCALED(opname, size, V, opc) OPT(opname, unscaled) = LoadStoreUnscaledOffsetOpSub(size, V, opc) - LOAD_STORE_OP_LIST(LOAD_STORE_UNSCALED) -#undef LOAD_STORE_UNSCALED -}; - -// Load/store unsigned offset. -enum LoadStoreUnsignedOffset { - LoadStoreUnsignedOffsetFixed = 0x39000000, - LoadStoreUnsignedOffsetFixedMask = 0x3B000000, - LoadStoreUnsignedOffsetMask = 0xFFC00000, - -#define LoadStoreUnsignedOffsetSub(size, V, opc) \ - LoadStoreUnsignedOffsetFixed | LeftShift(size, 2, 30) | LeftShift(V, 1, 26) | LeftShift(opc, 2, 22) -#define LOAD_STORE_UNSIGNED_OFFSET(opname, size, V, opc) \ - OPT(opname, unsigned) = LoadStoreUnsignedOffsetSub(size, V, opc) - LOAD_STORE_OP_LIST(LOAD_STORE_UNSIGNED_OFFSET) -#undef LOAD_STORE_UNSIGNED_OFFSET -}; - -// ===== - -// clang-format off -#define LOAD_STORE_PAIR_OP_LIST(V) \ - V(OP_W(STP), 0b00, 0, 0), \ - V(OP_W(LDP), 0b00, 0, 1), \ - V(OP_S(STP), 0b00, 1, 0), \ - V(OP_S(LDP), 0b00, 1, 1), \ - V(OP(LDPSW), 0b01, 0, 1), \ - V(OP_D(STP), 0b01, 1, 0), \ - V(OP_D(LDP), 0b01, 1, 1), \ - V(OP_X(STP), 0b10, 0, 0), \ - V(OP_X(LDP), 0b10, 0, 1), \ - V(OP_Q(STP), 0b10, 1, 0), \ - V(OP_Q(LDP), 0b10, 1, 1) -// clang-format on - -enum LoadStorePairOp { -#define LoadStorePairOpSub(opc, V, L) LeftShift(opc, 2, 30) | LeftShift(V, 1, 26) | LeftShift(L, 1, 22) -#define LOAD_STORE_PAIR(opname, opc, V, L) OP(opname) = LoadStorePairOpSub(opc, V, L) - LOAD_STORE_PAIR_OP_LIST(LOAD_STORE_PAIR) -#undef LOAD_STORE_PAIR -}; - -enum LoadStorePairOffsetOp { - LoadStorePairOffsetFixed = 0x29000000, - LoadStorePairOffsetFixedMask = 0x3B800000, - LoadStorePairOffsetMask = 0xFFC00000, - -#define LoadStorePairOffsetOpSub(opc, V, L) \ - LoadStorePairOffsetFixed | LeftShift(opc, 2, 30) | LeftShift(V, 1, 26) | LeftShift(L, 1, 22) -#define LOAD_STORE_PAIR_OFFSET(opname, opc, V, L) OPT(opname, offset) = LoadStorePairOffsetOpSub(opc, V, L) - LOAD_STORE_PAIR_OP_LIST(LOAD_STORE_PAIR_OFFSET) -#undef LOAD_STORE_PAIR_OFFSET -}; - -enum LoadStorePairPostIndexOp { - LoadStorePairPostIndexFixed = 0x28800000, - LoadStorePairPostIndexFixedMask = 0x3B800000, - LoadStorePairPostIndexMask = 0xFFC00000, - -#define LoadStorePairPostOpSub(opc, V, L) \ - LoadStorePairPostIndexFixed | LeftShift(opc, 2, 30) | LeftShift(V, 1, 26) | LeftShift(L, 1, 22) -#define LOAD_STORE_PAIR_POST_INDEX(opname, opc, V, L) OPT(opname, post) = LoadStorePairPostOpSub(opc, V, L) - LOAD_STORE_PAIR_OP_LIST(LOAD_STORE_PAIR_POST_INDEX) -#undef LOAD_STORE_PAIR_POST_INDEX -}; - -enum LoadStorePairPreIndexOp { - LoadStorePairPreIndexFixed = 0x29800000, - LoadStorePairPreIndexFixedMask = 0x3B800000, - LoadStorePairPreIndexMask = 0xFFC00000, - -#define LoadStorePairPreOpSub(opc, V, L) \ - LoadStorePairPreIndexFixed | LeftShift(opc, 2, 30) | LeftShift(V, 1, 26) | LeftShift(L, 1, 22) -#define LOAD_STORE_PAIR_PRE_INDEX(opname, opc, V, L) OPT(opname, pre) = LoadStorePairPreOpSub(opc, V, L) - LOAD_STORE_PAIR_OP_LIST(LOAD_STORE_PAIR_PRE_INDEX) -#undef LOAD_STORE_PAIR_PRE_INDEX -}; - -// ===== - -// Generic fields. -enum GenericInstrField { SixtyFourBits = 0x80000000, ThirtyTwoBits = 0x00000000, FP32 = 0x00000000, FP64 = 0x00400000 }; - -// Generic utils -// #define sf(rd) (rd.Is64Bits() ? SixtyFourBits : ThirtyTwoBits) - -// ===== - -// Move wide immediate. -enum MoveWideImmediateOp { - MoveWideImmediateFixed = 0x12800000, - MoveWideImmediateFixedMask = 0x1F800000, - MoveWideImmediateMask = 0xFF800000, - - OP(MOVN) = 0x00000000, - OP(MOVZ) = 0x40000000, - OP(MOVK) = 0x60000000, - -#define MoveWideImmediateOpSub(sf, opc) MoveWideImmediateFixed | LeftShift(sf, 1, 31) | LeftShift(opc, 2, 29) - OP_W(MOVN) = MoveWideImmediateFixed | MOVN, - OP_X(MOVN) = MoveWideImmediateFixed | MOVN | SixtyFourBits, - OP_W(MOVZ) = MoveWideImmediateFixed | MOVZ, - OP_X(MOVZ) = MoveWideImmediateFixed | MOVZ | SixtyFourBits, - OP_W(MOVK) = MoveWideImmediateFixed | MOVK, - OP_X(MOVK) = MoveWideImmediateFixed | MOVK | SixtyFourBits -}; - -// ===== - -enum AddSubImmediateOp { - AddSubImmediateFixed = 0x11000000, - AddSubImmediateFixedMask = 0x1F000000, - AddSubImmediateMask = 0xFF000000, - -#define AddSubImmediateOpSub(sf, op, S) \ - AddSubImmediateFixed | LeftShift(sf, 1, 31) | LeftShift(op, 1, 30) | LeftShift(S, 1, 29) - OPT_W(ADD, imm) = AddSubImmediateOpSub(0, 0, 0), - OPT_W(ADDS, imm) = AddSubImmediateOpSub(0, 0, 1), - OPT_W(SUB, imm) = AddSubImmediateOpSub(0, 1, 0), - OPT_W(SUBS, imm) = AddSubImmediateOpSub(0, 1, 1), - OPT_X(ADD, imm) = AddSubImmediateOpSub(1, 0, 0), - OPT_X(ADDS, imm) = AddSubImmediateOpSub(1, 0, 1), - OPT_X(SUB, imm) = AddSubImmediateOpSub(1, 1, 0), - OPT_X(SUBS, imm) = AddSubImmediateOpSub(1, 1, 1) -}; - -enum AddSubShiftedOp { - AddSubShiftedFixed = 0x0B000000, - AddSubShiftedFixedMask = 0x1F200000, - AddSubShiftedMask = 0xFF200000, - -#define AddSubShiftedOpSub(sf, op, S) \ - AddSubShiftedFixed | LeftShift(sf, 1, 31) | LeftShift(op, 1, 30) | LeftShift(S, 1, 29) - OPT_W(ADD, shift) = AddSubShiftedOpSub(0, 0, 0), - OPT_W(ADDS, shift) = AddSubShiftedOpSub(0, 0, 1), - OPT_W(SUB, shift) = AddSubShiftedOpSub(0, 1, 0), - OPT_W(SUBS, shift) = AddSubShiftedOpSub(0, 1, 1), - OPT_X(ADD, shift) = AddSubShiftedOpSub(1, 0, 0), - OPT_X(ADDS, shift) = AddSubShiftedOpSub(1, 0, 1), - OPT_X(SUB, shift) = AddSubShiftedOpSub(1, 1, 0), - OPT_X(SUBS, shift) = AddSubShiftedOpSub(1, 1, 1) -}; - -enum AddSubExtendedOp { - AddSubExtendedFixed = 0x0B200000, - AddSubExtendedFixedMask = 0x1F200000, - AddSubExtendedMask = 0xFFE00000, - -#define AddSubExtendedOpSub(sf, op, S) \ - AddSubExtendedFixed | LeftShift(sf, 1, 31) | LeftShift(op, 1, 30) | LeftShift(S, 1, 29) - OPT_W(ADD, extend) = AddSubExtendedOpSub(0, 0, 0), - OPT_W(ADDS, extend) = AddSubExtendedOpSub(0, 0, 1), - OPT_W(SUB, extend) = AddSubExtendedOpSub(0, 1, 0), - OPT_W(SUBS, extend) = AddSubExtendedOpSub(0, 1, 1), - OPT_X(ADD, extend) = AddSubExtendedOpSub(1, 0, 0), - OPT_X(ADDS, extend) = AddSubExtendedOpSub(1, 0, 1), - OPT_X(SUB, extend) = AddSubExtendedOpSub(1, 1, 0), - OPT_X(SUBS, extend) = AddSubExtendedOpSub(1, 1, 1) -}; - -// ===== - -// Logical (immediate and shifted register). -enum LogicalOp { - LogicalOpMask = 0x60200000, - NOT = 0x00200000, - AND = 0x00000000, - BIC = AND | NOT, - ORR = 0x20000000, - ORN = ORR | NOT, - EOR = 0x40000000, - EON = EOR | NOT, - ANDS = 0x60000000, - BICS = ANDS | NOT -}; - -// Logical immediate. -enum LogicalImmediateOp { - LogicalImmediateFixed = 0x12000000, - LogicalImmediateFixedMask = 0x1F800000, - LogicalImmediateMask = 0xFF800000, - -#define W_X_OP(opname, combine_fields) \ - OPT_W(opname, imm) = LogicalImmediateFixed | combine_fields | ThirtyTwoBits, \ - OPT_X(opname, imm) = LogicalImmediateFixed | combine_fields | SixtyFourBits -#define W_X_OP_LIST(V) V(AND, AND), V(ORR, ORR), V(EOR, EOR), V(ANDS, ANDS) -#undef W_X_OP -#undef W_X_OP_LIST -}; - -// Logical shifted register. -enum LogicalShiftedOp { - LogicalShiftedFixed = 0x0A000000, - LogicalShiftedFixedMask = 0x1F000000, - LogicalShiftedMask = 0xFF200000, - -#define W_X_OP(opname, combine_fields) \ - OPT_W(opname, shift) = LogicalShiftedFixed | combine_fields | ThirtyTwoBits, \ - OPT_X(opname, shift) = LogicalShiftedFixed | combine_fields | SixtyFourBits -#define W_X_OP_LIST(V) \ - V(AND, AND), V(BIC, BIC), V(ORR, ORR), V(ORN, ORN), V(EOR, EOR), V(EON, EON), V(ANDS, ANDS), V(BICS, BICS) -#undef W_X_OP -#undef W_X_OP_LIST -}; - -// PC relative addressing. -enum PCRelAddressingOp { - PCRelAddressingFixed = 0x10000000, - PCRelAddressingFixedMask = 0x1F000000, - PCRelAddressingMask = 0x9F000000, - ADR = PCRelAddressingFixed | 0x00000000, - ADRP = PCRelAddressingFixed | 0x80000000 -}; - -#endif diff --git a/app/src/main/cpp/Dobby/source/core/arch/arm64/registers-arm64.h b/app/src/main/cpp/Dobby/source/core/arch/arm64/registers-arm64.h deleted file mode 100644 index 84a6d6b9..00000000 --- a/app/src/main/cpp/Dobby/source/core/arch/arm64/registers-arm64.h +++ /dev/null @@ -1,142 +0,0 @@ -#ifndef ARCH_ARM64_REGISTERS -#define ARCH_ARM64_REGISTERS - -#include "core/arch/arm64/constants-arm64.h" -#include "core/arch/Cpu.h" - -namespace zz { -namespace arm64 { - -class CPURegister : RegisterBase { -public: - enum RegisterType { - kRegister_32, - kRegister_W = kRegister_32, - kRegister_64, - kRegister_X = kRegister_64, - kRegister, - - kVRegister, - kSIMD_FP_Register_8, - kSIMD_FP_Register_B = kSIMD_FP_Register_8, - kSIMD_FP_Register_16, - kSIMD_FP_Register_H = kSIMD_FP_Register_16, - kSIMD_FP_Register_32, - kSIMD_FP_Register_S = kSIMD_FP_Register_32, - kSIMD_FP_Register_64, - kSIMD_FP_Register_D = kSIMD_FP_Register_64, - kSIMD_FP_Register_128, - kSIMD_FP_Register_Q = kSIMD_FP_Register_128, - - kInvalid - }; - - constexpr CPURegister(int code, int size, RegisterType type) : RegisterBase(code), reg_size_(size), reg_type_(type) { - } - - static constexpr CPURegister Create(int code, int size, RegisterType type) { - return CPURegister(code, size, type); - } - - // ===== - - static constexpr CPURegister X(int code) { - return CPURegister(code, 64, kRegister_64); - } - - static constexpr CPURegister W(int code) { - return CPURegister(code, 32, kRegister_32); - } - - static constexpr CPURegister Q(int code) { - return CPURegister(code, 128, kSIMD_FP_Register_128); - } - - static constexpr CPURegister InvalidRegister() { - return CPURegister(0, 0, kInvalid); - } - - // ===== - - bool Is(const CPURegister ®) const { - return (reg.reg_code_ == this->reg_code_); - } - - bool Is64Bits() const { - return reg_size_ == 64; - } - - bool IsRegister() const { - return reg_type_ < kRegister; - } - - bool IsVRegister() const { - return reg_type_ > kVRegister; - } - - // ===== - - RegisterType type() const { - return reg_type_; - } - - int32_t code() const { - return reg_code_; - }; - -private: - RegisterType reg_type_; - int reg_size_; -}; - -typedef CPURegister Register; -typedef CPURegister VRegister; - -// clang-format off -#define GENERAL_REGISTER_CODE_LIST(R) \ - R(0) R(1) R(2) R(3) R(4) R(5) R(6) R(7) \ - R(8) R(9) R(10) R(11) R(12) R(13) R(14) R(15) \ - R(16) R(17) R(18) R(19) R(20) R(21) R(22) R(23) \ - R(24) R(25) R(26) R(27) R(28) R(29) R(30) R(31) - -#define DEFINE_REGISTER(register_class, name, ...) constexpr register_class name = register_class::Create(__VA_ARGS__) - -#define DEFINE_REGISTERS(N) \ - DEFINE_REGISTER(Register, w##N, N, 32, CPURegister::kRegister_32); \ - DEFINE_REGISTER(Register, x##N, N, 64, CPURegister::kRegister_64); - GENERAL_REGISTER_CODE_LIST(DEFINE_REGISTERS) -#undef DEFINE_REGISTERS - -#define DEFINE_VREGISTERS(N) \ - DEFINE_REGISTER(VRegister, b##N, N, 8, CPURegister::kSIMD_FP_Register_8); \ - DEFINE_REGISTER(VRegister, h##N, N, 16, CPURegister::kSIMD_FP_Register_16); \ - DEFINE_REGISTER(VRegister, s##N, N, 32, CPURegister::kSIMD_FP_Register_32); \ - DEFINE_REGISTER(VRegister, d##N, N, 64, CPURegister::kSIMD_FP_Register_64); \ - DEFINE_REGISTER(VRegister, q##N, N, 128, CPURegister::kSIMD_FP_Register_128); \ -GENERAL_REGISTER_CODE_LIST(DEFINE_VREGISTERS) -#undef DEFINE_VREGISTERS - -#undef DEFINE_REGISTER -// clang-format on - -// ===== - -constexpr Register wzr = w31; -constexpr Register xzr = x31; - -constexpr Register SP = x31; -constexpr Register wSP = w31; -constexpr Register FP = x29; -constexpr Register wFP = w29; -constexpr Register LR = x30; -constexpr Register wLR = w30; - -} // namespace arm64 -} // namespace zz - -#define W(code) CPURegister::W(code) -#define X(code) CPURegister::X(code) -#define Q(code) CPURegister::Q(code) -#define InvalidRegister CPURegister::InvalidRegister() - -#endif diff --git a/app/src/main/cpp/Dobby/source/core/arch/x64/constants-x64.h b/app/src/main/cpp/Dobby/source/core/arch/x64/constants-x64.h deleted file mode 100644 index d72f44f4..00000000 --- a/app/src/main/cpp/Dobby/source/core/arch/x64/constants-x64.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef CORE_ARCH_CONSTANTS_X64_H -#define CORE_ARCH_CONSTANTS_X64_H - -namespace zz { -namespace x64 { - -enum ScaleFactor { - TIMES_1 = 0, - TIMES_2 = 1, - TIMES_4 = 2, - TIMES_8 = 3, - TIMES_16 = 4, - TIMES_HALF_WORD_SIZE = sizeof(void *) / 2 - 1 -}; - -enum RexBits { REX_NONE = 0, REX_B = 1 << 0, REX_X = 1 << 1, REX_R = 1 << 2, REX_W = 1 << 3, REX_PREFIX = 1 << 6 }; - -} // namespace x64 -} // namespace zz - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/arch/x64/registers-x64.h b/app/src/main/cpp/Dobby/source/core/arch/x64/registers-x64.h deleted file mode 100644 index 4c7c612b..00000000 --- a/app/src/main/cpp/Dobby/source/core/arch/x64/registers-x64.h +++ /dev/null @@ -1,244 +0,0 @@ -#ifndef ARCH_X64_REGISTERS -#define ARCH_X64_REGISTERS - -#include "core/arch/x64/constants-x64.h" -#include "core/arch/Cpu.h" - -namespace zz { -namespace x64 { - -#define GENERAL_REGISTERS(V) \ - V(rax) \ - V(rcx) \ - V(rdx) \ - V(rbx) \ - V(rsp) \ - V(rbp) \ - V(rsi) \ - V(rdi) \ - V(r8) \ - V(r9) \ - V(r10) \ - V(r11) \ - V(r12) \ - V(r13) \ - V(r14) \ - V(r15) - -#define GENERAL_32_REGISTERS(V) \ - V(eax) \ - V(ecx) \ - V(edx) \ - V(ebx) \ - V(esp) \ - V(ebp) \ - V(esi) \ - V(edi) - -#define GENERAL_16_REGISTERS(V) \ - V(ax) \ - V(cx) \ - V(dx) \ - V(bx) \ - V(sp) \ - V(bp) \ - V(si) \ - V(di) - -#define GENERAL_8H_REGISTERS(V) \ - V(ah) \ - V(ch) \ - V(dh) \ - V(bh) - -#define GENERAL_8L_REGISTERS(V) \ - V(al) \ - V(cl) \ - V(dl) \ - V(bl) - -// clang-format off -enum RegisterCode { -#define REGISTER_CODE(R) kRegCode_##R, - kRegisterCodeStart8L = -1, - GENERAL_8L_REGISTERS(REGISTER_CODE) - kRegisterCodeStart8H = -1, - GENERAL_8H_REGISTERS(REGISTER_CODE) - kRegisterCodeStart16 = -1, - GENERAL_16_REGISTERS(REGISTER_CODE) - kRegisterCodeStart32 = -1, - GENERAL_32_REGISTERS(REGISTER_CODE) - kRegisterCodeStart64 = -1, - GENERAL_REGISTERS(REGISTER_CODE) -#undef REGISTER_CODE - kRegAfterLast -}; -// clang-format on - -class CPURegister : public RegisterBase { -public: - enum RegisterType { kDefault, kInvalid }; - - constexpr CPURegister(int code, int size, RegisterType type) : RegisterBase(code), reg_size_(size), reg_type_(type) { - } - - static constexpr CPURegister Create(int code, int size, RegisterType type) { - return CPURegister(code, size, type); - } - - static constexpr CPURegister from_code(int code) { - return CPURegister(code, 0, kDefault); - } - - static constexpr CPURegister InvalidRegister() { - return CPURegister(0, 0, kInvalid); - } - - bool Is64Bits() const { - return reg_size_ == 64; - } - - RegisterType type() const { - return reg_type_; - } - -public: - bool is_byte_register() const { - return reg_code_ <= 3; - } - - // Return the high bit of the register code as a 0 or 1. Used often - // when constructing the REX prefix byte. - int high_bit() const { - return reg_code_ >> 3; - } - - // Return the 3 low bits of the register code. Used when encoding registers - // in modR/M, SIB, and opcode bytes. - int low_bits() const { - return reg_code_ & 0x7; - } - - int size() { - return reg_size_; - } - -private: - RegisterType reg_type_; - int reg_size_; -}; - -typedef CPURegister Register; - -#define DECLARE_REGISTER(R) constexpr Register R = Register::Create(kRegCode_##R, 64, CPURegister::kDefault); -GENERAL_REGISTERS(DECLARE_REGISTER) -#undef DECLARE_REGISTER - -#define DECLARE_REGISTER(R) constexpr Register R = Register::Create(kRegCode_##R, 8, CPURegister::kDefault); -GENERAL_8H_REGISTERS(DECLARE_REGISTER) -#undef DECLARE_REGISTER - -#define DECLARE_REGISTER(R) constexpr Register R = Register::Create(kRegCode_##R, 8, CPURegister::kDefault); -GENERAL_8L_REGISTERS(DECLARE_REGISTER) -#undef DECLARE_REGISTER - -#define DECLARE_REGISTER(R) constexpr Register R = Register::Create(kRegCode_##R, 16, CPURegister::kDefault); -GENERAL_16_REGISTERS(DECLARE_REGISTER) -#undef DECLARE_REGISTER - -#define DECLARE_REGISTER(R) constexpr Register R = Register::Create(kRegCode_##R, 32, CPURegister::kDefault); -GENERAL_32_REGISTERS(DECLARE_REGISTER) -#undef DECLARE_REGISTER - -#ifdef _WIN64 -// Windows calling convention -constexpr Register arg_reg_1 = rcx; -constexpr Register arg_reg_2 = rdx; -constexpr Register arg_reg_3 = r8; -constexpr Register arg_reg_4 = r9; -#else -// AMD64 calling convention -constexpr Register arg_reg_1 = rdi; -constexpr Register arg_reg_2 = rsi; -constexpr Register arg_reg_3 = rdx; -constexpr Register arg_reg_4 = rcx; -#endif // _WIN64 - -#define DOUBLE_REGISTERS(V) \ - V(xmm0) \ - V(xmm1) \ - V(xmm2) \ - V(xmm3) \ - V(xmm4) \ - V(xmm5) \ - V(xmm6) \ - V(xmm7) \ - V(xmm8) \ - V(xmm9) \ - V(xmm10) \ - V(xmm11) \ - V(xmm12) \ - V(xmm13) \ - V(xmm14) \ - V(xmm15) - -#define FLOAT_REGISTERS DOUBLE_REGISTERS -#define SIMD128_REGISTERS DOUBLE_REGISTERS - -constexpr bool kPadArguments = false; -constexpr bool kSimpleFPAliasing = true; -constexpr bool kSimdMaskRegisters = false; - -enum DoubleRegisterCode { -#define REGISTER_CODE(R) kDoubleCode_##R, - DOUBLE_REGISTERS(REGISTER_CODE) -#undef REGISTER_CODE - kDoubleAfterLast -}; - -class XMMRegister : public RegisterBase { -public: - enum RegisterType { kInvalid }; - - constexpr XMMRegister(int code) : RegisterBase(code) { - } - - static constexpr XMMRegister Create(int code) { - return XMMRegister(code); - } - - static constexpr XMMRegister InvalidRegister() { - return XMMRegister(0); - } - -public: - // Return the high bit of the register code as a 0 or 1. Used often - // when constructing the REX prefix byte. - int high_bit() const { - return reg_code_ >> 3; - } - // Return the 3 low bits of the register code. Used when encoding registers - // in modR/M, SIB, and opcode bytes. - int low_bits() const { - return reg_code_ & 0x7; - } - -private: -}; - -typedef XMMRegister FloatRegister; - -typedef XMMRegister DoubleRegister; - -typedef XMMRegister Simd128Register; - -typedef XMMRegister FPURegister; - -#define DECLARE_REGISTER(R) constexpr DoubleRegister R = DoubleRegister::Create(kDoubleCode_##R); -DOUBLE_REGISTERS(DECLARE_REGISTER) -#undef DECLARE_REGISTER - -} // namespace x64 -} // namespace zz - -#endif diff --git a/app/src/main/cpp/Dobby/source/core/arch/x86/constants-x86.h b/app/src/main/cpp/Dobby/source/core/arch/x86/constants-x86.h deleted file mode 100644 index a243a76d..00000000 --- a/app/src/main/cpp/Dobby/source/core/arch/x86/constants-x86.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef CORE_ARCH_CONSTANTS_X86_H -#define CORE_ARCH_CONSTANTS_X86_H - -namespace zz { -namespace x86 { - -enum ScaleFactor { - TIMES_1 = 0, - TIMES_2 = 1, - TIMES_4 = 2, - TIMES_8 = 3, - TIMES_16 = 4, - TIMES_HALF_WORD_SIZE = sizeof(void *) / 2 - 1 -}; - -} // namespace x86 -} // namespace zz - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/arch/x86/cpu-x86.cc b/app/src/main/cpp/Dobby/source/core/arch/x86/cpu-x86.cc deleted file mode 100644 index d7005819..00000000 --- a/app/src/main/cpp/Dobby/source/core/arch/x86/cpu-x86.cc +++ /dev/null @@ -1,10 +0,0 @@ -#include "platform_detect_macro.h" -#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) - -#include "cpu-x86.h" - -X86CpuInfo::X86CpuInfo() { - -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/arch/x86/cpu-x86.h b/app/src/main/cpp/Dobby/source/core/arch/x86/cpu-x86.h deleted file mode 100644 index 68fd62c3..00000000 --- a/app/src/main/cpp/Dobby/source/core/arch/x86/cpu-x86.h +++ /dev/null @@ -1,120 +0,0 @@ -#ifndef CORE_ARCH_CPU_X86_H -#define CORE_ARCH_CPU_X86_H - -#include "core/arch/Cpu.h" - -class X86CpuInfo { - -public: - X86CpuInfo(); - -public: - // General features - bool has_fpu() const { - return has_fpu_; - } - int icache_line_size() const { - return icache_line_size_; - } - int dcache_line_size() const { - return dcache_line_size_; - } - - static const int UNKNOWN_CACHE_LINE_SIZE = 0; - - // x86 features - bool has_cmov() const { - return has_cmov_; - } - bool has_sahf() const { - return has_sahf_; - } - bool has_mmx() const { - return has_mmx_; - } - bool has_sse() const { - return has_sse_; - } - bool has_sse2() const { - return has_sse2_; - } - bool has_sse3() const { - return has_sse3_; - } - bool has_ssse3() const { - return has_ssse3_; - } - bool has_sse41() const { - return has_sse41_; - } - bool has_sse42() const { - return has_sse42_; - } - bool has_osxsave() const { - return has_osxsave_; - } - bool has_avx() const { - return has_avx_; - } - bool has_fma3() const { - return has_fma3_; - } - bool has_bmi1() const { - return has_bmi1_; - } - bool has_bmi2() const { - return has_bmi2_; - } - bool has_lzcnt() const { - return has_lzcnt_; - } - bool has_popcnt() const { - return has_popcnt_; - } - bool is_atom() const { - return is_atom_; - } - -private: - char vendor_[13]; - - // General features - int icache_line_size_; - int dcache_line_size_; - bool has_fpu_; - - // x86 features - bool has_cmov_; - bool has_sahf_; - bool has_mmx_; - bool has_sse_; - bool has_sse2_; - bool has_sse3_; - bool has_ssse3_; - bool has_sse41_; - bool has_sse42_; - bool has_osxsave_; - bool has_avx_; - bool has_fma3_; - bool has_bmi1_; - bool has_bmi2_; - bool has_lzcnt_; - bool has_popcnt_; - bool is_atom_; -}; - -class X86CpuFeatures : public CpuFeatures { -public: - static bool sse2_supported() { - return X86CpuInfo().has_sse2(); - } - static bool sse4_1_supported() { - return X86CpuInfo().has_sse41(); - } - -private: - static bool sse2_supported_; - static bool sse4_1_supported_; -}; - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/arch/x86/registers-x86.h b/app/src/main/cpp/Dobby/source/core/arch/x86/registers-x86.h deleted file mode 100644 index 65b06b2b..00000000 --- a/app/src/main/cpp/Dobby/source/core/arch/x86/registers-x86.h +++ /dev/null @@ -1,124 +0,0 @@ -#ifndef ARCH_IA32_REGISTERS -#define ARCH_IA32_REGISTERS - -#include "core/arch/x86/constants-x86.h" -#include "core/arch/Cpu.h" - -namespace zz { -namespace x86 { - -#define GENERAL_REGISTERS(V) \ - V(eax) \ - V(ecx) \ - V(edx) \ - V(ebx) \ - V(esp) \ - V(ebp) \ - V(esi) \ - V(edi) - -enum RegisterCode { -#define REGISTER_CODE(R) kRegCode_##R, - GENERAL_REGISTERS(REGISTER_CODE) -#undef REGISTER_CODE - kRegAfterLast -}; - -class CPURegister : public RegisterBase { -public: - enum RegisterType { kDefault, kInvalid }; - - constexpr CPURegister(int code, int size, RegisterType type) : RegisterBase(code), reg_size_(size), reg_type_(type) { - } - - static constexpr CPURegister Create(int code, int size, RegisterType type) { - return CPURegister(code, size, type); - } - - static constexpr CPURegister from_code(int code) { - return CPURegister(code, 0, kDefault); - } - - static constexpr CPURegister InvalidRegister() { - return CPURegister(0, 0, kInvalid); - } - - RegisterType type() const { - return reg_type_; - } - -public: - bool is_byte_register() const { - return reg_code_ <= 3; - } - - int size() { - return reg_size_; - } - -private: - RegisterType reg_type_; - int reg_size_; -}; - -typedef CPURegister Register; - -#define DEFINE_REGISTER(R) constexpr Register R = Register::Create(kRegCode_##R, 32, CPURegister::kDefault); -GENERAL_REGISTERS(DEFINE_REGISTER) -#undef DEFINE_REGISTER - -#define DOUBLE_REGISTERS(V) \ - V(xmm0) \ - V(xmm1) \ - V(xmm2) \ - V(xmm3) \ - V(xmm4) \ - V(xmm5) \ - V(xmm6) \ - V(xmm7) - -#define FLOAT_REGISTERS DOUBLE_REGISTERS -#define SIMD128_REGISTERS DOUBLE_REGISTERS - -constexpr bool kPadArguments = false; -constexpr bool kSimpleFPAliasing = true; -constexpr bool kSimdMaskRegisters = false; - -enum DoubleRegisterCode { -#define REGISTER_CODE(R) kDoubleCode_##R, - DOUBLE_REGISTERS(REGISTER_CODE) -#undef REGISTER_CODE - kDoubleAfterLast -}; - -class XMMRegister : public RegisterBase { -public: - enum RegisterType { kInvalid }; - - constexpr XMMRegister(int code) : RegisterBase(code) { - } - - static constexpr XMMRegister Create(int code) { - return XMMRegister(code); - } - - static constexpr XMMRegister InvalidRegister() { - return XMMRegister(0); - } - -private: -}; - -typedef XMMRegister FloatRegister; -typedef XMMRegister DoubleRegister; -typedef XMMRegister Simd128Register; -typedef XMMRegister FPURegister; - -#define DEFINE_REGISTER(R) constexpr DoubleRegister R = DoubleRegister::Create(kDoubleCode_##R); -DOUBLE_REGISTERS(DEFINE_REGISTER) -#undef DEFINE_REGISTER - -} // namespace x86 -} // namespace zz - -#endif diff --git a/app/src/main/cpp/Dobby/source/core/assembler/AssemblerPseudoLabel.h b/app/src/main/cpp/Dobby/source/core/assembler/AssemblerPseudoLabel.h deleted file mode 100644 index 8774774d..00000000 --- a/app/src/main/cpp/Dobby/source/core/assembler/AssemblerPseudoLabel.h +++ /dev/null @@ -1,85 +0,0 @@ -#pragma once - -#include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" - -class Label { -public: - Label(addr_t addr) : pos_(addr) { - } - -protected: - addr_t pos_; -}; - -class AssemblerPseudoLabel : public Label { -public: - typedef struct { - int link_type; - size_t pc_offset; - addr_t vmaddr_; - } ref_label_insn_t; - -public: - AssemblerPseudoLabel(addr_t addr) : Label(addr) { - ref_label_insns_.reserve(4); - - bind_to(addr); - } - - bool has_confused_instructions() { - return ref_label_insns_.size(); - } - - void link_confused_instructions(); - - void link_confused_instructions(CodeBufferBase *buffer_); - - void link_to(int link_type, uint32_t pc_offset) { - ref_label_insn_t insn; - insn.link_type = link_type; - insn.pc_offset = pc_offset; - ref_label_insns_.push_back(insn); - } - -public: - addr_t pos() { - return pos_; - }; - - void bind_to(addr_t addr) { - pos_ = addr; - } - -protected: - tinystl::vector ref_label_insns_; -}; - -struct RelocLabel : public AssemblerPseudoLabel { -public: - RelocLabel() : AssemblerPseudoLabel(0) { - memset(data_, 0, sizeof(data_)); - data_size_ = 0; - } - - template static RelocLabel *withData(T value) { - auto label = new RelocLabel(); - label->setData(value); - return label; - } - - template T data() { - return *(T *)data_; - } - - template void setData(T value) { - data_size_ = sizeof(T); - memcpy(data_, &value, data_size_); - } - - template void fixupData(T value) { - *(T *)data_ = value; - } - - uint8_t data_[8]; - int data_size_; -}; \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/assembler/assembler-arch.h b/app/src/main/cpp/Dobby/source/core/assembler/assembler-arch.h deleted file mode 100644 index 23ae9c3b..00000000 --- a/app/src/main/cpp/Dobby/source/core/assembler/assembler-arch.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef CORE_ASSEMBLER_ARCH_H -#define CORE_ASSEMBLER_ARCH_H - -#include "src/assembler.h" - -#if 0 -#if TARGET_ARCH_IA32 -#include "src/ia32/assembler-ia32.h" -#elif TARGET_ARCH_X64 -#include "src/x64/assembler-x64.h" -#elif TARGET_ARCH_ARM64 -#include "src/arm64/assembler-arm64.h" -#elif TARGET_ARCH_ARM -#include "src/arm/assembler-arm.h" -#elif TARGET_ARCH_PPC -#include "src/ppc/assembler-ppc.h" -#elif TARGET_ARCH_MIPS -#include "src/mips/assembler-mips.h" -#elif TARGET_ARCH_MIPS64 -#include "src/mips64/assembler-mips64.h" -#elif TARGET_ARCH_S390 -#include "src/s390/assembler-s390.h" -#else -#error Unknown architecture. -#endif -#endif - -#endif diff --git a/app/src/main/cpp/Dobby/source/core/assembler/assembler-arm.cc b/app/src/main/cpp/Dobby/source/core/assembler/assembler-arm.cc deleted file mode 100644 index 138db0c7..00000000 --- a/app/src/main/cpp/Dobby/source/core/assembler/assembler-arm.cc +++ /dev/null @@ -1,41 +0,0 @@ -#include "platform_detect_macro.h" -#if TARGET_ARCH_ARM - -#include "core/assembler/assembler-arm.h" - -void AssemblerPseudoLabel::link_confused_instructions(CodeBufferBase *buffer) { - CodeBuffer *_buffer = (CodeBuffer *)buffer; - - for (auto &ref_label_insn : ref_label_insns_) { - arm_inst_t inst = _buffer->LoadARMInst(ref_label_insn.pc_offset); - if (ref_label_insn.link_type == kLdrLiteral) { - int64_t pc = ref_label_insn.pc_offset + ARM_PC_OFFSET; - assert(pc % 4 == 0); - int32_t imm12 = pos() - pc; - if (imm12 > 0) { - set_bit(inst, 23, 1); - } else { - set_bit(inst, 23, 0); - imm12 = -imm12; - } - set_bits(inst, 0, 11, imm12); - } - _buffer->RewriteARMInst(ref_label_insn.pc_offset, inst); - } -} - -namespace zz { -namespace arm { - -void Assembler::EmitARMInst(arm_inst_t instr) { - buffer_->EmitARMInst(instr); -} - -void Assembler::EmitAddress(uint32_t value) { - buffer_->Emit32(value); -} - -} // namespace arm -} // namespace zz - -#endif diff --git a/app/src/main/cpp/Dobby/source/core/assembler/assembler-arm.h b/app/src/main/cpp/Dobby/source/core/assembler/assembler-arm.h deleted file mode 100644 index 46e080a4..00000000 --- a/app/src/main/cpp/Dobby/source/core/assembler/assembler-arm.h +++ /dev/null @@ -1,354 +0,0 @@ -#pragma once - -#include "dobby/common.h" - -#include "core/arch/arm/constants-arm.h" -#include "core/arch/arm/registers-arm.h" -#include "core/assembler/assembler.h" - -#include "MemoryAllocator/CodeBuffer/code_buffer_arm.h" - -enum ref_label_type_t { kLdrLiteral }; - -namespace zz { -namespace arm { - -// ARM design had a 3-stage pipeline (fetch-decode-execute) -#define ARM_PC_OFFSET 8 -#define Thumb_PC_OFFSET 4 - -// define instruction length -#define ARM_INST_LEN 4 -#define Thumb1_INST_LEN 2 -#define Thumb2_INST_LEN 4 - -// Thumb instructions address is odd -#define THUMB_ADDRESS_FLAG 1 - -constexpr Register TMP_REG_0 = r12; - -constexpr Register VOLATILE_REGISTER = r12; - -#define Rd(rd) (rd.code() << kRdShift) -#define Rt(rt) (rt.code() << kRtShift) -#define Rn(rn) (rn.code() << kRnShift) -#define Rm(rm) (rm.code() << kRmShift) - -// --- - -class Operand { - friend class OpEncode; - -public: - Operand(int immediate) : imm_(immediate), rm_(no_reg), shift_(LSL), shift_imm_(0), rs_(no_reg) { - } - - Operand(Register rm) : imm_(0), rm_(rm), shift_(LSL), shift_imm_(0), rs_(no_reg) { - } - - Operand(Register rm, Shift shift, uint32_t shift_imm) - : imm_(0), rm_(rm), shift_(shift), shift_imm_(shift_imm), rs_(no_reg) { - } - - Operand(Register rm, Shift shift, Register rs) : imm_(0), rm_(rm), shift_(shift), shift_imm_(0), rs_(rs) { - } - -public: - int GetImmediate() const { - return imm_; - } - -private: - Register rm_; - Register rs_; - - Shift shift_; - int shift_imm_; - - int imm_; - -private: - friend class EncodeUtility; -}; - -// --- - -class MemOperand { - friend class OpEncode; - -public: - MemOperand(Register rn, int32_t offset = 0, AddrMode addrmode = Offset) - : rn_(rn), offset_(offset), rm_(no_reg), shift_(LSL), shift_imm_(0), addrmode_(addrmode) { - } - - MemOperand(Register rn, Register rm, AddrMode addrmode = Offset) - : rn_(rn), offset_(0), rm_(rm), shift_(LSL), shift_imm_(0), addrmode_(addrmode) { - } - - MemOperand(Register rn, Register rm, Shift shift, uint32_t shift_imm, AddrMode addrmode = Offset) - : rn_(rn), offset_(0), rm_(rm), shift_(shift), shift_imm_(shift_imm), addrmode_(addrmode) { - } - - const Register &rn() const { - return rn_; - } - const Register &rm() const { - return rm_; - } - int32_t offset() const { - return offset_; - } - - bool IsImmediateOffset() const { - return (addrmode_ == Offset); - } - bool IsRegisterOffset() const { - return (addrmode_ == Offset); - } - bool IsPreIndex() const { - return addrmode_ == PreIndex; - } - bool IsPostIndex() const { - return addrmode_ == PostIndex; - } - -private: - Register rn_; // base - Register rm_; // register offset - - int32_t offset_; // valid if rm_ == no_reg - - Shift shift_; - uint32_t shift_imm_; // valid if rm_ != no_reg && rs_ == no_reg - - AddrMode addrmode_; // bits P, U, and W -}; - -// --- - -class OpEncode { -public: - static uint32_t MemOperand(const MemOperand operand) { - uint32_t encoding = 0; - if (operand.rm_.IsValid()) { - UNREACHABLE(); - } - - // sign - uint32_t U = 0; - if (operand.offset_ >= 0) { - U = (1 << 23); - } - encoding |= U; - - // offset - encoding |= bits(abs(operand.offset_), 0, 11); - - // addr mode - uint32_t P, W; - if (operand.addrmode_ == Offset) { - P = 1; - W = 0; - } else if (operand.addrmode_ == PostIndex) { - P = 0; - W = 0; - } else if (operand.addrmode_ == PreIndex) { - P = 1; - W = 1; - } - encoding |= ((P << 24) | (W << 21)); - - // rn - encoding |= Rn(operand.rn_); - - return encoding; - } - - static uint32_t Operand(const Operand operand) { - uint32_t encoding = 0; - if (operand.rm_.IsValid()) { - encoding = static_cast(operand.rm_.code()); - } else { - encoding = operand.GetImmediate(); - } - - return encoding; - } -}; - -// --- - -enum ExecuteState { ARMExecuteState, ThumbExecuteState }; - -class Assembler : public AssemblerBase { -private: - ExecuteState execute_state_; - -public: - Assembler(void *address) : AssemblerBase(address) { - execute_state_ = ARMExecuteState; - buffer_ = new CodeBuffer(); - } - - // shared_ptr is better choice - // but we can't use it at kernelspace - Assembler(void *address, CodeBuffer *buffer) : AssemblerBase(address) { - execute_state_ = ARMExecuteState; - buffer_ = buffer; - } - - void ClearCodeBuffer() { - buffer_ = NULL; - } - -public: - void SetExecuteState(ExecuteState state) { - execute_state_ = state; - } - ExecuteState GetExecuteState() { - return execute_state_; - } - - void SetRealizedAddress(void *address) { - DCHECK_EQ(0, reinterpret_cast(address) % 4); - AssemblerBase::SetRealizedAddress(address); - } - - void EmitARMInst(arm_inst_t instr); - - void EmitAddress(uint32_t value); - -public: - void sub(Register rd, Register rn, const Operand &operand) { - uint32_t encoding = B25 | B22; - add_sub(encoding, AL, rd, rn, operand); - } - - void add(Register rd, Register rn, const Operand &operand) { - uint32_t encoding = B25 | B23; - add_sub(encoding, AL, rd, rn, operand); - } - - void add_sub(uint32_t encoding, Condition cond, Register rd, Register rn, const Operand &operand) { - encoding |= (cond << kConditionShift); - - uint32_t imm = operand.GetImmediate(); - encoding |= imm; - - encoding |= Rd(rd); - - encoding |= Rn(rn); - - buffer_->EmitARMInst(encoding); - } - - void ldr(Register rt, const MemOperand &operand) { - uint32_t encoding = B20 | B26; - load_store(encoding, AL, rt, operand); - } - - void str(Register rt, const MemOperand &operand) { - uint32_t encoding = B26; - load_store(encoding, AL, rt, operand); - } - - void load_store(uint32_t encoding, Condition cond, Register rt, const MemOperand &operand) { - encoding |= (cond << kConditionShift); - encoding |= Rt(rt) | OpEncode::MemOperand(operand); - buffer_->EmitARMInst(encoding); - } - - void mov(Register rd, const Operand &operand) { - mov(AL, rd, operand); - } - - void mov(Condition cond, Register rd, const Operand &operand) { - uint32_t encoding = 0x01a00000; - encoding |= (cond << kConditionShift); - encoding |= Rd(rd) | OpEncode::Operand(operand); - buffer_->EmitARMInst(encoding); - } - - // Branch instructions. - void b(int branch_offset) { - b(AL, branch_offset); - } - void b(Condition cond, int branch_offset) { - uint32_t encoding = 0xa000000; - encoding |= (cond << kConditionShift); - uint32_t imm24 = bits(branch_offset >> 2, 0, 23); - encoding |= imm24; - buffer_->EmitARMInst(encoding); - } - - void bl(int branch_offset) { - bl(AL, branch_offset); - } - void bl(Condition cond, int branch_offset) { - uint32_t encoding = 0xb000000; - encoding |= (cond << kConditionShift); - uint32_t imm24 = bits(branch_offset >> 2, 0, 23); - encoding |= imm24; - buffer_->EmitARMInst(encoding); - } - - void blx(int branch_offset) { - UNIMPLEMENTED(); - } - void blx(Register target, Condition cond = AL) { - UNIMPLEMENTED(); - } - void bx(Register target, Condition cond = AL) { - UNIMPLEMENTED(); - } - -}; // namespace arm - -// --- - -class TurboAssembler : public Assembler { -public: - TurboAssembler(void *address) : Assembler(address) { - } - - ~TurboAssembler() { - } - - TurboAssembler(void *address, CodeBuffer *buffer) : Assembler(address, buffer) { - } - - void Ldr(Register rt, AssemblerPseudoLabel *label) { - if (label->pos()) { - int offset = label->pos() - buffer_->GetBufferSize(); - ldr(rt, MemOperand(pc, offset)); - } else { - // record this ldr, and fix later. - label->link_to(kLdrLiteral, buffer_->GetBufferSize()); - ldr(rt, MemOperand(pc, 0)); - } - } - - void CallFunction(ExternalReference function) { - // trick: use bl to replace lr register - bl(0); - b(4); - ldr(pc, MemOperand(pc, -4)); - buffer_->Emit32((uint32_t)(uintptr_t)function.address()); - } - - void Move32Immeidate(Register rd, const Operand &x, Condition cond = AL) { - } - - void RelocLabelFixup(tinystl::unordered_map *relocated_offset_map) { - for (auto *data_label : data_labels_) { - auto val = data_label->data(); - auto iter = relocated_offset_map->find(val); - if (iter != relocated_offset_map->end()) { - data_label->fixupData(iter->second); - } - } - } -}; - -} // namespace arm -} // namespace zz \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/assembler/assembler-arm64.cc b/app/src/main/cpp/Dobby/source/core/assembler/assembler-arm64.cc deleted file mode 100644 index e52fdc68..00000000 --- a/app/src/main/cpp/Dobby/source/core/assembler/assembler-arm64.cc +++ /dev/null @@ -1,25 +0,0 @@ -#include "platform_detect_macro.h" -#if TARGET_ARCH_ARM64 - -#include "core/assembler/assembler-arm64.h" - -void AssemblerPseudoLabel::link_confused_instructions(CodeBufferBase *buffer_) { - auto buffer = (CodeBuffer *)buffer_; - - for (auto &ref_label_insn : ref_label_insns_) { - int64_t fixup_offset = pos() - ref_label_insn.pc_offset; - - arm64_inst_t inst = buffer->LoadInst(ref_label_insn.pc_offset); - arm64_inst_t new_inst = 0; - - if (ref_label_insn.link_type == kLabelImm19) { - new_inst = encode_imm19_offset(inst, fixup_offset); - } - - buffer->RewriteInst(ref_label_insn.pc_offset, new_inst); - } -} - -using namespace zz::arm64; - -#endif diff --git a/app/src/main/cpp/Dobby/source/core/assembler/assembler-arm64.h b/app/src/main/cpp/Dobby/source/core/assembler/assembler-arm64.h deleted file mode 100644 index 70c53093..00000000 --- a/app/src/main/cpp/Dobby/source/core/assembler/assembler-arm64.h +++ /dev/null @@ -1,560 +0,0 @@ -#pragma once - -#include "dobby/dobby_internal.h" - -#include "core/arch/arm64/constants-arm64.h" -#include "core/arch/arm64/registers-arm64.h" -#include "core/assembler/assembler.h" - -#include "MemoryAllocator/CodeBuffer/code_buffer_arm64.h" - -#include "InstructionRelocation/arm64/inst_decode_encode_kit.h" - -static inline uint16_t Low16Bits(uint32_t value) { - return static_cast(value & 0xffff); -} - -static inline uint16_t High16Bits(uint32_t value) { - return static_cast(value >> 16); -} - -static inline uint32_t Low32Bits(uint64_t value) { - return static_cast(value); -} - -static inline uint32_t High32Bits(uint64_t value) { - return static_cast(value >> 32); -} - -enum ref_label_type_t { kLabelImm19 }; - -namespace zz { -namespace arm64 { - -constexpr Register TMP_REG_0 = X(ARM64_TMP_REG_NDX_0); - -#define Rd(rd) (rd.code() << kRdShift) -#define Rt(rt) (rt.code() << kRtShift) -#define Rt2(rt) (rt.code() << kRt2Shift) -#define Rn(rn) (rn.code() << kRnShift) -#define Rm(rm) (rm.code() << kRmShift) - -// --- - -class Operand { -public: - inline explicit Operand(int64_t imm) - : immediate_(imm), reg_(InvalidRegister), shift_(NO_SHIFT), extend_(NO_EXTEND), shift_extent_imm_(0) { - } - inline Operand(Register reg, Shift shift = LSL, int32_t shift_imm = 0) - : immediate_(0), reg_(reg), shift_(shift), extend_(NO_EXTEND), shift_extent_imm_(shift_imm) { - } - inline Operand(Register reg, Extend extend, int32_t shift_imm = 0) - : immediate_(0), reg_(reg), shift_(NO_SHIFT), extend_(extend), shift_extent_imm_(shift_imm) { - } - - bool IsImmediate() const { - return reg_.Is(InvalidRegister); - } - bool IsShiftedRegister() const { - return /* reg_.IsValid() && */ (shift_ != NO_SHIFT); - } - bool IsExtendedRegister() const { - return /* reg_.IsValid() && */ (extend_ != NO_EXTEND); - } - - Register reg() const { - DCHECK((IsShiftedRegister() || IsExtendedRegister())); - return reg_; - } - int64_t Immediate() const { - return immediate_; - } - Shift shift() const { - DCHECK(IsShiftedRegister()); - return shift_; - } - Extend extend() const { - DCHECK(IsExtendedRegister()); - return extend_; - } - int32_t shift_extend_imm() const { - return shift_extent_imm_; - } - -private: - int64_t immediate_; - - Register reg_; - - Shift shift_; - Extend extend_; - int32_t shift_extent_imm_; -}; - -// --- - -class MemOperand { -public: - inline explicit MemOperand(Register base, int64_t offset = 0, AddrMode addrmode = Offset) - : base_(base), regoffset_(InvalidRegister), offset_(offset), addrmode_(addrmode), shift_(NO_SHIFT), - extend_(NO_EXTEND), shift_extend_imm_(0) { - } - - inline explicit MemOperand(Register base, Register regoffset, Extend extend, unsigned extend_imm) - : base_(base), regoffset_(regoffset), offset_(0), addrmode_(Offset), shift_(NO_SHIFT), extend_(extend), - shift_extend_imm_(extend_imm) { - } - - inline explicit MemOperand(Register base, Register regoffset, Shift shift = LSL, unsigned shift_imm = 0) - : base_(base), regoffset_(regoffset), offset_(0), addrmode_(Offset), shift_(shift), extend_(NO_EXTEND), - shift_extend_imm_(shift_imm) { - } - - inline explicit MemOperand(Register base, const Operand &offset, AddrMode addrmode = Offset) - : base_(base), regoffset_(InvalidRegister), addrmode_(addrmode) { - if (offset.IsShiftedRegister()) { - regoffset_ = offset.reg(); - shift_ = offset.shift(); - shift_extend_imm_ = offset.shift_extend_imm(); - - extend_ = NO_EXTEND; - offset_ = 0; - } else if (offset.IsExtendedRegister()) { - regoffset_ = offset.reg(); - extend_ = offset.extend(); - shift_extend_imm_ = offset.shift_extend_imm(); - - shift_ = NO_SHIFT; - offset_ = 0; - } - } - - const Register &base() const { - return base_; - } - const Register ®offset() const { - return regoffset_; - } - int64_t offset() const { - return offset_; - } - AddrMode addrmode() const { - return addrmode_; - } - Shift shift() const { - return shift_; - } - Extend extend() const { - return extend_; - } - unsigned shift_extend_imm() const { - return shift_extend_imm_; - } - - bool IsImmediateOffset() const { - return (addrmode_ == Offset); - } - bool IsRegisterOffset() const { - return (addrmode_ == Offset); - } - bool IsPreIndex() const { - return addrmode_ == PreIndex; - } - bool IsPostIndex() const { - return addrmode_ == PostIndex; - } - -private: - Register base_; - Register regoffset_; - - int64_t offset_; - - Shift shift_; - Extend extend_; - uint32_t shift_extend_imm_; - - AddrMode addrmode_; -}; - -// --- - -class OpEncode { -public: - static int32_t sf(const Register ®, int32_t op) { - return (op | sf(reg)); - } - - // register operation size, 32 bits or 64 bits - static int32_t sf(const Register ®) { - if (reg.Is64Bits()) - return LeftShift(1, 1, 31); - return 0; - } - - static int32_t V(const Register ®, int32_t op) { - return (op | V(reg)); - } - - // register type, SIMD_FD register or general register - static int32_t V(const Register ®) { - if (reg.IsVRegister()) - return LeftShift(1, 1, 26); - return 0; - } - - // load or store - static int32_t L(bool load_or_store) { - if (load_or_store) { - return LeftShift(1, 1, 22); - } - return 0; - } - - // shift type - static int32_t shift(Shift shift) { - return LeftShift(shift, 2, 22); - } - - // LogicalImmeidate - static int32_t EncodeLogicalImmediate(const Register &rd, const Register &rn, const Operand &operand) { - int64_t imm = operand.Immediate(); - int32_t N, imms, immr; - immr = bits(imm, 0, 5); - imms = bits(imm, 6, 11); - N = bit(imm, 12); - - return (sf(rd) | LeftShift(immr, 6, 16) | LeftShift(imms, 6, 10) | Rd(rd) | Rn(rn)); - } - - // LogicalShift - static int32_t EncodeLogicalShift(const Register &rd, const Register &rn, const Operand &operand) { - return (sf(rd) | shift(operand.shift()) | Rm(operand.reg()) | LeftShift(operand.shift_extend_imm(), 6, 10) | - Rn(rn) | Rd(rd)); - } - - // LoadStore - static int32_t LoadStorePair(LoadStorePairOp op, CPURegister rt, CPURegister rt2, const MemOperand &addr) { - int32_t scale = 2; - int32_t opc = 0; - int imm7; - opc = bits(op, 30, 31); - if (rt.IsRegister()) { - scale += bit(opc, 1); - } else if (rt.IsVRegister()) { - scale += opc; - } - - imm7 = (int)(addr.offset() >> scale); - return LeftShift(imm7, 7, 15); - } - - // scale - static int32_t scale(int32_t op) { - int scale = 0; - if ((op & LoadStoreUnsignedOffsetFixed) == LoadStoreUnsignedOffsetFixed) { - scale = bits(op, 30, 31); - } - return scale; - } -}; - -// --- - -class Assembler : public AssemblerBase { -public: - Assembler(void *address) : AssemblerBase(address) { - buffer_ = new CodeBuffer(); - } - - ~Assembler() { - if (buffer_) - delete buffer_; - buffer_ = NULL; - } - -public: - void SetRealizedAddress(void *address) { - DCHECK_EQ(0, reinterpret_cast(address) % 4); - AssemblerBase::SetRealizedAddress(address); - } - - void Emit(uint32_t value) { - buffer_->Emit32(value); - } - - void EmitInt64(int64_t value) { - buffer_->Emit64(value); - } - - void bind(Label *label); - - void nop() { - Emit(0xD503201F); - } - - void brk(int code) { - Emit(BRK | LeftShift(code, 16, 5)); - } - - void ret() { - Emit(0xD65F03C0); - } - - void adrp(const Register &rd, int64_t imm) { - DCHECK(rd.Is64Bits()); - DCHECK((abs(imm) >> 12) < (1 << 21)); - - uint32_t immlo = LeftShift(bits(imm >> 12, 0, 1), 2, 29); - uint32_t immhi = LeftShift(bits(imm >> 12, 2, 20), 19, 5); - Emit(ADRP | Rd(rd) | immlo | immhi); - } - - void add(const Register &rd, const Register &rn, int64_t imm) { - if (rd.Is64Bits() && rn.Is64Bits()) - AddSubImmediate(rd, rn, Operand(imm), OPT_X(ADD, imm)); - else - AddSubImmediate(rd, rn, Operand(imm), OPT_W(ADD, imm)); - } - - void adds(const Register &rd, const Register &rn, int64_t imm) { - UNREACHABLE(); - } - void sub(const Register &rd, const Register &rn, int64_t imm) { - if (rd.Is64Bits() && rn.Is64Bits()) - AddSubImmediate(rd, rn, Operand(imm), OPT_X(SUB, imm)); - else - AddSubImmediate(rd, rn, Operand(imm), OPT_W(SUB, imm)); - } - void subs(const Register &rd, const Register &rn, int64_t imm) { - UNREACHABLE(); - } - - void b(int64_t imm) { - int32_t imm26 = bits(imm >> 2, 0, 25); - - Emit(B | imm26); - } - - void b(Label *label) { - int offset = LinkAndGetByteOffsetTo(label); - b(offset); - } - - void br(Register rn) { - Emit(BR | Rn(rn)); - } - - void blr(Register rn) { - Emit(BLR | Rn(rn)); - } - - void ldr(Register rt, int64_t imm) { - LoadRegLiteralOp op; - switch (rt.type()) { - case CPURegister::kRegister_32: - op = OPT_W(LDR, literal); - break; - case CPURegister::kRegister_X: - op = OPT_X(LDR, literal); - break; - case CPURegister::kSIMD_FP_Register_S: - op = OPT_S(LDR, literal); - break; - case CPURegister::kSIMD_FP_Register_D: - op = OPT_D(LDR, literal); - break; - case CPURegister::kSIMD_FP_Register_Q: - op = OPT_Q(LDR, literal); - break; - default: - UNREACHABLE(); - break; - } - EmitLoadRegLiteral(op, rt, imm); - } - - void ldr(const CPURegister &rt, const MemOperand &src) { - LoadStore(OP_X(LDR), rt, src); - } - - void str(const CPURegister &rt, const MemOperand &src) { - LoadStore(OP_X(STR), rt, src); - } - - void ldp(const Register &rt, const Register &rt2, const MemOperand &src) { - if (rt.type() == Register::kSIMD_FP_Register_128) { - LoadStorePair(OP_Q(LDP), rt, rt2, src); - } else if (rt.type() == Register::kRegister_X) { - LoadStorePair(OP_X(LDP), rt, rt2, src); - } else { - UNREACHABLE(); - } - } - - void stp(const Register &rt, const Register &rt2, const MemOperand &dst) { - if (rt.type() == Register::kSIMD_FP_Register_128) { - LoadStorePair(OP_Q(STP), rt, rt2, dst); - } else if (rt.type() == Register::kRegister_X) { - LoadStorePair(OP_X(STP), rt, rt2, dst); - } else { - UNREACHABLE(); - } - } - - void mov(const Register &rd, const Register &rn) { - if ((rd.Is(SP)) || (rn.Is(SP))) { - add(rd, rn, 0); - } else { - if (rd.Is64Bits()) - orr(rd, xzr, Operand(rn)); - else - orr(rd, wzr, Operand(rn)); - } - } - void movk(const Register &rd, uint64_t imm, int shift = -1) { - // Move and keep. - MoveWide(rd, imm, shift, MOVK); - } - void movn(const Register &rd, uint64_t imm, int shift = -1) { - // Move with non-zero. - MoveWide(rd, imm, shift, MOVN); - } - void movz(const Register &rd, uint64_t imm, int shift = -1) { - // Move with zero. - MoveWide(rd, imm, shift, MOVZ); - } - - void orr(const Register &rd, const Register &rn, const Operand &operand) { - Logical(rd, rn, operand, ORR); - } - -private: - // label helpers. - static constexpr int kStartOfLabelLinkChain = 0; - int LinkAndGetByteOffsetTo(Label *label); - - // load helpers. - void EmitLoadRegLiteral(LoadRegLiteralOp op, CPURegister rt, int64_t imm) { - const int32_t encoding = op | LeftShift(imm, 26, 5) | Rt(rt); - Emit(encoding); - } - - void LoadStore(LoadStoreOp op, CPURegister rt, const MemOperand &addr) { - int64_t imm12 = addr.offset(); - if (addr.IsImmediateOffset()) { - // TODO: check Scaled ??? - imm12 = addr.offset() >> OpEncode::scale(LoadStoreUnsignedOffsetFixed | op); - Emit(LoadStoreUnsignedOffsetFixed | op | LeftShift(imm12, 12, 10) | Rn(addr.base()) | Rt(rt)); - } else if (addr.IsRegisterOffset()) { - UNREACHABLE(); - } else { - // pre-index & post-index - UNREACHABLE(); - } - } - - void LoadStorePair(LoadStorePairOp op, CPURegister rt, CPURegister rt2, const MemOperand &addr) { - int32_t combine_fields_op = OpEncode::LoadStorePair(op, rt, rt2, addr) | Rt2(rt2) | Rn(addr.base()) | Rt(rt); - int32_t addrmodeop; - - if (addr.IsImmediateOffset()) { - addrmodeop = LoadStorePairOffsetFixed; - } else { - if (addr.IsPreIndex()) { - addrmodeop = LoadStorePairPreIndexFixed; - } else { - addrmodeop = LoadStorePairPostIndexFixed; - } - } - Emit(op | addrmodeop | combine_fields_op); - } - - void MoveWide(Register rd, uint64_t imm, int shift, MoveWideImmediateOp op) { - if (shift > 0) - shift /= 16; - else - shift = 0; - - int32_t imm16 = LeftShift(imm, 16, 5); - Emit(MoveWideImmediateFixed | op | OpEncode::sf(rd) | LeftShift(shift, 2, 21) | imm16 | Rd(rd)); - } - - void AddSubImmediate(const Register &rd, const Register &rn, const Operand &operand, AddSubImmediateOp op) { - if (operand.IsImmediate()) { - int64_t immediate = operand.Immediate(); - int32_t imm12 = LeftShift(immediate, 12, 10); - Emit(op | Rd(rd) | Rn(rn) | imm12); - } else { - UNREACHABLE(); - } - } - - void Logical(const Register &rd, const Register &rn, const Operand &operand, LogicalOp op) { - if (operand.IsImmediate()) { - LogicalImmediate(rd, rn, operand, op); - } else { - LogicalShift(rd, rn, operand, op); - } - } - void LogicalImmediate(const Register &rd, const Register &rn, const Operand &operand, LogicalOp op) { - int32_t combine_fields_op = OpEncode::EncodeLogicalImmediate(rd, rn, operand); - Emit(op | combine_fields_op); - } - void LogicalShift(const Register &rd, const Register &rn, const Operand &operand, LogicalOp op) { - int32_t combine_fields_op = OpEncode::EncodeLogicalShift(rd, rn, operand); - Emit(op | LogicalShiftedFixed | combine_fields_op); - } -}; - -// --- - -class TurboAssembler : public Assembler { -public: - TurboAssembler(void *address) : Assembler(address) { - } - - ~TurboAssembler() { - } - - void CallFunction(ExternalReference function) { - Mov(TMP_REG_0, (uint64_t)function.address()); - blr(TMP_REG_0); - } - - void Ldr(Register rt, AssemblerPseudoLabel *label) { - if (label->pos()) { - int offset = label->pos() - buffer_->GetBufferSize(); - ldr(rt, offset); - } else { - label->link_to(kLabelImm19, buffer_->GetBufferSize()); - ldr(rt, 0); - } - } - - void Mov(Register rd, uint64_t imm) { - const uint32_t w0 = Low32Bits(imm); - const uint32_t w1 = High32Bits(imm); - const uint16_t h0 = Low16Bits(w0); - const uint16_t h1 = High16Bits(w0); - const uint16_t h2 = Low16Bits(w1); - const uint16_t h3 = High16Bits(w1); - movz(rd, h0, 0); - movk(rd, h1, 16); - movk(rd, h2, 32); - movk(rd, h3, 48); - } - - void AdrpAdd(Register rd, uint64_t from, uint64_t to) { - uint64_t from_PAGE = ALIGN(from, 0x1000); - uint64_t to_PAGE = ALIGN(to, 0x1000); - uint64_t to_PAGEOFF = (uint64_t)to % 0x1000; - - adrp(rd, to_PAGE - from_PAGE); - add(rd, rd, to_PAGEOFF); - } -}; - -} // namespace arm64 -} // namespace zz \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/assembler/assembler-ia32.cc b/app/src/main/cpp/Dobby/source/core/assembler/assembler-ia32.cc deleted file mode 100644 index 12af8ede..00000000 --- a/app/src/main/cpp/Dobby/source/core/assembler/assembler-ia32.cc +++ /dev/null @@ -1,34 +0,0 @@ -#include "platform_detect_macro.h" -#if TARGET_ARCH_IA32 - -#include "core/assembler/assembler-ia32.h" - -using namespace zz::x86; - -void Assembler::jmp(Immediate imm) { - buffer_->Emit8(0xE9); - buffer_->Emit32((int)imm.value()); -} - -addr32_t TurboAssembler::CurrentIP() { - return pc_offset() + (addr_t)realized_addr_; -} - -void AssemblerPseudoLabel::link_confused_instructions(CodeBufferBase *buffer) { - auto _buffer = (CodeBuffer *)buffer; - - for (auto &ref_label_insn : ref_label_insns_) { - int64_t new_offset = pos() - ref_label_insn.pc_offset; - - if (ref_label_insn.link_type == kDisp32_off_7) { - // why 7 ? - // use `call` and `pop` get the runtime ip register - // but the ip register not the real call next insn - // it need add two insn length == 7 - int disp32_fix_pos = ref_label_insn.pc_offset - sizeof(int32_t); - _buffer->FixBindLabel(disp32_fix_pos, new_offset + 7); - } - } -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/assembler/assembler-ia32.h b/app/src/main/cpp/Dobby/source/core/assembler/assembler-ia32.h deleted file mode 100644 index 19474a3a..00000000 --- a/app/src/main/cpp/Dobby/source/core/assembler/assembler-ia32.h +++ /dev/null @@ -1,456 +0,0 @@ -#pragma once - -#include "dobby/common.h" - -#include "core/arch/x86/registers-x86.h" -#include "core/assembler/assembler.h" - -#include "MemoryAllocator/CodeBuffer/code_buffer_x86.h" - -#define IsInt8(imm) (-128 <= imm && imm <= 127) - -enum ref_label_type_t { kDisp32_off_7 }; - -namespace zz { -namespace x86 { - -constexpr Register VOLATILE_REGISTER = eax; - -#define ModRM_Mod(byte) ((byte & 0b11000000) >> 6) -#define ModRM_RegOpcode(byte) ((byte & 0b00111000) >> 3) -#define ModRM_RM(byte) (byte & 0b00000111) - -typedef union _ModRM { - byte_t ModRM; - struct { - byte_t RM : 3; - byte_t RegOpcode : 3; - byte_t Mod : 2; - }; -} ModRM; - -// --- - -class Immediate { -public: - explicit Immediate(int32_t imm) : value_(imm), value_size_(32) { - if ((int32_t)(int8_t)imm == imm) { - value_size_ = 8; - } else if ((int32_t)(int16_t)imm == imm) { - value_size_ = 16; - } else { - value_size_ = 32; - } - } - - explicit Immediate(int32_t imm, int size) : value_(imm), value_size_(size) { - } - - int32_t value() const { - return value_; - } - - int size() const { - return value_size_; - } - -private: - const int32_t value_; - - int value_size_; -}; - -// --- - -class Operand { -public: - // [base] - Operand(Register base); - - // [base + disp/r] - Operand(Register base, int32_t disp); - - // [base + index*scale + disp/r] - Operand(Register base, Register index, ScaleFactor scale, int32_t disp); - - // [index*scale + disp/r] - Operand(Register index, ScaleFactor scale, int32_t disp); - -public: // Getter and Setter - uint8_t modrm() { - return (encoding_at(0)); - } - - uint8_t mod() const { - return (encoding_at(0) >> 6) & 3; - } - - Register rm() const { - return Register::from_code(encoding_at(0) & 7); - } - - ScaleFactor scale() const { - return static_cast((encoding_at(1) >> 6) & 3); - } - - Register index() const { - return Register::from_code((encoding_at(1) >> 3) & 7); - } - - Register base() const { - return Register::from_code(encoding_at(1) & 7); - } - - int8_t disp8() const { - ASSERT(length_ >= 2); - return static_cast(encoding_[length_ - 1]); - } - - int32_t disp32() const { - ASSERT(length_ >= 5); - return static_cast(encoding_[length_ - 4]); - } - -protected: - Operand() : length_(0) { - } - - void SetModRM(int mod, Register rm) { - ASSERT((mod & ~3) == 0); - encoding_[0] = (mod << 6) | rm.code(); - length_ = 1; - } - - void SetSIB(ScaleFactor scale, Register index, Register base) { - ASSERT(length_ == 1); - ASSERT((scale & ~3) == 0); - encoding_[1] = (scale << 6) | (index.code() << 3) | base.code(); - length_ = 2; - } - - void SetDisp8(int8_t disp) { - ASSERT(length_ == 1 || length_ == 2); - encoding_[length_++] = static_cast(disp); - } - - void SetDisp32(int32_t disp) { - ASSERT(length_ == 1 || length_ == 2); - *(int32_t *)&encoding_[length_] = disp; - length_ += sizeof(disp); - } - -private: - // explicit Operand(Register reg) : rex_(REX_NONE) { SetModRM(3, reg); } - - // Get the operand encoding byte at the given index. - uint8_t encoding_at(intptr_t index) const { - ASSERT(index >= 0 && index < length_); - return encoding_[index]; - } - -public: - uint8_t length_; - uint8_t encoding_[6]; -}; - -// --- - -class Address : public Operand { -public: - Address(Register base, int32_t disp) { - int base_ = base.code(); - int ebp_ = ebp.code(); - int esp_ = esp.code(); - if ((disp == 0) && (base_ != ebp_)) { - SetModRM(0, base); - if (base_ == esp_) - SetSIB(TIMES_1, esp, base); - } else if (disp >= -128 && disp <= 127) { - SetModRM(1, base); - if (base_ == esp_) - SetSIB(TIMES_1, esp, base); - SetDisp8(disp); - } else { - SetModRM(2, base); - if (base_ == esp_) - SetSIB(TIMES_1, esp, base); - SetDisp32(disp); - } - } - - // This addressing mode does not exist. - Address(Register base, Register r); - - Address(Register index, ScaleFactor scale, int32_t disp) { - ASSERT(index.code() != rsp.code()); // Illegal addressing mode. - SetModRM(0, esp); - SetSIB(scale, index, ebp); - SetDisp32(disp); - } - - // This addressing mode does not exist. - Address(Register index, ScaleFactor scale, Register r); - - Address(Register base, Register index, ScaleFactor scale, int32_t disp) { - ASSERT(index.code() != rsp.code()); // Illegal addressing mode. - int rbp_ = ebp.code(); - if ((disp == 0) && ((base.code() & 7) != rbp_)) { - SetModRM(0, esp); - SetSIB(scale, index, base); - } else if (disp >= -128 && disp <= 127) { - SetModRM(1, esp); - SetSIB(scale, index, base); - SetDisp8(disp); - } else { - SetModRM(2, esp); - SetSIB(scale, index, base); - SetDisp32(disp); - } - } - - // This addressing mode does not exist. - Address(Register base, Register index, ScaleFactor scale, Register r); - -private: - Address(Register base, int32_t disp, bool fixed) { - ASSERT(fixed); - - SetModRM(2, base); - if (base.code() == esp.code()) { - SetSIB(TIMES_1, esp, base); - } - SetDisp32(disp); - } -}; - -// --- - -class Assembler : public AssemblerBase { -public: - Assembler(void *address) : AssemblerBase(address) { - buffer_ = new CodeBuffer(); - } - ~Assembler() { - if (buffer_) - delete buffer_; - buffer_ = NULL; - } - -public: - void Emit1(byte_t val) { - buffer_->Emit8(val); - } - - void Emit(int32_t value) { - buffer_->Emit32(value); - } - - // --- - - void EmitImmediate(Immediate imm, int imm_size) { - if (imm_size == 8) { - buffer_->Emit8((uint8_t)imm.value()); - } else if (imm_size == 32) { - buffer_->Emit32((uint32_t)imm.value()); - } else { - UNREACHABLE(); - } - } - - // --- - - // ATTENTION: - // ModR/M == 8 registers and 24 addressing mode - - void Emit_OpEn_Register_MemOperand(Register dst, Address &operand) { - EmitModRM_Update_Register(operand.modrm(), dst); - buffer_->EmitBuffer(&operand.encoding_[1], operand.length_ - 1); - } - - void Emit_OpEn_Register_RegOperand(Register dst, Register src) { - EmitModRM_Register_Register(dst, src); - } - - void Emit_OpEn_MemOperand_Immediate(uint8_t extra_opcode, Address &operand, Immediate imm) { - EmitModRM_Update_ExtraOpcode(operand.modrm(), extra_opcode); - buffer_->EmitBuffer(&operand.encoding_[1], operand.length_ - 1); - EmitImmediate(imm, imm.size()); - } - - void Emit_OpEn_RegOperand_Immediate(uint8_t extra_opcode, Register reg, Immediate imm) { - EmitModRM_ExtraOpcode_Register(extra_opcode, reg); - EmitImmediate(imm, imm.size()); - } - - void Emit_OpEn_MemOperand(uint8_t extra_opcode, Address &operand) { - EmitModRM_Update_ExtraOpcode(operand.modrm(), extra_opcode); - buffer_->EmitBuffer(&operand.encoding_[1], operand.length_ - 1); - } - - void Emit_OpEn_RegOperand(uint8_t extra_opcode, Register reg) { - EmitModRM_ExtraOpcode_Register(extra_opcode, reg); - } - - // Encoding: OI - void Emit_OpEn_OpcodeRegister_Immediate(uint8_t opcode, Register dst, Immediate imm) { - EmitOpcode_Register(opcode, dst); - EmitImmediate(imm, imm.size()); - } - - // --- - - inline void EmitModRM(uint8_t Mod, uint8_t RegOpcode, uint8_t RM) { - uint8_t ModRM = 0; - ModRM |= Mod << 6; - ModRM |= RegOpcode << 3; - ModRM |= RM; - Emit1(ModRM); - } - - void EmitModRM_ExtraOpcode_Register(uint8_t extra_opcode, Register reg) { - EmitModRM(0b11, extra_opcode, reg.code()); - } - - void EmitModRM_Register_Register(Register reg1, Register reg2) { - EmitModRM(0b11, reg1.code(), reg2.code()); - } - - // update operand's ModRM - void EmitModRM_Update_Register(uint8_t modRM, Register reg) { - EmitModRM(ModRM_Mod(modRM), reg.code(), ModRM_RM(modRM)); - } - - // update operand's ModRM - void EmitModRM_Update_ExtraOpcode(uint8_t modRM, uint8_t extra_opcode) { - EmitModRM(ModRM_Mod(modRM), extra_opcode, ModRM_RM(modRM)); - } - - // --- - - void EmitOpcode(uint8_t opcode) { - Emit1(opcode); - } - - void EmitOpcode_Register(uint8_t opcode, Register reg) { - EmitOpcode(opcode | reg.code()); - } - - // --- - - void pushfq() { - Emit1(0x9C); - } - - void jmp(Immediate imm); - - void sub(Register dst, Immediate imm) { - DCHECK_EQ(dst.size(), 32); - - EmitOpcode(0x81); - - Emit_OpEn_RegOperand_Immediate(0x5, dst, imm); - } - - void add(Register dst, Immediate imm) { - DCHECK_EQ(dst.size(), 32); - - EmitOpcode(0x81); - - Emit_OpEn_RegOperand_Immediate(0x0, dst, imm); - } - - // MOV RAX, 0x320 - // 48 c7 c0 20 03 00 00 (MI encoding) - // 48 b8 20 03 00 00 00 00 00 00 (OI encoding) - void mov(Register dst, const Immediate imm) { - Emit_OpEn_OpcodeRegister_Immediate(0xb8, dst, imm); - } - - void mov(Address dst, const Immediate imm) { - EmitOpcode(0xc7); - - Emit_OpEn_MemOperand_Immediate(0x0, dst, imm); - } - - void mov(Register dst, Address src) { - EmitOpcode(0x8B); - - Emit_OpEn_Register_MemOperand(dst, src); - } - - void mov(Address dst, Register src) { - EmitOpcode(0x89); - - Emit_OpEn_Register_MemOperand(src, dst); - } - - void mov(Register dst, Register src) { - Emit1(0x8B); - - Emit_OpEn_Register_RegOperand(dst, src); - } - - void call(Address operand) { - EmitOpcode(0xFF); - - Emit_OpEn_MemOperand(0x2, operand); - } - - void call(Immediate imm) { - EmitOpcode(0xe8); - - EmitImmediate(imm, imm.size()); - } - - void call(Register reg) { - EmitOpcode(0xFF); - - Emit_OpEn_RegOperand(0x2, reg); - } - - void pop(Register reg) { - EmitOpcode_Register(0x58, reg); - } - - void push(Register reg) { - EmitOpcode_Register(0x50, reg); - } - - void ret() { - EmitOpcode(0xc3); - } - void nop() { - EmitOpcode(0x90); - } -}; - -class TurboAssembler : public Assembler { -public: - TurboAssembler(void *address) : Assembler(address) { - } - - ~TurboAssembler() { - } - - addr32_t CurrentIP(); - - void CallFunction(ExternalReference function) { - nop(); - MovRipToRegister(VOLATILE_REGISTER); - call(Address(VOLATILE_REGISTER, INT32_MAX)); - { - auto label = RelocLabel::withData(function.address()); - label->link_to(kDisp32_off_7, ip_offset()); - AppendRelocLabel(label); - } - nop(); - } - - void MovRipToRegister(Register dst) { - call(Immediate(0, 32)); - pop(dst); - } -}; - -} // namespace x86 -} // namespace zz \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/assembler/assembler-x64.cc b/app/src/main/cpp/Dobby/source/core/assembler/assembler-x64.cc deleted file mode 100644 index 8441a11d..00000000 --- a/app/src/main/cpp/Dobby/source/core/assembler/assembler-x64.cc +++ /dev/null @@ -1,34 +0,0 @@ -#include "platform_detect_macro.h" -#if defined(TARGET_ARCH_X64) - -#include "core/assembler/assembler-x64.h" - -using namespace zz::x64; - -void AssemblerPseudoLabel::link_confused_instructions(CodeBufferBase *buffer) { - CodeBuffer *_buffer = (CodeBuffer *)buffer; - - for (auto &ref_label_insn : ref_label_insns_) { - int64_t new_offset = pos() - ref_label_insn.pc_offset; - - if (ref_label_insn.link_type == kDisp32_off_9) { - // why 9 ? - // use `call` and `pop` get the runtime ip register - // but the ip register not the real call next insn - // it need add two insn length == 9 - int disp32_fix_pos = ref_label_insn.pc_offset - sizeof(int32_t); - _buffer->FixBindLabel(disp32_fix_pos, new_offset + 9); - } - } -} - -void Assembler::jmp(Immediate imm) { - buffer_->Emit8(0xE9); - buffer_->Emit32((int)imm.value()); -} - -addr64_t TurboAssembler::CurrentIP() { - return pc_offset() + (addr_t)realized_addr_; -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/assembler/assembler-x64.h b/app/src/main/cpp/Dobby/source/core/assembler/assembler-x64.h deleted file mode 100644 index f94d94d7..00000000 --- a/app/src/main/cpp/Dobby/source/core/assembler/assembler-x64.h +++ /dev/null @@ -1,596 +0,0 @@ -#pragma once - -#include "dobby/common.h" - -#include "core/arch/x64/registers-x64.h" -#include "core/assembler/assembler.h" - -#include "MemoryAllocator/CodeBuffer/code_buffer_x64.h" - -#define IsInt8(imm) (-128 <= imm && imm <= 127) - -enum ref_label_type_t { kDisp32_off_9 }; - -namespace zz { -namespace x64 { - -constexpr Register VOLATILE_REGISTER = r11; - -#define ModRM_Mod(byte) ((byte & 0b11000000) >> 6) -#define ModRM_RegOpcode(byte) ((byte & 0b00111000) >> 3) -#define ModRM_RM(byte) (byte & 0b00000111) - -typedef union _ModRM { - byte_t ModRM; - struct { - byte_t RM : 3; - byte_t RegOpcode : 3; - byte_t Mod : 2; - }; -} ModRM; - -// --- - -class Immediate { -public: - explicit Immediate(int64_t imm) : value_(imm), value_size_(64) { - if ((int64_t)(int8_t)imm == imm) { - value_size_ = 8; - } else if ((int64_t)(int16_t)imm == imm) { - value_size_ = 8; - } else if ((int64_t)(int32_t)imm == imm) { - value_size_ = 32; - } else { - value_size_ = 64; - } - } - - explicit Immediate(int64_t imm, int size) : value_(imm), value_size_(size) { - } - - int64_t value() const { - return value_; - } - - int size() const { - return value_size_; - } - -private: - const int64_t value_; - - int value_size_; -}; - -// --- - -class Operand { -public: - // [base] - Operand(Register base); - - // [base + disp/r] - Operand(Register base, int32_t disp); - - // [base + index*scale + disp/r] - Operand(Register base, Register index, ScaleFactor scale, int32_t disp); - - // [index*scale + disp/r] - Operand(Register index, ScaleFactor scale, int32_t disp); - -public: // Getter and Setter - uint8_t rex() const { - return rex_; - } - - inline uint8_t rex_b() const { - return (rex_ & REX_B); - } - - inline uint8_t rex_x() const { - return (rex_ & REX_X); - } - - inline uint8_t rex_r() const { - return (rex_ & REX_R); - } - - inline uint8_t rex_w() const { - return (rex_ & REX_W); - } - - uint8_t modrm() { - return (encoding_at(0)); - } - - uint8_t mod() const { - return (encoding_at(0) >> 6) & 3; - } - - Register rm() const { - int rm_rex = rex_b() << 3; - return Register::from_code(rm_rex + (encoding_at(0) & 7)); - } - - ScaleFactor scale() const { - return static_cast((encoding_at(1) >> 6) & 3); - } - - Register index() const { - int index_rex = rex_x() << 2; - return Register::from_code(index_rex + ((encoding_at(1) >> 3) & 7)); - } - - Register base() const { - int base_rex = rex_b() << 3; - return Register::from_code(base_rex + (encoding_at(1) & 7)); - } - - int8_t disp8() const { - ASSERT(length_ >= 2); - return static_cast(encoding_[length_ - 1]); - } - - int32_t disp32() const { - ASSERT(length_ >= 5); - return static_cast(encoding_[length_ - 4]); - } - -protected: - Operand() : length_(0), rex_(REX_NONE) { - } // Needed by subclass Address. - - void SetModRM(int mod, Register rm) { - ASSERT((mod & ~3) == 0); - - if ((rm.code() > 7) && !((rm.Is(r12)) && (mod != 3))) { - rex_ |= REX_B; - } - encoding_[0] = (mod << 6) | (rm.code() & 7); - length_ = 1; - } - - void SetSIB(ScaleFactor scale, Register index, Register base) { - ASSERT(length_ == 1); - ASSERT((scale & ~3) == 0); - - if (base.code() > 7) { - ASSERT((rex_ & REX_B) == 0); // Must not have REX.B already set. - rex_ |= REX_B; - } - if (index.code() > 7) - rex_ |= REX_X; - - encoding_[1] = (scale << 6) | ((index.code() & 7) << 3) | (base.code() & 7); - length_ = 2; - } - - void SetDisp8(int8_t disp) { - ASSERT(length_ == 1 || length_ == 2); - - encoding_[length_++] = static_cast(disp); - } - - void SetDisp32(int32_t disp) { - ASSERT(length_ == 1 || length_ == 2); - - *(int32_t *)&encoding_[length_] = disp; - length_ += sizeof(disp); - } - -private: - // explicit Operand(Register reg) : rex_(REX_NONE) { SetModRM(3, reg); } - - // Get the operand encoding byte at the given index. - uint8_t encoding_at(intptr_t index) const { - ASSERT(index >= 0 && index < length_); - return encoding_[index]; - } - -public: - uint8_t length_; - uint8_t rex_; - uint8_t encoding_[6]; -}; - -// --- - -class Address : public Operand { -public: - Address(Register base, int32_t disp) { - int base_ = base.code(); - int rbp_ = rbp.code(); - int rsp_ = rsp.code(); - if ((disp == 0) && ((base_ & 7) != rbp_)) { - SetModRM(0, base); - if ((base_ & 7) == rsp_) { - SetSIB(TIMES_1, rsp, base); - } - } else if (IsInt8(disp)) { - SetModRM(1, base); - if ((base_ & 7) == rsp_) { - SetSIB(TIMES_1, rsp, base); - } - SetDisp8(disp); - } else { - SetModRM(2, base); - if ((base_ & 7) == rsp_) { - SetSIB(TIMES_1, rsp, base); - } - SetDisp32(disp); - } - } - - // This addressing mode does not exist. - Address(Register base, Register r); - - Address(Register index, ScaleFactor scale, int32_t disp) { - ASSERT(index.code() != rsp.code()); // Illegal addressing mode. - SetModRM(0, rsp); - SetSIB(scale, index, rbp); - SetDisp32(disp); - } - - // This addressing mode does not exist. - Address(Register index, ScaleFactor scale, Register r); - - Address(Register base, Register index, ScaleFactor scale, int32_t disp) { - ASSERT(index.code() != rsp.code()); // Illegal addressing mode. - int rbp_ = rbp.code(); - if ((disp == 0) && ((base.code() & 7) != rbp_)) { - SetModRM(0, rsp); - SetSIB(scale, index, base); - } else if (IsInt8(disp)) { - SetModRM(1, rsp); - SetSIB(scale, index, base); - SetDisp8(disp); - } else { - SetModRM(2, rsp); - SetSIB(scale, index, base); - SetDisp32(disp); - } - } - - // This addressing mode does not exist. - Address(Register base, Register index, ScaleFactor scale, Register r); - -private: - Address(Register base, int32_t disp, bool fixed) { - ASSERT(fixed); - - SetModRM(2, base); - if ((base.code() & 7) == rsp.code()) { - SetSIB(TIMES_1, rsp, base); - } - SetDisp32(disp); - } -}; - -// --- - -class Assembler : public AssemblerBase { -public: - Assembler(void *address) : AssemblerBase(address) { - buffer_ = new CodeBuffer(); - } - ~Assembler() { - if (buffer_) - delete buffer_; - buffer_ = NULL; - } - -public: - void Emit1(byte_t val) { - buffer_->Emit8(val); - } - - void Emit(int32_t value) { - buffer_->Emit32(value); - } - - void EmitInt64(int64_t value) { - buffer_->Emit64(value); - } - - // --- - - // refer android_art - uint8_t EmitOptionalRex(bool force, bool w, bool r, bool x, bool b) { - // REX.WRXB - // W - 64-bit operand - // R - MODRM.reg - // X - SIB.index - // B - MODRM.rm/SIB.base - - uint8_t rex = force ? 0x40 : 0; - if (w) { - rex |= 0x48; // REX.W000 - } - if (r) { - rex |= 0x44; // REX.0R00 - } - if (x) { - rex |= 0x42; // REX.00X0 - } - if (b) { - rex |= 0x41; // REX.000B - } - if (rex != 0) { - return rex; - } - return 0; - } - - void Emit_64REX(uint8_t extra) { - uint8_t rex = EmitOptionalRex(false, true, false, false, false); - rex |= extra; - if (rex) - Emit1(rex); - } - - void EmitREX_ExtraRegister(Register reg) { - uint8_t rex = EmitOptionalRex(false, reg.size() == 64, reg.code() > 7, false, reg.code() > 7); - if (rex) - Emit1(rex); - } - - void EmitREX_Register(Register reg) { - uint8_t rex = EmitOptionalRex(false, reg.size() == 64, reg.code() > 7, false, false); - if (rex) - Emit1(rex); - } - - void EmitREX_Register_Operand(Register reg, Operand &operand) { - if (reg.size() != 64) - UNIMPLEMENTED(); - uint8_t rex = operand.rex(); - rex |= EmitOptionalRex(true, reg.size() == 64, reg.code() > 7, false, false); - if (rex != 0) { - Emit1(rex); - } - } - - void EmitREX_Operand(Operand &operand) { - uint8_t rex = operand.rex(); - rex |= REX_PREFIX; - if (rex != 0) { - Emit1(rex); - } - } - - // --- - - void EmitImmediate(Immediate imm, int imm_size) { - if (imm_size == 8) { - buffer_->Emit8((uint8_t)imm.value()); - } else if (imm_size == 32) { - buffer_->Emit32((uint32_t)imm.value()); - } else if (imm_size == 64) { - buffer_->Emit64((uint64_t)imm.value()); - } else { - UNREACHABLE(); - } - } - - // --- - - // ATTENTION: - // ModR/M == 8 registers and 24 addressing mode - - void Emit_OpEn_Register_MemOperand(Register dst, Address &operand) { - EmitModRM_Update_Register(operand.modrm(), dst); - buffer_->EmitBuffer(&operand.encoding_[1], operand.length_ - 1); - } - - void Emit_OpEn_Register_RegOperand(Register dst, Register src) { - EmitModRM_Register_Register(dst, src); - } - - void Emit_OpEn_MemOperand_Immediate(uint8_t extra_opcode, Address &operand, Immediate imm) { - EmitModRM_Update_ExtraOpcode(operand.modrm(), extra_opcode); - buffer_->EmitBuffer(&operand.encoding_[1], operand.length_ - 1); - EmitImmediate(imm, imm.size()); - } - - void Emit_OpEn_RegOperand_Immediate(uint8_t extra_opcode, Register reg, Immediate imm) { - EmitModRM_ExtraOpcode_Register(extra_opcode, reg); - EmitImmediate(imm, imm.size()); - } - - void Emit_OpEn_MemOperand(uint8_t extra_opcode, Address &operand) { - EmitModRM_Update_ExtraOpcode(operand.modrm(), extra_opcode); - buffer_->EmitBuffer(&operand.encoding_[1], operand.length_ - 1); - } - - void Emit_OpEn_RegOperand(uint8_t extra_opcode, Register reg) { - EmitModRM_ExtraOpcode_Register(extra_opcode, reg); - } - - // Encoding: OI - void Emit_OpEn_OpcodeRegister_Immediate(uint8_t opcode, Register dst, Immediate imm) { - EmitOpcode_Register(opcode, dst); - EmitImmediate(imm, imm.size()); - } - - // --- - - inline void EmitModRM(uint8_t Mod, uint8_t RegOpcode, uint8_t RM) { - uint8_t ModRM = 0; - ModRM |= Mod << 6; - ModRM |= RegOpcode << 3; - ModRM |= RM; - Emit1(ModRM); - } - - void EmitModRM_ExtraOpcode_Register(uint8_t extra_opcode, Register reg) { - EmitModRM(0b11, extra_opcode, reg.code()); - } - - void EmitModRM_Register_Register(Register reg1, Register reg2) { - EmitModRM(0b11, reg1.code(), reg2.code()); - } - - // update operand's ModRM - void EmitModRM_Update_Register(uint8_t modRM, Register reg) { - EmitModRM(ModRM_Mod(modRM), reg.low_bits(), ModRM_RM(modRM)); - } - - // update operand's ModRM - void EmitModRM_Update_ExtraOpcode(uint8_t modRM, uint8_t extra_opcode) { - EmitModRM(ModRM_Mod(modRM), extra_opcode, ModRM_RM(modRM)); - } - - // --- - - void EmitOpcode(uint8_t opcode) { - Emit1(opcode); - } - - void EmitOpcode_Register(uint8_t opcode, Register reg) { - EmitOpcode(opcode | reg.low_bits()); - } - - // --- - - void pushfq() { - Emit1(0x9C); - } - - void jmp(Immediate imm); - - void sub(Register dst, Immediate imm) { - EmitREX_Register(dst); - - EmitOpcode(0x81); - - Emit_OpEn_RegOperand_Immediate(0x5, dst, imm); - } - - void add(Register dst, Immediate imm) { - EmitREX_Register(dst); - - EmitOpcode(0x81); - - Emit_OpEn_RegOperand_Immediate(0x0, dst, imm); - } - - // MOV RAX, 0x320 - // 48 c7 c0 20 03 00 00 (MI encoding) - // 48 b8 20 03 00 00 00 00 00 00 (OI encoding) - void mov(Register dst, const Immediate imm) { - EmitREX_Register(dst); - - Emit_OpEn_OpcodeRegister_Immediate(0xb8, dst, imm); - } - - void mov(Address dst, const Immediate imm) { - EmitREX_Operand(dst); - - EmitOpcode(0xc7); - - Emit_OpEn_MemOperand_Immediate(0x0, dst, imm); - } - - void mov(Register dst, Address src) { - EmitREX_Register(dst); - - EmitOpcode(0x8B); - - Emit_OpEn_Register_MemOperand(dst, src); - } - - void mov(Address dst, Register src) { - EmitREX_Register_Operand(src, dst); - - EmitOpcode(0x89); - - Emit_OpEn_Register_MemOperand(src, dst); - } - - void mov(Register dst, Register src) { - EmitREX_Register(dst); - - Emit1(0x8B); - - Emit_OpEn_Register_RegOperand(dst, src); - } - - void call(Address operand) { - EmitREX_Operand(operand); - - EmitOpcode(0xFF); - - Emit_OpEn_MemOperand(0x2, operand); - } - - void call(Immediate imm) { - EmitOpcode(0xe8); - - EmitImmediate(imm, imm.size()); - } - - void call(Register reg) { - EmitREX_Register(reg); - - EmitOpcode(0xFF); - - Emit_OpEn_RegOperand(0x2, reg); - } - - void pop(Register reg) { - EmitREX_ExtraRegister(reg); - - EmitOpcode_Register(0x58, reg); - } - - void push(Register reg) { - EmitREX_ExtraRegister(reg); - - EmitOpcode_Register(0x50, reg); - } - - void ret() { - EmitOpcode(0xc3); - } - void nop() { - EmitOpcode(0x90); - } -}; - -// --- - -class TurboAssembler : public Assembler { -public: - TurboAssembler(void *address) : Assembler(address) { - } - - ~TurboAssembler() { - } - - addr64_t CurrentIP(); - - void CallFunction(ExternalReference function) { -#if 0 - mov(r11, Immediate((int64_t)function.address(), 64)); - call(r11); -#endif - - nop(); - MovRipToRegister(VOLATILE_REGISTER); - call(Address(VOLATILE_REGISTER, INT32_MAX)); - { - auto label = RelocLabel::withData((uint64_t)function.address()); - label->link_to(kDisp32_off_9, ip_offset()); - this->AppendRelocLabel(label); - } - nop(); - } - - void MovRipToRegister(Register dst) { - call(Immediate(0, 32)); - pop(dst); - } -}; - -} // namespace x64 -} // namespace zz diff --git a/app/src/main/cpp/Dobby/source/core/assembler/assembler-x86-shared.cc b/app/src/main/cpp/Dobby/source/core/assembler/assembler-x86-shared.cc deleted file mode 100644 index e81e063d..00000000 --- a/app/src/main/cpp/Dobby/source/core/assembler/assembler-x86-shared.cc +++ /dev/null @@ -1,17 +0,0 @@ -#include "platform_detect_macro.h" -#if defined(TARGET_ARCH_X64) || defined(TARGET_ARCH_IA32) - -#include "core/assembler/assembler-x86-shared.h" - -using namespace zz::x86shared; - -void Assembler::jmp(Immediate imm) { - buffer_->Emit8(0xE9); - buffer_->Emit32((int)imm.value()); -} - -uint64_t TurboAssembler::CurrentIP() { - return pc_offset() + (addr_t)realized_addr_; -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/assembler/assembler-x86-shared.h b/app/src/main/cpp/Dobby/source/core/assembler/assembler-x86-shared.h deleted file mode 100644 index 2dcd87c6..00000000 --- a/app/src/main/cpp/Dobby/source/core/assembler/assembler-x86-shared.h +++ /dev/null @@ -1,707 +0,0 @@ -#pragma once - -#include "dobby/common.h" - -#include "core/arch/x64/registers-x64.h" -#include "core/assembler/assembler.h" - -#include "MemoryAllocator/CodeBuffer/code_buffer_x64.h" - -#include "xnucxx/LiteMutableArray.h" -#include "xnucxx/LiteIterator.h" - -#define IsInt8(imm) (-128 <= imm && imm <= 127) - -namespace zz { -namespace x86shared { - -using namespace x64; - -constexpr Register VOLATILE_REGISTER = r11; - -// ================================================================ -// AssemblerPseudoLabel - -class AssemblerPseudoLabel : public Label { -public: - enum PseudoLabelType { kDisp32_off_9 }; - - typedef struct _PseudoLabelInstruction { - int position_; - PseudoLabelType type_; - } PseudoLabelInstruction; - -public: - AssemblerPseudoLabel(void) { - instructions_.initWithCapacity(8); - } - ~AssemblerPseudoLabel(void) { - for (size_t i = 0; i < instructions_.getCount(); i++) { - PseudoLabelInstruction *item = (PseudoLabelInstruction *)instructions_.getObject(i); - delete item; - } - - instructions_.release(); - } - - bool has_confused_instructions() { - return instructions_.getCount() > 0; - } - - void link_confused_instructions(CodeBuffer *buffer = nullptr) { - if (!buffer) - UNREACHABLE(); - CodeBuffer *_buffer = buffer; - - for (size_t i = 0; i < instructions_.getCount(); i++) { - PseudoLabelInstruction *instruction = (PseudoLabelInstruction *)instructions_.getObject(i); - - int32_t offset = pos() - instruction->position_; - - switch (instruction->type_) { - case kDisp32_off_9: { - int disp32_fix_pos = instruction->position_ - sizeof(int32_t); - _buffer->FixBindLabel(disp32_fix_pos, offset + 9); - } break; - default: - UNREACHABLE(); - break; - } - } - }; - - void link_to(int pos, PseudoLabelType type) { - PseudoLabelInstruction *instruction = new PseudoLabelInstruction; - instruction->position_ = pos; - instruction->type_ = type; - instructions_.pushObject((LiteObject *)instruction); - } - -private: - LiteMutableArray instructions_; -}; - -class RelocLabel : public AssemblerPseudoLabel { -public: - explicit RelocLabel(uint64_t data) : data_size_(0) { - data_ = data; - } - - uint64_t data() { - return data_; - } - -private: - uint64_t data_; - - int data_size_; -}; - -#define ModRM_Mod(byte) ((byte & 0b11000000) >> 6) -#define ModRM_RegOpcode(byte) ((byte & 0b00111000) >> 3) -#define ModRM_RM(byte) (byte & 0b00000111) - -typedef union _ModRM { - byte_t ModRM; - struct { - byte_t RM : 3; - byte_t RegOpcode : 3; - byte_t Mod : 2; - }; -} ModRM; - -// ================================================================ -// Immediate - -class Immediate { -public: - explicit Immediate(int64_t imm) : value_(imm), value_size_(64) { - if ((int64_t)(int8_t)imm == imm) { - value_size_ = 8; - } else if ((int64_t)(int16_t)imm == imm) { - value_size_ = 8; - } else if ((int64_t)(int32_t)imm == imm) { - value_size_ = 32; - } else { - value_size_ = 64; - } - } - - explicit Immediate(int64_t imm, int size) : value_(imm), value_size_(size) { - } - - int64_t value() const { - return value_; - } - - int size() const { - return value_size_; - } - -private: - const int64_t value_; - - int value_size_; -}; - -// ================================================================ -// Operand - -class Operand { -public: - // [base] - Operand(Register base); - - // [base + disp/r] - Operand(Register base, int32_t disp); - - // [base + index*scale + disp/r] - Operand(Register base, Register index, ScaleFactor scale, int32_t disp); - - // [index*scale + disp/r] - Operand(Register index, ScaleFactor scale, int32_t disp); - -public: // Getter and Setter - uint8_t rex() const { - return rex_; - } - - inline uint8_t rex_b() const { - return (rex_ & REX_B); - } - - inline uint8_t rex_x() const { - return (rex_ & REX_X); - } - - inline uint8_t rex_r() const { - return (rex_ & REX_R); - } - - inline uint8_t rex_w() const { - return (rex_ & REX_W); - } - - uint8_t modrm() { - return (encoding_at(0)); - } - - uint8_t mod() const { - return (encoding_at(0) >> 6) & 3; - } - - Register rm() const { - int rm_rex = rex_b() << 3; - return Register::from_code(rm_rex + (encoding_at(0) & 7)); - } - - ScaleFactor scale() const { - return static_cast((encoding_at(1) >> 6) & 3); - } - - Register index() const { - int index_rex = rex_x() << 2; - return Register::from_code(index_rex + ((encoding_at(1) >> 3) & 7)); - } - - Register base() const { - int base_rex = rex_b() << 3; - return Register::from_code(base_rex + (encoding_at(1) & 7)); - } - - int8_t disp8() const { - ASSERT(length_ >= 2); - return static_cast(encoding_[length_ - 1]); - } - - int32_t disp32() const { - ASSERT(length_ >= 5); - return static_cast(encoding_[length_ - 4]); - } - -protected: - Operand() : length_(0), rex_(REX_NONE) { - } // Needed by subclass Address. - - void SetModRM(int mod, Register rm) { - ASSERT((mod & ~3) == 0); - - if ((rm.code() > 7) && !((rm.Is(r12)) && (mod != 3))) { - rex_ |= REX_B; - } - encoding_[0] = (mod << 6) | (rm.code() & 7); - length_ = 1; - } - - void SetSIB(ScaleFactor scale, Register index, Register base) { - ASSERT(length_ == 1); - ASSERT((scale & ~3) == 0); - - if (base.code() > 7) { - ASSERT((rex_ & REX_B) == 0); // Must not have REX.B already set. - rex_ |= REX_B; - } - if (index.code() > 7) - rex_ |= REX_X; - encoding_[1] = (scale << 6) | ((index.code() & 7) << 3) | (base.code() & 7); - length_ = 2; - } - - void SetDisp8(int8_t disp) { - ASSERT(length_ == 1 || length_ == 2); - - encoding_[length_++] = static_cast(disp); - } - - void SetDisp32(int32_t disp) { - ASSERT(length_ == 1 || length_ == 2); - - *(int32_t *)&encoding_[length_] = disp; - length_ += sizeof(disp); - } - -private: - // explicit Operand(Register reg) : rex_(REX_NONE) { SetModRM(3, reg); } - - // Get the operand encoding byte at the given index. - uint8_t encoding_at(intptr_t index) const { - ASSERT(index >= 0 && index < length_); - return encoding_[index]; - } - -public: - uint8_t length_; - uint8_t rex_; - uint8_t encoding_[6]; -}; - -// ================================================================ -// Address - -class Address : public Operand { -public: - Address(Register base, int32_t disp) { - int base_ = base.code(); - int rbp_ = rbp.code(); - int rsp_ = rsp.code(); - if ((disp == 0) && ((base_ & 7) != rbp_)) { - SetModRM(0, base); - if ((base_ & 7) == rsp_) { - SetSIB(TIMES_1, rsp, base); - } - } else if (IsInt8(disp)) { - SetModRM(1, base); - if ((base_ & 7) == rsp_) { - SetSIB(TIMES_1, rsp, base); - } - SetDisp8(disp); - } else { - SetModRM(2, base); - if ((base_ & 7) == rsp_) { - SetSIB(TIMES_1, rsp, base); - } - SetDisp32(disp); - } - } - - // This addressing mode does not exist. - Address(Register base, Register r); - - Address(Register index, ScaleFactor scale, int32_t disp) { - ASSERT(index.code() != rsp.code()); // Illegal addressing mode. - SetModRM(0, rsp); - SetSIB(scale, index, rbp); - SetDisp32(disp); - } - - // This addressing mode does not exist. - Address(Register index, ScaleFactor scale, Register r); - - Address(Register base, Register index, ScaleFactor scale, int32_t disp) { - ASSERT(index.code() != rsp.code()); // Illegal addressing mode. - int rbp_ = rbp.code(); - if ((disp == 0) && ((base.code() & 7) != rbp_)) { - SetModRM(0, rsp); - SetSIB(scale, index, base); - } else if (IsInt8(disp)) { - SetModRM(1, rsp); - SetSIB(scale, index, base); - SetDisp8(disp); - } else { - SetModRM(2, rsp); - SetSIB(scale, index, base); - SetDisp32(disp); - } - } - - // This addressing mode does not exist. - Address(Register base, Register index, ScaleFactor scale, Register r); - -private: - Address(Register base, int32_t disp, bool fixed) { - ASSERT(fixed); - SetModRM(2, base); - if ((base.code() & 7) == rsp.code()) { - SetSIB(TIMES_1, rsp, base); - } - SetDisp32(disp); - } -}; - -// ================================================================ -// Assembler - -class Assembler : public AssemblerBase { -public: - Assembler(void *address, int mode) : AssemblerBase(address) : mode_(mode) { - buffer_ = new CodeBuffer(); - } - ~Assembler() { - if (buffer_) - delete buffer_; - buffer_ = NULL - } - -public: - void Emit1(byte_t val) { - buffer_->Emit8(val); - } - - void Emit(int32_t value) { - buffer_->Emit32(value); - } - - void EmitInt64(int64_t value) { - buffer_->Emit64(value); - } - - void EmitAddr(uint64_t addr) { - if (mode == 64) { - EmitInt64(int64_t)addr); - } else { - EmitI((int32_t)addr); - } - } - - // ================================================================ - // REX - - // refer android_art - uint8_t EmitOptionalRex(bool force, bool w, bool r, bool x, bool b) { - // REX.WRXB - // W - 64-bit operand - // R - MODRM.reg - // X - SIB.index - // B - MODRM.rm/SIB.base - - uint8_t rex = force ? 0x40 : 0; - if (w) { - rex |= 0x48; // REX.W000 - } - if (r) { - rex |= 0x44; // REX.0R00 - } - if (x) { - rex |= 0x42; // REX.00X0 - } - if (b) { - rex |= 0x41; // REX.000B - } - if (rex != 0) { - return rex; - } - return 0; - } - - void Emit_64REX(uint8_t extra) { - uint8_t rex = EmitOptionalRex(false, true, false, false, false); - rex |= extra; - if (rex) - Emit1(rex); - } - - void EmitREX_ExtraRegister(Register reg) { - uint8_t rex = EmitOptionalRex(false, reg.size() == 64, reg.code() > 7, false, reg.code() > 7); - if (rex) - Emit1(rex); - } - - void EmitREX_Register(Register reg) { - uint8_t rex = EmitOptionalRex(false, reg.size() == 64, reg.code() > 7, false, false); - if (rex) - Emit1(rex); - } - - void EmitREX_Register_Operand(Register reg, Operand &operand) { - if (reg.size() != 64) - UNIMPLEMENTED(); - uint8_t rex = operand.rex(); - rex |= EmitOptionalRex(true, reg.size() == 64, reg.code() > 7, false, false); - if (rex != 0) { - Emit1(rex); - } - } - - void EmitREX_Operand(Operand &operand) { - uint8_t rex = operand.rex(); - rex |= REX_PREFIX; - if (rex != 0) { - Emit1(rex); - } - } - - // ================================================================ - // Immediate - - void EmitImmediate(Immediate imm, int imm_size) { - if (imm_size == 8) { - buffer_->Emit8((uint8_t)imm.value()); - } else if (imm_size == 32) { - buffer_->Emit32((uint32_t)imm.value()); - } else if (imm_size == 64) { - buffer_->Emit64((uint64_t)imm.value()); - } else { - UNREACHABLE(); - } - } - - // ================================================================ - // Operand Encoding - - // ATTENTION: - // ModR/M == 8 registers and 24 addressing mode - - // RM or MR - void Emit_OpEn_Register_MemOperand(Register dst, Address &operand) { - EmitModRM_Update_Register(operand.modrm(), dst); - buffer_->EmitBuffer(&operand.encoding_[1], operand.length_ - 1); - } - void Emit_OpEn_Register_RegOperand(Register dst, Register src) { - EmitModRM_Register_Register(dst, src); - } - - void Emit_OpEn_MemOperand_Immediate(uint8_t extra_opcode, Address &operand, Immediate imm) { - } - void Emit_OpEn_RegOperand_Immediate(uint8_t extra_opcode, Register reg, Immediate imm) { - EmitModRM_ExtraOpcode_Register(extra_opcode, reg); - EmitImmediate(imm, imm.size()); - } - - void Emit_OpEn_MemOperand(uint8_t extra_opcode, Address &operand) { - EmitModRM_Update_ExtraOpcode(operand.modrm(), extra_opcode); - buffer_->EmitBuffer(&operand.encoding_[1], operand.length_ - 1); - } - void Emit_OpEn_RegOperand(uint8_t extra_opcode, Register reg) { - EmitModRM_ExtraOpcode_Register(extra_opcode, reg); - } - - // Encoding: OI - void Emit_OpEn_OpcodeRegister_Immediate(uint8_t opcode, Register dst, Immediate imm) { - EmitOpcode_Register(opcode, dst); - EmitImmediate(imm, imm.size()); - } - - // ================================================================ - // ModRM - - inline void EmitModRM(uint8_t Mod, uint8_t RegOpcode, uint8_t RM) { - uint8_t ModRM = 0; - ModRM |= Mod << 6; - ModRM |= RegOpcode << 3; - ModRM |= RM; - Emit1(ModRM); - } - - void EmitModRM_ExtraOpcode_Register(uint8_t extra_opcode, Register reg) { - EmitModRM(0b11, extra_opcode, reg.code()); - } - - void EmitModRM_Register_Register(Register reg1, Register reg2) { - EmitModRM(0b11, reg1.code(), reg2.code()); - } - - // update operand's ModRM - void EmitModRM_Update_Register(uint8_t modRM, Register reg) { - EmitModRM(ModRM_Mod(modRM), reg.low_bits(), ModRM_RM(modRM)); - } - - // update operand's ModRM - void EmitModRM_Update_ExtraOpcode(uint8_t modRM, uint8_t extra_opcode) { - EmitModRM(ModRM_Mod(modRM), extra_opcode, ModRM_RM(modRM)); - } - - // ================================================================ - // Opcode - void EmitOpcode(uint8_t opcode) { - Emit1(opcode); - } - - void EmitOpcode_Register(uint8_t opcode, Register reg) { - EmitOpcode(opcode | reg.low_bits()); - } - - // ================================================================ - // Instruction - - void pushfq() { - Emit1(0x9C); - } - - void jmp(Immediate imm); - - void sub(Register dst, Immediate imm) { - EmitREX_Register(dst); - EmitOpcode(0x81); - Emit_OpEn_RegOperand_Immediate(0x5, dst, imm); - } - - void add(Register dst, Immediate imm) { - EmitREX_Register(dst); - EmitOpcode(0x81); - Emit_OpEn_RegOperand_Immediate(0x0, dst, imm); - } - - // MOV RAX, 0x320 - // 48 c7 c0 20 03 00 00 (MI encoding) - // 48 b8 20 03 00 00 00 00 00 00 (OI encoding) - void mov(Register dst, const Immediate imm) { - EmitREX_Register(dst); - - // OI encoding - Emit_OpEn_OpcodeRegister_Immediate(0xb8, dst, imm); - } - - void mov(Register dst, Address src) { - EmitREX_Register(dst); - - EmitOpcode(0x8B); - - Emit_OpEn_Register_MemOperand(dst, src); - } - - void mov(Address dst, Register src) { - EmitREX_Register_Operand(src, dst); - EmitOpcode(0x89); - Emit_OpEn_Register_MemOperand(src, dst); - } - - void mov(Register dst, Register src) { - EmitREX_Register(dst); - - Emit1(0x8B); - - Emit_OpEn_Register_RegOperand(dst, src); - } - - void call(Address operand) { - EmitREX_Operand(operand); - - EmitOpcode(0xFF); - - Emit_OpEn_MemOperand(0x2, operand); - } - - void call(Immediate imm) { - EmitOpcode(0xe8); - EmitImmediate(imm, imm.size()); - } - - void call(Register reg) { - EmitREX_Register(reg); - EmitOpcode(0xFF); - Emit_OpEn_RegOperand(0x2, reg); - } - - void pop(Register reg) { - EmitREX_ExtraRegister(reg); - EmitOpcode_Register(0x58, reg); - } - - void push(Register reg) { - EmitREX_ExtraRegister(reg); - EmitOpcode_Register(0x50, reg); - } - - void ret() { - EmitOpcode(0xc3); - } - void nop() { - EmitOpcode(0x90); - } - -private: - int mode_; -}; - -// ================================================================ -// TurboAssembler - -class TurboAssembler : public Assembler { -public: - TurboAssembler(void *address, int mode) : Assembler(address, mode) { - data_labels_ = NULL; - } - - addr64_t CurrentIP(); - - void CallFunction(ExternalReference function) { -#if 0 - mov(r11, Immediate((int64_t)function.address(), 64)); - call(r11); -#endif - - nop(); - MovRipToRegister(VOLATILE_REGISTER); - call(Address(VOLATILE_REGISTER, INT32_MAX)); - { - RelocLabel *addrLabel = new RelocLabel((uint64_t)function.address()); - addrLabel->link_to(ip_offset(), AssemblerPseudoLabel::kDisp32_off_9); - this->AppendRelocLabel(addrLabel); - } - nop(); - } - - void MovRipToRegister(Register dst) { - call(Immediate(0, 32)); - pop(dst); - } - - // ================================================================ - // RelocLabel - - void PseudoBind(AssemblerPseudoLabel *label) { - const addr_t bound_pc = buffer_->GetBufferSize(); - label->bind_to(bound_pc); - // If some instructions have been wrote, before the label bound, we need link these `confused` instructions - if (label->has_confused_instructions()) { - label->link_confused_instructions(reinterpret_cast(this->GetCodeBuffer())); - } - } - - void RelocBind() { - if (data_labels_ == NULL) - return; - for (size_t i = 0; i < data_labels_->getCount(); i++) { - RelocLabel *label = (RelocLabel *)data_labels_->getObject(i); - PseudoBind(label); - EmitAddr(label->data()); - } - } - - void AppendRelocLabel(RelocLabel *label) { - if (data_labels_ == NULL) { - data_labels_ = new LiteMutableArray(8); - } - data_labels_->pushObject((LiteObject *)label); - } - - LiteMutableArray *GetLabels() { - return data_labels_; - } - -private: - LiteMutableArray *data_labels_; -}; - -} // namespace x86shared -} // namespace zz \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/assembler/assembler.cc b/app/src/main/cpp/Dobby/source/core/assembler/assembler.cc deleted file mode 100644 index 30192bfd..00000000 --- a/app/src/main/cpp/Dobby/source/core/assembler/assembler.cc +++ /dev/null @@ -1,64 +0,0 @@ -#include "core/assembler/assembler.h" -#include "logging/logging.h" - -namespace zz { - -const void *ExternalReference::address() { - return address_; -} - -AssemblerBase::AssemblerBase(void *address) { - realized_addr_ = address; - buffer_ = nullptr; -} - -AssemblerBase::~AssemblerBase() { - buffer_ = nullptr; -} - -size_t AssemblerBase::ip_offset() const { - return reinterpret_cast(buffer_)->GetBufferSize(); -} - -size_t AssemblerBase::pc_offset() const { - return reinterpret_cast(buffer_)->GetBufferSize(); -} - -CodeBuffer *AssemblerBase::GetCodeBuffer() { - return buffer_; -} - -void AssemblerBase::PseudoBind(AssemblerPseudoLabel *label) { - auto pc_offset = reinterpret_cast(buffer_)->GetBufferSize(); - label->bind_to(pc_offset); - if (label->has_confused_instructions()) { - label->link_confused_instructions(reinterpret_cast(buffer_)); - } -} - -void AssemblerBase::RelocBind() { - for (auto *data_label : data_labels_) { - PseudoBind(data_label); - reinterpret_cast(buffer_)->EmitBuffer(data_label->data_, data_label->data_size_); - } -} - -void AssemblerBase::AppendRelocLabel(RelocLabel *label) { - data_labels_.push_back(label); -} - -void AssemblerBase::SetRealizedAddress(void *address) { - realized_addr_ = address; -} - -void *AssemblerBase::GetRealizedAddress() { - return realized_addr_; -} - -void AssemblerBase::FlushICache(addr_t start, int size) { -} - -void AssemblerBase::FlushICache(addr_t start, addr_t end) { -} - -} // namespace zz diff --git a/app/src/main/cpp/Dobby/source/core/assembler/assembler.h b/app/src/main/cpp/Dobby/source/core/assembler/assembler.h deleted file mode 100644 index e3e22dfb..00000000 --- a/app/src/main/cpp/Dobby/source/core/assembler/assembler.h +++ /dev/null @@ -1,74 +0,0 @@ -#pragma once - -#include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" - -#include "AssemblerPseudoLabel.h" - -class CodeBuffer; - -namespace zz { - -class ExternalReference { -public: - explicit ExternalReference(void *address) : address_(address) { -#if defined(__APPLE__) && __arm64e__ - address_ = pac_strip((void *)address_); -#endif - } - - const void *address(); - -private: - const void *address_; -}; - -class AssemblerBase { -public: - explicit AssemblerBase(void *address); - - ~AssemblerBase(); - - size_t ip_offset() const; - - size_t pc_offset() const; - - CodeBuffer *GetCodeBuffer(); - - void PseudoBind(AssemblerPseudoLabel *label); - - void RelocBind(); - - void AppendRelocLabel(RelocLabel *label); - -protected: - tinystl::vector data_labels_; - -public: - virtual void *GetRealizedAddress(); - - virtual void SetRealizedAddress(void *address); - - static void FlushICache(addr_t start, int size); - - static void FlushICache(addr_t start, addr_t end); - -protected: - CodeBuffer *buffer_; - - void *realized_addr_; -}; - -} // namespace zz - -#if 0 -#include "globals.h" -#if TARGET_ARCH_ARM -#include "core/assembler/assembler-arm.h" -#elif TARGET_ARCH_ARM64 -#include "core/assembler/assembler-arm64.h" -#elif TARGET_ARCH_X64 -#include "core/assembler/assembler-x64.h" -#else -#error "unsupported architecture" -#endif -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/codegen/codegen-arm.cc b/app/src/main/cpp/Dobby/source/core/codegen/codegen-arm.cc deleted file mode 100644 index 926d901b..00000000 --- a/app/src/main/cpp/Dobby/source/core/codegen/codegen-arm.cc +++ /dev/null @@ -1,19 +0,0 @@ -#include "platform_detect_macro.h" -#if defined(TARGET_ARCH_ARM) - -#include "core/codegen/codegen-arm.h" - -namespace zz { -namespace arm { - -void CodeGen::LiteralLdrBranch(uint32_t address) { - TurboAssembler *turbo_assembler_ = reinterpret_cast(this->assembler_); -#define _ turbo_assembler_-> - _ ldr(pc, MemOperand(pc, -4)); - turbo_assembler_->GetCodeBuffer()->Emit32((addr_t)address); -} - -} // namespace arm -} // namespace zz - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/codegen/codegen-arm.h b/app/src/main/cpp/Dobby/source/core/codegen/codegen-arm.h deleted file mode 100644 index 9f87202a..00000000 --- a/app/src/main/cpp/Dobby/source/core/codegen/codegen-arm.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef CORE_CODEGEN_ARM_H -#define CORE_CODEGEN_ARM_H - -#include "core/codegen/codegen.h" -#include "core/assembler/assembler.h" -#include "core/assembler/assembler-arm.h" - -namespace zz { -namespace arm { - -class CodeGen : public CodeGenBase { -public: - CodeGen(TurboAssembler *turbo_assembler) : CodeGenBase(turbo_assembler) { - } - - void LiteralLdrBranch(uint32_t address); -}; - -} // namespace arm -} // namespace zz - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/codegen/codegen-arm64.cc b/app/src/main/cpp/Dobby/source/core/codegen/codegen-arm64.cc deleted file mode 100644 index 8e827182..00000000 --- a/app/src/main/cpp/Dobby/source/core/codegen/codegen-arm64.cc +++ /dev/null @@ -1,26 +0,0 @@ -#include "platform_detect_macro.h" -#if defined(TARGET_ARCH_ARM64) - -#include "dobby/dobby_internal.h" -#include "core/codegen/codegen-arm64.h" - -namespace zz { -namespace arm64 { - -void CodeGen::LiteralLdrBranch(uint64_t address) { - auto turbo_assembler_ = reinterpret_cast(this->assembler_); -#define _ turbo_assembler_-> - - auto label = RelocLabel::withData(address); - turbo_assembler_->AppendRelocLabel(label); - - _ Ldr(TMP_REG_0, label); - _ br(TMP_REG_0); - -#undef _ -} - -} // namespace arm64 -} // namespace zz - -#endif diff --git a/app/src/main/cpp/Dobby/source/core/codegen/codegen-arm64.h b/app/src/main/cpp/Dobby/source/core/codegen/codegen-arm64.h deleted file mode 100644 index 99dafb35..00000000 --- a/app/src/main/cpp/Dobby/source/core/codegen/codegen-arm64.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef CORE_CODEGEN_ARM64_H -#define CORE_CODEGEN_ARM64_H - -#include "core/codegen/codegen.h" -#include "core/assembler/assembler.h" -#include "core/assembler/assembler-arm64.h" - -namespace zz { -namespace arm64 { - -class CodeGen : public CodeGenBase { -public: - CodeGen(TurboAssembler *turbo_assembler) : CodeGenBase(turbo_assembler) { - } - void LiteralLdrBranch(uint64_t address); -}; - -} // namespace arm64 -} // namespace zz - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/codegen/codegen-ia32.cc b/app/src/main/cpp/Dobby/source/core/codegen/codegen-ia32.cc deleted file mode 100644 index 821137f8..00000000 --- a/app/src/main/cpp/Dobby/source/core/codegen/codegen-ia32.cc +++ /dev/null @@ -1,23 +0,0 @@ -#include "platform_detect_macro.h" -#if defined(TARGET_ARCH_IA32) - -#include "core/codegen/codegen-ia32.h" - -namespace zz { -namespace x86 { - -void CodeGen::JmpNear(uint32_t address) { - TurboAssembler *turbo_assembler_ = reinterpret_cast(this->assembler_); -#define _ turbo_assembler_-> -#define __ turbo_assembler_->GetCodeBuffer()-> - uint32_t currIP = turbo_assembler_->CurrentIP() + 5; - int32_t offset = (int32_t)(address - currIP); - - __ Emit8(0xe9); - __ Emit32(offset); -} - -} // namespace x86 -} // namespace zz - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/codegen/codegen-ia32.h b/app/src/main/cpp/Dobby/source/core/codegen/codegen-ia32.h deleted file mode 100644 index 5ad42bcd..00000000 --- a/app/src/main/cpp/Dobby/source/core/codegen/codegen-ia32.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef CORE_CODEGEN_X86_H -#define CORE_CODEGEN_X86_H - -#include "core/codegen/codegen.h" -#include "core/assembler/assembler.h" -#include "core/assembler/assembler-ia32.h" - -namespace zz { -namespace x86 { - -class CodeGen : public CodeGenBase { -public: - CodeGen(TurboAssembler *turbo_assembler) : CodeGenBase(turbo_assembler) { - } - - void JmpNear(uint32_t address); -}; - -} // namespace x86 -} // namespace zz - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/codegen/codegen-x64.cc b/app/src/main/cpp/Dobby/source/core/codegen/codegen-x64.cc deleted file mode 100644 index ad6d6609..00000000 --- a/app/src/main/cpp/Dobby/source/core/codegen/codegen-x64.cc +++ /dev/null @@ -1,25 +0,0 @@ -#include "platform_detect_macro.h" -#if defined(TARGET_ARCH_X64) - -#include "core/codegen/codegen-x64.h" - -namespace zz { -namespace x64 { - -void CodeGen::JmpNearIndirect(addr_t forward_stub_addr) { - TurboAssembler *turbo_assembler_ = reinterpret_cast(this->assembler_); -#define _ turbo_assembler_-> -#define __ turbo_assembler_->GetCodeBuffer()-> - uint64_t currIP = turbo_assembler_->CurrentIP() + 6; - int32_t offset = (int32_t)(forward_stub_addr - currIP); - - // jmp *(rip + disp32) - __ Emit8(0xFF); - __ Emit8(0x25); // ModR/M: 00 100 101 - __ Emit32(offset); -} - -} // namespace x64 -} // namespace zz - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/codegen/codegen-x64.h b/app/src/main/cpp/Dobby/source/core/codegen/codegen-x64.h deleted file mode 100644 index 5fbbc1f2..00000000 --- a/app/src/main/cpp/Dobby/source/core/codegen/codegen-x64.h +++ /dev/null @@ -1,22 +0,0 @@ -#ifndef CORE_CODEGEN_X64_H -#define CORE_CODEGEN_X64_H - -#include "core/codegen/codegen.h" -#include "core/assembler/assembler.h" -#include "core/assembler/assembler-x64.h" - -namespace zz { -namespace x64 { - -class CodeGen : public CodeGenBase { -public: - CodeGen(TurboAssembler *turbo_assembler) : CodeGenBase(turbo_assembler) { - } - - void JmpNearIndirect(addr_t forward_stub_addr); -}; - -} // namespace x64 -} // namespace zz - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/codegen/codegen.h b/app/src/main/cpp/Dobby/source/core/codegen/codegen.h deleted file mode 100644 index e75d1931..00000000 --- a/app/src/main/cpp/Dobby/source/core/codegen/codegen.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef CORE_CODEGEN_H -#define CORE_CODEGEN_H - -#include "core/assembler/assembler.h" - -using namespace zz; - -class CodeGenBase { -public: - CodeGenBase(AssemblerBase *assembler) : assembler_(assembler) { - } - -protected: - AssemblerBase *assembler_; -}; - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/core/emulator/dummy.cc b/app/src/main/cpp/Dobby/source/core/emulator/dummy.cc deleted file mode 100644 index e69de29b..00000000 diff --git a/app/src/main/cpp/Dobby/source/dobby.cpp b/app/src/main/cpp/Dobby/source/dobby.cpp deleted file mode 100644 index 18b847b7..00000000 --- a/app/src/main/cpp/Dobby/source/dobby.cpp +++ /dev/null @@ -1,31 +0,0 @@ -#include "dobby/dobby_internal.h" -#include "Interceptor.h" - -__attribute__((constructor)) static void ctor() { - DEBUG_LOG("================================"); - DEBUG_LOG("Dobby"); - DEBUG_LOG("dobby in debug log mode, disable with cmake flag \"-DDOBBY_DEBUG=OFF\""); - DEBUG_LOG("================================"); -} - -PUBLIC const char *DobbyGetVersion() { - return ""; -} - -PUBLIC int DobbyDestroy(void *address) { -#if defined(TARGET_ARCH_ARM) - if ((addr_t)address % 2) { - address = (void *)((addr_t)address - 1); - } -#endif - auto entry = Interceptor::SharedInstance()->find((addr_t)address); - if (entry) { - uint8_t *buffer = entry->origin_insns; - uint32_t buffer_size = entry->origin_insn_size; - DobbyCodePatch(address, buffer, buffer_size); - Interceptor::SharedInstance()->remove((addr_t)address); - return 0; - } - - return -1; -} diff --git a/app/src/main/cpp/Dobby/source/dobby/common.h b/app/src/main/cpp/Dobby/source/dobby/common.h deleted file mode 100644 index 94d897bd..00000000 --- a/app/src/main/cpp/Dobby/source/dobby/common.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -#include "dobby.h" -#include "dobby/types.h" -#include "dobby/platform_features.h" -#include "dobby/platform_detect_macro.h" -#include "dobby/utility_macro.h" -#include "dobby/pac_kit.h" - -#include "logging/logging.h" -#include "logging/check_logging.h" \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/dobby/dobby_internal.h b/app/src/main/cpp/Dobby/source/dobby/dobby_internal.h deleted file mode 100644 index 121d6509..00000000 --- a/app/src/main/cpp/Dobby/source/dobby/dobby_internal.h +++ /dev/null @@ -1,13 +0,0 @@ -#pragma once - -#include "dobby/common.h" - -#include "PlatformUnifiedInterface/platform.h" - -#include "PlatformUnifiedInterface/MemoryAllocator.h" -#include "PlatformUnifiedInterface/ExecMemory/CodePatchTool.h" -#include "PlatformUnifiedInterface/ExecMemory/ClearCacheTool.h" - -#include "MemoryAllocator/AssemblyCodeBuilder.h" - -#include "InterceptRouting/InterceptRouting.h" \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/dobby/kernel_mode_header.h b/app/src/main/cpp/Dobby/source/dobby/kernel_mode_header.h deleted file mode 100644 index f962e3e6..00000000 --- a/app/src/main/cpp/Dobby/source/dobby/kernel_mode_header.h +++ /dev/null @@ -1,6 +0,0 @@ -#pragma once - -#include -#include -#include -#include diff --git a/app/src/main/cpp/Dobby/source/dobby/pac_kit.h b/app/src/main/cpp/Dobby/source/dobby/pac_kit.h deleted file mode 100644 index 12bf0977..00000000 --- a/app/src/main/cpp/Dobby/source/dobby/pac_kit.h +++ /dev/null @@ -1,35 +0,0 @@ -#pragma once - -#include - -#ifndef PAC_KIT -#define PAC_KIT -#if defined(__arm64e__) && __has_feature(ptrauth_calls) -#include -#endif - -static inline void *pac_strip(void *addr) { - if (addr == NULL) { - return NULL; - } -#if __has_feature(ptrauth_calls) - addr = ptrauth_strip(addr, ptrauth_key_asia); -#endif - return addr; -} - -static inline void *pac_sign(void *addr) { - if (addr == NULL) { - return NULL; - } -#if __has_feature(ptrauth_calls) - addr = ptrauth_sign_unauthenticated((void *)addr, ptrauth_key_asia, 0); -#endif - return addr; -} - -static inline void *pac_strip_and_sign(void *addr) { - return pac_sign(pac_strip(addr)); -} - -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/dobby/platform_detect_macro.h b/app/src/main/cpp/Dobby/source/dobby/platform_detect_macro.h deleted file mode 100644 index 300c7592..00000000 --- a/app/src/main/cpp/Dobby/source/dobby/platform_detect_macro.h +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -#if !defined(DISABLE_ARCH_DETECT) -#if defined(__arm__) -#define TARGET_ARCH_ARM 1 -#elif defined(__arm64__) || defined(__aarch64__) -#define TARGET_ARCH_ARM64 1 -#elif defined(_M_IX86) || defined(__i386__) -#define TARGET_ARCH_IA32 1 -#elif defined(_M_X64) || defined(__x86_64__) -#define TARGET_ARCH_X64 1 -#else -#error Target architecture was not detected as supported by Dobby -#endif -#endif diff --git a/app/src/main/cpp/Dobby/source/dobby/platform_features.h b/app/src/main/cpp/Dobby/source/dobby/platform_features.h deleted file mode 100644 index fb9076ad..00000000 --- a/app/src/main/cpp/Dobby/source/dobby/platform_features.h +++ /dev/null @@ -1,50 +0,0 @@ -#pragma once - -#if defined(__APPLE__) && __arm64e__ -#if __has_feature(ptrauth_calls) -#include -#endif -#endif - -#if defined(BUILDING_KERNEL) -#include -#include -#include -#include -#include -#include -#include -#else -#include -#include -#include -#include -#include -#include -#include -#include -#if defined(__linux__) || defined(__APPLE__) -#include -#include -#endif -#endif - -#if defined(BUILDING_KERNEL) -#include "kernel_mode_header.h" -#endif - -#if defined(BUILDING_KERNEL) -#define abs(a) ((a) < 0 ? -(a) : (a)) -#define llabs(a) (((long long)a) < 0 ? -((long long)a) : ((long long)a)) -#define min(a, b) (((a) < (b)) ? (a) : (b)) -#define max(a, b) (((a) > (b)) ? (a) : (b)) -#ifdef __cplusplus -#define abs(a) ((a) < 0 ? -(a) : (a)) -#endif -#else -#endif - -#ifdef __cplusplus -#include "TINYSTL/vector.h" -#include "TINYSTL/unordered_map.h" -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/source/dobby/types.h b/app/src/main/cpp/Dobby/source/dobby/types.h deleted file mode 100644 index f67546ef..00000000 --- a/app/src/main/cpp/Dobby/source/dobby/types.h +++ /dev/null @@ -1,10 +0,0 @@ -#pragma once - -#include - -typedef unsigned char byte_t; -typedef unsigned int uint; - -#ifndef NULL -#define NULL 0 -#endif diff --git a/app/src/main/cpp/Dobby/source/dobby/utility_macro.h b/app/src/main/cpp/Dobby/source/dobby/utility_macro.h deleted file mode 100644 index a6c567cd..00000000 --- a/app/src/main/cpp/Dobby/source/dobby/utility_macro.h +++ /dev/null @@ -1,62 +0,0 @@ -#pragma once - -// offset of struct member -#define OFFSETOF(TYPE, ELEMENT) ((size_t) & (((TYPE *)0)->ELEMENT)) - -// assert -#define ASSERT(X) - -// left/right shift -#define LeftShift(a, b, c) ((a & ((1 << b) - 1)) << c) -#define RightShift(a, b, c) ((a >> c) & ((1 << b) - 1)) - -// align -#ifndef ALIGN -#define ALIGN ALIGN_FLOOR -#endif -#define ALIGN_FLOOR(address, range) ((uintptr_t)address & ~((uintptr_t)range - 1)) -#define ALIGN_CEIL(address, range) (((uintptr_t)address + (uintptr_t)range - 1) & ~((uintptr_t)range - 1)) - -// borrow from gdb, refer: binutils-gdb/gdb/arch/arm.h -#define submask(x) ((1L << ((x) + 1)) - 1) -#define bits(obj, st, fn) (((obj) >> (st)) & submask((fn) - (st))) -#define bit(obj, st) (((obj) >> (st)) & 1) -#define sbits(obj, st, fn) ((long)(bits(obj, st, fn) | ((long)bit(obj, fn) * ~submask(fn - st)))) - -// make it easy -#define set_bit(obj, st, bit) obj = (((~(1 << st)) & obj) | (bit << st)) -#define set_bits(obj, st, fn, bits) obj = (((~(submask(fn - st) << st)) & obj) | (bits << st)) - -// definition to expand macro then apply to pragma message -// #pragma message(VAR_NAME_VALUE(HOST_OS_IOS)) -#define VALUE_TO_STRING(x) #x -#define VALUE(x) VALUE_TO_STRING(x) -#define VAR_NAME_VALUE(var) #var "=" VALUE(var) - -// format print -#ifdef __LP64__ -#define __PRI_64_prefix "l" -#define __PRI_PTR_prefix "l" -#else -#define __PRI_64_prefix "ll" -#define __PRI_PTR_prefix -#endif -#define PRIxPTR __PRI_PTR_prefix "x" /* uintptr_t */ - -// deprecated declared -#if defined(__GNUC__) || defined(__clang__) -#define DEPRECATED __attribute__((deprecated)) -#elif defined(_MSC_VER) -#define DEPRECATED __declspec(deprecated) -#else -#pragma message("WARNING: You need to implement DEPRECATED for this compiler") -#define DEPRECATED -#endif - -// export method -#if defined(_WIN32) -#define PUBLIC -#else -#define PUBLIC __attribute__((visibility("default"))) -#define INTERNAL __attribute__((visibility("internal"))) -#endif \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/tests/CMakeLists.txt b/app/src/main/cpp/Dobby/tests/CMakeLists.txt deleted file mode 100644 index 8cb2454b..00000000 --- a/app/src/main/cpp/Dobby/tests/CMakeLists.txt +++ /dev/null @@ -1,120 +0,0 @@ - -find_package(PkgConfig REQUIRED) -pkg_check_modules(CAPSTONE REQUIRED capstone) -message(STATUS "Capstone libraries: " ${CAPSTONE_LIBRARY_DIRS}) -message(STATUS "Capstone includes: " ${CAPSTONE_INCLUDE_DIRS}) - -pkg_check_modules(UNICORN REQUIRED unicorn) -message(STATUS "unicorn libraries: " ${UNICORN_LIBRARY_DIRS}) -message(STATUS "unicorn includes: " ${UNICORN_INCLUDE_DIRS}) - -get_property(DOBBY_SOURCE_FILE_LIST - TARGET dobby - PROPERTY SOURCES) - -set(DOBBY_SOURCES) -foreach (path ${DOBBY_SOURCE_FILE_LIST}) - if (NOT path MATCHES "^/") - list(APPEND DOBBY_SOURCES ${DOBBY_DIR}/${path}) - else () - list(APPEND DOBBY_SOURCES ${path}) - endif () -endforeach () - - -add_executable(test_insn_relo_arm64 - test_insn_relo_arm64.cpp - UniconEmulator.cpp - ${DOBBY_SOURCES} - ) - -target_compile_definitions(test_insn_relo_arm64 PUBLIC - LOGGING_DEBUG=1 - DISABLE_ARCH_DETECT=1 - TARGET_ARCH_ARM64=1 - TEST_WITH_UNICORN=1 - ) - -target_include_directories(test_insn_relo_arm64 PUBLIC - ${CAPSTONE_INCLUDE_DIRS} - ${UNICORN_INCLUDE_DIRS} - ) - -target_link_directories(test_insn_relo_arm64 PUBLIC - ${CAPSTONE_LIBRARY_DIRS} - ${UNICORN_LIBRARY_DIRS} - ) - -target_link_libraries(test_insn_relo_arm64 PUBLIC - ${CAPSTONE_LIBRARIES} - ${UNICORN_LIBRARIES} - ) - -# --- - -add_executable(test_insn_relo_arm - test_insn_relo_arm.cpp - UniconEmulator.cpp - ${DOBBY_SOURCES} - ) - -target_compile_definitions(test_insn_relo_arm PUBLIC - LOGGING_DEBUG=1 - DISABLE_ARCH_DETECT=1 - TARGET_ARCH_ARM=1 - TEST_WITH_UNICORN=1 - ) - -target_include_directories(test_insn_relo_arm PUBLIC - ${CAPSTONE_INCLUDE_DIRS} - ${UNICORN_INCLUDE_DIRS} - ) - -target_link_directories(test_insn_relo_arm PUBLIC - ${CAPSTONE_LIBRARY_DIRS} - ${UNICORN_LIBRARY_DIRS} - ) - -target_link_libraries(test_insn_relo_arm PUBLIC - ${CAPSTONE_LIBRARIES} - ${UNICORN_LIBRARIES} - ) - -# --- - -add_executable(test_insn_relo_x64 - test_insn_relo_x64.cpp - UniconEmulator.cpp - ${DOBBY_SOURCES} - ) - -target_compile_definitions(test_insn_relo_x64 PUBLIC - LOGGING_DEBUG=1 - DISABLE_ARCH_DETECT=1 - TARGET_ARCH_X64=1 - TEST_WITH_UNICORN=1 - # TARGET_ARCH_IA32=1 - ) - -target_include_directories(test_insn_relo_x64 PUBLIC - ${CAPSTONE_INCLUDE_DIRS} - ${UNICORN_INCLUDE_DIRS} - ) - -target_link_directories(test_insn_relo_x64 PUBLIC - ${CAPSTONE_LIBRARY_DIRS} - ${UNICORN_LIBRARY_DIRS} - ) - -target_link_libraries(test_insn_relo_x64 PUBLIC - ${CAPSTONE_LIBRARIES} - ${UNICORN_LIBRARIES} - ) - -# --- - -add_executable(test_native - test_native.cpp) - -target_link_libraries(test_native - dobby) \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/tests/UniconEmulator.cpp b/app/src/main/cpp/Dobby/tests/UniconEmulator.cpp deleted file mode 100644 index a0848ca5..00000000 --- a/app/src/main/cpp/Dobby/tests/UniconEmulator.cpp +++ /dev/null @@ -1,219 +0,0 @@ -#include "UniconEmulator.h" -#include "PlatformUnifiedInterface/MemoryAllocator.h" -#include "InstructionRelocation/InstructionRelocation.h" - -// align -#ifndef ALIGN -#define ALIGN ALIGN_FLOOR -#endif -#define ALIGN_FLOOR(address, range) ((uintptr_t)address & ~((uintptr_t)range - 1)) -#define ALIGN_CEIL(address, range) (((uintptr_t)address + (uintptr_t)range - 1) & ~((uintptr_t)range - 1)) - -std::string g_arch = ""; - -void set_global_arch(std::string arch) { - g_arch = arch; -} - -std::unordered_map CapstoneDisassembler::instances_; - -CapstoneDisassembler *CapstoneDisassembler::Get(const std::string &arch) { - if (instances_.count(arch) == 0) { - cs_err err = CS_ERR_OK; - csh csh_; - if (arch == "arm") { - err = cs_open(CS_ARCH_ARM, CS_MODE_ARM, &csh_); - } else if (arch == "thumb") { - err = cs_open(CS_ARCH_ARM, CS_MODE_THUMB, &csh_); - } else if (arch == "arm64") { - err = cs_open(CS_ARCH_ARM64, CS_MODE_ARM, &csh_); - } else if (arch == "x86_64") { - err = cs_open(CS_ARCH_X86, CS_MODE_64, &csh_); - } else if (arch == "x86") { - err = cs_open(CS_ARCH_X86, CS_MODE_32, &csh_); - } - - auto instance = new CapstoneDisassembler(arch, csh_); - instances_[arch] = instance; - } - return instances_[arch]; -} - -CapstoneDisassembler::CapstoneDisassembler(const std::string &arch, csh csh_) : arch_(arch), csh_(csh_) { -} - -CapstoneDisassembler::~CapstoneDisassembler() { - cs_close((csh *)&csh_); -} - -void CapstoneDisassembler::disassemble(uintptr_t addr, char *buffer, size_t buffer_size) { - cs_insn *insns; - - size_t count = cs_disasm(csh_, (uint8_t *)buffer, buffer_size, addr, 0, &insns); - for (size_t i = 0; i < count; ++i) { - auto &insn = insns[i]; - if (arch_ == "thumb") { - printf("%s %p: %s %s // thumb-%d\n", "-", insn.address, insn.mnemonic, insn.op_str, insn.size / 2); - } else { - printf("%s %p: %s %s\n", "-", insn.address, insn.mnemonic, insn.op_str); - } - } - cs_free(insns, count); -} - -static void hook_trace_insn(uc_engine *uc, uint64_t address, uint32_t size, void *user_data) { - auto emu = (UniconEmulator *)user_data; - - uc_err err; - char insn_bytes[16]; - err = uc_mem_read(uc, address, insn_bytes, size); - assert(err == UC_ERR_OK); - - if (address >= emu->end_) { - emu->stop(); - return; - } - - if ((emu->arch_ == "arm" || emu->arch_ == "thumb") && emu->isThumb()) { - CapstoneDisassembler::Get("thumb")->disassemble(address, (char *)insn_bytes, size); - } else { - CapstoneDisassembler::Get(g_arch)->disassemble(address, (char *)insn_bytes, size); - } -} - -static void hook_unmapped(uc_engine *uc, uc_mem_type type, uint64_t address, int size, int64_t value, void *user_data) { - printf(">>> Unmapped memory access at %p, data size = %p, data value = %p\n", address, size, value); - auto emu = (UniconEmulator *)user_data; - emu->setUnmappedAddr(address); - emu->stop(); -} - -void dump_regions(uc_engine *uc) { - uc_mem_region *regions; - uint32_t region_count; - uc_mem_regions(uc, ®ions, ®ion_count); - for (int i = 0; i < region_count; ++i) { - auto ®ion = regions[i]; - printf("region: %p - %p\n", region.begin, region.end); - } -} - -UniconEmulator::UniconEmulator(const std::string &arch) { - uc_err err = UC_ERR_OK; - if (arch == "arm" || arch == "thumb") { - err = uc_open(UC_ARCH_ARM, UC_MODE_ARM, &uc_); - } else if (arch == "arm64") { - err = uc_open(UC_ARCH_ARM64, UC_MODE_ARM, &uc_); - } else if (arch == "x86_64") { - err = uc_open(UC_ARCH_X86, UC_MODE_64, &uc_); - } else if (arch == "x86") { - err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc_); - } - assert(err == UC_ERR_OK); - - arch_ = arch; - - uc_hook hook_trace_insn_handle; - uc_hook_add(uc_, &hook_trace_insn_handle, UC_HOOK_CODE, (void *)hook_trace_insn, this, 1, 0); - - uc_hook hook_unmapped_handle; - uc_hook_add(uc_, &hook_unmapped_handle, UC_HOOK_MEM_UNMAPPED, (void *)hook_unmapped, this, 1, 0); -} - -void UniconEmulator::mapMemory(uintptr_t addr, char *buffer, size_t buffer_size) { - uc_err err = UC_ERR_OK; - uintptr_t map_addr = ALIGN_FLOOR(addr, 0x1000); - size_t map_size = ALIGN_CEIL(buffer_size, 0x1000); - err = uc_mem_map(uc_, map_addr, map_size, UC_PROT_ALL); - assert(err == UC_ERR_OK); - err = uc_mem_write(uc_, addr, buffer, buffer_size); - assert(err == UC_ERR_OK); -} - -void *UniconEmulator::readRegister(int regId) { - void *value = nullptr; - uc_reg_read(uc_, regId, &value); - return value; -} - -void UniconEmulator::writeRegister(int regNdx, void *value) { - uc_reg_write(uc_, regNdx, (void *)&value); -} - -void UniconEmulator::start(uintptr_t addr, uintptr_t end) { - uc_err err; - if (g_arch == "thumb") { - addr |= 1; - } - err = uc_emu_start(uc_, addr, end, 0, 0); - if (err == UC_ERR_FETCH_UNMAPPED || err == UC_ERR_READ_UNMAPPED || err == UC_ERR_WRITE_UNMAPPED) - err = UC_ERR_OK; - assert(err == UC_ERR_OK); -} - -void UniconEmulator::emulate(uintptr_t addr, uintptr_t end, char *buffer, size_t buffer_size) { - uc_err err; - mapMemory(addr, buffer, buffer_size); - writeRegister(UC_ARM_REG_PC, (void *)addr); - - if (end == 0) - end = addr + buffer_size; - - start_ = addr; - end_ = end; - - start(addr, end); -} - -void check_insn_relo(char *buffer, size_t buffer_size, bool check_fault_addr, int check_reg_id, - void (^callback)(UniconEmulator *orig, UniconEmulator *relo), uintptr_t relo_stop_size) { - auto *orig_ue = new UniconEmulator(g_arch); - auto *relo_ue = new UniconEmulator(g_arch); - - addr_t orig_addr = 0x100014000; - addr_t relocate_addr = 0x100024000; - - if (g_arch == "arm" || g_arch == "thumb") { - orig_addr = 0x10014000; - relocate_addr = 0x10024000; - } - - // auto dism = CapstoneDisassembler::Get("arm64"); - // dism->disassemble((uintptr_t)orig_addr, buffer, buffer_size); - // printf("\n"); - - auto origin = new CodeMemBlock(orig_addr, buffer_size); - auto relocated = new CodeMemBlock(relocate_addr, 0x1000); - if (g_arch == "thumb") { - origin->reset(origin->addr + 1, origin->size); - } - - GenRelocateCode(buffer, origin, relocated, false); - - if (g_arch == "thumb") { - orig_ue->writeRegister(UC_ARM_REG_CPSR, (void *)0x20); - relo_ue->writeRegister(UC_ARM_REG_CPSR, (void *)0x20); - } - orig_ue->emulate(orig_addr, 0, buffer, buffer_size); - if (g_arch == "thumb") { - relocated->addr -= 1; - } - if (relo_stop_size == 0) { - relo_stop_size = relocated->size; - } - relo_ue->emulate(relocate_addr, relocate_addr + relo_stop_size, (char *)relocated->addr, relocated->size); - - // dism->disassemble((uintptr_t)relocate_addr, (char *)relocated->addr, relocated->size); - // printf("\n"); - - if (check_fault_addr) { - assert(orig_ue->getFaultAddr() == relo_ue->getFaultAddr()); - } else if (check_reg_id != -1) { - assert(orig_ue->readRegister(check_reg_id) == relo_ue->readRegister(check_reg_id)); - } else if (callback) { - callback(orig_ue, relo_ue); - } - - delete orig_ue; - delete relo_ue; -} diff --git a/app/src/main/cpp/Dobby/tests/UniconEmulator.h b/app/src/main/cpp/Dobby/tests/UniconEmulator.h deleted file mode 100644 index 414618b7..00000000 --- a/app/src/main/cpp/Dobby/tests/UniconEmulator.h +++ /dev/null @@ -1,73 +0,0 @@ -#pragma once - -#include -#include - -#include -#include - -class CapstoneDisassembler { -public: - void disassemble(uintptr_t addr, char *buffer, size_t buffer_size); - - static CapstoneDisassembler *Get(const std::string &arch); - -private: - CapstoneDisassembler(const std::string &arch, csh csh_); - - ~CapstoneDisassembler(); - -private: - std::string arch_; - csh csh_; - - static std::unordered_map instances_; -}; - -class UniconEmulator { -public: - UniconEmulator(const std::string &arch); - - void mapMemory(uintptr_t addr, char *buffer, size_t buffer_size); - - void *readRegister(int regId); - - void writeRegister(int regId, void *value); - - void start(uintptr_t addr, uintptr_t end); - - void stop() { - uc_emu_stop(uc_); - } - - void emulate(uintptr_t addr, uintptr_t end, char *buffer, size_t buffer_size); - - void setUnmappedAddr(uintptr_t addr) { - unmapped_addr_ = addr; - } - - intptr_t getFaultAddr() { - return unmapped_addr_; - } - - bool isThumb() { - void *reg_value = readRegister(UC_ARM_REG_CPSR); - return (intptr_t)reg_value & 0x20; - } - - void reset(); - -public: - std::string arch_; - uintptr_t start_, end_; - -private: - uc_err err_; - uc_engine *uc_; - uintptr_t unmapped_addr_; -}; - -void set_global_arch(std::string arch); - -void check_insn_relo(char *buffer, size_t buffer_size, bool check_fault_addr, int check_reg_id, - void (^callback)(UniconEmulator *orig, UniconEmulator *relo), uintptr_t relo_stop_size = 0); \ No newline at end of file diff --git a/app/src/main/cpp/Dobby/tests/test_insn_decoder_x86.cpp b/app/src/main/cpp/Dobby/tests/test_insn_decoder_x86.cpp deleted file mode 100644 index 20e0fb90..00000000 --- a/app/src/main/cpp/Dobby/tests/test_insn_decoder_x86.cpp +++ /dev/null @@ -1,267 +0,0 @@ -#include "InstructionRelocation/InstructionRelocation.h" -#include "InstructionRelocation/arm64/InstructionRelocationARM64.h" - -#include -#include - -#include - -class CapstoneDisassembler { -public: - void disassemble(uintptr_t addr, char *buffer, size_t buffer_szie); - - static CapstoneDisassembler *Get(const std::string &arch); - -private: - CapstoneDisassembler(const std::string &arch, csh csh_); - - ~CapstoneDisassembler(); - -private: - csh csh_; - - static CapstoneDisassembler *instance_; -}; - -CapstoneDisassembler *CapstoneDisassembler::instance_ = nullptr; - -CapstoneDisassembler *CapstoneDisassembler::Get(const std::string &arch) { - if (instance_ == nullptr) { - cs_err err = CS_ERR_OK; - csh csh_; - if (arch == "arm") { - err = cs_open(CS_ARCH_ARM, CS_MODE_ARM, &csh_); - } else if (arch == "arm64") { - err = cs_open(CS_ARCH_ARM64, CS_MODE_ARM, &csh_); - } else if (arch == "x86_64") { - err = cs_open(CS_ARCH_X86, CS_MODE_64, &csh_); - } else if (arch == "x86") { - err = cs_open(CS_ARCH_X86, CS_MODE_32, &csh_); - } - instance_ = new CapstoneDisassembler(arch, csh_); - } - return instance_; -} - -CapstoneDisassembler::CapstoneDisassembler(const std::string &arch, csh csh_) : csh_(csh_) { -} - -CapstoneDisassembler::~CapstoneDisassembler() { - cs_close((csh *)&csh_); -} - -void CapstoneDisassembler::disassemble(uintptr_t addr, char *buffer, size_t buffer_size) { - cs_insn *insns; - - size_t count = cs_disasm(csh_, (uint8_t *)buffer, buffer_size, addr, 0, &insns); - for (size_t i = 0; i < count; ++i) { - auto &insn = insns[i]; - printf("%s %p: %s %s\n", "-", insn.address, insn.mnemonic, insn.op_str); - } - cs_free(insns, count); -} - -class UniconEmulator { -public: - UniconEmulator(const std::string &arch); - - void mapMemory(uintptr_t addr, char *buffer, size_t buffer_size); - - void *readRegister(int regId); - - void writeRegister(int regId, void *value); - - void start(uintptr_t addr, uintptr_t end); - - void stop() { - uc_emu_stop(uc_); - } - - void emulate(uintptr_t addr, char *buffer, size_t buffer_size); - - void setUnmappedAddr(uintptr_t addr) { - unmapped_addr_ = addr; - } - - intptr_t getFaultAddr() { - return unmapped_addr_; - } - - void reset(); - -private: -private: - uc_err err_; - uc_engine *uc_; - uintptr_t unmapped_addr_; -}; - -static void hook_trace_insn(uc_engine *uc, uint64_t address, uint32_t size, void *user_data) { - auto emu = (UniconEmulator *)user_data; - uc_err err; - char insn_bytes[16]; - err = uc_mem_read(uc, address, insn_bytes, size); - assert(err == UC_ERR_OK); - CapstoneDisassembler::Get("arm64")->disassemble(address, (char *)insn_bytes, size); -} - -static void hook_unmapped(uc_engine *uc, uc_mem_type type, uint64_t address, int size, int64_t value, void *user_data) { - printf(">>> Unmapped memory access at %p, data size = %p, data value = %p\n", address, size, value); - auto emu = (UniconEmulator *)user_data; - emu->setUnmappedAddr(address); - emu->stop(); -} - -void dump_regions(uc_engine *uc) { - uc_mem_region *regions; - uint32_t region_count; - uc_mem_regions(uc, ®ions, ®ion_count); - for (int i = 0; i < region_count; ++i) { - auto ®ion = regions[i]; - printf("region: %p - %p\n", region.begin, region.end); - } -} - -UniconEmulator::UniconEmulator(const std::string &arch) { - uc_err err = UC_ERR_OK; - if (arch == "arm") { - err = uc_open(UC_ARCH_ARM, UC_MODE_ARM, &uc_); - } else if (arch == "arm64") { - err = uc_open(UC_ARCH_ARM64, UC_MODE_ARM, &uc_); - } else if (arch == "x86_64") { - err = uc_open(UC_ARCH_X86, UC_MODE_64, &uc_); - } else if (arch == "x86") { - err = uc_open(UC_ARCH_X86, UC_MODE_32, &uc_); - } - assert(err == UC_ERR_OK); - - uc_hook hook_trace_insn_handle; - uc_hook_add(uc_, &hook_trace_insn_handle, UC_HOOK_CODE, (void *)hook_trace_insn, this, 1, 0); - - uc_hook hook_unmapped_handle; - uc_hook_add(uc_, &hook_unmapped_handle, UC_HOOK_MEM_UNMAPPED, (void *)hook_unmapped, this, 1, 0); -} - -void UniconEmulator::mapMemory(uintptr_t addr, char *buffer, size_t buffer_size) { - uc_err err = UC_ERR_OK; - uintptr_t map_addr = ALIGN_FLOOR(addr, 0x1000); - size_t map_size = ALIGN_CEIL(buffer_size, 0x1000); - err = uc_mem_map(uc_, map_addr, map_size, UC_PROT_ALL); - assert(err == UC_ERR_OK); - err = uc_mem_write(uc_, addr, buffer, buffer_size); - assert(err == UC_ERR_OK); -} - -void *UniconEmulator::readRegister(int regId) { - void *value = nullptr; - uc_reg_read(uc_, regId, &value); - return value; -} - -void UniconEmulator::writeRegister(int regNdx, void *value) { - uc_reg_write(uc_, regNdx, (void *)&value); -} - -void UniconEmulator::start(uintptr_t addr, uintptr_t end) { - uc_err err; - err = uc_emu_start(uc_, addr, end, 0, 0); - if (err == UC_ERR_FETCH_UNMAPPED || err == UC_ERR_READ_UNMAPPED || err == UC_ERR_WRITE_UNMAPPED) - err = UC_ERR_OK; - assert(err == UC_ERR_OK); -} - -void UniconEmulator::emulate(uintptr_t addr, char *buffer, size_t buffer_size) { - uc_err err; - mapMemory(addr, buffer, buffer_size); - writeRegister(UC_ARM_REG_PC, (void *)addr); - start(addr, addr + buffer_size); -} - -void check_insn_relo(char *buffer, size_t buffer_size, bool check_fault_addr, int check_reg_id, - void (^callback)(UniconEmulator *orig, UniconEmulator *relo)) { - auto *orig_ue = new UniconEmulator("arm64"); - auto *relo_ue = new UniconEmulator("arm64"); - - addr_t orig_addr = 0x100004000; - addr_t relocate_addr = 0x200004000; - - // auto dism = CapstoneDisassembler::Get("arm64"); - // dism->disassemble((uintptr_t)orig_addr, buffer, buffer_size); - // printf("\n"); - - auto origin = new CodeMemBlock(orig_addr, buffer_size); - auto relocated = new CodeMemBlock(); - - GenRelocateCode(buffer, origin, relocated, false); - - orig_ue->emulate(orig_addr, buffer, buffer_size); - relo_ue->emulate(relocate_addr, (char *)relocated->addr, relocated->size); - - // dism->disassemble((uintptr_t)relocate_addr, (char *)relocated->addr, relocated->size); - // printf("\n"); - - if (check_fault_addr) { - assert(orig_ue->getFaultAddr() == relo_ue->getFaultAddr()); - } else if (check_reg_id != -1) { - assert(orig_ue->readRegister(check_reg_id) == relo_ue->readRegister(check_reg_id)); - } else if (callback) { - callback(orig_ue, relo_ue); - } - - delete orig_ue; - delete relo_ue; -} - -int main() { - // b #-0x4000 - check_insn_relo("\x00\xf0\xff\x17", 4, true, -1, nullptr); - // b #0x4000 - check_insn_relo("\x00\x10\x00\x14", 4, true, -1, nullptr); - - // bl #-0x4000 - check_insn_relo("\x00\xf0\xff\x97", 4, true, -1, nullptr); - // bl #0x4000 - check_insn_relo("\x00\x10\x00\x94", 4, true, -1, nullptr); - - // mov x0, #0 - // cbz x0, #-0x4000 - check_insn_relo("\x00\x00\x80\xd2\x00\x00\xfe\xb4", 8, true, -1, nullptr); - // mov x0, #0 - // cbz x0, #0x4000 - check_insn_relo("\x00\x00\x80\xd2\x00\x00\x02\xb4", 8, true, -1, nullptr); - - // ldr x0, #-0x4000 - check_insn_relo("\x00\x00\xfe\x58", 4, true, -1, nullptr); - // ldr x0, #0x4000 - check_insn_relo("\x00\x00\x02\x58", 4, true, -1, nullptr); - - // adr x0, #-0x4000 - check_insn_relo("\x00\x00\xfe\x10", 4, false, UC_ARM64_REG_X0, nullptr); - // adr x0, #0x4000 - check_insn_relo("\x00\x00\x02\x10", 4, false, UC_ARM64_REG_X0, nullptr); - - // adrp x0, #-0x4000 - check_insn_relo("\xe0\xff\xff\x90", 4, false, UC_ARM64_REG_X0, nullptr); - // adrp x0, #0x4000 - check_insn_relo("\x20\x00\x00\x90", 4, false, UC_ARM64_REG_X0, nullptr); - - // mov x0, #0 - // cmp x0, #0 - // b.eq #-0x4000 - check_insn_relo("\x00\x00\x80\xd2\x1f\x00\x00\xf1\x00\x00\xfe\x54", 12, true, -1, nullptr); - // mov x0, #0 - // cmp x0, #0 - // b.eq #0x4000 - check_insn_relo("\x00\x00\x80\xd2\x1f\x00\x00\xf1\x00\x00\x02\x54", 12, true, -1, nullptr); - - // mov x0, #0xb - // tbz w0, 2, #-0x4000 - check_insn_relo("\x60\x01\x80\xd2\x00\x00\x16\x36", 8, true, -1, nullptr); - // mov x0, #0xb - - // mov x0, #0xb - // tbz w0, 2, #0x4000 - check_insn_relo("\x60\x01\x80\xd2\x00\x00\x12\x36", 8, true, -1, nullptr); - - return 0; -} diff --git a/app/src/main/cpp/Dobby/tests/test_insn_relo_arm.cpp b/app/src/main/cpp/Dobby/tests/test_insn_relo_arm.cpp deleted file mode 100644 index 43dd16ce..00000000 --- a/app/src/main/cpp/Dobby/tests/test_insn_relo_arm.cpp +++ /dev/null @@ -1,116 +0,0 @@ -#include "InstructionRelocation/InstructionRelocation.h" - -#include "UniconEmulator.h" - -void check_insn_relo_arm(char *buffer, size_t buffer_size, bool check_fault_addr, int check_reg_id, - void (^callback)(UniconEmulator *orig, UniconEmulator *relo)) { - __attribute__((aligned(4))) char code[64] = {0}; - memcpy(code, buffer, buffer_size); - check_insn_relo(code, buffer_size, check_fault_addr, check_reg_id, callback); -} - -void check_insn_relo_thumb(char *buffer, size_t buffer_size, bool check_fault_addr, int check_reg_id, - void (^callback)(UniconEmulator *orig, UniconEmulator *relo), uintptr_t relo_stop_size = 0) { - __attribute__((aligned(4))) char code[64] = {0}; - memcpy(code, buffer, buffer_size); - check_insn_relo(code, buffer_size, check_fault_addr, check_reg_id, callback, relo_stop_size); -} - -int main() { - log_set_level(0); - set_global_arch("arm"); - - // ldr r0, [pc, #-0x20] - __attribute__((aligned(4))) char *code_0 = "\x20\x00\x1f\xe5"; - check_insn_relo(code_0, 4, true, -1, nullptr); - - // ldr r0, [pc, #0x20] - __attribute__((aligned(4))) char *code_1 = "\x20\x00\x9f\xe5"; - check_insn_relo(code_1, 4, false, -1, ^(UniconEmulator *orig, UniconEmulator *relo) { - assert(relo->getFaultAddr() == 0x10014028); - }); - - // add r0, pc, #-0x4000 - check_insn_relo_arm("\x01\x09\x4f\xe2", 4, false, UC_ARM_REG_R0, nullptr); - // add r0, pc, #0x4000 - check_insn_relo_arm("\x01\x09\x8f\xe2", 4, false, UC_ARM_REG_R0, nullptr); - - // b #-0x4000 - check_insn_relo_arm("\xfe\xef\xff\xea", 4, true, -1, nullptr); - // b #0x4000 - check_insn_relo_arm("\xfe\x0f\x00\xea", 4, true, -1, nullptr); - - // bl #-0x4000 - check_insn_relo_arm("\xfe\xef\xff\xeb", 4, true, -1, nullptr); - // blx #0x4000 - check_insn_relo_arm("\xfe\x0f\x00\xfa", 4, true, -1, nullptr); - - set_global_arch("thumb"); - - // cmp r0, pc - check_insn_relo_thumb("\x78\x45", 2, false, -1, ^(UniconEmulator *orig, UniconEmulator *relo) { - assert(relo->readRegister(UC_ARM_REG_R12) == (void *)0x10014004); - }); - - // adr r0, #0x20 - check_insn_relo_thumb("\x08\xa0", 2, false, UC_ARM_REG_R0, nullptr, 8); - - // bx pc - check_insn_relo_thumb("\x78\x47", 2, false, UC_ARM_REG_PC, nullptr); - // blx pc - check_insn_relo_thumb("\xf8\x47", 2, false, UC_ARM_REG_PC, nullptr); - - // ldr r0, [pc, #8] - check_insn_relo_thumb("\x02\x48", 2, false, -1, ^(UniconEmulator *orig, UniconEmulator *relo) { - assert(relo->getFaultAddr() == 0x1001400c); - }); - - // b #-8 - check_insn_relo_thumb("\xfa\xe7", 2, true, -1, nullptr); - // b #8 - check_insn_relo_thumb("\x02\xe0", 2, false, -1, ^(UniconEmulator *orig, UniconEmulator *relo) { - assert(relo->getFaultAddr() == 0x10014008); - }); - - // mov r0, 0 - // cbz r0, #8 - check_insn_relo_thumb("\x4f\xf0\x00\x00" - "\x10\xb1", - 6, false, -1, ^(UniconEmulator *orig, UniconEmulator *relo) { - assert(relo->getFaultAddr() == 0x1001400c); - }); - - set_global_arch("thumb"); - - // cmp r0, r0 - // beq.w #-0x4000 - check_insn_relo_thumb("\x80\x42" - "\x3c\xf4\x00\xa8", - 6, true, -1, nullptr); - // cmp r0, r0 - // beq.w #0x4000 - check_insn_relo_thumb("\x80\x42" - "\x04\xf0\x00\x80", - 6, true, -1, nullptr); - - // bl #-0x4000 - check_insn_relo_thumb("\xfb\xf7\xfe\xff", 4, true, -1, nullptr); - // blx #0x4000 - check_insn_relo_thumb("\x03\xf0\xfe\xef", 4, true, -1, nullptr); - - // adr r0, #-0x512 - check_insn_relo_thumb("\xaf\xf2\x12\x50", 4, false, UC_ARM_REG_R0, nullptr); - // adr r0, #0x512 - check_insn_relo_thumb("\x0f\xf2\x12\x50", 4, false, UC_ARM_REG_R0, nullptr); - - // ldr r0, [pc, #-0x512] - check_insn_relo_thumb("\x5f\xf8\x12\x05", 4, true, -1, nullptr, 0xc); - // ldr r0, [pc, #0x512] - check_insn_relo_thumb( - "\xdf\xf8\x12\x05", 4, false, -1, - ^(UniconEmulator *orig, UniconEmulator *relo) { - assert(relo->getFaultAddr() == 0x10014000 + 0x512 + 4); - }, - 0xc); - return 0; -} diff --git a/app/src/main/cpp/Dobby/tests/test_insn_relo_arm64.cpp b/app/src/main/cpp/Dobby/tests/test_insn_relo_arm64.cpp deleted file mode 100644 index d76aee66..00000000 --- a/app/src/main/cpp/Dobby/tests/test_insn_relo_arm64.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* - -test_b: -b #-0x4000 -b #0x4000 - -test_bl: -bl #-0x4000 -bl #0x4000 - -test_cbz: -cbz x0, #-0x4000 -cbz x0, #0x4000 - -test_ldr_liberal: -ldr x0, #-0x4000 -ldr x0, #0x4000 - -test_adr: -adr x0, #-0x4000 -adr x0, #0x4000 - -test_adrp: -adrp x0, #-0x4000 -adrp x0, #0x4000 - -test_b_cond: -b.eq #-0x4000 -b.eq #0x4000 - -test_tbz: -tbz x0, #0, #-0x4000 -tbz x0, #0, #0x4000 - -*/ - -// clang -arch arm64 code_arm64.asm -o code_arm64.o - -#include "InstructionRelocation/InstructionRelocation.h" - -#include "UniconEmulator.h" - -int main() { - set_global_arch("arm64"); - - // b #-0x4000 - check_insn_relo("\x00\xf0\xff\x17", 4, true, -1, nullptr); - // b #0x4000 - check_insn_relo("\x00\x10\x00\x14", 4, true, -1, nullptr); - - // bl #-0x4000 - check_insn_relo("\x00\xf0\xff\x97", 4, true, -1, nullptr); - // bl #0x4000 - check_insn_relo("\x00\x10\x00\x94", 4, true, -1, nullptr); - - // mov x0, #0 - // cbz x0, #-0x4000 - check_insn_relo("\x00\x00\x80\xd2\x00\x00\xfe\xb4", 8, true, -1, nullptr); - // mov x0, #0 - // cbz x0, #0x4000 - check_insn_relo("\x00\x00\x80\xd2\x00\x00\x02\xb4", 8, true, -1, nullptr); - - // ldr x0, #-0x4000 - check_insn_relo("\x00\x00\xfe\x58", 4, true, -1, nullptr); - // ldr x0, #0x4000 - check_insn_relo("\x00\x00\x02\x58", 4, true, -1, nullptr); - - // adr x0, #-0x4000 - check_insn_relo("\x00\x00\xfe\x10", 4, false, UC_ARM64_REG_X0, nullptr); - // adr x0, #0x4000 - check_insn_relo("\x00\x00\x02\x10", 4, false, UC_ARM64_REG_X0, nullptr); - - // adrp x0, #-0x4000 - check_insn_relo("\xe0\xff\xff\x90", 4, false, UC_ARM64_REG_X0, nullptr); - // adrp x0, #0x4000 - check_insn_relo("\x20\x00\x00\x90", 4, false, UC_ARM64_REG_X0, nullptr); - - // mov x0, #0 - // cmp x0, #0 - // b.eq #-0x4000 - check_insn_relo("\x00\x00\x80\xd2\x1f\x00\x00\xf1\x00\x00\xfe\x54", 12, true, -1, nullptr); - // mov x0, #0 - // cmp x0, #0 - // b.eq #0x4000 - check_insn_relo("\x00\x00\x80\xd2\x1f\x00\x00\xf1\x00\x00\x02\x54", 12, true, -1, nullptr); - - // mov x0, #0xb - // tbz w0, 2, #-0x4000 - check_insn_relo("\x60\x01\x80\xd2\x00\x00\x16\x36", 8, true, -1, nullptr); - // mov x0, #0xb - - // mov x0, #0xb - // tbz w0, 2, #0x4000 - check_insn_relo("\x60\x01\x80\xd2\x00\x00\x12\x36", 8, true, -1, nullptr); - - return 0; -} diff --git a/app/src/main/cpp/Dobby/tests/test_insn_relo_x64.cpp b/app/src/main/cpp/Dobby/tests/test_insn_relo_x64.cpp deleted file mode 100644 index f9db59dd..00000000 --- a/app/src/main/cpp/Dobby/tests/test_insn_relo_x64.cpp +++ /dev/null @@ -1,38 +0,0 @@ -#include "InstructionRelocation/InstructionRelocation.h" - -#include "UniconEmulator.h" - -int main() { - log_set_level(0); - set_global_arch("x86_64"); - - - // cmp eax, eax - // jz -0x20 - check_insn_relo("\x39\xc0\x74\xdc", 4, false, UC_X86_REG_IP, nullptr); - // cmp eax, eax - // jz 0x20 - check_insn_relo("\x39\xc0\x74\x1c", 4, false, UC_X86_REG_IP, nullptr); - - // jmp -0x20 - check_insn_relo("\xeb\xde", 2, false, UC_X86_REG_IP, nullptr); - // jmp 0x20 - check_insn_relo("\xeb\x1e", 2, false, UC_X86_REG_IP, nullptr); - - - // jmp -0x4000 - check_insn_relo("\xe9\xfb\xbf\xff\xff", 4, false, UC_X86_REG_IP, nullptr); - // jmp 0x4000 - check_insn_relo("\xe9\xfb\x3f\x00\x00", 4, false, UC_X86_REG_IP, nullptr); - - // lea rax, [rip] - check_insn_relo("\x48\x8d\x05\x00\x00\x00\x00", 7, false, UC_X86_REG_RAX, nullptr); - - // lea rax, [rip + 0x4000] - check_insn_relo("\x48\x8d\x05\x00\x40\x00\x00", 7, false, UC_X86_REG_RAX, nullptr); - - // mov rax, [rip + 0x4000] - check_insn_relo("\x48\x8b\x05\x00\x40\x00\x00", 7, true, -1, nullptr); - - return 0; -} diff --git a/app/src/main/cpp/Dobby/tests/test_native.cpp b/app/src/main/cpp/Dobby/tests/test_native.cpp deleted file mode 100644 index 21f84a9c..00000000 --- a/app/src/main/cpp/Dobby/tests/test_native.cpp +++ /dev/null @@ -1,30 +0,0 @@ -#include "dobby.h" - -#include -#include - -#define LOG(fmt, ...) printf("[test_native] " fmt, ##__VA_ARGS__) - -void test_execve() { - char *argv[] = {NULL}; - char *envp[] = {NULL}; - - LOG("test execve"); - - DobbyInstrument(DobbySymbolResolver(0, "_execve"), [](void *, DobbyRegisterContext *ctx) { - LOG("execve: %s", (char *)ctx->general.regs.rdi); - return; - }); - - execve("ls", argv, envp); - - return; -} - -int main(int argc, char *argv[]) { - log_set_level(0); - - test_execve(); - - return 0; -} diff --git a/app/src/main/cpp/json.hpp b/app/src/main/cpp/json.hpp deleted file mode 100644 index 8b72ea65..00000000 --- a/app/src/main/cpp/json.hpp +++ /dev/null @@ -1,24765 +0,0 @@ -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.3 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann -// SPDX-License-Identifier: MIT - -/****************************************************************************\ - * Note on documentation: The source files contain links to the online * - * documentation of the public API at https://json.nlohmann.me. This URL * - * contains the most recent documentation and should also be applicable to * - * previous versions; documentation for deprecated functions is not * - * removed, but marked deprecated. See "Generate documentation" section in * - * file docs/README.md. * -\****************************************************************************/ - -#ifndef INCLUDE_NLOHMANN_JSON_HPP_ -#define INCLUDE_NLOHMANN_JSON_HPP_ - -#include // all_of, find, for_each -#include // nullptr_t, ptrdiff_t, size_t -#include // hash, less -#include // initializer_list -#ifndef JSON_NO_IO - #include // istream, ostream -#endif // JSON_NO_IO -#include // random_access_iterator_tag -#include // unique_ptr -#include // string, stoi, to_string -#include // declval, forward, move, pair, swap -#include // vector - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.3 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.3 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -// This file contains all macro definitions affecting or depending on the ABI - -#ifndef JSON_SKIP_LIBRARY_VERSION_CHECK - #if defined(NLOHMANN_JSON_VERSION_MAJOR) && defined(NLOHMANN_JSON_VERSION_MINOR) && defined(NLOHMANN_JSON_VERSION_PATCH) - #if NLOHMANN_JSON_VERSION_MAJOR != 3 || NLOHMANN_JSON_VERSION_MINOR != 11 || NLOHMANN_JSON_VERSION_PATCH != 3 - #warning "Already included a different version of the library!" - #endif - #endif -#endif - -#define NLOHMANN_JSON_VERSION_MAJOR 3 // NOLINT(modernize-macro-to-enum) -#define NLOHMANN_JSON_VERSION_MINOR 11 // NOLINT(modernize-macro-to-enum) -#define NLOHMANN_JSON_VERSION_PATCH 3 // NOLINT(modernize-macro-to-enum) - -#ifndef JSON_DIAGNOSTICS - #define JSON_DIAGNOSTICS 0 -#endif - -#ifndef JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON - #define JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON 0 -#endif - -#if JSON_DIAGNOSTICS - #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS _diag -#else - #define NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS -#endif - -#if JSON_USE_LEGACY_DISCARDED_VALUE_COMPARISON - #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON _ldvcmp -#else - #define NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON -#endif - -#ifndef NLOHMANN_JSON_NAMESPACE_NO_VERSION - #define NLOHMANN_JSON_NAMESPACE_NO_VERSION 0 -#endif - -// Construct the namespace ABI tags component -#define NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) json_abi ## a ## b -#define NLOHMANN_JSON_ABI_TAGS_CONCAT(a, b) \ - NLOHMANN_JSON_ABI_TAGS_CONCAT_EX(a, b) - -#define NLOHMANN_JSON_ABI_TAGS \ - NLOHMANN_JSON_ABI_TAGS_CONCAT( \ - NLOHMANN_JSON_ABI_TAG_DIAGNOSTICS, \ - NLOHMANN_JSON_ABI_TAG_LEGACY_DISCARDED_VALUE_COMPARISON) - -// Construct the namespace version component -#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) \ - _v ## major ## _ ## minor ## _ ## patch -#define NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(major, minor, patch) \ - NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT_EX(major, minor, patch) - -#if NLOHMANN_JSON_NAMESPACE_NO_VERSION -#define NLOHMANN_JSON_NAMESPACE_VERSION -#else -#define NLOHMANN_JSON_NAMESPACE_VERSION \ - NLOHMANN_JSON_NAMESPACE_VERSION_CONCAT(NLOHMANN_JSON_VERSION_MAJOR, \ - NLOHMANN_JSON_VERSION_MINOR, \ - NLOHMANN_JSON_VERSION_PATCH) -#endif - -// Combine namespace components -#define NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) a ## b -#define NLOHMANN_JSON_NAMESPACE_CONCAT(a, b) \ - NLOHMANN_JSON_NAMESPACE_CONCAT_EX(a, b) - -#ifndef NLOHMANN_JSON_NAMESPACE -#define NLOHMANN_JSON_NAMESPACE \ - nlohmann::NLOHMANN_JSON_NAMESPACE_CONCAT( \ - NLOHMANN_JSON_ABI_TAGS, \ - NLOHMANN_JSON_NAMESPACE_VERSION) -#endif - -#ifndef NLOHMANN_JSON_NAMESPACE_BEGIN -#define NLOHMANN_JSON_NAMESPACE_BEGIN \ - namespace nlohmann \ - { \ - inline namespace NLOHMANN_JSON_NAMESPACE_CONCAT( \ - NLOHMANN_JSON_ABI_TAGS, \ - NLOHMANN_JSON_NAMESPACE_VERSION) \ - { -#endif - -#ifndef NLOHMANN_JSON_NAMESPACE_END -#define NLOHMANN_JSON_NAMESPACE_END \ - } /* namespace (inline namespace) NOLINT(readability/namespace) */ \ - } // namespace nlohmann -#endif - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.3 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include // transform -#include // array -#include // forward_list -#include // inserter, front_inserter, end -#include // map -#include // string -#include // tuple, make_tuple -#include // is_arithmetic, is_same, is_enum, underlying_type, is_convertible -#include // unordered_map -#include // pair, declval -#include // valarray - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.3 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include // nullptr_t -#include // exception -#if JSON_DIAGNOSTICS - #include // accumulate -#endif -#include // runtime_error -#include // to_string -#include // vector - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.3 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include // array -#include // size_t -#include // uint8_t -#include // string - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.3 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include // declval, pair -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.3 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.3 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -// #include - - -NLOHMANN_JSON_NAMESPACE_BEGIN -namespace detail -{ - -template struct make_void -{ - using type = void; -}; -template using void_t = typename make_void::type; - -} // namespace detail -NLOHMANN_JSON_NAMESPACE_END - - -NLOHMANN_JSON_NAMESPACE_BEGIN -namespace detail -{ - -// https://en.cppreference.com/w/cpp/experimental/is_detected -struct nonesuch -{ - nonesuch() = delete; - ~nonesuch() = delete; - nonesuch(nonesuch const&) = delete; - nonesuch(nonesuch const&&) = delete; - void operator=(nonesuch const&) = delete; - void operator=(nonesuch&&) = delete; -}; - -template class Op, - class... Args> -struct detector -{ - using value_t = std::false_type; - using type = Default; -}; - -template class Op, class... Args> -struct detector>, Op, Args...> -{ - using value_t = std::true_type; - using type = Op; -}; - -template class Op, class... Args> -using is_detected = typename detector::value_t; - -template class Op, class... Args> -struct is_detected_lazy : is_detected { }; - -template class Op, class... Args> -using detected_t = typename detector::type; - -template class Op, class... Args> -using detected_or = detector; - -template class Op, class... Args> -using detected_or_t = typename detected_or::type; - -template class Op, class... Args> -using is_detected_exact = std::is_same>; - -template class Op, class... Args> -using is_detected_convertible = - std::is_convertible, To>; - -} // namespace detail -NLOHMANN_JSON_NAMESPACE_END - -// #include - - -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.3 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann -// SPDX-FileCopyrightText: 2016-2021 Evan Nemerson -// SPDX-License-Identifier: MIT - -/* Hedley - https://nemequ.github.io/hedley - * Created by Evan Nemerson - */ - -#if !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < 15) -#if defined(JSON_HEDLEY_VERSION) - #undef JSON_HEDLEY_VERSION -#endif -#define JSON_HEDLEY_VERSION 15 - -#if defined(JSON_HEDLEY_STRINGIFY_EX) - #undef JSON_HEDLEY_STRINGIFY_EX -#endif -#define JSON_HEDLEY_STRINGIFY_EX(x) #x - -#if defined(JSON_HEDLEY_STRINGIFY) - #undef JSON_HEDLEY_STRINGIFY -#endif -#define JSON_HEDLEY_STRINGIFY(x) JSON_HEDLEY_STRINGIFY_EX(x) - -#if defined(JSON_HEDLEY_CONCAT_EX) - #undef JSON_HEDLEY_CONCAT_EX -#endif -#define JSON_HEDLEY_CONCAT_EX(a,b) a##b - -#if defined(JSON_HEDLEY_CONCAT) - #undef JSON_HEDLEY_CONCAT -#endif -#define JSON_HEDLEY_CONCAT(a,b) JSON_HEDLEY_CONCAT_EX(a,b) - -#if defined(JSON_HEDLEY_CONCAT3_EX) - #undef JSON_HEDLEY_CONCAT3_EX -#endif -#define JSON_HEDLEY_CONCAT3_EX(a,b,c) a##b##c - -#if defined(JSON_HEDLEY_CONCAT3) - #undef JSON_HEDLEY_CONCAT3 -#endif -#define JSON_HEDLEY_CONCAT3(a,b,c) JSON_HEDLEY_CONCAT3_EX(a,b,c) - -#if defined(JSON_HEDLEY_VERSION_ENCODE) - #undef JSON_HEDLEY_VERSION_ENCODE -#endif -#define JSON_HEDLEY_VERSION_ENCODE(major,minor,revision) (((major) * 1000000) + ((minor) * 1000) + (revision)) - -#if defined(JSON_HEDLEY_VERSION_DECODE_MAJOR) - #undef JSON_HEDLEY_VERSION_DECODE_MAJOR -#endif -#define JSON_HEDLEY_VERSION_DECODE_MAJOR(version) ((version) / 1000000) - -#if defined(JSON_HEDLEY_VERSION_DECODE_MINOR) - #undef JSON_HEDLEY_VERSION_DECODE_MINOR -#endif -#define JSON_HEDLEY_VERSION_DECODE_MINOR(version) (((version) % 1000000) / 1000) - -#if defined(JSON_HEDLEY_VERSION_DECODE_REVISION) - #undef JSON_HEDLEY_VERSION_DECODE_REVISION -#endif -#define JSON_HEDLEY_VERSION_DECODE_REVISION(version) ((version) % 1000) - -#if defined(JSON_HEDLEY_GNUC_VERSION) - #undef JSON_HEDLEY_GNUC_VERSION -#endif -#if defined(__GNUC__) && defined(__GNUC_PATCHLEVEL__) - #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__) -#elif defined(__GNUC__) - #define JSON_HEDLEY_GNUC_VERSION JSON_HEDLEY_VERSION_ENCODE(__GNUC__, __GNUC_MINOR__, 0) -#endif - -#if defined(JSON_HEDLEY_GNUC_VERSION_CHECK) - #undef JSON_HEDLEY_GNUC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_GNUC_VERSION) - #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GNUC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_MSVC_VERSION) - #undef JSON_HEDLEY_MSVC_VERSION -#endif -#if defined(_MSC_FULL_VER) && (_MSC_FULL_VER >= 140000000) && !defined(__ICL) - #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 10000000, (_MSC_FULL_VER % 10000000) / 100000, (_MSC_FULL_VER % 100000) / 100) -#elif defined(_MSC_FULL_VER) && !defined(__ICL) - #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_FULL_VER / 1000000, (_MSC_FULL_VER % 1000000) / 10000, (_MSC_FULL_VER % 10000) / 10) -#elif defined(_MSC_VER) && !defined(__ICL) - #define JSON_HEDLEY_MSVC_VERSION JSON_HEDLEY_VERSION_ENCODE(_MSC_VER / 100, _MSC_VER % 100, 0) -#endif - -#if defined(JSON_HEDLEY_MSVC_VERSION_CHECK) - #undef JSON_HEDLEY_MSVC_VERSION_CHECK -#endif -#if !defined(JSON_HEDLEY_MSVC_VERSION) - #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (0) -#elif defined(_MSC_VER) && (_MSC_VER >= 1400) - #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 10000000) + (minor * 100000) + (patch))) -#elif defined(_MSC_VER) && (_MSC_VER >= 1200) - #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_FULL_VER >= ((major * 1000000) + (minor * 10000) + (patch))) -#else - #define JSON_HEDLEY_MSVC_VERSION_CHECK(major,minor,patch) (_MSC_VER >= ((major * 100) + (minor))) -#endif - -#if defined(JSON_HEDLEY_INTEL_VERSION) - #undef JSON_HEDLEY_INTEL_VERSION -#endif -#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && !defined(__ICL) - #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, __INTEL_COMPILER_UPDATE) -#elif defined(__INTEL_COMPILER) && !defined(__ICL) - #define JSON_HEDLEY_INTEL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER / 100, __INTEL_COMPILER % 100, 0) -#endif - -#if defined(JSON_HEDLEY_INTEL_VERSION_CHECK) - #undef JSON_HEDLEY_INTEL_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_INTEL_VERSION) - #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_INTEL_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_INTEL_CL_VERSION) - #undef JSON_HEDLEY_INTEL_CL_VERSION -#endif -#if defined(__INTEL_COMPILER) && defined(__INTEL_COMPILER_UPDATE) && defined(__ICL) - #define JSON_HEDLEY_INTEL_CL_VERSION JSON_HEDLEY_VERSION_ENCODE(__INTEL_COMPILER, __INTEL_COMPILER_UPDATE, 0) -#endif - -#if defined(JSON_HEDLEY_INTEL_CL_VERSION_CHECK) - #undef JSON_HEDLEY_INTEL_CL_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_INTEL_CL_VERSION) - #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_INTEL_CL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_INTEL_CL_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_PGI_VERSION) - #undef JSON_HEDLEY_PGI_VERSION -#endif -#if defined(__PGI) && defined(__PGIC__) && defined(__PGIC_MINOR__) && defined(__PGIC_PATCHLEVEL__) - #define JSON_HEDLEY_PGI_VERSION JSON_HEDLEY_VERSION_ENCODE(__PGIC__, __PGIC_MINOR__, __PGIC_PATCHLEVEL__) -#endif - -#if defined(JSON_HEDLEY_PGI_VERSION_CHECK) - #undef JSON_HEDLEY_PGI_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_PGI_VERSION) - #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PGI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_PGI_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_SUNPRO_VERSION) - #undef JSON_HEDLEY_SUNPRO_VERSION -#endif -#if defined(__SUNPRO_C) && (__SUNPRO_C > 0x1000) - #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_C >> 16) & 0xf) * 10) + ((__SUNPRO_C >> 12) & 0xf), (((__SUNPRO_C >> 8) & 0xf) * 10) + ((__SUNPRO_C >> 4) & 0xf), (__SUNPRO_C & 0xf) * 10) -#elif defined(__SUNPRO_C) - #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_C >> 8) & 0xf, (__SUNPRO_C >> 4) & 0xf, (__SUNPRO_C) & 0xf) -#elif defined(__SUNPRO_CC) && (__SUNPRO_CC > 0x1000) - #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((((__SUNPRO_CC >> 16) & 0xf) * 10) + ((__SUNPRO_CC >> 12) & 0xf), (((__SUNPRO_CC >> 8) & 0xf) * 10) + ((__SUNPRO_CC >> 4) & 0xf), (__SUNPRO_CC & 0xf) * 10) -#elif defined(__SUNPRO_CC) - #define JSON_HEDLEY_SUNPRO_VERSION JSON_HEDLEY_VERSION_ENCODE((__SUNPRO_CC >> 8) & 0xf, (__SUNPRO_CC >> 4) & 0xf, (__SUNPRO_CC) & 0xf) -#endif - -#if defined(JSON_HEDLEY_SUNPRO_VERSION_CHECK) - #undef JSON_HEDLEY_SUNPRO_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_SUNPRO_VERSION) - #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_SUNPRO_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_SUNPRO_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION) - #undef JSON_HEDLEY_EMSCRIPTEN_VERSION -#endif -#if defined(__EMSCRIPTEN__) - #define JSON_HEDLEY_EMSCRIPTEN_VERSION JSON_HEDLEY_VERSION_ENCODE(__EMSCRIPTEN_major__, __EMSCRIPTEN_minor__, __EMSCRIPTEN_tiny__) -#endif - -#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK) - #undef JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_EMSCRIPTEN_VERSION) - #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_EMSCRIPTEN_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_EMSCRIPTEN_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_ARM_VERSION) - #undef JSON_HEDLEY_ARM_VERSION -#endif -#if defined(__CC_ARM) && defined(__ARMCOMPILER_VERSION) - #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCOMPILER_VERSION / 1000000, (__ARMCOMPILER_VERSION % 1000000) / 10000, (__ARMCOMPILER_VERSION % 10000) / 100) -#elif defined(__CC_ARM) && defined(__ARMCC_VERSION) - #define JSON_HEDLEY_ARM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ARMCC_VERSION / 1000000, (__ARMCC_VERSION % 1000000) / 10000, (__ARMCC_VERSION % 10000) / 100) -#endif - -#if defined(JSON_HEDLEY_ARM_VERSION_CHECK) - #undef JSON_HEDLEY_ARM_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_ARM_VERSION) - #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_ARM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_ARM_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_IBM_VERSION) - #undef JSON_HEDLEY_IBM_VERSION -#endif -#if defined(__ibmxl__) - #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__ibmxl_version__, __ibmxl_release__, __ibmxl_modification__) -#elif defined(__xlC__) && defined(__xlC_ver__) - #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, (__xlC_ver__ >> 8) & 0xff) -#elif defined(__xlC__) - #define JSON_HEDLEY_IBM_VERSION JSON_HEDLEY_VERSION_ENCODE(__xlC__ >> 8, __xlC__ & 0xff, 0) -#endif - -#if defined(JSON_HEDLEY_IBM_VERSION_CHECK) - #undef JSON_HEDLEY_IBM_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_IBM_VERSION) - #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IBM_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_IBM_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_VERSION) - #undef JSON_HEDLEY_TI_VERSION -#endif -#if \ - defined(__TI_COMPILER_VERSION__) && \ - ( \ - defined(__TMS470__) || defined(__TI_ARM__) || \ - defined(__MSP430__) || \ - defined(__TMS320C2000__) \ - ) -#if (__TI_COMPILER_VERSION__ >= 16000000) - #define JSON_HEDLEY_TI_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif -#endif - -#if defined(JSON_HEDLEY_TI_VERSION_CHECK) - #undef JSON_HEDLEY_TI_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_VERSION) - #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CL2000_VERSION) - #undef JSON_HEDLEY_TI_CL2000_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C2000__) - #define JSON_HEDLEY_TI_CL2000_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CL2000_VERSION_CHECK) - #undef JSON_HEDLEY_TI_CL2000_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CL2000_VERSION) - #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL2000_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_CL2000_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CL430_VERSION) - #undef JSON_HEDLEY_TI_CL430_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__MSP430__) - #define JSON_HEDLEY_TI_CL430_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CL430_VERSION_CHECK) - #undef JSON_HEDLEY_TI_CL430_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CL430_VERSION) - #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL430_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_CL430_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_ARMCL_VERSION) - #undef JSON_HEDLEY_TI_ARMCL_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && (defined(__TMS470__) || defined(__TI_ARM__)) - #define JSON_HEDLEY_TI_ARMCL_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_ARMCL_VERSION_CHECK) - #undef JSON_HEDLEY_TI_ARMCL_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_ARMCL_VERSION) - #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_ARMCL_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CL6X_VERSION) - #undef JSON_HEDLEY_TI_CL6X_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__TMS320C6X__) - #define JSON_HEDLEY_TI_CL6X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CL6X_VERSION_CHECK) - #undef JSON_HEDLEY_TI_CL6X_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CL6X_VERSION) - #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL6X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_CL6X_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CL7X_VERSION) - #undef JSON_HEDLEY_TI_CL7X_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__C7000__) - #define JSON_HEDLEY_TI_CL7X_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CL7X_VERSION_CHECK) - #undef JSON_HEDLEY_TI_CL7X_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CL7X_VERSION) - #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CL7X_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_CL7X_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TI_CLPRU_VERSION) - #undef JSON_HEDLEY_TI_CLPRU_VERSION -#endif -#if defined(__TI_COMPILER_VERSION__) && defined(__PRU__) - #define JSON_HEDLEY_TI_CLPRU_VERSION JSON_HEDLEY_VERSION_ENCODE(__TI_COMPILER_VERSION__ / 1000000, (__TI_COMPILER_VERSION__ % 1000000) / 1000, (__TI_COMPILER_VERSION__ % 1000)) -#endif - -#if defined(JSON_HEDLEY_TI_CLPRU_VERSION_CHECK) - #undef JSON_HEDLEY_TI_CLPRU_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TI_CLPRU_VERSION) - #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TI_CLPRU_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_CRAY_VERSION) - #undef JSON_HEDLEY_CRAY_VERSION -#endif -#if defined(_CRAYC) - #if defined(_RELEASE_PATCHLEVEL) - #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, _RELEASE_PATCHLEVEL) - #else - #define JSON_HEDLEY_CRAY_VERSION JSON_HEDLEY_VERSION_ENCODE(_RELEASE_MAJOR, _RELEASE_MINOR, 0) - #endif -#endif - -#if defined(JSON_HEDLEY_CRAY_VERSION_CHECK) - #undef JSON_HEDLEY_CRAY_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_CRAY_VERSION) - #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_CRAY_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_CRAY_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_IAR_VERSION) - #undef JSON_HEDLEY_IAR_VERSION -#endif -#if defined(__IAR_SYSTEMS_ICC__) - #if __VER__ > 1000 - #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE((__VER__ / 1000000), ((__VER__ / 1000) % 1000), (__VER__ % 1000)) - #else - #define JSON_HEDLEY_IAR_VERSION JSON_HEDLEY_VERSION_ENCODE(__VER__ / 100, __VER__ % 100, 0) - #endif -#endif - -#if defined(JSON_HEDLEY_IAR_VERSION_CHECK) - #undef JSON_HEDLEY_IAR_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_IAR_VERSION) - #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_IAR_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_IAR_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_TINYC_VERSION) - #undef JSON_HEDLEY_TINYC_VERSION -#endif -#if defined(__TINYC__) - #define JSON_HEDLEY_TINYC_VERSION JSON_HEDLEY_VERSION_ENCODE(__TINYC__ / 1000, (__TINYC__ / 100) % 10, __TINYC__ % 100) -#endif - -#if defined(JSON_HEDLEY_TINYC_VERSION_CHECK) - #undef JSON_HEDLEY_TINYC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_TINYC_VERSION) - #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_TINYC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_TINYC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_DMC_VERSION) - #undef JSON_HEDLEY_DMC_VERSION -#endif -#if defined(__DMC__) - #define JSON_HEDLEY_DMC_VERSION JSON_HEDLEY_VERSION_ENCODE(__DMC__ >> 8, (__DMC__ >> 4) & 0xf, __DMC__ & 0xf) -#endif - -#if defined(JSON_HEDLEY_DMC_VERSION_CHECK) - #undef JSON_HEDLEY_DMC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_DMC_VERSION) - #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_DMC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_DMC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_COMPCERT_VERSION) - #undef JSON_HEDLEY_COMPCERT_VERSION -#endif -#if defined(__COMPCERT_VERSION__) - #define JSON_HEDLEY_COMPCERT_VERSION JSON_HEDLEY_VERSION_ENCODE(__COMPCERT_VERSION__ / 10000, (__COMPCERT_VERSION__ / 100) % 100, __COMPCERT_VERSION__ % 100) -#endif - -#if defined(JSON_HEDLEY_COMPCERT_VERSION_CHECK) - #undef JSON_HEDLEY_COMPCERT_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_COMPCERT_VERSION) - #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_COMPCERT_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_COMPCERT_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_PELLES_VERSION) - #undef JSON_HEDLEY_PELLES_VERSION -#endif -#if defined(__POCC__) - #define JSON_HEDLEY_PELLES_VERSION JSON_HEDLEY_VERSION_ENCODE(__POCC__ / 100, __POCC__ % 100, 0) -#endif - -#if defined(JSON_HEDLEY_PELLES_VERSION_CHECK) - #undef JSON_HEDLEY_PELLES_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_PELLES_VERSION) - #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_PELLES_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_PELLES_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_MCST_LCC_VERSION) - #undef JSON_HEDLEY_MCST_LCC_VERSION -#endif -#if defined(__LCC__) && defined(__LCC_MINOR__) - #define JSON_HEDLEY_MCST_LCC_VERSION JSON_HEDLEY_VERSION_ENCODE(__LCC__ / 100, __LCC__ % 100, __LCC_MINOR__) -#endif - -#if defined(JSON_HEDLEY_MCST_LCC_VERSION_CHECK) - #undef JSON_HEDLEY_MCST_LCC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_MCST_LCC_VERSION) - #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_MCST_LCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_MCST_LCC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_GCC_VERSION) - #undef JSON_HEDLEY_GCC_VERSION -#endif -#if \ - defined(JSON_HEDLEY_GNUC_VERSION) && \ - !defined(__clang__) && \ - !defined(JSON_HEDLEY_INTEL_VERSION) && \ - !defined(JSON_HEDLEY_PGI_VERSION) && \ - !defined(JSON_HEDLEY_ARM_VERSION) && \ - !defined(JSON_HEDLEY_CRAY_VERSION) && \ - !defined(JSON_HEDLEY_TI_VERSION) && \ - !defined(JSON_HEDLEY_TI_ARMCL_VERSION) && \ - !defined(JSON_HEDLEY_TI_CL430_VERSION) && \ - !defined(JSON_HEDLEY_TI_CL2000_VERSION) && \ - !defined(JSON_HEDLEY_TI_CL6X_VERSION) && \ - !defined(JSON_HEDLEY_TI_CL7X_VERSION) && \ - !defined(JSON_HEDLEY_TI_CLPRU_VERSION) && \ - !defined(__COMPCERT__) && \ - !defined(JSON_HEDLEY_MCST_LCC_VERSION) - #define JSON_HEDLEY_GCC_VERSION JSON_HEDLEY_GNUC_VERSION -#endif - -#if defined(JSON_HEDLEY_GCC_VERSION_CHECK) - #undef JSON_HEDLEY_GCC_VERSION_CHECK -#endif -#if defined(JSON_HEDLEY_GCC_VERSION) - #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (JSON_HEDLEY_GCC_VERSION >= JSON_HEDLEY_VERSION_ENCODE(major, minor, patch)) -#else - #define JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) (0) -#endif - -#if defined(JSON_HEDLEY_HAS_ATTRIBUTE) - #undef JSON_HEDLEY_HAS_ATTRIBUTE -#endif -#if \ - defined(__has_attribute) && \ - ( \ - (!defined(JSON_HEDLEY_IAR_VERSION) || JSON_HEDLEY_IAR_VERSION_CHECK(8,5,9)) \ - ) -# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) __has_attribute(attribute) -#else -# define JSON_HEDLEY_HAS_ATTRIBUTE(attribute) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_ATTRIBUTE) - #undef JSON_HEDLEY_GNUC_HAS_ATTRIBUTE -#endif -#if defined(__has_attribute) - #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) -#else - #define JSON_HEDLEY_GNUC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_ATTRIBUTE) - #undef JSON_HEDLEY_GCC_HAS_ATTRIBUTE -#endif -#if defined(__has_attribute) - #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) -#else - #define JSON_HEDLEY_GCC_HAS_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE) - #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE -#endif -#if \ - defined(__has_cpp_attribute) && \ - defined(__cplusplus) && \ - (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) - #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) __has_cpp_attribute(attribute) -#else - #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) (0) -#endif - -#if defined(JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS) - #undef JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS -#endif -#if !defined(__cplusplus) || !defined(__has_cpp_attribute) - #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0) -#elif \ - !defined(JSON_HEDLEY_PGI_VERSION) && \ - !defined(JSON_HEDLEY_IAR_VERSION) && \ - (!defined(JSON_HEDLEY_SUNPRO_VERSION) || JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0)) && \ - (!defined(JSON_HEDLEY_MSVC_VERSION) || JSON_HEDLEY_MSVC_VERSION_CHECK(19,20,0)) - #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(ns::attribute) -#else - #define JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(ns,attribute) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE) - #undef JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE -#endif -#if defined(__has_cpp_attribute) && defined(__cplusplus) - #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute) -#else - #define JSON_HEDLEY_GNUC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE) - #undef JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE -#endif -#if defined(__has_cpp_attribute) && defined(__cplusplus) - #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) __has_cpp_attribute(attribute) -#else - #define JSON_HEDLEY_GCC_HAS_CPP_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_BUILTIN) - #undef JSON_HEDLEY_HAS_BUILTIN -#endif -#if defined(__has_builtin) - #define JSON_HEDLEY_HAS_BUILTIN(builtin) __has_builtin(builtin) -#else - #define JSON_HEDLEY_HAS_BUILTIN(builtin) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_BUILTIN) - #undef JSON_HEDLEY_GNUC_HAS_BUILTIN -#endif -#if defined(__has_builtin) - #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin) -#else - #define JSON_HEDLEY_GNUC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_BUILTIN) - #undef JSON_HEDLEY_GCC_HAS_BUILTIN -#endif -#if defined(__has_builtin) - #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) __has_builtin(builtin) -#else - #define JSON_HEDLEY_GCC_HAS_BUILTIN(builtin,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_FEATURE) - #undef JSON_HEDLEY_HAS_FEATURE -#endif -#if defined(__has_feature) - #define JSON_HEDLEY_HAS_FEATURE(feature) __has_feature(feature) -#else - #define JSON_HEDLEY_HAS_FEATURE(feature) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_FEATURE) - #undef JSON_HEDLEY_GNUC_HAS_FEATURE -#endif -#if defined(__has_feature) - #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature) -#else - #define JSON_HEDLEY_GNUC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_FEATURE) - #undef JSON_HEDLEY_GCC_HAS_FEATURE -#endif -#if defined(__has_feature) - #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) __has_feature(feature) -#else - #define JSON_HEDLEY_GCC_HAS_FEATURE(feature,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_EXTENSION) - #undef JSON_HEDLEY_HAS_EXTENSION -#endif -#if defined(__has_extension) - #define JSON_HEDLEY_HAS_EXTENSION(extension) __has_extension(extension) -#else - #define JSON_HEDLEY_HAS_EXTENSION(extension) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_EXTENSION) - #undef JSON_HEDLEY_GNUC_HAS_EXTENSION -#endif -#if defined(__has_extension) - #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension) -#else - #define JSON_HEDLEY_GNUC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_EXTENSION) - #undef JSON_HEDLEY_GCC_HAS_EXTENSION -#endif -#if defined(__has_extension) - #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) __has_extension(extension) -#else - #define JSON_HEDLEY_GCC_HAS_EXTENSION(extension,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE) - #undef JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE -#endif -#if defined(__has_declspec_attribute) - #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) __has_declspec_attribute(attribute) -#else - #define JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE) - #undef JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE -#endif -#if defined(__has_declspec_attribute) - #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute) -#else - #define JSON_HEDLEY_GNUC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE) - #undef JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE -#endif -#if defined(__has_declspec_attribute) - #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) __has_declspec_attribute(attribute) -#else - #define JSON_HEDLEY_GCC_HAS_DECLSPEC_ATTRIBUTE(attribute,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_HAS_WARNING) - #undef JSON_HEDLEY_HAS_WARNING -#endif -#if defined(__has_warning) - #define JSON_HEDLEY_HAS_WARNING(warning) __has_warning(warning) -#else - #define JSON_HEDLEY_HAS_WARNING(warning) (0) -#endif - -#if defined(JSON_HEDLEY_GNUC_HAS_WARNING) - #undef JSON_HEDLEY_GNUC_HAS_WARNING -#endif -#if defined(__has_warning) - #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning) -#else - #define JSON_HEDLEY_GNUC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GNUC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_GCC_HAS_WARNING) - #undef JSON_HEDLEY_GCC_HAS_WARNING -#endif -#if defined(__has_warning) - #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) __has_warning(warning) -#else - #define JSON_HEDLEY_GCC_HAS_WARNING(warning,major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if \ - (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ - defined(__clang__) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,0,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) || \ - JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,17) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(8,0,0) || \ - (JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) && defined(__C99_PRAGMA_OPERATOR)) - #define JSON_HEDLEY_PRAGMA(value) _Pragma(#value) -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) - #define JSON_HEDLEY_PRAGMA(value) __pragma(value) -#else - #define JSON_HEDLEY_PRAGMA(value) -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_PUSH) - #undef JSON_HEDLEY_DIAGNOSTIC_PUSH -#endif -#if defined(JSON_HEDLEY_DIAGNOSTIC_POP) - #undef JSON_HEDLEY_DIAGNOSTIC_POP -#endif -#if defined(__clang__) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("clang diagnostic push") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("clang diagnostic pop") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("GCC diagnostic push") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("GCC diagnostic pop") -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH __pragma(warning(push)) - #define JSON_HEDLEY_DIAGNOSTIC_POP __pragma(warning(pop)) -#elif JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("push") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("pop") -#elif \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,4,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("diag_push") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("diag_pop") -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0) - #define JSON_HEDLEY_DIAGNOSTIC_PUSH _Pragma("warning(push)") - #define JSON_HEDLEY_DIAGNOSTIC_POP _Pragma("warning(pop)") -#else - #define JSON_HEDLEY_DIAGNOSTIC_PUSH - #define JSON_HEDLEY_DIAGNOSTIC_POP -#endif - -/* JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ is for - HEDLEY INTERNAL USE ONLY. API subject to change without notice. */ -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_ -#endif -#if defined(__cplusplus) -# if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat") -# if JSON_HEDLEY_HAS_WARNING("-Wc++17-extensions") -# if JSON_HEDLEY_HAS_WARNING("-Wc++1z-extensions") -# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ - _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \ - _Pragma("clang diagnostic ignored \"-Wc++1z-extensions\"") \ - xpr \ - JSON_HEDLEY_DIAGNOSTIC_POP -# else -# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ - _Pragma("clang diagnostic ignored \"-Wc++17-extensions\"") \ - xpr \ - JSON_HEDLEY_DIAGNOSTIC_POP -# endif -# else -# define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(xpr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wc++98-compat\"") \ - xpr \ - JSON_HEDLEY_DIAGNOSTIC_POP -# endif -# endif -#endif -#if !defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(x) x -#endif - -#if defined(JSON_HEDLEY_CONST_CAST) - #undef JSON_HEDLEY_CONST_CAST -#endif -#if defined(__cplusplus) -# define JSON_HEDLEY_CONST_CAST(T, expr) (const_cast(expr)) -#elif \ - JSON_HEDLEY_HAS_WARNING("-Wcast-qual") || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) -# define JSON_HEDLEY_CONST_CAST(T, expr) (__extension__ ({ \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL \ - ((T) (expr)); \ - JSON_HEDLEY_DIAGNOSTIC_POP \ - })) -#else -# define JSON_HEDLEY_CONST_CAST(T, expr) ((T) (expr)) -#endif - -#if defined(JSON_HEDLEY_REINTERPRET_CAST) - #undef JSON_HEDLEY_REINTERPRET_CAST -#endif -#if defined(__cplusplus) - #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) (reinterpret_cast(expr)) -#else - #define JSON_HEDLEY_REINTERPRET_CAST(T, expr) ((T) (expr)) -#endif - -#if defined(JSON_HEDLEY_STATIC_CAST) - #undef JSON_HEDLEY_STATIC_CAST -#endif -#if defined(__cplusplus) - #define JSON_HEDLEY_STATIC_CAST(T, expr) (static_cast(expr)) -#else - #define JSON_HEDLEY_STATIC_CAST(T, expr) ((T) (expr)) -#endif - -#if defined(JSON_HEDLEY_CPP_CAST) - #undef JSON_HEDLEY_CPP_CAST -#endif -#if defined(__cplusplus) -# if JSON_HEDLEY_HAS_WARNING("-Wold-style-cast") -# define JSON_HEDLEY_CPP_CAST(T, expr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wold-style-cast\"") \ - ((T) (expr)) \ - JSON_HEDLEY_DIAGNOSTIC_POP -# elif JSON_HEDLEY_IAR_VERSION_CHECK(8,3,0) -# define JSON_HEDLEY_CPP_CAST(T, expr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("diag_suppress=Pe137") \ - JSON_HEDLEY_DIAGNOSTIC_POP -# else -# define JSON_HEDLEY_CPP_CAST(T, expr) ((T) (expr)) -# endif -#else -# define JSON_HEDLEY_CPP_CAST(T, expr) (expr) -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wdeprecated-declarations") - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("clang diagnostic ignored \"-Wdeprecated-declarations\"") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warning(disable:1478 1786)") -#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:1478 1786)) -#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1216,1444,1445") -#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED __pragma(warning(disable:4996)) -#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1215,1444") -#elif \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress 1291,1718") -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && !defined(__cplusplus) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,E_DEPRECATED_ATT,E_DEPRECATED_ATT_MESS)") -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) && defined(__cplusplus) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("error_messages(off,symdeprecated,symdeprecated2)") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("diag_suppress=Pe1444,Pe1215") -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,90,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED _Pragma("warn(disable:2241)") -#else - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_DEPRECATED -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("clang diagnostic ignored \"-Wunknown-pragmas\"") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("warning(disable:161)") -#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:161)) -#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 1675") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("GCC diagnostic ignored \"-Wunknown-pragmas\"") -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS __pragma(warning(disable:4068)) -#elif \ - JSON_HEDLEY_TI_VERSION_CHECK(16,9,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163") -#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 163") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress=Pe161") -#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS _Pragma("diag_suppress 161") -#else - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunknown-attributes") - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("clang diagnostic ignored \"-Wunknown-attributes\"") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(4,6,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("warning(disable:1292)") -#elif JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:1292)) -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES __pragma(warning(disable:5030)) -#elif JSON_HEDLEY_PGI_VERSION_CHECK(20,7,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097,1098") -#elif JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097") -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("error_messages(off,attrskipunsup)") -#elif \ - JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1173") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress=Pe1097") -#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES _Pragma("diag_suppress 1097") -#else - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_CPP_ATTRIBUTES -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wcast-qual") - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("clang diagnostic ignored \"-Wcast-qual\"") -#elif JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("warning(disable:2203 2331)") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL _Pragma("GCC diagnostic ignored \"-Wcast-qual\"") -#else - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_CAST_QUAL -#endif - -#if defined(JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION) - #undef JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunused-function") - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("clang diagnostic ignored \"-Wunused-function\"") -#elif JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("GCC diagnostic ignored \"-Wunused-function\"") -#elif JSON_HEDLEY_MSVC_VERSION_CHECK(1,0,0) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION __pragma(warning(disable:4505)) -#elif JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION _Pragma("diag_suppress 3142") -#else - #define JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNUSED_FUNCTION -#endif - -#if defined(JSON_HEDLEY_DEPRECATED) - #undef JSON_HEDLEY_DEPRECATED -#endif -#if defined(JSON_HEDLEY_DEPRECATED_FOR) - #undef JSON_HEDLEY_DEPRECATED_FOR -#endif -#if \ - JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated("Since " # since)) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated("Since " #since "; use " #replacement)) -#elif \ - (JSON_HEDLEY_HAS_EXTENSION(attribute_deprecated_with_message) && !defined(JSON_HEDLEY_IAR_VERSION)) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,13,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(18,1,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(18,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,3,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,3,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__("Since " #since))) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__("Since " #since "; use " #replacement))) -#elif defined(__cplusplus) && (__cplusplus >= 201402L) - #define JSON_HEDLEY_DEPRECATED(since) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since)]]) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[deprecated("Since " #since "; use " #replacement)]]) -#elif \ - JSON_HEDLEY_HAS_ATTRIBUTE(deprecated) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) - #define JSON_HEDLEY_DEPRECATED(since) __attribute__((__deprecated__)) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __attribute__((__deprecated__)) -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ - JSON_HEDLEY_PELLES_VERSION_CHECK(6,50,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_DEPRECATED(since) __declspec(deprecated) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) __declspec(deprecated) -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_DEPRECATED(since) _Pragma("deprecated") - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) _Pragma("deprecated") -#else - #define JSON_HEDLEY_DEPRECATED(since) - #define JSON_HEDLEY_DEPRECATED_FOR(since, replacement) -#endif - -#if defined(JSON_HEDLEY_UNAVAILABLE) - #undef JSON_HEDLEY_UNAVAILABLE -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(warning) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,3,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_UNAVAILABLE(available_since) __attribute__((__warning__("Not available until " #available_since))) -#else - #define JSON_HEDLEY_UNAVAILABLE(available_since) -#endif - -#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT) - #undef JSON_HEDLEY_WARN_UNUSED_RESULT -#endif -#if defined(JSON_HEDLEY_WARN_UNUSED_RESULT_MSG) - #undef JSON_HEDLEY_WARN_UNUSED_RESULT_MSG -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(warn_unused_result) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_WARN_UNUSED_RESULT __attribute__((__warn_unused_result__)) - #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) __attribute__((__warn_unused_result__)) -#elif (JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) >= 201907L) - #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) - #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard(msg)]]) -#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(nodiscard) - #define JSON_HEDLEY_WARN_UNUSED_RESULT JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) - #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[nodiscard]]) -#elif defined(_Check_return_) /* SAL */ - #define JSON_HEDLEY_WARN_UNUSED_RESULT _Check_return_ - #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) _Check_return_ -#else - #define JSON_HEDLEY_WARN_UNUSED_RESULT - #define JSON_HEDLEY_WARN_UNUSED_RESULT_MSG(msg) -#endif - -#if defined(JSON_HEDLEY_SENTINEL) - #undef JSON_HEDLEY_SENTINEL -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(sentinel) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_SENTINEL(position) __attribute__((__sentinel__(position))) -#else - #define JSON_HEDLEY_SENTINEL(position) -#endif - -#if defined(JSON_HEDLEY_NO_RETURN) - #undef JSON_HEDLEY_NO_RETURN -#endif -#if JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_NO_RETURN __noreturn -#elif \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__)) -#elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L - #define JSON_HEDLEY_NO_RETURN _Noreturn -#elif defined(__cplusplus) && (__cplusplus >= 201103L) - #define JSON_HEDLEY_NO_RETURN JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[noreturn]]) -#elif \ - JSON_HEDLEY_HAS_ATTRIBUTE(noreturn) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,2,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) - #define JSON_HEDLEY_NO_RETURN __attribute__((__noreturn__)) -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) - #define JSON_HEDLEY_NO_RETURN _Pragma("does_not_return") -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_NO_RETURN __declspec(noreturn) -#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus) - #define JSON_HEDLEY_NO_RETURN _Pragma("FUNC_NEVER_RETURNS;") -#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0) - #define JSON_HEDLEY_NO_RETURN __attribute((noreturn)) -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0) - #define JSON_HEDLEY_NO_RETURN __declspec(noreturn) -#else - #define JSON_HEDLEY_NO_RETURN -#endif - -#if defined(JSON_HEDLEY_NO_ESCAPE) - #undef JSON_HEDLEY_NO_ESCAPE -#endif -#if JSON_HEDLEY_HAS_ATTRIBUTE(noescape) - #define JSON_HEDLEY_NO_ESCAPE __attribute__((__noescape__)) -#else - #define JSON_HEDLEY_NO_ESCAPE -#endif - -#if defined(JSON_HEDLEY_UNREACHABLE) - #undef JSON_HEDLEY_UNREACHABLE -#endif -#if defined(JSON_HEDLEY_UNREACHABLE_RETURN) - #undef JSON_HEDLEY_UNREACHABLE_RETURN -#endif -#if defined(JSON_HEDLEY_ASSUME) - #undef JSON_HEDLEY_ASSUME -#endif -#if \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_ASSUME(expr) __assume(expr) -#elif JSON_HEDLEY_HAS_BUILTIN(__builtin_assume) - #define JSON_HEDLEY_ASSUME(expr) __builtin_assume(expr) -#elif \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) - #if defined(__cplusplus) - #define JSON_HEDLEY_ASSUME(expr) std::_nassert(expr) - #else - #define JSON_HEDLEY_ASSUME(expr) _nassert(expr) - #endif -#endif -#if \ - (JSON_HEDLEY_HAS_BUILTIN(__builtin_unreachable) && (!defined(JSON_HEDLEY_ARM_VERSION))) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,5,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(18,10,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(13,1,5) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(10,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_UNREACHABLE() __builtin_unreachable() -#elif defined(JSON_HEDLEY_ASSUME) - #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0) -#endif -#if !defined(JSON_HEDLEY_ASSUME) - #if defined(JSON_HEDLEY_UNREACHABLE) - #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, ((expr) ? 1 : (JSON_HEDLEY_UNREACHABLE(), 1))) - #else - #define JSON_HEDLEY_ASSUME(expr) JSON_HEDLEY_STATIC_CAST(void, expr) - #endif -#endif -#if defined(JSON_HEDLEY_UNREACHABLE) - #if \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) - #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (JSON_HEDLEY_STATIC_CAST(void, JSON_HEDLEY_ASSUME(0)), (value)) - #else - #define JSON_HEDLEY_UNREACHABLE_RETURN(value) JSON_HEDLEY_UNREACHABLE() - #endif -#else - #define JSON_HEDLEY_UNREACHABLE_RETURN(value) return (value) -#endif -#if !defined(JSON_HEDLEY_UNREACHABLE) - #define JSON_HEDLEY_UNREACHABLE() JSON_HEDLEY_ASSUME(0) -#endif - -JSON_HEDLEY_DIAGNOSTIC_PUSH -#if JSON_HEDLEY_HAS_WARNING("-Wpedantic") - #pragma clang diagnostic ignored "-Wpedantic" -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wc++98-compat-pedantic") && defined(__cplusplus) - #pragma clang diagnostic ignored "-Wc++98-compat-pedantic" -#endif -#if JSON_HEDLEY_GCC_HAS_WARNING("-Wvariadic-macros",4,0,0) - #if defined(__clang__) - #pragma clang diagnostic ignored "-Wvariadic-macros" - #elif defined(JSON_HEDLEY_GCC_VERSION) - #pragma GCC diagnostic ignored "-Wvariadic-macros" - #endif -#endif -#if defined(JSON_HEDLEY_NON_NULL) - #undef JSON_HEDLEY_NON_NULL -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(nonnull) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) - #define JSON_HEDLEY_NON_NULL(...) __attribute__((__nonnull__(__VA_ARGS__))) -#else - #define JSON_HEDLEY_NON_NULL(...) -#endif -JSON_HEDLEY_DIAGNOSTIC_POP - -#if defined(JSON_HEDLEY_PRINTF_FORMAT) - #undef JSON_HEDLEY_PRINTF_FORMAT -#endif -#if defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && !defined(__USE_MINGW_ANSI_STDIO) - #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(ms_printf, string_idx, first_to_check))) -#elif defined(__MINGW32__) && JSON_HEDLEY_GCC_HAS_ATTRIBUTE(format,4,4,0) && defined(__USE_MINGW_ANSI_STDIO) - #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(gnu_printf, string_idx, first_to_check))) -#elif \ - JSON_HEDLEY_HAS_ATTRIBUTE(format) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,6,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __attribute__((__format__(__printf__, string_idx, first_to_check))) -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(6,0,0) - #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) __declspec(vaformat(printf,string_idx,first_to_check)) -#else - #define JSON_HEDLEY_PRINTF_FORMAT(string_idx,first_to_check) -#endif - -#if defined(JSON_HEDLEY_CONSTEXPR) - #undef JSON_HEDLEY_CONSTEXPR -#endif -#if defined(__cplusplus) - #if __cplusplus >= 201103L - #define JSON_HEDLEY_CONSTEXPR JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(constexpr) - #endif -#endif -#if !defined(JSON_HEDLEY_CONSTEXPR) - #define JSON_HEDLEY_CONSTEXPR -#endif - -#if defined(JSON_HEDLEY_PREDICT) - #undef JSON_HEDLEY_PREDICT -#endif -#if defined(JSON_HEDLEY_LIKELY) - #undef JSON_HEDLEY_LIKELY -#endif -#if defined(JSON_HEDLEY_UNLIKELY) - #undef JSON_HEDLEY_UNLIKELY -#endif -#if defined(JSON_HEDLEY_UNPREDICTABLE) - #undef JSON_HEDLEY_UNPREDICTABLE -#endif -#if JSON_HEDLEY_HAS_BUILTIN(__builtin_unpredictable) - #define JSON_HEDLEY_UNPREDICTABLE(expr) __builtin_unpredictable((expr)) -#endif -#if \ - (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect_with_probability) && !defined(JSON_HEDLEY_PGI_VERSION)) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(9,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -# define JSON_HEDLEY_PREDICT(expr, value, probability) __builtin_expect_with_probability( (expr), (value), (probability)) -# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) __builtin_expect_with_probability(!!(expr), 1 , (probability)) -# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) __builtin_expect_with_probability(!!(expr), 0 , (probability)) -# define JSON_HEDLEY_LIKELY(expr) __builtin_expect (!!(expr), 1 ) -# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect (!!(expr), 0 ) -#elif \ - (JSON_HEDLEY_HAS_BUILTIN(__builtin_expect) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,15,0) && defined(__cplusplus)) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,7,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,27) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -# define JSON_HEDLEY_PREDICT(expr, expected, probability) \ - (((probability) >= 0.9) ? __builtin_expect((expr), (expected)) : (JSON_HEDLEY_STATIC_CAST(void, expected), (expr))) -# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) \ - (__extension__ ({ \ - double hedley_probability_ = (probability); \ - ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 1) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 0) : !!(expr))); \ - })) -# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) \ - (__extension__ ({ \ - double hedley_probability_ = (probability); \ - ((hedley_probability_ >= 0.9) ? __builtin_expect(!!(expr), 0) : ((hedley_probability_ <= 0.1) ? __builtin_expect(!!(expr), 1) : !!(expr))); \ - })) -# define JSON_HEDLEY_LIKELY(expr) __builtin_expect(!!(expr), 1) -# define JSON_HEDLEY_UNLIKELY(expr) __builtin_expect(!!(expr), 0) -#else -# define JSON_HEDLEY_PREDICT(expr, expected, probability) (JSON_HEDLEY_STATIC_CAST(void, expected), (expr)) -# define JSON_HEDLEY_PREDICT_TRUE(expr, probability) (!!(expr)) -# define JSON_HEDLEY_PREDICT_FALSE(expr, probability) (!!(expr)) -# define JSON_HEDLEY_LIKELY(expr) (!!(expr)) -# define JSON_HEDLEY_UNLIKELY(expr) (!!(expr)) -#endif -#if !defined(JSON_HEDLEY_UNPREDICTABLE) - #define JSON_HEDLEY_UNPREDICTABLE(expr) JSON_HEDLEY_PREDICT(expr, 1, 0.5) -#endif - -#if defined(JSON_HEDLEY_MALLOC) - #undef JSON_HEDLEY_MALLOC -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(malloc) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_MALLOC __attribute__((__malloc__)) -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) - #define JSON_HEDLEY_MALLOC _Pragma("returns_new_memory") -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_MALLOC __declspec(restrict) -#else - #define JSON_HEDLEY_MALLOC -#endif - -#if defined(JSON_HEDLEY_PURE) - #undef JSON_HEDLEY_PURE -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(pure) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(2,96,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -# define JSON_HEDLEY_PURE __attribute__((__pure__)) -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) -# define JSON_HEDLEY_PURE _Pragma("does_not_write_global_data") -#elif defined(__cplusplus) && \ - ( \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(2,0,1) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(4,0,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) \ - ) -# define JSON_HEDLEY_PURE _Pragma("FUNC_IS_PURE;") -#else -# define JSON_HEDLEY_PURE -#endif - -#if defined(JSON_HEDLEY_CONST) - #undef JSON_HEDLEY_CONST -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(const) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(2,5,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_CONST __attribute__((__const__)) -#elif \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) - #define JSON_HEDLEY_CONST _Pragma("no_side_effect") -#else - #define JSON_HEDLEY_CONST JSON_HEDLEY_PURE -#endif - -#if defined(JSON_HEDLEY_RESTRICT) - #undef JSON_HEDLEY_RESTRICT -#endif -#if defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && !defined(__cplusplus) - #define JSON_HEDLEY_RESTRICT restrict -#elif \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_MSVC_VERSION_CHECK(14,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(17,10,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,4) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,14,0) && defined(__cplusplus)) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) || \ - defined(__clang__) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_RESTRICT __restrict -#elif JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,3,0) && !defined(__cplusplus) - #define JSON_HEDLEY_RESTRICT _Restrict -#else - #define JSON_HEDLEY_RESTRICT -#endif - -#if defined(JSON_HEDLEY_INLINE) - #undef JSON_HEDLEY_INLINE -#endif -#if \ - (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L)) || \ - (defined(__cplusplus) && (__cplusplus >= 199711L)) - #define JSON_HEDLEY_INLINE inline -#elif \ - defined(JSON_HEDLEY_GCC_VERSION) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(6,2,0) - #define JSON_HEDLEY_INLINE __inline__ -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,1,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(3,1,0) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,2,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(8,0,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_INLINE __inline -#else - #define JSON_HEDLEY_INLINE -#endif - -#if defined(JSON_HEDLEY_ALWAYS_INLINE) - #undef JSON_HEDLEY_ALWAYS_INLINE -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(always_inline) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) -# define JSON_HEDLEY_ALWAYS_INLINE __attribute__((__always_inline__)) JSON_HEDLEY_INLINE -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(12,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) -# define JSON_HEDLEY_ALWAYS_INLINE __forceinline -#elif defined(__cplusplus) && \ - ( \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) \ - ) -# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("FUNC_ALWAYS_INLINE;") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) -# define JSON_HEDLEY_ALWAYS_INLINE _Pragma("inline=forced") -#else -# define JSON_HEDLEY_ALWAYS_INLINE JSON_HEDLEY_INLINE -#endif - -#if defined(JSON_HEDLEY_NEVER_INLINE) - #undef JSON_HEDLEY_NEVER_INLINE -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(noinline) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(10,1,0) || \ - JSON_HEDLEY_TI_VERSION_CHECK(15,12,0) || \ - (JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(4,8,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_ARMCL_VERSION_CHECK(5,2,0) || \ - (JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL2000_VERSION_CHECK(6,4,0) || \ - (JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,0,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(4,3,0) || \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) || \ - JSON_HEDLEY_TI_CL7X_VERSION_CHECK(1,2,0) || \ - JSON_HEDLEY_TI_CLPRU_VERSION_CHECK(2,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) || \ - JSON_HEDLEY_IAR_VERSION_CHECK(8,10,0) - #define JSON_HEDLEY_NEVER_INLINE __attribute__((__noinline__)) -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,10,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline) -#elif JSON_HEDLEY_PGI_VERSION_CHECK(10,2,0) - #define JSON_HEDLEY_NEVER_INLINE _Pragma("noinline") -#elif JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,0,0) && defined(__cplusplus) - #define JSON_HEDLEY_NEVER_INLINE _Pragma("FUNC_CANNOT_INLINE;") -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) - #define JSON_HEDLEY_NEVER_INLINE _Pragma("inline=never") -#elif JSON_HEDLEY_COMPCERT_VERSION_CHECK(3,2,0) - #define JSON_HEDLEY_NEVER_INLINE __attribute((noinline)) -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(9,0,0) - #define JSON_HEDLEY_NEVER_INLINE __declspec(noinline) -#else - #define JSON_HEDLEY_NEVER_INLINE -#endif - -#if defined(JSON_HEDLEY_PRIVATE) - #undef JSON_HEDLEY_PRIVATE -#endif -#if defined(JSON_HEDLEY_PUBLIC) - #undef JSON_HEDLEY_PUBLIC -#endif -#if defined(JSON_HEDLEY_IMPORT) - #undef JSON_HEDLEY_IMPORT -#endif -#if defined(_WIN32) || defined(__CYGWIN__) -# define JSON_HEDLEY_PRIVATE -# define JSON_HEDLEY_PUBLIC __declspec(dllexport) -# define JSON_HEDLEY_IMPORT __declspec(dllimport) -#else -# if \ - JSON_HEDLEY_HAS_ATTRIBUTE(visibility) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ - JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,11,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ - ( \ - defined(__TI_EABI__) && \ - ( \ - (JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,2,0) && defined(__TI_GNU_ATTRIBUTE_SUPPORT__)) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(7,5,0) \ - ) \ - ) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) -# define JSON_HEDLEY_PRIVATE __attribute__((__visibility__("hidden"))) -# define JSON_HEDLEY_PUBLIC __attribute__((__visibility__("default"))) -# else -# define JSON_HEDLEY_PRIVATE -# define JSON_HEDLEY_PUBLIC -# endif -# define JSON_HEDLEY_IMPORT extern -#endif - -#if defined(JSON_HEDLEY_NO_THROW) - #undef JSON_HEDLEY_NO_THROW -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(nothrow) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,3,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_NO_THROW __attribute__((__nothrow__)) -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(13,1,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) - #define JSON_HEDLEY_NO_THROW __declspec(nothrow) -#else - #define JSON_HEDLEY_NO_THROW -#endif - -#if defined(JSON_HEDLEY_FALL_THROUGH) - #undef JSON_HEDLEY_FALL_THROUGH -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(fallthrough) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(7,0,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_FALL_THROUGH __attribute__((__fallthrough__)) -#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE_NS(clang,fallthrough) - #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[clang::fallthrough]]) -#elif JSON_HEDLEY_HAS_CPP_ATTRIBUTE(fallthrough) - #define JSON_HEDLEY_FALL_THROUGH JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_([[fallthrough]]) -#elif defined(__fallthrough) /* SAL */ - #define JSON_HEDLEY_FALL_THROUGH __fallthrough -#else - #define JSON_HEDLEY_FALL_THROUGH -#endif - -#if defined(JSON_HEDLEY_RETURNS_NON_NULL) - #undef JSON_HEDLEY_RETURNS_NON_NULL -#endif -#if \ - JSON_HEDLEY_HAS_ATTRIBUTE(returns_nonnull) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_RETURNS_NON_NULL __attribute__((__returns_nonnull__)) -#elif defined(_Ret_notnull_) /* SAL */ - #define JSON_HEDLEY_RETURNS_NON_NULL _Ret_notnull_ -#else - #define JSON_HEDLEY_RETURNS_NON_NULL -#endif - -#if defined(JSON_HEDLEY_ARRAY_PARAM) - #undef JSON_HEDLEY_ARRAY_PARAM -#endif -#if \ - defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 199901L) && \ - !defined(__STDC_NO_VLA__) && \ - !defined(__cplusplus) && \ - !defined(JSON_HEDLEY_PGI_VERSION) && \ - !defined(JSON_HEDLEY_TINYC_VERSION) - #define JSON_HEDLEY_ARRAY_PARAM(name) (name) -#else - #define JSON_HEDLEY_ARRAY_PARAM(name) -#endif - -#if defined(JSON_HEDLEY_IS_CONSTANT) - #undef JSON_HEDLEY_IS_CONSTANT -#endif -#if defined(JSON_HEDLEY_REQUIRE_CONSTEXPR) - #undef JSON_HEDLEY_REQUIRE_CONSTEXPR -#endif -/* JSON_HEDLEY_IS_CONSTEXPR_ is for - HEDLEY INTERNAL USE ONLY. API subject to change without notice. */ -#if defined(JSON_HEDLEY_IS_CONSTEXPR_) - #undef JSON_HEDLEY_IS_CONSTEXPR_ -#endif -#if \ - JSON_HEDLEY_HAS_BUILTIN(__builtin_constant_p) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,19) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(4,1,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ - JSON_HEDLEY_TI_CL6X_VERSION_CHECK(6,1,0) || \ - (JSON_HEDLEY_SUNPRO_VERSION_CHECK(5,10,0) && !defined(__cplusplus)) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_MCST_LCC_VERSION_CHECK(1,25,10) - #define JSON_HEDLEY_IS_CONSTANT(expr) __builtin_constant_p(expr) -#endif -#if !defined(__cplusplus) -# if \ - JSON_HEDLEY_HAS_BUILTIN(__builtin_types_compatible_p) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(3,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(13,1,0) || \ - JSON_HEDLEY_CRAY_VERSION_CHECK(8,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,4,0) || \ - JSON_HEDLEY_TINYC_VERSION_CHECK(0,9,24) -#if defined(__INTPTR_TYPE__) - #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0)), int*) -#else - #include - #define JSON_HEDLEY_IS_CONSTEXPR_(expr) __builtin_types_compatible_p(__typeof__((1 ? (void*) ((intptr_t) ((expr) * 0)) : (int*) 0)), int*) -#endif -# elif \ - ( \ - defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L) && \ - !defined(JSON_HEDLEY_SUNPRO_VERSION) && \ - !defined(JSON_HEDLEY_PGI_VERSION) && \ - !defined(JSON_HEDLEY_IAR_VERSION)) || \ - (JSON_HEDLEY_HAS_EXTENSION(c_generic_selections) && !defined(JSON_HEDLEY_IAR_VERSION)) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,9,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(17,0,0) || \ - JSON_HEDLEY_IBM_VERSION_CHECK(12,1,0) || \ - JSON_HEDLEY_ARM_VERSION_CHECK(5,3,0) -#if defined(__INTPTR_TYPE__) - #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((__INTPTR_TYPE__) ((expr) * 0)) : (int*) 0), int*: 1, void*: 0) -#else - #include - #define JSON_HEDLEY_IS_CONSTEXPR_(expr) _Generic((1 ? (void*) ((intptr_t) * 0) : (int*) 0), int*: 1, void*: 0) -#endif -# elif \ - defined(JSON_HEDLEY_GCC_VERSION) || \ - defined(JSON_HEDLEY_INTEL_VERSION) || \ - defined(JSON_HEDLEY_TINYC_VERSION) || \ - defined(JSON_HEDLEY_TI_ARMCL_VERSION) || \ - JSON_HEDLEY_TI_CL430_VERSION_CHECK(18,12,0) || \ - defined(JSON_HEDLEY_TI_CL2000_VERSION) || \ - defined(JSON_HEDLEY_TI_CL6X_VERSION) || \ - defined(JSON_HEDLEY_TI_CL7X_VERSION) || \ - defined(JSON_HEDLEY_TI_CLPRU_VERSION) || \ - defined(__clang__) -# define JSON_HEDLEY_IS_CONSTEXPR_(expr) ( \ - sizeof(void) != \ - sizeof(*( \ - 1 ? \ - ((void*) ((expr) * 0L) ) : \ -((struct { char v[sizeof(void) * 2]; } *) 1) \ - ) \ - ) \ - ) -# endif -#endif -#if defined(JSON_HEDLEY_IS_CONSTEXPR_) - #if !defined(JSON_HEDLEY_IS_CONSTANT) - #define JSON_HEDLEY_IS_CONSTANT(expr) JSON_HEDLEY_IS_CONSTEXPR_(expr) - #endif - #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (JSON_HEDLEY_IS_CONSTEXPR_(expr) ? (expr) : (-1)) -#else - #if !defined(JSON_HEDLEY_IS_CONSTANT) - #define JSON_HEDLEY_IS_CONSTANT(expr) (0) - #endif - #define JSON_HEDLEY_REQUIRE_CONSTEXPR(expr) (expr) -#endif - -#if defined(JSON_HEDLEY_BEGIN_C_DECLS) - #undef JSON_HEDLEY_BEGIN_C_DECLS -#endif -#if defined(JSON_HEDLEY_END_C_DECLS) - #undef JSON_HEDLEY_END_C_DECLS -#endif -#if defined(JSON_HEDLEY_C_DECL) - #undef JSON_HEDLEY_C_DECL -#endif -#if defined(__cplusplus) - #define JSON_HEDLEY_BEGIN_C_DECLS extern "C" { - #define JSON_HEDLEY_END_C_DECLS } - #define JSON_HEDLEY_C_DECL extern "C" -#else - #define JSON_HEDLEY_BEGIN_C_DECLS - #define JSON_HEDLEY_END_C_DECLS - #define JSON_HEDLEY_C_DECL -#endif - -#if defined(JSON_HEDLEY_STATIC_ASSERT) - #undef JSON_HEDLEY_STATIC_ASSERT -#endif -#if \ - !defined(__cplusplus) && ( \ - (defined(__STDC_VERSION__) && (__STDC_VERSION__ >= 201112L)) || \ - (JSON_HEDLEY_HAS_FEATURE(c_static_assert) && !defined(JSON_HEDLEY_INTEL_CL_VERSION)) || \ - JSON_HEDLEY_GCC_VERSION_CHECK(6,0,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) || \ - defined(_Static_assert) \ - ) -# define JSON_HEDLEY_STATIC_ASSERT(expr, message) _Static_assert(expr, message) -#elif \ - (defined(__cplusplus) && (__cplusplus >= 201103L)) || \ - JSON_HEDLEY_MSVC_VERSION_CHECK(16,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) -# define JSON_HEDLEY_STATIC_ASSERT(expr, message) JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(static_assert(expr, message)) -#else -# define JSON_HEDLEY_STATIC_ASSERT(expr, message) -#endif - -#if defined(JSON_HEDLEY_NULL) - #undef JSON_HEDLEY_NULL -#endif -#if defined(__cplusplus) - #if __cplusplus >= 201103L - #define JSON_HEDLEY_NULL JSON_HEDLEY_DIAGNOSTIC_DISABLE_CPP98_COMPAT_WRAP_(nullptr) - #elif defined(NULL) - #define JSON_HEDLEY_NULL NULL - #else - #define JSON_HEDLEY_NULL JSON_HEDLEY_STATIC_CAST(void*, 0) - #endif -#elif defined(NULL) - #define JSON_HEDLEY_NULL NULL -#else - #define JSON_HEDLEY_NULL ((void*) 0) -#endif - -#if defined(JSON_HEDLEY_MESSAGE) - #undef JSON_HEDLEY_MESSAGE -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") -# define JSON_HEDLEY_MESSAGE(msg) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \ - JSON_HEDLEY_PRAGMA(message msg) \ - JSON_HEDLEY_DIAGNOSTIC_POP -#elif \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) -# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message msg) -#elif JSON_HEDLEY_CRAY_VERSION_CHECK(5,0,0) -# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(_CRI message msg) -#elif JSON_HEDLEY_IAR_VERSION_CHECK(8,0,0) -# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg)) -#elif JSON_HEDLEY_PELLES_VERSION_CHECK(2,0,0) -# define JSON_HEDLEY_MESSAGE(msg) JSON_HEDLEY_PRAGMA(message(msg)) -#else -# define JSON_HEDLEY_MESSAGE(msg) -#endif - -#if defined(JSON_HEDLEY_WARNING) - #undef JSON_HEDLEY_WARNING -#endif -#if JSON_HEDLEY_HAS_WARNING("-Wunknown-pragmas") -# define JSON_HEDLEY_WARNING(msg) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - JSON_HEDLEY_DIAGNOSTIC_DISABLE_UNKNOWN_PRAGMAS \ - JSON_HEDLEY_PRAGMA(clang warning msg) \ - JSON_HEDLEY_DIAGNOSTIC_POP -#elif \ - JSON_HEDLEY_GCC_VERSION_CHECK(4,8,0) || \ - JSON_HEDLEY_PGI_VERSION_CHECK(18,4,0) || \ - JSON_HEDLEY_INTEL_VERSION_CHECK(13,0,0) -# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(GCC warning msg) -#elif \ - JSON_HEDLEY_MSVC_VERSION_CHECK(15,0,0) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) -# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_PRAGMA(message(msg)) -#else -# define JSON_HEDLEY_WARNING(msg) JSON_HEDLEY_MESSAGE(msg) -#endif - -#if defined(JSON_HEDLEY_REQUIRE) - #undef JSON_HEDLEY_REQUIRE -#endif -#if defined(JSON_HEDLEY_REQUIRE_MSG) - #undef JSON_HEDLEY_REQUIRE_MSG -#endif -#if JSON_HEDLEY_HAS_ATTRIBUTE(diagnose_if) -# if JSON_HEDLEY_HAS_WARNING("-Wgcc-compat") -# define JSON_HEDLEY_REQUIRE(expr) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ - __attribute__((diagnose_if(!(expr), #expr, "error"))) \ - JSON_HEDLEY_DIAGNOSTIC_POP -# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("clang diagnostic ignored \"-Wgcc-compat\"") \ - __attribute__((diagnose_if(!(expr), msg, "error"))) \ - JSON_HEDLEY_DIAGNOSTIC_POP -# else -# define JSON_HEDLEY_REQUIRE(expr) __attribute__((diagnose_if(!(expr), #expr, "error"))) -# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) __attribute__((diagnose_if(!(expr), msg, "error"))) -# endif -#else -# define JSON_HEDLEY_REQUIRE(expr) -# define JSON_HEDLEY_REQUIRE_MSG(expr,msg) -#endif - -#if defined(JSON_HEDLEY_FLAGS) - #undef JSON_HEDLEY_FLAGS -#endif -#if JSON_HEDLEY_HAS_ATTRIBUTE(flag_enum) && (!defined(__cplusplus) || JSON_HEDLEY_HAS_WARNING("-Wbitfield-enum-conversion")) - #define JSON_HEDLEY_FLAGS __attribute__((__flag_enum__)) -#else - #define JSON_HEDLEY_FLAGS -#endif - -#if defined(JSON_HEDLEY_FLAGS_CAST) - #undef JSON_HEDLEY_FLAGS_CAST -#endif -#if JSON_HEDLEY_INTEL_VERSION_CHECK(19,0,0) -# define JSON_HEDLEY_FLAGS_CAST(T, expr) (__extension__ ({ \ - JSON_HEDLEY_DIAGNOSTIC_PUSH \ - _Pragma("warning(disable:188)") \ - ((T) (expr)); \ - JSON_HEDLEY_DIAGNOSTIC_POP \ - })) -#else -# define JSON_HEDLEY_FLAGS_CAST(T, expr) JSON_HEDLEY_STATIC_CAST(T, expr) -#endif - -#if defined(JSON_HEDLEY_EMPTY_BASES) - #undef JSON_HEDLEY_EMPTY_BASES -#endif -#if \ - (JSON_HEDLEY_MSVC_VERSION_CHECK(19,0,23918) && !JSON_HEDLEY_MSVC_VERSION_CHECK(20,0,0)) || \ - JSON_HEDLEY_INTEL_CL_VERSION_CHECK(2021,1,0) - #define JSON_HEDLEY_EMPTY_BASES __declspec(empty_bases) -#else - #define JSON_HEDLEY_EMPTY_BASES -#endif - -/* Remaining macros are deprecated. */ - -#if defined(JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK) - #undef JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK -#endif -#if defined(__clang__) - #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) (0) -#else - #define JSON_HEDLEY_GCC_NOT_CLANG_VERSION_CHECK(major,minor,patch) JSON_HEDLEY_GCC_VERSION_CHECK(major,minor,patch) -#endif - -#if defined(JSON_HEDLEY_CLANG_HAS_ATTRIBUTE) - #undef JSON_HEDLEY_CLANG_HAS_ATTRIBUTE -#endif -#define JSON_HEDLEY_CLANG_HAS_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_ATTRIBUTE(attribute) - -#if defined(JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE) - #undef JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE -#endif -#define JSON_HEDLEY_CLANG_HAS_CPP_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_CPP_ATTRIBUTE(attribute) - -#if defined(JSON_HEDLEY_CLANG_HAS_BUILTIN) - #undef JSON_HEDLEY_CLANG_HAS_BUILTIN -#endif -#define JSON_HEDLEY_CLANG_HAS_BUILTIN(builtin) JSON_HEDLEY_HAS_BUILTIN(builtin) - -#if defined(JSON_HEDLEY_CLANG_HAS_FEATURE) - #undef JSON_HEDLEY_CLANG_HAS_FEATURE -#endif -#define JSON_HEDLEY_CLANG_HAS_FEATURE(feature) JSON_HEDLEY_HAS_FEATURE(feature) - -#if defined(JSON_HEDLEY_CLANG_HAS_EXTENSION) - #undef JSON_HEDLEY_CLANG_HAS_EXTENSION -#endif -#define JSON_HEDLEY_CLANG_HAS_EXTENSION(extension) JSON_HEDLEY_HAS_EXTENSION(extension) - -#if defined(JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE) - #undef JSON_HEDLEY_CLANG_HAS_DECLSPEC_DECLSPEC_ATTRIBUTE -#endif -#define JSON_HEDLEY_CLANG_HAS_DECLSPEC_ATTRIBUTE(attribute) JSON_HEDLEY_HAS_DECLSPEC_ATTRIBUTE(attribute) - -#if defined(JSON_HEDLEY_CLANG_HAS_WARNING) - #undef JSON_HEDLEY_CLANG_HAS_WARNING -#endif -#define JSON_HEDLEY_CLANG_HAS_WARNING(warning) JSON_HEDLEY_HAS_WARNING(warning) - -#endif /* !defined(JSON_HEDLEY_VERSION) || (JSON_HEDLEY_VERSION < X) */ - - -// This file contains all internal macro definitions (except those affecting ABI) -// You MUST include macro_unscope.hpp at the end of json.hpp to undef all of them - -// #include - - -// exclude unsupported compilers -#if !defined(JSON_SKIP_UNSUPPORTED_COMPILER_CHECK) - #if defined(__clang__) - #if (__clang_major__ * 10000 + __clang_minor__ * 100 + __clang_patchlevel__) < 30400 - #error "unsupported Clang version - see https://github.com/nlohmann/json#supported-compilers" - #endif - #elif defined(__GNUC__) && !(defined(__ICC) || defined(__INTEL_COMPILER)) - #if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) < 40800 - #error "unsupported GCC version - see https://github.com/nlohmann/json#supported-compilers" - #endif - #endif -#endif - -// C++ language standard detection -// if the user manually specified the used c++ version this is skipped -#if !defined(JSON_HAS_CPP_20) && !defined(JSON_HAS_CPP_17) && !defined(JSON_HAS_CPP_14) && !defined(JSON_HAS_CPP_11) - #if (defined(__cplusplus) && __cplusplus >= 202002L) || (defined(_MSVC_LANG) && _MSVC_LANG >= 202002L) - #define JSON_HAS_CPP_20 - #define JSON_HAS_CPP_17 - #define JSON_HAS_CPP_14 - #elif (defined(__cplusplus) && __cplusplus >= 201703L) || (defined(_HAS_CXX17) && _HAS_CXX17 == 1) // fix for issue #464 - #define JSON_HAS_CPP_17 - #define JSON_HAS_CPP_14 - #elif (defined(__cplusplus) && __cplusplus >= 201402L) || (defined(_HAS_CXX14) && _HAS_CXX14 == 1) - #define JSON_HAS_CPP_14 - #endif - // the cpp 11 flag is always specified because it is the minimal required version - #define JSON_HAS_CPP_11 -#endif - -#ifdef __has_include - #if __has_include() - #include - #endif -#endif - -#if !defined(JSON_HAS_FILESYSTEM) && !defined(JSON_HAS_EXPERIMENTAL_FILESYSTEM) - #ifdef JSON_HAS_CPP_17 - #if defined(__cpp_lib_filesystem) - #define JSON_HAS_FILESYSTEM 1 - #elif defined(__cpp_lib_experimental_filesystem) - #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 - #elif !defined(__has_include) - #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 - #elif __has_include() - #define JSON_HAS_FILESYSTEM 1 - #elif __has_include() - #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 1 - #endif - - // std::filesystem does not work on MinGW GCC 8: https://sourceforge.net/p/mingw-w64/bugs/737/ - #if defined(__MINGW32__) && defined(__GNUC__) && __GNUC__ == 8 - #undef JSON_HAS_FILESYSTEM - #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM - #endif - - // no filesystem support before GCC 8: https://en.cppreference.com/w/cpp/compiler_support - #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ < 8 - #undef JSON_HAS_FILESYSTEM - #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM - #endif - - // no filesystem support before Clang 7: https://en.cppreference.com/w/cpp/compiler_support - #if defined(__clang_major__) && __clang_major__ < 7 - #undef JSON_HAS_FILESYSTEM - #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM - #endif - - // no filesystem support before MSVC 19.14: https://en.cppreference.com/w/cpp/compiler_support - #if defined(_MSC_VER) && _MSC_VER < 1914 - #undef JSON_HAS_FILESYSTEM - #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM - #endif - - // no filesystem support before iOS 13 - #if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED < 130000 - #undef JSON_HAS_FILESYSTEM - #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM - #endif - - // no filesystem support before macOS Catalina - #if defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED < 101500 - #undef JSON_HAS_FILESYSTEM - #undef JSON_HAS_EXPERIMENTAL_FILESYSTEM - #endif - #endif -#endif - -#ifndef JSON_HAS_EXPERIMENTAL_FILESYSTEM - #define JSON_HAS_EXPERIMENTAL_FILESYSTEM 0 -#endif - -#ifndef JSON_HAS_FILESYSTEM - #define JSON_HAS_FILESYSTEM 0 -#endif - -#ifndef JSON_HAS_THREE_WAY_COMPARISON - #if defined(__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L \ - && defined(__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L - #define JSON_HAS_THREE_WAY_COMPARISON 1 - #else - #define JSON_HAS_THREE_WAY_COMPARISON 0 - #endif -#endif - -#ifndef JSON_HAS_RANGES - // ranges header shipping in GCC 11.1.0 (released 2021-04-27) has syntax error - #if defined(__GLIBCXX__) && __GLIBCXX__ == 20210427 - #define JSON_HAS_RANGES 0 - #elif defined(__cpp_lib_ranges) - #define JSON_HAS_RANGES 1 - #else - #define JSON_HAS_RANGES 0 - #endif -#endif - -#ifndef JSON_HAS_STATIC_RTTI - #if !defined(_HAS_STATIC_RTTI) || _HAS_STATIC_RTTI != 0 - #define JSON_HAS_STATIC_RTTI 1 - #else - #define JSON_HAS_STATIC_RTTI 0 - #endif -#endif - -#ifdef JSON_HAS_CPP_17 - #define JSON_INLINE_VARIABLE inline -#else - #define JSON_INLINE_VARIABLE -#endif - -#if JSON_HEDLEY_HAS_ATTRIBUTE(no_unique_address) - #define JSON_NO_UNIQUE_ADDRESS [[no_unique_address]] -#else - #define JSON_NO_UNIQUE_ADDRESS -#endif - -// disable documentation warnings on clang -#if defined(__clang__) - #pragma clang diagnostic push - #pragma clang diagnostic ignored "-Wdocumentation" - #pragma clang diagnostic ignored "-Wdocumentation-unknown-command" -#endif - -// allow disabling exceptions -#if (defined(__cpp_exceptions) || defined(__EXCEPTIONS) || defined(_CPPUNWIND)) && !defined(JSON_NOEXCEPTION) - #define JSON_THROW(exception) throw exception - #define JSON_TRY try - #define JSON_CATCH(exception) catch(exception) - #define JSON_INTERNAL_CATCH(exception) catch(exception) -#else - #include - #define JSON_THROW(exception) std::abort() - #define JSON_TRY if(true) - #define JSON_CATCH(exception) if(false) - #define JSON_INTERNAL_CATCH(exception) if(false) -#endif - -// override exception macros -#if defined(JSON_THROW_USER) - #undef JSON_THROW - #define JSON_THROW JSON_THROW_USER -#endif -#if defined(JSON_TRY_USER) - #undef JSON_TRY - #define JSON_TRY JSON_TRY_USER -#endif -#if defined(JSON_CATCH_USER) - #undef JSON_CATCH - #define JSON_CATCH JSON_CATCH_USER - #undef JSON_INTERNAL_CATCH - #define JSON_INTERNAL_CATCH JSON_CATCH_USER -#endif -#if defined(JSON_INTERNAL_CATCH_USER) - #undef JSON_INTERNAL_CATCH - #define JSON_INTERNAL_CATCH JSON_INTERNAL_CATCH_USER -#endif - -// allow overriding assert -#if !defined(JSON_ASSERT) - #include // assert - #define JSON_ASSERT(x) assert(x) -#endif - -// allow to access some private functions (needed by the test suite) -#if defined(JSON_TESTS_PRIVATE) - #define JSON_PRIVATE_UNLESS_TESTED public -#else - #define JSON_PRIVATE_UNLESS_TESTED private -#endif - -/*! -@brief macro to briefly define a mapping between an enum and JSON -@def NLOHMANN_JSON_SERIALIZE_ENUM -@since version 3.4.0 -*/ -#define NLOHMANN_JSON_SERIALIZE_ENUM(ENUM_TYPE, ...) \ - template \ - inline void to_json(BasicJsonType& j, const ENUM_TYPE& e) \ - { \ - static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ - static const std::pair m[] = __VA_ARGS__; \ - auto it = std::find_if(std::begin(m), std::end(m), \ - [e](const std::pair& ej_pair) -> bool \ - { \ - return ej_pair.first == e; \ - }); \ - j = ((it != std::end(m)) ? it : std::begin(m))->second; \ - } \ - template \ - inline void from_json(const BasicJsonType& j, ENUM_TYPE& e) \ - { \ - static_assert(std::is_enum::value, #ENUM_TYPE " must be an enum!"); \ - static const std::pair m[] = __VA_ARGS__; \ - auto it = std::find_if(std::begin(m), std::end(m), \ - [&j](const std::pair& ej_pair) -> bool \ - { \ - return ej_pair.second == j; \ - }); \ - e = ((it != std::end(m)) ? it : std::begin(m))->first; \ - } - -// Ugly macros to avoid uglier copy-paste when specializing basic_json. They -// may be removed in the future once the class is split. - -#define NLOHMANN_BASIC_JSON_TPL_DECLARATION \ - template class ObjectType, \ - template class ArrayType, \ - class StringType, class BooleanType, class NumberIntegerType, \ - class NumberUnsignedType, class NumberFloatType, \ - template class AllocatorType, \ - template class JSONSerializer, \ - class BinaryType, \ - class CustomBaseClass> - -#define NLOHMANN_BASIC_JSON_TPL \ - basic_json - -// Macros to simplify conversion from/to types - -#define NLOHMANN_JSON_EXPAND( x ) x -#define NLOHMANN_JSON_GET_MACRO(_1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, _60, _61, _62, _63, _64, NAME,...) NAME -#define NLOHMANN_JSON_PASTE(...) NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_GET_MACRO(__VA_ARGS__, \ - NLOHMANN_JSON_PASTE64, \ - NLOHMANN_JSON_PASTE63, \ - NLOHMANN_JSON_PASTE62, \ - NLOHMANN_JSON_PASTE61, \ - NLOHMANN_JSON_PASTE60, \ - NLOHMANN_JSON_PASTE59, \ - NLOHMANN_JSON_PASTE58, \ - NLOHMANN_JSON_PASTE57, \ - NLOHMANN_JSON_PASTE56, \ - NLOHMANN_JSON_PASTE55, \ - NLOHMANN_JSON_PASTE54, \ - NLOHMANN_JSON_PASTE53, \ - NLOHMANN_JSON_PASTE52, \ - NLOHMANN_JSON_PASTE51, \ - NLOHMANN_JSON_PASTE50, \ - NLOHMANN_JSON_PASTE49, \ - NLOHMANN_JSON_PASTE48, \ - NLOHMANN_JSON_PASTE47, \ - NLOHMANN_JSON_PASTE46, \ - NLOHMANN_JSON_PASTE45, \ - NLOHMANN_JSON_PASTE44, \ - NLOHMANN_JSON_PASTE43, \ - NLOHMANN_JSON_PASTE42, \ - NLOHMANN_JSON_PASTE41, \ - NLOHMANN_JSON_PASTE40, \ - NLOHMANN_JSON_PASTE39, \ - NLOHMANN_JSON_PASTE38, \ - NLOHMANN_JSON_PASTE37, \ - NLOHMANN_JSON_PASTE36, \ - NLOHMANN_JSON_PASTE35, \ - NLOHMANN_JSON_PASTE34, \ - NLOHMANN_JSON_PASTE33, \ - NLOHMANN_JSON_PASTE32, \ - NLOHMANN_JSON_PASTE31, \ - NLOHMANN_JSON_PASTE30, \ - NLOHMANN_JSON_PASTE29, \ - NLOHMANN_JSON_PASTE28, \ - NLOHMANN_JSON_PASTE27, \ - NLOHMANN_JSON_PASTE26, \ - NLOHMANN_JSON_PASTE25, \ - NLOHMANN_JSON_PASTE24, \ - NLOHMANN_JSON_PASTE23, \ - NLOHMANN_JSON_PASTE22, \ - NLOHMANN_JSON_PASTE21, \ - NLOHMANN_JSON_PASTE20, \ - NLOHMANN_JSON_PASTE19, \ - NLOHMANN_JSON_PASTE18, \ - NLOHMANN_JSON_PASTE17, \ - NLOHMANN_JSON_PASTE16, \ - NLOHMANN_JSON_PASTE15, \ - NLOHMANN_JSON_PASTE14, \ - NLOHMANN_JSON_PASTE13, \ - NLOHMANN_JSON_PASTE12, \ - NLOHMANN_JSON_PASTE11, \ - NLOHMANN_JSON_PASTE10, \ - NLOHMANN_JSON_PASTE9, \ - NLOHMANN_JSON_PASTE8, \ - NLOHMANN_JSON_PASTE7, \ - NLOHMANN_JSON_PASTE6, \ - NLOHMANN_JSON_PASTE5, \ - NLOHMANN_JSON_PASTE4, \ - NLOHMANN_JSON_PASTE3, \ - NLOHMANN_JSON_PASTE2, \ - NLOHMANN_JSON_PASTE1)(__VA_ARGS__)) -#define NLOHMANN_JSON_PASTE2(func, v1) func(v1) -#define NLOHMANN_JSON_PASTE3(func, v1, v2) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE2(func, v2) -#define NLOHMANN_JSON_PASTE4(func, v1, v2, v3) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE3(func, v2, v3) -#define NLOHMANN_JSON_PASTE5(func, v1, v2, v3, v4) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE4(func, v2, v3, v4) -#define NLOHMANN_JSON_PASTE6(func, v1, v2, v3, v4, v5) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE5(func, v2, v3, v4, v5) -#define NLOHMANN_JSON_PASTE7(func, v1, v2, v3, v4, v5, v6) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE6(func, v2, v3, v4, v5, v6) -#define NLOHMANN_JSON_PASTE8(func, v1, v2, v3, v4, v5, v6, v7) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE7(func, v2, v3, v4, v5, v6, v7) -#define NLOHMANN_JSON_PASTE9(func, v1, v2, v3, v4, v5, v6, v7, v8) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE8(func, v2, v3, v4, v5, v6, v7, v8) -#define NLOHMANN_JSON_PASTE10(func, v1, v2, v3, v4, v5, v6, v7, v8, v9) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE9(func, v2, v3, v4, v5, v6, v7, v8, v9) -#define NLOHMANN_JSON_PASTE11(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE10(func, v2, v3, v4, v5, v6, v7, v8, v9, v10) -#define NLOHMANN_JSON_PASTE12(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE11(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11) -#define NLOHMANN_JSON_PASTE13(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE12(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12) -#define NLOHMANN_JSON_PASTE14(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE13(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13) -#define NLOHMANN_JSON_PASTE15(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE14(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14) -#define NLOHMANN_JSON_PASTE16(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE15(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) -#define NLOHMANN_JSON_PASTE17(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE16(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16) -#define NLOHMANN_JSON_PASTE18(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE17(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17) -#define NLOHMANN_JSON_PASTE19(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE18(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18) -#define NLOHMANN_JSON_PASTE20(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE19(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19) -#define NLOHMANN_JSON_PASTE21(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE20(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20) -#define NLOHMANN_JSON_PASTE22(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE21(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21) -#define NLOHMANN_JSON_PASTE23(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE22(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22) -#define NLOHMANN_JSON_PASTE24(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE23(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23) -#define NLOHMANN_JSON_PASTE25(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE24(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24) -#define NLOHMANN_JSON_PASTE26(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE25(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25) -#define NLOHMANN_JSON_PASTE27(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE26(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26) -#define NLOHMANN_JSON_PASTE28(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE27(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27) -#define NLOHMANN_JSON_PASTE29(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE28(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28) -#define NLOHMANN_JSON_PASTE30(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE29(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29) -#define NLOHMANN_JSON_PASTE31(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE30(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30) -#define NLOHMANN_JSON_PASTE32(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE31(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31) -#define NLOHMANN_JSON_PASTE33(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE32(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32) -#define NLOHMANN_JSON_PASTE34(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE33(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33) -#define NLOHMANN_JSON_PASTE35(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE34(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34) -#define NLOHMANN_JSON_PASTE36(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE35(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35) -#define NLOHMANN_JSON_PASTE37(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE36(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36) -#define NLOHMANN_JSON_PASTE38(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE37(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37) -#define NLOHMANN_JSON_PASTE39(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE38(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38) -#define NLOHMANN_JSON_PASTE40(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE39(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39) -#define NLOHMANN_JSON_PASTE41(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE40(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40) -#define NLOHMANN_JSON_PASTE42(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE41(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41) -#define NLOHMANN_JSON_PASTE43(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE42(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42) -#define NLOHMANN_JSON_PASTE44(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE43(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43) -#define NLOHMANN_JSON_PASTE45(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE44(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44) -#define NLOHMANN_JSON_PASTE46(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE45(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45) -#define NLOHMANN_JSON_PASTE47(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE46(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46) -#define NLOHMANN_JSON_PASTE48(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE47(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47) -#define NLOHMANN_JSON_PASTE49(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE48(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48) -#define NLOHMANN_JSON_PASTE50(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE49(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49) -#define NLOHMANN_JSON_PASTE51(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE50(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50) -#define NLOHMANN_JSON_PASTE52(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE51(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51) -#define NLOHMANN_JSON_PASTE53(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE52(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52) -#define NLOHMANN_JSON_PASTE54(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE53(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53) -#define NLOHMANN_JSON_PASTE55(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE54(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54) -#define NLOHMANN_JSON_PASTE56(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE55(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55) -#define NLOHMANN_JSON_PASTE57(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE56(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56) -#define NLOHMANN_JSON_PASTE58(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE57(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57) -#define NLOHMANN_JSON_PASTE59(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE58(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58) -#define NLOHMANN_JSON_PASTE60(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE59(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59) -#define NLOHMANN_JSON_PASTE61(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE60(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60) -#define NLOHMANN_JSON_PASTE62(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE61(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61) -#define NLOHMANN_JSON_PASTE63(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE62(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62) -#define NLOHMANN_JSON_PASTE64(func, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) NLOHMANN_JSON_PASTE2(func, v1) NLOHMANN_JSON_PASTE63(func, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27, v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40, v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53, v54, v55, v56, v57, v58, v59, v60, v61, v62, v63) - -#define NLOHMANN_JSON_TO(v1) nlohmann_json_j[#v1] = nlohmann_json_t.v1; -#define NLOHMANN_JSON_FROM(v1) nlohmann_json_j.at(#v1).get_to(nlohmann_json_t.v1); -#define NLOHMANN_JSON_FROM_WITH_DEFAULT(v1) nlohmann_json_t.v1 = nlohmann_json_j.value(#v1, nlohmann_json_default_obj.v1); - -/*! -@brief macro -@def NLOHMANN_DEFINE_TYPE_INTRUSIVE -@since version 3.9.0 -*/ -#define NLOHMANN_DEFINE_TYPE_INTRUSIVE(Type, ...) \ - friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ - friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } - -#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_WITH_DEFAULT(Type, ...) \ - friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ - friend void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } - -#define NLOHMANN_DEFINE_TYPE_INTRUSIVE_ONLY_SERIALIZE(Type, ...) \ - friend void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } - -/*! -@brief macro -@def NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE -@since version 3.9.0 -*/ -#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE(Type, ...) \ - inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ - inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM, __VA_ARGS__)) } - -#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_ONLY_SERIALIZE(Type, ...) \ - inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } - -#define NLOHMANN_DEFINE_TYPE_NON_INTRUSIVE_WITH_DEFAULT(Type, ...) \ - inline void to_json(nlohmann::json& nlohmann_json_j, const Type& nlohmann_json_t) { NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_TO, __VA_ARGS__)) } \ - inline void from_json(const nlohmann::json& nlohmann_json_j, Type& nlohmann_json_t) { const Type nlohmann_json_default_obj{}; NLOHMANN_JSON_EXPAND(NLOHMANN_JSON_PASTE(NLOHMANN_JSON_FROM_WITH_DEFAULT, __VA_ARGS__)) } - -// inspired from https://stackoverflow.com/a/26745591 -// allows to call any std function as if (e.g. with begin): -// using std::begin; begin(x); -// -// it allows using the detected idiom to retrieve the return type -// of such an expression -#define NLOHMANN_CAN_CALL_STD_FUNC_IMPL(std_name) \ - namespace detail { \ - using std::std_name; \ - \ - template \ - using result_of_##std_name = decltype(std_name(std::declval()...)); \ - } \ - \ - namespace detail2 { \ - struct std_name##_tag \ - { \ - }; \ - \ - template \ - std_name##_tag std_name(T&&...); \ - \ - template \ - using result_of_##std_name = decltype(std_name(std::declval()...)); \ - \ - template \ - struct would_call_std_##std_name \ - { \ - static constexpr auto const value = ::nlohmann::detail:: \ - is_detected_exact::value; \ - }; \ - } /* namespace detail2 */ \ - \ - template \ - struct would_call_std_##std_name : detail2::would_call_std_##std_name \ - { \ - } - -#ifndef JSON_USE_IMPLICIT_CONVERSIONS - #define JSON_USE_IMPLICIT_CONVERSIONS 1 -#endif - -#if JSON_USE_IMPLICIT_CONVERSIONS - #define JSON_EXPLICIT -#else - #define JSON_EXPLICIT explicit -#endif - -#ifndef JSON_DISABLE_ENUM_SERIALIZATION - #define JSON_DISABLE_ENUM_SERIALIZATION 0 -#endif - -#ifndef JSON_USE_GLOBAL_UDLS - #define JSON_USE_GLOBAL_UDLS 1 -#endif - -#if JSON_HAS_THREE_WAY_COMPARISON - #include // partial_ordering -#endif - -NLOHMANN_JSON_NAMESPACE_BEGIN -namespace detail -{ - -/////////////////////////// -// JSON type enumeration // -/////////////////////////// - -/*! -@brief the JSON type enumeration - -This enumeration collects the different JSON types. It is internally used to -distinguish the stored values, and the functions @ref basic_json::is_null(), -@ref basic_json::is_object(), @ref basic_json::is_array(), -@ref basic_json::is_string(), @ref basic_json::is_boolean(), -@ref basic_json::is_number() (with @ref basic_json::is_number_integer(), -@ref basic_json::is_number_unsigned(), and @ref basic_json::is_number_float()), -@ref basic_json::is_discarded(), @ref basic_json::is_primitive(), and -@ref basic_json::is_structured() rely on it. - -@note There are three enumeration entries (number_integer, number_unsigned, and -number_float), because the library distinguishes these three types for numbers: -@ref basic_json::number_unsigned_t is used for unsigned integers, -@ref basic_json::number_integer_t is used for signed integers, and -@ref basic_json::number_float_t is used for floating-point numbers or to -approximate integers which do not fit in the limits of their respective type. - -@sa see @ref basic_json::basic_json(const value_t value_type) -- create a JSON -value with the default value for a given type - -@since version 1.0.0 -*/ -enum class value_t : std::uint8_t -{ - null, ///< null value - object, ///< object (unordered set of name/value pairs) - array, ///< array (ordered collection of values) - string, ///< string value - boolean, ///< boolean value - number_integer, ///< number value (signed integer) - number_unsigned, ///< number value (unsigned integer) - number_float, ///< number value (floating-point) - binary, ///< binary array (ordered collection of bytes) - discarded ///< discarded by the parser callback function -}; - -/*! -@brief comparison operator for JSON types - -Returns an ordering that is similar to Python: -- order: null < boolean < number < object < array < string < binary -- furthermore, each type is not smaller than itself -- discarded values are not comparable -- binary is represented as a b"" string in python and directly comparable to a - string; however, making a binary array directly comparable with a string would - be surprising behavior in a JSON file. - -@since version 1.0.0 -*/ -#if JSON_HAS_THREE_WAY_COMPARISON - inline std::partial_ordering operator<=>(const value_t lhs, const value_t rhs) noexcept // *NOPAD* -#else - inline bool operator<(const value_t lhs, const value_t rhs) noexcept -#endif -{ - static constexpr std::array order = {{ - 0 /* null */, 3 /* object */, 4 /* array */, 5 /* string */, - 1 /* boolean */, 2 /* integer */, 2 /* unsigned */, 2 /* float */, - 6 /* binary */ - } - }; - - const auto l_index = static_cast(lhs); - const auto r_index = static_cast(rhs); -#if JSON_HAS_THREE_WAY_COMPARISON - if (l_index < order.size() && r_index < order.size()) - { - return order[l_index] <=> order[r_index]; // *NOPAD* - } - return std::partial_ordering::unordered; -#else - return l_index < order.size() && r_index < order.size() && order[l_index] < order[r_index]; -#endif -} - -// GCC selects the built-in operator< over an operator rewritten from -// a user-defined spaceship operator -// Clang, MSVC, and ICC select the rewritten candidate -// (see GCC bug https://gcc.gnu.org/bugzilla/show_bug.cgi?id=105200) -#if JSON_HAS_THREE_WAY_COMPARISON && defined(__GNUC__) -inline bool operator<(const value_t lhs, const value_t rhs) noexcept -{ - return std::is_lt(lhs <=> rhs); // *NOPAD* -} -#endif - -} // namespace detail -NLOHMANN_JSON_NAMESPACE_END - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.3 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -// #include - - -NLOHMANN_JSON_NAMESPACE_BEGIN -namespace detail -{ - -/*! -@brief replace all occurrences of a substring by another string - -@param[in,out] s the string to manipulate; changed so that all - occurrences of @a f are replaced with @a t -@param[in] f the substring to replace with @a t -@param[in] t the string to replace @a f - -@pre The search string @a f must not be empty. **This precondition is -enforced with an assertion.** - -@since version 2.0.0 -*/ -template -inline void replace_substring(StringType& s, const StringType& f, - const StringType& t) -{ - JSON_ASSERT(!f.empty()); - for (auto pos = s.find(f); // find first occurrence of f - pos != StringType::npos; // make sure f was found - s.replace(pos, f.size(), t), // replace with t, and - pos = s.find(f, pos + t.size())) // find next occurrence of f - {} -} - -/*! - * @brief string escaping as described in RFC 6901 (Sect. 4) - * @param[in] s string to escape - * @return escaped string - * - * Note the order of escaping "~" to "~0" and "/" to "~1" is important. - */ -template -inline StringType escape(StringType s) -{ - replace_substring(s, StringType{"~"}, StringType{"~0"}); - replace_substring(s, StringType{"/"}, StringType{"~1"}); - return s; -} - -/*! - * @brief string unescaping as described in RFC 6901 (Sect. 4) - * @param[in] s string to unescape - * @return unescaped string - * - * Note the order of escaping "~1" to "/" and "~0" to "~" is important. - */ -template -static void unescape(StringType& s) -{ - replace_substring(s, StringType{"~1"}, StringType{"/"}); - replace_substring(s, StringType{"~0"}, StringType{"~"}); -} - -} // namespace detail -NLOHMANN_JSON_NAMESPACE_END - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.3 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include // size_t - -// #include - - -NLOHMANN_JSON_NAMESPACE_BEGIN -namespace detail -{ - -/// struct to capture the start position of the current token -struct position_t -{ - /// the total number of characters read - std::size_t chars_read_total = 0; - /// the number of characters read in the current line - std::size_t chars_read_current_line = 0; - /// the number of lines read - std::size_t lines_read = 0; - - /// conversion to size_t to preserve SAX interface - constexpr operator size_t() const - { - return chars_read_total; - } -}; - -} // namespace detail -NLOHMANN_JSON_NAMESPACE_END - -// #include - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.3 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann -// SPDX-FileCopyrightText: 2018 The Abseil Authors -// SPDX-License-Identifier: MIT - - - -#include // array -#include // size_t -#include // conditional, enable_if, false_type, integral_constant, is_constructible, is_integral, is_same, remove_cv, remove_reference, true_type -#include // index_sequence, make_index_sequence, index_sequence_for - -// #include - - -NLOHMANN_JSON_NAMESPACE_BEGIN -namespace detail -{ - -template -using uncvref_t = typename std::remove_cv::type>::type; - -#ifdef JSON_HAS_CPP_14 - -// the following utilities are natively available in C++14 -using std::enable_if_t; -using std::index_sequence; -using std::make_index_sequence; -using std::index_sequence_for; - -#else - -// alias templates to reduce boilerplate -template -using enable_if_t = typename std::enable_if::type; - -// The following code is taken from https://github.com/abseil/abseil-cpp/blob/10cb35e459f5ecca5b2ff107635da0bfa41011b4/absl/utility/utility.h -// which is part of Google Abseil (https://github.com/abseil/abseil-cpp), licensed under the Apache License 2.0. - -//// START OF CODE FROM GOOGLE ABSEIL - -// integer_sequence -// -// Class template representing a compile-time integer sequence. An instantiation -// of `integer_sequence` has a sequence of integers encoded in its -// type through its template arguments (which is a common need when -// working with C++11 variadic templates). `absl::integer_sequence` is designed -// to be a drop-in replacement for C++14's `std::integer_sequence`. -// -// Example: -// -// template< class T, T... Ints > -// void user_function(integer_sequence); -// -// int main() -// { -// // user_function's `T` will be deduced to `int` and `Ints...` -// // will be deduced to `0, 1, 2, 3, 4`. -// user_function(make_integer_sequence()); -// } -template -struct integer_sequence -{ - using value_type = T; - static constexpr std::size_t size() noexcept - { - return sizeof...(Ints); - } -}; - -// index_sequence -// -// A helper template for an `integer_sequence` of `size_t`, -// `absl::index_sequence` is designed to be a drop-in replacement for C++14's -// `std::index_sequence`. -template -using index_sequence = integer_sequence; - -namespace utility_internal -{ - -template -struct Extend; - -// Note that SeqSize == sizeof...(Ints). It's passed explicitly for efficiency. -template -struct Extend, SeqSize, 0> -{ - using type = integer_sequence < T, Ints..., (Ints + SeqSize)... >; -}; - -template -struct Extend, SeqSize, 1> -{ - using type = integer_sequence < T, Ints..., (Ints + SeqSize)..., 2 * SeqSize >; -}; - -// Recursion helper for 'make_integer_sequence'. -// 'Gen::type' is an alias for 'integer_sequence'. -template -struct Gen -{ - using type = - typename Extend < typename Gen < T, N / 2 >::type, N / 2, N % 2 >::type; -}; - -template -struct Gen -{ - using type = integer_sequence; -}; - -} // namespace utility_internal - -// Compile-time sequences of integers - -// make_integer_sequence -// -// This template alias is equivalent to -// `integer_sequence`, and is designed to be a drop-in -// replacement for C++14's `std::make_integer_sequence`. -template -using make_integer_sequence = typename utility_internal::Gen::type; - -// make_index_sequence -// -// This template alias is equivalent to `index_sequence<0, 1, ..., N-1>`, -// and is designed to be a drop-in replacement for C++14's -// `std::make_index_sequence`. -template -using make_index_sequence = make_integer_sequence; - -// index_sequence_for -// -// Converts a typename pack into an index sequence of the same length, and -// is designed to be a drop-in replacement for C++14's -// `std::index_sequence_for()` -template -using index_sequence_for = make_index_sequence; - -//// END OF CODE FROM GOOGLE ABSEIL - -#endif - -// dispatch utility (taken from ranges-v3) -template struct priority_tag : priority_tag < N - 1 > {}; -template<> struct priority_tag<0> {}; - -// taken from ranges-v3 -template -struct static_const -{ - static JSON_INLINE_VARIABLE constexpr T value{}; -}; - -#ifndef JSON_HAS_CPP_17 - template - constexpr T static_const::value; -#endif - -template -inline constexpr std::array make_array(Args&& ... args) -{ - return std::array {{static_cast(std::forward(args))...}}; -} - -} // namespace detail -NLOHMANN_JSON_NAMESPACE_END - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.3 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include // numeric_limits -#include // false_type, is_constructible, is_integral, is_same, true_type -#include // declval -#include // tuple -#include // char_traits - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.3 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -#include // random_access_iterator_tag - -// #include - -// #include - -// #include - - -NLOHMANN_JSON_NAMESPACE_BEGIN -namespace detail -{ - -template -struct iterator_types {}; - -template -struct iterator_types < - It, - void_t> -{ - using difference_type = typename It::difference_type; - using value_type = typename It::value_type; - using pointer = typename It::pointer; - using reference = typename It::reference; - using iterator_category = typename It::iterator_category; -}; - -// This is required as some compilers implement std::iterator_traits in a way that -// doesn't work with SFINAE. See https://github.com/nlohmann/json/issues/1341. -template -struct iterator_traits -{ -}; - -template -struct iterator_traits < T, enable_if_t < !std::is_pointer::value >> - : iterator_types -{ -}; - -template -struct iterator_traits::value>> -{ - using iterator_category = std::random_access_iterator_tag; - using value_type = T; - using difference_type = ptrdiff_t; - using pointer = T*; - using reference = T&; -}; - -} // namespace detail -NLOHMANN_JSON_NAMESPACE_END - -// #include - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.3 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -// #include - - -NLOHMANN_JSON_NAMESPACE_BEGIN - -NLOHMANN_CAN_CALL_STD_FUNC_IMPL(begin); - -NLOHMANN_JSON_NAMESPACE_END - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.3 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann -// SPDX-License-Identifier: MIT - - - -// #include - - -NLOHMANN_JSON_NAMESPACE_BEGIN - -NLOHMANN_CAN_CALL_STD_FUNC_IMPL(end); - -NLOHMANN_JSON_NAMESPACE_END - -// #include - -// #include - -// #include -// __ _____ _____ _____ -// __| | __| | | | JSON for Modern C++ -// | | |__ | | | | | | version 3.11.3 -// |_____|_____|_____|_|___| https://github.com/nlohmann/json -// -// SPDX-FileCopyrightText: 2013-2023 Niels Lohmann -// SPDX-License-Identifier: MIT - -#ifndef INCLUDE_NLOHMANN_JSON_FWD_HPP_ - #define INCLUDE_NLOHMANN_JSON_FWD_HPP_ - - #include // int64_t, uint64_t - #include // map - #include // allocator - #include // string - #include // vector - - // #include - - - /*! - @brief namespace for Niels Lohmann - @see https://github.com/nlohmann - @since version 1.0.0 - */ - NLOHMANN_JSON_NAMESPACE_BEGIN - - /*! - @brief default JSONSerializer template argument - - This serializer ignores the template arguments and uses ADL - ([argument-dependent lookup](https://en.cppreference.com/w/cpp/language/adl)) - for serialization. - */ - template - struct adl_serializer; - - /// a class to store JSON values - /// @sa https://json.nlohmann.me/api/basic_json/ - template class ObjectType = - std::map, - template class ArrayType = std::vector, - class StringType = std::string, class BooleanType = bool, - class NumberIntegerType = std::int64_t, - class NumberUnsignedType = std::uint64_t, - class NumberFloatType = double, - template class AllocatorType = std::allocator, - template class JSONSerializer = - adl_serializer, - class BinaryType = std::vector, // cppcheck-suppress syntaxError - class CustomBaseClass = void> - class basic_json; - - /// @brief JSON Pointer defines a string syntax for identifying a specific value within a JSON document - /// @sa https://json.nlohmann.me/api/json_pointer/ - template - class json_pointer; - - /*! - @brief default specialization - @sa https://json.nlohmann.me/api/json/ - */ - using json = basic_json<>; - - /// @brief a minimal map-like container that preserves insertion order - /// @sa https://json.nlohmann.me/api/ordered_map/ - template - struct ordered_map; - - /// @brief specialization that maintains the insertion order of object keys - /// @sa https://json.nlohmann.me/api/ordered_json/ - using ordered_json = basic_json; - - NLOHMANN_JSON_NAMESPACE_END - -#endif // INCLUDE_NLOHMANN_JSON_FWD_HPP_ - - -NLOHMANN_JSON_NAMESPACE_BEGIN -/*! -@brief detail namespace with internal helper functions - -This namespace collects functions that should not be exposed, -implementations of some @ref basic_json methods, and meta-programming helpers. - -@since version 2.1.0 -*/ -namespace detail -{ - -///////////// -// helpers // -///////////// - -// Note to maintainers: -// -// Every trait in this file expects a non CV-qualified type. -// The only exceptions are in the 'aliases for detected' section -// (i.e. those of the form: decltype(T::member_function(std::declval()))) -// -// In this case, T has to be properly CV-qualified to constraint the function arguments -// (e.g. to_json(BasicJsonType&, const T&)) - -template struct is_basic_json : std::false_type {}; - -NLOHMANN_BASIC_JSON_TPL_DECLARATION -struct is_basic_json : std::true_type {}; - -// used by exceptions create() member functions -// true_type for pointer to possibly cv-qualified basic_json or std::nullptr_t -// false_type otherwise -template -struct is_basic_json_context : - std::integral_constant < bool, - is_basic_json::type>::type>::value - || std::is_same::value > -{}; - -////////////////////// -// json_ref helpers // -////////////////////// - -template -class json_ref; - -template -struct is_json_ref : std::false_type {}; - -template -struct is_json_ref> : std::true_type {}; - -////////////////////////// -// aliases for detected // -////////////////////////// - -template -using mapped_type_t = typename T::mapped_type; - -template -using key_type_t = typename T::key_type; - -template -using value_type_t = typename T::value_type; - -template -using difference_type_t = typename T::difference_type; - -template -using pointer_t = typename T::pointer; - -template -using reference_t = typename T::reference; - -template -using iterator_category_t = typename T::iterator_category; - -template -using to_json_function = decltype(T::to_json(std::declval()...)); - -template -using from_json_function = decltype(T::from_json(std::declval()...)); - -template -using get_template_function = decltype(std::declval().template get()); - -// trait checking if JSONSerializer::from_json(json const&, udt&) exists -template -struct has_from_json : std::false_type {}; - -// trait checking if j.get is valid -// use this trait instead of std::is_constructible or std::is_convertible, -// both rely on, or make use of implicit conversions, and thus fail when T -// has several constructors/operator= (see https://github.com/nlohmann/json/issues/958) -template -struct is_getable -{ - static constexpr bool value = is_detected::value; -}; - -template -struct has_from_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> -{ - using serializer = typename BasicJsonType::template json_serializer; - - static constexpr bool value = - is_detected_exact::value; -}; - -// This trait checks if JSONSerializer::from_json(json const&) exists -// this overload is used for non-default-constructible user-defined-types -template -struct has_non_default_from_json : std::false_type {}; - -template -struct has_non_default_from_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> -{ - using serializer = typename BasicJsonType::template json_serializer; - - static constexpr bool value = - is_detected_exact::value; -}; - -// This trait checks if BasicJsonType::json_serializer::to_json exists -// Do not evaluate the trait when T is a basic_json type, to avoid template instantiation infinite recursion. -template -struct has_to_json : std::false_type {}; - -template -struct has_to_json < BasicJsonType, T, enable_if_t < !is_basic_json::value >> -{ - using serializer = typename BasicJsonType::template json_serializer; - - static constexpr bool value = - is_detected_exact::value; -}; - -template -using detect_key_compare = typename T::key_compare; - -template -struct has_key_compare : std::integral_constant::value> {}; - -// obtains the actual object key comparator -template -struct actual_object_comparator -{ - using object_t = typename BasicJsonType::object_t; - using object_comparator_t = typename BasicJsonType::default_object_comparator_t; - using type = typename std::conditional < has_key_compare::value, - typename object_t::key_compare, object_comparator_t>::type; -}; - -template -using actual_object_comparator_t = typename actual_object_comparator::type; - -///////////////// -// char_traits // -///////////////// - -// Primary template of char_traits calls std char_traits -template -struct char_traits : std::char_traits -{}; - -// Explicitly define char traits for unsigned char since it is not standard -template<> -struct char_traits : std::char_traits -{ - using char_type = unsigned char; - using int_type = uint64_t; - - // Redefine to_int_type function - static int_type to_int_type(char_type c) noexcept - { - return static_cast(c); - } - - static char_type to_char_type(int_type i) noexcept - { - return static_cast(i); - } - - static constexpr int_type eof() noexcept - { - return static_cast(EOF); - } -}; - -// Explicitly define char traits for signed char since it is not standard -template<> -struct char_traits : std::char_traits -{ - using char_type = signed char; - using int_type = uint64_t; - - // Redefine to_int_type function - static int_type to_int_type(char_type c) noexcept - { - return static_cast(c); - } - - static char_type to_char_type(int_type i) noexcept - { - return static_cast(i); - } - - static constexpr int_type eof() noexcept - { - return static_cast(EOF); - } -}; - -/////////////////// -// is_ functions // -/////////////////// - -// https://en.cppreference.com/w/cpp/types/conjunction -template struct conjunction : std::true_type { }; -template struct conjunction : B { }; -template -struct conjunction -: std::conditional(B::value), conjunction, B>::type {}; - -// https://en.cppreference.com/w/cpp/types/negation -template struct negation : std::integral_constant < bool, !B::value > { }; - -// Reimplementation of is_constructible and is_default_constructible, due to them being broken for -// std::pair and std::tuple until LWG 2367 fix (see https://cplusplus.github.io/LWG/lwg-defects.html#2367). -// This causes compile errors in e.g. clang 3.5 or gcc 4.9. -template -struct is_default_constructible : std::is_default_constructible {}; - -template -struct is_default_constructible> - : conjunction, is_default_constructible> {}; - -template -struct is_default_constructible> - : conjunction, is_default_constructible> {}; - -template -struct is_default_constructible> - : conjunction...> {}; - -template -struct is_default_constructible> - : conjunction...> {}; - -template -struct is_constructible : std::is_constructible {}; - -template -struct is_constructible> : is_default_constructible> {}; - -template -struct is_constructible> : is_default_constructible> {}; - -template -struct is_constructible> : is_default_constructible> {}; - -template -struct is_constructible> : is_default_constructible> {}; - -template -struct is_iterator_traits : std::false_type {}; - -template -struct is_iterator_traits> -{ - private: - using traits = iterator_traits; - - public: - static constexpr auto value = - is_detected::value && - is_detected::value && - is_detected::value && - is_detected::value && - is_detected::value; -}; - -template -struct is_range -{ - private: - using t_ref = typename std::add_lvalue_reference::type; - - using iterator = detected_t; - using sentinel = detected_t; - - // to be 100% correct, it should use https://en.cppreference.com/w/cpp/iterator/input_or_output_iterator - // and https://en.cppreference.com/w/cpp/iterator/sentinel_for - // but reimplementing these would be too much work, as a lot of other concepts are used underneath - static constexpr auto is_iterator_begin = - is_iterator_traits>::value; - - public: - static constexpr bool value = !std::is_same::value && !std::is_same::value && is_iterator_begin; -}; - -template -using iterator_t = enable_if_t::value, result_of_begin())>>; - -template -using range_value_t = value_type_t>>; - -// The following implementation of is_complete_type is taken from -// https://blogs.msdn.microsoft.com/vcblog/2015/12/02/partial-support-for-expression-sfinae-in-vs-2015-update-1/ -// and is written by Xiang Fan who agreed to using it in this library. - -template -struct is_complete_type : std::false_type {}; - -template -struct is_complete_type : std::true_type {}; - -template -struct is_compatible_object_type_impl : std::false_type {}; - -template -struct is_compatible_object_type_impl < - BasicJsonType, CompatibleObjectType, - enable_if_t < is_detected::value&& - is_detected::value >> -{ - using object_t = typename BasicJsonType::object_t; - - // macOS's is_constructible does not play well with nonesuch... - static constexpr bool value = - is_constructible::value && - is_constructible::value; -}; - -template -struct is_compatible_object_type - : is_compatible_object_type_impl {}; - -template -struct is_constructible_object_type_impl : std::false_type {}; - -template -struct is_constructible_object_type_impl < - BasicJsonType, ConstructibleObjectType, - enable_if_t < is_detected::value&& - is_detected::value >> -{ - using object_t = typename BasicJsonType::object_t; - - static constexpr bool value = - (is_default_constructible::value && - (std::is_move_assignable::value || - std::is_copy_assignable::value) && - (is_constructible::value && - std::is_same < - typename object_t::mapped_type, - typename ConstructibleObjectType::mapped_type >::value)) || - (has_from_json::value || - has_non_default_from_json < - BasicJsonType, - typename ConstructibleObjectType::mapped_type >::value); -}; - -template -struct is_constructible_object_type - : is_constructible_object_type_impl {}; - -template -struct is_compatible_string_type -{ - static constexpr auto value = - is_constructible::value; -}; - -template -struct is_constructible_string_type -{ - // launder type through decltype() to fix compilation failure on ICPC -#ifdef __INTEL_COMPILER - using laundered_type = decltype(std::declval()); -#else - using laundered_type = ConstructibleStringType; -#endif - - static constexpr auto value = - conjunction < - is_constructible, - is_detected_exact>::value; -}; - -template -struct is_compatible_array_type_impl : std::false_type {}; - -template -struct is_compatible_array_type_impl < - BasicJsonType, CompatibleArrayType, - enable_if_t < - is_detected::value&& - is_iterator_traits>>::value&& -// special case for types like std::filesystem::path whose iterator's value_type are themselves -// c.f. https://github.com/nlohmann/json/pull/3073 - !std::is_same>::value >> -{ - static constexpr bool value = - is_constructible>::value; -}; - -template -struct is_compatible_array_type - : is_compatible_array_type_impl {}; - -template -struct is_constructible_array_type_impl : std::false_type {}; - -template -struct is_constructible_array_type_impl < - BasicJsonType, ConstructibleArrayType, - enable_if_t::value >> - : std::true_type {}; - -template -struct is_constructible_array_type_impl < - BasicJsonType, ConstructibleArrayType, - enable_if_t < !std::is_same::value&& - !is_compatible_string_type::value&& - is_default_constructible::value&& -(std::is_move_assignable::value || - std::is_copy_assignable::value)&& -is_detected::value&& -is_iterator_traits>>::value&& -is_detected::value&& -// special case for types like std::filesystem::path whose iterator's value_type are themselves -// c.f. https://github.com/nlohmann/json/pull/3073 -!std::is_same>::value&& - is_complete_type < - detected_t>::value >> -{ - using value_type = range_value_t; - - static constexpr bool value = - std::is_same::value || - has_from_json::value || - has_non_default_from_json < - BasicJsonType, - value_type >::value; -}; - -template -struct is_constructible_array_type - : is_constructible_array_type_impl {}; - -template -struct is_compatible_integer_type_impl : std::false_type {}; - -template -struct is_compatible_integer_type_impl < - RealIntegerType, CompatibleNumberIntegerType, - enable_if_t < std::is_integral::value&& - std::is_integral::value&& - !std::is_same::value >> -{ - // is there an assert somewhere on overflows? - using RealLimits = std::numeric_limits; - using CompatibleLimits = std::numeric_limits; - - static constexpr auto value = - is_constructible::value && - CompatibleLimits::is_integer && - RealLimits::is_signed == CompatibleLimits::is_signed; -}; - -template -struct is_compatible_integer_type - : is_compatible_integer_type_impl {}; - -template -struct is_compatible_type_impl: std::false_type {}; - -template -struct is_compatible_type_impl < - BasicJsonType, CompatibleType, - enable_if_t::value >> -{ - static constexpr bool value = - has_to_json::value; -}; - -template -struct is_compatible_type - : is_compatible_type_impl {}; - -template -struct is_constructible_tuple : std::false_type {}; - -template -struct is_constructible_tuple> : conjunction...> {}; - -template -struct is_json_iterator_of : std::false_type {}; - -template -struct is_json_iterator_of : std::true_type {}; - -template -struct is_json_iterator_of : std::true_type -{}; - -// checks if a given type T is a template specialization of Primary -template