diff --git a/Bcore/src/main/assets/vm.jar b/Bcore/src/main/assets/vm.jar new file mode 100644 index 00000000..8e930fb9 Binary files /dev/null and b/Bcore/src/main/assets/vm.jar differ diff --git a/Bcore/src/main/cpp/CMakeLists.txt b/Bcore/src/main/cpp/CMakeLists.txt index 83c1ef45..cd986166 100644 --- a/Bcore/src/main/cpp/CMakeLists.txt +++ b/Bcore/src/main/cpp/CMakeLists.txt @@ -5,6 +5,11 @@ cmake_minimum_required(VERSION 3.4.1) +set(DOBBY_SOURCE_DIR ./Dobby) +# 指定静态链接,否则默认动态链接 +set(GENERATE_SHARED OFF) +add_subdirectory(${DOBBY_SOURCE_DIR} blackdex_d.out) + # Creates and names a library, sets it as either STATIC # or SHARED, and provides the relative paths to its source code. # You can define multiple libraries, and CMake builds them for you. @@ -58,7 +63,7 @@ find_library( # Sets the name of the path variable. target_link_libraries( # Specifies the target library. blackdex - + blackdex_d # Links the target library to the log library # included in the NDK. ${log-lib} diff --git a/Bcore/src/main/cpp/DexDump.cpp b/Bcore/src/main/cpp/DexDump.cpp index bab675a8..877931c4 100644 --- a/Bcore/src/main/cpp/DexDump.cpp +++ b/Bcore/src/main/cpp/DexDump.cpp @@ -15,15 +15,86 @@ #include #include #include +#include +#include #include "unistd.h" -#include "dex/dex_file.h" +#include "dex/dex_file-inl.h" #include "dex/dex_file_loader.h" #include "jnihook/JniHook.h" #include "xhook/xhook.h" +#include "Dobby/include/dobby.h" + +#define _uintval(p) reinterpret_cast(p) +#define _ptr(p) reinterpret_cast(p) +#define _align_up(x, n) (((x) + ((n) - 1)) & ~((n) - 1)) +#define _align_down(x, n) ((x) & -(n)) +#define _page_size 4096 +#define _page_align(n) _align_up(static_cast(n), _page_size) +#define _ptr_align(x) _ptr(_align_down(reinterpret_cast(x), _page_size)) +#define _make_rwx(p, n) ::mprotect(_ptr_align(p), \ + _page_align(_uintval(p) + n) != _page_align(_uintval(p)) ? _page_align(n) + _page_size : _page_align(n), \ + PROT_READ | PROT_WRITE | PROT_EXEC) using namespace std; static int beginOffset = -2; +static const char *dumpPath; +std::list dumped; + +void handleDumpByDexFile(void *dex_file) { + char magic[8] = {0x64, 0x65, 0x78, 0x0a, 0x30, 0x33, 0x35, 0x00}; + if (!PointerCheck::check(dex_file)) { + return; + } + auto dexFile = static_cast(dex_file); + + int size = dexFile->Size(); + list::iterator iterator; + for (iterator = dumped.begin(); iterator != dumped.end(); ++iterator) { + int value = *iterator; + if (size == value) { + return; + } + } + void *buffer = malloc(size); + if (buffer) { + memcpy(buffer, dexFile->Begin(), size); + // fix magic + memcpy(buffer, magic, sizeof(magic)); + + const bool kVerifyChecksum = false; + const bool kVerify = true; + const art_lkchan::DexFileLoader dex_file_loader; + std::string error_msg; + std::vector> dex_files; + if (!dex_file_loader.OpenAll(reinterpret_cast(buffer), + size, + "", + kVerify, + kVerifyChecksum, + &error_msg, + &dex_files)) { + // Display returned error message to user. Note that this error behavior + // differs from the error messages shown by the original Dalvik dexdump. + ALOGE("Open dex error %s", error_msg.c_str()); + return; + } + + char path[1024]; + sprintf(path, "%s/hook_%d.dex", dumpPath, size); + auto fd = open(path, O_CREAT | O_WRONLY, 0600); + ssize_t w = write(fd, buffer, size); + fsync(fd); + if (w > 0) { + ALOGE("hook dump dex ======> %s", path); + } else { + remove(path); + } + close(fd); + free(buffer); + dumped.push_back(size); + } +} HOOK_JNI(int, kill, pid_t __pid, int __signal) { ALOGE("hooked so kill"); @@ -35,6 +106,34 @@ HOOK_JNI(int, killpg, int __pgrp, int __signal) { return 0; } +HOOK_FUN(void, LoadMethodO, void *thiz, + void *dex_file, + void *method, + void *klass, + void *dst) { + orig_LoadMethodO(thiz, dex_file, method, klass, dst); + handleDumpByDexFile(dex_file); +} + +HOOK_FUN(void, LoadMethodM, void *thiz, + void *thread, + void *dex_file, + void *method, + void *klass, + void *dst) { + orig_LoadMethodM(thiz, thread, dex_file, method, klass, dst); + handleDumpByDexFile(dex_file); +} + +HOOK_FUN(void, LoadMethodL, void *thiz, + void *thread, + void *dex_file, + void *method, + void *klass) { + orig_LoadMethodL(thiz, thread, dex_file, method, klass); + handleDumpByDexFile(dex_file); +} + void init(JNIEnv *env) { const char *soName = ".*\\.so$"; xhook_register(soName, "kill", (void *) new_kill, @@ -72,7 +171,7 @@ void init(JNIEnv *env) { } void fixCodeItem(JNIEnv *env, const art_lkchan::DexFile *dex_file_, size_t begin) { - for (size_t classdef_ctr = 0;classdef_ctr < dex_file_->NumClassDefs(); ++classdef_ctr) { + for (size_t classdef_ctr = 0; classdef_ctr < dex_file_->NumClassDefs(); ++classdef_ctr) { const art_lkchan::DexFile::ClassDef &cd = dex_file_->GetClassDef(classdef_ctr); const uint8_t *class_data = dex_file_->GetClassData(cd); auto &classTypeId = dex_file_->GetTypeId(cd.class_idx_); @@ -109,7 +208,7 @@ void fixCodeItem(JNIEnv *env, const art_lkchan::DexFile *dex_file_, size_t begin } } -void DexDump::dumpDex(JNIEnv *env, jlong cookie, jstring dir, jboolean fix) { +void DexDump::cookieDumpDex(JNIEnv *env, jlong cookie, jstring dir, jboolean fix) { if (beginOffset == -2) { init(env); } @@ -156,12 +255,12 @@ void DexDump::dumpDex(JNIEnv *env, jlong cookie, jstring dir, jboolean fix) { fixCodeItem(env, dex_files[0].get(), begin); } char path[1024]; - sprintf(path, "%s/dex_%d.dex", dirC, size); + sprintf(path, "%s/cookie_%d.dex", dirC, size); auto fd = open(path, O_CREAT | O_WRONLY, 0600); ssize_t w = write(fd, buffer, size); fsync(fd); if (w > 0) { - ALOGE("dump dex ======> %s", path); + ALOGE("cookie dump dex ======> %s", path); } else { remove(path); } @@ -170,3 +269,37 @@ void DexDump::dumpDex(JNIEnv *env, jlong cookie, jstring dir, jboolean fix) { env->ReleaseStringUTFChars(dir, dirC); } } + +void DexDump::hookDumpDex(JNIEnv *env, jstring dir) { + dumpPath = env->GetStringUTFChars(dir, 0); + const char *libart = "libart.so"; + + // L + void *loadMethod = DobbySymbolResolver(libart, + "_ZN3art11ClassLinker10LoadMethodEPNS_6ThreadERKNS_7DexFileERKNS_21ClassDataItemIteratorENS_6HandleINS_6mirror5ClassEEE"); + if (!loadMethod) { + // M + loadMethod = DobbySymbolResolver(libart, + "_ZN3art11ClassLinker10LoadMethodEPNS_6ThreadERKNS_7DexFileERKNS_21ClassDataItemIteratorENS_6HandleINS_6mirror5ClassEEEPNS_9ArtMethodE"); + } + if (!loadMethod) { + // O + loadMethod = DobbySymbolResolver(libart, + "_ZN3art11ClassLinker10LoadMethodERKNS_7DexFileERKNS_13ClassAccessor6MethodENS_6HandleINS_6mirror5ClassEEEPNS_9ArtMethodE"); + } + + _make_rwx(loadMethod, _page_size); + if (loadMethod) { + if (android_get_device_api_level() >= __ANDROID_API_O__) { + DobbyHook(loadMethod, (void *) new_LoadMethodO, + (void **) &orig_LoadMethodO); + } else if (android_get_device_api_level() >= __ANDROID_API_M__) { + DobbyHook(loadMethod, (void *) new_LoadMethodM, + (void **) &orig_LoadMethodM); + } else { + DobbyHook(loadMethod, (void *) new_LoadMethodL, + (void **) &orig_LoadMethodL); + } + } +} + diff --git a/Bcore/src/main/cpp/DexDump.h b/Bcore/src/main/cpp/DexDump.h index 4f3e4865..6d9e959c 100644 --- a/Bcore/src/main/cpp/DexDump.h +++ b/Bcore/src/main/cpp/DexDump.h @@ -12,7 +12,8 @@ class DexDump { public: - static void dumpDex(JNIEnv *env, jlong cookie, jstring dir, jboolean fix); + static void hookDumpDex(JNIEnv *env, jstring dir); + static void cookieDumpDex(JNIEnv *env, jlong cookie, jstring dir, jboolean fix); }; diff --git a/Bcore/src/main/cpp/Dobby/.clang-format b/Bcore/src/main/cpp/Dobby/.clang-format new file mode 100644 index 00000000..17d6bc41 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/.clang-format @@ -0,0 +1,18 @@ +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/Bcore/src/main/cpp/Dobby/.gitignore b/Bcore/src/main/cpp/Dobby/.gitignore new file mode 100644 index 00000000..4bbed764 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/.gitignore @@ -0,0 +1,80 @@ +.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/Bcore/src/main/cpp/Dobby/CMakeLists.txt b/Bcore/src/main/cpp/Dobby/CMakeLists.txt new file mode 100644 index 00000000..ac3aaf9a --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/CMakeLists.txt @@ -0,0 +1,430 @@ +cmake_minimum_required(VERSION 3.5) +project(Dobby) +enable_language(ASM) + +include(cmake/Util.cmake) +include(cmake/Globals.cmake) +include(cmake/Macros.cmake) +include(cmake/XcodeGenerator.cmake) +include(cmake/AutoFiles.cmake) + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_C_STANDARD 11) + +AutoFiles("." "CmakeSource" "\\.(cc|cpp|c|h)$") + +# :< You Shall Not Pass! +if(0) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Werror") +endif() + +# ===== Handle Option ===== +option(DOBBY_GENERATE_SHARED "Build shared library" ON) + +option(DOBBY_DEBUG "Enable debug logging" ON) + +option(NearBranch "Enable Near Branch Trampoline" ON) + +option(DynamicBinaryInstrument "Enable Dynamic Binary Instrument" ON) + +option(FullFloatingPointRegisterPack "Save and pack all floating-point registers" OFF) + +option(EnableObfuscation "Enable llvm obfuscation" OFF) + +option(Plugin.SymbolResolver "Resolve symbol by [DobbySymbolResolver] " ON) + +option(Plugin.GlobalOffsetTableHook "Global Offset Table Hook by [DobbyGlobalOffsetTableReplace] " ON) + +option(Plugin.LinkerLoadCallback "Register image load callback " OFF) + +# frida is better choice +option(Plugin.ApplicationEventMonitor "Auto monitor linker, file, etc." OFF) + +option(Plugin.Android.BionicLinkerRestriction "Enable android bionic linker restriction" OFF) + +# Use native assembly bridge to replace the runtime codegen +# if(CLOSURE_BRIDGE_TEMPLATE) +# SET(CMAKE_ASM_FLAGS "${CMAKE_C_FLAGS}") +# enable_language(ASM) +# add_definitions(-DENABLE_CLOSURE_BRIDGE_TEMPLATE) +# endif() + +# Enable debug will log more information +#if (CMAKE_BUILD_TYPE STREQUAL "Debug") +# set(DOBBY_DEBUG ON) +#endif() +if(DOBBY_DEBUG) + add_definitions(-DDOBBY_DEBUG) + add_definitions(-DLOGGING_DEBUG) + message(STATUS "[Dobby] Enable debug logging") +endif() + +# Enable full floating point register pack +# for arm64, allow access q8 - q31 +if(FullFloatingPointRegisterPack) + add_definitions(-DFULL_FLOATING_POINT_REGISTER_PACK) + message(STATUS "[Dobby] Save and pack all floating-point registers") +endif() + +if(SYSTEM.Darwin) + # -lstdc++ + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -stdlib=libc++") + if (NOT DOBBY_DEBUG) + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-x -Wl,-S") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-exported_symbol,_log_internal_impl -Wl,-exported_symbol,_log_set_level") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-exported_symbol,_CodePatch") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-exported_symbol,_DobbyBuildVersion -Wl,-exported_symbol,_DobbyHook -Wl,-exported_symbol,_DobbyInstrument -Wl,-exported_symbol,_DobbyDestroy") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-exported_symbol,_DobbyGlobalOffsetTableReplace") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-exported_symbol,_DobbySymbolResolver") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-exported_symbol,_intercept_routing_common_bridge_handler") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,-exported_symbol,_dobby_enable_near_branch_trampoline -Wl,-exported_symbol,_dobby_disable_near_branch_trampoline") + endif() +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(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--gc-sections -Wl,--exclude-libs,ALL") + endif() +elseif(SYSTEM.Linux) + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC") +elseif(SYSTEM.Windows) + if(NOT DOBBY_DEBUG) + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /export:log_internal_impl") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /export:DobbyHook /export:DobbyInstrument /export:DobbySymbolResolver") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /export:dobby_enable_near_branch_trampoline /export:dobby_disable_near_branch_trampoline") + endif() +endif() + +if(COMPILER.Clang) + 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() +endif() + +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}") + +# arch prefix +if(PROCESSOR.ARM) + set(ARCH1 ARM) + set(arch1 arm) + set(core_arch arm) +elseif(PROCESSOR.AARCH64) + set(ARCH1 ARM64) + set(arch1 arm64) + set(core_arch arm64) +elseif(PROCESSOR.X86) + set(ARCH1 X86) + set(arch1 x86) + set(core_arch ia32) +elseif(PROCESSOR.X86_64) + set(ARCH1 X64) + set(arch1 x64) + set(core_arch x64) +else() +endif() + +# system prefix +if(SYSTEM.Darwin OR SYSTEM.iOS OR SYSTEM.macOS) + set(platform1 posix) + set(platform2 Darwin) +elseif(SYSTEM.Linux OR SYSTEM.Android) + set(platform1 posix) + set(platform2 Linux) +elseif(SYSTEM.Windows) + set(platform1 windows) + set(platform2 Windows) +else() +endif() + +if(CMAKE_GENERATOR STREQUAL Xcode) +endif() +include(cmake/dobby.xcode.source.cmake) + +include_directories( + . + + ./include + + ./source + ./source/include + ./source/UserMode + + ./external + ./external/logging + ./external/xnucxx + ./external/misc-helper + + builtin-plugin +) + +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/modules/assembler/assembler.cc + source/core/modules/assembler/assembler-${core_arch}.cc + + # codegen + source/core/modules/codegen/codegen-${core_arch}.cc + + # memory kit + source/MemoryAllocator/CodeBuffer/CodeBufferBase.cc + source/MemoryAllocator/CodeBuffer/code-buffer-${arch1}.cc + source/MemoryAllocator/AssemblyCodeBuilder.cc + source/MemoryAllocator/MemoryArena.cc + + # instruction relocation + source/InstructionRelocation/${arch1}/${ARCH1}InstructionRelocation.cc + + # intercept routing + source/InterceptRouting/InterceptRouting.cpp + + # intercept routing trampoline + source/TrampolineBridge/Trampoline/${arch1}/trampoline-${arch1}.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 + + # 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 + ) + +if (PROCESSOR.X86_64 OR PROCESSOR.X86) + set(NearBranch ON) + if (PROCESSOR.X86_64) + add_definitions(-DDETOURS_X64) + endif() +endif() + +if(SYSTEM.Darwin) + include_directories( + source/UserMode/ExecMemory/substrated/include + ) + set(dobby.SOURCE_FILE_LIST ${dobby.SOURCE_FILE_LIST} + source/UserMode/ExecMemory/code-patch-tool-darwin.cc + ) +endif() + +if(SYSTEM.iOS) + add_definitions(-DCODE_PATCH_WITH_SUBSTRATED) + set(dobby.SOURCE_FILE_LIST ${dobby.SOURCE_FILE_LIST} + source/UserMode/ExecMemory/substrated/mach_interface_support/substrated_client.c + ) +endif() + + +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/${arch1}/helper-${arch1}.cc + source/TrampolineBridge/ClosureTrampolineBridge/${arch1}/closure-bridge-${arch1}.cc + source/TrampolineBridge/ClosureTrampolineBridge/${arch1}/${ARCH1}AssemblyClosureTrampoline.cc + + # user mode - multi thread support + # source/UserMode/MultiThreadSupport/ThreadSupport.cpp + # source/UserMode/Thread/PlatformThread.cc + # source/UserMode/Thread/platform-thread-${platform1}.cc + ) +endif() + +if(FunctionWrapper) + message(FATAL_ERROR "[!] FunctionWrapper plugin is not supported") +endif() + +if(DynamicBinaryInstrument) + message(STATUS "[Dobby] Enable dynamic binary instrument(hook instruction with register context)") + set(dobby.SOURCE_FILE_LIST ${dobby.SOURCE_FILE_LIST} + source/InterceptRouting/Routing/DynamicBinaryInstrument/dynamic-binary-instrument.cc + source/InterceptRouting/Routing/DynamicBinaryInstrument/DynamicBinaryInstrumentExport.cc + source/InterceptRouting/Routing/DynamicBinaryInstrument/intercept_routing_handler.cc + ) +endif() + +if(NearBranch) + message(STATUS "[Dobby] Enable near branch trampoline(trampoline within single instruction)") + set(dobby.SOURCE_FILE_LIST ${dobby.SOURCE_FILE_LIST} + source/InterceptRouting/RoutingPlugin/NearBranchTrampoline/NeaBranchTrampoline.cc + source/MemoryAllocator/NearMemoryArena.cc) +endif() + +add_subdirectory(external/misc-helper) +get_target_property(misc_helper.SOURCE_FILE_LIST misc_helper SOURCES) + +# add logging library +add_subdirectory(external/logging) +get_target_property(logging.SOURCE_FILE_LIST logging SOURCES) + +# add xnucxx library +add_subdirectory(external/xnucxx) +get_target_property(xnucxx.SOURCE_FILE_LIST xnucxx SOURCES) + +if(Plugin.GlobalOffsetTableHook AND SYSTEM.Darwin) + message(STATUS "[Dobby] Enable global offset table hook") + + include_directories(builtin-plugin/GlobalOffsetTableHook) + add_subdirectory(builtin-plugin/GlobalOffsetTableHook) + get_target_property(global_offset_table_hook.SOURCE_FILE_LIST global_offset_table_hook SOURCES) + set(dobby.plugin.SOURCE_FILE_LIST ${dobby.plugin.SOURCE_FILE_LIST} + ${global_offset_table_hook.SOURCE_FILE_LIST} + ) +endif() + +if(Plugin.SymbolResolver) + message(STATUS "[Dobby] Enable symbol resolver") + + include_directories(builtin-plugin/SymbolResolver) + add_subdirectory(builtin-plugin/SymbolResolver) + get_target_property(symbol_resolver.SOURCE_FILE_LIST symbol_resolver SOURCES) + set(dobby.plugin.SOURCE_FILE_LIST ${dobby.plugin.SOURCE_FILE_LIST} + ${symbol_resolver.SOURCE_FILE_LIST} + ) +endif() + +if(Plugin.Android.BionicLinkerRestriction) + if(NOT SYSTEM.Android) + message(FATAL_ERROR "[!] Plugin.Android.BionicLinkerRestriction only works on Android.") + endif() + message(STATUS "[Dobby] Enable Plugin.Android.BionicLinkerRestriction") + set(dobby.plugin.SOURCE_FILE_LIST ${dobby.plugin.SOURCE_FILE_LIST} + builtin-plugin/BionicLinkerRestriction/bionic_linker_restriction.cc + ) +endif() + +if(Plugin.HideSystemCall) + set(dobby.plugin.SOURCE_FILE_LIST ${dobby.plugin.SOURCE_FILE_LIST} + ) +endif() + +if(Plugin.LinkerLoadCallback) + set(dobby.plugin.SOURCE_FILE_LIST ${dobby.plugin.SOURCE_FILE_LIST} + builtin-plugin/LinkerImageLoadCallback/linker_load_callback.cc + ) +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}") +add_definitions(-D__DOBBY_BUILD_VERSION__="${DOBBY_BUILD_VERSION}") +message(STATUS "[Dobby] ${DOBBY_BUILD_VERSION}") + +if(DOBBY_GENERATE_SHARED) + message(STATUS "[Dobby] Generate shared library") + set(DOBBY_LIBRARY_TYPE SHARED) +else() + message(STATUS "[Dobby] Generate static library") + set(DOBBY_LIBRARY_TYPE STATIC) +endif() +add_library(blackdex_d ${DOBBY_LIBRARY_TYPE} ${dobby.HEADER_FILE_LIST} ${dobby.SOURCE_FILE_LIST} ${logging.SOURCE_FILE_LIST} ${xnucxx.SOURCE_FILE_LIST} ${dobby.plugin.SOURCE_FILE_LIST}) + +target_include_directories(blackdex_d PUBLIC include) + +if(EnableObfuscation) +set(linker_flags "${linker_flags} -Wl,-mllvm -Wl,-obfuscator-conf=all") +endif() +set_target_properties(blackdex_d + PROPERTIES LINK_FLAGS "${linker_flags}" + ) +if(SYSTEM.Darwin) + # 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} ${xnucxx.SOURCE_FILE_LIST} ${dobby.plugin.SOURCE_FILE_LIST}) + + set_target_properties(DobbyX + PROPERTIES LINK_FLAGS "${linker_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" + ) + # set_target_properties(Dobby PROPERTIES + # LINK_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}" + # ) + + # message(STATUS "[Dobby] Enable Gollum.framework(iOS: 11.0 <= version, version <= 12.2, version == 12.4 )") + # add_custom_command(TARGET Dobby + # POST_BUILD + # COMMAND mkdir -p $/Frameworks + # COMMAND cp -R ${CMAKE_SOURCE_DIR}/buildin-plugin/Gollum_2019.12.31.framework $/Frameworks/Gollum.framework + # ) +endif() + +if(SYSTEM.Android) + target_link_libraries(blackdex_d log) +endif() + +if(SYSTEM.Linux) + target_link_libraries(blackdex_d dl) +endif() + +if(SYSTEM.Darwin) + target_link_libraries(DobbyX + "-framework Foundation") +endif() + +if(SYSTEM.Darwin) + add_subdirectory(builtin-plugin/Dyld2HideLibrary) + + add_subdirectory(builtin-plugin/ObjcRuntimeHook) + if(PROCESSOR.AARCH64) + add_subdirectory(builtin-plugin/SupervisorCallMonitor) + endif() +endif() + +add_subdirectory(example) diff --git a/Bcore/src/main/cpp/Dobby/LICENSE b/Bcore/src/main/cpp/Dobby/LICENSE new file mode 100644 index 00000000..f49a4e16 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/LICENSE @@ -0,0 +1,201 @@ + 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/Bcore/src/main/cpp/Dobby/README.md b/Bcore/src/main/cpp/Dobby/README.md new file mode 100755 index 00000000..43e39471 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/README.md @@ -0,0 +1,45 @@ +## 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) +- Clean code without STL(port to kernel easily) +- Plugin support(SymbolResolver, SupervisorCallMonitor) +- iOS kernel exploit support(Gollum ?) + +## Getting started + +``` +git clone https://github.com/jmpews/Dobby.git --depth=1 +cd Dobby/example/ +mkdir build; cd build; cmake .. +``` + +Or download [latest release](https://github.com/jmpews/Dobby/releases/tag/latest) + +#### [Build Installation](docs/build-documentation.md) + +#### [Getting Started with iOS](docs/get-started-ios.md) + +#### [Getting Started with Android](docs/get-started-android.md) + +## Documentation + +[full Installation documentation site](https://jmpews.github.io/Dobby/#/) + +## Download + +[download static 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/Bcore/src/main/cpp/Dobby/README_zh-cn.md b/Bcore/src/main/cpp/Dobby/README_zh-cn.md new file mode 100644 index 00000000..2f528b45 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/README_zh-cn.md @@ -0,0 +1,3 @@ +## Dobby + +**待更新** \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/build-workspace/auto-build.sh b/Bcore/src/main/cpp/Dobby/build-workspace/auto-build.sh new file mode 100755 index 00000000..72542e66 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/build-workspace/auto-build.sh @@ -0,0 +1,149 @@ +#!/bin/sh + +# if error, exit +set - + +CURRENT_DIR=$(dirname "$0") +SOURCE_DIR=${CURRENT_DIR}/.. + +compress_dir_array="" + +summary_output_dir_name=auto-build-output + +rm -rf ${summary_output_dir_name} + +# Darwin ================================================================ + +darwin_library_name=libdobby.a +darwin_fat_library_name=libdobby.a + +# build macos x86_64 +output_dir_name=auto-build-workspace/darwin-x86_64-build +echo "prepare build ${output_dir_name}" + +mkdir -p ${CURRENT_DIR}/${output_dir_name} +cmake -S ${SOURCE_DIR} -B ${output_dir_name} -DCMAKE_BUILD_TYPE=Release \ + -DDOBBY_GENERATE_SHARED=OFF -DDOBBY_DEBUG=OFF +cmake --build ${output_dir_name} --parallel 4 --target dobby + +mkdir -p ${summary_output_dir_name}/darwin/x86_64 +cp -r ${output_dir_name}/${darwin_library_name} ${summary_output_dir_name}/darwin/x86_64 + +# build iphone arm64 +output_dir_name=auto-build-workspace/darwin-arm64-build +compress_dir_array="$compress_dir_array $output_dir_name" +echo "prepare build ${output_dir_name}" + +mkdir -p ${CURRENT_DIR}/${output_dir_name} +cmake -S ${SOURCE_DIR} -B ${output_dir_name} -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_SYSTEM_PROCESSOR=arm64 -DCMAKE_OSX_DEPLOYMENT_TARGET=9.3 \ + -DDOBBY_GENERATE_SHARED=OFF -DDOBBY_DEBUG=OFF +cmake --build ${output_dir_name} --parallel 4 --target dobby + +mkdir -p ${summary_output_dir_name}/darwin/arm64 +cp -r ${output_dir_name}/${darwin_library_name} ${summary_output_dir_name}/darwin/arm64 + +# build iphone arm64e +output_dir_name=auto-build-workspace/darwin-arm64e-build +compress_dir_array="$compress_dir_array $output_dir_name" +echo "prepare build ${output_dir_name}" + +mkdir -p ${CURRENT_DIR}/${output_dir_name} +cmake -S ${SOURCE_DIR} -B ${output_dir_name} -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_TOOLCHAIN_FILE=cmake/ios.toolchain.cmake \ + -DPLATFORM=OS64 -DARCHS="arm64e" -DCMAKE_SYSTEM_PROCESSOR=arm64e \ + -DENABLE_BITCODE=0 -DENABLE_ARC=0 -DENABLE_VISIBILITY=1 -DDEPLOYMENT_TARGET=9.3 \ + -DDOBBY_GENERATE_SHARED=OFF -DDOBBY_DEBUG=OFF +cmake --build ${output_dir_name} --parallel 4 --target dobby + +mkdir -p ${summary_output_dir_name}/darwin/arm64e +cp -r ${output_dir_name}/${darwin_library_name} ${summary_output_dir_name}/darwin/arm64e + +# build darwin universal +output_dir_name=auto-build-workspace/darwin-universal-build +echo "prepare build ${output_dir_name}" + +mkdir -p ${CURRENT_DIR}/${output_dir_name} +cp -r ${summary_output_dir_name}/darwin/arm64/${darwin_library_name} ${output_dir_name} + +# create universal fat lib +lipo -create \ + ${summary_output_dir_name}/darwin/arm64/${darwin_fat_library_name} \ + ${summary_output_dir_name}/darwin/arm64e/${darwin_fat_library_name} \ + ${summary_output_dir_name}/darwin/x86_64/${darwin_fat_library_name} \ + -output ${output_dir_name}/${darwin_fat_library_name} + +mkdir -p ${summary_output_dir_name}/darwin/universal +cp -r ${output_dir_name}/${darwin_library_name} ${summary_output_dir_name}/darwin/universal + +# Android ================================================================ + +android_library_name=libdobby.a + +# build android aarch64 +output_dir_name=auto-build-workspace/android-arm64-build +compress_dir_array="$compress_dir_array $output_dir_name" +echo "prepare build ${output_dir_name}" + +cmake -S ${SOURCE_DIR} -B ${output_dir_name} -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_SYSTEM_NAME=Android -DCMAKE_ANDROID_ARCH_ABI="arm64-v8a" -DCMAKE_ANDROID_NDK=$ANDROID_NDK_DIR -DCMAKE_SYSTEM_VERSION=21 -DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=clang \ + -DDOBBY_GENERATE_SHARED=OFF -DDOBBY_DEBUG=OFF -DPlugin.Android.BionicLinkerRestriction=ON +cmake --build ${output_dir_name} --parallel 4 --target dobby + +mkdir -p ${summary_output_dir_name}/android/arm64 +mv ${output_dir_name}/${android_library_name} ${summary_output_dir_name}/android/arm64/${android_library_name} +mv ${output_dir_name}/${android_library_name} "prefab/modules/dobby/libs/android.arm64-v8a/${android_library_name}" + +# build android armv7 +output_dir_name=auto-build-workspace/android-armv7-build +compress_dir_array="$compress_dir_array $output_dir_name" +echo "prepare build ${output_dir_name}" + +cmake -S ${SOURCE_DIR} -B ${output_dir_name} -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_SYSTEM_NAME=Android -DCMAKE_ANDROID_ARCH_ABI="armeabi-v7a" -DCMAKE_ANDROID_NDK=$ANDROID_NDK_DIR -DCMAKE_SYSTEM_VERSION=16 -DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=clang \ + -DDOBBY_GENERATE_SHARED=OFF -DDOBBY_DEBUG=OFF -DPlugin.Android.BionicLinkerRestriction=ON +cmake --build ${output_dir_name} --parallel 4 --target dobby + +mkdir -p ${summary_output_dir_name}/android/armv7 +mv ${output_dir_name}/${android_library_name} ${summary_output_dir_name}/android/armv7/${android_library_name} +mv ${output_dir_name}/${android_library_name} "prefab/modules/dobby/libs/android.armeabi-v7a/${android_library_name}" + +# build android x86 +output_dir_name=auto-build-workspace/android-x86-build +compress_dir_array="$compress_dir_array $output_dir_name" +echo "prepare build ${output_dir_name}" + +cmake -S ${SOURCE_DIR} -B ${output_dir_name} -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_SYSTEM_NAME=Android -DCMAKE_ANDROID_ARCH_ABI="x86" -DCMAKE_ANDROID_NDK=$ANDROID_NDK_DIR -DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=clang \ + -DDOBBY_GENERATE_SHARED=OFF -DDOBBY_DEBUG=OFF -DPlugin.Android.BionicLinkerRestriction=ON +cmake --build ${output_dir_name} --parallel 4 --target dobby + +mkdir -p ${summary_output_dir_name}/android/x86 +mv ${output_dir_name}/${android_library_name} ${summary_output_dir_name}/android/x86/${android_library_name} +mv ${output_dir_name}/${android_library_name} "prefab/modules/dobby/libs/android.x86/${android_library_name}" + +# build android x86_64 +output_dir_name=auto-build-workspace/android-x86_64-build +compress_dir_array="$compress_dir_array $output_dir_name" +echo "prepare build ${output_dir_name}" + +cmake -S ${SOURCE_DIR} -B ${output_dir_name} -DCMAKE_BUILD_TYPE=Release \ + -DCMAKE_SYSTEM_NAME=Android -DCMAKE_ANDROID_ARCH_ABI="x86_64" -DCMAKE_ANDROID_NDK=$ANDROID_NDK_DIR -DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=clang \ + -DDOBBY_GENERATE_SHARED=OFF -DDOBBY_DEBUG=OFF -DPlugin.Android.BionicLinkerRestriction=ON +cmake --build ${output_dir_name} --parallel 4 --target dobby + +mkdir -p ${summary_output_dir_name}/android/x86_64 +mv ${output_dir_name}/${android_library_name} ${summary_output_dir_name}/android/x86_64/${android_library_name} +#mv ${output_dir_name}/${android_library_name} "prefab/modules/dobby/libs/android.x86_64/${android_library_name}" + +## zip android prefab +#mkdir -p prefab/modules/dobby/include +#cp "include/dobby.h" "prefab/modules/dobby/include/" +#cp "builtin-plugin/BionicLinkerRestriction/bionic_linker_restriction.h" "prefab/modules/dobby/include/" +#cp "builtin-plugin/SymbolResolver/dobby_symbol_resolver.h" "prefab/modules/dobby/include/" +#cp "prefab/AndroidManifest.xml" . +#zip -r ${summary_output_dir_name}/android_prefab.aar prefab AndroidManifest.xml -x prefab/AndroidManifest.xml + +if [ $DOBBY_BUILD_OUTPUT_NAME ]; then + tar czvf ${DOBBY_BUILD_OUTPUT_NAME} ${summary_output_dir_name} +fi diff --git a/Bcore/src/main/cpp/Dobby/build-workspace/prefab/AndroidManifest.xml b/Bcore/src/main/cpp/Dobby/build-workspace/prefab/AndroidManifest.xml new file mode 100644 index 00000000..c7fb4f35 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/build-workspace/prefab/AndroidManifest.xml @@ -0,0 +1,9 @@ + + + + + + diff --git a/Bcore/src/main/cpp/Dobby/build-workspace/prefab/modules/dobby/libs/android.arm64-v8a/abi.json b/Bcore/src/main/cpp/Dobby/build-workspace/prefab/modules/dobby/libs/android.arm64-v8a/abi.json new file mode 100644 index 00000000..64805a3c --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/build-workspace/prefab/modules/dobby/libs/android.arm64-v8a/abi.json @@ -0,0 +1,6 @@ +{ + "abi": "arm64-v8a", + "api": 21, + "ndk": 21, + "stl": "c++_static" +} diff --git a/Bcore/src/main/cpp/Dobby/build-workspace/prefab/modules/dobby/libs/android.armeabi-v7a/abi.json b/Bcore/src/main/cpp/Dobby/build-workspace/prefab/modules/dobby/libs/android.armeabi-v7a/abi.json new file mode 100644 index 00000000..143d3034 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/build-workspace/prefab/modules/dobby/libs/android.armeabi-v7a/abi.json @@ -0,0 +1,6 @@ +{ + "abi": "armeabi-v7a", + "api": 16, + "ndk": 21, + "stl": "c++_static" +} diff --git a/Bcore/src/main/cpp/Dobby/build-workspace/prefab/modules/dobby/libs/android.x86/abi.json b/Bcore/src/main/cpp/Dobby/build-workspace/prefab/modules/dobby/libs/android.x86/abi.json new file mode 100644 index 00000000..00d05a42 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/build-workspace/prefab/modules/dobby/libs/android.x86/abi.json @@ -0,0 +1,6 @@ +{ + "abi": "x86", + "api": 16, + "ndk": 21, + "stl": "c++_static" +} diff --git a/Bcore/src/main/cpp/Dobby/build-workspace/prefab/modules/dobby/libs/android.x86_64/abi.json b/Bcore/src/main/cpp/Dobby/build-workspace/prefab/modules/dobby/libs/android.x86_64/abi.json new file mode 100644 index 00000000..2adf0060 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/build-workspace/prefab/modules/dobby/libs/android.x86_64/abi.json @@ -0,0 +1,6 @@ +{ + "abi": "x86_64", + "api": 21, + "ndk": 21, + "stl": "c++_static" +} diff --git a/Bcore/src/main/cpp/Dobby/build-workspace/prefab/modules/dobby/module.json b/Bcore/src/main/cpp/Dobby/build-workspace/prefab/modules/dobby/module.json new file mode 100644 index 00000000..5d239944 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/build-workspace/prefab/modules/dobby/module.json @@ -0,0 +1,4 @@ +{ + "export_libraries": [], + "android": {} +} diff --git a/Bcore/src/main/cpp/Dobby/build-workspace/prefab/prefab.json b/Bcore/src/main/cpp/Dobby/build-workspace/prefab/prefab.json new file mode 100644 index 00000000..ba38d7fc --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/build-workspace/prefab/prefab.json @@ -0,0 +1,5 @@ +{ + "name": "dobby", + "schema_version": 1, + "dependencies": [] +} diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/MGCopyAnswerMonitor.cc b/Bcore/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/MGCopyAnswerMonitor.cc new file mode 100644 index 00000000..275a25be --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/MGCopyAnswerMonitor.cc @@ -0,0 +1,46 @@ +#include "./dobby_monitor.h" + +#include +#include + +#define LOG_TAG "MGCopyAnswer" + +static uintptr_t getCallFirstArg(RegisterContext *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(RegisterContext *ctx, const HookEntryInfo *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/Bcore/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/dobby_monitor.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/dobby_monitor.h new file mode 100644 index 00000000..0332b493 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/dobby_monitor.h @@ -0,0 +1,28 @@ +#ifndef DOBBY_MONITOR_H +#define DOBBY_MONITOR_H + +#include /* getenv */ +#include +#include + +#include +#include + +#include +#include + +#include "dobby.h" + +#define LOG printf + +#ifdef __cplusplus +extern "C" { +#endif + +int DobbyHook(void *function_address, void *replace_call, void **origin_call); + +#ifdef __cplusplus +} +#endif + +#endif // !1DOBBY_MONITOR diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/dynamic_loader_monitor.cc b/Bcore/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/dynamic_loader_monitor.cc new file mode 100644 index 00000000..5de42843 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/dynamic_loader_monitor.cc @@ -0,0 +1,94 @@ +#include /* getenv */ +#include +#include + +#include +#include + +#include +#include + +#include +#include + +#include "dobby.h" + +#include "common_header.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); + LOG(1, "[-] 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); + LOG(1, "[-] 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) { + LOG(1, "[-] 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) { + LOG(1, "[-] 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/Bcore/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/file_operation_monitor.cc b/Bcore/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/file_operation_monitor.cc new file mode 100644 index 00000000..d4f09ca5 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/file_operation_monitor.cc @@ -0,0 +1,97 @@ +#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/Bcore/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/memory_operation_instrument.cc b/Bcore/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/memory_operation_instrument.cc new file mode 100644 index 00000000..7604e68e --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/memory_operation_instrument.cc @@ -0,0 +1,58 @@ +#include "./dobby_monitor.h" + +#include +#include +#include + +static uintptr_t getCallFirstArg(RegisterContext *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(RegisterContext *ctx, const HookEntryInfo *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(RegisterContext *ctx, const HookEntryInfo *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/Bcore/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/posix_file_descriptor_operation_monitor.cc b/Bcore/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/posix_file_descriptor_operation_monitor.cc new file mode 100644 index 00000000..4aaa2f4d --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/posix_file_descriptor_operation_monitor.cc @@ -0,0 +1,120 @@ +#include /* getenv */ +#include +#include + +#include +#include +#include + +#include + +#include +#include + +#include +#include + +#include + +#include "dobby.h" +#include "common_header.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); + LOG(1, "[-] 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); + LOG(1, "[-] 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) { + LOG(1, "[-] 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) { + LOG(1, "[-] 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) { + LOG(1, "[-] 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/Bcore/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/posix_socket_network_monitor.cc b/Bcore/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/posix_socket_network_monitor.cc new file mode 100644 index 00000000..8314a189 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/ApplicationEventMonitor/posix_socket_network_monitor.cc @@ -0,0 +1,57 @@ +#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) { + LOG(1, "[-] 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) { + LOG(1, "[-] 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) { + LOG(1, "[-] 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/Bcore/src/main/cpp/Dobby/builtin-plugin/BionicLinkerRestriction/bionic_linker_restriction.cc b/Bcore/src/main/cpp/Dobby/builtin-plugin/BionicLinkerRestriction/bionic_linker_restriction.cc new file mode 100644 index 00000000..1fdba7ba --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/BionicLinkerRestriction/bionic_linker_restriction.cc @@ -0,0 +1,197 @@ +#include "bionic_linker_restriction.h" + +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "dobby.h" +#include "dobby_symbol_resolver.h" + +#include "common_header.h" + +#undef LOG_TAG +#define LOG_TAG "AndroidLinkerRestriction" + +#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.release", 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); + LOG(1, "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) { + LOG(1, "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); + + LOG(1, "disable namespace restriction done"); +} diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/BionicLinkerRestriction/bionic_linker_restriction.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/BionicLinkerRestriction/bionic_linker_restriction.h new file mode 100644 index 00000000..bf192dd6 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/BionicLinkerRestriction/bionic_linker_restriction.h @@ -0,0 +1,26 @@ +#ifndef LINKER_RESTRICTION_H +#define LINKER_RESTRICTION_H + +#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 + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/BionicLinkerRestriction/linker_restriction_demo.cc b/Bcore/src/main/cpp/Dobby/builtin-plugin/BionicLinkerRestriction/linker_restriction_demo.cc new file mode 100644 index 00000000..eb96607a --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/BionicLinkerRestriction/linker_restriction_demo.cc @@ -0,0 +1,36 @@ +#include "dobby.h" + +#include "bionic_linker_restriction.h" + +#include "logging/logging.h" + +#include + +#define LOG_TAG "AndroidLinkerRestriction" + +__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"); + LOG(1, "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 + LOG(1, "vm %p", vm); +} diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/Dyld2HideLibrary/CMakeLists.txt b/Bcore/src/main/cpp/Dobby/builtin-plugin/Dyld2HideLibrary/CMakeLists.txt new file mode 100644 index 00000000..ccab875b --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/Dyld2HideLibrary/CMakeLists.txt @@ -0,0 +1,3 @@ +add_library(dyld2_hide_library + dyld2_hide_library.cc + ) \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/Dyld2HideLibrary/dyld2_hide_library.cc b/Bcore/src/main/cpp/Dobby/builtin-plugin/Dyld2HideLibrary/dyld2_hide_library.cc new file mode 100644 index 00000000..9ca9d786 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/Dyld2HideLibrary/dyld2_hide_library.cc @@ -0,0 +1,136 @@ +#include "Dyld2HideLibrary/dyld2_hide_library.h" + +#include +#include +#include +#include + +#include +#include + +#include + +#include + +#include + +#include "dobby_internal.h" + +typedef void ImageLoader; + +typedef void ImageLoaderMachO; + +static void *(*removeImageFromAllImages)(const struct mach_header *mh) = NULL; + +static char *(*ImageLoader__getShortName)(ImageLoader *loader) = NULL; + +static struct mach_header *(*ImageLoaderMachO__machHeader)(ImageLoaderMachO *loader) = NULL; + +static std::vector *sAllImages = NULL; + +std::vector *g_prepare_remove_array; + +static int dobby_hide_library_internal(const char *library_name) { + if (removeImageFromAllImages == NULL) { + removeImageFromAllImages = + (typeof(removeImageFromAllImages))DobbySymbolResolver("dyld", "__Z24removeImageFromAllImagesPK11mach_header"); + } + + if (ImageLoader__getShortName == NULL) { + ImageLoader__getShortName = + (typeof(ImageLoader__getShortName))DobbySymbolResolver("dyld", "__ZNK11ImageLoader12getShortNameEv"); + } + + if (ImageLoaderMachO__machHeader == NULL) { + ImageLoaderMachO__machHeader = + (typeof(ImageLoaderMachO__machHeader))DobbySymbolResolver("dyld", "__ZNK16ImageLoaderMachO10machHeaderEv"); + } + + if (sAllImages == NULL) + sAllImages = (typeof(sAllImages))DobbySymbolResolver("dyld", "__ZN4dyldL10sAllImagesE"); + +#if 0 + if (dyld3__AllImages__imageLoadAddressByIndex == NULL) { + dyld3__AllImages__imageLoadAddressByIndex = (typeof(removeImageFromAllImages))DobbySymbolResolver( + "libdyld.dylib", "__ZNK5dyld39AllImages23imageLoadAddressByIndexEj"); + } + + if (dyld3_sAllImages == NULL) + dyld3_sAllImages = (typeof(dyld3_sAllImages))DobbySymbolResolver("libdyld.dylib", "__ZN5dyld310gAllImagesE"); +#endif + +#if 0 + typedef void AllImages; + static void(*AllImages__decRefCount)(AllImages *_this, const struct mach_header *mh) = NULL; + if(AllImages__decRefCount == NULL) { + AllImages__decRefCount = (typeof(AllImages__decRefCount))DobbySymbolResolver("libdyld.dylib", "__ZN5dyld39AllImages11decRefCountEPK11mach_header"); + } + + static AllImages *gAllImages = NULL; + if(gAllImages == NULL) { + gAllImages = (typeof(gAllImages))DobbySymbolResolver("libdyld.dylib", "__ZN5dyld310gAllImagesE"); + } +#endif + + // int count = _dyld_image_count(); + // for (int i = 0; i < count; i++) { + // const char *name = _dyld_get_image_name(i); + // const char *image_name = strrchr(name, '/'); + // if (image_name == NULL) { + // continue; + // } + // image_name += 1; + // if (strcmp(image_name, library_name) == 0) { + // const struct mach_header *header = _dyld_get_image_header(i); + // AllImages__decRefCount(gAllImages, header); + // break; + // } + // } + + for (std::vector::iterator it = sAllImages->begin(); it != sAllImages->end(); it++) { + char *name = ImageLoader__getShortName(*it); + // LOG(2, "load library : %s", name); + if (strcmp(name, library_name) == 0) { + LOG(2, "strip load library : %s", library_name); + struct mach_header *header = ImageLoaderMachO__machHeader(*it); + removeImageFromAllImages(header); + sAllImages->erase(it); + break; + } + } + + return 0; +} + +PUBLIC int dyld2_hide_library(const char *library_name) { +#if 1 + dobby_hide_library_internal(library_name); + return 0; +#endif + + if (g_prepare_remove_array == NULL) + g_prepare_remove_array = new std::vector(); + g_prepare_remove_array->push_back((char *)library_name); +} + +static void common_handler(RegisterContext *ctx, const HookEntryInfo *info) { + if (g_prepare_remove_array == nullptr) + return; + for (auto name : *g_prepare_remove_array) { + dobby_hide_library_internal(name); + } +} + +__attribute__((constructor)) static void ctor() { +#if 0 + void *dyld__notifyMonitoringDyldMain = DobbySymbolResolver("dyld", "__ZN4dyldL24notifyMonitoringDyldMainEv"); + DobbyInstrument(dyld__notifyMonitoringDyldMain, common_handler); +#endif + + log_switch_to_syslog(); + +#if defined(DOBBY_DEBUG) && 0 + dyld2_hide_library("Dobby"); + dyld2_hide_library("liblangid.dylib"); +#endif +} diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/Dyld2HideLibrary/dyld2_hide_library.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/Dyld2HideLibrary/dyld2_hide_library.h new file mode 100644 index 00000000..be9e88ed --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/Dyld2HideLibrary/dyld2_hide_library.h @@ -0,0 +1,11 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +int dyld2_hide_library(const char *library_name); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/GlobalOffsetTableHook/CMakeLists.txt b/Bcore/src/main/cpp/Dobby/builtin-plugin/GlobalOffsetTableHook/CMakeLists.txt new file mode 100644 index 00000000..194b450f --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/GlobalOffsetTableHook/CMakeLists.txt @@ -0,0 +1,13 @@ +if(SYSTEM.Darwin) +set(SOURCE_FILE_LIST + ${CMAKE_CURRENT_SOURCE_DIR}/global_offset_table_hook.cc + ) +endif() + +add_library(global_offset_table_hook STATIC + ${SOURCE_FILE_LIST} + ) + +include_directories( + . +) diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/GlobalOffsetTableHook/global_offset_table_hook.cc b/Bcore/src/main/cpp/Dobby/builtin-plugin/GlobalOffsetTableHook/global_offset_table_hook.cc new file mode 100644 index 00000000..70fbe045 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/GlobalOffsetTableHook/global_offset_table_hook.cc @@ -0,0 +1,192 @@ +#include "global_offset_table_hook.h" + +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include + +#include "common_header.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 DobbyGlobalOffsetTableReplace(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 + LOG(1, "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/Bcore/src/main/cpp/Dobby/builtin-plugin/GlobalOffsetTableHook/global_offset_table_hook.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/GlobalOffsetTableHook/global_offset_table_hook.h new file mode 100644 index 00000000..f88c0670 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/GlobalOffsetTableHook/global_offset_table_hook.h @@ -0,0 +1,11 @@ +#pragma once + +#ifdef __cplusplus +extern "C" { +#endif + +int DobbyGlobalOffsetTableReplace(char *image_name, char *symbol_name, void *fake_func, void **orig_func); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/HideSystemCall/README b/Bcore/src/main/cpp/Dobby/builtin-plugin/HideSystemCall/README new file mode 100644 index 00000000..c8c6761a --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/HideSystemCall/README @@ -0,0 +1 @@ +private \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/IntegrityReadCallback/README b/Bcore/src/main/cpp/Dobby/builtin-plugin/IntegrityReadCallback/README new file mode 100644 index 00000000..c8c6761a --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/IntegrityReadCallback/README @@ -0,0 +1 @@ +private \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/LinkerImageLoadCallback/linker_load_callback.cc b/Bcore/src/main/cpp/Dobby/builtin-plugin/LinkerImageLoadCallback/linker_load_callback.cc new file mode 100644 index 00000000..a3f026a6 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/LinkerImageLoadCallback/linker_load_callback.cc @@ -0,0 +1,61 @@ +#include "dobby.h" +#include "common_header.h" + +#include + +#include + +#define LOG_TAG "LinkerLoadCallback" + +std::vector *linker_load_callback_array; + +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) { + for (auto &callback : *linker_load_callback_array) { + callback(__file, result); + } + } + 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) { + for (auto &callback : *linker_load_callback_array) { + callback(filename, result); + } + } + return result; +} + +PUBLIC void dobby_register_image_load_callback(linker_load_callback_t func) { + if (linker_load_callback_array == NULL) + linker_load_callback_array = new std::vector(); + linker_load_callback_array->push_back(func); +} + +#if defined(DOBBY_DEBUG) && 1 +static void monitor_linker_load(const char *image_name, void *handle) { + LOG(1, "load %s at %p", image_name, handle); +} +#endif + +__attribute__((constructor)) static void ctor() { + if (linker_load_callback_array == NULL) + linker_load_callback_array = new std::vector(); + +#if defined(__ANDROID__) + void *__loader_dlopen = DobbySymbolResolver(NULL, "__loader_dlopen"); + LOG(1, "__loader_dlopen: %p", __loader_dlopen); + DobbyHook(__loader_dlopen, (void *)fake_loader_dlopen, (void **)&orig_loader_dlopen); +#else + DobbyHook((void *)DobbySymbolResolver(NULL, "dlopen"), (void *)fake_dlopen, (void **)&orig_dlopen); +#endif + +#if defined(DOBBY_DEBUG) && 1 + dobby_register_image_load_callback(monitor_linker_load); +#endif +} diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/MemoryRemapHook/README b/Bcore/src/main/cpp/Dobby/builtin-plugin/MemoryRemapHook/README new file mode 100644 index 00000000..c8c6761a --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/MemoryRemapHook/README @@ -0,0 +1 @@ +private \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/ObjcRuntimeHook/CMakeLists.txt b/Bcore/src/main/cpp/Dobby/builtin-plugin/ObjcRuntimeHook/CMakeLists.txt new file mode 100644 index 00000000..c689f124 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/ObjcRuntimeHook/CMakeLists.txt @@ -0,0 +1,3 @@ +add_library(objc_runtime_hook + objc_runtime_hook.mm + ) \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/ObjcRuntimeHook/objc_runtime_hook.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/ObjcRuntimeHook/objc_runtime_hook.h new file mode 100644 index 00000000..bb721da9 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/ObjcRuntimeHook/objc_runtime_hook.h @@ -0,0 +1,19 @@ +#pragma once + +#include +#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/Bcore/src/main/cpp/Dobby/builtin-plugin/ObjcRuntimeHook/objc_runtime_hook.mm b/Bcore/src/main/cpp/Dobby/builtin-plugin/ObjcRuntimeHook/objc_runtime_hook.mm new file mode 100644 index 00000000..292fa99e --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/ObjcRuntimeHook/objc_runtime_hook.mm @@ -0,0 +1,60 @@ +#include "ObjcRuntimeHook/objc_runtime_hook.h" +#include "dobby_internal.h" + +#include +#include + +extern "C" { +#include "misc-helper/variable_cache.h" +} + +/* 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_) { + DLOG(0, "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_) { + DLOG(0, "Not found class: %s, selector: %s method\n", class_name, selector_name); + return; + } + + void *orig_impl = NULL; + 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_) { + DLOG(0, "Not found class: %s, selector: %s method\n", class_name, selector_name); + return NULL; + } + return (void *)method_getImplementation(method_); +} diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/CMakeLists.txt b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/CMakeLists.txt new file mode 100644 index 00000000..ddddfd76 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/CMakeLists.txt @@ -0,0 +1,23 @@ +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/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/README b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/README new file mode 100644 index 00000000..3832eb51 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/README @@ -0,0 +1 @@ +Monitor all supervisor call \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/README b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/README new file mode 100644 index 00000000..b4966e0e --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/README @@ -0,0 +1 @@ +syscalls.c is automatically generated \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/audit_triggers.defs b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/audit_triggers.defs new file mode 100644 index 00000000..1d6e279b --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/audit_triggers.defs @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2004-2008, Apple Inc. All rights reserved. + * + * @APPLE_BSD_LICENSE_HEADER_START@ + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * @APPLE_BSD_LICENSE_HEADER_END@ +*/ + +/* + * Interface definition for the audit logging facility. + */ + +subsystem +#if KERNEL_USER + KernelUser +#endif /* KERNEL_USER */ + audit_triggers 123; + +#include +#include + +simpleroutine audit_triggers( + audit_port : mach_port_t; + in flags : int); + diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/boolean.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/boolean.h new file mode 100644 index 00000000..6ef6d4bc --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/boolean.h @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * File: mach/boolean.h + * + * Boolean data type. + * + */ + +#ifndef _MACH_BOOLEAN_H_ +#define _MACH_BOOLEAN_H_ + +/* + * Pick up "boolean_t" type definition + */ + +#ifndef ASSEMBLER +#include +#endif /* ASSEMBLER */ + +/* + * Define TRUE and FALSE if not defined. + */ + +#ifndef TRUE +#define TRUE 1 +#endif /* TRUE */ + +#ifndef FALSE +#define FALSE 0 +#endif /* FALSE */ + +#endif /* _MACH_BOOLEAN_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/bootstrap.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/bootstrap.h new file mode 100644 index 00000000..e8300859 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/bootstrap.h @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2002 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * Mach bootstrap interfaces (obsolete: header included only for compatibility) + */ +#ifndef _MACH_BOOTSTRAP_H_ +#define _MACH_BOOTSTRAP_H_ + +#endif /* _MACH_BOOTSTRAP_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/clock.defs b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/clock.defs new file mode 100644 index 00000000..440042c8 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/clock.defs @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * File: mach/clock.defs + * Purpose: Kernel clock subsystem definitions. This + * file defines the clock request interface. + */ + +subsystem +#if KERNEL_SERVER + KernelServer +#endif /* KERNEL_SERVER */ + clock 1000; + +#include +#include +#include + +/* + * References to clock objects are returned by: + * host_get_clock_service(host_t,...) + * host_get_clock_control(host_priv_t,...) - Priviledged subclass + */ + +/* + * Get the clock time. + * Available to all. + */ +routine clock_get_time( + clock_serv : clock_serv_t; + out cur_time : mach_timespec_t); + +/* + * Get clock attributes. + * Available to all. + */ +routine clock_get_attributes( + clock_serv : clock_serv_t; + in flavor : clock_flavor_t; + out clock_attr : clock_attr_t, CountInOut); + +/* + * Setup a clock alarm. + * Available to all. + */ +routine clock_alarm( + clock_serv : clock_serv_t; + alarm_type : alarm_type_t; + alarm_time : mach_timespec_t; + alarm_port : clock_reply_t = + MACH_MSG_TYPE_MAKE_SEND_ONCE|polymorphic); + +/* vim: set ft=c : */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/clock.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/clock.h new file mode 100644 index 00000000..81e90eea --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/clock.h @@ -0,0 +1,245 @@ +#ifndef _clock_user_ +#define _clock_user_ + +/* Module clock */ + +#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 clock_MSG_COUNT +#define clock_MSG_COUNT 3 +#endif /* clock_MSG_COUNT */ + +#include +#include +#include +#include +#include + +#ifdef __BeforeMigUserHeader +__BeforeMigUserHeader +#endif /* __BeforeMigUserHeader */ + +#include +__BEGIN_DECLS + + +/* Routine clock_get_time */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t clock_get_time +( + clock_serv_t clock_serv, + mach_timespec_t *cur_time +); + +/* Routine clock_get_attributes */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t clock_get_attributes +( + clock_serv_t clock_serv, + clock_flavor_t flavor, + clock_attr_t clock_attr, + mach_msg_type_number_t *clock_attrCnt +); + +/* Routine clock_alarm */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t clock_alarm +( + clock_serv_t clock_serv, + alarm_type_t alarm_type, + mach_timespec_t alarm_time, + clock_reply_t alarm_port +); + +__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__clock_subsystem__defined +#define __Request__clock_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__clock_get_time_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + clock_flavor_t flavor; + mach_msg_type_number_t clock_attrCnt; + } __Request__clock_get_attributes_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 alarm_port; + /* end of the kernel processed data */ + NDR_record_t NDR; + alarm_type_t alarm_type; + mach_timespec_t alarm_time; + } __Request__clock_alarm_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Request__clock_subsystem__defined */ + +/* union of all requests */ + +#ifndef __RequestUnion__clock_subsystem__defined +#define __RequestUnion__clock_subsystem__defined +union __RequestUnion__clock_subsystem { + __Request__clock_get_time_t Request_clock_get_time; + __Request__clock_get_attributes_t Request_clock_get_attributes; + __Request__clock_alarm_t Request_clock_alarm; +}; +#endif /* !__RequestUnion__clock_subsystem__defined */ +/* typedefs for all replies */ + +#ifndef __Reply__clock_subsystem__defined +#define __Reply__clock_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_timespec_t cur_time; + } __Reply__clock_get_time_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t clock_attrCnt; + int clock_attr[1]; + } __Reply__clock_get_attributes_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__clock_alarm_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Reply__clock_subsystem__defined */ + +/* union of all replies */ + +#ifndef __ReplyUnion__clock_subsystem__defined +#define __ReplyUnion__clock_subsystem__defined +union __ReplyUnion__clock_subsystem { + __Reply__clock_get_time_t Reply_clock_get_time; + __Reply__clock_get_attributes_t Reply_clock_get_attributes; + __Reply__clock_alarm_t Reply_clock_alarm; +}; +#endif /* !__RequestUnion__clock_subsystem__defined */ + +#ifndef subsystem_to_name_map_clock +#define subsystem_to_name_map_clock \ + { "clock_get_time", 1000 },\ + { "clock_get_attributes", 1001 },\ + { "clock_alarm", 1002 } +#endif + +#ifdef __AfterMigUserHeader +__AfterMigUserHeader +#endif /* __AfterMigUserHeader */ + +#endif /* _clock_user_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/clock_priv.defs b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/clock_priv.defs new file mode 100644 index 00000000..b3854a4e --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/clock_priv.defs @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * File: mach/clock_priv.defs + * Purpose: Kernel clock subsystem definitions. This + * file defines the clock request interface. + */ + +subsystem +#if KERNEL_SERVER + KernelServer +#endif /* KERNEL_SERVER */ + clock_priv 1200; + +#include +#include +#include + +/* + * References to clock_priv objects are returned by: + * host_get_clock_control(host_priv_t,...) - Priviledged subclass + */ + +/* + * Set the clock time. + * Privileged. + */ +routine clock_set_time( + clock_ctrl : clock_ctrl_t; + new_time : mach_timespec_t); + +/* + * Set clock attributes. + * Privileged. + */ +routine clock_set_attributes( + clock_ctrl : clock_ctrl_t; + in flavor : clock_flavor_t; + in clock_attr : clock_attr_t); + +/* vim: set ft=c : */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/clock_priv.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/clock_priv.h new file mode 100644 index 00000000..ec6a6584 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/clock_priv.h @@ -0,0 +1,199 @@ +#ifndef _clock_priv_user_ +#define _clock_priv_user_ + +/* Module clock_priv */ + +#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 clock_priv_MSG_COUNT +#define clock_priv_MSG_COUNT 2 +#endif /* clock_priv_MSG_COUNT */ + +#include +#include +#include +#include +#include + +#ifdef __BeforeMigUserHeader +__BeforeMigUserHeader +#endif /* __BeforeMigUserHeader */ + +#include +__BEGIN_DECLS + + +/* Routine clock_set_time */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t clock_set_time +( + clock_ctrl_t clock_ctrl, + mach_timespec_t new_time +); + +/* Routine clock_set_attributes */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t clock_set_attributes +( + clock_ctrl_t clock_ctrl, + clock_flavor_t flavor, + clock_attr_t clock_attr, + mach_msg_type_number_t clock_attrCnt +); + +__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__clock_priv_subsystem__defined +#define __Request__clock_priv_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_timespec_t new_time; + } __Request__clock_set_time_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + clock_flavor_t flavor; + mach_msg_type_number_t clock_attrCnt; + int clock_attr[1]; + } __Request__clock_set_attributes_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Request__clock_priv_subsystem__defined */ + +/* union of all requests */ + +#ifndef __RequestUnion__clock_priv_subsystem__defined +#define __RequestUnion__clock_priv_subsystem__defined +union __RequestUnion__clock_priv_subsystem { + __Request__clock_set_time_t Request_clock_set_time; + __Request__clock_set_attributes_t Request_clock_set_attributes; +}; +#endif /* !__RequestUnion__clock_priv_subsystem__defined */ +/* typedefs for all replies */ + +#ifndef __Reply__clock_priv_subsystem__defined +#define __Reply__clock_priv_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__clock_set_time_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__clock_set_attributes_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Reply__clock_priv_subsystem__defined */ + +/* union of all replies */ + +#ifndef __ReplyUnion__clock_priv_subsystem__defined +#define __ReplyUnion__clock_priv_subsystem__defined +union __ReplyUnion__clock_priv_subsystem { + __Reply__clock_set_time_t Reply_clock_set_time; + __Reply__clock_set_attributes_t Reply_clock_set_attributes; +}; +#endif /* !__RequestUnion__clock_priv_subsystem__defined */ + +#ifndef subsystem_to_name_map_clock_priv +#define subsystem_to_name_map_clock_priv \ + { "clock_set_time", 1200 },\ + { "clock_set_attributes", 1201 } +#endif + +#ifdef __AfterMigUserHeader +__AfterMigUserHeader +#endif /* __AfterMigUserHeader */ + +#endif /* _clock_priv_user_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/clock_reply.defs b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/clock_reply.defs new file mode 100644 index 00000000..9646f90d --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/clock_reply.defs @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * File: clock_reply.defs + * Purpose: Kernel clock subsystem definitions. This + * file defines the clock reply interface. + */ + +subsystem +#if KERNEL_USER + KernelUser +#endif /* KERNEL_USER */ + clock_reply 3125107; /* Matches up with old value */ + +#include +#include + + +/* + * Reply routine for clock_alarm. + */ +simpleroutine clock_alarm_reply( + alarm_port : clock_reply_t; + alarm_code : kern_return_t; + alarm_type : alarm_type_t; + alarm_time : mach_timespec_t); + +/* vim: set ft=c : */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/clock_reply.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/clock_reply.h new file mode 100644 index 00000000..7bacc95c --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/clock_reply.h @@ -0,0 +1,159 @@ +#ifndef _clock_reply_user_ +#define _clock_reply_user_ + +/* Module clock_reply */ + +#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 clock_reply_MSG_COUNT +#define clock_reply_MSG_COUNT 1 +#endif /* clock_reply_MSG_COUNT */ + +#include +#include +#include + +#ifdef __BeforeMigUserHeader +__BeforeMigUserHeader +#endif /* __BeforeMigUserHeader */ + +#include +__BEGIN_DECLS + + +/* SimpleRoutine clock_alarm_reply */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t clock_alarm_reply +( + clock_reply_t alarm_port, + mach_msg_type_name_t alarm_portPoly, + kern_return_t alarm_code, + alarm_type_t alarm_type, + mach_timespec_t alarm_time +); + +__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__clock_reply_subsystem__defined +#define __Request__clock_reply_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t alarm_code; + alarm_type_t alarm_type; + mach_timespec_t alarm_time; + } __Request__clock_alarm_reply_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Request__clock_reply_subsystem__defined */ + +/* union of all requests */ + +#ifndef __RequestUnion__clock_reply_subsystem__defined +#define __RequestUnion__clock_reply_subsystem__defined +union __RequestUnion__clock_reply_subsystem { + __Request__clock_alarm_reply_t Request_clock_alarm_reply; +}; +#endif /* !__RequestUnion__clock_reply_subsystem__defined */ +/* typedefs for all replies */ + +#ifndef __Reply__clock_reply_subsystem__defined +#define __Reply__clock_reply_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__clock_alarm_reply_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Reply__clock_reply_subsystem__defined */ + +/* union of all replies */ + +#ifndef __ReplyUnion__clock_reply_subsystem__defined +#define __ReplyUnion__clock_reply_subsystem__defined +union __ReplyUnion__clock_reply_subsystem { + __Reply__clock_alarm_reply_t Reply_clock_alarm_reply; +}; +#endif /* !__RequestUnion__clock_reply_subsystem__defined */ + +#ifndef subsystem_to_name_map_clock_reply +#define subsystem_to_name_map_clock_reply \ + { "clock_alarm_reply", 3125107 } +#endif + +#ifdef __AfterMigUserHeader +__AfterMigUserHeader +#endif /* __AfterMigUserHeader */ + +#endif /* _clock_reply_user_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/clock_types.defs b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/clock_types.defs new file mode 100644 index 00000000..4dbacfcf --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/clock_types.defs @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * File: clock_types.defs + * Purpose: + * Clock kernel interface type declarations + */ + +#ifndef _MACH_CLOCK_TYPES_DEFS_ +#define _MACH_CLOCK_TYPES_DEFS_ + +#include + +type clock_serv_t = mach_port_t + cusertype: clock_serv_t +#if KERNEL_SERVER + intran: clock_serv_t convert_port_to_clock(mach_port_t) + outtran: mach_port_t convert_clock_to_port(clock_serv_t) +#endif /* KERNEL_SERVER */ + ; + +type clock_ctrl_t = mach_port_t + cusertype: clock_ctrl_t +#if KERNEL_SERVER + intran: clock_ctrl_t convert_port_to_clock_ctrl(mach_port_t) + outtran: mach_port_t convert_clock_ctrl_to_port(clock_ctrl_t) +#endif /* KERNEL_SERVER */ + ; + +type clock_reply_t = polymorphic|MACH_MSG_TYPE_MAKE_SEND_ONCE; + +type clock_flavor_t = int; +type clock_attr_t = array[*:1] of int; +type mach_timespec_t = struct[2] of int; +type time_t = int; +type sleep_type_t = int; +type alarm_type_t = int; +type clock_res_t = int; +type clock_id_t = int; + +import ; + +#endif /* _MACH_CLOCK_TYPES_DEFS_ */ + +/* vim: set ft=c : */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/clock_types.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/clock_types.h new file mode 100644 index 00000000..9b3d49a9 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/clock_types.h @@ -0,0 +1,127 @@ +/* + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * File: clock_types.h + * Purpose: Clock facility header definitions. These + * definitons are needed by both kernel and + * user-level software. + */ + +/* + * All interfaces defined here are obsolete. + */ + +#ifndef _MACH_CLOCK_TYPES_H_ +#define _MACH_CLOCK_TYPES_H_ + +#include +#include + +/* + * Type definitions. + */ +typedef int alarm_type_t; /* alarm time type */ +typedef int sleep_type_t; /* sleep time type */ +typedef int clock_id_t; /* clock identification type */ +typedef int clock_flavor_t; /* clock flavor type */ +typedef int *clock_attr_t; /* clock attribute type */ +typedef int clock_res_t; /* clock resolution type */ + +/* + * Normal time specification used by the kernel clock facility. + */ +struct mach_timespec { + unsigned int tv_sec; /* seconds */ + clock_res_t tv_nsec; /* nanoseconds */ +}; +typedef struct mach_timespec mach_timespec_t; + +/* + * Reserved clock id values for default clocks. + */ +#define SYSTEM_CLOCK 0 +#define CALENDAR_CLOCK 1 + +#define REALTIME_CLOCK 0 + +/* + * Attribute names. + */ +#define CLOCK_GET_TIME_RES 1 /* get_time call resolution */ +/* 2 * was map_time call resolution */ +#define CLOCK_ALARM_CURRES 3 /* current alarm resolution */ +#define CLOCK_ALARM_MINRES 4 /* minimum alarm resolution */ +#define CLOCK_ALARM_MAXRES 5 /* maximum alarm resolution */ + +#define NSEC_PER_USEC 1000ull /* nanoseconds per microsecond */ +#define USEC_PER_SEC 1000000ull /* microseconds per second */ +#define NSEC_PER_SEC 1000000000ull /* nanoseconds per second */ +#define NSEC_PER_MSEC 1000000ull /* nanoseconds per millisecond */ + +#define BAD_MACH_TIMESPEC(t) \ + ((t)->tv_nsec < 0 || (t)->tv_nsec >= (long)NSEC_PER_SEC) + +/* t1 <=> t2, also (t1 - t2) in nsec with max of +- 1 sec */ +#define CMP_MACH_TIMESPEC(t1, t2) \ + ((t1)->tv_sec > (t2)->tv_sec ? (long) +NSEC_PER_SEC : \ + ((t1)->tv_sec < (t2)->tv_sec ? (long) -NSEC_PER_SEC : \ + (t1)->tv_nsec - (t2)->tv_nsec)) + +/* t1 += t2 */ +#define ADD_MACH_TIMESPEC(t1, t2) \ + do { \ + if (((t1)->tv_nsec += (t2)->tv_nsec) >= (long) NSEC_PER_SEC) { \ + (t1)->tv_nsec -= (long) NSEC_PER_SEC; \ + (t1)->tv_sec += 1; \ + } \ + (t1)->tv_sec += (t2)->tv_sec; \ + } while (0) + +/* t1 -= t2 */ +#define SUB_MACH_TIMESPEC(t1, t2) \ + do { \ + if (((t1)->tv_nsec -= (t2)->tv_nsec) < 0) { \ + (t1)->tv_nsec += (long) NSEC_PER_SEC; \ + (t1)->tv_sec -= 1; \ + } \ + (t1)->tv_sec -= (t2)->tv_sec; \ + } while (0) + +/* + * Alarm parameter defines. + */ +#define ALRMTYPE 0xff /* type (8-bit field) */ +#define TIME_ABSOLUTE 0x00 /* absolute time */ +#define TIME_RELATIVE 0x01 /* relative time */ + +#define BAD_ALRMTYPE(t) (((t) &~ TIME_RELATIVE) != 0) + +#endif /* _MACH_CLOCK_TYPES_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/dyld_kernel.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/dyld_kernel.h new file mode 100644 index 00000000..b28e45f1 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/dyld_kernel.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2016 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _MACH_DYLIB_INFO_H_ +#define _MACH_DYLIB_INFO_H_ + +#include +#include +#include +#include +#include +#include + +/* These definitions must be kept in sync with the ones in + * osfmk/mach/mach_types.defs. + */ + +struct dyld_kernel_image_info { + uuid_t uuid; + fsobj_id_t fsobjid; + fsid_t fsid; + uint64_t load_addr; +}; + +struct dyld_kernel_process_info { + struct dyld_kernel_image_info cache_image_info; + uint64_t timestamp; // mach_absolute_time of last time dyld change to image list + uint32_t imageCount; // number of images currently loaded into process + uint32_t initialImageCount; // number of images statically loaded into process (before any dlopen() calls) + uint8_t dyldState; // one of dyld_process_state_* values + boolean_t no_cache; // process is running without a dyld cache + boolean_t private_cache; // process is using a private copy of its dyld cache +}; + +/* typedefs so our MIG is sane */ + +typedef struct dyld_kernel_image_info dyld_kernel_image_info_t; +typedef struct dyld_kernel_process_info dyld_kernel_process_info_t; +typedef dyld_kernel_image_info_t *dyld_kernel_image_info_array_t; + +#endif /* _MACH_DYLIB_INFO_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/error.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/error.h new file mode 100644 index 00000000..50c77b9c --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/error.h @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * File: mach/error.h + * Purpose: + * error module definitions + * + */ + +#ifndef _MACH_ERROR_H_ +#define _MACH_ERROR_H_ + +#include + +/* + * error number layout as follows: + * + * hi lo + * | system(6) | subsystem(12) | code(14) | + */ + + +#define err_none (mach_error_t)0 +#define ERR_SUCCESS (mach_error_t)0 +#define ERR_ROUTINE_NIL (mach_error_fn_t)0 + + +#define err_system(x) ((signed)((((unsigned)(x))&0x3f)<<26)) +#define err_sub(x) (((x)&0xfff)<<14) + +#define err_get_system(err) (((err)>>26)&0x3f) +#define err_get_sub(err) (((err)>>14)&0xfff) +#define err_get_code(err) ((err)&0x3fff) + +#define system_emask (err_system(0x3f)) +#define sub_emask (err_sub(0xfff)) +#define code_emask (0x3fff) + + +/* major error systems */ +#define err_kern err_system(0x0) /* kernel */ +#define err_us err_system(0x1) /* user space library */ +#define err_server err_system(0x2) /* user space servers */ +#define err_ipc err_system(0x3) /* old ipc errors */ +#define err_mach_ipc err_system(0x4) /* mach-ipc errors */ +#define err_dipc err_system(0x7) /* distributed ipc */ +#define err_local err_system(0x3e) /* user defined errors */ +#define err_ipc_compat err_system(0x3f) /* (compatibility) mach-ipc errors */ + +#define err_max_system 0x3f + + +/* unix errors get lumped into one subsystem */ +#define unix_err(errno) (err_kern|err_sub(3)|errno) + +typedef kern_return_t mach_error_t; +typedef mach_error_t (* mach_error_fn_t)( void ); + +#endif /* _MACH_ERROR_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/exc.defs b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/exc.defs new file mode 100644 index 00000000..734e7408 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/exc.defs @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * Abstract: + * MiG definitions file for Mach exception interface. + */ + +subsystem +#if KERNEL_SERVER + KernelServer +#endif /* KERNEL_SERVER */ + +#if KERNEL_USER + KernelUser +#endif + exc 2401; + +#include +#include + +ServerPrefix catch_; + +type exception_data_t = array[*:2] of integer_t; +type exception_type_t = int; + +routine exception_raise( + exception_port : mach_port_t; + thread : mach_port_t; + task : mach_port_t; + exception : exception_type_t; + code : exception_data_t +#if EXC_SERVER_SECTOKEN + ; + ServerSecToken stoken : security_token_t +#endif +#if EXC_SERVER_AUDITTOKEN + ; + ServerAuditToken atoken: audit_token_t +#endif + ); + +routine exception_raise_state( + exception_port : mach_port_t; + exception : exception_type_t; + code : exception_data_t, const; + inout flavor : int; + old_state : thread_state_t, const; + out new_state : thread_state_t +#if EXC_SERVER_SECTOKEN + ; + ServerSecToken stoken : security_token_t +#endif +#if EXC_SERVER_AUDITTOKEN + ; + ServerAuditToken atoken: audit_token_t +#endif + ); + +routine exception_raise_state_identity( + exception_port : mach_port_t; + thread : mach_port_t; + task : mach_port_t; + exception : exception_type_t; + code : exception_data_t; + inout flavor : int; + old_state : thread_state_t; + out new_state : thread_state_t +#if EXC_SERVER_SECTOKEN + ; + ServerSecToken stoken : security_token_t +#endif +#if EXC_SERVER_AUDITTOKEN + ; + ServerAuditToken atoken: audit_token_t +#endif + ); + +/* vim: set ft=c : */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/exc.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/exc.h new file mode 100644 index 00000000..f02096b2 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/exc.h @@ -0,0 +1,281 @@ +#ifndef _exc_user_ +#define _exc_user_ + +/* Module exc */ + +#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 exc_MSG_COUNT +#define exc_MSG_COUNT 3 +#endif /* exc_MSG_COUNT */ + +#include +#include +#include +#include + +#ifdef __BeforeMigUserHeader +__BeforeMigUserHeader +#endif /* __BeforeMigUserHeader */ + +#include +__BEGIN_DECLS + + +/* Routine exception_raise */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t exception_raise +( + mach_port_t exception_port, + mach_port_t thread, + mach_port_t task, + exception_type_t exception, + exception_data_t code, + mach_msg_type_number_t codeCnt +); + +/* Routine exception_raise_state */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t exception_raise_state +( + mach_port_t exception_port, + exception_type_t exception, + const exception_data_t code, + mach_msg_type_number_t codeCnt, + int *flavor, + const thread_state_t old_state, + mach_msg_type_number_t old_stateCnt, + thread_state_t new_state, + mach_msg_type_number_t *new_stateCnt +); + +/* Routine exception_raise_state_identity */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t exception_raise_state_identity +( + mach_port_t exception_port, + mach_port_t thread, + mach_port_t task, + exception_type_t exception, + exception_data_t code, + mach_msg_type_number_t codeCnt, + int *flavor, + thread_state_t old_state, + mach_msg_type_number_t old_stateCnt, + thread_state_t new_state, + mach_msg_type_number_t *new_stateCnt +); + +__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__exc_subsystem__defined +#define __Request__exc_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 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 thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + integer_t code[2]; + } __Request__exception_raise_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + integer_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[614]; + } __Request__exception_raise_state_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 thread; + mach_msg_port_descriptor_t task; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_type_t exception; + mach_msg_type_number_t codeCnt; + integer_t code[2]; + int flavor; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[614]; + } __Request__exception_raise_state_identity_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Request__exc_subsystem__defined */ + +/* union of all requests */ + +#ifndef __RequestUnion__exc_subsystem__defined +#define __RequestUnion__exc_subsystem__defined +union __RequestUnion__exc_subsystem { + __Request__exception_raise_t Request_exception_raise; + __Request__exception_raise_state_t Request_exception_raise_state; + __Request__exception_raise_state_identity_t Request_exception_raise_state_identity; +}; +#endif /* !__RequestUnion__exc_subsystem__defined */ +/* typedefs for all replies */ + +#ifndef __Reply__exc_subsystem__defined +#define __Reply__exc_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__exception_raise_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[614]; + } __Reply__exception_raise_state_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[614]; + } __Reply__exception_raise_state_identity_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Reply__exc_subsystem__defined */ + +/* union of all replies */ + +#ifndef __ReplyUnion__exc_subsystem__defined +#define __ReplyUnion__exc_subsystem__defined +union __ReplyUnion__exc_subsystem { + __Reply__exception_raise_t Reply_exception_raise; + __Reply__exception_raise_state_t Reply_exception_raise_state; + __Reply__exception_raise_state_identity_t Reply_exception_raise_state_identity; +}; +#endif /* !__RequestUnion__exc_subsystem__defined */ + +#ifndef subsystem_to_name_map_exc +#define subsystem_to_name_map_exc \ + { "exception_raise", 2401 },\ + { "exception_raise_state", 2402 },\ + { "exception_raise_state_identity", 2403 } +#endif + +#ifdef __AfterMigUserHeader +__AfterMigUserHeader +#endif /* __AfterMigUserHeader */ + +#endif /* _exc_user_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/exception.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/exception.h new file mode 100644 index 00000000..7baea703 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/exception.h @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + +#ifndef _MACH_EXCEPTION_H_ +#define _MACH_EXCEPTION_H_ + +#include + +#endif /* _MACH_EXCEPTION_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/exception_types.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/exception_types.h new file mode 100644 index 00000000..ccbcf0bb --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/exception_types.h @@ -0,0 +1,204 @@ +/* + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ + +#ifndef _MACH_EXCEPTION_TYPES_H_ +#define _MACH_EXCEPTION_TYPES_H_ + +#include + +/* + * Machine-independent exception definitions. + */ + +#define EXC_BAD_ACCESS 1 /* Could not access memory */ +/* Code contains kern_return_t describing error. */ +/* Subcode contains bad memory address. */ + +#define EXC_BAD_INSTRUCTION 2 /* Instruction failed */ +/* Illegal or undefined instruction or operand */ + +#define EXC_ARITHMETIC 3 /* Arithmetic exception */ +/* Exact nature of exception is in code field */ + +#define EXC_EMULATION 4 /* Emulation instruction */ +/* Emulation support instruction encountered */ +/* Details in code and subcode fields */ + +#define EXC_SOFTWARE 5 /* Software generated exception */ +/* Exact exception is in code field. */ +/* Codes 0 - 0xFFFF reserved to hardware */ +/* Codes 0x10000 - 0x1FFFF reserved for OS emulation (Unix) */ + +#define EXC_BREAKPOINT 6 /* Trace, breakpoint, etc. */ +/* Details in code field. */ + +#define EXC_SYSCALL 7 /* System calls. */ + +#define EXC_MACH_SYSCALL 8 /* Mach system calls. */ + +#define EXC_RPC_ALERT 9 /* RPC alert */ + +#define EXC_CRASH 10 /* Abnormal process exit */ + +#define EXC_RESOURCE 11 /* Hit resource consumption limit */ +/* Exact resource is in code field. */ + +#define EXC_GUARD 12 /* Violated guarded resource protections */ + +#define EXC_CORPSE_NOTIFY 13 /* Abnormal process exited to corpse state */ + +#define EXC_CORPSE_VARIANT_BIT 0x100 /* bit set for EXC_*_CORPSE variants of EXC_* */ + + +/* + * Machine-independent exception behaviors + */ + +# define EXCEPTION_DEFAULT 1 +/* Send a catch_exception_raise message including the identity. + */ + +# define EXCEPTION_STATE 2 +/* Send a catch_exception_raise_state message including the + * thread state. + */ + +# define EXCEPTION_STATE_IDENTITY 3 +/* Send a catch_exception_raise_state_identity message including + * the thread identity and state. + */ + +#define MACH_EXCEPTION_ERRORS 0x40000000 +/* include additional exception specific errors, not used yet. */ + +#define MACH_EXCEPTION_CODES 0x80000000 +/* Send 64-bit code and subcode in the exception header */ + +#define MACH_EXCEPTION_MASK (MACH_EXCEPTION_CODES | MACH_EXCEPTION_ERRORS) +/* + * Masks for exception definitions, above + * bit zero is unused, therefore 1 word = 31 exception types + */ + +#define EXC_MASK_BAD_ACCESS (1 << EXC_BAD_ACCESS) +#define EXC_MASK_BAD_INSTRUCTION (1 << EXC_BAD_INSTRUCTION) +#define EXC_MASK_ARITHMETIC (1 << EXC_ARITHMETIC) +#define EXC_MASK_EMULATION (1 << EXC_EMULATION) +#define EXC_MASK_SOFTWARE (1 << EXC_SOFTWARE) +#define EXC_MASK_BREAKPOINT (1 << EXC_BREAKPOINT) +#define EXC_MASK_SYSCALL (1 << EXC_SYSCALL) +#define EXC_MASK_MACH_SYSCALL (1 << EXC_MACH_SYSCALL) +#define EXC_MASK_RPC_ALERT (1 << EXC_RPC_ALERT) +#define EXC_MASK_CRASH (1 << EXC_CRASH) +#define EXC_MASK_RESOURCE (1 << EXC_RESOURCE) +#define EXC_MASK_GUARD (1 << EXC_GUARD) +#define EXC_MASK_CORPSE_NOTIFY (1 << EXC_CORPSE_NOTIFY) + +#define EXC_MASK_ALL (EXC_MASK_BAD_ACCESS | \ + EXC_MASK_BAD_INSTRUCTION | \ + EXC_MASK_ARITHMETIC | \ + EXC_MASK_EMULATION | \ + EXC_MASK_SOFTWARE | \ + EXC_MASK_BREAKPOINT | \ + EXC_MASK_SYSCALL | \ + EXC_MASK_MACH_SYSCALL | \ + EXC_MASK_RPC_ALERT | \ + EXC_MASK_RESOURCE | \ + EXC_MASK_GUARD | \ + EXC_MASK_MACHINE) + + +#define FIRST_EXCEPTION 1 /* ZERO is illegal */ + +/* + * Machine independent codes for EXC_SOFTWARE + * Codes 0x10000 - 0x1FFFF reserved for OS emulation (Unix) + * 0x10000 - 0x10002 in use for unix signals + * 0x20000 - 0x2FFFF reserved for MACF + */ +#define EXC_SOFT_SIGNAL 0x10003 /* Unix signal exceptions */ + +#define EXC_MACF_MIN 0x20000 /* MACF exceptions */ +#define EXC_MACF_MAX 0x2FFFF + +#ifndef ASSEMBLER + +#include +#include +#include +/* + * Exported types + */ + +typedef int exception_type_t; +typedef integer_t exception_data_type_t; +typedef int64_t mach_exception_data_type_t; +typedef int exception_behavior_t; +typedef exception_data_type_t *exception_data_t; +typedef mach_exception_data_type_t *mach_exception_data_t; +typedef unsigned int exception_mask_t; +typedef exception_mask_t *exception_mask_array_t; +typedef exception_behavior_t *exception_behavior_array_t; +typedef thread_state_flavor_t *exception_flavor_array_t; +typedef mach_port_t *exception_port_array_t; +typedef mach_exception_data_type_t mach_exception_code_t; +typedef mach_exception_data_type_t mach_exception_subcode_t; + +#endif /* ASSEMBLER */ + +#endif /* _MACH_EXCEPTION_TYPES_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/host_info.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/host_info.h new file mode 100644 index 00000000..648d25ca --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/host_info.h @@ -0,0 +1,260 @@ +/* + * Copyright (c) 2000-2015 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + +/* + * File: mach/host_info.h + * + * Definitions for host_info call. + */ + +#ifndef _MACH_HOST_INFO_H_ +#define _MACH_HOST_INFO_H_ + +#include +#include +#include +#include +#include + +#include + +/* + * Generic information structure to allow for expansion. + */ +typedef integer_t *host_info_t; /* varying array of int. */ +typedef integer_t *host_info64_t; /* varying array of int. */ + +#define HOST_INFO_MAX (1024) /* max array size */ +typedef integer_t host_info_data_t[HOST_INFO_MAX]; + +#define KERNEL_VERSION_MAX (512) +typedef char kernel_version_t[KERNEL_VERSION_MAX]; + +#define KERNEL_BOOT_INFO_MAX (4096) +typedef char kernel_boot_info_t[KERNEL_BOOT_INFO_MAX]; + +/* + * Currently defined information. + */ +/* host_info() */ +typedef integer_t host_flavor_t; +#define HOST_BASIC_INFO 1 /* basic info */ +#define HOST_SCHED_INFO 3 /* scheduling info */ +#define HOST_RESOURCE_SIZES 4 /* kernel struct sizes */ +#define HOST_PRIORITY_INFO 5 /* priority information */ +#define HOST_SEMAPHORE_TRAPS 7 /* Has semaphore traps */ +#define HOST_MACH_MSG_TRAP 8 /* Has mach_msg_trap */ +#define HOST_VM_PURGABLE 9 /* purg'e'able memory info */ +#define HOST_DEBUG_INFO_INTERNAL 10 /* Used for kernel internal development tests only */ +#define HOST_CAN_HAS_DEBUGGER 11 +#define HOST_PREFERRED_USER_ARCH 12 /* Get the preferred user-space architecture */ + + +struct host_can_has_debugger_info { + boolean_t can_has_debugger; +}; +typedef struct host_can_has_debugger_info host_can_has_debugger_info_data_t; +typedef struct host_can_has_debugger_info *host_can_has_debugger_info_t; +#define HOST_CAN_HAS_DEBUGGER_COUNT ((mach_msg_type_number_t) \ + (sizeof(host_can_has_debugger_info_data_t)/sizeof(integer_t))) + +#pragma pack(push, 4) + +struct host_basic_info { + integer_t max_cpus; /* max number of CPUs possible */ + integer_t avail_cpus; /* number of CPUs now available */ + natural_t memory_size; /* size of memory in bytes, capped at 2 GB */ + cpu_type_t cpu_type; /* cpu type */ + cpu_subtype_t cpu_subtype; /* cpu subtype */ + cpu_threadtype_t cpu_threadtype; /* cpu threadtype */ + integer_t physical_cpu; /* number of physical CPUs now available */ + integer_t physical_cpu_max; /* max number of physical CPUs possible */ + integer_t logical_cpu; /* number of logical cpu now available */ + integer_t logical_cpu_max; /* max number of physical CPUs possible */ + uint64_t max_mem; /* actual size of physical memory */ +}; + +#pragma pack(pop) + +typedef struct host_basic_info host_basic_info_data_t; +typedef struct host_basic_info *host_basic_info_t; +#define HOST_BASIC_INFO_COUNT ((mach_msg_type_number_t) \ + (sizeof(host_basic_info_data_t)/sizeof(integer_t))) + +struct host_sched_info { + integer_t min_timeout; /* minimum timeout in milliseconds */ + integer_t min_quantum; /* minimum quantum in milliseconds */ +}; + +typedef struct host_sched_info host_sched_info_data_t; +typedef struct host_sched_info *host_sched_info_t; +#define HOST_SCHED_INFO_COUNT ((mach_msg_type_number_t) \ + (sizeof(host_sched_info_data_t)/sizeof(integer_t))) + +struct kernel_resource_sizes { + natural_t task; + natural_t thread; + natural_t port; + natural_t memory_region; + natural_t memory_object; +}; + +typedef struct kernel_resource_sizes kernel_resource_sizes_data_t; +typedef struct kernel_resource_sizes *kernel_resource_sizes_t; +#define HOST_RESOURCE_SIZES_COUNT ((mach_msg_type_number_t) \ + (sizeof(kernel_resource_sizes_data_t)/sizeof(integer_t))) + +struct host_priority_info { + integer_t kernel_priority; + integer_t system_priority; + integer_t server_priority; + integer_t user_priority; + integer_t depress_priority; + integer_t idle_priority; + integer_t minimum_priority; + integer_t maximum_priority; +}; + +typedef struct host_priority_info host_priority_info_data_t; +typedef struct host_priority_info *host_priority_info_t; +#define HOST_PRIORITY_INFO_COUNT ((mach_msg_type_number_t) \ + (sizeof(host_priority_info_data_t)/sizeof(integer_t))) + +/* host_statistics() */ +#define HOST_LOAD_INFO 1 /* System loading stats */ +#define HOST_VM_INFO 2 /* Virtual memory stats */ +#define HOST_CPU_LOAD_INFO 3 /* CPU load stats */ + +/* host_statistics64() */ +#define HOST_VM_INFO64 4 /* 64-bit virtual memory stats */ +#define HOST_EXTMOD_INFO64 5 /* External modification stats */ +#define HOST_EXPIRED_TASK_INFO 6 /* Statistics for expired tasks */ + + +struct host_load_info { + integer_t avenrun[3]; /* scaled by LOAD_SCALE */ + integer_t mach_factor[3]; /* scaled by LOAD_SCALE */ +}; + +typedef struct host_load_info host_load_info_data_t; +typedef struct host_load_info *host_load_info_t; +#define HOST_LOAD_INFO_COUNT ((mach_msg_type_number_t) \ + (sizeof(host_load_info_data_t)/sizeof(integer_t))) + +typedef struct vm_purgeable_info host_purgable_info_data_t; +typedef struct vm_purgeable_info *host_purgable_info_t; +#define HOST_VM_PURGABLE_COUNT ((mach_msg_type_number_t) \ + (sizeof(host_purgable_info_data_t)/sizeof(integer_t))) + +/* in */ +/* vm_statistics64 */ +#define HOST_VM_INFO64_COUNT ((mach_msg_type_number_t) \ + (sizeof(vm_statistics64_data_t)/sizeof(integer_t))) + +/* size of the latest version of the structure */ +#define HOST_VM_INFO64_LATEST_COUNT HOST_VM_INFO64_COUNT +#define HOST_VM_INFO64_REV1_COUNT HOST_VM_INFO64_LATEST_COUNT +/* previous versions: adjust the size according to what was added each time */ +#define HOST_VM_INFO64_REV0_COUNT /* added compression and swapper info (14 ints) */ \ + ((mach_msg_type_number_t) \ + (HOST_VM_INFO64_REV1_COUNT - 14)) + +/* in */ +/* vm_extmod_statistics */ +#define HOST_EXTMOD_INFO64_COUNT ((mach_msg_type_number_t) \ + (sizeof(vm_extmod_statistics_data_t)/sizeof(integer_t))) + +/* size of the latest version of the structure */ +#define HOST_EXTMOD_INFO64_LATEST_COUNT HOST_EXTMOD_INFO64_COUNT + +/* vm_statistics */ +#define HOST_VM_INFO_COUNT ((mach_msg_type_number_t) \ + (sizeof(vm_statistics_data_t)/sizeof(integer_t))) + +/* size of the latest version of the structure */ +#define HOST_VM_INFO_LATEST_COUNT HOST_VM_INFO_COUNT +#define HOST_VM_INFO_REV2_COUNT HOST_VM_INFO_LATEST_COUNT +/* previous versions: adjust the size according to what was added each time */ +#define HOST_VM_INFO_REV1_COUNT /* added "speculative_count" (1 int) */ \ + ((mach_msg_type_number_t) \ + (HOST_VM_INFO_REV2_COUNT - 1)) +#define HOST_VM_INFO_REV0_COUNT /* added "purgable" info (2 ints) */ \ + ((mach_msg_type_number_t) \ + (HOST_VM_INFO_REV1_COUNT - 2)) + +struct host_cpu_load_info { /* number of ticks while running... */ + natural_t cpu_ticks[CPU_STATE_MAX]; /* ... in the given mode */ +}; + +typedef struct host_cpu_load_info host_cpu_load_info_data_t; +typedef struct host_cpu_load_info *host_cpu_load_info_t; +#define HOST_CPU_LOAD_INFO_COUNT ((mach_msg_type_number_t) \ + (sizeof (host_cpu_load_info_data_t) / sizeof (integer_t))) + +struct host_preferred_user_arch { + cpu_type_t cpu_type; /* Preferred user-space cpu type */ + cpu_subtype_t cpu_subtype; /* Preferred user-space cpu subtype */ +}; + +typedef struct host_preferred_user_arch host_preferred_user_arch_data_t; +typedef struct host_preferred_user_arch *host_preferred_user_arch_t; +#define HOST_PREFERRED_USER_ARCH_COUNT ((mach_msg_type_number_t) \ + (sizeof(host_preferred_user_arch_data_t)/sizeof(integer_t))) + + + + +#endif /* _MACH_HOST_INFO_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/host_notify.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/host_notify.h new file mode 100644 index 00000000..cda654bf --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/host_notify.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _MACH_HOST_NOTIFY_H_ +#define _MACH_HOST_NOTIFY_H_ + +#define HOST_NOTIFY_CALENDAR_CHANGE 0 +#define HOST_NOTIFY_CALENDAR_SET 1 +#define HOST_NOTIFY_TYPE_MAX 1 + +#define HOST_CALENDAR_CHANGED_REPLYID 950 +#define HOST_CALENDAR_SET_REPLYID 951 + +#endif /* _MACH_HOST_NOTIFY_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/host_notify_reply.defs b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/host_notify_reply.defs new file mode 100644 index 00000000..469777cb --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/host_notify_reply.defs @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ + +subsystem +#if KERNEL_USER + KernelUser +#endif /* KERN_USER */ + host_notify_reply 950; + +#include + +simpleroutine host_calendar_changed( + notify_port : mach_port_move_send_once_t); + +simpleroutine host_calendar_set( + notify_port : mach_port_move_send_once_t); + +/* vim: set ft=c : */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/host_priv.defs b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/host_priv.defs new file mode 100644 index 00000000..83f601b5 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/host_priv.defs @@ -0,0 +1,359 @@ +/* + * Copyright (c) 2000-2004 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ + +/* + * Matchmaker definitions file for Mach kernel interface. + */ +subsystem +#if KERNEL_USER + KernelUser +#endif /* KERNEL_USER */ +#if KERNEL_SERVER + KernelServer +#endif /* KERNEL_SERVER */ + host_priv 400; + +#ifdef KERNEL_USER +userprefix r_; +#endif /* KERNEL_USER */ + +#define CONCAT(a,b) a ## b +#if KERNEL_SERVER +#define KERNEL_SERVER_SUFFIX(NAME) CONCAT(NAME, _external) +#else +#define KERNEL_SERVER_SUFFIX(NAME) NAME +#endif + +#include +#include +#include +#include + +/* + * Get boot configuration information from kernel. + */ +routine host_get_boot_info( + host_priv : host_priv_t; + out boot_info : kernel_boot_info_t); + +/* + * Reboot this host. + * Only available to privileged users. + */ +routine host_reboot( + host_priv : host_priv_t; + options : int); + + +/* + * Return privileged statistics from this host. + */ +routine host_priv_statistics( + host_priv : host_priv_t; + flavor : host_flavor_t; + out host_info_out : host_info_t, CountInOut); + +/* + * Sets the default memory manager, the port to which + * newly-created temporary memory objects are delivered. + * [See (memory_object_default)memory_object_create.] + * Also sets the default cluster size used for pagein/pageout + * to this port. + * The old memory manager port is returned. + */ +routine host_default_memory_manager( + host_priv : host_priv_t; + inout default_manager : memory_object_default_t = + MACH_MSG_TYPE_MAKE_SEND; + cluster_size : memory_object_cluster_size_t); + + +/* + * Specify that the range of the virtual address space + * of the target task must not cause page faults for + * the indicated accesses. + * + * [ To unwire the pages, specify VM_PROT_NONE. ] + */ +routine vm_wire( + host_priv : host_priv_t; + task : vm_map_t; + address : vm_address_t; + size : vm_size_t; + desired_access : vm_prot_t); + +/* + * Specify that the target thread must always be able + * to run and to allocate memory. + */ +routine thread_wire( + host_priv : host_priv_t; + thread : thread_act_t; + wired : boolean_t); + +/* + * Allocate zero-filled, wired, contiguous physical memory + * in the address space of the target task, either at the + * specified address, or wherever space can be found (if + * anywhere is TRUE), of the specified size. The address + * at which the allocation actually took place is returned. + * All pages will be entered into the task's pmap immediately, + * with VM_PROT_ALL. + * + * In addition to all the failure modes of its cousin, + * vm_allocate, this call may also fail if insufficient + * contiguous memory exists to satisfy the request. + * + * Memory obtained from this call should be freed the + * normal way, via vm_deallocate. + * + * N.B. This is an EXPERIMENTAL interface! + */ +routine vm_allocate_cpm( + host_priv : host_priv_t; + task : vm_map_t; + inout address : vm_address_t; + size : vm_size_t; + flags : int); + +/* + * Get list of processors on this host. + */ +routine host_processors( + host_priv : host_priv_t; + out out_processor_list : processor_array_t); + + +/* + * Get control port for a system-wide clock. + * Privileged. + */ +routine host_get_clock_control( + host_priv : host_priv_t; + clock_id : clock_id_t; + out clock_ctrl : clock_ctrl_t); + + +/* + * kernel module interface (obsolete as of SnowLeopard) + * see mach/kmod.h + */ +/* kmod_ MIG calls now return KERN_NOT_SUPPORTED on PPC/i386/x86_64. */ +routine kmod_create( + host_priv : host_priv_t; + info : vm_address_t; + out module : kmod_t); + +routine kmod_destroy( + host_priv : host_priv_t; + module : kmod_t); + +routine kmod_control( + host_priv : host_priv_t; + module : kmod_t; + flavor : kmod_control_flavor_t; + inout data : kmod_args_t); + +/* + * Get a given special port for a given node. + * Special ports are defined in host_special_ports.h; + * examples include the master device port. + * There are a limited number of slots available for system servers. + */ +routine host_get_special_port( + host_priv : host_priv_t; + node : int; + which : int; + out port : mach_port_t); + +/* + * Set a given special port for the local node. + * See host_get_special_port. + */ +routine host_set_special_port( + host_priv : host_priv_t; + which : int; + port : mach_port_t); + +/* + * Set an exception handler for a host on one or more exception types. + * These handlers are invoked for all threads on the host if there are + * no task or thread-specific exception handlers or those handlers returned + * an error. + */ +routine host_set_exception_ports( + host_priv : host_priv_t; + exception_mask : exception_mask_t; + new_port : mach_port_t; + behavior : exception_behavior_t; + new_flavor : thread_state_flavor_t); + + +/* + * Lookup some of the old exception handlers for a host + */ +routine host_get_exception_ports( + host_priv : host_priv_t; + exception_mask : exception_mask_t; + out masks : exception_mask_array_t; + out old_handlers : exception_handler_array_t, SameCount; + out old_behaviors : exception_behavior_array_t, SameCount; + out old_flavors : exception_flavor_array_t, SameCount); + + +/* + * Set an exception handler for a host on one or more exception types. + * At the same time, return the previously defined exception handlers for + * those types. + */ +routine host_swap_exception_ports( + host_priv : host_priv_t; + exception_mask : exception_mask_t; + new_port : mach_port_t; + behavior : exception_behavior_t; + new_flavor : thread_state_flavor_t; + out masks : exception_mask_array_t; + out old_handlerss : exception_handler_array_t, SameCount; + out old_behaviors : exception_behavior_array_t, SameCount; + out old_flavors : exception_flavor_array_t, SameCount); + +skip; /* old host_load_symbol_table */ + +/* + * Specify that the range of the virtual address space + * of the target task must not cause page faults for + * the indicated accesses. + * + * [ To unwire the pages, specify VM_PROT_NONE. ] + */ +routine KERNEL_SERVER_SUFFIX(mach_vm_wire)( + host_priv : host_priv_t; + task : vm_map_t; + address : mach_vm_address_t; + size : mach_vm_size_t; + desired_access : vm_prot_t); + +/* + * JMM - Keep all processor_set related items at the end for easy + * removal. + */ +/* + * List all processor sets on host. + */ +routine host_processor_sets( + host_priv : host_priv_t; + out processor_sets : processor_set_name_array_t); + +/* + * Get control port for a processor set. + */ +routine host_processor_set_priv( + host_priv : host_priv_t; + set_name : processor_set_name_t; + out set : processor_set_t); + +/************************** Warning *************************************/ +/* The following routines are going away in a future release */ +/* use the appropriate variant of host_set_special_port instead */ +/************************************************************************/ + +skip;/* old set_dp_control_port */ +skip;/* old get_dp_control_port */ + +/* + * Set the UserNotification daemon access port for this host. + * If this value is already set, the kernel will discard its + * reference to the previously registered port. + */ +routine host_set_UNDServer( + host : host_priv_t; + in server : UNDServerRef); + +/* + * Get the UserNotification daemon access port for this host. + * This can then be used to communicate with that daemon, which + * in turn communicates with the User through whatever means + * available (pop-up-menus for GUI systems, text for non-GUI, etc..). + * + * Access to this port is restricted to privileged clients because + * it is a special purpose port intended for kernel clients. User + * level clients should go directly to the CFUserNotifcation services. + */ +routine host_get_UNDServer( + host : host_priv_t; + out server : UNDServerRef); + +/* + * Perform an operation with a kernel extension, on the kext loading system, + * or request information about loaded kexts or the state of the kext loading + * system. + * Active operations (load, unload, disable/enable) require host_priv/root access. + * Info retrieval does not. + * + * WARNING: THIS ROUTINE IS PRIVATE TO THE KEXT-MANAGEMENT STACK AND IS + * SUBJECT TO CHANGE AT ANY TIME. + */ +routine kext_request( + host_priv : host_priv_t; + in user_log_flags : uint32_t; + in request_data : pointer_t; + out response_data : pointer_t; + out log_data : pointer_t; + out op_result : kern_return_t); + +/* vim: set ft=c : */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/host_priv.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/host_priv.h new file mode 100644 index 00000000..33d87f2f --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/host_priv.h @@ -0,0 +1,1163 @@ +#ifndef _host_priv_user_ +#define _host_priv_user_ + +/* Module host_priv */ + +#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 host_priv_MSG_COUNT +#define host_priv_MSG_COUNT 26 +#endif /* host_priv_MSG_COUNT */ + +#include +#include +#include +#include +#include +#include + +#ifdef __BeforeMigUserHeader +__BeforeMigUserHeader +#endif /* __BeforeMigUserHeader */ + +#include +__BEGIN_DECLS + + +/* Routine host_get_boot_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_get_boot_info +( + host_priv_t host_priv, + kernel_boot_info_t boot_info +); + +/* Routine host_reboot */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_reboot +( + host_priv_t host_priv, + int options +); + +/* Routine host_priv_statistics */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_priv_statistics +( + host_priv_t host_priv, + host_flavor_t flavor, + host_info_t host_info_out, + mach_msg_type_number_t *host_info_outCnt +); + +/* Routine host_default_memory_manager */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_default_memory_manager +( + host_priv_t host_priv, + memory_object_default_t *default_manager, + memory_object_cluster_size_t cluster_size +); + +/* Routine vm_wire */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_wire +( + host_priv_t host_priv, + vm_map_t task, + vm_address_t address, + vm_size_t size, + vm_prot_t desired_access +); + +/* Routine thread_wire */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t thread_wire +( + host_priv_t host_priv, + thread_act_t thread, + boolean_t wired +); + +/* Routine vm_allocate_cpm */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_allocate_cpm +( + host_priv_t host_priv, + vm_map_t task, + vm_address_t *address, + vm_size_t size, + int flags +); + +/* Routine host_processors */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_processors +( + host_priv_t host_priv, + processor_array_t *out_processor_list, + mach_msg_type_number_t *out_processor_listCnt +); + +/* Routine host_get_clock_control */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_get_clock_control +( + host_priv_t host_priv, + clock_id_t clock_id, + clock_ctrl_t *clock_ctrl +); + +/* Routine kmod_create */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t kmod_create +( + host_priv_t host_priv, + vm_address_t info, + kmod_t *module +); + +/* Routine kmod_destroy */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t kmod_destroy +( + host_priv_t host_priv, + kmod_t module +); + +/* Routine kmod_control */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t kmod_control +( + host_priv_t host_priv, + kmod_t module, + kmod_control_flavor_t flavor, + kmod_args_t *data, + mach_msg_type_number_t *dataCnt +); + +/* Routine host_get_special_port */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_get_special_port +( + host_priv_t host_priv, + int node, + int which, + mach_port_t *port +); + +/* Routine host_set_special_port */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_set_special_port +( + host_priv_t host_priv, + int which, + mach_port_t port +); + +/* Routine host_set_exception_ports */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_set_exception_ports +( + host_priv_t host_priv, + exception_mask_t exception_mask, + mach_port_t new_port, + exception_behavior_t behavior, + thread_state_flavor_t new_flavor +); + +/* Routine host_get_exception_ports */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_get_exception_ports +( + host_priv_t host_priv, + exception_mask_t exception_mask, + exception_mask_array_t masks, + mach_msg_type_number_t *masksCnt, + exception_handler_array_t old_handlers, + exception_behavior_array_t old_behaviors, + exception_flavor_array_t old_flavors +); + +/* Routine host_swap_exception_ports */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_swap_exception_ports +( + host_priv_t host_priv, + exception_mask_t exception_mask, + mach_port_t new_port, + exception_behavior_t behavior, + thread_state_flavor_t new_flavor, + exception_mask_array_t masks, + mach_msg_type_number_t *masksCnt, + exception_handler_array_t old_handlerss, + exception_behavior_array_t old_behaviors, + exception_flavor_array_t old_flavors +); + +/* Routine mach_vm_wire */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_vm_wire +( + host_priv_t host_priv, + vm_map_t task, + mach_vm_address_t address, + mach_vm_size_t size, + vm_prot_t desired_access +); + +/* Routine host_processor_sets */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_processor_sets +( + host_priv_t host_priv, + processor_set_name_array_t *processor_sets, + mach_msg_type_number_t *processor_setsCnt +); + +/* Routine host_processor_set_priv */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_processor_set_priv +( + host_priv_t host_priv, + processor_set_name_t set_name, + processor_set_t *set +); + +/* Routine host_set_UNDServer */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_set_UNDServer +( + host_priv_t host, + UNDServerRef server +); + +/* Routine host_get_UNDServer */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_get_UNDServer +( + host_priv_t host, + UNDServerRef *server +); + +/* Routine kext_request */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t kext_request +( + host_priv_t host_priv, + uint32_t user_log_flags, + vm_offset_t request_data, + mach_msg_type_number_t request_dataCnt, + vm_offset_t *response_data, + mach_msg_type_number_t *response_dataCnt, + vm_offset_t *log_data, + mach_msg_type_number_t *log_dataCnt, + kern_return_t *op_result +); + +__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__host_priv_subsystem__defined +#define __Request__host_priv_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__host_get_boot_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int options; + } __Request__host_reboot_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + host_flavor_t flavor; + mach_msg_type_number_t host_info_outCnt; + } __Request__host_priv_statistics_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 default_manager; + /* end of the kernel processed data */ + NDR_record_t NDR; + memory_object_cluster_size_t cluster_size; + } __Request__host_default_memory_manager_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 task; + /* end of the kernel processed data */ + NDR_record_t NDR; + vm_address_t address; + vm_size_t size; + vm_prot_t desired_access; + } __Request__vm_wire_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 thread; + /* end of the kernel processed data */ + NDR_record_t NDR; + boolean_t wired; + } __Request__thread_wire_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 task; + /* end of the kernel processed data */ + NDR_record_t NDR; + vm_address_t address; + vm_size_t size; + int flags; + } __Request__vm_allocate_cpm_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__host_processors_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + clock_id_t clock_id; + } __Request__host_get_clock_control_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t info; + } __Request__kmod_create_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kmod_t module; + } __Request__kmod_destroy_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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; + kmod_t module; + kmod_control_flavor_t flavor; + mach_msg_type_number_t dataCnt; + } __Request__kmod_control_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int node; + int which; + } __Request__host_get_special_port_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 port; + /* end of the kernel processed data */ + NDR_record_t NDR; + int which; + } __Request__host_set_special_port_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 new_port; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_mask_t exception_mask; + exception_behavior_t behavior; + thread_state_flavor_t new_flavor; + } __Request__host_set_exception_ports_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + exception_mask_t exception_mask; + } __Request__host_get_exception_ports_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 new_port; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_mask_t exception_mask; + exception_behavior_t behavior; + thread_state_flavor_t new_flavor; + } __Request__host_swap_exception_ports_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 task; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_vm_address_t address; + mach_vm_size_t size; + vm_prot_t desired_access; + } __Request__mach_vm_wire_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__host_processor_sets_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 set_name; + /* end of the kernel processed data */ + } __Request__host_processor_set_priv_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 server; + /* end of the kernel processed data */ + } __Request__host_set_UNDServer_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__host_get_UNDServer_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 request_data; + /* end of the kernel processed data */ + NDR_record_t NDR; + uint32_t user_log_flags; + mach_msg_type_number_t request_dataCnt; + } __Request__kext_request_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Request__host_priv_subsystem__defined */ + +/* union of all requests */ + +#ifndef __RequestUnion__host_priv_subsystem__defined +#define __RequestUnion__host_priv_subsystem__defined +union __RequestUnion__host_priv_subsystem { + __Request__host_get_boot_info_t Request_host_get_boot_info; + __Request__host_reboot_t Request_host_reboot; + __Request__host_priv_statistics_t Request_host_priv_statistics; + __Request__host_default_memory_manager_t Request_host_default_memory_manager; + __Request__vm_wire_t Request_vm_wire; + __Request__thread_wire_t Request_thread_wire; + __Request__vm_allocate_cpm_t Request_vm_allocate_cpm; + __Request__host_processors_t Request_host_processors; + __Request__host_get_clock_control_t Request_host_get_clock_control; + __Request__kmod_create_t Request_kmod_create; + __Request__kmod_destroy_t Request_kmod_destroy; + __Request__kmod_control_t Request_kmod_control; + __Request__host_get_special_port_t Request_host_get_special_port; + __Request__host_set_special_port_t Request_host_set_special_port; + __Request__host_set_exception_ports_t Request_host_set_exception_ports; + __Request__host_get_exception_ports_t Request_host_get_exception_ports; + __Request__host_swap_exception_ports_t Request_host_swap_exception_ports; + __Request__mach_vm_wire_t Request_mach_vm_wire; + __Request__host_processor_sets_t Request_host_processor_sets; + __Request__host_processor_set_priv_t Request_host_processor_set_priv; + __Request__host_set_UNDServer_t Request_host_set_UNDServer; + __Request__host_get_UNDServer_t Request_host_get_UNDServer; + __Request__kext_request_t Request_kext_request; +}; +#endif /* !__RequestUnion__host_priv_subsystem__defined */ +/* typedefs for all replies */ + +#ifndef __Reply__host_priv_subsystem__defined +#define __Reply__host_priv_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t boot_infoOffset; /* MiG doesn't use it */ + mach_msg_type_number_t boot_infoCnt; + char boot_info[4096]; + } __Reply__host_get_boot_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__host_reboot_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t host_info_outCnt; + integer_t host_info_out[68]; + } __Reply__host_priv_statistics_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 default_manager; + /* end of the kernel processed data */ + } __Reply__host_default_memory_manager_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__vm_wire_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__thread_wire_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + vm_address_t address; + } __Reply__vm_allocate_cpm_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_ool_ports_descriptor_t out_processor_list; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t out_processor_listCnt; + } __Reply__host_processors_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 clock_ctrl; + /* end of the kernel processed data */ + } __Reply__host_get_clock_control_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + kmod_t module; + } __Reply__kmod_create_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__kmod_destroy_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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__kmod_control_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 port; + /* end of the kernel processed data */ + } __Reply__host_get_special_port_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__host_set_special_port_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__host_set_exception_ports_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 old_handlers[32]; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t masksCnt; + exception_mask_t masks[32]; + exception_behavior_t old_behaviors[32]; + thread_state_flavor_t old_flavors[32]; + } __Reply__host_get_exception_ports_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 old_handlerss[32]; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t masksCnt; + exception_mask_t masks[32]; + exception_behavior_t old_behaviors[32]; + thread_state_flavor_t old_flavors[32]; + } __Reply__host_swap_exception_ports_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_vm_wire_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_ool_ports_descriptor_t processor_sets; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t processor_setsCnt; + } __Reply__host_processor_sets_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 set; + /* end of the kernel processed data */ + } __Reply__host_processor_set_priv_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__host_set_UNDServer_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 server; + /* end of the kernel processed data */ + } __Reply__host_get_UNDServer_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 response_data; + mach_msg_ool_descriptor_t log_data; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t response_dataCnt; + mach_msg_type_number_t log_dataCnt; + kern_return_t op_result; + } __Reply__kext_request_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Reply__host_priv_subsystem__defined */ + +/* union of all replies */ + +#ifndef __ReplyUnion__host_priv_subsystem__defined +#define __ReplyUnion__host_priv_subsystem__defined +union __ReplyUnion__host_priv_subsystem { + __Reply__host_get_boot_info_t Reply_host_get_boot_info; + __Reply__host_reboot_t Reply_host_reboot; + __Reply__host_priv_statistics_t Reply_host_priv_statistics; + __Reply__host_default_memory_manager_t Reply_host_default_memory_manager; + __Reply__vm_wire_t Reply_vm_wire; + __Reply__thread_wire_t Reply_thread_wire; + __Reply__vm_allocate_cpm_t Reply_vm_allocate_cpm; + __Reply__host_processors_t Reply_host_processors; + __Reply__host_get_clock_control_t Reply_host_get_clock_control; + __Reply__kmod_create_t Reply_kmod_create; + __Reply__kmod_destroy_t Reply_kmod_destroy; + __Reply__kmod_control_t Reply_kmod_control; + __Reply__host_get_special_port_t Reply_host_get_special_port; + __Reply__host_set_special_port_t Reply_host_set_special_port; + __Reply__host_set_exception_ports_t Reply_host_set_exception_ports; + __Reply__host_get_exception_ports_t Reply_host_get_exception_ports; + __Reply__host_swap_exception_ports_t Reply_host_swap_exception_ports; + __Reply__mach_vm_wire_t Reply_mach_vm_wire; + __Reply__host_processor_sets_t Reply_host_processor_sets; + __Reply__host_processor_set_priv_t Reply_host_processor_set_priv; + __Reply__host_set_UNDServer_t Reply_host_set_UNDServer; + __Reply__host_get_UNDServer_t Reply_host_get_UNDServer; + __Reply__kext_request_t Reply_kext_request; +}; +#endif /* !__RequestUnion__host_priv_subsystem__defined */ + +#ifndef subsystem_to_name_map_host_priv +#define subsystem_to_name_map_host_priv \ + { "host_get_boot_info", 400 },\ + { "host_reboot", 401 },\ + { "host_priv_statistics", 402 },\ + { "host_default_memory_manager", 403 },\ + { "vm_wire", 404 },\ + { "thread_wire", 405 },\ + { "vm_allocate_cpm", 406 },\ + { "host_processors", 407 },\ + { "host_get_clock_control", 408 },\ + { "kmod_create", 409 },\ + { "kmod_destroy", 410 },\ + { "kmod_control", 411 },\ + { "host_get_special_port", 412 },\ + { "host_set_special_port", 413 },\ + { "host_set_exception_ports", 414 },\ + { "host_get_exception_ports", 415 },\ + { "host_swap_exception_ports", 416 },\ + { "mach_vm_wire", 418 },\ + { "host_processor_sets", 419 },\ + { "host_processor_set_priv", 420 },\ + { "host_set_UNDServer", 423 },\ + { "host_get_UNDServer", 424 },\ + { "kext_request", 425 } +#endif + +#ifdef __AfterMigUserHeader +__AfterMigUserHeader +#endif /* __AfterMigUserHeader */ + +#endif /* _host_priv_user_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/host_reboot.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/host_reboot.h new file mode 100644 index 00000000..02d8d089 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/host_reboot.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ + +#ifndef _MACH_HOST_REBOOT_ +#define _MACH_HOST_REBOOT_ + +#define HOST_REBOOT_HALT 0x0008 +#define HOST_REBOOT_UPSDELAY 0x0100 +#define HOST_REBOOT_DEBUGGER 0x1000 + +#endif /* _MACH_HOST_REBOOT_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/host_security.defs b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/host_security.defs new file mode 100644 index 00000000..4098df44 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/host_security.defs @@ -0,0 +1,101 @@ +/* + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ + +/* + * File: mach/host_security.defs + * + * Abstract: + * Mach host security operations support. + */ +subsystem +#if KERNEL_SERVER + KernelServer +#endif /* KERNEL_SERVER */ + host_security 600; + +/* + * Basic types + */ +#include +#include + + +/* + * Create a new task with an explicit security token + */ +routine host_security_create_task_token( + host_security : host_security_t; + parent_task : task_t; + sec_token : security_token_t; + audit_token : audit_token_t; + host : host_t; + ledgers : ledger_array_t; + inherit_memory : boolean_t; + out child_task : task_t); + +/* + * Change a task's security token + */ +routine host_security_set_task_token( + host_security : host_security_t; + target_task : task_t; + sec_token : security_token_t; + audit_token : audit_token_t; + host : host_t); + +/* vim: set ft=c : */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/host_security.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/host_security.h new file mode 100644 index 00000000..a7928db8 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/host_security.h @@ -0,0 +1,221 @@ +#ifndef _host_security_user_ +#define _host_security_user_ + +/* Module host_security */ + +#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 host_security_MSG_COUNT +#define host_security_MSG_COUNT 2 +#endif /* host_security_MSG_COUNT */ + +#include +#include +#include +#include + +#ifdef __BeforeMigUserHeader +__BeforeMigUserHeader +#endif /* __BeforeMigUserHeader */ + +#include +__BEGIN_DECLS + + +/* Routine host_security_create_task_token */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_security_create_task_token +( + host_security_t host_security, + task_t parent_task, + security_token_t sec_token, + audit_token_t audit_token, + host_t host, + ledger_array_t ledgers, + mach_msg_type_number_t ledgersCnt, + boolean_t inherit_memory, + task_t *child_task +); + +/* Routine host_security_set_task_token */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_security_set_task_token +( + host_security_t host_security, + task_t target_task, + security_token_t sec_token, + audit_token_t audit_token, + host_t host +); + +__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__host_security_subsystem__defined +#define __Request__host_security_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 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_task; + mach_msg_port_descriptor_t host; + mach_msg_ool_ports_descriptor_t ledgers; + /* end of the kernel processed data */ + NDR_record_t NDR; + security_token_t sec_token; + audit_token_t audit_token; + mach_msg_type_number_t ledgersCnt; + boolean_t inherit_memory; + } __Request__host_security_create_task_token_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 target_task; + mach_msg_port_descriptor_t host; + /* end of the kernel processed data */ + NDR_record_t NDR; + security_token_t sec_token; + audit_token_t audit_token; + } __Request__host_security_set_task_token_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Request__host_security_subsystem__defined */ + +/* union of all requests */ + +#ifndef __RequestUnion__host_security_subsystem__defined +#define __RequestUnion__host_security_subsystem__defined +union __RequestUnion__host_security_subsystem { + __Request__host_security_create_task_token_t Request_host_security_create_task_token; + __Request__host_security_set_task_token_t Request_host_security_set_task_token; +}; +#endif /* !__RequestUnion__host_security_subsystem__defined */ +/* typedefs for all replies */ + +#ifndef __Reply__host_security_subsystem__defined +#define __Reply__host_security_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 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 child_task; + /* end of the kernel processed data */ + } __Reply__host_security_create_task_token_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__host_security_set_task_token_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Reply__host_security_subsystem__defined */ + +/* union of all replies */ + +#ifndef __ReplyUnion__host_security_subsystem__defined +#define __ReplyUnion__host_security_subsystem__defined +union __ReplyUnion__host_security_subsystem { + __Reply__host_security_create_task_token_t Reply_host_security_create_task_token; + __Reply__host_security_set_task_token_t Reply_host_security_set_task_token; +}; +#endif /* !__RequestUnion__host_security_subsystem__defined */ + +#ifndef subsystem_to_name_map_host_security +#define subsystem_to_name_map_host_security \ + { "host_security_create_task_token", 600 },\ + { "host_security_set_task_token", 601 } +#endif + +#ifdef __AfterMigUserHeader +__AfterMigUserHeader +#endif /* __AfterMigUserHeader */ + +#endif /* _host_security_user_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/host_special_ports.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/host_special_ports.h new file mode 100644 index 00000000..d09b44b6 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/host_special_ports.h @@ -0,0 +1,281 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * File: mach/host_special_ports.h + * + * Defines codes for access to host-wide special ports. + */ + +#ifndef _MACH_HOST_SPECIAL_PORTS_H_ +#define _MACH_HOST_SPECIAL_PORTS_H_ + +/* + * Cannot be set or gotten from user space + */ +#define HOST_SECURITY_PORT 0 + +#define HOST_MIN_SPECIAL_PORT HOST_SECURITY_PORT + +/* + * Always provided by kernel (cannot be set from user-space). + */ +#define HOST_PORT 1 +#define HOST_PRIV_PORT 2 +#define HOST_IO_MASTER_PORT 3 +#define HOST_MAX_SPECIAL_KERNEL_PORT 7 /* room to grow */ + +#define HOST_LAST_SPECIAL_KERNEL_PORT HOST_IO_MASTER_PORT + +/* + * Not provided by kernel + */ +#define HOST_DYNAMIC_PAGER_PORT (1 + HOST_MAX_SPECIAL_KERNEL_PORT) +#define HOST_AUDIT_CONTROL_PORT (2 + HOST_MAX_SPECIAL_KERNEL_PORT) +#define HOST_USER_NOTIFICATION_PORT (3 + HOST_MAX_SPECIAL_KERNEL_PORT) +#define HOST_AUTOMOUNTD_PORT (4 + HOST_MAX_SPECIAL_KERNEL_PORT) +#define HOST_LOCKD_PORT (5 + HOST_MAX_SPECIAL_KERNEL_PORT) +#define HOST_KTRACE_BACKGROUND_PORT (6 + HOST_MAX_SPECIAL_KERNEL_PORT) +#define HOST_SEATBELT_PORT (7 + HOST_MAX_SPECIAL_KERNEL_PORT) +#define HOST_KEXTD_PORT (8 + HOST_MAX_SPECIAL_KERNEL_PORT) +#define HOST_LAUNCHCTL_PORT (9 + HOST_MAX_SPECIAL_KERNEL_PORT) +#define HOST_UNFREED_PORT (10 + HOST_MAX_SPECIAL_KERNEL_PORT) +#define HOST_AMFID_PORT (11 + HOST_MAX_SPECIAL_KERNEL_PORT) +#define HOST_GSSD_PORT (12 + HOST_MAX_SPECIAL_KERNEL_PORT) +#define HOST_TELEMETRY_PORT (13 + HOST_MAX_SPECIAL_KERNEL_PORT) +#define HOST_ATM_NOTIFICATION_PORT (14 + HOST_MAX_SPECIAL_KERNEL_PORT) +#define HOST_COALITION_PORT (15 + HOST_MAX_SPECIAL_KERNEL_PORT) +#define HOST_SYSDIAGNOSE_PORT (16 + HOST_MAX_SPECIAL_KERNEL_PORT) +#define HOST_XPC_EXCEPTION_PORT (17 + HOST_MAX_SPECIAL_KERNEL_PORT) +#define HOST_CONTAINERD_PORT (18 + HOST_MAX_SPECIAL_KERNEL_PORT) +#define HOST_NODE_PORT (19 + HOST_MAX_SPECIAL_KERNEL_PORT) +#define HOST_RESOURCE_NOTIFY_PORT (20 + HOST_MAX_SPECIAL_KERNEL_PORT) +#define HOST_CLOSURED_PORT (21 + HOST_MAX_SPECIAL_KERNEL_PORT) +#define HOST_SYSPOLICYD_PORT (22 + HOST_MAX_SPECIAL_KERNEL_PORT) +#define HOST_FILECOORDINATIOND_PORT (23 + HOST_MAX_SPECIAL_KERNEL_PORT) +#define HOST_FAIRPLAYD_PORT (24 + HOST_MAX_SPECIAL_KERNEL_PORT) + +#define HOST_MAX_SPECIAL_PORT HOST_FAIRPLAYD_PORT +/* MAX = last since rdar://35861175 */ + +/* obsolete name */ +#define HOST_CHUD_PORT HOST_LAUNCHCTL_PORT + +/* + * Special node identifier to always represent the local node. + */ +#define HOST_LOCAL_NODE -1 + +/* + * Definitions for ease of use. + * + * In the get call, the host parameter can be any host, but will generally + * be the local node host port. In the set call, the host must the per-node + * host port for the node being affected. + */ +#define host_get_host_port(host, port) \ + (host_get_special_port((host), \ + HOST_LOCAL_NODE, HOST_PORT, (port))) +#define host_set_host_port(host, port) (KERN_INVALID_ARGUMENT) + +#define host_get_host_priv_port(host, port) \ + (host_get_special_port((host), \ + HOST_LOCAL_NODE, HOST_PRIV_PORT, (port))) +#define host_set_host_priv_port(host, port) (KERN_INVALID_ARGUMENT) + +#define host_get_io_master_port(host, port) \ + (host_get_special_port((host), \ + HOST_LOCAL_NODE, HOST_IO_MASTER_PORT, (port))) +#define host_set_io_master_port(host, port) (KERN_INVALID_ARGUMENT) + +/* + * User-settable special ports. + */ +#define host_get_dynamic_pager_port(host, port) \ + (host_get_special_port((host), \ + HOST_LOCAL_NODE, HOST_DYNAMIC_PAGER_PORT, (port))) +#define host_set_dynamic_pager_port(host, port) \ + (host_set_special_port((host), HOST_DYNAMIC_PAGER_PORT, (port))) + +#define host_get_audit_control_port(host, port) \ + (host_get_special_port((host), \ + HOST_LOCAL_NODE, HOST_AUDIT_CONTROL_PORT, (port))) +#define host_set_audit_control_port(host, port) \ + (host_set_special_port((host), HOST_AUDIT_CONTROL_PORT, (port))) + +#define host_get_user_notification_port(host, port) \ + (host_get_special_port((host), \ + HOST_LOCAL_NODE, HOST_USER_NOTIFICATION_PORT, (port))) +#define host_set_user_notification_port(host, port) \ + (host_set_special_port((host), HOST_USER_NOTIFICATION_PORT, (port))) + +#define host_get_automountd_port(host, port) \ + (host_get_special_port((host), \ + HOST_LOCAL_NODE, HOST_AUTOMOUNTD_PORT, (port))) +#define host_set_automountd_port(host, port) \ + (host_set_special_port((host), HOST_AUTOMOUNTD_PORT, (port))) + +#define host_get_lockd_port(host, port) \ + (host_get_special_port((host), \ + HOST_LOCAL_NODE, HOST_LOCKD_PORT, (port))) +#define host_set_lockd_port(host, port) \ + (host_set_special_port((host), HOST_LOCKD_PORT, (port))) + +#define host_get_ktrace_background_port(host, port) \ + (host_get_special_port((host), \ + HOST_LOCAL_NODE, HOST_KTRACE_BACKGROUND_PORT, (port))) +#define host_set_ktrace_background_port(host, port) \ + (host_set_special_port((host), HOST_KTRACE_BACKGROUND_PORT, (port))) + +#define host_get_kextd_port(host, port) \ + (host_get_special_port((host), \ + HOST_LOCAL_NODE, HOST_KEXTD_PORT, (port))) +#define host_set_kextd_port(host, port) \ + (host_set_special_port((host), HOST_KEXTD_PORT, (port))) + +#define host_get_launchctl_port(host, port) \ + (host_get_special_port((host), HOST_LOCAL_NODE, HOST_LAUNCHCTL_PORT, \ + (port))) +#define host_set_launchctl_port(host, port) \ + (host_set_special_port((host), HOST_LAUNCHCTL_PORT, (port))) + +#define host_get_chud_port(host, port) host_get_launchctl_port(host, port) +#define host_set_chud_port(host, port) host_set_launchctl_port(host, port) + +#define host_get_unfreed_port(host, port) \ + (host_get_special_port((host), \ + HOST_LOCAL_NODE, HOST_UNFREED_PORT, (port))) +#define host_set_unfreed_port(host, port) \ + (host_set_special_port((host), HOST_UNFREED_PORT, (port))) + +#define host_get_amfid_port(host, port) \ + (host_get_special_port((host), \ + HOST_LOCAL_NODE, HOST_AMFID_PORT, (port))) +#define host_set_amfid_port(host, port) \ + (host_set_special_port((host), HOST_AMFID_PORT, (port))) + +#define host_get_gssd_port(host, port) \ + (host_get_special_port((host), \ + HOST_LOCAL_NODE, HOST_GSSD_PORT, (port))) +#define host_set_gssd_port(host, port) \ + (host_set_special_port((host), HOST_GSSD_PORT, (port))) + +#define host_get_telemetry_port(host, port) \ + (host_get_special_port((host), \ + HOST_LOCAL_NODE, HOST_TELEMETRY_PORT, (port))) +#define host_set_telemetry_port(host, port) \ + (host_set_special_port((host), HOST_TELEMETRY_PORT, (port))) + +#define host_get_atm_notification_port(host, port) \ + (host_get_special_port((host), \ + HOST_LOCAL_NODE, HOST_ATM_NOTIFICATION_PORT, (port))) +#define host_set_atm_notification_port(host, port) \ + (host_set_special_port((host), HOST_ATM_NOTIFICATION_PORT, (port))) + +#define host_get_coalition_port(host, port) \ + (host_get_special_port((host), \ + HOST_LOCAL_NODE, HOST_COALITION_PORT, (port))) +#define host_set_coalition_port(host, port) \ + (host_set_special_port((host), HOST_COALITION_PORT, (port))) + +#define host_get_sysdiagnose_port(host, port) \ + (host_get_special_port((host), \ + HOST_LOCAL_NODE, HOST_SYSDIAGNOSE_PORT, (port))) +#define host_set_sysdiagnose_port(host, port) \ + (host_set_special_port((host), HOST_SYSDIAGNOSE_PORT, (port))) + +#define host_get_container_port(host, port) \ + (host_get_special_port((host), \ + HOST_LOCAL_NODE, HOST_CONTAINERD_PORT, (port))) +#define host_set_container_port(host, port) \ + (host_set_special_port((host), HOST_CONTAINERD_PORT, (port))) + +#define host_get_node_port(host, port) \ + (host_get_special_port((host), \ + HOST_LOCAL_NODE, HOST_NODE_PORT, (port))) +#define host_set_node_port(host, port) \ + (host_set_special_port((host), HOST_NODE_PORT, (port))) + +#define host_get_closured_port(host, port) \ + (host_get_special_port((host), \ + HOST_LOCAL_NODE, HOST_CLOSURED_PORT, (port))) +#define host_set_closured_port(host, port) \ + (host_set_special_port((host), HOST_CLOSURED_PORT, (port))) + +#define host_get_syspolicyd_port(host, port) \ + (host_get_special_port((host), \ + HOST_LOCAL_NODE, HOST_SYSPOLICYD_PORT, (port))) +#define host_set_syspolicyd_port(host, port) \ + (host_set_special_port((host), HOST_SYSPOLICYD_PORT, (port))) + +#define host_get_filecoordinationd_port(host, port) \ + (host_get_special_port((host), \ + HOST_LOCAL_NODE, HOST_FILECOORDINATIOND_PORT, (port))) +#define host_set_filecoordinationd_port(host, port) \ + (host_set_special_port((host), HOST_FILECOORDINATIOND_PORT, (port))) + +#define host_get_fairplayd_port(host, port) \ + (host_get_special_port((host), \ + HOST_LOCAL_NODE, HOST_FAIRPLAYD_PORT, (port))) +#define host_set_fairplayd_port(host, port) \ + (host_set_special_port((host), HOST_FAIRPLAYD_PORT, (port))) + +/* HOST_RESOURCE_NOTIFY_PORT doesn't #defines these conveniences. + * All lookups go through send_resource_violation() + */ + +#endif /* _MACH_HOST_SPECIAL_PORTS_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/_structs.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/_structs.h new file mode 100644 index 00000000..c9cc8992 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/_structs.h @@ -0,0 +1,1232 @@ +/* + * Copyright (c) 2004-2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ + +#ifndef _MACH_I386__STRUCTS_H_ +#define _MACH_I386__STRUCTS_H_ + +#include /* __DARWIN_UNIX03 */ +#include /* __uint8_t */ + +/* + * i386 is the structure that is exported to user threads for + * use in status/mutate calls. This structure should never change. + * + */ + +#if __DARWIN_UNIX03 +#define _STRUCT_X86_THREAD_STATE32 struct __darwin_i386_thread_state +_STRUCT_X86_THREAD_STATE32 +{ + unsigned int __eax; + unsigned int __ebx; + unsigned int __ecx; + unsigned int __edx; + unsigned int __edi; + unsigned int __esi; + unsigned int __ebp; + unsigned int __esp; + unsigned int __ss; + unsigned int __eflags; + unsigned int __eip; + unsigned int __cs; + unsigned int __ds; + unsigned int __es; + unsigned int __fs; + unsigned int __gs; +}; +#else /* !__DARWIN_UNIX03 */ +#define _STRUCT_X86_THREAD_STATE32 struct i386_thread_state +_STRUCT_X86_THREAD_STATE32 +{ + unsigned int eax; + unsigned int ebx; + unsigned int ecx; + unsigned int edx; + unsigned int edi; + unsigned int esi; + unsigned int ebp; + unsigned int esp; + unsigned int ss; + unsigned int eflags; + unsigned int eip; + unsigned int cs; + unsigned int ds; + unsigned int es; + unsigned int fs; + unsigned int gs; +}; +#endif /* !__DARWIN_UNIX03 */ + +/* This structure should be double-word aligned for performance */ + +#if __DARWIN_UNIX03 +#define _STRUCT_FP_CONTROL struct __darwin_fp_control +_STRUCT_FP_CONTROL +{ + unsigned short __invalid :1, + __denorm :1, + __zdiv :1, + __ovrfl :1, + __undfl :1, + __precis :1, + :2, + __pc :2, +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +#define FP_PREC_24B 0 +#define FP_PREC_53B 2 +#define FP_PREC_64B 3 +#endif /* !_POSIX_C_SOURCE || _DARWIN_C_SOURCE */ + __rc :2, +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +#define FP_RND_NEAR 0 +#define FP_RND_DOWN 1 +#define FP_RND_UP 2 +#define FP_CHOP 3 +#endif /* !_POSIX_C_SOURCE || _DARWIN_C_SOURCE */ + /*inf*/ :1, + :3; +}; +typedef _STRUCT_FP_CONTROL __darwin_fp_control_t; +#else /* !__DARWIN_UNIX03 */ +#define _STRUCT_FP_CONTROL struct fp_control +_STRUCT_FP_CONTROL +{ + unsigned short invalid :1, + denorm :1, + zdiv :1, + ovrfl :1, + undfl :1, + precis :1, + :2, + pc :2, +#define FP_PREC_24B 0 +#define FP_PREC_53B 2 +#define FP_PREC_64B 3 + rc :2, +#define FP_RND_NEAR 0 +#define FP_RND_DOWN 1 +#define FP_RND_UP 2 +#define FP_CHOP 3 + /*inf*/ :1, + :3; +}; +typedef _STRUCT_FP_CONTROL fp_control_t; +#endif /* !__DARWIN_UNIX03 */ + +/* + * Status word. + */ + +#if __DARWIN_UNIX03 +#define _STRUCT_FP_STATUS struct __darwin_fp_status +_STRUCT_FP_STATUS +{ + unsigned short __invalid :1, + __denorm :1, + __zdiv :1, + __ovrfl :1, + __undfl :1, + __precis :1, + __stkflt :1, + __errsumm :1, + __c0 :1, + __c1 :1, + __c2 :1, + __tos :3, + __c3 :1, + __busy :1; +}; +typedef _STRUCT_FP_STATUS __darwin_fp_status_t; +#else /* !__DARWIN_UNIX03 */ +#define _STRUCT_FP_STATUS struct fp_status +_STRUCT_FP_STATUS +{ + unsigned short invalid :1, + denorm :1, + zdiv :1, + ovrfl :1, + undfl :1, + precis :1, + stkflt :1, + errsumm :1, + c0 :1, + c1 :1, + c2 :1, + tos :3, + c3 :1, + busy :1; +}; +typedef _STRUCT_FP_STATUS fp_status_t; +#endif /* !__DARWIN_UNIX03 */ + +/* defn of 80bit x87 FPU or MMX register */ + +#if __DARWIN_UNIX03 +#define _STRUCT_MMST_REG struct __darwin_mmst_reg +_STRUCT_MMST_REG +{ + char __mmst_reg[10]; + char __mmst_rsrv[6]; +}; +#else /* !__DARWIN_UNIX03 */ +#define _STRUCT_MMST_REG struct mmst_reg +_STRUCT_MMST_REG +{ + char mmst_reg[10]; + char mmst_rsrv[6]; +}; +#endif /* !__DARWIN_UNIX03 */ + + +/* defn of 128 bit XMM regs */ + +#if __DARWIN_UNIX03 +#define _STRUCT_XMM_REG struct __darwin_xmm_reg +_STRUCT_XMM_REG +{ + char __xmm_reg[16]; +}; +#else /* !__DARWIN_UNIX03 */ +#define _STRUCT_XMM_REG struct xmm_reg +_STRUCT_XMM_REG +{ + char xmm_reg[16]; +}; +#endif /* !__DARWIN_UNIX03 */ + +/* defn of 256 bit YMM regs */ + +#if __DARWIN_UNIX03 +#define _STRUCT_YMM_REG struct __darwin_ymm_reg +_STRUCT_YMM_REG +{ + char __ymm_reg[32]; +}; +#else /* !__DARWIN_UNIX03 */ +#define _STRUCT_YMM_REG struct ymm_reg +_STRUCT_YMM_REG +{ + char ymm_reg[32]; +}; +#endif /* !__DARWIN_UNIX03 */ + +/* defn of 512 bit ZMM regs */ + +#if __DARWIN_UNIX03 +#define _STRUCT_ZMM_REG struct __darwin_zmm_reg +_STRUCT_ZMM_REG +{ + char __zmm_reg[64]; +}; +#else /* !__DARWIN_UNIX03 */ +#define _STRUCT_ZMM_REG struct zmm_reg +_STRUCT_ZMM_REG +{ + char zmm_reg[64]; +}; +#endif /* !__DARWIN_UNIX03 */ + +#if __DARWIN_UNIX03 +#define _STRUCT_OPMASK_REG struct __darwin_opmask_reg +_STRUCT_OPMASK_REG +{ + char __opmask_reg[8]; +}; +#else /* !__DARWIN_UNIX03 */ +#define _STRUCT_OPMASK_REG struct opmask_reg +_STRUCT_OPMASK_REG +{ + char opmask_reg[8]; +}; +#endif /* !__DARWIN_UNIX03 */ + +/* + * Floating point state. + */ + +#if !defined(_POSIX_C_SOURCE) || defined(_DARWIN_C_SOURCE) +#define FP_STATE_BYTES 512 /* number of chars worth of data from fpu_fcw */ +#endif /* !_POSIX_C_SOURCE || _DARWIN_C_SOURCE */ + +#if __DARWIN_UNIX03 +#define _STRUCT_X86_FLOAT_STATE32 struct __darwin_i386_float_state +_STRUCT_X86_FLOAT_STATE32 +{ + int __fpu_reserved[2]; + _STRUCT_FP_CONTROL __fpu_fcw; /* x87 FPU control word */ + _STRUCT_FP_STATUS __fpu_fsw; /* x87 FPU status word */ + __uint8_t __fpu_ftw; /* x87 FPU tag word */ + __uint8_t __fpu_rsrv1; /* reserved */ + __uint16_t __fpu_fop; /* x87 FPU Opcode */ + __uint32_t __fpu_ip; /* x87 FPU Instruction Pointer offset */ + __uint16_t __fpu_cs; /* x87 FPU Instruction Pointer Selector */ + __uint16_t __fpu_rsrv2; /* reserved */ + __uint32_t __fpu_dp; /* x87 FPU Instruction Operand(Data) Pointer offset */ + __uint16_t __fpu_ds; /* x87 FPU Instruction Operand(Data) Pointer Selector */ + __uint16_t __fpu_rsrv3; /* reserved */ + __uint32_t __fpu_mxcsr; /* MXCSR Register state */ + __uint32_t __fpu_mxcsrmask; /* MXCSR mask */ + _STRUCT_MMST_REG __fpu_stmm0; /* ST0/MM0 */ + _STRUCT_MMST_REG __fpu_stmm1; /* ST1/MM1 */ + _STRUCT_MMST_REG __fpu_stmm2; /* ST2/MM2 */ + _STRUCT_MMST_REG __fpu_stmm3; /* ST3/MM3 */ + _STRUCT_MMST_REG __fpu_stmm4; /* ST4/MM4 */ + _STRUCT_MMST_REG __fpu_stmm5; /* ST5/MM5 */ + _STRUCT_MMST_REG __fpu_stmm6; /* ST6/MM6 */ + _STRUCT_MMST_REG __fpu_stmm7; /* ST7/MM7 */ + _STRUCT_XMM_REG __fpu_xmm0; /* XMM 0 */ + _STRUCT_XMM_REG __fpu_xmm1; /* XMM 1 */ + _STRUCT_XMM_REG __fpu_xmm2; /* XMM 2 */ + _STRUCT_XMM_REG __fpu_xmm3; /* XMM 3 */ + _STRUCT_XMM_REG __fpu_xmm4; /* XMM 4 */ + _STRUCT_XMM_REG __fpu_xmm5; /* XMM 5 */ + _STRUCT_XMM_REG __fpu_xmm6; /* XMM 6 */ + _STRUCT_XMM_REG __fpu_xmm7; /* XMM 7 */ + char __fpu_rsrv4[14*16]; /* reserved */ + int __fpu_reserved1; +}; + +#define _STRUCT_X86_AVX_STATE32 struct __darwin_i386_avx_state +_STRUCT_X86_AVX_STATE32 +{ + int __fpu_reserved[2]; + _STRUCT_FP_CONTROL __fpu_fcw; /* x87 FPU control word */ + _STRUCT_FP_STATUS __fpu_fsw; /* x87 FPU status word */ + __uint8_t __fpu_ftw; /* x87 FPU tag word */ + __uint8_t __fpu_rsrv1; /* reserved */ + __uint16_t __fpu_fop; /* x87 FPU Opcode */ + __uint32_t __fpu_ip; /* x87 FPU Instruction Pointer offset */ + __uint16_t __fpu_cs; /* x87 FPU Instruction Pointer Selector */ + __uint16_t __fpu_rsrv2; /* reserved */ + __uint32_t __fpu_dp; /* x87 FPU Instruction Operand(Data) Pointer offset */ + __uint16_t __fpu_ds; /* x87 FPU Instruction Operand(Data) Pointer Selector */ + __uint16_t __fpu_rsrv3; /* reserved */ + __uint32_t __fpu_mxcsr; /* MXCSR Register state */ + __uint32_t __fpu_mxcsrmask; /* MXCSR mask */ + _STRUCT_MMST_REG __fpu_stmm0; /* ST0/MM0 */ + _STRUCT_MMST_REG __fpu_stmm1; /* ST1/MM1 */ + _STRUCT_MMST_REG __fpu_stmm2; /* ST2/MM2 */ + _STRUCT_MMST_REG __fpu_stmm3; /* ST3/MM3 */ + _STRUCT_MMST_REG __fpu_stmm4; /* ST4/MM4 */ + _STRUCT_MMST_REG __fpu_stmm5; /* ST5/MM5 */ + _STRUCT_MMST_REG __fpu_stmm6; /* ST6/MM6 */ + _STRUCT_MMST_REG __fpu_stmm7; /* ST7/MM7 */ + _STRUCT_XMM_REG __fpu_xmm0; /* XMM 0 */ + _STRUCT_XMM_REG __fpu_xmm1; /* XMM 1 */ + _STRUCT_XMM_REG __fpu_xmm2; /* XMM 2 */ + _STRUCT_XMM_REG __fpu_xmm3; /* XMM 3 */ + _STRUCT_XMM_REG __fpu_xmm4; /* XMM 4 */ + _STRUCT_XMM_REG __fpu_xmm5; /* XMM 5 */ + _STRUCT_XMM_REG __fpu_xmm6; /* XMM 6 */ + _STRUCT_XMM_REG __fpu_xmm7; /* XMM 7 */ + char __fpu_rsrv4[14*16]; /* reserved */ + int __fpu_reserved1; + char __avx_reserved1[64]; + _STRUCT_XMM_REG __fpu_ymmh0; /* YMMH 0 */ + _STRUCT_XMM_REG __fpu_ymmh1; /* YMMH 1 */ + _STRUCT_XMM_REG __fpu_ymmh2; /* YMMH 2 */ + _STRUCT_XMM_REG __fpu_ymmh3; /* YMMH 3 */ + _STRUCT_XMM_REG __fpu_ymmh4; /* YMMH 4 */ + _STRUCT_XMM_REG __fpu_ymmh5; /* YMMH 5 */ + _STRUCT_XMM_REG __fpu_ymmh6; /* YMMH 6 */ + _STRUCT_XMM_REG __fpu_ymmh7; /* YMMH 7 */ +}; + +#define _STRUCT_X86_AVX512_STATE32 struct __darwin_i386_avx512_state +_STRUCT_X86_AVX512_STATE32 +{ + int __fpu_reserved[2]; + _STRUCT_FP_CONTROL __fpu_fcw; /* x87 FPU control word */ + _STRUCT_FP_STATUS __fpu_fsw; /* x87 FPU status word */ + __uint8_t __fpu_ftw; /* x87 FPU tag word */ + __uint8_t __fpu_rsrv1; /* reserved */ + __uint16_t __fpu_fop; /* x87 FPU Opcode */ + __uint32_t __fpu_ip; /* x87 FPU Instruction Pointer offset */ + __uint16_t __fpu_cs; /* x87 FPU Instruction Pointer Selector */ + __uint16_t __fpu_rsrv2; /* reserved */ + __uint32_t __fpu_dp; /* x87 FPU Instruction Operand(Data) Pointer offset */ + __uint16_t __fpu_ds; /* x87 FPU Instruction Operand(Data) Pointer Selector */ + __uint16_t __fpu_rsrv3; /* reserved */ + __uint32_t __fpu_mxcsr; /* MXCSR Register state */ + __uint32_t __fpu_mxcsrmask; /* MXCSR mask */ + _STRUCT_MMST_REG __fpu_stmm0; /* ST0/MM0 */ + _STRUCT_MMST_REG __fpu_stmm1; /* ST1/MM1 */ + _STRUCT_MMST_REG __fpu_stmm2; /* ST2/MM2 */ + _STRUCT_MMST_REG __fpu_stmm3; /* ST3/MM3 */ + _STRUCT_MMST_REG __fpu_stmm4; /* ST4/MM4 */ + _STRUCT_MMST_REG __fpu_stmm5; /* ST5/MM5 */ + _STRUCT_MMST_REG __fpu_stmm6; /* ST6/MM6 */ + _STRUCT_MMST_REG __fpu_stmm7; /* ST7/MM7 */ + _STRUCT_XMM_REG __fpu_xmm0; /* XMM 0 */ + _STRUCT_XMM_REG __fpu_xmm1; /* XMM 1 */ + _STRUCT_XMM_REG __fpu_xmm2; /* XMM 2 */ + _STRUCT_XMM_REG __fpu_xmm3; /* XMM 3 */ + _STRUCT_XMM_REG __fpu_xmm4; /* XMM 4 */ + _STRUCT_XMM_REG __fpu_xmm5; /* XMM 5 */ + _STRUCT_XMM_REG __fpu_xmm6; /* XMM 6 */ + _STRUCT_XMM_REG __fpu_xmm7; /* XMM 7 */ + char __fpu_rsrv4[14*16]; /* reserved */ + int __fpu_reserved1; + char __avx_reserved1[64]; + _STRUCT_XMM_REG __fpu_ymmh0; /* YMMH 0 */ + _STRUCT_XMM_REG __fpu_ymmh1; /* YMMH 1 */ + _STRUCT_XMM_REG __fpu_ymmh2; /* YMMH 2 */ + _STRUCT_XMM_REG __fpu_ymmh3; /* YMMH 3 */ + _STRUCT_XMM_REG __fpu_ymmh4; /* YMMH 4 */ + _STRUCT_XMM_REG __fpu_ymmh5; /* YMMH 5 */ + _STRUCT_XMM_REG __fpu_ymmh6; /* YMMH 6 */ + _STRUCT_XMM_REG __fpu_ymmh7; /* YMMH 7 */ + _STRUCT_OPMASK_REG __fpu_k0; /* K0 */ + _STRUCT_OPMASK_REG __fpu_k1; /* K1 */ + _STRUCT_OPMASK_REG __fpu_k2; /* K2 */ + _STRUCT_OPMASK_REG __fpu_k3; /* K3 */ + _STRUCT_OPMASK_REG __fpu_k4; /* K4 */ + _STRUCT_OPMASK_REG __fpu_k5; /* K5 */ + _STRUCT_OPMASK_REG __fpu_k6; /* K6 */ + _STRUCT_OPMASK_REG __fpu_k7; /* K7 */ + _STRUCT_YMM_REG __fpu_zmmh0; /* ZMMH 0 */ + _STRUCT_YMM_REG __fpu_zmmh1; /* ZMMH 1 */ + _STRUCT_YMM_REG __fpu_zmmh2; /* ZMMH 2 */ + _STRUCT_YMM_REG __fpu_zmmh3; /* ZMMH 3 */ + _STRUCT_YMM_REG __fpu_zmmh4; /* ZMMH 4 */ + _STRUCT_YMM_REG __fpu_zmmh5; /* ZMMH 5 */ + _STRUCT_YMM_REG __fpu_zmmh6; /* ZMMH 6 */ + _STRUCT_YMM_REG __fpu_zmmh7; /* ZMMH 7 */ +}; + +#else /* !__DARWIN_UNIX03 */ +#define _STRUCT_X86_FLOAT_STATE32 struct i386_float_state +_STRUCT_X86_FLOAT_STATE32 +{ + int fpu_reserved[2]; + _STRUCT_FP_CONTROL fpu_fcw; /* x87 FPU control word */ + _STRUCT_FP_STATUS fpu_fsw; /* x87 FPU status word */ + __uint8_t fpu_ftw; /* x87 FPU tag word */ + __uint8_t fpu_rsrv1; /* reserved */ + __uint16_t fpu_fop; /* x87 FPU Opcode */ + __uint32_t fpu_ip; /* x87 FPU Instruction Pointer offset */ + __uint16_t fpu_cs; /* x87 FPU Instruction Pointer Selector */ + __uint16_t fpu_rsrv2; /* reserved */ + __uint32_t fpu_dp; /* x87 FPU Instruction Operand(Data) Pointer offset */ + __uint16_t fpu_ds; /* x87 FPU Instruction Operand(Data) Pointer Selector */ + __uint16_t fpu_rsrv3; /* reserved */ + __uint32_t fpu_mxcsr; /* MXCSR Register state */ + __uint32_t fpu_mxcsrmask; /* MXCSR mask */ + _STRUCT_MMST_REG fpu_stmm0; /* ST0/MM0 */ + _STRUCT_MMST_REG fpu_stmm1; /* ST1/MM1 */ + _STRUCT_MMST_REG fpu_stmm2; /* ST2/MM2 */ + _STRUCT_MMST_REG fpu_stmm3; /* ST3/MM3 */ + _STRUCT_MMST_REG fpu_stmm4; /* ST4/MM4 */ + _STRUCT_MMST_REG fpu_stmm5; /* ST5/MM5 */ + _STRUCT_MMST_REG fpu_stmm6; /* ST6/MM6 */ + _STRUCT_MMST_REG fpu_stmm7; /* ST7/MM7 */ + _STRUCT_XMM_REG fpu_xmm0; /* XMM 0 */ + _STRUCT_XMM_REG fpu_xmm1; /* XMM 1 */ + _STRUCT_XMM_REG fpu_xmm2; /* XMM 2 */ + _STRUCT_XMM_REG fpu_xmm3; /* XMM 3 */ + _STRUCT_XMM_REG fpu_xmm4; /* XMM 4 */ + _STRUCT_XMM_REG fpu_xmm5; /* XMM 5 */ + _STRUCT_XMM_REG fpu_xmm6; /* XMM 6 */ + _STRUCT_XMM_REG fpu_xmm7; /* XMM 7 */ + char fpu_rsrv4[14*16]; /* reserved */ + int fpu_reserved1; +}; + +#define _STRUCT_X86_AVX_STATE32 struct i386_avx_state +_STRUCT_X86_AVX_STATE32 +{ + int fpu_reserved[2]; + _STRUCT_FP_CONTROL fpu_fcw; /* x87 FPU control word */ + _STRUCT_FP_STATUS fpu_fsw; /* x87 FPU status word */ + __uint8_t fpu_ftw; /* x87 FPU tag word */ + __uint8_t fpu_rsrv1; /* reserved */ + __uint16_t fpu_fop; /* x87 FPU Opcode */ + __uint32_t fpu_ip; /* x87 FPU Instruction Pointer offset */ + __uint16_t fpu_cs; /* x87 FPU Instruction Pointer Selector */ + __uint16_t fpu_rsrv2; /* reserved */ + __uint32_t fpu_dp; /* x87 FPU Instruction Operand(Data) Pointer offset */ + __uint16_t fpu_ds; /* x87 FPU Instruction Operand(Data) Pointer Selector */ + __uint16_t fpu_rsrv3; /* reserved */ + __uint32_t fpu_mxcsr; /* MXCSR Register state */ + __uint32_t fpu_mxcsrmask; /* MXCSR mask */ + _STRUCT_MMST_REG fpu_stmm0; /* ST0/MM0 */ + _STRUCT_MMST_REG fpu_stmm1; /* ST1/MM1 */ + _STRUCT_MMST_REG fpu_stmm2; /* ST2/MM2 */ + _STRUCT_MMST_REG fpu_stmm3; /* ST3/MM3 */ + _STRUCT_MMST_REG fpu_stmm4; /* ST4/MM4 */ + _STRUCT_MMST_REG fpu_stmm5; /* ST5/MM5 */ + _STRUCT_MMST_REG fpu_stmm6; /* ST6/MM6 */ + _STRUCT_MMST_REG fpu_stmm7; /* ST7/MM7 */ + _STRUCT_XMM_REG fpu_xmm0; /* XMM 0 */ + _STRUCT_XMM_REG fpu_xmm1; /* XMM 1 */ + _STRUCT_XMM_REG fpu_xmm2; /* XMM 2 */ + _STRUCT_XMM_REG fpu_xmm3; /* XMM 3 */ + _STRUCT_XMM_REG fpu_xmm4; /* XMM 4 */ + _STRUCT_XMM_REG fpu_xmm5; /* XMM 5 */ + _STRUCT_XMM_REG fpu_xmm6; /* XMM 6 */ + _STRUCT_XMM_REG fpu_xmm7; /* XMM 7 */ + char fpu_rsrv4[14*16]; /* reserved */ + int fpu_reserved1; + char avx_reserved1[64]; + _STRUCT_XMM_REG fpu_ymmh0; /* YMMH 0 */ + _STRUCT_XMM_REG fpu_ymmh1; /* YMMH 1 */ + _STRUCT_XMM_REG fpu_ymmh2; /* YMMH 2 */ + _STRUCT_XMM_REG fpu_ymmh3; /* YMMH 3 */ + _STRUCT_XMM_REG fpu_ymmh4; /* YMMH 4 */ + _STRUCT_XMM_REG fpu_ymmh5; /* YMMH 5 */ + _STRUCT_XMM_REG fpu_ymmh6; /* YMMH 6 */ + _STRUCT_XMM_REG fpu_ymmh7; /* YMMH 7 */ +}; + +#define _STRUCT_X86_AVX512_STATE32 struct i386_avx512_state +_STRUCT_X86_AVX512_STATE32 +{ + int fpu_reserved[2]; + _STRUCT_FP_CONTROL fpu_fcw; /* x87 FPU control word */ + _STRUCT_FP_STATUS fpu_fsw; /* x87 FPU status word */ + __uint8_t fpu_ftw; /* x87 FPU tag word */ + __uint8_t fpu_rsrv1; /* reserved */ + __uint16_t fpu_fop; /* x87 FPU Opcode */ + __uint32_t fpu_ip; /* x87 FPU Instruction Pointer offset */ + __uint16_t fpu_cs; /* x87 FPU Instruction Pointer Selector */ + __uint16_t fpu_rsrv2; /* reserved */ + __uint32_t fpu_dp; /* x87 FPU Instruction Operand(Data) Pointer offset */ + __uint16_t fpu_ds; /* x87 FPU Instruction Operand(Data) Pointer Selector */ + __uint16_t fpu_rsrv3; /* reserved */ + __uint32_t fpu_mxcsr; /* MXCSR Register state */ + __uint32_t fpu_mxcsrmask; /* MXCSR mask */ + _STRUCT_MMST_REG fpu_stmm0; /* ST0/MM0 */ + _STRUCT_MMST_REG fpu_stmm1; /* ST1/MM1 */ + _STRUCT_MMST_REG fpu_stmm2; /* ST2/MM2 */ + _STRUCT_MMST_REG fpu_stmm3; /* ST3/MM3 */ + _STRUCT_MMST_REG fpu_stmm4; /* ST4/MM4 */ + _STRUCT_MMST_REG fpu_stmm5; /* ST5/MM5 */ + _STRUCT_MMST_REG fpu_stmm6; /* ST6/MM6 */ + _STRUCT_MMST_REG fpu_stmm7; /* ST7/MM7 */ + _STRUCT_XMM_REG fpu_xmm0; /* XMM 0 */ + _STRUCT_XMM_REG fpu_xmm1; /* XMM 1 */ + _STRUCT_XMM_REG fpu_xmm2; /* XMM 2 */ + _STRUCT_XMM_REG fpu_xmm3; /* XMM 3 */ + _STRUCT_XMM_REG fpu_xmm4; /* XMM 4 */ + _STRUCT_XMM_REG fpu_xmm5; /* XMM 5 */ + _STRUCT_XMM_REG fpu_xmm6; /* XMM 6 */ + _STRUCT_XMM_REG fpu_xmm7; /* XMM 7 */ + char fpu_rsrv4[14*16]; /* reserved */ + int fpu_reserved1; + char avx_reserved1[64]; + _STRUCT_XMM_REG fpu_ymmh0; /* YMMH 0 */ + _STRUCT_XMM_REG fpu_ymmh1; /* YMMH 1 */ + _STRUCT_XMM_REG fpu_ymmh2; /* YMMH 2 */ + _STRUCT_XMM_REG fpu_ymmh3; /* YMMH 3 */ + _STRUCT_XMM_REG fpu_ymmh4; /* YMMH 4 */ + _STRUCT_XMM_REG fpu_ymmh5; /* YMMH 5 */ + _STRUCT_XMM_REG fpu_ymmh6; /* YMMH 6 */ + _STRUCT_XMM_REG fpu_ymmh7; /* YMMH 7 */ + _STRUCT_OPMASK_REG fpu_k0; /* K0 */ + _STRUCT_OPMASK_REG fpu_k1; /* K1 */ + _STRUCT_OPMASK_REG fpu_k2; /* K2 */ + _STRUCT_OPMASK_REG fpu_k3; /* K3 */ + _STRUCT_OPMASK_REG fpu_k4; /* K4 */ + _STRUCT_OPMASK_REG fpu_k5; /* K5 */ + _STRUCT_OPMASK_REG fpu_k6; /* K6 */ + _STRUCT_OPMASK_REG fpu_k7; /* K7 */ + _STRUCT_YMM_REG fpu_zmmh0; /* ZMMH 0 */ + _STRUCT_YMM_REG fpu_zmmh1; /* ZMMH 1 */ + _STRUCT_YMM_REG fpu_zmmh2; /* ZMMH 2 */ + _STRUCT_YMM_REG fpu_zmmh3; /* ZMMH 3 */ + _STRUCT_YMM_REG fpu_zmmh4; /* ZMMH 4 */ + _STRUCT_YMM_REG fpu_zmmh5; /* ZMMH 5 */ + _STRUCT_YMM_REG fpu_zmmh6; /* ZMMH 6 */ + _STRUCT_YMM_REG fpu_zmmh7; /* ZMMH 7 */ +}; + +#endif /* !__DARWIN_UNIX03 */ + +#if __DARWIN_UNIX03 +#define _STRUCT_X86_EXCEPTION_STATE32 struct __darwin_i386_exception_state +_STRUCT_X86_EXCEPTION_STATE32 +{ + __uint16_t __trapno; + __uint16_t __cpu; + __uint32_t __err; + __uint32_t __faultvaddr; +}; +#else /* !__DARWIN_UNIX03 */ +#define _STRUCT_X86_EXCEPTION_STATE32 struct i386_exception_state +_STRUCT_X86_EXCEPTION_STATE32 +{ + __uint16_t trapno; + __uint16_t cpu; + __uint32_t err; + __uint32_t faultvaddr; +}; +#endif /* !__DARWIN_UNIX03 */ + +#if __DARWIN_UNIX03 +#define _STRUCT_X86_DEBUG_STATE32 struct __darwin_x86_debug_state32 +_STRUCT_X86_DEBUG_STATE32 +{ + unsigned int __dr0; + unsigned int __dr1; + unsigned int __dr2; + unsigned int __dr3; + unsigned int __dr4; + unsigned int __dr5; + unsigned int __dr6; + unsigned int __dr7; +}; +#else /* !__DARWIN_UNIX03 */ +#define _STRUCT_X86_DEBUG_STATE32 struct x86_debug_state32 +_STRUCT_X86_DEBUG_STATE32 +{ + unsigned int dr0; + unsigned int dr1; + unsigned int dr2; + unsigned int dr3; + unsigned int dr4; + unsigned int dr5; + unsigned int dr6; + unsigned int dr7; +}; +#endif /* !__DARWIN_UNIX03 */ + +#define _STRUCT_X86_PAGEIN_STATE struct __x86_pagein_state +_STRUCT_X86_PAGEIN_STATE +{ + int __pagein_error; +}; + +/* + * 64 bit versions of the above + */ + +#if __DARWIN_UNIX03 +#define _STRUCT_X86_THREAD_STATE64 struct __darwin_x86_thread_state64 +_STRUCT_X86_THREAD_STATE64 +{ + __uint64_t __rax; + __uint64_t __rbx; + __uint64_t __rcx; + __uint64_t __rdx; + __uint64_t __rdi; + __uint64_t __rsi; + __uint64_t __rbp; + __uint64_t __rsp; + __uint64_t __r8; + __uint64_t __r9; + __uint64_t __r10; + __uint64_t __r11; + __uint64_t __r12; + __uint64_t __r13; + __uint64_t __r14; + __uint64_t __r15; + __uint64_t __rip; + __uint64_t __rflags; + __uint64_t __cs; + __uint64_t __fs; + __uint64_t __gs; +}; +#else /* !__DARWIN_UNIX03 */ +#define _STRUCT_X86_THREAD_STATE64 struct x86_thread_state64 +_STRUCT_X86_THREAD_STATE64 +{ + __uint64_t rax; + __uint64_t rbx; + __uint64_t rcx; + __uint64_t rdx; + __uint64_t rdi; + __uint64_t rsi; + __uint64_t rbp; + __uint64_t rsp; + __uint64_t r8; + __uint64_t r9; + __uint64_t r10; + __uint64_t r11; + __uint64_t r12; + __uint64_t r13; + __uint64_t r14; + __uint64_t r15; + __uint64_t rip; + __uint64_t rflags; + __uint64_t cs; + __uint64_t fs; + __uint64_t gs; +}; +#endif /* !__DARWIN_UNIX03 */ + +/* + * 64 bit versions of the above (complete) + */ + +#if __DARWIN_UNIX03 +#define _STRUCT_X86_THREAD_FULL_STATE64 struct __darwin_x86_thread_full_state64 +_STRUCT_X86_THREAD_FULL_STATE64 +{ + _STRUCT_X86_THREAD_STATE64 __ss64; + __uint64_t __ds; + __uint64_t __es; + __uint64_t __ss; + __uint64_t __gsbase; +}; +#else /* !__DARWIN_UNIX03 */ +#define _STRUCT_X86_THREAD_FULL_STATE64 struct x86_thread_full_state64 +_STRUCT_X86_THREAD_FULL_STATE64 +{ + _STRUCT_X86_THREAD_STATE64 ss64; + __uint64_t ds; + __uint64_t es; + __uint64_t ss; + __uint64_t gsbase; +}; +#endif /* !__DARWIN_UNIX03 */ + + +#if __DARWIN_UNIX03 +#define _STRUCT_X86_FLOAT_STATE64 struct __darwin_x86_float_state64 +_STRUCT_X86_FLOAT_STATE64 +{ + int __fpu_reserved[2]; + _STRUCT_FP_CONTROL __fpu_fcw; /* x87 FPU control word */ + _STRUCT_FP_STATUS __fpu_fsw; /* x87 FPU status word */ + __uint8_t __fpu_ftw; /* x87 FPU tag word */ + __uint8_t __fpu_rsrv1; /* reserved */ + __uint16_t __fpu_fop; /* x87 FPU Opcode */ + + /* x87 FPU Instruction Pointer */ + __uint32_t __fpu_ip; /* offset */ + __uint16_t __fpu_cs; /* Selector */ + + __uint16_t __fpu_rsrv2; /* reserved */ + + /* x87 FPU Instruction Operand(Data) Pointer */ + __uint32_t __fpu_dp; /* offset */ + __uint16_t __fpu_ds; /* Selector */ + + __uint16_t __fpu_rsrv3; /* reserved */ + __uint32_t __fpu_mxcsr; /* MXCSR Register state */ + __uint32_t __fpu_mxcsrmask; /* MXCSR mask */ + _STRUCT_MMST_REG __fpu_stmm0; /* ST0/MM0 */ + _STRUCT_MMST_REG __fpu_stmm1; /* ST1/MM1 */ + _STRUCT_MMST_REG __fpu_stmm2; /* ST2/MM2 */ + _STRUCT_MMST_REG __fpu_stmm3; /* ST3/MM3 */ + _STRUCT_MMST_REG __fpu_stmm4; /* ST4/MM4 */ + _STRUCT_MMST_REG __fpu_stmm5; /* ST5/MM5 */ + _STRUCT_MMST_REG __fpu_stmm6; /* ST6/MM6 */ + _STRUCT_MMST_REG __fpu_stmm7; /* ST7/MM7 */ + _STRUCT_XMM_REG __fpu_xmm0; /* XMM 0 */ + _STRUCT_XMM_REG __fpu_xmm1; /* XMM 1 */ + _STRUCT_XMM_REG __fpu_xmm2; /* XMM 2 */ + _STRUCT_XMM_REG __fpu_xmm3; /* XMM 3 */ + _STRUCT_XMM_REG __fpu_xmm4; /* XMM 4 */ + _STRUCT_XMM_REG __fpu_xmm5; /* XMM 5 */ + _STRUCT_XMM_REG __fpu_xmm6; /* XMM 6 */ + _STRUCT_XMM_REG __fpu_xmm7; /* XMM 7 */ + _STRUCT_XMM_REG __fpu_xmm8; /* XMM 8 */ + _STRUCT_XMM_REG __fpu_xmm9; /* XMM 9 */ + _STRUCT_XMM_REG __fpu_xmm10; /* XMM 10 */ + _STRUCT_XMM_REG __fpu_xmm11; /* XMM 11 */ + _STRUCT_XMM_REG __fpu_xmm12; /* XMM 12 */ + _STRUCT_XMM_REG __fpu_xmm13; /* XMM 13 */ + _STRUCT_XMM_REG __fpu_xmm14; /* XMM 14 */ + _STRUCT_XMM_REG __fpu_xmm15; /* XMM 15 */ + char __fpu_rsrv4[6*16]; /* reserved */ + int __fpu_reserved1; +}; + +#define _STRUCT_X86_AVX_STATE64 struct __darwin_x86_avx_state64 +_STRUCT_X86_AVX_STATE64 +{ + int __fpu_reserved[2]; + _STRUCT_FP_CONTROL __fpu_fcw; /* x87 FPU control word */ + _STRUCT_FP_STATUS __fpu_fsw; /* x87 FPU status word */ + __uint8_t __fpu_ftw; /* x87 FPU tag word */ + __uint8_t __fpu_rsrv1; /* reserved */ + __uint16_t __fpu_fop; /* x87 FPU Opcode */ + + /* x87 FPU Instruction Pointer */ + __uint32_t __fpu_ip; /* offset */ + __uint16_t __fpu_cs; /* Selector */ + + __uint16_t __fpu_rsrv2; /* reserved */ + + /* x87 FPU Instruction Operand(Data) Pointer */ + __uint32_t __fpu_dp; /* offset */ + __uint16_t __fpu_ds; /* Selector */ + + __uint16_t __fpu_rsrv3; /* reserved */ + __uint32_t __fpu_mxcsr; /* MXCSR Register state */ + __uint32_t __fpu_mxcsrmask; /* MXCSR mask */ + _STRUCT_MMST_REG __fpu_stmm0; /* ST0/MM0 */ + _STRUCT_MMST_REG __fpu_stmm1; /* ST1/MM1 */ + _STRUCT_MMST_REG __fpu_stmm2; /* ST2/MM2 */ + _STRUCT_MMST_REG __fpu_stmm3; /* ST3/MM3 */ + _STRUCT_MMST_REG __fpu_stmm4; /* ST4/MM4 */ + _STRUCT_MMST_REG __fpu_stmm5; /* ST5/MM5 */ + _STRUCT_MMST_REG __fpu_stmm6; /* ST6/MM6 */ + _STRUCT_MMST_REG __fpu_stmm7; /* ST7/MM7 */ + _STRUCT_XMM_REG __fpu_xmm0; /* XMM 0 */ + _STRUCT_XMM_REG __fpu_xmm1; /* XMM 1 */ + _STRUCT_XMM_REG __fpu_xmm2; /* XMM 2 */ + _STRUCT_XMM_REG __fpu_xmm3; /* XMM 3 */ + _STRUCT_XMM_REG __fpu_xmm4; /* XMM 4 */ + _STRUCT_XMM_REG __fpu_xmm5; /* XMM 5 */ + _STRUCT_XMM_REG __fpu_xmm6; /* XMM 6 */ + _STRUCT_XMM_REG __fpu_xmm7; /* XMM 7 */ + _STRUCT_XMM_REG __fpu_xmm8; /* XMM 8 */ + _STRUCT_XMM_REG __fpu_xmm9; /* XMM 9 */ + _STRUCT_XMM_REG __fpu_xmm10; /* XMM 10 */ + _STRUCT_XMM_REG __fpu_xmm11; /* XMM 11 */ + _STRUCT_XMM_REG __fpu_xmm12; /* XMM 12 */ + _STRUCT_XMM_REG __fpu_xmm13; /* XMM 13 */ + _STRUCT_XMM_REG __fpu_xmm14; /* XMM 14 */ + _STRUCT_XMM_REG __fpu_xmm15; /* XMM 15 */ + char __fpu_rsrv4[6*16]; /* reserved */ + int __fpu_reserved1; + char __avx_reserved1[64]; + _STRUCT_XMM_REG __fpu_ymmh0; /* YMMH 0 */ + _STRUCT_XMM_REG __fpu_ymmh1; /* YMMH 1 */ + _STRUCT_XMM_REG __fpu_ymmh2; /* YMMH 2 */ + _STRUCT_XMM_REG __fpu_ymmh3; /* YMMH 3 */ + _STRUCT_XMM_REG __fpu_ymmh4; /* YMMH 4 */ + _STRUCT_XMM_REG __fpu_ymmh5; /* YMMH 5 */ + _STRUCT_XMM_REG __fpu_ymmh6; /* YMMH 6 */ + _STRUCT_XMM_REG __fpu_ymmh7; /* YMMH 7 */ + _STRUCT_XMM_REG __fpu_ymmh8; /* YMMH 8 */ + _STRUCT_XMM_REG __fpu_ymmh9; /* YMMH 9 */ + _STRUCT_XMM_REG __fpu_ymmh10; /* YMMH 10 */ + _STRUCT_XMM_REG __fpu_ymmh11; /* YMMH 11 */ + _STRUCT_XMM_REG __fpu_ymmh12; /* YMMH 12 */ + _STRUCT_XMM_REG __fpu_ymmh13; /* YMMH 13 */ + _STRUCT_XMM_REG __fpu_ymmh14; /* YMMH 14 */ + _STRUCT_XMM_REG __fpu_ymmh15; /* YMMH 15 */ +}; + +#define _STRUCT_X86_AVX512_STATE64 struct __darwin_x86_avx512_state64 +_STRUCT_X86_AVX512_STATE64 +{ + int __fpu_reserved[2]; + _STRUCT_FP_CONTROL __fpu_fcw; /* x87 FPU control word */ + _STRUCT_FP_STATUS __fpu_fsw; /* x87 FPU status word */ + __uint8_t __fpu_ftw; /* x87 FPU tag word */ + __uint8_t __fpu_rsrv1; /* reserved */ + __uint16_t __fpu_fop; /* x87 FPU Opcode */ + + /* x87 FPU Instruction Pointer */ + __uint32_t __fpu_ip; /* offset */ + __uint16_t __fpu_cs; /* Selector */ + + __uint16_t __fpu_rsrv2; /* reserved */ + + /* x87 FPU Instruction Operand(Data) Pointer */ + __uint32_t __fpu_dp; /* offset */ + __uint16_t __fpu_ds; /* Selector */ + + __uint16_t __fpu_rsrv3; /* reserved */ + __uint32_t __fpu_mxcsr; /* MXCSR Register state */ + __uint32_t __fpu_mxcsrmask; /* MXCSR mask */ + _STRUCT_MMST_REG __fpu_stmm0; /* ST0/MM0 */ + _STRUCT_MMST_REG __fpu_stmm1; /* ST1/MM1 */ + _STRUCT_MMST_REG __fpu_stmm2; /* ST2/MM2 */ + _STRUCT_MMST_REG __fpu_stmm3; /* ST3/MM3 */ + _STRUCT_MMST_REG __fpu_stmm4; /* ST4/MM4 */ + _STRUCT_MMST_REG __fpu_stmm5; /* ST5/MM5 */ + _STRUCT_MMST_REG __fpu_stmm6; /* ST6/MM6 */ + _STRUCT_MMST_REG __fpu_stmm7; /* ST7/MM7 */ + _STRUCT_XMM_REG __fpu_xmm0; /* XMM 0 */ + _STRUCT_XMM_REG __fpu_xmm1; /* XMM 1 */ + _STRUCT_XMM_REG __fpu_xmm2; /* XMM 2 */ + _STRUCT_XMM_REG __fpu_xmm3; /* XMM 3 */ + _STRUCT_XMM_REG __fpu_xmm4; /* XMM 4 */ + _STRUCT_XMM_REG __fpu_xmm5; /* XMM 5 */ + _STRUCT_XMM_REG __fpu_xmm6; /* XMM 6 */ + _STRUCT_XMM_REG __fpu_xmm7; /* XMM 7 */ + _STRUCT_XMM_REG __fpu_xmm8; /* XMM 8 */ + _STRUCT_XMM_REG __fpu_xmm9; /* XMM 9 */ + _STRUCT_XMM_REG __fpu_xmm10; /* XMM 10 */ + _STRUCT_XMM_REG __fpu_xmm11; /* XMM 11 */ + _STRUCT_XMM_REG __fpu_xmm12; /* XMM 12 */ + _STRUCT_XMM_REG __fpu_xmm13; /* XMM 13 */ + _STRUCT_XMM_REG __fpu_xmm14; /* XMM 14 */ + _STRUCT_XMM_REG __fpu_xmm15; /* XMM 15 */ + char __fpu_rsrv4[6*16]; /* reserved */ + int __fpu_reserved1; + char __avx_reserved1[64]; + _STRUCT_XMM_REG __fpu_ymmh0; /* YMMH 0 */ + _STRUCT_XMM_REG __fpu_ymmh1; /* YMMH 1 */ + _STRUCT_XMM_REG __fpu_ymmh2; /* YMMH 2 */ + _STRUCT_XMM_REG __fpu_ymmh3; /* YMMH 3 */ + _STRUCT_XMM_REG __fpu_ymmh4; /* YMMH 4 */ + _STRUCT_XMM_REG __fpu_ymmh5; /* YMMH 5 */ + _STRUCT_XMM_REG __fpu_ymmh6; /* YMMH 6 */ + _STRUCT_XMM_REG __fpu_ymmh7; /* YMMH 7 */ + _STRUCT_XMM_REG __fpu_ymmh8; /* YMMH 8 */ + _STRUCT_XMM_REG __fpu_ymmh9; /* YMMH 9 */ + _STRUCT_XMM_REG __fpu_ymmh10; /* YMMH 10 */ + _STRUCT_XMM_REG __fpu_ymmh11; /* YMMH 11 */ + _STRUCT_XMM_REG __fpu_ymmh12; /* YMMH 12 */ + _STRUCT_XMM_REG __fpu_ymmh13; /* YMMH 13 */ + _STRUCT_XMM_REG __fpu_ymmh14; /* YMMH 14 */ + _STRUCT_XMM_REG __fpu_ymmh15; /* YMMH 15 */ + _STRUCT_OPMASK_REG __fpu_k0; /* K0 */ + _STRUCT_OPMASK_REG __fpu_k1; /* K1 */ + _STRUCT_OPMASK_REG __fpu_k2; /* K2 */ + _STRUCT_OPMASK_REG __fpu_k3; /* K3 */ + _STRUCT_OPMASK_REG __fpu_k4; /* K4 */ + _STRUCT_OPMASK_REG __fpu_k5; /* K5 */ + _STRUCT_OPMASK_REG __fpu_k6; /* K6 */ + _STRUCT_OPMASK_REG __fpu_k7; /* K7 */ + _STRUCT_YMM_REG __fpu_zmmh0; /* ZMMH 0 */ + _STRUCT_YMM_REG __fpu_zmmh1; /* ZMMH 1 */ + _STRUCT_YMM_REG __fpu_zmmh2; /* ZMMH 2 */ + _STRUCT_YMM_REG __fpu_zmmh3; /* ZMMH 3 */ + _STRUCT_YMM_REG __fpu_zmmh4; /* ZMMH 4 */ + _STRUCT_YMM_REG __fpu_zmmh5; /* ZMMH 5 */ + _STRUCT_YMM_REG __fpu_zmmh6; /* ZMMH 6 */ + _STRUCT_YMM_REG __fpu_zmmh7; /* ZMMH 7 */ + _STRUCT_YMM_REG __fpu_zmmh8; /* ZMMH 8 */ + _STRUCT_YMM_REG __fpu_zmmh9; /* ZMMH 9 */ + _STRUCT_YMM_REG __fpu_zmmh10; /* ZMMH 10 */ + _STRUCT_YMM_REG __fpu_zmmh11; /* ZMMH 11 */ + _STRUCT_YMM_REG __fpu_zmmh12; /* ZMMH 12 */ + _STRUCT_YMM_REG __fpu_zmmh13; /* ZMMH 13 */ + _STRUCT_YMM_REG __fpu_zmmh14; /* ZMMH 14 */ + _STRUCT_YMM_REG __fpu_zmmh15; /* ZMMH 15 */ + _STRUCT_ZMM_REG __fpu_zmm16; /* ZMM 16 */ + _STRUCT_ZMM_REG __fpu_zmm17; /* ZMM 17 */ + _STRUCT_ZMM_REG __fpu_zmm18; /* ZMM 18 */ + _STRUCT_ZMM_REG __fpu_zmm19; /* ZMM 19 */ + _STRUCT_ZMM_REG __fpu_zmm20; /* ZMM 20 */ + _STRUCT_ZMM_REG __fpu_zmm21; /* ZMM 21 */ + _STRUCT_ZMM_REG __fpu_zmm22; /* ZMM 22 */ + _STRUCT_ZMM_REG __fpu_zmm23; /* ZMM 23 */ + _STRUCT_ZMM_REG __fpu_zmm24; /* ZMM 24 */ + _STRUCT_ZMM_REG __fpu_zmm25; /* ZMM 25 */ + _STRUCT_ZMM_REG __fpu_zmm26; /* ZMM 26 */ + _STRUCT_ZMM_REG __fpu_zmm27; /* ZMM 27 */ + _STRUCT_ZMM_REG __fpu_zmm28; /* ZMM 28 */ + _STRUCT_ZMM_REG __fpu_zmm29; /* ZMM 29 */ + _STRUCT_ZMM_REG __fpu_zmm30; /* ZMM 30 */ + _STRUCT_ZMM_REG __fpu_zmm31; /* ZMM 31 */ +}; + +#else /* !__DARWIN_UNIX03 */ +#define _STRUCT_X86_FLOAT_STATE64 struct x86_float_state64 +_STRUCT_X86_FLOAT_STATE64 +{ + int fpu_reserved[2]; + _STRUCT_FP_CONTROL fpu_fcw; /* x87 FPU control word */ + _STRUCT_FP_STATUS fpu_fsw; /* x87 FPU status word */ + __uint8_t fpu_ftw; /* x87 FPU tag word */ + __uint8_t fpu_rsrv1; /* reserved */ + __uint16_t fpu_fop; /* x87 FPU Opcode */ + + /* x87 FPU Instruction Pointer */ + __uint32_t fpu_ip; /* offset */ + __uint16_t fpu_cs; /* Selector */ + + __uint16_t fpu_rsrv2; /* reserved */ + + /* x87 FPU Instruction Operand(Data) Pointer */ + __uint32_t fpu_dp; /* offset */ + __uint16_t fpu_ds; /* Selector */ + + __uint16_t fpu_rsrv3; /* reserved */ + __uint32_t fpu_mxcsr; /* MXCSR Register state */ + __uint32_t fpu_mxcsrmask; /* MXCSR mask */ + _STRUCT_MMST_REG fpu_stmm0; /* ST0/MM0 */ + _STRUCT_MMST_REG fpu_stmm1; /* ST1/MM1 */ + _STRUCT_MMST_REG fpu_stmm2; /* ST2/MM2 */ + _STRUCT_MMST_REG fpu_stmm3; /* ST3/MM3 */ + _STRUCT_MMST_REG fpu_stmm4; /* ST4/MM4 */ + _STRUCT_MMST_REG fpu_stmm5; /* ST5/MM5 */ + _STRUCT_MMST_REG fpu_stmm6; /* ST6/MM6 */ + _STRUCT_MMST_REG fpu_stmm7; /* ST7/MM7 */ + _STRUCT_XMM_REG fpu_xmm0; /* XMM 0 */ + _STRUCT_XMM_REG fpu_xmm1; /* XMM 1 */ + _STRUCT_XMM_REG fpu_xmm2; /* XMM 2 */ + _STRUCT_XMM_REG fpu_xmm3; /* XMM 3 */ + _STRUCT_XMM_REG fpu_xmm4; /* XMM 4 */ + _STRUCT_XMM_REG fpu_xmm5; /* XMM 5 */ + _STRUCT_XMM_REG fpu_xmm6; /* XMM 6 */ + _STRUCT_XMM_REG fpu_xmm7; /* XMM 7 */ + _STRUCT_XMM_REG fpu_xmm8; /* XMM 8 */ + _STRUCT_XMM_REG fpu_xmm9; /* XMM 9 */ + _STRUCT_XMM_REG fpu_xmm10; /* XMM 10 */ + _STRUCT_XMM_REG fpu_xmm11; /* XMM 11 */ + _STRUCT_XMM_REG fpu_xmm12; /* XMM 12 */ + _STRUCT_XMM_REG fpu_xmm13; /* XMM 13 */ + _STRUCT_XMM_REG fpu_xmm14; /* XMM 14 */ + _STRUCT_XMM_REG fpu_xmm15; /* XMM 15 */ + char fpu_rsrv4[6*16]; /* reserved */ + int fpu_reserved1; +}; + +#define _STRUCT_X86_AVX_STATE64 struct x86_avx_state64 +_STRUCT_X86_AVX_STATE64 +{ + int fpu_reserved[2]; + _STRUCT_FP_CONTROL fpu_fcw; /* x87 FPU control word */ + _STRUCT_FP_STATUS fpu_fsw; /* x87 FPU status word */ + __uint8_t fpu_ftw; /* x87 FPU tag word */ + __uint8_t fpu_rsrv1; /* reserved */ + __uint16_t fpu_fop; /* x87 FPU Opcode */ + + /* x87 FPU Instruction Pointer */ + __uint32_t fpu_ip; /* offset */ + __uint16_t fpu_cs; /* Selector */ + + __uint16_t fpu_rsrv2; /* reserved */ + + /* x87 FPU Instruction Operand(Data) Pointer */ + __uint32_t fpu_dp; /* offset */ + __uint16_t fpu_ds; /* Selector */ + + __uint16_t fpu_rsrv3; /* reserved */ + __uint32_t fpu_mxcsr; /* MXCSR Register state */ + __uint32_t fpu_mxcsrmask; /* MXCSR mask */ + _STRUCT_MMST_REG fpu_stmm0; /* ST0/MM0 */ + _STRUCT_MMST_REG fpu_stmm1; /* ST1/MM1 */ + _STRUCT_MMST_REG fpu_stmm2; /* ST2/MM2 */ + _STRUCT_MMST_REG fpu_stmm3; /* ST3/MM3 */ + _STRUCT_MMST_REG fpu_stmm4; /* ST4/MM4 */ + _STRUCT_MMST_REG fpu_stmm5; /* ST5/MM5 */ + _STRUCT_MMST_REG fpu_stmm6; /* ST6/MM6 */ + _STRUCT_MMST_REG fpu_stmm7; /* ST7/MM7 */ + _STRUCT_XMM_REG fpu_xmm0; /* XMM 0 */ + _STRUCT_XMM_REG fpu_xmm1; /* XMM 1 */ + _STRUCT_XMM_REG fpu_xmm2; /* XMM 2 */ + _STRUCT_XMM_REG fpu_xmm3; /* XMM 3 */ + _STRUCT_XMM_REG fpu_xmm4; /* XMM 4 */ + _STRUCT_XMM_REG fpu_xmm5; /* XMM 5 */ + _STRUCT_XMM_REG fpu_xmm6; /* XMM 6 */ + _STRUCT_XMM_REG fpu_xmm7; /* XMM 7 */ + _STRUCT_XMM_REG fpu_xmm8; /* XMM 8 */ + _STRUCT_XMM_REG fpu_xmm9; /* XMM 9 */ + _STRUCT_XMM_REG fpu_xmm10; /* XMM 10 */ + _STRUCT_XMM_REG fpu_xmm11; /* XMM 11 */ + _STRUCT_XMM_REG fpu_xmm12; /* XMM 12 */ + _STRUCT_XMM_REG fpu_xmm13; /* XMM 13 */ + _STRUCT_XMM_REG fpu_xmm14; /* XMM 14 */ + _STRUCT_XMM_REG fpu_xmm15; /* XMM 15 */ + char fpu_rsrv4[6*16]; /* reserved */ + int fpu_reserved1; + char avx_reserved1[64]; + _STRUCT_XMM_REG fpu_ymmh0; /* YMMH 0 */ + _STRUCT_XMM_REG fpu_ymmh1; /* YMMH 1 */ + _STRUCT_XMM_REG fpu_ymmh2; /* YMMH 2 */ + _STRUCT_XMM_REG fpu_ymmh3; /* YMMH 3 */ + _STRUCT_XMM_REG fpu_ymmh4; /* YMMH 4 */ + _STRUCT_XMM_REG fpu_ymmh5; /* YMMH 5 */ + _STRUCT_XMM_REG fpu_ymmh6; /* YMMH 6 */ + _STRUCT_XMM_REG fpu_ymmh7; /* YMMH 7 */ + _STRUCT_XMM_REG fpu_ymmh8; /* YMMH 8 */ + _STRUCT_XMM_REG fpu_ymmh9; /* YMMH 9 */ + _STRUCT_XMM_REG fpu_ymmh10; /* YMMH 10 */ + _STRUCT_XMM_REG fpu_ymmh11; /* YMMH 11 */ + _STRUCT_XMM_REG fpu_ymmh12; /* YMMH 12 */ + _STRUCT_XMM_REG fpu_ymmh13; /* YMMH 13 */ + _STRUCT_XMM_REG fpu_ymmh14; /* YMMH 14 */ + _STRUCT_XMM_REG fpu_ymmh15; /* YMMH 15 */ +}; + +#define _STRUCT_X86_AVX512_STATE64 struct x86_avx512_state64 +_STRUCT_X86_AVX512_STATE64 +{ + int fpu_reserved[2]; + _STRUCT_FP_CONTROL fpu_fcw; /* x87 FPU control word */ + _STRUCT_FP_STATUS fpu_fsw; /* x87 FPU status word */ + __uint8_t fpu_ftw; /* x87 FPU tag word */ + __uint8_t fpu_rsrv1; /* reserved */ + __uint16_t fpu_fop; /* x87 FPU Opcode */ + + /* x87 FPU Instruction Pointer */ + __uint32_t fpu_ip; /* offset */ + __uint16_t fpu_cs; /* Selector */ + + __uint16_t fpu_rsrv2; /* reserved */ + + /* x87 FPU Instruction Operand(Data) Pointer */ + __uint32_t fpu_dp; /* offset */ + __uint16_t fpu_ds; /* Selector */ + + __uint16_t fpu_rsrv3; /* reserved */ + __uint32_t fpu_mxcsr; /* MXCSR Register state */ + __uint32_t fpu_mxcsrmask; /* MXCSR mask */ + _STRUCT_MMST_REG fpu_stmm0; /* ST0/MM0 */ + _STRUCT_MMST_REG fpu_stmm1; /* ST1/MM1 */ + _STRUCT_MMST_REG fpu_stmm2; /* ST2/MM2 */ + _STRUCT_MMST_REG fpu_stmm3; /* ST3/MM3 */ + _STRUCT_MMST_REG fpu_stmm4; /* ST4/MM4 */ + _STRUCT_MMST_REG fpu_stmm5; /* ST5/MM5 */ + _STRUCT_MMST_REG fpu_stmm6; /* ST6/MM6 */ + _STRUCT_MMST_REG fpu_stmm7; /* ST7/MM7 */ + _STRUCT_XMM_REG fpu_xmm0; /* XMM 0 */ + _STRUCT_XMM_REG fpu_xmm1; /* XMM 1 */ + _STRUCT_XMM_REG fpu_xmm2; /* XMM 2 */ + _STRUCT_XMM_REG fpu_xmm3; /* XMM 3 */ + _STRUCT_XMM_REG fpu_xmm4; /* XMM 4 */ + _STRUCT_XMM_REG fpu_xmm5; /* XMM 5 */ + _STRUCT_XMM_REG fpu_xmm6; /* XMM 6 */ + _STRUCT_XMM_REG fpu_xmm7; /* XMM 7 */ + _STRUCT_XMM_REG fpu_xmm8; /* XMM 8 */ + _STRUCT_XMM_REG fpu_xmm9; /* XMM 9 */ + _STRUCT_XMM_REG fpu_xmm10; /* XMM 10 */ + _STRUCT_XMM_REG fpu_xmm11; /* XMM 11 */ + _STRUCT_XMM_REG fpu_xmm12; /* XMM 12 */ + _STRUCT_XMM_REG fpu_xmm13; /* XMM 13 */ + _STRUCT_XMM_REG fpu_xmm14; /* XMM 14 */ + _STRUCT_XMM_REG fpu_xmm15; /* XMM 15 */ + char fpu_rsrv4[6*16]; /* reserved */ + int fpu_reserved1; + char avx_reserved1[64]; + _STRUCT_XMM_REG fpu_ymmh0; /* YMMH 0 */ + _STRUCT_XMM_REG fpu_ymmh1; /* YMMH 1 */ + _STRUCT_XMM_REG fpu_ymmh2; /* YMMH 2 */ + _STRUCT_XMM_REG fpu_ymmh3; /* YMMH 3 */ + _STRUCT_XMM_REG fpu_ymmh4; /* YMMH 4 */ + _STRUCT_XMM_REG fpu_ymmh5; /* YMMH 5 */ + _STRUCT_XMM_REG fpu_ymmh6; /* YMMH 6 */ + _STRUCT_XMM_REG fpu_ymmh7; /* YMMH 7 */ + _STRUCT_XMM_REG fpu_ymmh8; /* YMMH 8 */ + _STRUCT_XMM_REG fpu_ymmh9; /* YMMH 9 */ + _STRUCT_XMM_REG fpu_ymmh10; /* YMMH 10 */ + _STRUCT_XMM_REG fpu_ymmh11; /* YMMH 11 */ + _STRUCT_XMM_REG fpu_ymmh12; /* YMMH 12 */ + _STRUCT_XMM_REG fpu_ymmh13; /* YMMH 13 */ + _STRUCT_XMM_REG fpu_ymmh14; /* YMMH 14 */ + _STRUCT_XMM_REG fpu_ymmh15; /* YMMH 15 */ + _STRUCT_OPMASK_REG fpu_k0; /* K0 */ + _STRUCT_OPMASK_REG fpu_k1; /* K1 */ + _STRUCT_OPMASK_REG fpu_k2; /* K2 */ + _STRUCT_OPMASK_REG fpu_k3; /* K3 */ + _STRUCT_OPMASK_REG fpu_k4; /* K4 */ + _STRUCT_OPMASK_REG fpu_k5; /* K5 */ + _STRUCT_OPMASK_REG fpu_k6; /* K6 */ + _STRUCT_OPMASK_REG fpu_k7; /* K7 */ + _STRUCT_YMM_REG fpu_zmmh0; /* ZMMH 0 */ + _STRUCT_YMM_REG fpu_zmmh1; /* ZMMH 1 */ + _STRUCT_YMM_REG fpu_zmmh2; /* ZMMH 2 */ + _STRUCT_YMM_REG fpu_zmmh3; /* ZMMH 3 */ + _STRUCT_YMM_REG fpu_zmmh4; /* ZMMH 4 */ + _STRUCT_YMM_REG fpu_zmmh5; /* ZMMH 5 */ + _STRUCT_YMM_REG fpu_zmmh6; /* ZMMH 6 */ + _STRUCT_YMM_REG fpu_zmmh7; /* ZMMH 7 */ + _STRUCT_YMM_REG fpu_zmmh8; /* ZMMH 8 */ + _STRUCT_YMM_REG fpu_zmmh9; /* ZMMH 9 */ + _STRUCT_YMM_REG fpu_zmmh10; /* ZMMH 10 */ + _STRUCT_YMM_REG fpu_zmmh11; /* ZMMH 11 */ + _STRUCT_YMM_REG fpu_zmmh12; /* ZMMH 12 */ + _STRUCT_YMM_REG fpu_zmmh13; /* ZMMH 13 */ + _STRUCT_YMM_REG fpu_zmmh14; /* ZMMH 14 */ + _STRUCT_YMM_REG fpu_zmmh15; /* ZMMH 15 */ + _STRUCT_ZMM_REG fpu_zmm16; /* ZMM 16 */ + _STRUCT_ZMM_REG fpu_zmm17; /* ZMM 17 */ + _STRUCT_ZMM_REG fpu_zmm18; /* ZMM 18 */ + _STRUCT_ZMM_REG fpu_zmm19; /* ZMM 19 */ + _STRUCT_ZMM_REG fpu_zmm20; /* ZMM 20 */ + _STRUCT_ZMM_REG fpu_zmm21; /* ZMM 21 */ + _STRUCT_ZMM_REG fpu_zmm22; /* ZMM 22 */ + _STRUCT_ZMM_REG fpu_zmm23; /* ZMM 23 */ + _STRUCT_ZMM_REG fpu_zmm24; /* ZMM 24 */ + _STRUCT_ZMM_REG fpu_zmm25; /* ZMM 25 */ + _STRUCT_ZMM_REG fpu_zmm26; /* ZMM 26 */ + _STRUCT_ZMM_REG fpu_zmm27; /* ZMM 27 */ + _STRUCT_ZMM_REG fpu_zmm28; /* ZMM 28 */ + _STRUCT_ZMM_REG fpu_zmm29; /* ZMM 29 */ + _STRUCT_ZMM_REG fpu_zmm30; /* ZMM 30 */ + _STRUCT_ZMM_REG fpu_zmm31; /* ZMM 31 */ +}; + +#endif /* !__DARWIN_UNIX03 */ + +#if __DARWIN_UNIX03 +#define _STRUCT_X86_EXCEPTION_STATE64 struct __darwin_x86_exception_state64 +_STRUCT_X86_EXCEPTION_STATE64 +{ + __uint16_t __trapno; + __uint16_t __cpu; + __uint32_t __err; + __uint64_t __faultvaddr; +}; +#else /* !__DARWIN_UNIX03 */ +#define _STRUCT_X86_EXCEPTION_STATE64 struct x86_exception_state64 +_STRUCT_X86_EXCEPTION_STATE64 +{ + __uint16_t trapno; + __uint16_t cpu; + __uint32_t err; + __uint64_t faultvaddr; +}; +#endif /* !__DARWIN_UNIX03 */ + +#if __DARWIN_UNIX03 +#define _STRUCT_X86_DEBUG_STATE64 struct __darwin_x86_debug_state64 +_STRUCT_X86_DEBUG_STATE64 +{ + __uint64_t __dr0; + __uint64_t __dr1; + __uint64_t __dr2; + __uint64_t __dr3; + __uint64_t __dr4; + __uint64_t __dr5; + __uint64_t __dr6; + __uint64_t __dr7; +}; +#else /* !__DARWIN_UNIX03 */ +#define _STRUCT_X86_DEBUG_STATE64 struct x86_debug_state64 +_STRUCT_X86_DEBUG_STATE64 +{ + __uint64_t dr0; + __uint64_t dr1; + __uint64_t dr2; + __uint64_t dr3; + __uint64_t dr4; + __uint64_t dr5; + __uint64_t dr6; + __uint64_t dr7; +}; +#endif /* !__DARWIN_UNIX03 */ + +#if __DARWIN_UNIX03 +#define _STRUCT_X86_CPMU_STATE64 struct __darwin_x86_cpmu_state64 +_STRUCT_X86_CPMU_STATE64 +{ + __uint64_t __ctrs[16]; +}; +#else /* __DARWIN_UNIX03 */ +#define _STRUCT_X86_CPMU_STATE64 struct x86_cpmu_state64 +_STRUCT_X86_CPMU_STATE64 +{ + __uint64_t ctrs[16]; +}; +#endif /* !__DARWIN_UNIX03 */ + +#endif /* _MACH_I386__STRUCTS_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/asm.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/asm.h new file mode 100644 index 00000000..50905a62 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/asm.h @@ -0,0 +1,380 @@ +/* + * Copyright (c) 2000-2018 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + +#ifndef _I386_ASM_H_ +#define _I386_ASM_H_ + +#if defined(__i386__) + +#define S_PC (%esp) +#define S_ARG0 4(%esp) +#define S_ARG1 8(%esp) +#define S_ARG2 12(%esp) +#define S_ARG3 16(%esp) +#define S_ARG4 20(%esp) + +#define FRAME pushl %ebp; movl %esp, %ebp +#define EMARF leave + +#define B_LINK (%ebp) +#define B_PC 4(%ebp) +#define B_ARG0 8(%ebp) +#define B_ARG1 12(%ebp) +#define B_ARG2 16(%ebp) +#define B_ARG3 20(%ebp) + +#elif defined(__x86_64__) + +#define S_PC (%rsp) + +#define FRAME pushq %rbp; movq %rsp, %rbp +#define EMARF leave + +#define B_LINK (%rbp) +#define B_PC 8(%rbp) + +#else +#error unsupported architecture +#endif + +/* There is another definition of ALIGN for .c sources */ +#ifdef ASSEMBLER +#define ALIGN 4,0x90 +#endif /* ASSEMBLER */ + +#ifndef FALIGN +#define FALIGN ALIGN +#endif + +#define LB(x,n) n +#if __STDC__ +#ifndef __NO_UNDERSCORES__ +#define LCL(x) L ## x +#define EXT(x) _ ## x +#define LEXT(x) _ ## x ## : +#else +#define LCL(x) .L ## x +#define EXT(x) x +#define LEXT(x) x ## : +#endif +#define LBc(x,n) n ## : +#define LBb(x,n) n ## b +#define LBf(x,n) n ## f +#else /* __STDC__ */ +#ifndef __NO_UNDERSCORES__ +#define LCL(x) L/**/x +#define EXT(x) _/**/x +#define LEXT(x) _/**/x/**/: +#else /* __NO_UNDERSCORES__ */ +#define LCL(x) .L/**/x +#define EXT(x) x +#define LEXT(x) x/**/: +#endif /* __NO_UNDERSCORES__ */ +#define LBc(x,n) n/**/: +#define LBb(x,n) n/**/b +#define LBf(x,n) n/**/f +#endif /* __STDC__ */ + +#define SVC .byte 0x9a; .long 0; .word 0x7 + +#define RPC_SVC .byte 0x9a; .long 0; .word 0xf + +#define String .asciz +#define Value .word +#define Times(a,b) (a*b) +#define Divide(a,b) (a/b) + +#define INB inb %dx, %al +#define OUTB outb %al, %dx +#define INL inl %dx, %eax +#define OUTL outl %eax, %dx + +#define data16 .byte 0x66 +#define addr16 .byte 0x67 + +#define MCOUNT + +#if defined(__SHARED__) +#define MCOUNT ; .data;\ + .align ALIGN;\ + LBc(x, 8) .long 0;\ + .text;\ + Gpush;\ + Gload;\ + leal Gotoff(LBb(x,8)),%edx;\ + Egaddr(%eax,_mcount_ptr);\ + Gpop;\ + call *(%eax); +#endif /* __SHARED__ */ + +#ifdef __ELF__ +#define ELF_FUNC(x) .type x,@function +#define ELF_DATA(x) .type x,@object +#define ELF_SIZE(x,s) .size x,s +#else +#define ELF_FUNC(x) +#define ELF_DATA(x) +#define ELF_SIZE(x,s) +#endif + +#define Entry(x) .globl EXT(x); ELF_FUNC(EXT(x)); .align FALIGN; LEXT(x) +#define ENTRY(x) Entry(x) MCOUNT +#define ENTRY2(x,y) .globl EXT(x); .globl EXT(y); \ + ELF_FUNC(EXT(x)); ELF_FUNC(EXT(y)); \ + .align FALIGN; LEXT(x); LEXT(y) \ + MCOUNT +#if __STDC__ +#define ASENTRY(x) .globl x; .align FALIGN; x ## : ELF_FUNC(x) MCOUNT +#else +#define ASENTRY(x) .globl x; .align FALIGN; x: ELF_FUNC(x) MCOUNT +#endif /* __STDC__ */ + +#define DATA(x) .globl EXT(x); ELF_DATA(EXT(x)); .align ALIGN; LEXT(x) + +#define End(x) ELF_SIZE(x,.-x) +#define END(x) End(EXT(x)) +#define ENDDATA(x) END(x) +#define Enddata(x) End(x) + +/* + * ELF shared library accessor macros. + * Gpush saves the %ebx register used for the GOT address + * Gpop pops %ebx if we need a GOT + * Gload loads %ebx with the GOT address if shared libraries are used + * Gcall calls an external function. + * Gotoff allows you to reference local labels. + * Gotoff2 allows you to reference local labels with an index reg. + * Gotoff3 allows you to reference local labels with an index reg & size. + * Gaddr loads up a register with an address of an external item. + * Gstack is the number of bytes that Gpush pushes on the stack. + * + * Varients of the above with E or L prefixes do EXT(name) or LCL(name) + * respectively. + */ + +#ifndef __SHARED__ +#define Gpush +#define Gpop +#define Gload +#define Gcall(func) call func +#define Gotoff(lab) lab +#define Gotoff2(l,r) l(r) +#define Gotoff3(l,r,s) l(,r,s) +#define Gaddr(to,lab) movl $lab,to +#define Gcmp(lab,reg) cmpl $lab,reg +#define Gmemload(lab,reg) movl lab,reg +#define Gmemstore(reg,lab,tmp) movl reg,lab +#define Gstack 0 + +#else +#ifdef __ELF__ /* ELF shared libraries */ +#define Gpush pushl %ebx +#define Gpop popl %ebx +#define Gload call 9f; 9: popl %ebx; addl $_GLOBAL_OFFSET_TABLE_+[.-9b],%ebx +#define Gcall(func) call EXT(func)@PLT +#define Gotoff(lab) lab@GOTOFF(%ebx) +#define Gotoff2(l,r) l@GOTOFF(%ebx,r) +#define Gotoff3(l,r,s) l@GOTOFF(%ebx,r,s) +#define Gaddr(to,lab) movl lab@GOT(%ebx),to +#define Gcmp(lab,reg) cmpl reg,lab@GOT(%ebx) +#define Gmemload(lab,reg) movl lab@GOT(%ebx),reg; movl (reg),reg +#define Gmemstore(reg,lab,tmp) movl lab@GOT(%ebx),tmp; movl reg,(tmp) +#define Gstack 4 + +#else /* ROSE shared libraries */ +#define Gpush +#define Gpop +#define Gload +#define Gcall(func) call *9f; .data; .align ALIGN; 9: .long func; .text +#define Gotoff(lab) lab +#define Gotoff2(l,r) l(r) +#define Gotoff3(l,r,s) l(,r,s) +#define Gaddr(to,lab) movl 9f,to; .data; .align ALIGN; 9: .long lab; .text +#define Gcmp(lab,reg) cmpl reg,9f; .data; .align ALIGN; 9: .long lab; .text +#define Gmemload(lab,reg) movl 9f,reg; movl (reg),reg; .data; .align ALIGN; 9: .long lab; .text +#define Gmemstore(reg,lab,tmp) movl 9f,tmp; movl reg,(tmp); .data; .align ALIGN; 9: .long lab; .text +#define Gstack 0 +#endif /* __ELF__ */ +#endif /* __SHARED__ */ + +/* Egotoff is not provided, since external symbols should not use @GOTOFF + relocations. */ +#define Egcall(func) Gcall(EXT(func)) +#define Egaddr(to,lab) Gaddr(to,EXT(lab)) +#define Egcmp(lab,reg) Gcmp(EXT(lab),reg) +#define Egmemload(lab,reg) Gmemload(EXT(lab),reg) +#define Egmemstore(reg,lab,tmp) Gmemstore(reg,EXT(lab),tmp) + +#define Lgotoff(lab) Gotoff(LCL(lab)) +#define Lgotoff2(l,r) Gotoff2(LCL(l),r) +#define Lgotoff3(l,r,s) Gotoff3(LCL(l),r,s) +#define Lgcmp(lab,reg) Gcmp(LCL(lab),reg) +#define Lgmemload(lab,reg) movl Lgotoff(lab),reg +#define Lgmemstore(reg,lab,tmp) movl reg,Lgotoff(lab) + +#ifndef ASSEMBLER +/* These defines are here for .c files that wish to reference global symbols + * within __asm__ statements. + */ +#ifndef __NO_UNDERSCORES__ +#define CC_SYM_PREFIX "_" +#else +#define CC_SYM_PREFIX "" +#endif /* __NO_UNDERSCORES__ */ +#endif /* ASSEMBLER */ + +/* + * The following macros make calls into C code. + * They dynamically align the stack to 16 bytes. + */ +#if defined(__i386__) +/* + * Arguments are moved (not pushed) onto the correctly aligned stack. + * NOTE: ESI is destroyed in the process, and hence cannot + * be directly used as a parameter. Users of this macro must + * independently preserve ESI (a non-volatile) if the routine is + * intended to be called from C, for instance. + */ + +#define CCALL(fn) \ + movl %esp, %esi ;\ + andl $0xFFFFFFF0, %esp ;\ + call EXT(fn) ;\ + movl %esi, %esp + +#define CCALL1(fn, arg1) \ + movl %esp, %esi ;\ + subl $4, %esp ;\ + andl $0xFFFFFFF0, %esp ;\ + movl arg1, (%esp) ;\ + call EXT(fn) ;\ + movl %esi, %esp + +#define CCALL2(fn, arg1, arg2) \ + movl %esp, %esi ;\ + subl $8, %esp ;\ + andl $0xFFFFFFF0, %esp ;\ + movl arg2, 4(%esp) ;\ + movl arg1, (%esp) ;\ + call EXT(fn) ;\ + movl %esi, %esp + +/* This variant exists to permit adjustment of the stack by "dtrace" */ +#define CCALL1WITHSP(fn, arg1) \ + movl %esp, %esi ;\ + subl $12, %esp ;\ + andl $0xFFFFFFF0, %esp ;\ + movl %esi, 8(%esp) ;\ + leal 8(%esp), %esi ;\ + movl %esi, 4(%esp) ;\ + movl arg1, (%esp) ;\ + call EXT(fn) ;\ + movl 8(%esp), %esp + +/* + * CCALL5 is used for callee functions with 3 arguments but + * where arg2 (a3:a2) and arg3 (a5:a4) are 64-bit values. + */ +#define CCALL5(fn, a1, a2, a3, a4, a5) \ + movl %esp, %esi ;\ + subl $20, %esp ;\ + andl $0xFFFFFFF0, %esp ;\ + movl a5, 16(%esp) ;\ + movl a4, 12(%esp) ;\ + movl a3, 8(%esp) ;\ + movl a2, 4(%esp) ;\ + movl a1, (%esp) ;\ + call EXT(fn) ;\ + movl %esi, %esp + +#elif defined(__x86_64__) + +/* This variant exists to permit adjustment of the stack by "dtrace" */ +#define CCALLWITHSP(fn) \ + mov %rsp, %r12 ;\ + sub $8, %rsp ;\ + and $0xFFFFFFFFFFFFFFF0, %rsp ;\ + mov %r12, (%rsp) ;\ + leaq (%rsp), %rsi ;\ + call EXT(fn) ;\ + mov (%rsp), %rsp + +#define CCALL(fn) \ + mov %rsp, %r12 ;\ + and $0xFFFFFFFFFFFFFFF0, %rsp ;\ + call EXT(fn) ;\ + mov %r12, %rsp + +#define CCALL1(fn, arg1) \ + mov arg1, %rdi ;\ + CCALL(fn) + +#define CCALL2(fn, arg1, arg2) \ + mov arg1, %rdi ;\ + mov arg2, %rsi ;\ + CCALL(fn) + +#define CCALL3(fn, arg1, arg2, arg3) \ + mov arg1, %rdi ;\ + mov arg2, %rsi ;\ + mov arg3, %rdx ;\ + CCALL(fn) + +#else +#error unsupported architecture +#endif + +#endif /* _I386_ASM_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/boolean.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/boolean.h new file mode 100644 index 00000000..70237593 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/boolean.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ + +/* + * File: boolean.h + * + * Boolean type, for I386. + */ + +#ifndef _MACH_I386_BOOLEAN_H_ +#define _MACH_I386_BOOLEAN_H_ + +#if defined(__x86_64__) && !defined(KERNEL) +typedef unsigned int boolean_t; +#else +typedef int boolean_t; +#endif + +#endif /* _MACH_I386_BOOLEAN_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/exception.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/exception.h new file mode 100644 index 00000000..44b5272d --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/exception.h @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ + +#ifndef _MACH_I386_EXCEPTION_H_ +#define _MACH_I386_EXCEPTION_H_ + +/* + * No machine dependent types for the 80386 + */ + +#define EXC_TYPES_COUNT 14 /* incl. illegal exception 0 */ + +/* + * Codes and subcodes for 80386 exceptions. + */ + +#define EXCEPTION_CODE_MAX 2 /* currently code and subcode */ + +/* + * EXC_BAD_INSTRUCTION + */ + +#define EXC_I386_INVOP 1 + +/* + * EXC_ARITHMETIC + */ + +#define EXC_I386_DIV 1 +#define EXC_I386_INTO 2 +#define EXC_I386_NOEXT 3 +#define EXC_I386_EXTOVR 4 +#define EXC_I386_EXTERR 5 +#define EXC_I386_EMERR 6 +#define EXC_I386_BOUND 7 +#define EXC_I386_SSEEXTERR 8 + +/* + * EXC_SOFTWARE + * Note: 0x10000-0x10003 in use for unix signal + */ + +/* + * EXC_BAD_ACCESS + */ + +/* + * EXC_BREAKPOINT + */ + +#define EXC_I386_SGL 1 +#define EXC_I386_BPT 2 + +#define EXC_I386_DIVERR 0 /* divide by 0 eprror */ +#define EXC_I386_SGLSTP 1 /* single step */ +#define EXC_I386_NMIFLT 2 /* NMI */ +#define EXC_I386_BPTFLT 3 /* breakpoint fault */ +#define EXC_I386_INTOFLT 4 /* INTO overflow fault */ +#define EXC_I386_BOUNDFLT 5 /* BOUND instruction fault */ +#define EXC_I386_INVOPFLT 6 /* invalid opcode fault */ +#define EXC_I386_NOEXTFLT 7 /* extension not available fault*/ +#define EXC_I386_DBLFLT 8 /* double fault */ +#define EXC_I386_EXTOVRFLT 9 /* extension overrun fault */ +#define EXC_I386_INVTSSFLT 10 /* invalid TSS fault */ +#define EXC_I386_SEGNPFLT 11 /* segment not present fault */ +#define EXC_I386_STKFLT 12 /* stack fault */ +#define EXC_I386_GPFLT 13 /* general protection fault */ +#define EXC_I386_PGFLT 14 /* page fault */ +#define EXC_I386_EXTERRFLT 16 /* extension error fault */ +#define EXC_I386_ALIGNFLT 17 /* Alignment fault */ +#define EXC_I386_ENDPERR 33 /* emulated extension error flt */ +#define EXC_I386_ENOEXTFLT 32 /* emulated ext not present */ + + +/* + * machine dependent exception masks + */ +#define EXC_MASK_MACHINE 0 + +#endif /* _MACH_I386_EXCEPTION_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/fp_reg.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/fp_reg.h new file mode 100644 index 00000000..35937059 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/fp_reg.h @@ -0,0 +1,118 @@ +/* + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1992-1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ + +#ifndef _I386_FP_SAVE_H_ +#define _I386_FP_SAVE_H_ + +/* + * Control register + */ +#define FPC_IE 0x0001 /* enable invalid operation + * exception */ +#define FPC_IM FPC_IE +#define FPC_DE 0x0002 /* enable denormalized operation + * exception */ +#define FPC_DM FPC_DE +#define FPC_ZE 0x0004 /* enable zero-divide exception */ +#define FPC_ZM FPC_ZE +#define FPC_OE 0x0008 /* enable overflow exception */ +#define FPC_OM FPC_OE +#define FPC_UE 0x0010 /* enable underflow exception */ +#define FPC_PE 0x0020 /* enable precision exception */ +#define FPC_PC 0x0300 /* precision control: */ +#define FPC_PC_24 0x0000 /* 24 bits */ +#define FPC_PC_53 0x0200 /* 53 bits */ +#define FPC_PC_64 0x0300 /* 64 bits */ +#define FPC_RC 0x0c00 /* rounding control: */ +#define FPC_RC_RN 0x0000 /* round to nearest or even */ +#define FPC_RC_RD 0x0400 /* round down */ +#define FPC_RC_RU 0x0800 /* round up */ +#define FPC_RC_CHOP 0x0c00 /* chop */ +#define FPC_IC 0x1000 /* infinity control (obsolete) */ +#define FPC_IC_PROJ 0x0000 /* projective infinity */ +#define FPC_IC_AFF 0x1000 /* affine infinity (std) */ + +/* + * Status register + */ +#define FPS_IE 0x0001 /* invalid operation */ +#define FPS_DE 0x0002 /* denormalized operand */ +#define FPS_ZE 0x0004 /* divide by zero */ +#define FPS_OE 0x0008 /* overflow */ +#define FPS_UE 0x0010 /* underflow */ +#define FPS_PE 0x0020 /* precision */ +#define FPS_SF 0x0040 /* stack flag */ +#define FPS_ES 0x0080 /* error summary */ +#define FPS_C0 0x0100 /* condition code bit 0 */ +#define FPS_C1 0x0200 /* condition code bit 1 */ +#define FPS_C2 0x0400 /* condition code bit 2 */ +#define FPS_TOS 0x3800 /* top-of-stack pointer */ +#define FPS_TOS_SHIFT 11 +#define FPS_C3 0x4000 /* condition code bit 3 */ +#define FPS_BUSY 0x8000 /* FPU busy */ + +/* + * Kind of floating-point support provided by kernel. + */ +#define FP_NO 0 /* no floating point */ +#define FP_SOFT 1 /* software FP emulator */ +#define FP_287 2 /* 80287 */ +#define FP_387 3 /* 80387 or 80486 */ +#define FP_FXSR 4 /* Fast save/restore SIMD Extension */ + +#endif /* _I386_FP_SAVE_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/kern_return.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/kern_return.h new file mode 100644 index 00000000..5caefe8a --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/kern_return.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ + +/* + * File: kern_return.h + * Author: Avadis Tevanian, Jr., Michael Wayne Young + * Date: 1985 + * + * Machine-dependent kernel return definitions. + */ + +#ifndef _MACH_I386_KERN_RETURN_H_ +#define _MACH_I386_KERN_RETURN_H_ + +#ifndef ASSEMBLER +typedef int kern_return_t; +#endif /* ASSEMBLER */ + +#endif /* _MACH_I386_KERN_RETURN_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/ndr_def.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/ndr_def.h new file mode 100644 index 00000000..0e36b2ff --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/ndr_def.h @@ -0,0 +1,45 @@ +/* + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ + +/* NDR record for Intel x86s */ + +#include + +NDR_record_t NDR_record = { + 0, /* mig_reserved */ + 0, /* mig_reserved */ + 0, /* mig_reserved */ + NDR_PROTOCOL_2_0, + NDR_INT_LITTLE_ENDIAN, + NDR_CHAR_ASCII, + NDR_FLOAT_IEEE, + 0, +}; diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/processor_info.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/processor_info.h new file mode 100644 index 00000000..a1930895 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/processor_info.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * File: mach/i386/processor_info.h + * + * Data structure definitions for i386 specific processor control + */ + +#ifndef _MACH_I386_PROCESSOR_INFO_H_ +#define _MACH_I386_PROCESSOR_INFO_H_ + +#endif /* _MACH_I386_PROCESSOR_INFO_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/rpc.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/rpc.h new file mode 100644 index 00000000..396bdea3 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/rpc.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2002,2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ + +#ifndef _MACH_I386_RPC_H_ +#define _MACH_I386_RPC_H_ + +#endif /* _MACH_I386_RPC_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/sdt_isa.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/sdt_isa.h new file mode 100644 index 00000000..e990b852 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/sdt_isa.h @@ -0,0 +1,414 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _MACH_I386_SDT_ISA_H +#define _MACH_I386_SDT_ISA_H + +/* + * Only define when testing. This makes the calls into actual calls to + * test functions. + */ +/* #define DTRACE_CALL_TEST */ + +#define DTRACE_STRINGIFY(s) #s +#define DTRACE_TOSTRING(s) DTRACE_STRINGIFY(s) +#define DTRACE_LABEL(p, n) \ + "__dtrace_probe$" DTRACE_TOSTRING(%=__LINE__) DTRACE_STRINGIFY(_##p##___##n) ":" "\n\t" + +#ifdef DTRACE_CALL_TEST + +#define DTRACE_CALL(p,n) \ + DTRACE_LABEL(p,n) \ + DTRACE_CALL_INSN(p,n) + +#else + +#define DTRACE_CALL(p,n) \ + DTRACE_LABEL(p,n) \ + DTRACE_NOPS + +#endif + +#ifdef __x86_64__ + +#define DTRACE_NOPS \ + "nop" "\n\t" \ + "nop" "\n\t" \ + "nop" "\n\t" + +#define DTRACE_CALL_INSN(p,n) \ + "call _dtracetest" DTRACE_STRINGIFY(_##p##_##n) "\n\t" + +#define ARG1_EXTENT 1 +#define ARGS2_EXTENT 2 +#define ARGS3_EXTENT 3 +#define ARGS4_EXTENT 4 +#define ARGS5_EXTENT 5 +#define ARGS6_EXTENT 6 +#define ARGS7_EXTENT 7 +#define ARGS8_EXTENT 8 +#define ARGS9_EXTENT 9 +#define ARGS10_EXTENT 10 + +#define DTRACE_CALL0ARGS(provider, name) \ + asm volatile ( \ + DTRACE_CALL(provider, name) \ + : \ + : \ + ); + +#define DTRACE_CALL1ARG(provider, name) \ + asm volatile ("movq\t0x0(%0),%%rdi" "\n\t" \ + DTRACE_CALL(provider, name) \ + : \ + : "r" (__dtrace_args) \ + : "memory", "rdi" \ + ); + +#define DTRACE_CALL2ARGS(provider, name) \ + asm volatile ("movq\t0x0(%0),%%rdi" "\n\t" \ + "movq\t0x8(%0),%%rsi" "\n\t" \ + DTRACE_CALL(provider, name) \ + : \ + : "r" (__dtrace_args) \ + : "memory", "rdi", "rsi" \ + ); + +#define DTRACE_CALL3ARGS(provider, name) \ + asm volatile ("movq\t0x0(%0),%%rdi" "\n\t" \ + "movq\t0x8(%0),%%rsi" "\n\t" \ + "movq\t0x10(%0),%%rdx" "\n\t" \ + DTRACE_CALL(provider, name) \ + : \ + : "r" (__dtrace_args) \ + : "memory", "rdi", "rsi", "rdx" \ + ); + +#define DTRACE_CALL4ARGS(provider, name) \ + asm volatile ("movq\t0x0(%0),%%rdi" "\n\t" \ + "movq\t0x8(%0),%%rsi" "\n\t" \ + "movq\t0x10(%0),%%rdx" "\n\t" \ + "movq\t0x18(%0),%%rcx" "\n\t" \ + DTRACE_CALL(provider, name) \ + : \ + : "r" (__dtrace_args) \ + : "memory", "rdi", "rsi", "rdx", "rcx" \ + ); + +#define DTRACE_CALL5ARGS(provider, name) \ + asm volatile ("movq\t0x0(%0),%%rdi" "\n\t" \ + "movq\t0x8(%0),%%rsi" "\n\t" \ + "movq\t0x10(%0),%%rdx" "\n\t" \ + "movq\t0x18(%0),%%rcx" "\n\t" \ + "movq\t0x20(%0),%%r8" "\n\t" \ + DTRACE_CALL(provider, name) \ + : \ + : "r" (__dtrace_args) \ + : "memory", "rdi", "rsi", "rdx", "rcx", "r8" \ + ); + +#define DTRACE_CALL6ARGS(provider, name) \ + asm volatile ("movq\t0x0(%0),%%rdi" "\n\t" \ + "movq\t0x8(%0),%%rsi" "\n\t" \ + "movq\t0x10(%0),%%rdx" "\n\t" \ + "movq\t0x18(%0),%%rcx" "\n\t" \ + "movq\t0x20(%0),%%r8" "\n\t" \ + "movq\t0x28(%0),%%r9" "\n\t" \ + DTRACE_CALL(provider, name) \ + : \ + : "r" (__dtrace_args) \ + : "memory", "rdi", "rsi", "rdx", "rcx", "r8", "r9" \ + ); + +#define DTRACE_CALL7ARGS(provider, name) \ + asm volatile ("subq\t$0x8,%%rsp" "\n\t" \ + "movq\t0x0(%0),%%rdi" "\n\t" \ + "movq\t0x8(%0),%%rsi" "\n\t" \ + "movq\t0x10(%0),%%rdx" "\n\t" \ + "movq\t0x18(%0),%%rcx" "\n\t" \ + "movq\t0x20(%0),%%r8" "\n\t" \ + "movq\t0x28(%0),%%r9" "\n\t" \ + "movq\t0x30(%0),%%rax" "\n\t" \ + "movq\t%%rax,0x0(%%rsp)" "\n\t" \ + DTRACE_CALL(provider, name) \ + "addq\t$0x8,%%rsp" "\n\t" \ + : \ + : "r" (__dtrace_args) \ + : "memory", "rdi", "rsi", "rdx", "rcx", "r8", "r9", "rax" \ + ); + +#endif // __x86_64__ + +#ifdef __i386__ + +#define DTRACE_NOPS \ + "nop" "\n\t" \ + "leal 0(%%esi), %%esi" "\n\t" + +#define DTRACE_CALL_INSN(p,n) \ + "call _dtracetest" DTRACE_STRINGIFY(_##p##_##n) "\n\t" + +#define ARG1_EXTENT 1 +#define ARGS2_EXTENT 2 +#define ARGS3_EXTENT 4 +#define ARGS4_EXTENT 4 +#define ARGS5_EXTENT 8 +#define ARGS6_EXTENT 8 +#define ARGS7_EXTENT 8 +#define ARGS8_EXTENT 8 +#define ARGS9_EXTENT 12 +#define ARGS10_EXTENT 12 + +/* + * Because this code is used in the kernel, we must not touch any floating point + * or specialized registers. This leaves the following registers: + * + * eax ; volatile, safe to use + * ebx ; PIC register, gcc error when used + * ecx ; volatile, safe to use + * edx ; volatile, safe to use + * esi ; non-volatile, otherwise safe to use + * edi ; non-volatile, otherwise safe to use + * + * Using any of the non volatile register causes a spill to stack which is almost + * certainly a net performance loss. Also, note that the array ref (__dtrace_args) + * consumes one free register. If all three of the volatile regs are used for load/store, + * the compiler will spill a register to hold the array ref. + * + * The end result is that we only pipeline two loads/stores at a time. Blech. + */ + +#define DTRACE_CALL0ARGS(provider, name) \ + asm volatile ( \ + DTRACE_CALL(provider, name) \ + "# eat trailing nl +tabfrom DTRACE_CALL" \ + : \ + : \ + ); + +#define DTRACE_CALL1ARG(provider, name) \ + asm volatile ("subl\t$0x10,%%esp" "\n\t" \ + "movl\t0x0(%0),%%eax" "\n\t" \ + "movl\t%%eax,0x0(%%esp)" "\n\t" \ + DTRACE_CALL(provider, name) \ + "addl\t$0x10,%%esp" \ + : \ + : "r" (__dtrace_args) \ + : "memory", "eax" \ + ); + +#define DTRACE_CALL2ARGS(provider, name) \ + asm volatile ("subl\t$0x10,%%esp" "\n\t" \ + "movl\t0x0(%0),%%eax" "\n\t" \ + "movl\t0x4(%0),%%edx" "\n\t" \ + "movl\t%%eax,0x0(%%esp)" "\n\t" \ + "movl\t%%edx,0x4(%%esp)" "\n\t" \ + DTRACE_CALL(provider, name) \ + "addl\t$0x10,%%esp" \ + : \ + : "r" (__dtrace_args) \ + : "memory", "eax", "edx" \ + ); + +#define DTRACE_CALL3ARGS(provider, name) \ + asm volatile ("subl\t$0x10,%%esp" "\n\t" \ + "movl\t0x0(%0),%%eax" "\n\t" \ + "movl\t0x4(%0),%%edx" "\n\t" \ + "movl\t%%eax,0x0(%%esp)" "\n\t" \ + "movl\t%%edx,0x4(%%esp)" "\n\t" \ + "movl\t0x8(%0),%%eax" "\n\t" \ + "movl\t%%eax,0x8(%%esp)" "\n\t" \ + DTRACE_CALL(provider, name) \ + "addl\t$0x10,%%esp" \ + : \ + : "r" (__dtrace_args) \ + : "memory", "eax", "edx" \ + ); + +#define DTRACE_CALL4ARGS(provider, name) \ + asm volatile ("subl\t$0x10,%%esp" "\n\t" \ + "movl\t0x0(%0),%%eax" "\n\t" \ + "movl\t0x4(%0),%%edx" "\n\t" \ + "movl\t%%eax,0x0(%%esp)" "\n\t" \ + "movl\t%%edx,0x4(%%esp)" "\n\t" \ + "movl\t0x8(%0),%%eax" "\n\t" \ + "movl\t0xC(%0),%%edx" "\n\t" \ + "movl\t%%eax,0x8(%%esp)" "\n\t" \ + "movl\t%%edx,0xC(%%esp)" "\n\t" \ + DTRACE_CALL(provider, name) \ + "addl\t$0x10,%%esp" \ + : \ + : "r" (__dtrace_args) \ + : "memory", "eax", "edx" \ + ); + +#define DTRACE_CALL5ARGS(provider, name) \ + asm volatile ("subl\t$0x20,%%esp" "\n\t" \ + "movl\t0x0(%0),%%eax" "\n\t" \ + "movl\t0x4(%0),%%edx" "\n\t" \ + "movl\t%%eax,0x0(%%esp)" "\n\t" \ + "movl\t%%edx,0x4(%%esp)" "\n\t" \ + "movl\t0x8(%0),%%eax" "\n\t" \ + "movl\t0xC(%0),%%edx" "\n\t" \ + "movl\t%%eax,0x8(%%esp)" "\n\t" \ + "movl\t%%edx,0xC(%%esp)" "\n\t" \ + "movl\t0x10(%0),%%eax" "\n\t" \ + "movl\t%%eax,0x10(%%esp)" "\n\t" \ + DTRACE_CALL(provider, name) \ + "addl\t$0x20,%%esp" \ + : \ + : "r" (__dtrace_args) \ + : "memory", "eax", "edx" \ + ); + +#define DTRACE_CALL6ARGS(provider, name) \ + asm volatile ("subl\t$0x20,%%esp" "\n\t" \ + "movl\t0x0(%0),%%eax" "\n\t" \ + "movl\t0x4(%0),%%edx" "\n\t" \ + "movl\t%%eax,0x0(%%esp)" "\n\t" \ + "movl\t%%edx,0x4(%%esp)" "\n\t" \ + "movl\t0x8(%0),%%eax" "\n\t" \ + "movl\t0xC(%0),%%edx" "\n\t" \ + "movl\t%%eax,0x8(%%esp)" "\n\t" \ + "movl\t%%edx,0xC(%%esp)" "\n\t" \ + "movl\t0x10(%0),%%eax" "\n\t" \ + "movl\t0x14(%0),%%edx" "\n\t" \ + "movl\t%%eax,0x10(%%esp)" "\n\t" \ + "movl\t%%edx,0x14(%%esp)" "\n\t" \ + DTRACE_CALL(provider, name) \ + "addl\t$0x20,%%esp" \ + : \ + : "r" (__dtrace_args) \ + : "memory", "eax", "edx" \ + ); + +#define DTRACE_CALL7ARGS(provider, name) \ + asm volatile ("subl\t$0x20,%%esp" "\n\t" \ + "movl\t0x0(%0),%%eax" "\n\t" \ + "movl\t0x4(%0),%%edx" "\n\t" \ + "movl\t%%eax,0x0(%%esp)" "\n\t" \ + "movl\t%%edx,0x4(%%esp)" "\n\t" \ + "movl\t0x8(%0),%%eax" "\n\t" \ + "movl\t0xC(%0),%%edx" "\n\t" \ + "movl\t%%eax,0x8(%%esp)" "\n\t" \ + "movl\t%%edx,0xC(%%esp)" "\n\t" \ + "movl\t0x10(%0),%%eax" "\n\t" \ + "movl\t0x14(%0),%%edx" "\n\t" \ + "movl\t%%eax,0x10(%%esp)" "\n\t" \ + "movl\t%%edx,0x14(%%esp)" "\n\t" \ + "movl\t0x18(%0),%%eax" "\n\t" \ + "movl\t%%eax,0x18(%%esp)" "\n\t" \ + DTRACE_CALL(provider, name) \ + "addl\t$0x20,%%esp" \ + : \ + : "r" (__dtrace_args) \ + : "memory", "eax", "edx" \ + ); + +#define DTRACE_CALL8ARGS(provider, name) \ + asm volatile ("subl\t$0x20,%%esp" "\n\t" \ + "movl\t0x0(%0),%%eax" "\n\t" \ + "movl\t0x4(%0),%%edx" "\n\t" \ + "movl\t%%eax,0x0(%%esp)" "\n\t" \ + "movl\t%%edx,0x4(%%esp)" "\n\t" \ + "movl\t0x8(%0),%%eax" "\n\t" \ + "movl\t0xC(%0),%%edx" "\n\t" \ + "movl\t%%eax,0x8(%%esp)" "\n\t" \ + "movl\t%%edx,0xC(%%esp)" "\n\t" \ + "movl\t0x10(%0),%%eax" "\n\t" \ + "movl\t0x14(%0),%%edx" "\n\t" \ + "movl\t%%eax,0x10(%%esp)" "\n\t" \ + "movl\t%%edx,0x14(%%esp)" "\n\t" \ + "movl\t0x18(%0),%%eax" "\n\t" \ + "movl\t0x1C(%0),%%edx" "\n\t" \ + "movl\t%%eax,0x18(%%esp)" "\n\t" \ + "movl\t%%edx,0x1C(%%esp)" "\n\t" \ + DTRACE_CALL(provider, name) \ + "addl\t$0x20,%%esp" \ + : \ + : "r" (__dtrace_args) \ + : "memory", "eax", "edx" \ + ); + +#define DTRACE_CALL9ARGS(provider, name) \ + asm volatile ("subl\t$0x30,%%esp" "\n\t" \ + "movl\t0x0(%0),%%eax" "\n\t" \ + "movl\t0x4(%0),%%edx" "\n\t" \ + "movl\t%%eax,0x0(%%esp)" "\n\t" \ + "movl\t%%edx,0x4(%%esp)" "\n\t" \ + "movl\t0x8(%0),%%eax" "\n\t" \ + "movl\t0xC(%0),%%edx" "\n\t" \ + "movl\t%%eax,0x8(%%esp)" "\n\t" \ + "movl\t%%edx,0xC(%%esp)" "\n\t" \ + "movl\t0x10(%0),%%eax" "\n\t" \ + "movl\t0x14(%0),%%edx" "\n\t" \ + "movl\t%%eax,0x10(%%esp)" "\n\t" \ + "movl\t%%edx,0x14(%%esp)" "\n\t" \ + "movl\t0x18(%0),%%eax" "\n\t" \ + "movl\t0x1C(%0),%%edx" "\n\t" \ + "movl\t%%eax,0x18(%%esp)" "\n\t" \ + "movl\t%%edx,0x1C(%%esp)" "\n\t" \ + "movl\t0x20(%0),%%eax" "\n\t" \ + "movl\t%%eax,0x20(%%esp)" "\n\t" \ + DTRACE_CALL(provider, name) \ + "addl\t$0x30,%%esp" \ + : \ + : "r" (__dtrace_args) \ + : "memory", "eax", "edx" \ + ); + +#define DTRACE_CALL10ARGS(provider, name) \ + asm volatile ("subl\t$0x30,%%esp" "\n\t" \ + "movl\t0x0(%0),%%eax" "\n\t" \ + "movl\t0x4(%0),%%edx" "\n\t" \ + "movl\t%%eax,0x0(%%esp)" "\n\t" \ + "movl\t%%edx,0x4(%%esp)" "\n\t" \ + "movl\t0x8(%0),%%eax" "\n\t" \ + "movl\t0xC(%0),%%edx" "\n\t" \ + "movl\t%%eax,0x8(%%esp)" "\n\t" \ + "movl\t%%edx,0xC(%%esp)" "\n\t" \ + "movl\t0x10(%0),%%eax" "\n\t" \ + "movl\t0x14(%0),%%edx" "\n\t" \ + "movl\t%%eax,0x10(%%esp)" "\n\t" \ + "movl\t%%edx,0x14(%%esp)" "\n\t" \ + "movl\t0x18(%0),%%eax" "\n\t" \ + "movl\t0x1C(%0),%%edx" "\n\t" \ + "movl\t%%eax,0x18(%%esp)" "\n\t" \ + "movl\t%%edx,0x1C(%%esp)" "\n\t" \ + "movl\t0x20(%0),%%eax" "\n\t" \ + "movl\t0x24(%0),%%edx" "\n\t" \ + "movl\t%%eax,0x20(%%esp)" "\n\t" \ + "movl\t%%edx,0x24(%%esp)" "\n\t" \ + DTRACE_CALL(provider, name) \ + "addl\t$0x30,%%esp" \ + : \ + : "r" (__dtrace_args) \ + : "memory", "eax", "edx" \ + ); + +#endif // __i386__ + +#endif /* _MACH_I386_SDT_ISA_H */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/thread_state.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/thread_state.h new file mode 100644 index 00000000..759489dc --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/thread_state.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ + +#ifndef _MACH_I386_THREAD_STATE_H_ +#define _MACH_I386_THREAD_STATE_H_ + +/* Size of maximum exported thread state in words */ +#define I386_THREAD_STATE_MAX (614) /* Size of biggest state possible */ + +#if defined (__i386__) || defined(__x86_64__) +#define THREAD_STATE_MAX I386_THREAD_STATE_MAX +#endif + +#endif /* _MACH_I386_THREAD_STATE_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/thread_status.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/thread_status.h new file mode 100644 index 00000000..105fe352 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/thread_status.h @@ -0,0 +1,345 @@ +/* + * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * File: thread_status.h + * Author: Avadis Tevanian, Jr. + * Date: 1985 + * + * This file contains the structure definitions for the thread + * state as applied to I386 processors. + */ + +#ifndef _MACH_I386_THREAD_STATUS_H_ +#define _MACH_I386_THREAD_STATUS_H_ + +#include +#include +#include +#include +#include + + +/* + * the i386_xxxx form is kept for legacy purposes since these types + * are externally known... eventually they should be deprecated. + * our internal implementation has moved to the following naming convention + * + * x86_xxxx32 names are used to deal with 32 bit states + * x86_xxxx64 names are used to deal with 64 bit states + * x86_xxxx names are used to deal with either 32 or 64 bit states + * via a self-describing mechanism + */ + +/* + * these are the legacy names which should be deprecated in the future + * they are externally known which is the only reason we don't just get + * rid of them + */ +#define i386_THREAD_STATE 1 +#define i386_FLOAT_STATE 2 +#define i386_EXCEPTION_STATE 3 + +/* + * THREAD_STATE_FLAVOR_LIST 0 + * these are the supported flavors + */ +#define x86_THREAD_STATE32 1 +#define x86_FLOAT_STATE32 2 +#define x86_EXCEPTION_STATE32 3 +#define x86_THREAD_STATE64 4 +#define x86_FLOAT_STATE64 5 +#define x86_EXCEPTION_STATE64 6 +#define x86_THREAD_STATE 7 +#define x86_FLOAT_STATE 8 +#define x86_EXCEPTION_STATE 9 +#define x86_DEBUG_STATE32 10 +#define x86_DEBUG_STATE64 11 +#define x86_DEBUG_STATE 12 +#define THREAD_STATE_NONE 13 +/* 14 and 15 are used for the internal x86_SAVED_STATE flavours */ +/* Arrange for flavors to take sequential values, 32-bit, 64-bit, non-specific */ +#define x86_AVX_STATE32 16 +#define x86_AVX_STATE64 (x86_AVX_STATE32 + 1) +#define x86_AVX_STATE (x86_AVX_STATE32 + 2) +#define x86_AVX512_STATE32 19 +#define x86_AVX512_STATE64 (x86_AVX512_STATE32 + 1) +#define x86_AVX512_STATE (x86_AVX512_STATE32 + 2) +#define x86_PAGEIN_STATE 22 +#define x86_THREAD_FULL_STATE64 23 + +/* + * Largest state on this machine: + * (be sure mach/machine/thread_state.h matches!) + */ +#define THREAD_MACHINE_STATE_MAX THREAD_STATE_MAX + +/* + * VALID_THREAD_STATE_FLAVOR is a platform specific macro that when passed + * an exception flavor will return if that is a defined flavor for that + * platform. The macro must be manually updated to include all of the valid + * exception flavors as defined above. + */ +#define VALID_THREAD_STATE_FLAVOR(x) \ + ((x == x86_THREAD_STATE32) || \ + (x == x86_FLOAT_STATE32) || \ + (x == x86_EXCEPTION_STATE32) || \ + (x == x86_DEBUG_STATE32) || \ + (x == x86_THREAD_STATE64) || \ + (x == x86_THREAD_FULL_STATE64) || \ + (x == x86_FLOAT_STATE64) || \ + (x == x86_EXCEPTION_STATE64) || \ + (x == x86_DEBUG_STATE64) || \ + (x == x86_THREAD_STATE) || \ + (x == x86_FLOAT_STATE) || \ + (x == x86_EXCEPTION_STATE) || \ + (x == x86_DEBUG_STATE) || \ + (x == x86_AVX_STATE32) || \ + (x == x86_AVX_STATE64) || \ + (x == x86_AVX_STATE) || \ + (x == x86_AVX512_STATE32) || \ + (x == x86_AVX512_STATE64) || \ + (x == x86_AVX512_STATE) || \ + (x == x86_PAGEIN_STATE) || \ + (x == THREAD_STATE_NONE)) + +struct x86_state_hdr { + uint32_t flavor; + uint32_t count; +}; +typedef struct x86_state_hdr x86_state_hdr_t; + +/* + * Default segment register values. + */ + +#define USER_CODE_SELECTOR 0x0017 +#define USER_DATA_SELECTOR 0x001f +#define KERN_CODE_SELECTOR 0x0008 +#define KERN_DATA_SELECTOR 0x0010 + +/* + * to be deprecated in the future + */ +typedef _STRUCT_X86_THREAD_STATE32 i386_thread_state_t; +#define i386_THREAD_STATE_COUNT ((mach_msg_type_number_t) \ + ( sizeof (i386_thread_state_t) / sizeof (int) )) + +typedef _STRUCT_X86_THREAD_STATE32 x86_thread_state32_t; +#define x86_THREAD_STATE32_COUNT ((mach_msg_type_number_t) \ + ( sizeof (x86_thread_state32_t) / sizeof (int) )) + +/* + * to be deprecated in the future + */ +typedef _STRUCT_X86_FLOAT_STATE32 i386_float_state_t; +#define i386_FLOAT_STATE_COUNT ((mach_msg_type_number_t) \ + (sizeof(i386_float_state_t)/sizeof(unsigned int))) + +typedef _STRUCT_X86_FLOAT_STATE32 x86_float_state32_t; +#define x86_FLOAT_STATE32_COUNT ((mach_msg_type_number_t) \ + (sizeof(x86_float_state32_t)/sizeof(unsigned int))) + +typedef _STRUCT_X86_AVX_STATE32 x86_avx_state32_t; +#define x86_AVX_STATE32_COUNT ((mach_msg_type_number_t) \ + (sizeof(x86_avx_state32_t)/sizeof(unsigned int))) + +typedef _STRUCT_X86_AVX512_STATE32 x86_avx512_state32_t; +#define x86_AVX512_STATE32_COUNT ((mach_msg_type_number_t) \ + (sizeof(x86_avx512_state32_t)/sizeof(unsigned int))) + +/* + * to be deprecated in the future + */ +typedef _STRUCT_X86_EXCEPTION_STATE32 i386_exception_state_t; +#define i386_EXCEPTION_STATE_COUNT ((mach_msg_type_number_t) \ + ( sizeof (i386_exception_state_t) / sizeof (int) )) + +typedef _STRUCT_X86_EXCEPTION_STATE32 x86_exception_state32_t; +#define x86_EXCEPTION_STATE32_COUNT ((mach_msg_type_number_t) \ + ( sizeof (x86_exception_state32_t) / sizeof (int) )) + +#define I386_EXCEPTION_STATE_COUNT i386_EXCEPTION_STATE_COUNT + +typedef _STRUCT_X86_DEBUG_STATE32 x86_debug_state32_t; +#define x86_DEBUG_STATE32_COUNT ((mach_msg_type_number_t) \ + ( sizeof (x86_debug_state32_t) / sizeof (int) )) + +#define X86_DEBUG_STATE32_COUNT x86_DEBUG_STATE32_COUNT + +typedef _STRUCT_X86_THREAD_STATE64 x86_thread_state64_t; +#define x86_THREAD_STATE64_COUNT ((mach_msg_type_number_t) \ + ( sizeof (x86_thread_state64_t) / sizeof (int) )) + +typedef _STRUCT_X86_THREAD_FULL_STATE64 x86_thread_full_state64_t; +#define x86_THREAD_FULL_STATE64_COUNT ((mach_msg_type_number_t) \ + ( sizeof (x86_thread_full_state64_t) / sizeof (int) )) + +typedef _STRUCT_X86_FLOAT_STATE64 x86_float_state64_t; +#define x86_FLOAT_STATE64_COUNT ((mach_msg_type_number_t) \ + (sizeof(x86_float_state64_t)/sizeof(unsigned int))) + +typedef _STRUCT_X86_AVX_STATE64 x86_avx_state64_t; +#define x86_AVX_STATE64_COUNT ((mach_msg_type_number_t) \ + (sizeof(x86_avx_state64_t)/sizeof(unsigned int))) + +typedef _STRUCT_X86_AVX512_STATE64 x86_avx512_state64_t; +#define x86_AVX512_STATE64_COUNT ((mach_msg_type_number_t) \ + (sizeof(x86_avx512_state64_t)/sizeof(unsigned int))) + +typedef _STRUCT_X86_EXCEPTION_STATE64 x86_exception_state64_t; +#define x86_EXCEPTION_STATE64_COUNT ((mach_msg_type_number_t) \ + ( sizeof (x86_exception_state64_t) / sizeof (int) )) + +#define X86_EXCEPTION_STATE64_COUNT x86_EXCEPTION_STATE64_COUNT + +typedef _STRUCT_X86_DEBUG_STATE64 x86_debug_state64_t; +#define x86_DEBUG_STATE64_COUNT ((mach_msg_type_number_t) \ + ( sizeof (x86_debug_state64_t) / sizeof (int) )) + +#define X86_DEBUG_STATE64_COUNT x86_DEBUG_STATE64_COUNT + +typedef _STRUCT_X86_PAGEIN_STATE x86_pagein_state_t; +#define x86_PAGEIN_STATE_COUNT \ + ((mach_msg_type_number_t)(sizeof(x86_pagein_state_t) / sizeof(int))) + +#define X86_PAGEIN_STATE_COUNT x86_PAGEIN_STATE_COUNT + +/* + * Combined thread, float and exception states + */ +struct x86_thread_state { + x86_state_hdr_t tsh; + union { + x86_thread_state32_t ts32; + x86_thread_state64_t ts64; + } uts; +}; + +struct x86_float_state { + x86_state_hdr_t fsh; + union { + x86_float_state32_t fs32; + x86_float_state64_t fs64; + } ufs; +}; + +struct x86_exception_state { + x86_state_hdr_t esh; + union { + x86_exception_state32_t es32; + x86_exception_state64_t es64; + } ues; +}; + +struct x86_debug_state { + x86_state_hdr_t dsh; + union { + x86_debug_state32_t ds32; + x86_debug_state64_t ds64; + } uds; +}; + +struct x86_avx_state { + x86_state_hdr_t ash; + union { + x86_avx_state32_t as32; + x86_avx_state64_t as64; + } ufs; +}; + +struct x86_avx512_state { + x86_state_hdr_t ash; + union { + x86_avx512_state32_t as32; + x86_avx512_state64_t as64; + } ufs; +}; + +typedef struct x86_thread_state x86_thread_state_t; +#define x86_THREAD_STATE_COUNT ((mach_msg_type_number_t) \ + ( sizeof (x86_thread_state_t) / sizeof (int) )) + +typedef struct x86_float_state x86_float_state_t; +#define x86_FLOAT_STATE_COUNT ((mach_msg_type_number_t) \ + (sizeof(x86_float_state_t)/sizeof(unsigned int))) + +typedef struct x86_exception_state x86_exception_state_t; +#define x86_EXCEPTION_STATE_COUNT ((mach_msg_type_number_t) \ + (sizeof(x86_exception_state_t)/sizeof(unsigned int))) + +typedef struct x86_debug_state x86_debug_state_t; +#define x86_DEBUG_STATE_COUNT ((mach_msg_type_number_t) \ + (sizeof(x86_debug_state_t)/sizeof(unsigned int))) + +typedef struct x86_avx_state x86_avx_state_t; +#define x86_AVX_STATE_COUNT ((mach_msg_type_number_t) \ + (sizeof(x86_avx_state_t)/sizeof(unsigned int))) + +typedef struct x86_avx512_state x86_avx512_state_t; +#define x86_AVX512_STATE_COUNT ((mach_msg_type_number_t) \ + (sizeof(x86_avx512_state_t)/sizeof(unsigned int))) + +/* + * Machine-independent way for servers and Mach's exception mechanism to + * choose the most efficient state flavor for exception RPC's: + */ +#define MACHINE_THREAD_STATE x86_THREAD_STATE +#define MACHINE_THREAD_STATE_COUNT x86_THREAD_STATE_COUNT + + +#endif /* _MACH_I386_THREAD_STATUS_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/vm_param.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/vm_param.h new file mode 100644 index 00000000..fc37cd1d --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/vm_param.h @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2000-2012 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + +/* + * Copyright (c) 1994 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + * + */ + +/* + * File: vm_param.h + * Author: Avadis Tevanian, Jr. + * Date: 1985 + * + * I386 machine dependent virtual memory parameters. + * Most of the declarations are preceeded by I386_ (or i386_) + * which is OK because only I386 specific code will be using + * them. + */ + +#ifndef _MACH_I386_VM_PARAM_H_ +#define _MACH_I386_VM_PARAM_H_ + +#define BYTE_SIZE 8 /* byte size in bits */ + +#define I386_PGBYTES 4096 /* bytes per 80386 page */ +#define I386_PGSHIFT 12 /* bitshift for pages */ + +#define PAGE_SIZE I386_PGBYTES +#define PAGE_SHIFT I386_PGSHIFT +#define PAGE_MASK (PAGE_SIZE - 1) + +#define PAGE_MAX_SHIFT PAGE_SHIFT +#define PAGE_MAX_SIZE PAGE_SIZE +#define PAGE_MAX_MASK PAGE_MASK + +#define PAGE_MIN_SHIFT PAGE_SHIFT +#define PAGE_MIN_SIZE PAGE_SIZE +#define PAGE_MIN_MASK PAGE_MASK + +#define I386_LPGBYTES 2*1024*1024 /* bytes per large page */ +#define I386_LPGSHIFT 21 /* bitshift for large pages */ +#define I386_LPGMASK (I386_LPGBYTES-1) + +/* + * Convert bytes to pages and convert pages to bytes. + * No rounding is used. + */ + +#define i386_btop(x) ((ppnum_t)((x) >> I386_PGSHIFT)) +#define machine_btop(x) i386_btop(x) +#define i386_ptob(x) (((pmap_paddr_t)(x)) << I386_PGSHIFT) +#define machine_ptob(x) i386_ptob(x) + +/* + * Round off or truncate to the nearest page. These will work + * for either addresses or counts. (i.e. 1 byte rounds to 1 page + * bytes. + */ + +#define i386_round_page(x) ((((pmap_paddr_t)(x)) + I386_PGBYTES - 1) & \ + ~(I386_PGBYTES-1)) +#define i386_trunc_page(x) (((pmap_paddr_t)(x)) & ~(I386_PGBYTES-1)) + + + +#define VM_MIN_ADDRESS64 ((user_addr_t) 0x0000000000000000ULL) +/* + * default top of user stack... it grows down from here + */ +#define VM_USRSTACK64 ((user_addr_t) 0x00007FFEEFC00000ULL) + +/* + * XXX TODO: Obsolete? + */ +#define VM_DYLD64 ((user_addr_t) 0x00007FFF5FC00000ULL) +#define VM_LIB64_SHR_DATA ((user_addr_t) 0x00007FFF60000000ULL) +#define VM_LIB64_SHR_TEXT ((user_addr_t) 0x00007FFF80000000ULL) +/* + * the end of the usable user address space , for now about 47 bits. + * the 64 bit commpage is past the end of this + */ +#define VM_MAX_PAGE_ADDRESS ((user_addr_t) 0x00007FFFFFE00000ULL) +/* + * canonical end of user address space for limits checking + */ +#define VM_MAX_USER_PAGE_ADDRESS ((user_addr_t)0x00007FFFFFFFF000ULL) + + +/* system-wide values */ +#define MACH_VM_MIN_ADDRESS ((mach_vm_offset_t) 0) +#define MACH_VM_MAX_ADDRESS ((mach_vm_offset_t) VM_MAX_PAGE_ADDRESS) + +/* process-relative values (all 32-bit legacy only for now) */ +#define VM_MIN_ADDRESS ((vm_offset_t) 0) +#define VM_USRSTACK32 ((vm_offset_t) 0xC0000000) /* ASLR slides stack down by up to 1 MB */ +#define VM_MAX_ADDRESS ((vm_offset_t) 0xFFE00000) + + + +#endif /* _MACH_I386_VM_PARAM_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/vm_types.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/vm_types.h new file mode 100644 index 00000000..f75fd05a --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/i386/vm_types.h @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2000-2016 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ + +/* + * File: vm_types.h + * Author: Avadis Tevanian, Jr. + * Date: 1985 + * + * Header file for VM data types. I386 version. + */ + +#ifndef _MACH_I386_VM_TYPES_H_ +#define _MACH_I386_VM_TYPES_H_ + +#ifndef ASSEMBLER + +#include +#include +#include + +/* + * natural_t and integer_t are Mach's legacy types for machine- + * independent integer types (unsigned, and signed, respectively). + * Their original purpose was to define other types in a machine/ + * compiler independent way. + * + * They also had an implicit "same size as pointer" characteristic + * to them (i.e. Mach's traditional types are very ILP32 or ILP64 + * centric). We support x86 ABIs that do not follow either of + * these models (specifically LP64). Therefore, we had to make a + * choice between making these types scale with pointers or stay + * tied to integers. Because their use is predominantly tied to + * to the size of an integer, we are keeping that association and + * breaking free from pointer size guarantees. + * + * New use of these types is discouraged. + */ +typedef __darwin_natural_t natural_t; +typedef int integer_t; + +/* + * A vm_offset_t is a type-neutral pointer, + * e.g. an offset into a virtual memory space. + */ +#ifdef __LP64__ +typedef uintptr_t vm_offset_t; +#else /* __LP64__ */ +typedef natural_t vm_offset_t; +#endif /* __LP64__ */ + +/* + * A vm_size_t is the proper type for e.g. + * expressing the difference between two + * vm_offset_t entities. + */ +#ifdef __LP64__ +typedef uintptr_t vm_size_t; +#else /* __LP64__ */ +typedef natural_t vm_size_t; +#endif /* __LP64__ */ + +/* + * This new type is independent of a particular vm map's + * implementation size - and represents appropriate types + * for all possible maps. This is used for interfaces + * where the size of the map is not known - or we don't + * want to have to distinguish. + */ +typedef uint64_t mach_vm_address_t; +typedef uint64_t mach_vm_offset_t; +typedef uint64_t mach_vm_size_t; + +typedef uint64_t vm_map_offset_t; +typedef uint64_t vm_map_address_t; +typedef uint64_t vm_map_size_t; + +typedef mach_vm_address_t mach_port_context_t; + + +#endif /* ASSEMBLER */ + +/* + * If composing messages by hand (please do not) + */ +#define MACH_MSG_TYPE_INTEGER_T MACH_MSG_TYPE_INTEGER_32 + +#endif /* _MACH_I386_VM_TYPES_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/kern_return.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/kern_return.h new file mode 100644 index 00000000..cbc29d93 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/kern_return.h @@ -0,0 +1,330 @@ +/* + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * File: h/kern_return.h + * Author: Avadis Tevanian, Jr. + * Date: 1985 + * + * Kernel return codes. + * + */ + +#ifndef _MACH_KERN_RETURN_H_ +#define _MACH_KERN_RETURN_H_ + +#include + +#define KERN_SUCCESS 0 + +#define KERN_INVALID_ADDRESS 1 +/* Specified address is not currently valid. + */ + +#define KERN_PROTECTION_FAILURE 2 +/* Specified memory is valid, but does not permit the + * required forms of access. + */ + +#define KERN_NO_SPACE 3 +/* The address range specified is already in use, or + * no address range of the size specified could be + * found. + */ + +#define KERN_INVALID_ARGUMENT 4 +/* The function requested was not applicable to this + * type of argument, or an argument is invalid + */ + +#define KERN_FAILURE 5 +/* The function could not be performed. A catch-all. + */ + +#define KERN_RESOURCE_SHORTAGE 6 +/* A system resource could not be allocated to fulfill + * this request. This failure may not be permanent. + */ + +#define KERN_NOT_RECEIVER 7 +/* The task in question does not hold receive rights + * for the port argument. + */ + +#define KERN_NO_ACCESS 8 +/* Bogus access restriction. + */ + +#define KERN_MEMORY_FAILURE 9 +/* During a page fault, the target address refers to a + * memory object that has been destroyed. This + * failure is permanent. + */ + +#define KERN_MEMORY_ERROR 10 +/* During a page fault, the memory object indicated + * that the data could not be returned. This failure + * may be temporary; future attempts to access this + * same data may succeed, as defined by the memory + * object. + */ + +#define KERN_ALREADY_IN_SET 11 +/* The receive right is already a member of the portset. + */ + +#define KERN_NOT_IN_SET 12 +/* The receive right is not a member of a port set. + */ + +#define KERN_NAME_EXISTS 13 +/* The name already denotes a right in the task. + */ + +#define KERN_ABORTED 14 +/* The operation was aborted. Ipc code will + * catch this and reflect it as a message error. + */ + +#define KERN_INVALID_NAME 15 +/* The name doesn't denote a right in the task. + */ + +#define KERN_INVALID_TASK 16 +/* Target task isn't an active task. + */ + +#define KERN_INVALID_RIGHT 17 +/* The name denotes a right, but not an appropriate right. + */ + +#define KERN_INVALID_VALUE 18 +/* A blatant range error. + */ + +#define KERN_UREFS_OVERFLOW 19 +/* Operation would overflow limit on user-references. + */ + +#define KERN_INVALID_CAPABILITY 20 +/* The supplied (port) capability is improper. + */ + +#define KERN_RIGHT_EXISTS 21 +/* The task already has send or receive rights + * for the port under another name. + */ + +#define KERN_INVALID_HOST 22 +/* Target host isn't actually a host. + */ + +#define KERN_MEMORY_PRESENT 23 +/* An attempt was made to supply "precious" data + * for memory that is already present in a + * memory object. + */ + +#define KERN_MEMORY_DATA_MOVED 24 +/* A page was requested of a memory manager via + * memory_object_data_request for an object using + * a MEMORY_OBJECT_COPY_CALL strategy, with the + * VM_PROT_WANTS_COPY flag being used to specify + * that the page desired is for a copy of the + * object, and the memory manager has detected + * the page was pushed into a copy of the object + * while the kernel was walking the shadow chain + * from the copy to the object. This error code + * is delivered via memory_object_data_error + * and is handled by the kernel (it forces the + * kernel to restart the fault). It will not be + * seen by users. + */ + +#define KERN_MEMORY_RESTART_COPY 25 +/* A strategic copy was attempted of an object + * upon which a quicker copy is now possible. + * The caller should retry the copy using + * vm_object_copy_quickly. This error code + * is seen only by the kernel. + */ + +#define KERN_INVALID_PROCESSOR_SET 26 +/* An argument applied to assert processor set privilege + * was not a processor set control port. + */ + +#define KERN_POLICY_LIMIT 27 +/* The specified scheduling attributes exceed the thread's + * limits. + */ + +#define KERN_INVALID_POLICY 28 +/* The specified scheduling policy is not currently + * enabled for the processor set. + */ + +#define KERN_INVALID_OBJECT 29 +/* The external memory manager failed to initialize the + * memory object. + */ + +#define KERN_ALREADY_WAITING 30 +/* A thread is attempting to wait for an event for which + * there is already a waiting thread. + */ + +#define KERN_DEFAULT_SET 31 +/* An attempt was made to destroy the default processor + * set. + */ + +#define KERN_EXCEPTION_PROTECTED 32 +/* An attempt was made to fetch an exception port that is + * protected, or to abort a thread while processing a + * protected exception. + */ + +#define KERN_INVALID_LEDGER 33 +/* A ledger was required but not supplied. + */ + +#define KERN_INVALID_MEMORY_CONTROL 34 +/* The port was not a memory cache control port. + */ + +#define KERN_INVALID_SECURITY 35 +/* An argument supplied to assert security privilege + * was not a host security port. + */ + +#define KERN_NOT_DEPRESSED 36 +/* thread_depress_abort was called on a thread which + * was not currently depressed. + */ + +#define KERN_TERMINATED 37 +/* Object has been terminated and is no longer available + */ + +#define KERN_LOCK_SET_DESTROYED 38 +/* Lock set has been destroyed and is no longer available. + */ + +#define KERN_LOCK_UNSTABLE 39 +/* The thread holding the lock terminated before releasing + * the lock + */ + +#define KERN_LOCK_OWNED 40 +/* The lock is already owned by another thread + */ + +#define KERN_LOCK_OWNED_SELF 41 +/* The lock is already owned by the calling thread + */ + +#define KERN_SEMAPHORE_DESTROYED 42 +/* Semaphore has been destroyed and is no longer available. + */ + +#define KERN_RPC_SERVER_TERMINATED 43 +/* Return from RPC indicating the target server was + * terminated before it successfully replied + */ + +#define KERN_RPC_TERMINATE_ORPHAN 44 +/* Terminate an orphaned activation. + */ + +#define KERN_RPC_CONTINUE_ORPHAN 45 +/* Allow an orphaned activation to continue executing. + */ + +#define KERN_NOT_SUPPORTED 46 +/* Empty thread activation (No thread linked to it) + */ + +#define KERN_NODE_DOWN 47 +/* Remote node down or inaccessible. + */ + +#define KERN_NOT_WAITING 48 +/* A signalled thread was not actually waiting. */ + +#define KERN_OPERATION_TIMED_OUT 49 +/* Some thread-oriented operation (semaphore_wait) timed out + */ + +#define KERN_CODESIGN_ERROR 50 +/* During a page fault, indicates that the page was rejected + * as a result of a signature check. + */ + +#define KERN_POLICY_STATIC 51 +/* The requested property cannot be changed at this time. + */ + +#define KERN_INSUFFICIENT_BUFFER_SIZE 52 +/* The provided buffer is of insufficient size for the requested data. + */ + +#define KERN_RETURN_MAX 0x100 +/* Maximum return value allowable + */ + +#endif /* _MACH_KERN_RETURN_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/kmod.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/kmod.h new file mode 100644 index 00000000..d23086b5 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/kmod.h @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2000-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce + * support for mandatory and extensible security protections. This notice + * is included in support of clause 2.2 (b) of the Apple Public License, + * Version 2.0. + */ + +#ifndef _MACH_KMOD_H_ +#define _MACH_KMOD_H_ + +#include +#include + +#include + +__BEGIN_DECLS + +#if PRAGMA_MARK +#pragma mark Basic macros & typedefs +#endif +/*********************************************************************** +* Basic macros & typedefs +***********************************************************************/ +#define KMOD_MAX_NAME 64 + +#define KMOD_RETURN_SUCCESS KERN_SUCCESS +#define KMOD_RETURN_FAILURE KERN_FAILURE + +typedef int kmod_t; + +struct kmod_info; +typedef kern_return_t kmod_start_func_t(struct kmod_info * ki, void * data); +typedef kern_return_t kmod_stop_func_t(struct kmod_info * ki, void * data); + +#if PRAGMA_MARK +#pragma mark Structure definitions +#endif +/*********************************************************************** +* Structure definitions +* +* All structures must be #pragma pack(4). +***********************************************************************/ +#pragma pack(push, 4) + +/* Run-time struct only; never saved to a file */ +typedef struct kmod_reference { + struct kmod_reference * next; + struct kmod_info * info; +} kmod_reference_t; + +/*********************************************************************** +* Warning: Any changes to the kmod_info structure affect the +* KMOD_..._DECL macros below. +***********************************************************************/ + +/* The kmod_info_t structure is only safe to use inside the running + * kernel. If you need to work with a kmod_info_t structure outside + * the kernel, please use the compatibility definitions below. + */ +typedef struct kmod_info { + struct kmod_info * next; + int32_t info_version; // version of this structure + uint32_t id; + char name[KMOD_MAX_NAME]; + char version[KMOD_MAX_NAME]; + int32_t reference_count; // # linkage refs to this + kmod_reference_t * reference_list; // who this refs (links on) + vm_address_t address; // starting address + vm_size_t size; // total size + vm_size_t hdr_size; // unwired hdr size + kmod_start_func_t * start; + kmod_stop_func_t * stop; +} kmod_info_t; + +/* A compatibility definition of kmod_info_t for 32-bit kexts. + */ +typedef struct kmod_info_32_v1 { + uint32_t next_addr; + int32_t info_version; + uint32_t id; + uint8_t name[KMOD_MAX_NAME]; + uint8_t version[KMOD_MAX_NAME]; + int32_t reference_count; + uint32_t reference_list_addr; + uint32_t address; + uint32_t size; + uint32_t hdr_size; + uint32_t start_addr; + uint32_t stop_addr; +} kmod_info_32_v1_t; + +/* A compatibility definition of kmod_info_t for 64-bit kexts. + */ +typedef struct kmod_info_64_v1 { + uint64_t next_addr; + int32_t info_version; + uint32_t id; + uint8_t name[KMOD_MAX_NAME]; + uint8_t version[KMOD_MAX_NAME]; + int32_t reference_count; + uint64_t reference_list_addr; + uint64_t address; + uint64_t size; + uint64_t hdr_size; + uint64_t start_addr; + uint64_t stop_addr; +} kmod_info_64_v1_t; + +#pragma pack(pop) + +#if PRAGMA_MARK +#pragma mark Kmod structure declaration macros +#endif +/*********************************************************************** +* Kmod structure declaration macros +***********************************************************************/ +#define KMOD_INFO_NAME kmod_info +#define KMOD_INFO_VERSION 1 + +#define KMOD_DECL(name, version) \ + static kmod_start_func_t name ## _module_start; \ + static kmod_stop_func_t name ## _module_stop; \ + kmod_info_t KMOD_INFO_NAME = { 0, KMOD_INFO_VERSION, -1U, \ + { #name }, { version }, -1, 0, 0, 0, 0, \ + name ## _module_start, \ + name ## _module_stop }; + +#define KMOD_EXPLICIT_DECL(name, version, start, stop) \ + kmod_info_t KMOD_INFO_NAME = { 0, KMOD_INFO_VERSION, -1U, \ + { #name }, { version }, -1, 0, 0, 0, 0, \ + start, stop }; + +#if PRAGMA_MARK +#pragma mark Kernel private declarations +#endif +/*********************************************************************** +* Kernel private declarations. +***********************************************************************/ + + +#if PRAGMA_MARK +#pragma mark Obsolete kmod stuff +#endif +/*********************************************************************** +* These 3 should be dropped but they're referenced by MIG declarations. +***********************************************************************/ +typedef void * kmod_args_t; +typedef int kmod_control_flavor_t; +typedef kmod_info_t * kmod_info_array_t; + +__END_DECLS + +#endif /* _MACH_KMOD_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/lock_set.defs b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/lock_set.defs new file mode 100644 index 00000000..d4cb9abb --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/lock_set.defs @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + * + */ +/* + * File: mach/lock_set.defs + * Author: Joseph CaraDonna + * + * Exported kernel calls + * + */ + +subsystem +#if KERNEL_SERVER + KernelServer +#endif /* KERNEL_SERVER */ + lock_set 617000; + +#include +#include + +/* + * OBSOLETE interfaces + * a lock_set_t is created and destroyed through the task object. + * lock_set_create(task,&lock_set_t,...); + * lock_set_destroy(task,lock_set_t); + */ + +/* + * OBSOLETE interfaces + */ +routine lock_acquire( + lock_set : lock_set_t; + lock_id : int); + +routine lock_release( + lock_set : lock_set_t; + lock_id : int); + +routine lock_try( + lock_set : lock_set_t; + lock_id : int); + +routine lock_make_stable( + lock_set : lock_set_t; + lock_id : int); + +routine lock_handoff( + lock_set : lock_set_t; + lock_id : int); + +routine lock_handoff_accept( + lock_set : lock_set_t; + lock_id : int); + +/* vim: set ft=c : */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/lock_set.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/lock_set.h new file mode 100644 index 00000000..e4dcf8a8 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/lock_set.h @@ -0,0 +1,350 @@ +#ifndef _lock_set_user_ +#define _lock_set_user_ + +/* Module lock_set */ + +#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 lock_set_MSG_COUNT +#define lock_set_MSG_COUNT 6 +#endif /* lock_set_MSG_COUNT */ + +#include +#include +#include +#include + +#ifdef __BeforeMigUserHeader +__BeforeMigUserHeader +#endif /* __BeforeMigUserHeader */ + +#include +__BEGIN_DECLS + + +/* Routine lock_acquire */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t lock_acquire +( + lock_set_t lock_set, + int lock_id +); + +/* Routine lock_release */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t lock_release +( + lock_set_t lock_set, + int lock_id +); + +/* Routine lock_try */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t lock_try +( + lock_set_t lock_set, + int lock_id +); + +/* Routine lock_make_stable */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t lock_make_stable +( + lock_set_t lock_set, + int lock_id +); + +/* Routine lock_handoff */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t lock_handoff +( + lock_set_t lock_set, + int lock_id +); + +/* Routine lock_handoff_accept */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t lock_handoff_accept +( + lock_set_t lock_set, + int lock_id +); + +__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__lock_set_subsystem__defined +#define __Request__lock_set_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int lock_id; + } __Request__lock_acquire_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int lock_id; + } __Request__lock_release_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int lock_id; + } __Request__lock_try_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int lock_id; + } __Request__lock_make_stable_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int lock_id; + } __Request__lock_handoff_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int lock_id; + } __Request__lock_handoff_accept_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Request__lock_set_subsystem__defined */ + +/* union of all requests */ + +#ifndef __RequestUnion__lock_set_subsystem__defined +#define __RequestUnion__lock_set_subsystem__defined +union __RequestUnion__lock_set_subsystem { + __Request__lock_acquire_t Request_lock_acquire; + __Request__lock_release_t Request_lock_release; + __Request__lock_try_t Request_lock_try; + __Request__lock_make_stable_t Request_lock_make_stable; + __Request__lock_handoff_t Request_lock_handoff; + __Request__lock_handoff_accept_t Request_lock_handoff_accept; +}; +#endif /* !__RequestUnion__lock_set_subsystem__defined */ +/* typedefs for all replies */ + +#ifndef __Reply__lock_set_subsystem__defined +#define __Reply__lock_set_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__lock_acquire_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__lock_release_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__lock_try_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__lock_make_stable_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__lock_handoff_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__lock_handoff_accept_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Reply__lock_set_subsystem__defined */ + +/* union of all replies */ + +#ifndef __ReplyUnion__lock_set_subsystem__defined +#define __ReplyUnion__lock_set_subsystem__defined +union __ReplyUnion__lock_set_subsystem { + __Reply__lock_acquire_t Reply_lock_acquire; + __Reply__lock_release_t Reply_lock_release; + __Reply__lock_try_t Reply_lock_try; + __Reply__lock_make_stable_t Reply_lock_make_stable; + __Reply__lock_handoff_t Reply_lock_handoff; + __Reply__lock_handoff_accept_t Reply_lock_handoff_accept; +}; +#endif /* !__RequestUnion__lock_set_subsystem__defined */ + +#ifndef subsystem_to_name_map_lock_set +#define subsystem_to_name_map_lock_set \ + { "lock_acquire", 617000 },\ + { "lock_release", 617001 },\ + { "lock_try", 617002 },\ + { "lock_make_stable", 617003 },\ + { "lock_handoff", 617004 },\ + { "lock_handoff_accept", 617005 } +#endif + +#ifdef __AfterMigUserHeader +__AfterMigUserHeader +#endif /* __AfterMigUserHeader */ + +#endif /* _lock_set_user_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach.h new file mode 100644 index 00000000..9ebf5c8c --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach.h @@ -0,0 +1,245 @@ +/* + * Copyright (c) 1999-2014 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + +/* + * Includes all the types that a normal user + * of Mach programs should need + */ + +#ifndef _MACH_H_ +#define _MACH_H_ + +#define __MACH30__ +#define MACH_IPC_FLAVOR UNTYPED + +#include +#include +#include +#include +#include +#include +#include + +#include /* for compatibility only */ +#include + +#include +#include + +#include + +__BEGIN_DECLS +/* + * Standard prototypes + */ +extern void panic_init(mach_port_t); +extern void panic(const char *, ...); + +extern void safe_gets(char *, + char *, + int); + +extern void slot_name(cpu_type_t, + cpu_subtype_t, + char **, + char **); + +extern void mig_reply_setup(mach_msg_header_t *, + mach_msg_header_t *); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED +extern void mach_msg_destroy(mach_msg_header_t *); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED +extern mach_msg_return_t mach_msg_receive(mach_msg_header_t *); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED +extern mach_msg_return_t mach_msg_send(mach_msg_header_t *); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED +extern mach_msg_return_t mach_msg_server_once(boolean_t (*) + (mach_msg_header_t *, + mach_msg_header_t *), + mach_msg_size_t, + mach_port_t, + mach_msg_options_t); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED +extern mach_msg_return_t mach_msg_server(boolean_t (*) + (mach_msg_header_t *, + mach_msg_header_t *), + mach_msg_size_t, + mach_port_t, + mach_msg_options_t); + +__WATCHOS_PROHIBITED __TVOS_PROHIBITED +extern mach_msg_return_t mach_msg_server_importance(boolean_t (*) + (mach_msg_header_t *, + mach_msg_header_t *), + mach_msg_size_t, + mach_port_t, + mach_msg_options_t); + +/* + * Prototypes for compatibility + */ +extern kern_return_t clock_get_res(mach_port_t, + clock_res_t *); +extern kern_return_t clock_set_res(mach_port_t, + clock_res_t); + +extern kern_return_t clock_sleep(mach_port_t, + int, + mach_timespec_t, + mach_timespec_t *); + +/*! + * @group voucher_mach_msg Prototypes + */ + +#define VOUCHER_MACH_MSG_API_VERSION 20140205 + +/*! + * @typedef voucher_mach_msg_state_t + * + * @abstract + * Opaque object encapsulating state changed by voucher_mach_msg_adopt(). + */ +typedef struct voucher_mach_msg_state_s *voucher_mach_msg_state_t; + +/*! + * @const VOUCHER_MACH_MSG_STATE_UNCHANGED + * + * @discussion + * Constant indicating no state change occurred. + */ +#define VOUCHER_MACH_MSG_STATE_UNCHANGED ((voucher_mach_msg_state_t)~0ul) + +/*! + * @function voucher_mach_msg_set + * + * @abstract + * Change specified message header to contain current mach voucher with a + * COPY_SEND disposition. + * Does not change message if it already has non-zero MACH_MSGH_BITS_VOUCHER. + * + * @discussion + * Borrows reference to current thread voucher so message should be sent + * immediately (without intervening calls that might change that voucher). + * + * @param msg + * The message to modify. + * + * @result + * True if header was changed. + */ +extern boolean_t voucher_mach_msg_set(mach_msg_header_t *msg); + +/*! + * @function voucher_mach_msg_clear + * + * @abstract + * Removes changes made to specified message header by voucher_mach_msg_set() + * and any mach_msg() send operations (successful or not). + * If the message is not needed further, mach_msg_destroy() should be called + * instead. + * + * @discussion + * Not intended to be called if voucher_mach_msg_set() returned false. + * Releases reference to message mach voucher if an extra reference was + * acquired due to an unsuccessful send operation (pseudo-receive). + * + * @param msg + * The message to modify. + */ +extern void voucher_mach_msg_clear(mach_msg_header_t *msg); + +/*! + * @function voucher_mach_msg_adopt + * + * @abstract + * Adopt the voucher contained in the specified message on the current thread + * and return the previous thread voucher state. + * + * @discussion + * Ownership of the mach voucher in the message is transferred to the current + * thread and the message header voucher fields are cleared. + * + * @param msg + * The message to query and modify. + * + * @result + * The previous thread voucher state or VOUCHER_MACH_MSG_STATE_UNCHANGED if no + * state change occurred. + */ +extern voucher_mach_msg_state_t voucher_mach_msg_adopt(mach_msg_header_t *msg); + +/*! + * @function voucher_mach_msg_revert + * + * @abstract + * Restore thread voucher state previously modified by voucher_mach_msg_adopt(). + * + * @discussion + * Current thread voucher reference is released. + * No change to thread voucher state if passed VOUCHER_MACH_MSG_STATE_UNCHANGED. + * + * @param state + * The thread voucher state to restore. + */ + +extern void voucher_mach_msg_revert(voucher_mach_msg_state_t state); + +__END_DECLS + +#endif /* _MACH_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_error.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_error.h new file mode 100644 index 00000000..538b5cb1 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_error.h @@ -0,0 +1,93 @@ +/* + * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + */ + +/* + * File: mach_error.h + * Author: Douglas Orr, Carnegie Mellon University + * Date: Mar. 1988 + * + * Definitions of routines in mach_error.c + */ + +#ifndef _MACH_ERROR_ +#define _MACH_ERROR_ 1 + +#include + +#include + +__BEGIN_DECLS +char *mach_error_string( +/* + * Returns a string appropriate to the error argument given + */ + mach_error_t error_value + ); + +void mach_error( +/* + * Prints an appropriate message on the standard error stream + */ + const char *str, + mach_error_t error_value + ); + +char *mach_error_type( +/* + * Returns a string with the error system, subsystem and code + */ + mach_error_t error_value + ); +__END_DECLS + +#endif /* _MACH_ERROR_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_exc.defs b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_exc.defs new file mode 100644 index 00000000..5ce6427b --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_exc.defs @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * Abstract: + * MiG definitions file for Mach exception interface. + */ + +subsystem +#if KERNEL_USER + KernelUser +#endif +#if KERNEL_SERVER + KernelServer +#endif /* KERNEL_SERVER */ + + mach_exc 2405; + +#include +#include + +ServerPrefix catch_; + +type mach_exception_data_t = array[*:2] of int64_t; +type exception_type_t = int; + +routine mach_exception_raise( + exception_port : mach_port_t; + thread : mach_port_t; + task : mach_port_t; + exception : exception_type_t; + code : mach_exception_data_t +#if MACH_EXC_SERVER_SECTOKEN + ; + ServerSecToken stoken : security_token_t +#endif +#if MACH_EXC_SERVER_AUDITTOKEN + ; + ServerAuditToken atoken: audit_token_t +#endif + ); + +routine mach_exception_raise_state( + exception_port : mach_port_t; + exception : exception_type_t; + code : mach_exception_data_t, const; + inout flavor : int; + old_state : thread_state_t, const; + out new_state : thread_state_t +#if MACH_EXC_SERVER_SECTOKEN + ; + ServerSecToken stoken : security_token_t +#endif +#if MACH_EXC_SERVER_AUDITTOKEN + ; + ServerAuditToken atoken: audit_token_t +#endif + ); + +routine mach_exception_raise_state_identity( + exception_port : mach_port_t; + thread : mach_port_t; + task : mach_port_t; + exception : exception_type_t; + code : mach_exception_data_t; + inout flavor : int; + old_state : thread_state_t; + out new_state : thread_state_t +#if MACH_EXC_SERVER_SECTOKEN + ; + ServerSecToken stoken : security_token_t +#endif +#if MACH_EXC_SERVER_AUDITTOKEN + ; + ServerAuditToken atoken: audit_token_t +#endif + ); + +/* vim: set ft=c : */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_host.defs b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_host.defs new file mode 100644 index 00000000..a22918ef --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_host.defs @@ -0,0 +1,357 @@ +/* + * Copyright (c) 2000-2009 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ + +/* + * File: mach/mach_host.defs + * + * Abstract: + * Mach host operations support. Includes processor allocation and + * control. + */ + +subsystem +#if KERNEL_SERVER + KernelServer +#endif /* KERNEL_SERVER */ + mach_host 200; + +/* + * Basic types + */ + +#include +#include +#include +#include + +/* + * References to host objects are returned by: + * mach_host_self() - trap + */ + +/* + * Return information about this host. + */ +routine host_info( + host : host_t; + flavor : host_flavor_t; + out host_info_out : host_info_t, CountInOut); + +/* + * Get string describing current kernel version. + */ +routine host_kernel_version( + host : host_t; + out kernel_version : kernel_version_t); + +/* + * Get host page size + * (compatibility for running old libraries on new kernels - + * host_page_size() is now a library routine based on constants) + */ +routine _host_page_size( + host : host_t; + out out_page_size : vm_size_t); + +/* + * Allow pagers to create named entries that point to un-mapped + * abstract memory object. The named entries are generally mappable + * and can be subsetted through the mach_make_memory_entry call + */ +routine mach_memory_object_memory_entry( + host :host_t; + internal :boolean_t; + size :vm_size_t; + permission :vm_prot_t; + pager :memory_object_t; + out entry_handle :mach_port_move_send_t); + + +/* + * Get processor info for all the processors on this host. + * The returned data is an OOL array of processor info. + */ +routine host_processor_info( + host : host_t; + flavor : processor_flavor_t; + out out_processor_count : natural_t; + out out_processor_info : processor_info_array_t); + +/* + * Return host IO master access port + */ +routine host_get_io_master( + host : host_t; + out io_master : io_master_t); + +/* + * Get service port for a processor set. + * Available to all. + */ +routine host_get_clock_service( + host : host_t; + clock_id : clock_id_t; + out clock_serv : clock_serv_t); + +/* + * kernel module interface (obsolete as of SnowLeopard) + * see mach/kmod.h + */ +/* kmod_ MIG calls now return KERN_NOT_SUPPORTED on PPC/i386/x86_64. */ +routine kmod_get_info( + host : host_t; + out modules : kmod_args_t); + + +skip; /* was host_zone_info */ + +/* + * Returns information about the global VP table. + * Only supported in MACH_VM_DEBUG kernels, + * otherwise returns KERN_FAILURE. + */ +routine host_virtual_physical_table_info( + host : host_t; + out info : hash_info_bucket_array_t, + Dealloc); + + +skip; /* was host_ipc_hash_info */ +skip; /* was enable_bluebox */ +skip; /* was disable_bluebox */ + +/* + * JMM - Keep processor_set related items at the end for easy + * removal. + */ +/* + * Get default processor set for host. + */ +routine processor_set_default( + host : host_t; + out default_set : processor_set_name_t); + +/* + * Create new processor set. Returns real port for manipulations, + * and name port for obtaining information. + */ +routine processor_set_create( + host : host_t; + out new_set : processor_set_t; + out new_name : processor_set_name_t); + +/* + * Temporary interfaces for conversion to 64 bit data path + */ + +routine mach_memory_object_memory_entry_64( + host :host_t; + internal :boolean_t; + size :memory_object_size_t; + permission :vm_prot_t; + pager :memory_object_t; + out entry_handle :mach_port_move_send_t); + +/* + * Return statistics from this host. + */ +routine +#ifdef KERNEL_SERVER +host_statistics_from_user( +#else +host_statistics( +#endif + host_priv : host_t; + flavor : host_flavor_t; + out host_info_out : host_info_t, CountInOut); + +routine host_request_notification( + host : host_t; + notify_type : host_flavor_t; + notify_port : mach_port_make_send_once_t); + +routine host_lockgroup_info( + host : host_t; + out lockgroup_info : lockgroup_info_array_t, + Dealloc); + +/* + * Return 64-bit statistics from this host. + */ +routine +#ifdef KERNEL_SERVER +host_statistics64_from_user( +#else +host_statistics64( +#endif + host_priv : host_t; + flavor : host_flavor_t; + out host_info64_out : host_info64_t, CountInOut); + +/* + * Returns information about the memory allocation zones. + * Data returned is compatible with various caller and kernel + * address space sizes. + */ +routine mach_zone_info( + host : host_priv_t; + out names : mach_zone_name_array_t, + Dealloc; + out info : mach_zone_info_array_t, + Dealloc); + +skip; + +/* + * Create a new voucher by running a series of commands against + * pairs of resource attributes. + */ +#if !KERNEL && !LIBSYSCALL_INTERFACE +routine _kernelrpc_host_create_mach_voucher( +#else +routine host_create_mach_voucher( +#endif + host : host_t; + recipes : mach_voucher_attr_raw_recipe_array_t; + out voucher : ipc_voucher_t); + +/* + * Register a resource manager with the kernel. A new key is selected. + */ +routine host_register_mach_voucher_attr_manager( + host : host_t; + attr_manager : mach_voucher_attr_manager_t; + default_value : mach_voucher_attr_value_handle_t; + out new_key : mach_voucher_attr_key_t; + out new_attr_control: ipc_voucher_attr_control_t); + +/* + * Register a resource manager (with a well-known key value) with the kernel. + */ +routine host_register_well_known_mach_voucher_attr_manager( + host : host_t; + attr_manager : mach_voucher_attr_manager_t; + default_value : mach_voucher_attr_value_handle_t; + key : mach_voucher_attr_key_t; + out new_attr_control: ipc_voucher_attr_control_t); + + +/* + * Update the global ATM diagnostic flag, readable from the commpage + */ +routine host_set_atm_diagnostic_flag( + host : host_t; + in diagnostic_flag : uint32_t); + +#if !KERNEL && LIBSYSCALL_INTERFACE +routine host_get_atm_diagnostic_flag( + host : host_t; + out diagnostic_flag : uint32_t); +#else +skip; +#endif + +routine mach_memory_info( + host : host_priv_t; + out names : mach_zone_name_array_t, + Dealloc; + out info : mach_zone_info_array_t, + Dealloc; + out memory_info : mach_memory_info_array_t, + Dealloc); + +/* + * Update the global multiuser flags, readable from the commpage + */ +routine host_set_multiuser_config_flags( + host_priv : host_priv_t; + in multiuser_flags : uint32_t); + +#if !KERNEL && LIBSYSCALL_INTERFACE +routine host_get_multiuser_config_flags( + host : host_t; + out multiuser_flags : uint32_t); +#else +skip; +#endif // !KERNEL && LIBSYSCALL_INTERFACE + +#if !KERNEL && LIBSYSCALL_INTERFACE +routine host_check_multiuser_mode( + host : host_t; + out multiuser_mode : uint32_t); +#else +skip; +#endif // !KERNEL && LIBSYSCALL_INTERFACE + +/* + * Returns information about a specific zone. + * The zone name is passed in via the argument name, + * info returns the zone info. + */ +routine mach_zone_info_for_zone( + host : host_priv_t; + name : mach_zone_name_t; + out info : mach_zone_info_t); + +skip; + +skip; + +skip; + +/* vim: set ft=c : */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_host.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_host.h new file mode 100644 index 00000000..41c68050 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_host.h @@ -0,0 +1,1295 @@ +#ifndef _mach_host_user_ +#define _mach_host_user_ + +/* Module mach_host */ + +#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_host_MSG_COUNT +#define mach_host_MSG_COUNT 35 +#endif /* mach_host_MSG_COUNT */ + +#include +#include +#include +#include +#include +#include +#include + +#ifdef __BeforeMigUserHeader +__BeforeMigUserHeader +#endif /* __BeforeMigUserHeader */ + +#include +__BEGIN_DECLS + + +/* Routine host_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t host_info +( + host_t host, + host_flavor_t flavor, + host_info_t host_info_out, + mach_msg_type_number_t *host_info_outCnt +); + +/* Routine host_kernel_version */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_kernel_version +( + host_t host, + kernel_version_t kernel_version +); + +/* Routine _host_page_size */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t _host_page_size +( + host_t host, + vm_size_t *out_page_size +); + +/* Routine mach_memory_object_memory_entry */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_memory_object_memory_entry +( + host_t host, + boolean_t internal, + vm_size_t size, + vm_prot_t permission, + memory_object_t pager, + mach_port_t *entry_handle +); + +/* Routine host_processor_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_processor_info +( + host_t host, + processor_flavor_t flavor, + natural_t *out_processor_count, + processor_info_array_t *out_processor_info, + mach_msg_type_number_t *out_processor_infoCnt +); + +/* Routine host_get_io_master */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_get_io_master +( + host_t host, + io_master_t *io_master +); + +/* Routine host_get_clock_service */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_get_clock_service +( + host_t host, + clock_id_t clock_id, + clock_serv_t *clock_serv +); + +/* Routine kmod_get_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t kmod_get_info +( + host_t host, + kmod_args_t *modules, + mach_msg_type_number_t *modulesCnt +); + +/* Routine host_virtual_physical_table_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_virtual_physical_table_info +( + host_t host, + hash_info_bucket_array_t *info, + mach_msg_type_number_t *infoCnt +); + +/* Routine processor_set_default */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_set_default +( + host_t host, + processor_set_name_t *default_set +); + +/* Routine processor_set_create */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_set_create +( + host_t host, + processor_set_t *new_set, + processor_set_name_t *new_name +); + +/* Routine mach_memory_object_memory_entry_64 */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_memory_object_memory_entry_64 +( + host_t host, + boolean_t internal, + memory_object_size_t size, + vm_prot_t permission, + memory_object_t pager, + mach_port_t *entry_handle +); + +/* Routine host_statistics */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_statistics +( + host_t host_priv, + host_flavor_t flavor, + host_info_t host_info_out, + mach_msg_type_number_t *host_info_outCnt +); + +/* Routine host_request_notification */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t host_request_notification +( + host_t host, + host_flavor_t notify_type, + mach_port_t notify_port +); + +/* Routine host_lockgroup_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_lockgroup_info +( + host_t host, + lockgroup_info_array_t *lockgroup_info, + mach_msg_type_number_t *lockgroup_infoCnt +); + +/* Routine host_statistics64 */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_statistics64 +( + host_t host_priv, + host_flavor_t flavor, + host_info64_t host_info64_out, + mach_msg_type_number_t *host_info64_outCnt +); + +/* Routine mach_zone_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_zone_info +( + host_priv_t host, + mach_zone_name_array_t *names, + mach_msg_type_number_t *namesCnt, + mach_zone_info_array_t *info, + mach_msg_type_number_t *infoCnt +); + +/* Routine host_create_mach_voucher */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t host_create_mach_voucher +( + host_t host, + mach_voucher_attr_raw_recipe_array_t recipes, + mach_msg_type_number_t recipesCnt, + ipc_voucher_t *voucher +); + +/* Routine host_register_mach_voucher_attr_manager */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t host_register_mach_voucher_attr_manager +( + host_t host, + mach_voucher_attr_manager_t attr_manager, + mach_voucher_attr_value_handle_t default_value, + mach_voucher_attr_key_t *new_key, + ipc_voucher_attr_control_t *new_attr_control +); + +/* Routine host_register_well_known_mach_voucher_attr_manager */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t host_register_well_known_mach_voucher_attr_manager +( + host_t host, + mach_voucher_attr_manager_t attr_manager, + mach_voucher_attr_value_handle_t default_value, + mach_voucher_attr_key_t key, + ipc_voucher_attr_control_t *new_attr_control +); + +/* Routine host_set_atm_diagnostic_flag */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t host_set_atm_diagnostic_flag +( + host_t host, + uint32_t diagnostic_flag +); + +/* Routine host_get_atm_diagnostic_flag */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t host_get_atm_diagnostic_flag +( + host_t host, + uint32_t *diagnostic_flag +); + +/* Routine mach_memory_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_memory_info +( + host_priv_t host, + mach_zone_name_array_t *names, + mach_msg_type_number_t *namesCnt, + mach_zone_info_array_t *info, + mach_msg_type_number_t *infoCnt, + mach_memory_info_array_t *memory_info, + mach_msg_type_number_t *memory_infoCnt +); + +/* Routine host_set_multiuser_config_flags */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_set_multiuser_config_flags +( + host_priv_t host_priv, + uint32_t multiuser_flags +); + +/* Routine host_get_multiuser_config_flags */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_get_multiuser_config_flags +( + host_t host, + uint32_t *multiuser_flags +); + +/* Routine host_check_multiuser_mode */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t host_check_multiuser_mode +( + host_t host, + uint32_t *multiuser_mode +); + +/* Routine mach_zone_info_for_zone */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_zone_info_for_zone +( + host_priv_t host, + mach_zone_name_t name, + mach_zone_info_t *info +); + +__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_host_subsystem__defined +#define __Request__mach_host_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + host_flavor_t flavor; + mach_msg_type_number_t host_info_outCnt; + } __Request__host_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__host_kernel_version_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request___host_page_size_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 pager; + /* end of the kernel processed data */ + NDR_record_t NDR; + boolean_t internal; + vm_size_t size; + vm_prot_t permission; + } __Request__mach_memory_object_memory_entry_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + processor_flavor_t flavor; + } __Request__host_processor_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__host_get_io_master_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + clock_id_t clock_id; + } __Request__host_get_clock_service_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__kmod_get_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__host_virtual_physical_table_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__processor_set_default_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__processor_set_create_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 pager; + /* end of the kernel processed data */ + NDR_record_t NDR; + boolean_t internal; + memory_object_size_t size; + vm_prot_t permission; + } __Request__mach_memory_object_memory_entry_64_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + host_flavor_t flavor; + mach_msg_type_number_t host_info_outCnt; + } __Request__host_statistics_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 notify_port; + /* end of the kernel processed data */ + NDR_record_t NDR; + host_flavor_t notify_type; + } __Request__host_request_notification_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__host_lockgroup_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + host_flavor_t flavor; + mach_msg_type_number_t host_info64_outCnt; + } __Request__host_statistics64_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__mach_zone_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_msg_type_number_t recipesCnt; + uint8_t recipes[5120]; + } __Request__host_create_mach_voucher_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 attr_manager; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_voucher_attr_value_handle_t default_value; + } __Request__host_register_mach_voucher_attr_manager_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 attr_manager; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_voucher_attr_value_handle_t default_value; + mach_voucher_attr_key_t key; + } __Request__host_register_well_known_mach_voucher_attr_manager_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + uint32_t diagnostic_flag; + } __Request__host_set_atm_diagnostic_flag_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__host_get_atm_diagnostic_flag_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__mach_memory_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + uint32_t multiuser_flags; + } __Request__host_set_multiuser_config_flags_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__host_get_multiuser_config_flags_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__host_check_multiuser_mode_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_zone_name_t name; + } __Request__mach_zone_info_for_zone_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Request__mach_host_subsystem__defined */ + +/* union of all requests */ + +#ifndef __RequestUnion__mach_host_subsystem__defined +#define __RequestUnion__mach_host_subsystem__defined +union __RequestUnion__mach_host_subsystem { + __Request__host_info_t Request_host_info; + __Request__host_kernel_version_t Request_host_kernel_version; + __Request___host_page_size_t Request__host_page_size; + __Request__mach_memory_object_memory_entry_t Request_mach_memory_object_memory_entry; + __Request__host_processor_info_t Request_host_processor_info; + __Request__host_get_io_master_t Request_host_get_io_master; + __Request__host_get_clock_service_t Request_host_get_clock_service; + __Request__kmod_get_info_t Request_kmod_get_info; + __Request__host_virtual_physical_table_info_t Request_host_virtual_physical_table_info; + __Request__processor_set_default_t Request_processor_set_default; + __Request__processor_set_create_t Request_processor_set_create; + __Request__mach_memory_object_memory_entry_64_t Request_mach_memory_object_memory_entry_64; + __Request__host_statistics_t Request_host_statistics; + __Request__host_request_notification_t Request_host_request_notification; + __Request__host_lockgroup_info_t Request_host_lockgroup_info; + __Request__host_statistics64_t Request_host_statistics64; + __Request__mach_zone_info_t Request_mach_zone_info; + __Request__host_create_mach_voucher_t Request_host_create_mach_voucher; + __Request__host_register_mach_voucher_attr_manager_t Request_host_register_mach_voucher_attr_manager; + __Request__host_register_well_known_mach_voucher_attr_manager_t Request_host_register_well_known_mach_voucher_attr_manager; + __Request__host_set_atm_diagnostic_flag_t Request_host_set_atm_diagnostic_flag; + __Request__host_get_atm_diagnostic_flag_t Request_host_get_atm_diagnostic_flag; + __Request__mach_memory_info_t Request_mach_memory_info; + __Request__host_set_multiuser_config_flags_t Request_host_set_multiuser_config_flags; + __Request__host_get_multiuser_config_flags_t Request_host_get_multiuser_config_flags; + __Request__host_check_multiuser_mode_t Request_host_check_multiuser_mode; + __Request__mach_zone_info_for_zone_t Request_mach_zone_info_for_zone; +}; +#endif /* !__RequestUnion__mach_host_subsystem__defined */ +/* typedefs for all replies */ + +#ifndef __Reply__mach_host_subsystem__defined +#define __Reply__mach_host_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t host_info_outCnt; + integer_t host_info_out[68]; + } __Reply__host_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t kernel_versionOffset; /* MiG doesn't use it */ + mach_msg_type_number_t kernel_versionCnt; + char kernel_version[512]; + } __Reply__host_kernel_version_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + vm_size_t out_page_size; + } __Reply___host_page_size_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 entry_handle; + /* end of the kernel processed data */ + } __Reply__mach_memory_object_memory_entry_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 out_processor_info; + /* end of the kernel processed data */ + NDR_record_t NDR; + natural_t out_processor_count; + mach_msg_type_number_t out_processor_infoCnt; + } __Reply__host_processor_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 io_master; + /* end of the kernel processed data */ + } __Reply__host_get_io_master_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 clock_serv; + /* end of the kernel processed data */ + } __Reply__host_get_clock_service_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 modules; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t modulesCnt; + } __Reply__kmod_get_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 info; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t infoCnt; + } __Reply__host_virtual_physical_table_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 default_set; + /* end of the kernel processed data */ + } __Reply__processor_set_default_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 new_set; + mach_msg_port_descriptor_t new_name; + /* end of the kernel processed data */ + } __Reply__processor_set_create_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 entry_handle; + /* end of the kernel processed data */ + } __Reply__mach_memory_object_memory_entry_64_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t host_info_outCnt; + integer_t host_info_out[68]; + } __Reply__host_statistics_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__host_request_notification_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 lockgroup_info; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t lockgroup_infoCnt; + } __Reply__host_lockgroup_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t host_info64_outCnt; + integer_t host_info64_out[256]; + } __Reply__host_statistics64_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 names; + mach_msg_ool_descriptor_t info; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t namesCnt; + mach_msg_type_number_t infoCnt; + } __Reply__mach_zone_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 voucher; + /* end of the kernel processed data */ + } __Reply__host_create_mach_voucher_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 new_attr_control; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_voucher_attr_key_t new_key; + } __Reply__host_register_mach_voucher_attr_manager_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 new_attr_control; + /* end of the kernel processed data */ + } __Reply__host_register_well_known_mach_voucher_attr_manager_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__host_set_atm_diagnostic_flag_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + uint32_t diagnostic_flag; + } __Reply__host_get_atm_diagnostic_flag_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 names; + mach_msg_ool_descriptor_t info; + mach_msg_ool_descriptor_t memory_info; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t namesCnt; + mach_msg_type_number_t infoCnt; + mach_msg_type_number_t memory_infoCnt; + } __Reply__mach_memory_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__host_set_multiuser_config_flags_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + uint32_t multiuser_flags; + } __Reply__host_get_multiuser_config_flags_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + uint32_t multiuser_mode; + } __Reply__host_check_multiuser_mode_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_zone_info_t info; + } __Reply__mach_zone_info_for_zone_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Reply__mach_host_subsystem__defined */ + +/* union of all replies */ + +#ifndef __ReplyUnion__mach_host_subsystem__defined +#define __ReplyUnion__mach_host_subsystem__defined +union __ReplyUnion__mach_host_subsystem { + __Reply__host_info_t Reply_host_info; + __Reply__host_kernel_version_t Reply_host_kernel_version; + __Reply___host_page_size_t Reply__host_page_size; + __Reply__mach_memory_object_memory_entry_t Reply_mach_memory_object_memory_entry; + __Reply__host_processor_info_t Reply_host_processor_info; + __Reply__host_get_io_master_t Reply_host_get_io_master; + __Reply__host_get_clock_service_t Reply_host_get_clock_service; + __Reply__kmod_get_info_t Reply_kmod_get_info; + __Reply__host_virtual_physical_table_info_t Reply_host_virtual_physical_table_info; + __Reply__processor_set_default_t Reply_processor_set_default; + __Reply__processor_set_create_t Reply_processor_set_create; + __Reply__mach_memory_object_memory_entry_64_t Reply_mach_memory_object_memory_entry_64; + __Reply__host_statistics_t Reply_host_statistics; + __Reply__host_request_notification_t Reply_host_request_notification; + __Reply__host_lockgroup_info_t Reply_host_lockgroup_info; + __Reply__host_statistics64_t Reply_host_statistics64; + __Reply__mach_zone_info_t Reply_mach_zone_info; + __Reply__host_create_mach_voucher_t Reply_host_create_mach_voucher; + __Reply__host_register_mach_voucher_attr_manager_t Reply_host_register_mach_voucher_attr_manager; + __Reply__host_register_well_known_mach_voucher_attr_manager_t Reply_host_register_well_known_mach_voucher_attr_manager; + __Reply__host_set_atm_diagnostic_flag_t Reply_host_set_atm_diagnostic_flag; + __Reply__host_get_atm_diagnostic_flag_t Reply_host_get_atm_diagnostic_flag; + __Reply__mach_memory_info_t Reply_mach_memory_info; + __Reply__host_set_multiuser_config_flags_t Reply_host_set_multiuser_config_flags; + __Reply__host_get_multiuser_config_flags_t Reply_host_get_multiuser_config_flags; + __Reply__host_check_multiuser_mode_t Reply_host_check_multiuser_mode; + __Reply__mach_zone_info_for_zone_t Reply_mach_zone_info_for_zone; +}; +#endif /* !__RequestUnion__mach_host_subsystem__defined */ + +#ifndef subsystem_to_name_map_mach_host +#define subsystem_to_name_map_mach_host \ + { "host_info", 200 },\ + { "host_kernel_version", 201 },\ + { "_host_page_size", 202 },\ + { "mach_memory_object_memory_entry", 203 },\ + { "host_processor_info", 204 },\ + { "host_get_io_master", 205 },\ + { "host_get_clock_service", 206 },\ + { "kmod_get_info", 207 },\ + { "host_virtual_physical_table_info", 209 },\ + { "processor_set_default", 213 },\ + { "processor_set_create", 214 },\ + { "mach_memory_object_memory_entry_64", 215 },\ + { "host_statistics", 216 },\ + { "host_request_notification", 217 },\ + { "host_lockgroup_info", 218 },\ + { "host_statistics64", 219 },\ + { "mach_zone_info", 220 },\ + { "host_create_mach_voucher", 222 },\ + { "host_register_mach_voucher_attr_manager", 223 },\ + { "host_register_well_known_mach_voucher_attr_manager", 224 },\ + { "host_set_atm_diagnostic_flag", 225 },\ + { "host_get_atm_diagnostic_flag", 226 },\ + { "mach_memory_info", 227 },\ + { "host_set_multiuser_config_flags", 228 },\ + { "host_get_multiuser_config_flags", 229 },\ + { "host_check_multiuser_mode", 230 },\ + { "mach_zone_info_for_zone", 231 } +#endif + +#ifdef __AfterMigUserHeader +__AfterMigUserHeader +#endif /* __AfterMigUserHeader */ + +#endif /* _mach_host_user_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_init.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_init.h new file mode 100644 index 00000000..4d9d51f4 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_init.h @@ -0,0 +1,110 @@ +/* + * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987,1986 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + +/* + * Items provided by the Mach environment initialization. + */ + +#ifndef _MACH_INIT_ +#define _MACH_INIT_ 1 + +#include +#include +#include + +#include + +/* + * Kernel-related ports; how a task/thread controls itself + */ + +__BEGIN_DECLS +extern mach_port_t mach_host_self(void); +extern mach_port_t mach_thread_self(void); +extern kern_return_t host_page_size(host_t, vm_size_t *); + +extern mach_port_t mach_task_self_; +#define mach_task_self() mach_task_self_ +#define current_task() mach_task_self() + +__END_DECLS +#include +__BEGIN_DECLS + +/* + * Other important ports in the Mach user environment + */ + +extern mach_port_t bootstrap_port; + +/* + * Where these ports occur in the "mach_ports_register" + * collection... only servers or the runtime library need know. + */ + +#define NAME_SERVER_SLOT 0 +#define ENVIRONMENT_SLOT 1 +#define SERVICE_SLOT 2 + +#define MACH_PORTS_SLOTS_USED 3 + +/* + * fprintf_stderr uses vprintf_stderr_func to produce + * error messages, this can be overridden by a user + * application to point to a user-specified output function + */ +extern int (*vprintf_stderr_func)(const char *format, va_list ap); + +__END_DECLS + +#endif /* _MACH_INIT_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_interface.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_interface.h new file mode 100644 index 00000000..e6c6b7ac --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_interface.h @@ -0,0 +1,53 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * Copyright (C) Apple Computer 1998 + * ALL Rights Reserved + */ +/* + * This file represents the interfaces that used to come + * from creating the user headers from the mach.defs file. + * Because mach.defs was decomposed, this file now just + * wraps up all the new interface headers generated from + * each of the new .defs resulting from that decomposition. + */ +#ifndef _MACH_INTERFACE_H_ +#define _MACH_INTERFACE_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif /* _MACH_INTERFACE_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_param.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_param.h new file mode 100644 index 00000000..fb426130 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_param.h @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * File: mach/mach_param.h + * Author: Avadis Tevanian, Jr., Michael Wayne Young + * Date: 1986 + * + * Mach system sizing parameters + */ + +#ifndef _MACH_MACH_PARAM_H_ +#define _MACH_MACH_PARAM_H_ + +/* Number of "registered" ports */ + +#define TASK_PORT_REGISTER_MAX 3 + +/* Number of watchport for task */ +#define TASK_MAX_WATCHPORT_COUNT 32 + +#endif /* _MACH_MACH_PARAM_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_port.defs b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_port.defs new file mode 100644 index 00000000..d62095ad --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_port.defs @@ -0,0 +1,676 @@ +/* + * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_FREE_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * File: mach/mach_port.defs + * Author: Rich Draves + * + * Exported kernel calls. + */ + +subsystem +#if KERNEL_SERVER + KernelServer +#endif /* KERNEL_SERVER */ + mach_port 3200; + +#if !KERNEL && !LIBSYSCALL_INTERFACE + UserPrefix _kernelrpc_; +#endif + +#include +#include +#include + +type kobject_description_t = c_string[*:512]; + +/* + * Returns the set of port and port set names + * to which the target task has access, along with + * the type (set or port) for each name. + */ + +routine mach_port_names( + task : ipc_space_t; + out names : mach_port_name_array_t; + out types : mach_port_type_array_t); + +/* + * Returns the type (set or port) for the port name + * within the target task. Also indicates whether + * there is a dead-name request for the name. + */ + +routine mach_port_type( + task : ipc_space_t; + name : mach_port_name_t; + out ptype : mach_port_type_t); + +/* + * Changes the name by which a port (or port set) is known to + * the target task. The new name can't be in use. The + * old name becomes available for recycling. + * + * This interface is OBSOLETE and will always + * return KERN_NOT_SUPPORTED. + */ + +routine mach_port_rename( + task : ipc_space_t; + old_name : mach_port_name_t; + new_name : mach_port_name_t); + +/* + * Allocates the specified kind of object, with the given name. + * The right must be one of + * MACH_PORT_RIGHT_RECEIVE + * MACH_PORT_RIGHT_PORT_SET + * MACH_PORT_RIGHT_DEAD_NAME + * New port sets are empty. New ports don't have any + * send/send-once rights or queued messages. The make-send + * count is zero and their queue limit is MACH_PORT_QLIMIT_DEFAULT. + * New sets, ports, and dead names have one user reference. + */ + +routine mach_port_allocate_name( + task : ipc_space_t; + right : mach_port_right_t; + name : mach_port_name_t); + +/* + * Allocates the specified kind of object. + * The right must be one of + * MACH_PORT_RIGHT_RECEIVE + * MACH_PORT_RIGHT_PORT_SET + * MACH_PORT_RIGHT_DEAD_NAME + * Like port_allocate_name, but the kernel picks a name. + * It can use any name not associated with a right. + */ + +routine mach_port_allocate( + task : ipc_space_t; + right : mach_port_right_t; + out name : mach_port_name_t); + +/* + * Destroys all rights associated with the name and makes it + * available for recycling immediately. The name can be a + * port (possibly with multiple user refs), a port set, or + * a dead name (again, with multiple user refs). + */ + +routine mach_port_destroy( + task : ipc_space_t; + name : mach_port_name_t); + +/* + * Releases one send/send-once/dead-name user ref. + * Just like mach_port_mod_refs -1, but deduces the + * correct type of right. This allows a user task + * to release a ref for a port without worrying + * about whether the port has died or not. + */ + +routine mach_port_deallocate( + task : ipc_space_t; + name : mach_port_name_t); + +/* + * A port set always has one user ref. + * A send-once right always has one user ref. + * A dead name always has one or more user refs. + * A send right always has one or more user refs. + * A receive right always has one user ref. + * The right must be one of + * MACH_PORT_RIGHT_RECEIVE + * MACH_PORT_RIGHT_PORT_SET + * MACH_PORT_RIGHT_DEAD_NAME + * MACH_PORT_RIGHT_SEND + * MACH_PORT_RIGHT_SEND_ONCE + */ + +routine mach_port_get_refs( + task : ipc_space_t; + name : mach_port_name_t; + right : mach_port_right_t; + out refs : mach_port_urefs_t); + +/* + * The delta is a signed change to the task's + * user ref count for the right. Only dead names + * and send rights can have a positive delta. + * The resulting user ref count can't be negative. + * If it is zero, the right is deallocated. + * If the name isn't a composite right, it becomes + * available for recycling. The right must be one of + * MACH_PORT_RIGHT_RECEIVE + * MACH_PORT_RIGHT_PORT_SET + * MACH_PORT_RIGHT_DEAD_NAME + * MACH_PORT_RIGHT_SEND + * MACH_PORT_RIGHT_SEND_ONCE + */ + +routine mach_port_mod_refs( + task : ipc_space_t; + name : mach_port_name_t; + right : mach_port_right_t; + delta : mach_port_delta_t); + +/* + * Peek at the message queue for the specified receive + * right and return info about the message with the + * sequence number matching the input. If zero is + * specified as the seqno, the first message in the + * queue will be peeked. + * + * Only the following trailer types are currently supported: + * MACH_RCV_TRAILER_TYPE(MACH_MSG_TRAILER_FORMAT_0) + * + * or'ed with one of these element types: + * MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_NULL) + * MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_SEQNO) + * MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_SENDER) + * MACH_RCV_TRAILER_ELEMENTS(MACH_RCV_TRAILER_AUDIT) + */ +routine mach_port_peek( + task : ipc_space_t; + name : mach_port_name_t; + trailer_type : mach_msg_trailer_type_t; + inout request_seqnop : mach_port_seqno_t; + out msg_sizep : mach_msg_size_t; + out msg_idp : mach_msg_id_t; + out trailer_infop : mach_msg_trailer_info_t, CountInOut); + +/* + * Only valid for receive rights. + * Sets the make-send count for the port. + */ +routine mach_port_set_mscount( + task : ipc_space_t; + name : mach_port_name_t; + mscount : mach_port_mscount_t); + +/* + * Only valid for port sets. Returns a list of + * the members. + */ + +routine mach_port_get_set_status( + task : ipc_space_inspect_t; + name : mach_port_name_t; + out members : mach_port_name_array_t); + +/* + * Puts the member port (the task must have receive rights) + * into the after port set. If the port is already a member + * of any set(s), it is atomically removed from those sets as + * part of this operation. (If after is MACH_PORT_NULL, the + * port is still removed from all current sets). + */ + +routine mach_port_move_member( + task : ipc_space_t; + member : mach_port_name_t; + after : mach_port_name_t); + +/* + * Requests a notification from the kernel. The request + * must supply the send-once right which is used for + * the notification. If a send-once right was previously + * registered, it is returned. The msgid must be one of: + * MACH_NOTIFY_PORT_DESTROYED (receive rights) + * MACH_NOTIFY_DEAD_NAME (send/receive/send-once rights) + * MACH_NOTIFY_SEND_POSSIBLE (send/receive/send-once rights) + * MACH_NOTIFY_NO_SENDERS (receive rights) + * + * The sync value specifies whether a notification should + * get sent immediately, if appropriate. The exact meaning + * depends on the notification: + * MACH_NOTIFY_PORT_DESTROYED: must be zero. + * MACH_NOTIFY_DEAD_NAME: if non-zero, then name can be dead, + * and the notification gets sent immediately. + * If zero, then name can't be dead. + * MACH_NOTIFY_SEND_POSSIBLE: if non-zero, will generate a send- + * possible notification as soon as it is possible to send + * to the port. If zero, will generate a send-possible + * notification only after a subsequent failed send + * (with MACH_SEND_NOTIFY option to mach_msg call). Can + * generate a dead-name notification if name is already dead + * or becomes dead before a send-possible notification fires. + * MACH_NOTIFY_NO_SENDERS: the notification gets sent + * immediately if the current mscount is greater + * than or equal to the sync value and there are no + * extant send rights. + * + * If the name is deleted before a successfully registered notification + * is delivered, it is replaced with a port-deleted notification. + */ + +routine mach_port_request_notification( + task : ipc_space_t; + name : mach_port_name_t; + msgid : mach_msg_id_t; + sync : mach_port_mscount_t; + notify : mach_port_send_once_t; + out previous : mach_port_move_send_once_t); + +/* + * Inserts the specified rights into the target task, + * using the specified name. If inserting send/receive + * rights and the task already has send/receive rights + * for the port, then the names must agree. In any case, + * the task gains a user ref for the port. + */ + +routine mach_port_insert_right( + task : ipc_space_t; + name : mach_port_name_t; + poly : mach_port_poly_t); + +/* + * Returns the specified right for the named port + * in the target task, extracting that right from + * the target task. The target task loses a user + * ref and the name may be available for recycling. + * msgt_name must be one of + * MACH_MSG_TYPE_MOVE_RECEIVE + * MACH_MSG_TYPE_COPY_SEND + * MACH_MSG_TYPE_MAKE_SEND + * MACH_MSG_TYPE_MOVE_SEND + * MACH_MSG_TYPE_MAKE_SEND_ONCE + * MACH_MSG_TYPE_MOVE_SEND_ONCE + */ + +routine mach_port_extract_right( + task : ipc_space_t; + name : mach_port_name_t; + msgt_name : mach_msg_type_name_t; + out poly : mach_port_poly_t); + +/* + * Only valid for receive rights. + * Sets the sequence number for the port. + */ + +routine mach_port_set_seqno( + task : ipc_space_t; + name : mach_port_name_t; + seqno : mach_port_seqno_t); + +/* + * Returns information about a port. + */ + +routine mach_port_get_attributes( + task : ipc_space_inspect_t; + name : mach_port_name_t; + flavor : mach_port_flavor_t; + out port_info_out : mach_port_info_t, CountInOut); + +/* + * Set attributes of a port + */ + +routine mach_port_set_attributes( + task : ipc_space_t; + name : mach_port_name_t; + flavor : mach_port_flavor_t; + port_info : mach_port_info_t); + + +/* + * Allocates the specified kind of object, qos version. + * The right must be + * MACH_PORT_RIGHT_RECEIVE + * Like port_allocate_name, but the kernel picks a name. + * It can use any name not associated with a right. + */ + +routine mach_port_allocate_qos( + task : ipc_space_t; + right : mach_port_right_t; + inout qos : mach_port_qos_t; + out name : mach_port_name_t); + + +/* + * Generic interface to allocation various kinds of ports. + * Should never be called directly by users (at least not + * unless they are exceedingly masochistic). + */ + +routine mach_port_allocate_full( + task : ipc_space_t; + right : mach_port_right_t; + proto : mach_port_t; + inout qos : mach_port_qos_t; + inout name : mach_port_name_t); + + +/* + * Pre-expand task port name space. + */ +routine task_set_port_space( + task : ipc_space_t; + table_entries : int); + + +/* + * Returns the exact number of extant send rights + * for the given receive right. + * This call is only valid on MACH_IPC_DEBUG kernels. + * Otherwise, KERN_FAILURE is returned. + */ +routine mach_port_get_srights( + task : ipc_space_t; + name : mach_port_name_t; + out srights : mach_port_rights_t); + + +/* + * Returns information about an IPC space. + * This call is only valid on MACH_IPC_DEBUG kernels. + * Otherwise, KERN_FAILURE is returned. + */ +routine mach_port_space_info( + task : ipc_space_inspect_t; + out space_info : ipc_info_space_t; + out table_info : ipc_info_name_array_t; + out tree_info : ipc_info_tree_name_array_t); + +/* + * Returns information about the dead-name requests + * registered with the named receive right. + * This call is only valid on MACH_IPC_DEBUG kernels. + * Otherwise, KERN_FAILURE is returned. + */ +routine mach_port_dnrequest_info( + task : ipc_space_t; + name : mach_port_name_t; + out dnr_total : unsigned; /* total size of table */ + out dnr_used : unsigned); /* amount used */ + +/* + * Return the type and address of the kernel object + * that the given send/receive right represents. + * This call is only valid on MACH_IPC_DEBUG kernels. + * Otherwise, KERN_FAILURE is returned. + * + * This interface is DEPRECATED in favor of the new + * mach_port_kernel_object64() call (see below). + */ +routine mach_port_kernel_object( + task : ipc_space_inspect_t; + name : mach_port_name_t; + out object_type : unsigned; + out object_addr : unsigned); + + +/* + * Inserts the specified rights into the portset identified + * by the pair. The results of passing in the + * Poly argument via the supplied disposition must yield a + * receive right. + * + * If the pair does not represent a valid portset + * KERN_INVALID_RIGHT is returned. + * + * If the passed in name argument does not represent a receive + * right, KERN_INVALID_CAPABILITY will be returned. + * + * If the port represented by the receive right is already in + * the portset, KERN_ALREADY_IN_SET is returned. + */ +routine mach_port_insert_member( + task : ipc_space_t; + name : mach_port_name_t; + pset : mach_port_name_t); + +/* + * Extracts the specified right from the named portset + * in the target task. + * the target task. The target task loses a user + * ref and the name may be available for recycling. + * msgt_name must be one of + * MACH_MSG_TYPE_MOVE_RECEIVE + * MACH_MSG_TYPE_COPY_SEND + * MACH_MSG_TYPE_MAKE_SEND + * MACH_MSG_TYPE_MOVE_SEND + * MACH_MSG_TYPE_MAKE_SEND_ONCE + * MACH_MSG_TYPE_MOVE_SEND_ONCE + */ + +routine mach_port_extract_member( + task : ipc_space_t; + name : mach_port_name_t; + pset : mach_port_name_t); + +/* + * Only valid for receive rights. + * Gets the context pointer for the port. + */ + +routine mach_port_get_context( + task : ipc_space_inspect_t; + name : mach_port_name_t; +#ifdef LIBSYSCALL_INTERFACE + out context : mach_port_context_t +#else + out context : mach_vm_address_t +#endif + ); + +/* + * Only valid for receive rights. + * Sets the context pointer for the port. + */ + +routine mach_port_set_context( + task : ipc_space_t; + name : mach_port_name_t; +#ifdef LIBSYSCALL_INTERFACE + context : mach_port_context_t +#else + context : mach_vm_address_t +#endif + ); + +/* + * Return the type and address of the kernel object + * that the given send/receive right represents. + * This call is only valid on MACH_IPC_DEBUG kernels. + * Otherwise, KERN_FAILURE is returned. + */ +routine mach_port_kobject( + task : ipc_space_inspect_t; + name : mach_port_name_t; + out object_type : natural_t; + out object_addr : mach_vm_address_t); + + +/* + * Constructs a right based on the options passed + * in. Also allows guarding the port as one of the + * options if the requested right is a receive + * right. + */ +routine mach_port_construct( + task : ipc_space_t; + options : mach_port_options_ptr_t; +#ifdef LIBSYSCALL_INTERFACE + context : mach_port_context_t; +#else + context : uint64_t; +#endif + out name : mach_port_name_t); + +/* + * Destroys a mach port using the guard provided + * for guarded ports. Also reduces the user ref + * count for send rights as specified by srdelta. + */ +routine mach_port_destruct( + task : ipc_space_t; + name : mach_port_name_t; + srdelta : mach_port_delta_t; +#ifdef LIBSYSCALL_INTERFACE + guard : mach_port_context_t +#else + guard : uint64_t +#endif + ); + +/* + * Guard an already existing port. Allows guarding + * receive rights only. Uses the context field in the + * port structure to store the guard. + */ +routine mach_port_guard( + task : ipc_space_t; + name : mach_port_name_t; +#ifdef LIBSYSCALL_INTERFACE + guard : mach_port_context_t; +#else + guard : uint64_t; +#endif + strict : boolean_t); + +/* + * Unguard a port guarded previously. For unguarded ports + * or incorrect guards passed in it raises an exception + * indicating guarding misbehavior. + */ +routine mach_port_unguard( + task : ipc_space_t; + name : mach_port_name_t; +#ifdef LIBSYSCALL_INTERFACE + guard : mach_port_context_t +#else + guard : uint64_t +#endif + ); + +/* + * Returns basic information about an IPC space. + * This call is only valid on MACH_IPC_DEBUG kernels. + * Otherwise, KERN_FAILURE is returned. + */ +routine mach_port_space_basic_info( + task : ipc_space_inspect_t; + out basic_info : ipc_info_space_basic_t); + +#if KERNEL || !LIBSYSCALL_INTERFACE +/* + * Returns sync ipc turnstile link status + * for special reply ports. + */ +routine mach_port_special_reply_port_reset_link( + task : ipc_space_t; + name : mach_port_name_t; + out srp_lost_link : boolean_t); +#else +skip; +#endif + +/* + * Guard an already existing port. Allows guarding + * receive rights only. Uses the context field in the + * port structure to store the guard. + */ +routine mach_port_guard_with_flags( + task : ipc_space_t; + name : mach_port_name_t; +#ifdef LIBSYSCALL_INTERFACE + guard : mach_port_context_t; +#else + guard : uint64_t; +#endif + flags : uint64_t); + +/* + * Swap guard value of an existing guarded port. Works + * only if it is not a strict guard. + */ +routine mach_port_swap_guard( + task : ipc_space_t; + name : mach_port_name_t; +#ifdef LIBSYSCALL_INTERFACE + old_guard : mach_port_context_t; +#else + old_guard : uint64_t; +#endif + +#ifdef LIBSYSCALL_INTERFACE + new_guard : mach_port_context_t); +#else + new_guard : uint64_t); +#endif + +/* + * Return the type and address of the kernel object + * that the given send/receive right represents. + * This call is only valid on MACH_IPC_DEBUG kernels. + * Otherwise, KERN_FAILURE is returned. + */ +routine mach_port_kobject_description( + task : ipc_space_inspect_t; + name : mach_port_name_t; + out object_type : natural_t; + out object_addr : mach_vm_address_t; + out description : kobject_description_t); + +/* vim: set ft=c : */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_port.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_port.h new file mode 100644 index 00000000..8f587e3b --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_port.h @@ -0,0 +1,1808 @@ +#ifndef _mach_port_user_ +#define _mach_port_user_ + +/* Module mach_port */ + +#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_port_MSG_COUNT +#define mach_port_MSG_COUNT 40 +#endif /* mach_port_MSG_COUNT */ + +#include +#include +#include +#include +#include + +#ifdef __BeforeMigUserHeader +__BeforeMigUserHeader +#endif /* __BeforeMigUserHeader */ + +#include +__BEGIN_DECLS + + +/* Routine mach_port_names */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_names +( + ipc_space_t task, + mach_port_name_array_t *names, + mach_msg_type_number_t *namesCnt, + mach_port_type_array_t *types, + mach_msg_type_number_t *typesCnt +); + +/* Routine mach_port_type */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_type +( + ipc_space_t task, + mach_port_name_t name, + mach_port_type_t *ptype +); + +/* Routine mach_port_rename */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_rename +( + ipc_space_t task, + mach_port_name_t old_name, + mach_port_name_t new_name +); + +/* Routine mach_port_allocate_name */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t mach_port_allocate_name +( + ipc_space_t task, + mach_port_right_t right, + mach_port_name_t name +); + +/* Routine mach_port_allocate */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_allocate +( + ipc_space_t task, + mach_port_right_t right, + mach_port_name_t *name +); + +/* Routine mach_port_destroy */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_destroy +( + ipc_space_t task, + mach_port_name_t name +); + +/* Routine mach_port_deallocate */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_deallocate +( + ipc_space_t task, + mach_port_name_t name +); + +/* Routine mach_port_get_refs */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_get_refs +( + ipc_space_t task, + mach_port_name_t name, + mach_port_right_t right, + mach_port_urefs_t *refs +); + +/* Routine mach_port_mod_refs */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_mod_refs +( + ipc_space_t task, + mach_port_name_t name, + mach_port_right_t right, + mach_port_delta_t delta +); + +/* Routine mach_port_peek */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_peek +( + ipc_space_t task, + mach_port_name_t name, + mach_msg_trailer_type_t trailer_type, + mach_port_seqno_t *request_seqnop, + mach_msg_size_t *msg_sizep, + mach_msg_id_t *msg_idp, + mach_msg_trailer_info_t trailer_infop, + mach_msg_type_number_t *trailer_infopCnt +); + +/* Routine mach_port_set_mscount */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_set_mscount +( + ipc_space_t task, + mach_port_name_t name, + mach_port_mscount_t mscount +); + +/* Routine mach_port_get_set_status */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_get_set_status +( + ipc_space_inspect_t task, + mach_port_name_t name, + mach_port_name_array_t *members, + mach_msg_type_number_t *membersCnt +); + +/* Routine mach_port_move_member */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_move_member +( + ipc_space_t task, + mach_port_name_t member, + mach_port_name_t after +); + +/* Routine mach_port_request_notification */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_request_notification +( + ipc_space_t task, + mach_port_name_t name, + mach_msg_id_t msgid, + mach_port_mscount_t sync, + mach_port_t notify, + mach_msg_type_name_t notifyPoly, + mach_port_t *previous +); + +/* Routine mach_port_insert_right */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_insert_right +( + ipc_space_t task, + mach_port_name_t name, + mach_port_t poly, + mach_msg_type_name_t polyPoly +); + +/* Routine mach_port_extract_right */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_extract_right +( + ipc_space_t task, + mach_port_name_t name, + mach_msg_type_name_t msgt_name, + mach_port_t *poly, + mach_msg_type_name_t *polyPoly +); + +/* Routine mach_port_set_seqno */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_set_seqno +( + ipc_space_t task, + mach_port_name_t name, + mach_port_seqno_t seqno +); + +/* Routine mach_port_get_attributes */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_get_attributes +( + ipc_space_inspect_t task, + mach_port_name_t name, + mach_port_flavor_t flavor, + mach_port_info_t port_info_out, + mach_msg_type_number_t *port_info_outCnt +); + +/* Routine mach_port_set_attributes */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_set_attributes +( + ipc_space_t task, + mach_port_name_t name, + mach_port_flavor_t flavor, + mach_port_info_t port_info, + mach_msg_type_number_t port_infoCnt +); + +/* Routine mach_port_allocate_qos */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_allocate_qos +( + ipc_space_t task, + mach_port_right_t right, + mach_port_qos_t *qos, + mach_port_name_t *name +); + +/* Routine mach_port_allocate_full */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_allocate_full +( + ipc_space_t task, + mach_port_right_t right, + mach_port_t proto, + mach_port_qos_t *qos, + mach_port_name_t *name +); + +/* Routine task_set_port_space */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t task_set_port_space +( + ipc_space_t task, + int table_entries +); + +/* Routine mach_port_get_srights */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_get_srights +( + ipc_space_t task, + mach_port_name_t name, + mach_port_rights_t *srights +); + +/* Routine mach_port_space_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_space_info +( + ipc_space_inspect_t task, + ipc_info_space_t *space_info, + ipc_info_name_array_t *table_info, + mach_msg_type_number_t *table_infoCnt, + ipc_info_tree_name_array_t *tree_info, + mach_msg_type_number_t *tree_infoCnt +); + +/* Routine mach_port_dnrequest_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_dnrequest_info +( + ipc_space_t task, + mach_port_name_t name, + unsigned *dnr_total, + unsigned *dnr_used +); + +/* Routine mach_port_kernel_object */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_kernel_object +( + ipc_space_inspect_t task, + mach_port_name_t name, + unsigned *object_type, + unsigned *object_addr +); + +/* Routine mach_port_insert_member */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_insert_member +( + ipc_space_t task, + mach_port_name_t name, + mach_port_name_t pset +); + +/* Routine mach_port_extract_member */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_extract_member +( + ipc_space_t task, + mach_port_name_t name, + mach_port_name_t pset +); + +/* Routine mach_port_get_context */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_get_context +( + ipc_space_inspect_t task, + mach_port_name_t name, + mach_port_context_t *context +); + +/* Routine mach_port_set_context */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_set_context +( + ipc_space_t task, + mach_port_name_t name, + mach_port_context_t context +); + +/* Routine mach_port_kobject */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_kobject +( + ipc_space_inspect_t task, + mach_port_name_t name, + natural_t *object_type, + mach_vm_address_t *object_addr +); + +/* Routine mach_port_construct */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_construct +( + ipc_space_t task, + mach_port_options_ptr_t options, + mach_port_context_t context, + mach_port_name_t *name +); + +/* Routine mach_port_destruct */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_destruct +( + ipc_space_t task, + mach_port_name_t name, + mach_port_delta_t srdelta, + mach_port_context_t guard +); + +/* Routine mach_port_guard */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_guard +( + ipc_space_t task, + mach_port_name_t name, + mach_port_context_t guard, + boolean_t strict +); + +/* Routine mach_port_unguard */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_unguard +( + ipc_space_t task, + mach_port_name_t name, + mach_port_context_t guard +); + +/* Routine mach_port_space_basic_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_space_basic_info +( + ipc_space_inspect_t task, + ipc_info_space_basic_t *basic_info +); + +/* Routine mach_port_guard_with_flags */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_guard_with_flags +( + ipc_space_t task, + mach_port_name_t name, + mach_port_context_t guard, + uint64_t flags +); + +/* Routine mach_port_swap_guard */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_swap_guard +( + ipc_space_t task, + mach_port_name_t name, + mach_port_context_t old_guard, + mach_port_context_t new_guard +); + +/* Routine mach_port_kobject_description */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_port_kobject_description +( + ipc_space_inspect_t task, + mach_port_name_t name, + natural_t *object_type, + mach_vm_address_t *object_addr, + kobject_description_t description +); + +__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_port_subsystem__defined +#define __Request__mach_port_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__mach_port_names_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + } __Request__mach_port_type_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t old_name; + mach_port_name_t new_name; + } __Request__mach_port_rename_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_right_t right; + mach_port_name_t name; + } __Request__mach_port_allocate_name_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_right_t right; + } __Request__mach_port_allocate_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + } __Request__mach_port_destroy_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + } __Request__mach_port_deallocate_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + mach_port_right_t right; + } __Request__mach_port_get_refs_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + mach_port_right_t right; + mach_port_delta_t delta; + } __Request__mach_port_mod_refs_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + mach_msg_trailer_type_t trailer_type; + mach_port_seqno_t request_seqnop; + mach_msg_type_number_t trailer_infopCnt; + } __Request__mach_port_peek_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + mach_port_mscount_t mscount; + } __Request__mach_port_set_mscount_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + } __Request__mach_port_get_set_status_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t member; + mach_port_name_t after; + } __Request__mach_port_move_member_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 notify; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_port_name_t name; + mach_msg_id_t msgid; + mach_port_mscount_t sync; + } __Request__mach_port_request_notification_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 poly; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_port_name_t name; + } __Request__mach_port_insert_right_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + mach_msg_type_name_t msgt_name; + } __Request__mach_port_extract_right_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + mach_port_seqno_t seqno; + } __Request__mach_port_set_seqno_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + mach_port_flavor_t flavor; + mach_msg_type_number_t port_info_outCnt; + } __Request__mach_port_get_attributes_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + mach_port_flavor_t flavor; + mach_msg_type_number_t port_infoCnt; + integer_t port_info[17]; + } __Request__mach_port_set_attributes_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_right_t right; + mach_port_qos_t qos; + } __Request__mach_port_allocate_qos_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 proto; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_port_right_t right; + mach_port_qos_t qos; + mach_port_name_t name; + } __Request__mach_port_allocate_full_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int table_entries; + } __Request__task_set_port_space_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + } __Request__mach_port_get_srights_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__mach_port_space_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + } __Request__mach_port_dnrequest_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + } __Request__mach_port_kernel_object_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + mach_port_name_t pset; + } __Request__mach_port_insert_member_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + mach_port_name_t pset; + } __Request__mach_port_extract_member_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + } __Request__mach_port_get_context_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + mach_port_context_t context; + } __Request__mach_port_set_context_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + } __Request__mach_port_kobject_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 options; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_port_context_t context; + } __Request__mach_port_construct_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + mach_port_delta_t srdelta; + mach_port_context_t guard; + } __Request__mach_port_destruct_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + mach_port_context_t guard; + boolean_t strict; + } __Request__mach_port_guard_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + mach_port_context_t guard; + } __Request__mach_port_unguard_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__mach_port_space_basic_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + mach_port_context_t guard; + uint64_t flags; + } __Request__mach_port_guard_with_flags_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + mach_port_context_t old_guard; + mach_port_context_t new_guard; + } __Request__mach_port_swap_guard_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t name; + } __Request__mach_port_kobject_description_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Request__mach_port_subsystem__defined */ + +/* union of all requests */ + +#ifndef __RequestUnion__mach_port_subsystem__defined +#define __RequestUnion__mach_port_subsystem__defined +union __RequestUnion__mach_port_subsystem { + __Request__mach_port_names_t Request_mach_port_names; + __Request__mach_port_type_t Request_mach_port_type; + __Request__mach_port_rename_t Request_mach_port_rename; + __Request__mach_port_allocate_name_t Request_mach_port_allocate_name; + __Request__mach_port_allocate_t Request_mach_port_allocate; + __Request__mach_port_destroy_t Request_mach_port_destroy; + __Request__mach_port_deallocate_t Request_mach_port_deallocate; + __Request__mach_port_get_refs_t Request_mach_port_get_refs; + __Request__mach_port_mod_refs_t Request_mach_port_mod_refs; + __Request__mach_port_peek_t Request_mach_port_peek; + __Request__mach_port_set_mscount_t Request_mach_port_set_mscount; + __Request__mach_port_get_set_status_t Request_mach_port_get_set_status; + __Request__mach_port_move_member_t Request_mach_port_move_member; + __Request__mach_port_request_notification_t Request_mach_port_request_notification; + __Request__mach_port_insert_right_t Request_mach_port_insert_right; + __Request__mach_port_extract_right_t Request_mach_port_extract_right; + __Request__mach_port_set_seqno_t Request_mach_port_set_seqno; + __Request__mach_port_get_attributes_t Request_mach_port_get_attributes; + __Request__mach_port_set_attributes_t Request_mach_port_set_attributes; + __Request__mach_port_allocate_qos_t Request_mach_port_allocate_qos; + __Request__mach_port_allocate_full_t Request_mach_port_allocate_full; + __Request__task_set_port_space_t Request_task_set_port_space; + __Request__mach_port_get_srights_t Request_mach_port_get_srights; + __Request__mach_port_space_info_t Request_mach_port_space_info; + __Request__mach_port_dnrequest_info_t Request_mach_port_dnrequest_info; + __Request__mach_port_kernel_object_t Request_mach_port_kernel_object; + __Request__mach_port_insert_member_t Request_mach_port_insert_member; + __Request__mach_port_extract_member_t Request_mach_port_extract_member; + __Request__mach_port_get_context_t Request_mach_port_get_context; + __Request__mach_port_set_context_t Request_mach_port_set_context; + __Request__mach_port_kobject_t Request_mach_port_kobject; + __Request__mach_port_construct_t Request_mach_port_construct; + __Request__mach_port_destruct_t Request_mach_port_destruct; + __Request__mach_port_guard_t Request_mach_port_guard; + __Request__mach_port_unguard_t Request_mach_port_unguard; + __Request__mach_port_space_basic_info_t Request_mach_port_space_basic_info; + __Request__mach_port_guard_with_flags_t Request_mach_port_guard_with_flags; + __Request__mach_port_swap_guard_t Request_mach_port_swap_guard; + __Request__mach_port_kobject_description_t Request_mach_port_kobject_description; +}; +#endif /* !__RequestUnion__mach_port_subsystem__defined */ +/* typedefs for all replies */ + +#ifndef __Reply__mach_port_subsystem__defined +#define __Reply__mach_port_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 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 names; + mach_msg_ool_descriptor_t types; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t namesCnt; + mach_msg_type_number_t typesCnt; + } __Reply__mach_port_names_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_port_type_t ptype; + } __Reply__mach_port_type_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_port_rename_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_port_allocate_name_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_port_name_t name; + } __Reply__mach_port_allocate_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_port_destroy_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_port_deallocate_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_port_urefs_t refs; + } __Reply__mach_port_get_refs_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_port_mod_refs_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_port_seqno_t request_seqnop; + mach_msg_size_t msg_sizep; + mach_msg_id_t msg_idp; + mach_msg_type_number_t trailer_infopCnt; + char trailer_infop[68]; + } __Reply__mach_port_peek_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_port_set_mscount_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 members; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t membersCnt; + } __Reply__mach_port_get_set_status_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_port_move_member_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 previous; + /* end of the kernel processed data */ + } __Reply__mach_port_request_notification_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_port_insert_right_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 poly; + /* end of the kernel processed data */ + } __Reply__mach_port_extract_right_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_port_set_seqno_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t port_info_outCnt; + integer_t port_info_out[17]; + } __Reply__mach_port_get_attributes_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_port_set_attributes_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_port_qos_t qos; + mach_port_name_t name; + } __Reply__mach_port_allocate_qos_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_port_qos_t qos; + mach_port_name_t name; + } __Reply__mach_port_allocate_full_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__task_set_port_space_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_port_rights_t srights; + } __Reply__mach_port_get_srights_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 table_info; + mach_msg_ool_descriptor_t tree_info; + /* end of the kernel processed data */ + NDR_record_t NDR; + ipc_info_space_t space_info; + mach_msg_type_number_t table_infoCnt; + mach_msg_type_number_t tree_infoCnt; + } __Reply__mach_port_space_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + unsigned dnr_total; + unsigned dnr_used; + } __Reply__mach_port_dnrequest_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + unsigned object_type; + unsigned object_addr; + } __Reply__mach_port_kernel_object_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_port_insert_member_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_port_extract_member_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_port_context_t context; + } __Reply__mach_port_get_context_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_port_set_context_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + natural_t object_type; + mach_vm_address_t object_addr; + } __Reply__mach_port_kobject_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_port_name_t name; + } __Reply__mach_port_construct_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_port_destruct_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_port_guard_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_port_unguard_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + ipc_info_space_basic_t basic_info; + } __Reply__mach_port_space_basic_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_port_guard_with_flags_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_port_swap_guard_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + natural_t object_type; + mach_vm_address_t object_addr; + mach_msg_type_number_t descriptionOffset; /* MiG doesn't use it */ + mach_msg_type_number_t descriptionCnt; + char description[512]; + } __Reply__mach_port_kobject_description_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Reply__mach_port_subsystem__defined */ + +/* union of all replies */ + +#ifndef __ReplyUnion__mach_port_subsystem__defined +#define __ReplyUnion__mach_port_subsystem__defined +union __ReplyUnion__mach_port_subsystem { + __Reply__mach_port_names_t Reply_mach_port_names; + __Reply__mach_port_type_t Reply_mach_port_type; + __Reply__mach_port_rename_t Reply_mach_port_rename; + __Reply__mach_port_allocate_name_t Reply_mach_port_allocate_name; + __Reply__mach_port_allocate_t Reply_mach_port_allocate; + __Reply__mach_port_destroy_t Reply_mach_port_destroy; + __Reply__mach_port_deallocate_t Reply_mach_port_deallocate; + __Reply__mach_port_get_refs_t Reply_mach_port_get_refs; + __Reply__mach_port_mod_refs_t Reply_mach_port_mod_refs; + __Reply__mach_port_peek_t Reply_mach_port_peek; + __Reply__mach_port_set_mscount_t Reply_mach_port_set_mscount; + __Reply__mach_port_get_set_status_t Reply_mach_port_get_set_status; + __Reply__mach_port_move_member_t Reply_mach_port_move_member; + __Reply__mach_port_request_notification_t Reply_mach_port_request_notification; + __Reply__mach_port_insert_right_t Reply_mach_port_insert_right; + __Reply__mach_port_extract_right_t Reply_mach_port_extract_right; + __Reply__mach_port_set_seqno_t Reply_mach_port_set_seqno; + __Reply__mach_port_get_attributes_t Reply_mach_port_get_attributes; + __Reply__mach_port_set_attributes_t Reply_mach_port_set_attributes; + __Reply__mach_port_allocate_qos_t Reply_mach_port_allocate_qos; + __Reply__mach_port_allocate_full_t Reply_mach_port_allocate_full; + __Reply__task_set_port_space_t Reply_task_set_port_space; + __Reply__mach_port_get_srights_t Reply_mach_port_get_srights; + __Reply__mach_port_space_info_t Reply_mach_port_space_info; + __Reply__mach_port_dnrequest_info_t Reply_mach_port_dnrequest_info; + __Reply__mach_port_kernel_object_t Reply_mach_port_kernel_object; + __Reply__mach_port_insert_member_t Reply_mach_port_insert_member; + __Reply__mach_port_extract_member_t Reply_mach_port_extract_member; + __Reply__mach_port_get_context_t Reply_mach_port_get_context; + __Reply__mach_port_set_context_t Reply_mach_port_set_context; + __Reply__mach_port_kobject_t Reply_mach_port_kobject; + __Reply__mach_port_construct_t Reply_mach_port_construct; + __Reply__mach_port_destruct_t Reply_mach_port_destruct; + __Reply__mach_port_guard_t Reply_mach_port_guard; + __Reply__mach_port_unguard_t Reply_mach_port_unguard; + __Reply__mach_port_space_basic_info_t Reply_mach_port_space_basic_info; + __Reply__mach_port_guard_with_flags_t Reply_mach_port_guard_with_flags; + __Reply__mach_port_swap_guard_t Reply_mach_port_swap_guard; + __Reply__mach_port_kobject_description_t Reply_mach_port_kobject_description; +}; +#endif /* !__RequestUnion__mach_port_subsystem__defined */ + +#ifndef subsystem_to_name_map_mach_port +#define subsystem_to_name_map_mach_port \ + { "mach_port_names", 3200 },\ + { "mach_port_type", 3201 },\ + { "mach_port_rename", 3202 },\ + { "mach_port_allocate_name", 3203 },\ + { "mach_port_allocate", 3204 },\ + { "mach_port_destroy", 3205 },\ + { "mach_port_deallocate", 3206 },\ + { "mach_port_get_refs", 3207 },\ + { "mach_port_mod_refs", 3208 },\ + { "mach_port_peek", 3209 },\ + { "mach_port_set_mscount", 3210 },\ + { "mach_port_get_set_status", 3211 },\ + { "mach_port_move_member", 3212 },\ + { "mach_port_request_notification", 3213 },\ + { "mach_port_insert_right", 3214 },\ + { "mach_port_extract_right", 3215 },\ + { "mach_port_set_seqno", 3216 },\ + { "mach_port_get_attributes", 3217 },\ + { "mach_port_set_attributes", 3218 },\ + { "mach_port_allocate_qos", 3219 },\ + { "mach_port_allocate_full", 3220 },\ + { "task_set_port_space", 3221 },\ + { "mach_port_get_srights", 3222 },\ + { "mach_port_space_info", 3223 },\ + { "mach_port_dnrequest_info", 3224 },\ + { "mach_port_kernel_object", 3225 },\ + { "mach_port_insert_member", 3226 },\ + { "mach_port_extract_member", 3227 },\ + { "mach_port_get_context", 3228 },\ + { "mach_port_set_context", 3229 },\ + { "mach_port_kobject", 3230 },\ + { "mach_port_construct", 3231 },\ + { "mach_port_destruct", 3232 },\ + { "mach_port_guard", 3233 },\ + { "mach_port_unguard", 3234 },\ + { "mach_port_space_basic_info", 3235 },\ + { "mach_port_guard_with_flags", 3237 },\ + { "mach_port_swap_guard", 3238 },\ + { "mach_port_kobject_description", 3239 } +#endif + +#ifdef __AfterMigUserHeader +__AfterMigUserHeader +#endif /* __AfterMigUserHeader */ + +#endif /* _mach_port_user_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_right.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_right.h new file mode 100644 index 00000000..8f449e5f --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_right.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2018 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +#ifndef __MACH_RIGHT_H +#define __MACH_RIGHT_H + +#include + +#if __has_include() +#include +#endif + +#endif // __MACH_RIGHT_H diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_syscalls.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_syscalls.h new file mode 100644 index 00000000..29399ce8 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_syscalls.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ + +#ifndef _MACH_MACH_SYSCALLS_H_ +#define _MACH_MACH_SYSCALLS_H_ + +#include + +#endif /* _MACH_MACH_SYSCALLS_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_time.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_time.h new file mode 100644 index 00000000..2853aac3 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_time.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2001-2005 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _MACH_MACH_TIME_H_ +#define _MACH_MACH_TIME_H_ + +#include +#include +#include + +struct mach_timebase_info { + uint32_t numer; + uint32_t denom; +}; + +typedef struct mach_timebase_info *mach_timebase_info_t; +typedef struct mach_timebase_info mach_timebase_info_data_t; + +__BEGIN_DECLS + +kern_return_t mach_timebase_info( + mach_timebase_info_t info); + +kern_return_t mach_wait_until( + uint64_t deadline); + + +uint64_t mach_absolute_time(void); + +__OSX_AVAILABLE_STARTING(__MAC_10_10, __IPHONE_8_0) +uint64_t mach_approximate_time(void); + +/* + * like mach_absolute_time, but advances during sleep + */ +__OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) +uint64_t mach_continuous_time(void); + +/* + * like mach_approximate_time, but advances during sleep + */ +__OSX_AVAILABLE(10.12) __IOS_AVAILABLE(10.0) __TVOS_AVAILABLE(10.0) __WATCHOS_AVAILABLE(3.0) +uint64_t mach_continuous_approximate_time(void); + + +__END_DECLS + +#endif /* _MACH_MACH_TIME_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_traps.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_traps.h new file mode 100644 index 00000000..e38647c7 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_traps.h @@ -0,0 +1,303 @@ +/* + * Copyright (c) 2000-2019 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * Definitions of general Mach system traps. + * + * These are the definitions as seen from user-space. + * The kernel definitions are in . + * Kernel RPC functions are defined in . + */ + +#ifndef _MACH_MACH_TRAPS_H_ +#define _MACH_MACH_TRAPS_H_ + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include + +__BEGIN_DECLS + + + +extern kern_return_t clock_sleep_trap( + mach_port_name_t clock_name, + sleep_type_t sleep_type, + int sleep_sec, + int sleep_nsec, + mach_timespec_t *wakeup_time); + +extern kern_return_t _kernelrpc_mach_vm_allocate_trap( + mach_port_name_t target, + mach_vm_offset_t *addr, + mach_vm_size_t size, + int flags); + +extern kern_return_t _kernelrpc_mach_vm_deallocate_trap( + mach_port_name_t target, + mach_vm_address_t address, + mach_vm_size_t size + ); + +extern kern_return_t _kernelrpc_mach_vm_protect_trap( + mach_port_name_t target, + mach_vm_address_t address, + mach_vm_size_t size, + boolean_t set_maximum, + vm_prot_t new_protection + ); + +extern kern_return_t _kernelrpc_mach_vm_map_trap( + mach_port_name_t target, + mach_vm_offset_t *address, + mach_vm_size_t size, + mach_vm_offset_t mask, + int flags, + vm_prot_t cur_protection + ); + +extern kern_return_t _kernelrpc_mach_vm_purgable_control_trap( + mach_port_name_t target, + mach_vm_offset_t address, + vm_purgable_t control, + int *state); + +extern kern_return_t _kernelrpc_mach_port_allocate_trap( + mach_port_name_t target, + mach_port_right_t right, + mach_port_name_t *name + ); + + +extern kern_return_t _kernelrpc_mach_port_destroy_trap( + mach_port_name_t target, + mach_port_name_t name + ); + +extern kern_return_t _kernelrpc_mach_port_deallocate_trap( + mach_port_name_t target, + mach_port_name_t name + ); + +extern kern_return_t _kernelrpc_mach_port_mod_refs_trap( + mach_port_name_t target, + mach_port_name_t name, + mach_port_right_t right, + mach_port_delta_t delta + ); + +extern kern_return_t _kernelrpc_mach_port_move_member_trap( + mach_port_name_t target, + mach_port_name_t member, + mach_port_name_t after + ); + +extern kern_return_t _kernelrpc_mach_port_insert_right_trap( + mach_port_name_t target, + mach_port_name_t name, + mach_port_name_t poly, + mach_msg_type_name_t polyPoly + ); + +extern kern_return_t _kernelrpc_mach_port_get_attributes_trap( + mach_port_name_t target, + mach_port_name_t name, + mach_port_flavor_t flavor, + mach_port_info_t port_info_out, + mach_msg_type_number_t *port_info_outCnt + ); + +extern kern_return_t _kernelrpc_mach_port_insert_member_trap( + mach_port_name_t target, + mach_port_name_t name, + mach_port_name_t pset + ); + +extern kern_return_t _kernelrpc_mach_port_extract_member_trap( + mach_port_name_t target, + mach_port_name_t name, + mach_port_name_t pset + ); + +extern kern_return_t _kernelrpc_mach_port_construct_trap( + mach_port_name_t target, + mach_port_options_t *options, + uint64_t context, + mach_port_name_t *name + ); + +extern kern_return_t _kernelrpc_mach_port_destruct_trap( + mach_port_name_t target, + mach_port_name_t name, + mach_port_delta_t srdelta, + uint64_t guard + ); + +extern kern_return_t _kernelrpc_mach_port_guard_trap( + mach_port_name_t target, + mach_port_name_t name, + uint64_t guard, + boolean_t strict + ); + +extern kern_return_t _kernelrpc_mach_port_unguard_trap( + mach_port_name_t target, + mach_port_name_t name, + uint64_t guard + ); + +extern kern_return_t mach_generate_activity_id( + mach_port_name_t target, + int count, + uint64_t *activity_id + ); + +extern kern_return_t macx_swapon( + uint64_t filename, + int flags, + int size, + int priority); + +extern kern_return_t macx_swapoff( + uint64_t filename, + int flags); + +extern kern_return_t macx_triggers( + int hi_water, + int low_water, + int flags, + mach_port_t alert_port); + +extern kern_return_t macx_backing_store_suspend( + boolean_t suspend); + +extern kern_return_t macx_backing_store_recovery( + int pid); + +extern boolean_t swtch_pri(int pri); + +extern boolean_t swtch(void); + +extern kern_return_t thread_switch( + mach_port_name_t thread_name, + int option, + mach_msg_timeout_t option_time); + +extern mach_port_name_t task_self_trap(void); + +extern kern_return_t host_create_mach_voucher_trap( + mach_port_name_t host, + mach_voucher_attr_raw_recipe_array_t recipes, + int recipes_size, + mach_port_name_t *voucher); + +extern kern_return_t mach_voucher_extract_attr_recipe_trap( + mach_port_name_t voucher_name, + mach_voucher_attr_key_t key, + mach_voucher_attr_raw_recipe_t recipe, + mach_msg_type_number_t *recipe_size); + +extern kern_return_t _kernelrpc_mach_port_type_trap( + ipc_space_t task, + mach_port_name_t name, + mach_port_type_t *ptype); + +extern kern_return_t _kernelrpc_mach_port_request_notification_trap( + ipc_space_t task, + mach_port_name_t name, + mach_msg_id_t msgid, + mach_port_mscount_t sync, + mach_port_name_t notify, + mach_msg_type_name_t notifyPoly, + mach_port_name_t *previous); + +/* + * Obsolete interfaces. + */ + +extern kern_return_t task_for_pid( + mach_port_name_t target_tport, + int pid, + mach_port_name_t *t); + +extern kern_return_t task_name_for_pid( + mach_port_name_t target_tport, + int pid, + mach_port_name_t *tn); + +extern kern_return_t pid_for_task( + mach_port_name_t t, + int *x); + +extern kern_return_t debug_control_port_for_pid( + mach_port_name_t target_tport, + int pid, + mach_port_name_t *t); + + +__END_DECLS + +#endif /* _MACH_MACH_TRAPS_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_types.defs b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_types.defs new file mode 100644 index 00000000..b8dddaa3 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_types.defs @@ -0,0 +1,618 @@ +/* + * Copyright (c) 2000-2016 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * NOTICE: This file was modified by McAfee Research in 2004 to introduce + * support for mandatory and extensible security protections. This notice + * is included in support of clause 2.2 (b) of the Apple Public License, + * Version 2.0. + */ +/* + */ +/* + * Mach kernel interface type declarations + */ + +#ifndef _MACH_MACH_TYPES_DEFS_ +#define _MACH_MACH_TYPES_DEFS_ + + +#include + +type memory_object_offset_t = uint64_t; +type memory_object_size_t = uint64_t; +type memory_object_cluster_size_t = uint32_t; +type memory_object_fault_info_t = array[16] of integer_t; + + +type mach_port_status_t = struct[10] of integer_t; /* obsolete */ +type mach_port_info_ext_t = struct[17] of integer_t; + + /* mach_port_info_t: can hold either a + * mach_port_status_t (9 ints) or a + * mach_port_limits_t (1 int) or a + * mach_port_info_ext_t (17 ints). If new flavors of + * mach_port_{get,set}_attributes are added, the size of + * this array may have to be increased. (See mach/port.h) + */ +type mach_port_flavor_t = int; +type mach_port_info_t = array[*:17] of integer_t; + + /* + * mach_msg_max_trailer_t: can hold + * mach_msg_trailer_type_t (1 int) + * mach_msg_trailer_size_t (1 int) + * mach_port_seqno_t (1 int) + * security_token_t (2 ints) + * audit_token_t (8 ints) + * mach_port_context_t (2 ints) + * msgh_ad (1 int) + * msg_labels_t (1 int) + */ +type mach_msg_trailer_type_t = int; +type mach_msg_trailer_info_t = array[*:68] of char; + +type task_t = mach_port_t +#if KERNEL_SERVER + intran: task_t convert_port_to_task(mach_port_t) + outtran: mach_port_t convert_task_to_port(task_t) + destructor: task_deallocate(task_t) +#endif /* KERNEL_SERVER */ + ; + +type task_name_t = mach_port_t +#if KERNEL_SERVER + intran: task_name_t convert_port_to_task_name(mach_port_t) + outtran: mach_port_t convert_task_name_to_port(task_name_t) + destructor: task_name_deallocate(task_name_t) +#endif /* KERNEL_SERVER */ + ; + +type task_inspect_t = mach_port_t +#if KERNEL_SERVER + intran: task_inspect_t convert_port_to_task_inspect(mach_port_t) + outtran: mach_port_t convert_task_inspect_to_port(task_inspect_t) + destructor: task_inspect_deallocate(task_inspect_t) +#endif /* KERNEL_SERVER */ + ; + +type thread_t = mach_port_t +#if KERNEL_SERVER + intran: thread_t convert_port_to_thread(mach_port_t) + outtran: mach_port_t convert_thread_to_port(thread_t) + destructor: thread_deallocate(thread_t) +#endif /* KERNEL_SERVER */ + ; + +type thread_inspect_t = mach_port_t +#if KERNEL_SERVER + intran: thread_inspect_t convert_port_to_thread_inspect(mach_port_t) + outtran: mach_port_t convert_thread_inspect_to_port(thread_inspect_t) + destructor: thread_inspect_deallocate(thread_inspect_t) +#endif /* KERNEL_SERVER */ + ; + +type thread_act_t = mach_port_t +#if KERNEL_SERVER + intran: thread_act_t convert_port_to_thread(mach_port_t) + outtran: mach_port_t convert_thread_to_port(thread_act_t) + destructor: thread_deallocate(thread_act_t) +#endif /* KERNEL_SERVER */ + ; + +type thread_act_consume_ref_t = mach_port_move_send_t + cusertype: thread_act_t +#if KERNEL_SERVER + intran: thread_act_t convert_port_to_thread(mach_port_t) + destructor: thread_deallocate(thread_act_t) +#endif /* KERNEL_SERVER */ + ; + +type suid_cred_path_t = c_string[*:1024]; +type suid_cred_uid_t = uint32_t; +type suid_cred_t = mach_port_t +#if KERNEL_SERVER + outtran: mach_port_t convert_suid_cred_to_port(suid_cred_t) +#endif /* KERNEL_SERVER */ + ; + + + /* thread_state_t: This inline array can hold + * a machine-dependent amount of data, defined in + * mach/machine/???? (currently THREAD_STATE_MAX, + * in mach/thread_state.h) + */ +#include +type thread_state_flavor_t = int; +type thread_state_t = array[*:THREAD_STATE_MAX] of natural_t; + +type task_array_t = ^array[] of task_t; +type thread_array_t = ^array[] of thread_t; +type thread_act_array_t = ^array[] of thread_act_t; +type act_params_t = array[6] of int; + +type vm_map_t = mach_port_t +#if KERNEL_SERVER + intran: vm_map_t convert_port_to_map(mach_port_t) + destructor: vm_map_deallocate(vm_map_t) +#endif /* KERNEL_SERVER */ + ; + +type vm_task_entry_t = mach_port_t + cusertype: vm_map_t +#if KERNEL_SERVER + intran: vm_map_t convert_port_entry_to_map(mach_port_t) + destructor: vm_map_deallocate(vm_map_t) +#endif /* KERNEL_SERVER */ + ; + +type ipc_space_t = mach_port_t +#if KERNEL_SERVER + intran: ipc_space_t convert_port_to_space(mach_port_t) + destructor: space_deallocate(ipc_space_t) +#endif /* KERNEL_SERVER */ + ; + +type ipc_space_inspect_t = mach_port_t +#if KERNEL_SERVER + intran: ipc_space_inspect_t convert_port_to_space_inspect(mach_port_t) + destructor: space_inspect_deallocate(ipc_space_inspect_t) +#endif /* KERNEL_SERVER */ + ; + +type arcade_register_t = mach_port_t +#if KERNEL_SERVER + intran: arcade_register_t convert_port_to_arcade_register(mach_port_t) +#endif /* KERNEL_SERVER */ + ; + +type vm_prot_t = int; +type vm_inherit_t = int; +type vm_purgable_t = int; +type xxx_vm_statistics_data_t = struct[13] of integer_t; +type vm_behavior_t = int; +type vm_statistics_data_t = struct[15] of integer_t; +type vm_machine_attribute_t = int; +type vm_machine_attribute_val_t = int; +type vm_sync_t = int; + + /* thread_info_t: this inline array can hold any of: + * thread_basic_info_t (10 ints) + * policy_timeshare_info_t (5 ints) + * policy_fifo_info_t (4 ints) + * policy_rr_info_t (5 ints) + * thread_extended_info (12 ints + 64 chars) + * if other thread_info flavors are added, this + * definition may need to be changed. (See + * mach/thread_info.h and mach/policy.h) */ +type thread_flavor_t = int; +type thread_info_t = array[*:32] of integer_t; + +type thread_policy_flavor_t = natural_t; +type thread_policy_t = array[*:16] of integer_t; + + /* task_info_t: this inline array can hold any of: + * task_basic_info_32_t (8 ints) + * task_basic_info_64_t (10 ints) + * task_events_info_t (8 ints) + * task_thread_times_info_t (4 ints) + * policy_timeshare_info_t (5 ints) + * policy_fifo_info_t (4 ints) + * policy_rr_info_t (5 ints) + * task security token (2 ints) + * task audit token (8 ints) + * dyld info (2 64-bit ints and 1 int) + * task_extmod_info_t (8 64-bit ints) + * task_basic_info_64_2_t + * mach_task_basic_info_t (12 ints) + * task_power_info_t (18 ints) + * task_vm_info_t (87 ints) + * If other task_info flavors are added, this + * definition may need to be changed. (See + * mach/task_info.h and mach/policy.h) */ +type task_flavor_t = int; +type task_info_t = array[*:87] of integer_t; + +type task_purgable_info_t = struct[68] of integer_t; + +type task_policy_flavor_t = natural_t; +type task_policy_t = array[*:16] of integer_t; + +type task_inspect_flavor_t = natural_t; +type task_inspect_info_t = array[*:4] of integer_t; + +type task_exc_guard_behavior_t = uint32_t; + +type mem_entry_name_port_t = mach_port_t +#if KERNEL_SERVER + intran: mem_entry_name_port_t null_conversion(mach_port_t) + outtran: mach_port_t null_conversion(mem_entry_name_port_t) +#endif /* KERNEL_SERVER */ + ; + +type mem_entry_name_port_move_send_t = mach_port_move_send_t + cusertype: mem_entry_name_port_t +#if KERNEL_SERVER + intran: mem_entry_name_port_t null_conversion(mach_port_t) + outtran: mach_port_t null_conversion(mem_entry_name_port_t) +#endif /* KERNEL_SERVER */ + ; + +type memory_object_default_t = mach_port_t + ; + +type memory_object_t = mach_port_t + ; + + +type memory_object_control_t = mach_port_t + ; + +type memory_object_name_t = mach_port_t + ctype: mach_port_t + ; + + +type memory_object_copy_strategy_t = int; +type memory_object_return_t = int; + +type machine_info_data_t = struct[5] of integer_t; +type machine_slot_data_t = struct[8] of integer_t; + +type host_t = mach_port_t +#if KERNEL_SERVER + intran: host_t convert_port_to_host(mach_port_t) + outtran: mach_port_t convert_host_to_port(host_t) +#endif /* KERNEL_SERVER */ + ; + +type host_priv_t = mach_port_t +#if KERNEL_SERVER + intran: host_priv_t convert_port_to_host_priv(mach_port_t) +#endif /* KERNEL_SERVER */ + ; + +type host_security_t = mach_port_t +#if KERNEL_SERVER + intran: host_security_t convert_port_to_host_security(mach_port_t) +#endif /* KERNEL_SERVER */ + ; + + /* + * host_info_t: variable-sized inline array that can contain: + * + * host_basic_info_old_t (5 ints) + * host_basic_info_t (12 ints) + * host_sched_info_t (2 ints) + * kernel_resource_sizes_t (5 ints) + * host_load_info_t (6 ints) + * vm_statistics32_t (15 ints) + * host_purgable_info_t (68 ints) + * host_expired_task_info uses a task_power_info (18 ints) + * + * If other host_info flavors are added, this definition may + * need to be changed. (See mach/{host_info,vm_statistics}.h) + */ +type host_flavor_t = int; +type host_info_t = array[*:68] of integer_t; + /* + * host_info64_t: variable-sized inline array that can contain: + * + * vm_statistics_t (6 ints and 9 longs) + * vm_extmod_statistics_t (6 64-bit ints) + */ +type host_info64_t = array[*:256] of integer_t; + +type processor_t = mach_port_t +#if KERNEL_SERVER + intran: processor_t convert_port_to_processor(mach_port_t) + outtran: mach_port_t convert_processor_to_port(processor_t) +#endif /* KERNEL_SERVER */ + ; + +type processor_array_t = ^array[] of processor_t; + + /* + * processor_info_t: variable-sized inline array that can + * contain: + * + * - processor_basic_info_t: (5 ints) + * - processor_cpu_load_info_t: (4 ints) + * - processor_machine_info_t: (12 ints) + * - processor_cpu_stat_t: (10 ints) + * - processor_cpu_stat64_t: (20 ints) + * + * If other processor_info flavors are added, this definition + * may need to be changed. + * + * See mach/processor_info.h and mach/arm/processor_info.h. + */ + +type processor_flavor_t = int; +type processor_info_t = array[*:20] of integer_t; +type processor_info_array_t = ^array[] of integer_t; + +type processor_set_t = mach_port_t +#if KERNEL_SERVER + intran: processor_set_t convert_port_to_pset(mach_port_t) + outtran: mach_port_t convert_pset_to_port(processor_set_t) + destructor: pset_deallocate(processor_set_t) +#endif /* KERNEL_SERVER */ + ; + +type processor_set_array_t = ^array[] of processor_set_t; + +type processor_set_name_t = mach_port_t +#if KERNEL_SERVER + intran: processor_set_name_t convert_port_to_pset_name(mach_port_t) + outtran: mach_port_t convert_pset_name_to_port(processor_set_name_t) + destructor: pset_deallocate(processor_set_name_t) +#endif /* KERNEL_SERVER */ + ; + +type processor_set_name_array_t = ^array[] of processor_set_name_t; + + /* processor_set_info_t: variable-size inline array + * that can hold: + * processor_set_basic_info (5 ints) + * processor_set_load_info (4 ints) + * policy_timeshare_base_t (1 int) + * policy_fifo_base_t (1 int) + * policy_rr_base_t (1 int) + * policy_timeshare_base_t (1 int) + * policy_fifo_base_t (1 int) + * policy_rr_base_t (1 int) + * policy_t (1 int) + * If other flavors are added, this definition may + * need to be changed. (see mach/processor.h) */ +type processor_set_flavor_t = int; +type processor_set_info_t = array[*:5] of integer_t; + +type bootstrap_t = mach_port_t; + +type kernel_version_t = c_string[*:512]; +type kernel_boot_info_t = c_string[*:4096]; + +type time_value_t = struct[2] of integer_t; + +type mach_port_qos_t = struct[2] of integer_t; + +type mach_port_options_t = struct[3] of uint64_t; +type mach_port_options_ptr_t = ^ mach_port_options_t; + +type emulation_vector_t = ^array[] of vm_offset_t; + +type inline_existence_map_t = array[*:512] of char; + +type policy_t = int; + /* policy_info_t: variable-size inline array. Can hold: + * policy_timeshare_info_t (5 ints) + * policy_fifo_info_t (4 ints) + * policy_rr_info_t (5 ints) */ +type policy_base_t = array[*:5] of integer_t; +type policy_info_t = array[*:2] of integer_t; +type policy_limit_t = array[*:1] of integer_t; + +type ledger_t = mach_port_t +#if KERNEL_SERVER + intran: ledger_t convert_port_to_ledger(mach_port_t) + outtran: mach_port_t convert_ledger_to_port(ledger_t) +#endif /* KERNEL_SERVER */ + ; + +type ledger_array_t = ^array[] of ledger_t; +type ledger_item_t = integer_t; + /* DEPRECATED */ + +type ledger_amount_t = int64_t; + +type security_token_t = struct[2] of uint32_t; +type audit_token_t = struct[8] of uint32_t; + +type msg_labels_t = mach_port_t; + + /* memory_object_info_t: variable-size inline array: + * memory_object_attr_info_t (5 ints) + * XXX actually it's 6 ints temporarily (object_ready!) + * memory_object_behave_info_t (4 ints) + * memory_object_perf_info_t (2 ints) + * old_memory_object_attr_info_t (3 ints) + * If other flavors are added, this definition may + * need to be changed. (see mach/memory_object.h) */ +type memory_object_flavor_t = int; +type memory_object_info_t = array[*:6] of int; + + /* vm_region_info_t: variable-size inline array that can hold: + * vm_region_basic_info_t (8 ints) + * If other flavors are added, this definition may + * need to be changed. (see mach/vm_region.h) */ +type vm_region_flavor_t = int; +type vm_region_info_t = array[*:10] of int; +type vm_region_recurse_info_t = array[*:19] of int; + +type vm_page_info_flavor_t = int; +type vm_page_info_t = array[*:32] of int; + +type mach_vm_read_entry_t = array[512] of mach_vm_offset_t; +type vm_read_entry_t = array[512] of vm_offset_t; +#ifdef VM32_SUPPORT +type vm32_read_entry_t = array[512] of vm32_offset_t; +#endif + +type exception_mask_t = int; +type exception_behavior_t = int; + +type exception_handler_t = mach_port_t; + +type exception_handler_array_t = + array[*:32] of exception_handler_t; + +type exception_behavior_array_t = + array[*:32] of exception_behavior_t; + +type exception_flavor_array_t = + array[*:32] of thread_state_flavor_t; + +type exception_mask_array_t = + array[*:32] of exception_mask_t; + +type semaphore_t = mach_port_t +#if KERNEL_SERVER + intran: semaphore_t convert_port_to_semaphore(mach_port_t) + outtran: mach_port_t convert_semaphore_to_port(semaphore_t) + destructor: semaphore_dereference(semaphore_t) +#endif /* KERNEL_SERVER */ + ; + +type semaphore_consume_ref_t = mach_port_move_send_t + cusertype: semaphore_t +#if KERNEL_SERVER + intran: semaphore_t convert_port_to_semaphore(mach_port_t) + outtran: mach_port_t convert_semaphore_to_port(semaphore_t) +#endif /* KERNEL_SERVER */ + ; + +type lock_set_t = mach_port_t +#if KERNEL_SERVER + intran: lock_set_t convert_port_to_lock_set(mach_port_t) + outtran: mach_port_t convert_lock_set_to_port(lock_set_t) + destructor: lock_set_dereference(lock_set_t) +#endif /* KERNEL_SERVER */ + ; + +type task_suspension_token_t = mach_port_move_send_once_t +#if KERNEL_SERVER + intran: task_suspension_token_t convert_port_to_task_suspension_token(mach_port_t) + outtran: mach_port_t convert_task_suspension_token_to_port(task_suspension_token_t) +#endif /* KERNEL_SERVER */ + ; + +type vfs_path_t = c_string[4096]; +type nspace_path_t = c_string[1024]; /* 1024 == PATH_MAX */ + +/* public voucher types */ + +/* Mach voucher object */ +type mach_voucher_t = mach_port_t; +type mach_voucher_name_t = mach_port_name_t; + +type mach_voucher_attr_manager_t = mach_port_t; +type mach_voucher_attr_control_t = mach_port_t; + +/* IPC voucher internal object */ +type ipc_voucher_t = mach_port_t +#if KERNEL_SERVER + intran: ipc_voucher_t convert_port_to_voucher(mach_port_t) + outtran: mach_port_t convert_voucher_to_port(ipc_voucher_t) + destructor: ipc_voucher_release(ipc_voucher_t) +#endif /* KERNEL_SERVER */ + ; + +/* IPC voucher attribute control internal object */ +type ipc_voucher_attr_control_t = mach_port_t +#if KERNEL_SERVER + intran: ipc_voucher_attr_control_t convert_port_to_voucher_attr_control(mach_port_t) + outtran: mach_port_t convert_voucher_attr_control_to_port(ipc_voucher_attr_control_t) + destructor: ipc_voucher_attr_control_release(ipc_voucher_attr_control_t) +#endif /* KERNEL_SERVER */ + ; + +type mach_voucher_attr_key_t = uint32_t; + +type mach_voucher_attr_command_t = uint32_t; +type mach_voucher_attr_recipe_command_t = uint32_t; + +type mach_voucher_attr_content_size_t = uint32_t; +type mach_voucher_attr_content_t = array[*:4096] of uint8_t; +type mach_voucher_attr_content_array_t = array[*:5120] of uint8_t; + +type mach_voucher_attr_raw_recipe_size_t = uint32_t; +type mach_voucher_attr_raw_recipe_t = array[*:4096] of uint8_t; +type mach_voucher_attr_raw_recipe_array_t = array[*:5120] of uint8_t; + +type mach_voucher_selector_t = uint32_t; + +type mach_voucher_attr_value_handle_t = uint64_t; +type mach_voucher_attr_value_handle_array_t = array[*:4] of mach_voucher_attr_value_handle_t; +type mach_voucher_attr_value_reference_t = uint32_t; + +/* kernel module loader */ +type kmod_t = int; +type kmod_control_flavor_t = int; + +type kmod_args_t = ^array[] of MACH_MSG_TYPE_BYTE + ctype: kmod_args_t; + +type io_master_t = mach_port_t; +type UNDServerRef = mach_port_t; + +/* These must be kept in sync with definitions in osfmk/mach/dyld_kernel.h */ +type dyld_kernel_image_info_t = struct[40] of MACH_MSG_TYPE_BYTE; +type dyld_kernel_image_info_array_t = ^array[] of dyld_kernel_image_info_t; +type dyld_kernel_process_info_t = struct[64] of MACH_MSG_TYPE_BYTE; + +#if KERNEL_SERVER + +simport ; /* pick up kernel-specific MIG things */ + +simport ; +#endif /* KERNEL_SERVER */ + +import ; +import ; + +#endif /* _MACH_MACH_TYPES_DEFS_ */ + +/* vim: set ft=c : */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_types.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_types.h new file mode 100644 index 00000000..bd4bc342 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_types.h @@ -0,0 +1,254 @@ +/* + * Copyright (c) 2000-2018 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce + * support for mandatory and extensible security protections. This notice + * is included in support of clause 2.2 (b) of the Apple Public License, + * Version 2.0. + */ +/* + * File: mach/mach_types.h + * Author: Avadis Tevanian, Jr., Michael Wayne Young + * Date: 1986 + * + * Mach external interface definitions. + * + */ + +#ifndef _MACH_MACH_TYPES_H_ +#define _MACH_MACH_TYPES_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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* + * If we are not in the kernel, then these will all be represented by + * ports at user-space. + */ +typedef mach_port_t task_t; +typedef mach_port_t task_name_t; +typedef mach_port_t task_inspect_t; +typedef mach_port_t task_suspension_token_t; +typedef mach_port_t thread_t; +typedef mach_port_t thread_act_t; +typedef mach_port_t thread_inspect_t; +typedef mach_port_t ipc_space_t; +typedef mach_port_t ipc_space_inspect_t; +typedef mach_port_t coalition_t; +typedef mach_port_t host_t; +typedef mach_port_t host_priv_t; +typedef mach_port_t host_security_t; +typedef mach_port_t processor_t; +typedef mach_port_t processor_set_t; +typedef mach_port_t processor_set_control_t; +typedef mach_port_t semaphore_t; +typedef mach_port_t lock_set_t; +typedef mach_port_t ledger_t; +typedef mach_port_t alarm_t; +typedef mach_port_t clock_serv_t; +typedef mach_port_t clock_ctrl_t; +typedef mach_port_t arcade_register_t; +typedef mach_port_t suid_cred_t; + + +/* + * These aren't really unique types. They are just called + * out as unique types at one point in history. So we list + * them here for compatibility. + */ +typedef processor_set_t processor_set_name_t; + +/* + * These types are just hard-coded as ports + */ +typedef mach_port_t clock_reply_t; +typedef mach_port_t bootstrap_t; +typedef mach_port_t mem_entry_name_port_t; +typedef mach_port_t exception_handler_t; +typedef exception_handler_t *exception_handler_array_t; +typedef mach_port_t vm_task_entry_t; +typedef mach_port_t io_master_t; +typedef mach_port_t UNDServerRef; + +/* + * Mig doesn't translate the components of an array. + * For example, Mig won't use the thread_t translations + * to translate a thread_array_t argument. So, these definitions + * are not completely accurate at the moment for other kernel + * components. + */ +typedef task_t *task_array_t; +typedef thread_t *thread_array_t; +typedef processor_set_t *processor_set_array_t; +typedef processor_set_t *processor_set_name_array_t; +typedef processor_t *processor_array_t; +typedef thread_act_t *thread_act_array_t; +typedef ledger_t *ledger_array_t; + +/* + * However the real mach_types got declared, we also have to declare + * types with "port" in the name for compatability with the way OSF + * had declared the user interfaces at one point. Someday these should + * go away. + */ +typedef task_t task_port_t; +typedef task_array_t task_port_array_t; +typedef thread_t thread_port_t; +typedef thread_array_t thread_port_array_t; +typedef ipc_space_t ipc_space_port_t; +typedef host_t host_name_t; +typedef host_t host_name_port_t; +typedef processor_set_t processor_set_port_t; +typedef processor_set_t processor_set_name_port_t; +typedef processor_set_array_t processor_set_name_port_array_t; +typedef processor_set_t processor_set_control_port_t; +typedef processor_t processor_port_t; +typedef processor_array_t processor_port_array_t; +typedef thread_act_t thread_act_port_t; +typedef thread_act_array_t thread_act_port_array_t; +typedef semaphore_t semaphore_port_t; +typedef lock_set_t lock_set_port_t; +typedef ledger_t ledger_port_t; +typedef ledger_array_t ledger_port_array_t; +typedef alarm_t alarm_port_t; +typedef clock_serv_t clock_serv_port_t; +typedef clock_ctrl_t clock_ctrl_port_t; +typedef exception_handler_t exception_port_t; +typedef exception_handler_array_t exception_port_arrary_t; +typedef char vfs_path_t[4096]; +typedef char nspace_path_t[1024]; /* 1024 == PATH_MAX */ +typedef char suid_cred_path_t[1024]; +typedef uint32_t suid_cred_uid_t; + +#define TASK_NULL ((task_t) 0) +#define TASK_NAME_NULL ((task_name_t) 0) +#define TASK_INSPECT_NULL ((task_inspect_t) 0) +#define THREAD_NULL ((thread_t) 0) +#define THREAD_INSPECT_NULL ((thread_inspect_t) 0) +#define TID_NULL ((uint64_t) 0) +#define THR_ACT_NULL ((thread_act_t) 0) +#define IPC_SPACE_NULL ((ipc_space_t) 0) +#define IPC_SPACE_INSPECT_NULL ((ipc_space_inspect_t) 0) +#define COALITION_NULL ((coalition_t) 0) +#define HOST_NULL ((host_t) 0) +#define HOST_PRIV_NULL ((host_priv_t) 0) +#define HOST_SECURITY_NULL ((host_security_t) 0) +#define PROCESSOR_SET_NULL ((processor_set_t) 0) +#define PROCESSOR_NULL ((processor_t) 0) +#define SEMAPHORE_NULL ((semaphore_t) 0) +#define LOCK_SET_NULL ((lock_set_t) 0) +#define LEDGER_NULL ((ledger_t) 0) +#define ALARM_NULL ((alarm_t) 0) +#define CLOCK_NULL ((clock_t) 0) +#define UND_SERVER_NULL ((UNDServerRef) 0) +#define ARCADE_REG_NULL ((arcade_register_t) 0) +#define SUID_CRED_NULL ((suid_cred_t) 0) + +/* DEPRECATED */ +typedef natural_t ledger_item_t; +#define LEDGER_ITEM_INFINITY ((ledger_item_t) (~0)) + +typedef int64_t ledger_amount_t; +#define LEDGER_LIMIT_INFINITY ((ledger_amount_t)((1ULL << 63) - 1)) + +typedef mach_vm_offset_t *emulation_vector_t; +typedef char *user_subsystem_t; + +typedef char *labelstr_t; +/* + * Backwards compatibility, for those programs written + * before mach/{std,mach}_types.{defs,h} were set up. + */ +#include + +#endif /* _MACH_MACH_TYPES_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_vm.defs b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_vm.defs new file mode 100644 index 00000000..17a357e4 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_vm.defs @@ -0,0 +1,542 @@ +/* + * Copyright (c) 2004 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_FREE_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * File: mach/mach_vm.defs + * + * Exported kernel VM calls (for any task on the platform). + */ + +subsystem +#if KERNEL_SERVER + KernelServer +#endif /* KERNEL_SERVER */ +#if !defined(_MACH_VM_PUBLISH_AS_LOCAL_) + mach_vm +#else + vm_map_lp64_local +#endif + 4800; + +#include +#include +#include + +#define CONCAT(a,b) a ## b +#if !KERNEL && !LIBSYSCALL_INTERFACE +#define PREFIX(NAME) CONCAT(_kernelrpc_, NAME) +#else +#define PREFIX(NAME) NAME +#endif + +#if KERNEL_SERVER +#define KERNEL_SERVER_SUFFIX(NAME) CONCAT(NAME, _external) +#else +#define KERNEL_SERVER_SUFFIX(NAME) NAME +#endif + +/* + * Allocate zero-filled memory in the address space + * of the target task, either at the specified address, + * or wherever space can be found (controlled by flags), + * of the specified size. The address at which the + * allocation actually took place is returned. + */ +#if !defined(_MACH_VM_PUBLISH_AS_LOCAL_) +routine PREFIX(KERNEL_SERVER_SUFFIX(mach_vm_allocate)) ( + target : vm_task_entry_t; + inout address : mach_vm_address_t; + size : mach_vm_size_t; + flags : int); + +#else + +#if !KERNEL && !LIBSYSCALL_INTERFACE +skip; +#else +routine PREFIX(KERNEL_SERVER_SUFFIX(vm_allocate)) ( + target : vm_task_entry_t; + inout address : mach_vm_address_t; + size : mach_vm_size_t; + flags : int); + +#endif + +#endif + + +/* + * Deallocate the specified range from the virtual + * address space of the target virtual memory map. + */ +#if !defined(_MACH_VM_PUBLISH_AS_LOCAL_) +routine PREFIX(mach_vm_deallocate) ( + target : vm_task_entry_t; + address : mach_vm_address_t; + size : mach_vm_size_t); + +#else + +#if !KERNEL && !LIBSYSCALL_INTERFACE +skip; +#else +routine PREFIX(vm_deallocate) ( + target : vm_task_entry_t; + address : mach_vm_address_t; + size : mach_vm_size_t); +#endif + +#endif + +/* + * Set the current or maximum protection attribute + * for the specified range of the virtual address + * space of the target virtual memory map. The current + * protection limits the memory access rights of threads + * within the map; the maximum protection limits the accesses + * that may be given in the current protection. + * Protections are specified as a set of {read, write, execute} + * *permissions*. + */ +#if !defined(_MACH_VM_PUBLISH_AS_LOCAL_) +routine PREFIX(mach_vm_protect) ( + target_task : vm_task_entry_t; + address : mach_vm_address_t; + size : mach_vm_size_t; + set_maximum : boolean_t; + new_protection : vm_prot_t); + + +#else + +#if !KERNEL && !LIBSYSCALL_INTERFACE +skip; +#else + +routine PREFIX(vm_protect) ( + target_task : vm_task_entry_t; + address : mach_vm_address_t; + size : mach_vm_size_t; + set_maximum : boolean_t; + new_protection : vm_prot_t); + +#endif + +#endif + +/* + * Set the inheritance attribute for the specified range + * of the virtual address space of the target address space. + * The inheritance value is one of {none, copy, share}, and + * specifies how the child address space should acquire + * this memory at the time of a task_create call. + */ +#if !defined(_MACH_VM_PUBLISH_AS_LOCAL_) +routine mach_vm_inherit( +#else +routine vm_inherit( +#endif + target_task : vm_task_entry_t; + address : mach_vm_address_t; + size : mach_vm_size_t; + new_inheritance : vm_inherit_t); + +/* + * Returns the contents of the specified range of the + * virtual address space of the target task. [The + * range must be aligned on a virtual page boundary, + * and must be a multiple of pages in extent. The + * protection on the specified range must permit reading.] + */ +#if !defined(_MACH_VM_PUBLISH_AS_LOCAL_) +routine PREFIX(mach_vm_read) ( +#else +routine PREFIX(vm_read) ( +#endif + target_task : vm_map_t; + address : mach_vm_address_t; + size : mach_vm_size_t; + out data : pointer_t); + +/* + * List corrollary to vm_read, returns mapped contents of specified + * ranges within target address space. + */ +#if !defined(_MACH_VM_PUBLISH_AS_LOCAL_) +routine mach_vm_read_list( +#else +routine vm_read_list( +#endif + target_task : vm_map_t; + inout data_list : mach_vm_read_entry_t; + count : natural_t); + +/* + * Writes the contents of the specified range of the + * virtual address space of the target task. [The + * range must be aligned on a virtual page boundary, + * and must be a multiple of pages in extent. The + * protection on the specified range must permit writing.] + */ +#if !defined(_MACH_VM_PUBLISH_AS_LOCAL_) +routine mach_vm_write( +#else +routine vm_write( +#endif + target_task : vm_map_t; + address : mach_vm_address_t; + data : pointer_t); + +/* + * Copy the contents of the source range of the virtual + * address space of the target task to the destination + * range in that same address space. [Both of the + * ranges must be aligned on a virtual page boundary, + * and must be multiples of pages in extent. The + * protection on the source range must permit reading, + * and the protection on the destination range must + * permit writing.] + */ +#if !defined(_MACH_VM_PUBLISH_AS_LOCAL_) +routine mach_vm_copy( +#else +routine vm_copy( +#endif + target_task : vm_map_t; + source_address : mach_vm_address_t; + size : mach_vm_size_t; + dest_address : mach_vm_address_t); + +/* + * Returns the contents of the specified range of the + * virtual address space of the target task. [There + * are no alignment restrictions, and the results will + * overwrite the area pointed to by data - which must + * already exist. The protection on the specified range + * must permit reading.] + */ +#if !defined(_MACH_VM_PUBLISH_AS_LOCAL_) +routine mach_vm_read_overwrite( +#else +routine vm_read_overwrite( +#endif + target_task : vm_map_t; + address : mach_vm_address_t; + size : mach_vm_size_t; + data : mach_vm_address_t; + out outsize : mach_vm_size_t); + + +#if !defined(_MACH_VM_PUBLISH_AS_LOCAL_) +routine mach_vm_msync( +#else +routine vm_msync( +#endif + target_task : vm_map_t; + address : mach_vm_address_t; + size : mach_vm_size_t; + sync_flags : vm_sync_t ); + +/* + * Set the paging behavior attribute for the specified range + * of the virtual address space of the target task. + * The behavior value is one of {default, random, forward + * sequential, reverse sequential} and indicates the expected + * page reference pattern for the specified range. + */ +#if !defined(_MACH_VM_PUBLISH_AS_LOCAL_) +routine mach_vm_behavior_set( +#else +routine vm_behavior_set( +#endif + target_task : vm_map_t; + address : mach_vm_address_t; + size : mach_vm_size_t; + new_behavior : vm_behavior_t); + + +/* + * Map a user-supplie memory object into the virtual address + * space of the target task. If desired (anywhere is TRUE), + * the kernel will find a suitable address range of the + * specified size; else, the specific address will be allocated. + * + * The beginning address of the range will be aligned on a virtual + * page boundary, be at or beyond the address specified, and + * meet the mask requirements (bits turned on in the mask must not + * be turned on in the result); the size of the range, in bytes, + * will be rounded up to an integral number of virtual pages. + * + * The memory in the resulting range will be associated with the + * specified memory object, with the beginning of the memory range + * referring to the specified offset into the memory object. + * + * The mapping will take the current and maximum protections and + * the inheritance attributes specified; see the vm_protect and + * vm_inherit calls for a description of these attributes. + * + * If desired (copy is TRUE), the memory range will be filled + * with a copy of the data from the memory object; this copy will + * be private to this mapping in this target task. Otherwise, + * the memory in this mapping will be shared with other mappings + * of the same memory object at the same offset (in this task or + * in other tasks). [The Mach kernel only enforces shared memory + * consistency among mappings on one host with similar page alignments. + * The user-defined memory manager for this object is responsible + * for further consistency.] + */ +#if !defined(_MACH_VM_PUBLISH_AS_LOCAL_) +routine PREFIX(KERNEL_SERVER_SUFFIX(mach_vm_map)) ( +#else +routine PREFIX(KERNEL_SERVER_SUFFIX(vm_map)) ( +#endif + target_task : vm_task_entry_t; + inout address : mach_vm_address_t; + size : mach_vm_size_t; + mask : mach_vm_offset_t; + flags : int; + object : mem_entry_name_port_t; + offset : memory_object_offset_t; + copy : boolean_t; + cur_protection : vm_prot_t; + max_protection : vm_prot_t; + inheritance : vm_inherit_t); + +/* + * Set/Get special properties of memory associated + * to some virtual address range, such as cachability, + * migrability, replicability. Machine-dependent. + */ +#if !defined(_MACH_VM_PUBLISH_AS_LOCAL_) +routine mach_vm_machine_attribute( +#else +routine vm_machine_attribute( +#endif + target_task : vm_map_t; + address : mach_vm_address_t; + size : mach_vm_size_t; + attribute : vm_machine_attribute_t; + inout value : vm_machine_attribute_val_t); + +/* + * Map portion of a task's address space. + */ +#if !defined(_MACH_VM_PUBLISH_AS_LOCAL_) +routine PREFIX(KERNEL_SERVER_SUFFIX(mach_vm_remap)) ( +#else +routine PREFIX(KERNEL_SERVER_SUFFIX(vm_remap)) ( +#endif + target_task : vm_map_t; + inout target_address : mach_vm_address_t; + size : mach_vm_size_t; + mask : mach_vm_offset_t; + flags : int; + src_task : vm_map_t; + src_address : mach_vm_address_t; + copy : boolean_t; + out cur_protection : vm_prot_t; + out max_protection : vm_prot_t; + inheritance : vm_inherit_t); + +/* + * Give the caller information on the given location in a virtual + * address space. If a page is mapped return ref and dirty info. + */ +#if !defined(_MACH_VM_PUBLISH_AS_LOCAL_) +routine mach_vm_page_query( +#else +routine vm_map_page_query( +#endif + target_map :vm_map_t; + offset :mach_vm_offset_t; + out disposition :integer_t; + out ref_count :integer_t); + + +#if !defined(_MACH_VM_PUBLISH_AS_LOCAL_) +routine mach_vm_region_recurse( +#else +routine vm_region_recurse_64( +#endif + target_task : vm_map_t; + inout address : mach_vm_address_t; + out size : mach_vm_size_t; + inout nesting_depth : natural_t; + out info : vm_region_recurse_info_t,CountInOut); + +/* + * Returns information about the contents of the virtual + * address space of the target task at the specified + * address. The returned protection, inheritance, sharing + * and memory object values apply to the entire range described + * by the address range returned; the memory object offset + * corresponds to the beginning of the address range. + * [If the specified address is not allocated, the next + * highest address range is described. If no addresses beyond + * the one specified are allocated, the call returns KERN_NO_SPACE.] + */ +#if !defined(_MACH_VM_PUBLISH_AS_LOCAL_) +routine mach_vm_region( +#else +routine vm_region_64( +#endif + target_task : vm_map_t; + inout address : mach_vm_address_t; + out size : mach_vm_size_t; + flavor : vm_region_flavor_t; + out info : vm_region_info_t, CountInOut; + out object_name : memory_object_name_t = + MACH_MSG_TYPE_MOVE_SEND + ctype: mach_port_t); + +/* + * Allow application level processes to create named entries which + * correspond to mapped portions of their address space. These named + * entries can then be manipulated, shared with other processes in + * other address spaces and ultimately mapped in ohter address spaces + * + * THIS INTERFACE IS STILL EVOLVING. + */ +#if !defined(_MACH_VM_PUBLISH_AS_LOCAL_) +#if !defined(__LP64__) || KERNEL_SERVER || XNU_KERNEL_PRIVATE || LIBSYSCALL_INTERFACE +routine _mach_make_memory_entry( +#else +routine mach_make_memory_entry( +#endif +#else +routine mach_make_memory_entry_64( +#endif + target_task :vm_map_t; + inout size :memory_object_size_t; + offset :memory_object_offset_t; + permission :vm_prot_t; + out object_handle :mem_entry_name_port_move_send_t; + parent_handle :mem_entry_name_port_t); + +/* + * Control behavior and investigate state of a "purgable" object in + * the virtual address space of the target task. A purgable object is + * created via a call to mach_vm_allocate() with VM_FLAGS_PURGABLE + * specified. See the routine implementation for a complete + * definition of the routine. + */ +#if !defined(_MACH_VM_PUBLISH_AS_LOCAL_) +routine PREFIX(mach_vm_purgable_control) ( +#else +routine PREFIX(vm_purgable_control) ( +#endif + target_task : vm_map_t; + address : mach_vm_address_t; + control : vm_purgable_t; + inout state : int); + + +#if !defined(_MACH_VM_PUBLISH_AS_LOCAL_) +routine mach_vm_page_info( + target_task : vm_map_t; + address : mach_vm_address_t; + flavor : vm_page_info_flavor_t; + out info : vm_page_info_t, CountInOut); +#else +skip; +#endif + +#if !defined(_MACH_VM_PUBLISH_AS_LOCAL_) +routine mach_vm_page_range_query( + target_map : vm_map_t; + address : mach_vm_offset_t; + size : mach_vm_size_t; + dispositions : mach_vm_address_t; + inout dispositions_count : mach_vm_size_t); +#else +skip; +#endif + +/****************************** Legacy section ***************************/ +/* The following definitions are exist to provide compatibility with */ +/* the legacy APIs. They are no different. We just need to produce */ +/* the user-level stub interface for them. */ +/****************************** Legacy section ***************************/ + + +/* + * These interfaces just aren't supported in the new (wide) model: + * + * mach_vm_region_info() - + * vm_map_pages_info() - + * no user-level replacement for these MACH_DEBUG interfaces + * vm_map_get_upl() - + * no user-level replacement at the moment + * vm_region_info() - + * use mach_vm_region_info() or vm_region_info_64() + * vm_region_recurse() - + * use mach_vm_region_recurse() or vm_region_recurse_64() + */ + +/* + * The following legacy interfaces are provides as macro wrappers to the new + * interfaces. You should strive to use the new ones instead: + * + * vm_map() - + * use mach_vm_map() or vm_map_64() + * vm_region() - + * use mach_vm_region() or vm_region_64() + * mach_make_memory_entry() - + * use mach_vm_make_memory_entry() or mach_make_memory_entry_64() + */ + +/* vim: set ft=c : */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_vm.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_vm.h new file mode 100644 index 00000000..288b8cee --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_vm.h @@ -0,0 +1,1102 @@ +#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 21 +#endif /* mach_vm_MSG_COUNT */ + +#include +#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 cur_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 *cur_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 +); + +/* Routine mach_vm_page_range_query */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_vm_page_range_query +( + vm_map_t target_map, + mach_vm_offset_t address, + mach_vm_size_t size, + mach_vm_address_t dispositions, + mach_vm_size_t *dispositions_count +); + +__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(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 cur_protection; + vm_prot_t max_protection; + vm_inherit_t inheritance; + } __Request__mach_vm_map_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_vm_offset_t address; + mach_vm_size_t size; + mach_vm_address_t dispositions; + mach_vm_size_t dispositions_count; + } __Request__mach_vm_page_range_query_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#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; + __Request__mach_vm_page_range_query_t Request_mach_vm_page_range_query; +}; +#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(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 cur_protection; + vm_prot_t max_protection; + } __Reply__mach_vm_remap_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_vm_size_t dispositions_count; + } __Reply__mach_vm_page_range_query_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#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; + __Reply__mach_vm_page_range_query_t Reply_mach_vm_page_range_query; +}; +#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 },\ + { "mach_vm_page_range_query", 4820 } +#endif + +#ifdef __AfterMigUserHeader +__AfterMigUserHeader +#endif /* __AfterMigUserHeader */ + +#endif /* _mach_vm_user_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_voucher.defs b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_voucher.defs new file mode 100644 index 00000000..3decdd8a --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_voucher.defs @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2013 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ + +subsystem +#if KERNEL_SERVER + KernelServer +#endif /* KERNEL_SERVER */ + mach_voucher 5400; + +#include +#include + +/* extract just the content data for a pair */ +routine mach_voucher_extract_attr_content( + voucher : ipc_voucher_t; + key : mach_voucher_attr_key_t; + out content : mach_voucher_attr_content_t, CountInOut); + +/* extract a recipe to reconstitue a pair item in a future voucher */ +#if !KERNEL && !LIBSYSCALL_INTERFACE +routine _kernelrpc_mach_voucher_extract_attr_recipe( +#else +routine mach_voucher_extract_attr_recipe( +#endif + voucher : ipc_voucher_t; + key : mach_voucher_attr_key_t; + out recipe : mach_voucher_attr_raw_recipe_t, CountInOut); + +/* extract a recipe array to reconstitue all the key values in a future voucher */ +routine mach_voucher_extract_all_attr_recipes( + voucher : ipc_voucher_t; + out recipes : mach_voucher_attr_raw_recipe_array_t, CountInOut); + +/* execute a command against a given voucher attribute */ +routine mach_voucher_attr_command( + voucher : ipc_voucher_t; + key : mach_voucher_attr_key_t; + command : mach_voucher_attr_command_t; + in_content : mach_voucher_attr_content_t; + out out_content : mach_voucher_attr_content_t, CountInOut); + +/* extract a recipe array to reconstitue all the key values in a future voucher */ +routine mach_voucher_debug_info( + task : ipc_space_t; + voucher_name: mach_port_name_t; + out recipes : mach_voucher_attr_raw_recipe_array_t, CountInOut); + +/* vim: set ft=c : */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_voucher.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_voucher.h new file mode 100644 index 00000000..8c49b682 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_voucher.h @@ -0,0 +1,340 @@ +#ifndef _mach_voucher_user_ +#define _mach_voucher_user_ + +/* Module mach_voucher */ + +#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_voucher_MSG_COUNT +#define mach_voucher_MSG_COUNT 5 +#endif /* mach_voucher_MSG_COUNT */ + +#include +#include +#include +#include + +#ifdef __BeforeMigUserHeader +__BeforeMigUserHeader +#endif /* __BeforeMigUserHeader */ + +#include +__BEGIN_DECLS + + +/* Routine mach_voucher_extract_attr_content */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_voucher_extract_attr_content +( + ipc_voucher_t voucher, + mach_voucher_attr_key_t key, + mach_voucher_attr_content_t content, + mach_msg_type_number_t *contentCnt +); + +/* Routine mach_voucher_extract_attr_recipe */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_voucher_extract_attr_recipe +( + ipc_voucher_t voucher, + mach_voucher_attr_key_t key, + mach_voucher_attr_raw_recipe_t recipe, + mach_msg_type_number_t *recipeCnt +); + +/* Routine mach_voucher_extract_all_attr_recipes */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_voucher_extract_all_attr_recipes +( + ipc_voucher_t voucher, + mach_voucher_attr_raw_recipe_array_t recipes, + mach_msg_type_number_t *recipesCnt +); + +/* Routine mach_voucher_attr_command */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_voucher_attr_command +( + ipc_voucher_t voucher, + mach_voucher_attr_key_t key, + mach_voucher_attr_command_t command, + mach_voucher_attr_content_t in_content, + mach_msg_type_number_t in_contentCnt, + mach_voucher_attr_content_t out_content, + mach_msg_type_number_t *out_contentCnt +); + +/* Routine mach_voucher_debug_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_voucher_debug_info +( + ipc_space_t task, + mach_port_name_t voucher_name, + mach_voucher_attr_raw_recipe_array_t recipes, + mach_msg_type_number_t *recipesCnt +); + +__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_voucher_subsystem__defined +#define __Request__mach_voucher_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_voucher_attr_key_t key; + mach_msg_type_number_t contentCnt; + } __Request__mach_voucher_extract_attr_content_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_voucher_attr_key_t key; + mach_msg_type_number_t recipeCnt; + } __Request__mach_voucher_extract_attr_recipe_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_msg_type_number_t recipesCnt; + } __Request__mach_voucher_extract_all_attr_recipes_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_voucher_attr_key_t key; + mach_voucher_attr_command_t command; + mach_msg_type_number_t in_contentCnt; + uint8_t in_content[4096]; + mach_msg_type_number_t out_contentCnt; + } __Request__mach_voucher_attr_command_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_port_name_t voucher_name; + mach_msg_type_number_t recipesCnt; + } __Request__mach_voucher_debug_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Request__mach_voucher_subsystem__defined */ + +/* union of all requests */ + +#ifndef __RequestUnion__mach_voucher_subsystem__defined +#define __RequestUnion__mach_voucher_subsystem__defined +union __RequestUnion__mach_voucher_subsystem { + __Request__mach_voucher_extract_attr_content_t Request_mach_voucher_extract_attr_content; + __Request__mach_voucher_extract_attr_recipe_t Request_mach_voucher_extract_attr_recipe; + __Request__mach_voucher_extract_all_attr_recipes_t Request_mach_voucher_extract_all_attr_recipes; + __Request__mach_voucher_attr_command_t Request_mach_voucher_attr_command; + __Request__mach_voucher_debug_info_t Request_mach_voucher_debug_info; +}; +#endif /* !__RequestUnion__mach_voucher_subsystem__defined */ +/* typedefs for all replies */ + +#ifndef __Reply__mach_voucher_subsystem__defined +#define __Reply__mach_voucher_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t contentCnt; + uint8_t content[4096]; + } __Reply__mach_voucher_extract_attr_content_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t recipeCnt; + uint8_t recipe[4096]; + } __Reply__mach_voucher_extract_attr_recipe_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t recipesCnt; + uint8_t recipes[5120]; + } __Reply__mach_voucher_extract_all_attr_recipes_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t out_contentCnt; + uint8_t out_content[4096]; + } __Reply__mach_voucher_attr_command_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t recipesCnt; + uint8_t recipes[5120]; + } __Reply__mach_voucher_debug_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Reply__mach_voucher_subsystem__defined */ + +/* union of all replies */ + +#ifndef __ReplyUnion__mach_voucher_subsystem__defined +#define __ReplyUnion__mach_voucher_subsystem__defined +union __ReplyUnion__mach_voucher_subsystem { + __Reply__mach_voucher_extract_attr_content_t Reply_mach_voucher_extract_attr_content; + __Reply__mach_voucher_extract_attr_recipe_t Reply_mach_voucher_extract_attr_recipe; + __Reply__mach_voucher_extract_all_attr_recipes_t Reply_mach_voucher_extract_all_attr_recipes; + __Reply__mach_voucher_attr_command_t Reply_mach_voucher_attr_command; + __Reply__mach_voucher_debug_info_t Reply_mach_voucher_debug_info; +}; +#endif /* !__RequestUnion__mach_voucher_subsystem__defined */ + +#ifndef subsystem_to_name_map_mach_voucher +#define subsystem_to_name_map_mach_voucher \ + { "mach_voucher_extract_attr_content", 5400 },\ + { "mach_voucher_extract_attr_recipe", 5401 },\ + { "mach_voucher_extract_all_attr_recipes", 5402 },\ + { "mach_voucher_attr_command", 5403 },\ + { "mach_voucher_debug_info", 5404 } +#endif + +#ifdef __AfterMigUserHeader +__AfterMigUserHeader +#endif /* __AfterMigUserHeader */ + +#endif /* _mach_voucher_user_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_voucher_attr_control.defs b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_voucher_attr_control.defs new file mode 100644 index 00000000..89fb66cc --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_voucher_attr_control.defs @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2013 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ + +subsystem +#if KERNEL_SERVER + KernelServer +#endif /* KERNEL_SERVER */ + mach_voucher_attr_control 5600; + +#include +#include + +/* Extract the given voucher-control's value-handle from the supplied voucher */ +routine mach_voucher_attr_control_get_values( + control : ipc_voucher_attr_control_t; + voucher : ipc_voucher_t; + out value_handles : mach_voucher_attr_value_handle_array_t, CountInOut); + +/* Create a new voucher with the control's privilege (to directly assign value-handles) */ +routine mach_voucher_attr_control_create_mach_voucher( + control : ipc_voucher_attr_control_t; + recipes : mach_voucher_attr_raw_recipe_array_t; + out voucher : ipc_voucher_t); diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_voucher_types.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_voucher_types.h new file mode 100644 index 00000000..89d38216 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mach_voucher_types.h @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2013 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _MACH_VOUCHER_TYPES_H_ +#define _MACH_VOUCHER_TYPES_H_ + +#include +#include + +/* + * Mach Voucher - an immutable collection of attribute value handles. + * + * The mach voucher is such that it can be passed between processes + * as a Mach port send right (by convention in the mach_msg_header_t’s + * msgh_voucher field). + * + * You may construct a new mach voucher by passing a construction + * recipe to host_create_mach_voucher(). The construction recipe supports + * generic commands for copying, removing, and redeeming attribute value + * handles from previous vouchers, or running attribute-mananger-specific + * commands within the recipe. + * + * Once the set of attribute value handles is constructed and returned, + * that set will not change for the life of the voucher (just because the + * attribute value handle itself doesn't change, the value the handle refers + * to is free to change at will). + */ +typedef mach_port_t mach_voucher_t; +#define MACH_VOUCHER_NULL ((mach_voucher_t) 0) + +typedef mach_port_name_t mach_voucher_name_t; +#define MACH_VOUCHER_NAME_NULL ((mach_voucher_name_t) 0) + +typedef mach_voucher_name_t *mach_voucher_name_array_t; +#define MACH_VOUCHER_NAME_ARRAY_NULL ((mach_voucher_name_array_t) 0) + +/* + * This type changes appearance between user-space and kernel. It is + * a port at user-space and a reference to an ipc_voucher structure in-kernel. + */ +typedef mach_voucher_t ipc_voucher_t; +#define IPC_VOUCHER_NULL ((ipc_voucher_t) 0) + +/* + * mach_voucher_selector_t - A means of specifying which thread/task value to extract - + * the current voucher set at this level, or a voucher representing + * the full [layered] effective value for the task/thread. + */ +typedef uint32_t mach_voucher_selector_t; +#define MACH_VOUCHER_SELECTOR_CURRENT ((mach_voucher_selector_t)0) +#define MACH_VOUCHER_SELECTOR_EFFECTIVE ((mach_voucher_selector_t)1) + + +/* + * mach_voucher_attr_key_t - The key used to identify a particular managed resource or + * to select the specific resource manager’s data associated + * with a given voucher. + */ +typedef uint32_t mach_voucher_attr_key_t; +typedef mach_voucher_attr_key_t *mach_voucher_attr_key_array_t; + +#define MACH_VOUCHER_ATTR_KEY_ALL ((mach_voucher_attr_key_t)~0) +#define MACH_VOUCHER_ATTR_KEY_NONE ((mach_voucher_attr_key_t)0) + +/* other well-known-keys will be added here */ +#define MACH_VOUCHER_ATTR_KEY_ATM ((mach_voucher_attr_key_t)1) +#define MACH_VOUCHER_ATTR_KEY_IMPORTANCE ((mach_voucher_attr_key_t)2) +#define MACH_VOUCHER_ATTR_KEY_BANK ((mach_voucher_attr_key_t)3) +#define MACH_VOUCHER_ATTR_KEY_PTHPRIORITY ((mach_voucher_attr_key_t)4) + +#define MACH_VOUCHER_ATTR_KEY_USER_DATA ((mach_voucher_attr_key_t)7) +#define MACH_VOUCHER_ATTR_KEY_BITS MACH_VOUCHER_ATTR_KEY_USER_DATA /* deprecated */ +#define MACH_VOUCHER_ATTR_KEY_TEST ((mach_voucher_attr_key_t)8) + +#define MACH_VOUCHER_ATTR_KEY_NUM_WELL_KNOWN MACH_VOUCHER_ATTR_KEY_TEST + +/* + * mach_voucher_attr_content_t + * + * Data passed to a resource manager for modifying an attribute + * value or returned from the resource manager in response to a + * request to externalize the current value for that attribute. + */ +typedef uint8_t *mach_voucher_attr_content_t; +typedef uint32_t mach_voucher_attr_content_size_t; + +/* + * mach_voucher_attr_command_t - The private verbs implemented by each voucher + * attribute manager via mach_voucher_attr_command(). + */ +typedef uint32_t mach_voucher_attr_command_t; + +/* + * mach_voucher_attr_recipe_command_t + * + * The verbs used to create/morph a voucher attribute value. + * We define some system-wide commands here - related to creation, and transport of + * vouchers and attributes. Additional commands can be defined by, and supported by, + * individual attribute resource managers. + */ +typedef uint32_t mach_voucher_attr_recipe_command_t; +typedef mach_voucher_attr_recipe_command_t *mach_voucher_attr_recipe_command_array_t; + +#define MACH_VOUCHER_ATTR_NOOP ((mach_voucher_attr_recipe_command_t)0) +#define MACH_VOUCHER_ATTR_COPY ((mach_voucher_attr_recipe_command_t)1) +#define MACH_VOUCHER_ATTR_REMOVE ((mach_voucher_attr_recipe_command_t)2) +#define MACH_VOUCHER_ATTR_SET_VALUE_HANDLE ((mach_voucher_attr_recipe_command_t)3) +#define MACH_VOUCHER_ATTR_AUTO_REDEEM ((mach_voucher_attr_recipe_command_t)4) +#define MACH_VOUCHER_ATTR_SEND_PREPROCESS ((mach_voucher_attr_recipe_command_t)5) + +/* redeem is on its way out? */ +#define MACH_VOUCHER_ATTR_REDEEM ((mach_voucher_attr_recipe_command_t)10) + +/* recipe command(s) for importance attribute manager */ +#define MACH_VOUCHER_ATTR_IMPORTANCE_SELF ((mach_voucher_attr_recipe_command_t)200) + +/* recipe command(s) for bit-store attribute manager */ +#define MACH_VOUCHER_ATTR_USER_DATA_STORE ((mach_voucher_attr_recipe_command_t)211) +#define MACH_VOUCHER_ATTR_BITS_STORE MACH_VOUCHER_ATTR_USER_DATA_STORE /* deprecated */ + +/* recipe command(s) for test attribute manager */ +#define MACH_VOUCHER_ATTR_TEST_STORE MACH_VOUCHER_ATTR_USER_DATA_STORE + +/* + * mach_voucher_attr_recipe_t + * + * An element in a recipe list to create a voucher. + */ +#pragma pack(push, 1) + +typedef struct mach_voucher_attr_recipe_data { + mach_voucher_attr_key_t key; + mach_voucher_attr_recipe_command_t command; + mach_voucher_name_t previous_voucher; + mach_voucher_attr_content_size_t content_size; + uint8_t content[]; +} mach_voucher_attr_recipe_data_t; +typedef mach_voucher_attr_recipe_data_t *mach_voucher_attr_recipe_t; +typedef mach_msg_type_number_t mach_voucher_attr_recipe_size_t; + +/* Make the above palatable to MIG */ +typedef uint8_t *mach_voucher_attr_raw_recipe_t; +typedef mach_voucher_attr_raw_recipe_t mach_voucher_attr_raw_recipe_array_t; +typedef mach_msg_type_number_t mach_voucher_attr_raw_recipe_size_t; +typedef mach_msg_type_number_t mach_voucher_attr_raw_recipe_array_size_t; + +#define MACH_VOUCHER_ATTR_MAX_RAW_RECIPE_ARRAY_SIZE 5120 +#define MACH_VOUCHER_TRAP_STACK_LIMIT 256 + +#pragma pack(pop) + +/* + * VOUCHER ATTRIBUTE MANAGER Writer types + */ + +/* + * mach_voucher_attr_manager_t + * + * A handle through which the mach voucher mechanism communicates with the voucher + * attribute manager for a given attribute key. + */ +typedef mach_port_t mach_voucher_attr_manager_t; +#define MACH_VOUCHER_ATTR_MANAGER_NULL ((mach_voucher_attr_manager_t) 0) + +/* + * mach_voucher_attr_control_t + * + * A handle provided to the voucher attribute manager for a given attribute key + * through which it makes inquiries or control operations of the mach voucher mechanism. + */ +typedef mach_port_t mach_voucher_attr_control_t; +#define MACH_VOUCHER_ATTR_CONTROL_NULL ((mach_voucher_attr_control_t) 0) + +/* + * These types are different in-kernel vs user-space. They are ports in user-space, + * pointers to opaque structs in most of the kernel, and pointers to known struct + * types in the Mach portion of the kernel. + */ +typedef mach_port_t ipc_voucher_attr_manager_t; +typedef mach_port_t ipc_voucher_attr_control_t; +#define IPC_VOUCHER_ATTR_MANAGER_NULL ((ipc_voucher_attr_manager_t) 0) +#define IPC_VOUCHER_ATTR_CONTROL_NULL ((ipc_voucher_attr_control_t) 0) + +/* + * mach_voucher_attr_value_handle_t + * + * The private handle that the voucher attribute manager provides to + * the mach voucher mechanism to represent a given attr content/value. + */ +typedef uint64_t mach_voucher_attr_value_handle_t; +typedef mach_voucher_attr_value_handle_t *mach_voucher_attr_value_handle_array_t; + +typedef mach_msg_type_number_t mach_voucher_attr_value_handle_array_size_t; +#define MACH_VOUCHER_ATTR_VALUE_MAX_NESTED ((mach_voucher_attr_value_handle_array_size_t)4) + +typedef uint32_t mach_voucher_attr_value_reference_t; +typedef uint32_t mach_voucher_attr_value_flags_t; +#define MACH_VOUCHER_ATTR_VALUE_FLAGS_NONE ((mach_voucher_attr_value_flags_t)0) +#define MACH_VOUCHER_ATTR_VALUE_FLAGS_PERSIST ((mach_voucher_attr_value_flags_t)1) + +/* USE - TBD */ +typedef uint32_t mach_voucher_attr_control_flags_t; +#define MACH_VOUCHER_ATTR_CONTROL_FLAGS_NONE ((mach_voucher_attr_control_flags_t)0) + +/* + * Commands and types for the IPC Importance Attribute Manager + * + * These are the valid mach_voucher_attr_command() options with the + * MACH_VOUCHER_ATTR_KEY_IMPORTANCE key. + */ +#define MACH_VOUCHER_IMPORTANCE_ATTR_ADD_EXTERNAL 1 /* Add some number of external refs (not supported) */ +#define MACH_VOUCHER_IMPORTANCE_ATTR_DROP_EXTERNAL 2 /* Drop some number of external refs */ +typedef uint32_t mach_voucher_attr_importance_refs; + +/* + * Activity id Generation defines + */ +#define MACH_ACTIVITY_ID_COUNT_MAX 16 + +#endif /* _MACH_VOUCHER_TYPES_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine.h new file mode 100644 index 00000000..a2096232 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine.h @@ -0,0 +1,395 @@ +/* + * Copyright (c) 2007-2016 Apple, Inc. All rights reserved. + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* File: machine.h + * Author: Avadis Tevanian, Jr. + * Date: 1986 + * + * Machine independent machine abstraction. + */ + +#ifndef _MACH_MACHINE_H_ +#define _MACH_MACHINE_H_ + +#ifndef __ASSEMBLER__ + +#include +#include +#include + +typedef integer_t cpu_type_t; +typedef integer_t cpu_subtype_t; +typedef integer_t cpu_threadtype_t; + +#define CPU_STATE_MAX 4 + +#define CPU_STATE_USER 0 +#define CPU_STATE_SYSTEM 1 +#define CPU_STATE_IDLE 2 +#define CPU_STATE_NICE 3 + + + +/* + * Capability bits used in the definition of cpu_type. + */ +#define CPU_ARCH_MASK 0xff000000 /* mask for architecture bits */ +#define CPU_ARCH_ABI64 0x01000000 /* 64 bit ABI */ +#define CPU_ARCH_ABI64_32 0x02000000 /* ABI for 64-bit hardware with 32-bit types; LP32 */ + +/* + * Machine types known by all. + */ + +#define CPU_TYPE_ANY ((cpu_type_t) -1) + +#define CPU_TYPE_VAX ((cpu_type_t) 1) +/* skip ((cpu_type_t) 2) */ +/* skip ((cpu_type_t) 3) */ +/* skip ((cpu_type_t) 4) */ +/* skip ((cpu_type_t) 5) */ +#define CPU_TYPE_MC680x0 ((cpu_type_t) 6) +#define CPU_TYPE_X86 ((cpu_type_t) 7) +#define CPU_TYPE_I386 CPU_TYPE_X86 /* compatibility */ +#define CPU_TYPE_X86_64 (CPU_TYPE_X86 | CPU_ARCH_ABI64) + +/* skip CPU_TYPE_MIPS ((cpu_type_t) 8) */ +/* skip ((cpu_type_t) 9) */ +#define CPU_TYPE_MC98000 ((cpu_type_t) 10) +#define CPU_TYPE_HPPA ((cpu_type_t) 11) +#define CPU_TYPE_ARM ((cpu_type_t) 12) +#define CPU_TYPE_ARM64 (CPU_TYPE_ARM | CPU_ARCH_ABI64) +#define CPU_TYPE_ARM64_32 (CPU_TYPE_ARM | CPU_ARCH_ABI64_32) +#define CPU_TYPE_MC88000 ((cpu_type_t) 13) +#define CPU_TYPE_SPARC ((cpu_type_t) 14) +#define CPU_TYPE_I860 ((cpu_type_t) 15) +/* skip CPU_TYPE_ALPHA ((cpu_type_t) 16) */ +/* skip ((cpu_type_t) 17) */ +#define CPU_TYPE_POWERPC ((cpu_type_t) 18) +#define CPU_TYPE_POWERPC64 (CPU_TYPE_POWERPC | CPU_ARCH_ABI64) +/* skip ((cpu_type_t) 19) */ + +/* + * Machine subtypes (these are defined here, instead of in a machine + * dependent directory, so that any program can get all definitions + * regardless of where is it compiled). + */ + +/* + * Capability bits used in the definition of cpu_subtype. + */ +#define CPU_SUBTYPE_MASK 0xff000000 /* mask for feature flags */ +#define CPU_SUBTYPE_LIB64 0x80000000 /* 64 bit libraries */ + + +/* + * Object files that are hand-crafted to run on any + * implementation of an architecture are tagged with + * CPU_SUBTYPE_MULTIPLE. This functions essentially the same as + * the "ALL" subtype of an architecture except that it allows us + * to easily find object files that may need to be modified + * whenever a new implementation of an architecture comes out. + * + * It is the responsibility of the implementor to make sure the + * software handles unsupported implementations elegantly. + */ +#define CPU_SUBTYPE_MULTIPLE ((cpu_subtype_t) -1) +#define CPU_SUBTYPE_LITTLE_ENDIAN ((cpu_subtype_t) 0) +#define CPU_SUBTYPE_BIG_ENDIAN ((cpu_subtype_t) 1) + +/* + * Machine threadtypes. + * This is none - not defined - for most machine types/subtypes. + */ +#define CPU_THREADTYPE_NONE ((cpu_threadtype_t) 0) + +/* + * VAX subtypes (these do *not* necessary conform to the actual cpu + * ID assigned by DEC available via the SID register). + */ + +#define CPU_SUBTYPE_VAX_ALL ((cpu_subtype_t) 0) +#define CPU_SUBTYPE_VAX780 ((cpu_subtype_t) 1) +#define CPU_SUBTYPE_VAX785 ((cpu_subtype_t) 2) +#define CPU_SUBTYPE_VAX750 ((cpu_subtype_t) 3) +#define CPU_SUBTYPE_VAX730 ((cpu_subtype_t) 4) +#define CPU_SUBTYPE_UVAXI ((cpu_subtype_t) 5) +#define CPU_SUBTYPE_UVAXII ((cpu_subtype_t) 6) +#define CPU_SUBTYPE_VAX8200 ((cpu_subtype_t) 7) +#define CPU_SUBTYPE_VAX8500 ((cpu_subtype_t) 8) +#define CPU_SUBTYPE_VAX8600 ((cpu_subtype_t) 9) +#define CPU_SUBTYPE_VAX8650 ((cpu_subtype_t) 10) +#define CPU_SUBTYPE_VAX8800 ((cpu_subtype_t) 11) +#define CPU_SUBTYPE_UVAXIII ((cpu_subtype_t) 12) + +/* + * 680x0 subtypes + * + * The subtype definitions here are unusual for historical reasons. + * NeXT used to consider 68030 code as generic 68000 code. For + * backwards compatability: + * + * CPU_SUBTYPE_MC68030 symbol has been preserved for source code + * compatability. + * + * CPU_SUBTYPE_MC680x0_ALL has been defined to be the same + * subtype as CPU_SUBTYPE_MC68030 for binary comatability. + * + * CPU_SUBTYPE_MC68030_ONLY has been added to allow new object + * files to be tagged as containing 68030-specific instructions. + */ + +#define CPU_SUBTYPE_MC680x0_ALL ((cpu_subtype_t) 1) +#define CPU_SUBTYPE_MC68030 ((cpu_subtype_t) 1) /* compat */ +#define CPU_SUBTYPE_MC68040 ((cpu_subtype_t) 2) +#define CPU_SUBTYPE_MC68030_ONLY ((cpu_subtype_t) 3) + +/* + * I386 subtypes + */ + +#define CPU_SUBTYPE_INTEL(f, m) ((cpu_subtype_t) (f) + ((m) << 4)) + +#define CPU_SUBTYPE_I386_ALL CPU_SUBTYPE_INTEL(3, 0) +#define CPU_SUBTYPE_386 CPU_SUBTYPE_INTEL(3, 0) +#define CPU_SUBTYPE_486 CPU_SUBTYPE_INTEL(4, 0) +#define CPU_SUBTYPE_486SX CPU_SUBTYPE_INTEL(4, 8) // 8 << 4 = 128 +#define CPU_SUBTYPE_586 CPU_SUBTYPE_INTEL(5, 0) +#define CPU_SUBTYPE_PENT CPU_SUBTYPE_INTEL(5, 0) +#define CPU_SUBTYPE_PENTPRO CPU_SUBTYPE_INTEL(6, 1) +#define CPU_SUBTYPE_PENTII_M3 CPU_SUBTYPE_INTEL(6, 3) +#define CPU_SUBTYPE_PENTII_M5 CPU_SUBTYPE_INTEL(6, 5) +#define CPU_SUBTYPE_CELERON CPU_SUBTYPE_INTEL(7, 6) +#define CPU_SUBTYPE_CELERON_MOBILE CPU_SUBTYPE_INTEL(7, 7) +#define CPU_SUBTYPE_PENTIUM_3 CPU_SUBTYPE_INTEL(8, 0) +#define CPU_SUBTYPE_PENTIUM_3_M CPU_SUBTYPE_INTEL(8, 1) +#define CPU_SUBTYPE_PENTIUM_3_XEON CPU_SUBTYPE_INTEL(8, 2) +#define CPU_SUBTYPE_PENTIUM_M CPU_SUBTYPE_INTEL(9, 0) +#define CPU_SUBTYPE_PENTIUM_4 CPU_SUBTYPE_INTEL(10, 0) +#define CPU_SUBTYPE_PENTIUM_4_M CPU_SUBTYPE_INTEL(10, 1) +#define CPU_SUBTYPE_ITANIUM CPU_SUBTYPE_INTEL(11, 0) +#define CPU_SUBTYPE_ITANIUM_2 CPU_SUBTYPE_INTEL(11, 1) +#define CPU_SUBTYPE_XEON CPU_SUBTYPE_INTEL(12, 0) +#define CPU_SUBTYPE_XEON_MP CPU_SUBTYPE_INTEL(12, 1) + +#define CPU_SUBTYPE_INTEL_FAMILY(x) ((x) & 15) +#define CPU_SUBTYPE_INTEL_FAMILY_MAX 15 + +#define CPU_SUBTYPE_INTEL_MODEL(x) ((x) >> 4) +#define CPU_SUBTYPE_INTEL_MODEL_ALL 0 + +/* + * X86 subtypes. + */ + +#define CPU_SUBTYPE_X86_ALL ((cpu_subtype_t)3) +#define CPU_SUBTYPE_X86_64_ALL ((cpu_subtype_t)3) +#define CPU_SUBTYPE_X86_ARCH1 ((cpu_subtype_t)4) +#define CPU_SUBTYPE_X86_64_H ((cpu_subtype_t)8) /* Haswell feature subset */ + + +#define CPU_THREADTYPE_INTEL_HTT ((cpu_threadtype_t) 1) + +/* + * Mips subtypes. + */ + +#define CPU_SUBTYPE_MIPS_ALL ((cpu_subtype_t) 0) +#define CPU_SUBTYPE_MIPS_R2300 ((cpu_subtype_t) 1) +#define CPU_SUBTYPE_MIPS_R2600 ((cpu_subtype_t) 2) +#define CPU_SUBTYPE_MIPS_R2800 ((cpu_subtype_t) 3) +#define CPU_SUBTYPE_MIPS_R2000a ((cpu_subtype_t) 4) /* pmax */ +#define CPU_SUBTYPE_MIPS_R2000 ((cpu_subtype_t) 5) +#define CPU_SUBTYPE_MIPS_R3000a ((cpu_subtype_t) 6) /* 3max */ +#define CPU_SUBTYPE_MIPS_R3000 ((cpu_subtype_t) 7) + +/* + * MC98000 (PowerPC) subtypes + */ +#define CPU_SUBTYPE_MC98000_ALL ((cpu_subtype_t) 0) +#define CPU_SUBTYPE_MC98601 ((cpu_subtype_t) 1) + +/* + * HPPA subtypes for Hewlett-Packard HP-PA family of + * risc processors. Port by NeXT to 700 series. + */ + +#define CPU_SUBTYPE_HPPA_ALL ((cpu_subtype_t) 0) +#define CPU_SUBTYPE_HPPA_7100 ((cpu_subtype_t) 0) /* compat */ +#define CPU_SUBTYPE_HPPA_7100LC ((cpu_subtype_t) 1) + +/* + * MC88000 subtypes. + */ +#define CPU_SUBTYPE_MC88000_ALL ((cpu_subtype_t) 0) +#define CPU_SUBTYPE_MC88100 ((cpu_subtype_t) 1) +#define CPU_SUBTYPE_MC88110 ((cpu_subtype_t) 2) + +/* + * SPARC subtypes + */ +#define CPU_SUBTYPE_SPARC_ALL ((cpu_subtype_t) 0) + +/* + * I860 subtypes + */ +#define CPU_SUBTYPE_I860_ALL ((cpu_subtype_t) 0) +#define CPU_SUBTYPE_I860_860 ((cpu_subtype_t) 1) + +/* + * PowerPC subtypes + */ +#define CPU_SUBTYPE_POWERPC_ALL ((cpu_subtype_t) 0) +#define CPU_SUBTYPE_POWERPC_601 ((cpu_subtype_t) 1) +#define CPU_SUBTYPE_POWERPC_602 ((cpu_subtype_t) 2) +#define CPU_SUBTYPE_POWERPC_603 ((cpu_subtype_t) 3) +#define CPU_SUBTYPE_POWERPC_603e ((cpu_subtype_t) 4) +#define CPU_SUBTYPE_POWERPC_603ev ((cpu_subtype_t) 5) +#define CPU_SUBTYPE_POWERPC_604 ((cpu_subtype_t) 6) +#define CPU_SUBTYPE_POWERPC_604e ((cpu_subtype_t) 7) +#define CPU_SUBTYPE_POWERPC_620 ((cpu_subtype_t) 8) +#define CPU_SUBTYPE_POWERPC_750 ((cpu_subtype_t) 9) +#define CPU_SUBTYPE_POWERPC_7400 ((cpu_subtype_t) 10) +#define CPU_SUBTYPE_POWERPC_7450 ((cpu_subtype_t) 11) +#define CPU_SUBTYPE_POWERPC_970 ((cpu_subtype_t) 100) + +/* + * ARM subtypes + */ +#define CPU_SUBTYPE_ARM_ALL ((cpu_subtype_t) 0) +#define CPU_SUBTYPE_ARM_V4T ((cpu_subtype_t) 5) +#define CPU_SUBTYPE_ARM_V6 ((cpu_subtype_t) 6) +#define CPU_SUBTYPE_ARM_V5TEJ ((cpu_subtype_t) 7) +#define CPU_SUBTYPE_ARM_XSCALE ((cpu_subtype_t) 8) +#define CPU_SUBTYPE_ARM_V7 ((cpu_subtype_t) 9) /* ARMv7-A and ARMv7-R */ +#define CPU_SUBTYPE_ARM_V7F ((cpu_subtype_t) 10) /* Cortex A9 */ +#define CPU_SUBTYPE_ARM_V7S ((cpu_subtype_t) 11) /* Swift */ +#define CPU_SUBTYPE_ARM_V7K ((cpu_subtype_t) 12) +#define CPU_SUBTYPE_ARM_V8 ((cpu_subtype_t) 13) +#define CPU_SUBTYPE_ARM_V6M ((cpu_subtype_t) 14) /* Not meant to be run under xnu */ +#define CPU_SUBTYPE_ARM_V7M ((cpu_subtype_t) 15) /* Not meant to be run under xnu */ +#define CPU_SUBTYPE_ARM_V7EM ((cpu_subtype_t) 16) /* Not meant to be run under xnu */ +#define CPU_SUBTYPE_ARM_V8M ((cpu_subtype_t) 17) /* Not meant to be run under xnu */ + +/* + * ARM64 subtypes + */ +#define CPU_SUBTYPE_ARM64_ALL ((cpu_subtype_t) 0) +#define CPU_SUBTYPE_ARM64_V8 ((cpu_subtype_t) 1) +#define CPU_SUBTYPE_ARM64E ((cpu_subtype_t) 2) + +/* CPU subtype feature flags for ptrauth on arm64e platforms */ +#define CPU_SUBTYPE_ARM64_PTR_AUTH_MASK 0x0f000000 +#define CPU_SUBTYPE_ARM64_PTR_AUTH_VERSION(x) (((x) & CPU_SUBTYPE_ARM64_PTR_AUTH_MASK) >> 24) + +/* + * ARM64_32 subtypes + */ +#define CPU_SUBTYPE_ARM64_32_ALL ((cpu_subtype_t) 0) +#define CPU_SUBTYPE_ARM64_32_V8 ((cpu_subtype_t) 1) + +#endif /* !__ASSEMBLER__ */ + +/* + * CPU families (sysctl hw.cpufamily) + * + * These are meant to identify the CPU's marketing name - an + * application can map these to (possibly) localized strings. + * NB: the encodings of the CPU families are intentionally arbitrary. + * There is no ordering, and you should never try to deduce whether + * or not some feature is available based on the family. + * Use feature flags (eg, hw.optional.altivec) to test for optional + * functionality. + */ +#define CPUFAMILY_UNKNOWN 0 +#define CPUFAMILY_POWERPC_G3 0xcee41549 +#define CPUFAMILY_POWERPC_G4 0x77c184ae +#define CPUFAMILY_POWERPC_G5 0xed76d8aa +#define CPUFAMILY_INTEL_6_13 0xaa33392b +#define CPUFAMILY_INTEL_PENRYN 0x78ea4fbc +#define CPUFAMILY_INTEL_NEHALEM 0x6b5a4cd2 +#define CPUFAMILY_INTEL_WESTMERE 0x573b5eec +#define CPUFAMILY_INTEL_SANDYBRIDGE 0x5490b78c +#define CPUFAMILY_INTEL_IVYBRIDGE 0x1f65e835 +#define CPUFAMILY_INTEL_HASWELL 0x10b282dc +#define CPUFAMILY_INTEL_BROADWELL 0x582ed09c +#define CPUFAMILY_INTEL_SKYLAKE 0x37fc219f +#define CPUFAMILY_INTEL_KABYLAKE 0x0f817246 +#if !defined(RC_HIDE_XNU_ICELAKE) +#define CPUFAMILY_INTEL_ICELAKE 0x38435547 +#endif /* not RC_HIDE_XNU_ICELAKE */ +#if !defined(RC_HIDE_XNU_COMETLAKE) +#define CPUFAMILY_INTEL_COMETLAKE 0x1cf8a03e +#endif /* not RC_HIDE_XNU_COMETLAKE */ +#define CPUFAMILY_ARM_9 0xe73283ae +#define CPUFAMILY_ARM_11 0x8ff620d8 +#define CPUFAMILY_ARM_XSCALE 0x53b005f5 +#define CPUFAMILY_ARM_12 0xbd1b0ae9 +#define CPUFAMILY_ARM_13 0x0cc90e64 +#define CPUFAMILY_ARM_14 0x96077ef1 +#define CPUFAMILY_ARM_15 0xa8511bca +#define CPUFAMILY_ARM_SWIFT 0x1e2d6381 +#define CPUFAMILY_ARM_CYCLONE 0x37a09642 +#define CPUFAMILY_ARM_TYPHOON 0x2c91a47e +#define CPUFAMILY_ARM_TWISTER 0x92fb37c8 +#define CPUFAMILY_ARM_HURRICANE 0x67ceee93 +#define CPUFAMILY_ARM_MONSOON_MISTRAL 0xe81e7ef6 +#define CPUFAMILY_ARM_VORTEX_TEMPEST 0x07d34b9f +#define CPUFAMILY_ARM_LIGHTNING_THUNDER 0x462504d2 + +/* The following synonyms are deprecated: */ +#define CPUFAMILY_INTEL_6_23 CPUFAMILY_INTEL_PENRYN +#define CPUFAMILY_INTEL_6_26 CPUFAMILY_INTEL_NEHALEM + + +#endif /* _MACH_MACHINE_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/_structs.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/_structs.h new file mode 100644 index 00000000..e0bdc108 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/_structs.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2017 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _MACH_MACHINE__STRUCTS_H_ +#define _MACH_MACHINE__STRUCTS_H_ + +#if defined (__i386__) || defined(__x86_64__) +#include "mach/i386/_structs.h" +#else +#error architecture not supported +#endif + +#endif /* _MACH_MACHINE__STRUCTS_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/asm.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/asm.h new file mode 100644 index 00000000..1cdbb810 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/asm.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2000-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _MACH_MACHINE_ASM_H +#define _MACH_MACHINE_ASM_H + +#if defined (__i386__) || defined(__x86_64__) +#include "mach/i386/asm.h" +#else +#error architecture not supported +#endif + +#endif /* _MACH_MACHINE_ASM_H */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/boolean.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/boolean.h new file mode 100644 index 00000000..6423078b --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/boolean.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2000-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _MACH_MACHINE_BOOLEAN_H_ +#define _MACH_MACHINE_BOOLEAN_H_ + +#if defined (__i386__) || defined(__x86_64__) +#include "mach/i386/boolean.h" +#else +#error architecture not supported +#endif + +#endif /* _MACH_MACHINE_BOOLEAN_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/exception.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/exception.h new file mode 100644 index 00000000..5a85bd37 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/exception.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2000-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _MACH_MACHINE_EXCEPTION_H_ +#define _MACH_MACHINE_EXCEPTION_H_ + +#if defined (__i386__) || defined(__x86_64__) +#include "mach/i386/exception.h" +#else +#error architecture not supported +#endif + +#endif /* _MACH_MACHINE_EXCEPTION_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/kern_return.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/kern_return.h new file mode 100644 index 00000000..276656cb --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/kern_return.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2000-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _MACH_MACHINE_KERN_RETURN_H_ +#define _MACH_MACHINE_KERN_RETURN_H_ + +#if defined (__i386__) || defined(__x86_64__) +#include "mach/i386/kern_return.h" +#else +#error architecture not supported +#endif + +#endif /* _MACH_MACHINE_KERN_RETURN_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/machine_types.defs b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/machine_types.defs new file mode 100644 index 00000000..f4813948 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/machine_types.defs @@ -0,0 +1,130 @@ +/* + * Copyright (c) 2000-2007 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ + +/* + * Header file for basic, machine-dependent data types. arm+i386 version. + */ + +#ifndef _MACH_MACHINE_MACHNINE_TYPES_DEFS +#define _MACH_MACHINE_MACHNINE_TYPES_DEFS + +type short = int16_t; +type int = int32_t; +type unsigned = uint32_t; + +type float = MACH_MSG_TYPE_REAL_32; +type double = MACH_MSG_TYPE_REAL_64; + + +/* from ISO/IEC 988:1999 spec */ +/* 7.18.1.4 Integer types capable of hgolding object pointers */ +/* + * The [u]intptr_t types for the native + * integer type, e.g. 32 or 64 or.. whatever + * register size the machine has. They are + * used for entities that might be either + * [unsigned] integers or pointers, and for + * type-casting between the two. + * + * For instance, the IPC system represents + * a port in user space as an integer and + * in kernel space as a pointer. + */ +#if defined(__LP64__) +type uintptr_t = uint64_t; +type intptr_t = int64_t; +#else +type uintptr_t = uint32_t; +type intptr_t = int32_t; +#endif + +/* + * These are the legacy Mach types that are + * the [rough] equivalents of the standards above. + * They were defined in terms of int, not + * long int, so they remain separate. + */ +#if defined(__LP64__) +type register_t = int64_t; +#else +type register_t = int32_t; +#endif +type integer_t = int32_t; +type natural_t = uint32_t; + +/* + * These are the VM types that scale with the address + * space size of a given process. + */ + +#if defined(__LP64__) +type vm_address_t = uint64_t; +type vm_offset_t = uint64_t; +type vm_size_t = uint64_t; +#else +type vm_address_t = natural_t; +type vm_offset_t = natural_t; +type vm_size_t = natural_t; +#endif + +/* This is a bit of a hack for arm. We implement the backend with a wide type, but present a native-sized type to callers */ +type mach_port_context_t = uint64_t; + +/* + * The mach_vm_xxx_t types are sized to hold the + * maximum pointer, offset, etc... supported on the + * platform. + */ +type mach_vm_address_t = uint64_t; +type mach_vm_offset_t = uint64_t; +type mach_vm_size_t = uint64_t; + +#if MACH_IPC_COMPAT +/* + * For the old IPC interface + */ +#define MSG_TYPE_PORT_NAME natural_t + +#endif /* MACH_IPC_COMPAT */ + +/* + * These are types used internal to Mach to implement the + * legacy 32-bit VM APIs published by the kernel. + */ +#define VM32_SUPPORT 1 + +type vm32_address_t = uint32_t; +type vm32_offset_t = uint32_t; +type vm32_size_t = uint32_t; + +#endif /* _MACH_MACHINE_MACHNINE_TYPES_DEFS */ + +/* vim: set ft=c : */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/ndr_def.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/ndr_def.h new file mode 100644 index 00000000..26b9099c --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/ndr_def.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2000-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _MACH_MACHINE_NDR_DEF_H +#define _MACH_MACHINE_NDR_DEF_H + +#if defined (__i386__) || defined(__x86_64__) +#include "mach/i386/ndr_def.h" +#else +#error architecture not supported +#endif + +#endif /* _MACH_MACHINE_NDR_DEF_H */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/processor_info.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/processor_info.h new file mode 100644 index 00000000..da865d7f --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/processor_info.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2000-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _MACH_MACHINE_PROCESSOR_INFO_H_ +#define _MACH_MACHINE_PROCESSOR_INFO_H_ + +#if defined (__i386__) || defined(__x86_64__) +#include "mach/i386/processor_info.h" +#else +#error architecture not supported +#endif + +#endif /* _MACH_MACHINE_PROCESSOR_INFO_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/rpc.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/rpc.h new file mode 100644 index 00000000..196a1546 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/rpc.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2000-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _MACH_MACHINE_RPC_H_ +#define _MACH_MACHINE_RPC_H_ + +#if defined (__i386__) || defined(__x86_64__) +#include "mach/i386/rpc.h" +#else +#error architecture not supported +#endif + +#endif /* _MACH_MACHINE_RPC_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/sdt.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/sdt.h new file mode 100644 index 00000000..8cd16fe2 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/sdt.h @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2007-2019 Apple Inc. All rights reserved. + */ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _MACH_MACHINE_SYS_SDT_H +#define _MACH_MACHINE_SYS_SDT_H + +#include + + +#endif /* _MACH_MACHINE_SYS_SDT_H */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/sdt_isa.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/sdt_isa.h new file mode 100644 index 00000000..edd26dcc --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/sdt_isa.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2000-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +#ifndef _MACH_MACHINE_SDT_ISA_H_ +#define _MACH_MACHINE_SDT_ISA_H_ + +#if defined (__i386__) || defined(__x86_64__) +#include +#else +#error architecture not supported +#endif + +#endif /* _BSD_MACHINE_SDT_ISA_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/thread_state.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/thread_state.h new file mode 100644 index 00000000..7dbfecef --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/thread_state.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2000-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _MACH_MACHINE_THREAD_STATE_H_ +#define _MACH_MACHINE_THREAD_STATE_H_ + +#if defined (__i386__) || defined(__x86_64__) +#include "mach/i386/thread_state.h" +#else +#error architecture not supported +#endif + +#endif /* _MACH_MACHINE_THREAD_STATE_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/thread_status.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/thread_status.h new file mode 100644 index 00000000..1c389658 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/thread_status.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2000-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _MACH_MACHINE_THREAD_STATUS_H_ +#define _MACH_MACHINE_THREAD_STATUS_H_ + +#if defined (__i386__) || defined(__x86_64__) +#include "mach/i386/thread_status.h" +#else +#error architecture not supported +#endif + +#endif /* _MACH_MACHINE_THREAD_STATUS_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/vm_param.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/vm_param.h new file mode 100644 index 00000000..08f4ac5f --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/vm_param.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2000-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _MACH_MACHINE_VM_PARAM_H_ +#define _MACH_MACHINE_VM_PARAM_H_ + +#if defined (__i386__) || defined(__x86_64__) +#include "mach/i386/vm_param.h" +#else +#error architecture not supported +#endif + +#endif /* _MACH_MACHINE_VM_PARAM_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/vm_types.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/vm_types.h new file mode 100644 index 00000000..66cbebfd --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/machine/vm_types.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2000-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _MACH_MACHINE_VM_TYPES_H_ +#define _MACH_MACHINE_VM_TYPES_H_ + +#if defined (__i386__) || defined(__x86_64__) +#include "mach/i386/vm_types.h" +#else +#error architecture not supported +#endif + +#endif /* _MACH_MACHINE_VM_TYPES_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/memory_entry.defs b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/memory_entry.defs new file mode 100644 index 00000000..bcc83f26 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/memory_entry.defs @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2017 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ + +subsystem +#if KERNEL_SERVER + KernelServer +#endif /* KERNEL_SERVER */ + memory_entry 4900; + +#include +#include +#include + +routine mach_memory_entry_purgable_control( + mem_entry : mem_entry_name_port_t; + control : vm_purgable_t; + inout state : int); + +routine mach_memory_entry_access_tracking( + mem_entry : mem_entry_name_port_t; + inout access_tracking : int; + out access_tracking_reads : uint32_t; + out access_tracking_writes : uint32_t); + +routine mach_memory_entry_ownership( + mem_entry : mem_entry_name_port_t; + owner : task_t; + ledger_tag : int; + ledger_flags : int); diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/memory_entry.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/memory_entry.h new file mode 100644 index 00000000..6c51e888 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/memory_entry.h @@ -0,0 +1,249 @@ +#ifndef _memory_entry_user_ +#define _memory_entry_user_ + +/* Module memory_entry */ + +#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 memory_entry_MSG_COUNT +#define memory_entry_MSG_COUNT 3 +#endif /* memory_entry_MSG_COUNT */ + +#include +#include +#include +#include +#include + +#ifdef __BeforeMigUserHeader +__BeforeMigUserHeader +#endif /* __BeforeMigUserHeader */ + +#include +__BEGIN_DECLS + + +/* Routine mach_memory_entry_purgable_control */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_memory_entry_purgable_control +( + mem_entry_name_port_t mem_entry, + vm_purgable_t control, + int *state +); + +/* Routine mach_memory_entry_access_tracking */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_memory_entry_access_tracking +( + mem_entry_name_port_t mem_entry, + int *access_tracking, + uint32_t *access_tracking_reads, + uint32_t *access_tracking_writes +); + +/* Routine mach_memory_entry_ownership */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_memory_entry_ownership +( + mem_entry_name_port_t mem_entry, + task_t owner, + int ledger_tag, + int ledger_flags +); + +__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__memory_entry_subsystem__defined +#define __Request__memory_entry_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_purgable_t control; + int state; + } __Request__mach_memory_entry_purgable_control_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int access_tracking; + } __Request__mach_memory_entry_access_tracking_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 owner; + /* end of the kernel processed data */ + NDR_record_t NDR; + int ledger_tag; + int ledger_flags; + } __Request__mach_memory_entry_ownership_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Request__memory_entry_subsystem__defined */ + +/* union of all requests */ + +#ifndef __RequestUnion__memory_entry_subsystem__defined +#define __RequestUnion__memory_entry_subsystem__defined +union __RequestUnion__memory_entry_subsystem { + __Request__mach_memory_entry_purgable_control_t Request_mach_memory_entry_purgable_control; + __Request__mach_memory_entry_access_tracking_t Request_mach_memory_entry_access_tracking; + __Request__mach_memory_entry_ownership_t Request_mach_memory_entry_ownership; +}; +#endif /* !__RequestUnion__memory_entry_subsystem__defined */ +/* typedefs for all replies */ + +#ifndef __Reply__memory_entry_subsystem__defined +#define __Reply__memory_entry_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int state; + } __Reply__mach_memory_entry_purgable_control_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int access_tracking; + uint32_t access_tracking_reads; + uint32_t access_tracking_writes; + } __Reply__mach_memory_entry_access_tracking_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_memory_entry_ownership_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Reply__memory_entry_subsystem__defined */ + +/* union of all replies */ + +#ifndef __ReplyUnion__memory_entry_subsystem__defined +#define __ReplyUnion__memory_entry_subsystem__defined +union __ReplyUnion__memory_entry_subsystem { + __Reply__mach_memory_entry_purgable_control_t Reply_mach_memory_entry_purgable_control; + __Reply__mach_memory_entry_access_tracking_t Reply_mach_memory_entry_access_tracking; + __Reply__mach_memory_entry_ownership_t Reply_mach_memory_entry_ownership; +}; +#endif /* !__RequestUnion__memory_entry_subsystem__defined */ + +#ifndef subsystem_to_name_map_memory_entry +#define subsystem_to_name_map_memory_entry \ + { "mach_memory_entry_purgable_control", 4900 },\ + { "mach_memory_entry_access_tracking", 4901 },\ + { "mach_memory_entry_ownership", 4902 } +#endif + +#ifdef __AfterMigUserHeader +__AfterMigUserHeader +#endif /* __AfterMigUserHeader */ + +#endif /* _memory_entry_user_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/memory_object_types.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/memory_object_types.h new file mode 100644 index 00000000..1a731d5b --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/memory_object_types.h @@ -0,0 +1,299 @@ +/* + * Copyright (c) 2000-2016 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * File: memory_object.h + * Author: Michael Wayne Young + * + * External memory management interface definition. + */ + +#ifndef _MACH_MEMORY_OBJECT_TYPES_H_ +#define _MACH_MEMORY_OBJECT_TYPES_H_ + +/* + * User-visible types used in the external memory + * management interface: + */ + +#include +#include +#include +#include +#include +#include + +#include + +#define VM_64_BIT_DATA_OBJECTS + +typedef unsigned long long memory_object_offset_t; +typedef unsigned long long memory_object_size_t; +typedef natural_t memory_object_cluster_size_t; +typedef natural_t * memory_object_fault_info_t; + +typedef unsigned long long vm_object_id_t; + + +/* + * Temporary until real EMMI version gets re-implemented + */ + + +typedef mach_port_t memory_object_t; +typedef mach_port_t memory_object_control_t; + + +typedef memory_object_t *memory_object_array_t; +/* A memory object ... */ +/* Used by the kernel to retrieve */ +/* or store data */ + +typedef mach_port_t memory_object_name_t; +/* Used to describe the memory ... */ +/* object in vm_regions() calls */ + +typedef mach_port_t memory_object_default_t; +/* Registered with the host ... */ +/* for creating new internal objects */ + +#define MEMORY_OBJECT_NULL ((memory_object_t) 0) +#define MEMORY_OBJECT_CONTROL_NULL ((memory_object_control_t) 0) +#define MEMORY_OBJECT_NAME_NULL ((memory_object_name_t) 0) +#define MEMORY_OBJECT_DEFAULT_NULL ((memory_object_default_t) 0) + + +typedef int memory_object_copy_strategy_t; +/* How memory manager handles copy: */ +#define MEMORY_OBJECT_COPY_NONE 0 +/* ... No special support */ +#define MEMORY_OBJECT_COPY_CALL 1 +/* ... Make call on memory manager */ +#define MEMORY_OBJECT_COPY_DELAY 2 +/* ... Memory manager doesn't + * change data externally. + */ +#define MEMORY_OBJECT_COPY_TEMPORARY 3 +/* ... Memory manager doesn't + * change data externally, and + * doesn't need to see changes. + */ +#define MEMORY_OBJECT_COPY_SYMMETRIC 4 +/* ... Memory manager doesn't + * change data externally, + * doesn't need to see changes, + * and object will not be + * multiply mapped. + * + * XXX + * Not yet safe for non-kernel use. + */ + +#define MEMORY_OBJECT_COPY_INVALID 5 +/* ... An invalid copy strategy, + * for external objects which + * have not been initialized. + * Allows copy_strategy to be + * examined without also + * examining pager_ready and + * internal. + */ + +typedef int memory_object_return_t; +/* Which pages to return to manager + * this time (lock_request) */ +#define MEMORY_OBJECT_RETURN_NONE 0 +/* ... don't return any. */ +#define MEMORY_OBJECT_RETURN_DIRTY 1 +/* ... only dirty pages. */ +#define MEMORY_OBJECT_RETURN_ALL 2 +/* ... dirty and precious pages. */ +#define MEMORY_OBJECT_RETURN_ANYTHING 3 +/* ... any resident page. */ + +/* + * Data lock request flags + */ + +#define MEMORY_OBJECT_DATA_FLUSH 0x1 +#define MEMORY_OBJECT_DATA_NO_CHANGE 0x2 +#define MEMORY_OBJECT_DATA_PURGE 0x4 +#define MEMORY_OBJECT_COPY_SYNC 0x8 +#define MEMORY_OBJECT_DATA_SYNC 0x10 +#define MEMORY_OBJECT_IO_SYNC 0x20 +#define MEMORY_OBJECT_DATA_FLUSH_ALL 0x40 + +/* + * Types for the memory object flavor interfaces + */ + +#define MEMORY_OBJECT_INFO_MAX (1024) +typedef int *memory_object_info_t; +typedef int memory_object_flavor_t; +typedef int memory_object_info_data_t[MEMORY_OBJECT_INFO_MAX]; + + +#define MEMORY_OBJECT_PERFORMANCE_INFO 11 +#define MEMORY_OBJECT_ATTRIBUTE_INFO 14 +#define MEMORY_OBJECT_BEHAVIOR_INFO 15 + + +struct memory_object_perf_info { + memory_object_cluster_size_t cluster_size; + boolean_t may_cache; +}; + +struct memory_object_attr_info { + memory_object_copy_strategy_t copy_strategy; + memory_object_cluster_size_t cluster_size; + boolean_t may_cache_object; + boolean_t temporary; +}; + +struct memory_object_behave_info { + memory_object_copy_strategy_t copy_strategy; + boolean_t temporary; + boolean_t invalidate; + boolean_t silent_overwrite; + boolean_t advisory_pageout; +}; + + +typedef struct memory_object_behave_info *memory_object_behave_info_t; +typedef struct memory_object_behave_info memory_object_behave_info_data_t; + +typedef struct memory_object_perf_info *memory_object_perf_info_t; +typedef struct memory_object_perf_info memory_object_perf_info_data_t; + +typedef struct memory_object_attr_info *memory_object_attr_info_t; +typedef struct memory_object_attr_info memory_object_attr_info_data_t; + +#define MEMORY_OBJECT_BEHAVE_INFO_COUNT ((mach_msg_type_number_t) \ + (sizeof(memory_object_behave_info_data_t)/sizeof(int))) +#define MEMORY_OBJECT_PERF_INFO_COUNT ((mach_msg_type_number_t) \ + (sizeof(memory_object_perf_info_data_t)/sizeof(int))) +#define MEMORY_OBJECT_ATTR_INFO_COUNT ((mach_msg_type_number_t) \ + (sizeof(memory_object_attr_info_data_t)/sizeof(int))) + +#define invalid_memory_object_flavor(f) \ + (f != MEMORY_OBJECT_ATTRIBUTE_INFO && \ + f != MEMORY_OBJECT_PERFORMANCE_INFO && \ + f != OLD_MEMORY_OBJECT_BEHAVIOR_INFO && \ + f != MEMORY_OBJECT_BEHAVIOR_INFO && \ + f != OLD_MEMORY_OBJECT_ATTRIBUTE_INFO) + + +/* + * Used to support options on memory_object_release_name call + */ +#define MEMORY_OBJECT_TERMINATE_IDLE 0x1 +#define MEMORY_OBJECT_RESPECT_CACHE 0x2 +#define MEMORY_OBJECT_RELEASE_NO_OP 0x4 + + +/* named entry processor mapping options */ +/* enumerated */ +#define MAP_MEM_NOOP 0 +#define MAP_MEM_COPYBACK 1 +#define MAP_MEM_IO 2 +#define MAP_MEM_WTHRU 3 +#define MAP_MEM_WCOMB 4 /* Write combining mode */ + /* aka store gather */ +#define MAP_MEM_INNERWBACK 5 +#define MAP_MEM_POSTED 6 +#define MAP_MEM_RT 7 +#define MAP_MEM_POSTED_REORDERED 8 +#define MAP_MEM_POSTED_COMBINED_REORDERED 9 + +#define GET_MAP_MEM(flags) \ + ((((unsigned int)(flags)) >> 24) & 0xFF) + +#define SET_MAP_MEM(caching, flags) \ + ((flags) = ((((unsigned int)(caching)) << 24) \ + & 0xFF000000) | ((flags) & 0xFFFFFF)); + +/* leave room for vm_prot bits (0xFF ?) */ +#define MAP_MEM_LEDGER_TAGGED 0x002000 /* object owned by a specific task and ledger */ +#define MAP_MEM_PURGABLE_KERNEL_ONLY 0x004000 /* volatility controlled by kernel */ +#define MAP_MEM_GRAB_SECLUDED 0x008000 /* can grab secluded pages */ +#define MAP_MEM_ONLY 0x010000 /* change processor caching */ +#define MAP_MEM_NAMED_CREATE 0x020000 /* create extant object */ +#define MAP_MEM_PURGABLE 0x040000 /* create a purgable VM object */ +#define MAP_MEM_NAMED_REUSE 0x080000 /* reuse provided entry if identical */ +#define MAP_MEM_USE_DATA_ADDR 0x100000 /* preserve address of data, rather than base of page */ +#define MAP_MEM_VM_COPY 0x200000 /* make a copy of a VM range */ +#define MAP_MEM_VM_SHARE 0x400000 /* extract a VM range for remap */ +#define MAP_MEM_4K_DATA_ADDR 0x800000 /* preserve 4K aligned address of data */ + +#define MAP_MEM_FLAGS_MASK 0x00FFFF00 +#define MAP_MEM_FLAGS_USER ( \ + MAP_MEM_PURGABLE_KERNEL_ONLY | \ + MAP_MEM_GRAB_SECLUDED | \ + MAP_MEM_ONLY | \ + MAP_MEM_NAMED_CREATE | \ + MAP_MEM_PURGABLE | \ + MAP_MEM_NAMED_REUSE | \ + MAP_MEM_USE_DATA_ADDR | \ + MAP_MEM_VM_COPY | \ + MAP_MEM_VM_SHARE | \ + MAP_MEM_LEDGER_TAGGED | \ + MAP_MEM_4K_DATA_ADDR) +#define MAP_MEM_FLAGS_ALL ( \ + MAP_MEM_FLAGS_USER) + + +#endif /* _MACH_MEMORY_OBJECT_TYPES_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/message.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/message.h new file mode 100644 index 00000000..59e9fa07 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/message.h @@ -0,0 +1,902 @@ +/* + * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * NOTICE: This file was modified by McAfee Research in 2004 to introduce + * support for mandatory and extensible security protections. This notice + * is included in support of clause 2.2 (b) of the Apple Public License, + * Version 2.0. + * Copyright (c) 2005 SPARTA, Inc. + */ +/* + */ +/* + * File: mach/message.h + * + * Mach IPC message and primitive function definitions. + */ + +#ifndef _MACH_MESSAGE_H_ +#define _MACH_MESSAGE_H_ + +#include +#include +#include +#include +#include + +#include +#include +#include + +/* + * The timeout mechanism uses mach_msg_timeout_t values, + * passed by value. The timeout units are milliseconds. + * It is controlled with the MACH_SEND_TIMEOUT + * and MACH_RCV_TIMEOUT options. + */ + +typedef natural_t mach_msg_timeout_t; + +/* + * The value to be used when there is no timeout. + * (No MACH_SEND_TIMEOUT/MACH_RCV_TIMEOUT option.) + */ + +#define MACH_MSG_TIMEOUT_NONE ((mach_msg_timeout_t) 0) + +/* + * The kernel uses MACH_MSGH_BITS_COMPLEX as a hint. If it isn't on, it + * assumes the body of the message doesn't contain port rights or OOL + * data. The field is set in received messages. A user task must + * use caution in interpreting the body of a message if the bit isn't + * on, because the mach_msg_type's in the body might "lie" about the + * contents. If the bit isn't on, but the mach_msg_types + * in the body specify rights or OOL data, the behavior is undefined. + * (Ie, an error may or may not be produced.) + * + * The value of MACH_MSGH_BITS_REMOTE determines the interpretation + * of the msgh_remote_port field. It is handled like a msgt_name, + * but must result in a send or send-once type right. + * + * The value of MACH_MSGH_BITS_LOCAL determines the interpretation + * of the msgh_local_port field. It is handled like a msgt_name, + * and also must result in a send or send-once type right. + * + * The value of MACH_MSGH_BITS_VOUCHER determines the interpretation + * of the msgh_voucher_port field. It is handled like a msgt_name, + * but must result in a send right (and the msgh_voucher_port field + * must be the name of a send right to a Mach voucher kernel object. + * + * MACH_MSGH_BITS() combines two MACH_MSG_TYPE_* values, for the remote + * and local fields, into a single value suitable for msgh_bits. + * + * MACH_MSGH_BITS_CIRCULAR should be zero; is is used internally. + * + * The unused bits should be zero and are reserved for the kernel + * or for future interface expansion. + */ + +#define MACH_MSGH_BITS_ZERO 0x00000000 + +#define MACH_MSGH_BITS_REMOTE_MASK 0x0000001f +#define MACH_MSGH_BITS_LOCAL_MASK 0x00001f00 +#define MACH_MSGH_BITS_VOUCHER_MASK 0x001f0000 + +#define MACH_MSGH_BITS_PORTS_MASK \ + (MACH_MSGH_BITS_REMOTE_MASK | \ + MACH_MSGH_BITS_LOCAL_MASK | \ + MACH_MSGH_BITS_VOUCHER_MASK) + +#define MACH_MSGH_BITS_COMPLEX 0x80000000U /* message is complex */ + +#define MACH_MSGH_BITS_USER 0x801f1f1fU /* allowed bits user->kernel */ + +#define MACH_MSGH_BITS_RAISEIMP 0x20000000U /* importance raised due to msg */ +#define MACH_MSGH_BITS_DENAP MACH_MSGH_BITS_RAISEIMP + +#define MACH_MSGH_BITS_IMPHOLDASRT 0x10000000U /* assertion help, userland private */ +#define MACH_MSGH_BITS_DENAPHOLDASRT MACH_MSGH_BITS_IMPHOLDASRT + +#define MACH_MSGH_BITS_CIRCULAR 0x10000000U /* message circular, kernel private */ + +#define MACH_MSGH_BITS_USED 0xb01f1f1fU + +/* setter macros for the bits */ +#define MACH_MSGH_BITS(remote, local) /* legacy */ \ + ((remote) | ((local) << 8)) +#define MACH_MSGH_BITS_SET_PORTS(remote, local, voucher) \ + (((remote) & MACH_MSGH_BITS_REMOTE_MASK) | \ + (((local) << 8) & MACH_MSGH_BITS_LOCAL_MASK) | \ + (((voucher) << 16) & MACH_MSGH_BITS_VOUCHER_MASK)) +#define MACH_MSGH_BITS_SET(remote, local, voucher, other) \ + (MACH_MSGH_BITS_SET_PORTS((remote), (local), (voucher)) \ + | ((other) &~ MACH_MSGH_BITS_PORTS_MASK)) + +/* getter macros for pulling values out of the bits field */ +#define MACH_MSGH_BITS_REMOTE(bits) \ + ((bits) & MACH_MSGH_BITS_REMOTE_MASK) +#define MACH_MSGH_BITS_LOCAL(bits) \ + (((bits) & MACH_MSGH_BITS_LOCAL_MASK) >> 8) +#define MACH_MSGH_BITS_VOUCHER(bits) \ + (((bits) & MACH_MSGH_BITS_VOUCHER_MASK) >> 16) +#define MACH_MSGH_BITS_PORTS(bits) \ + ((bits) & MACH_MSGH_BITS_PORTS_MASK) +#define MACH_MSGH_BITS_OTHER(bits) \ + ((bits) &~ MACH_MSGH_BITS_PORTS_MASK) + +/* checking macros */ +#define MACH_MSGH_BITS_HAS_REMOTE(bits) \ + (MACH_MSGH_BITS_REMOTE(bits) != MACH_MSGH_BITS_ZERO) +#define MACH_MSGH_BITS_HAS_LOCAL(bits) \ + (MACH_MSGH_BITS_LOCAL(bits) != MACH_MSGH_BITS_ZERO) +#define MACH_MSGH_BITS_HAS_VOUCHER(bits) \ + (MACH_MSGH_BITS_VOUCHER(bits) != MACH_MSGH_BITS_ZERO) +#define MACH_MSGH_BITS_IS_COMPLEX(bits) \ + (((bits) & MACH_MSGH_BITS_COMPLEX) != MACH_MSGH_BITS_ZERO) + +/* importance checking macros */ +#define MACH_MSGH_BITS_RAISED_IMPORTANCE(bits) \ + (((bits) & MACH_MSGH_BITS_RAISEIMP) != MACH_MSGH_BITS_ZERO) +#define MACH_MSGH_BITS_HOLDS_IMPORTANCE_ASSERTION(bits) \ + (((bits) & MACH_MSGH_BITS_IMPHOLDASRT) != MACH_MSGH_BITS_ZERO) + +/* + * Every message starts with a message header. + * Following the message header, if the message is complex, are a count + * of type descriptors and the type descriptors themselves + * (mach_msg_descriptor_t). The size of the message must be specified in + * bytes, and includes the message header, descriptor count, descriptors, + * and inline data. + * + * The msgh_remote_port field specifies the destination of the message. + * It must specify a valid send or send-once right for a port. + * + * The msgh_local_port field specifies a "reply port". Normally, + * This field carries a send-once right that the receiver will use + * to reply to the message. It may carry the values MACH_PORT_NULL, + * MACH_PORT_DEAD, a send-once right, or a send right. + * + * The msgh_voucher_port field specifies a Mach voucher port. Only + * send rights to kernel-implemented Mach Voucher kernel objects in + * addition to MACH_PORT_NULL or MACH_PORT_DEAD may be passed. + * + * The msgh_id field is uninterpreted by the message primitives. + * It normally carries information specifying the format + * or meaning of the message. + */ + +typedef unsigned int mach_msg_bits_t; +typedef natural_t mach_msg_size_t; +typedef integer_t mach_msg_id_t; + +#define MACH_MSG_SIZE_NULL (mach_msg_size_t *) 0 + +typedef unsigned int mach_msg_priority_t; + +#define MACH_MSG_PRIORITY_UNSPECIFIED (mach_msg_priority_t) 0 + +typedef unsigned int mach_msg_type_name_t; + +#define MACH_MSG_TYPE_MOVE_RECEIVE 16 /* Must hold receive right */ +#define MACH_MSG_TYPE_MOVE_SEND 17 /* Must hold send right(s) */ +#define MACH_MSG_TYPE_MOVE_SEND_ONCE 18 /* Must hold sendonce right */ +#define MACH_MSG_TYPE_COPY_SEND 19 /* Must hold send right(s) */ +#define MACH_MSG_TYPE_MAKE_SEND 20 /* Must hold receive right */ +#define MACH_MSG_TYPE_MAKE_SEND_ONCE 21 /* Must hold receive right */ +#define MACH_MSG_TYPE_COPY_RECEIVE 22 /* NOT VALID */ +#define MACH_MSG_TYPE_DISPOSE_RECEIVE 24 /* must hold receive right */ +#define MACH_MSG_TYPE_DISPOSE_SEND 25 /* must hold send right(s) */ +#define MACH_MSG_TYPE_DISPOSE_SEND_ONCE 26 /* must hold sendonce right */ + +typedef unsigned int mach_msg_copy_options_t; + +#define MACH_MSG_PHYSICAL_COPY 0 +#define MACH_MSG_VIRTUAL_COPY 1 +#define MACH_MSG_ALLOCATE 2 +#define MACH_MSG_OVERWRITE 3 /* deprecated */ +#ifdef MACH_KERNEL +#define MACH_MSG_KALLOC_COPY_T 4 +#endif /* MACH_KERNEL */ + +#define MACH_MSG_GUARD_FLAGS_NONE 0x0000 +#define MACH_MSG_GUARD_FLAGS_IMMOVABLE_RECEIVE 0x0001 /* Move the receive right and mark it as immovable */ +#define MACH_MSG_GUARD_FLAGS_UNGUARDED_ON_SEND 0x0002 /* Verify that the port is unguarded */ +#define MACH_MSG_GUARD_FLAGS_MASK 0x0003 /* Valid flag bits */ +typedef unsigned int mach_msg_guard_flags_t; + +/* + * In a complex mach message, the mach_msg_header_t is followed by + * a descriptor count, then an array of that number of descriptors + * (mach_msg_*_descriptor_t). The type field of mach_msg_type_descriptor_t + * (which any descriptor can be cast to) indicates the flavor of the + * descriptor. + * + * Note that in LP64, the various types of descriptors are no longer all + * the same size as mach_msg_descriptor_t, so the array cannot be indexed + * as expected. + */ + +typedef unsigned int mach_msg_descriptor_type_t; + +#define MACH_MSG_PORT_DESCRIPTOR 0 +#define MACH_MSG_OOL_DESCRIPTOR 1 +#define MACH_MSG_OOL_PORTS_DESCRIPTOR 2 +#define MACH_MSG_OOL_VOLATILE_DESCRIPTOR 3 +#define MACH_MSG_GUARDED_PORT_DESCRIPTOR 4 + +#pragma pack(push, 4) + +typedef struct{ + natural_t pad1; + mach_msg_size_t pad2; + unsigned int pad3 : 24; + mach_msg_descriptor_type_t type : 8; +} mach_msg_type_descriptor_t; + +typedef struct{ + mach_port_t name; +// Pad to 8 bytes everywhere except the K64 kernel where mach_port_t is 8 bytes + mach_msg_size_t pad1; + unsigned int pad2 : 16; + mach_msg_type_name_t disposition : 8; + mach_msg_descriptor_type_t type : 8; +} mach_msg_port_descriptor_t; + +typedef struct{ + uint32_t address; + mach_msg_size_t size; + boolean_t deallocate: 8; + mach_msg_copy_options_t copy: 8; + unsigned int pad1: 8; + mach_msg_descriptor_type_t type: 8; +} mach_msg_ool_descriptor32_t; + +typedef struct{ + uint64_t address; + boolean_t deallocate: 8; + mach_msg_copy_options_t copy: 8; + unsigned int pad1: 8; + mach_msg_descriptor_type_t type: 8; + mach_msg_size_t size; +} mach_msg_ool_descriptor64_t; + +typedef struct{ + void* address; +#if !defined(__LP64__) + mach_msg_size_t size; +#endif + boolean_t deallocate: 8; + mach_msg_copy_options_t copy: 8; + unsigned int pad1: 8; + mach_msg_descriptor_type_t type: 8; +#if defined(__LP64__) + mach_msg_size_t size; +#endif +} mach_msg_ool_descriptor_t; + +typedef struct{ + uint32_t address; + mach_msg_size_t count; + boolean_t deallocate: 8; + mach_msg_copy_options_t copy: 8; + mach_msg_type_name_t disposition : 8; + mach_msg_descriptor_type_t type : 8; +} mach_msg_ool_ports_descriptor32_t; + +typedef struct{ + uint64_t address; + boolean_t deallocate: 8; + mach_msg_copy_options_t copy: 8; + mach_msg_type_name_t disposition : 8; + mach_msg_descriptor_type_t type : 8; + mach_msg_size_t count; +} mach_msg_ool_ports_descriptor64_t; + +typedef struct{ + void* address; +#if !defined(__LP64__) + mach_msg_size_t count; +#endif + boolean_t deallocate: 8; + mach_msg_copy_options_t copy: 8; + mach_msg_type_name_t disposition : 8; + mach_msg_descriptor_type_t type : 8; +#if defined(__LP64__) + mach_msg_size_t count; +#endif +} mach_msg_ool_ports_descriptor_t; + +typedef struct{ + uint32_t context; + mach_port_name_t name; + mach_msg_guard_flags_t flags : 16; + mach_msg_type_name_t disposition : 8; + mach_msg_descriptor_type_t type : 8; +} mach_msg_guarded_port_descriptor32_t; + +typedef struct{ + uint64_t context; + mach_msg_guard_flags_t flags : 16; + mach_msg_type_name_t disposition : 8; + mach_msg_descriptor_type_t type : 8; + mach_port_name_t name; +} mach_msg_guarded_port_descriptor64_t; + +typedef struct{ + mach_port_context_t context; +#if !defined(__LP64__) + mach_port_name_t name; +#endif + mach_msg_guard_flags_t flags : 16; + mach_msg_type_name_t disposition : 8; + mach_msg_descriptor_type_t type : 8; +#if defined(__LP64__) + mach_port_name_t name; +#endif /* defined(__LP64__) */ +} mach_msg_guarded_port_descriptor_t; + +/* + * LP64support - This union definition is not really + * appropriate in LP64 mode because not all descriptors + * are of the same size in that environment. + */ +typedef union{ + mach_msg_port_descriptor_t port; + mach_msg_ool_descriptor_t out_of_line; + mach_msg_ool_ports_descriptor_t ool_ports; + mach_msg_type_descriptor_t type; + mach_msg_guarded_port_descriptor_t guarded_port; +} mach_msg_descriptor_t; + +typedef struct{ + mach_msg_size_t msgh_descriptor_count; +} mach_msg_body_t; + +#define MACH_MSG_BODY_NULL (mach_msg_body_t *) 0 +#define MACH_MSG_DESCRIPTOR_NULL (mach_msg_descriptor_t *) 0 + +typedef struct{ + mach_msg_bits_t msgh_bits; + mach_msg_size_t msgh_size; + mach_port_t msgh_remote_port; + mach_port_t msgh_local_port; + mach_port_name_t msgh_voucher_port; + mach_msg_id_t msgh_id; +} mach_msg_header_t; + +#define msgh_reserved msgh_voucher_port +#define MACH_MSG_NULL (mach_msg_header_t *) 0 + +typedef struct{ + mach_msg_header_t header; + mach_msg_body_t body; +} mach_msg_base_t; + +typedef unsigned int mach_msg_trailer_type_t; + +#define MACH_MSG_TRAILER_FORMAT_0 0 + +typedef unsigned int mach_msg_trailer_size_t; +typedef char *mach_msg_trailer_info_t; + +typedef struct{ + mach_msg_trailer_type_t msgh_trailer_type; + mach_msg_trailer_size_t msgh_trailer_size; +} mach_msg_trailer_t; + +/* + * The msgh_seqno field carries a sequence number + * associated with the received-from port. A port's + * sequence number is incremented every time a message + * is received from it and included in the received + * trailer to help put messages back in sequence if + * multiple threads receive and/or process received + * messages. + */ +typedef struct{ + mach_msg_trailer_type_t msgh_trailer_type; + mach_msg_trailer_size_t msgh_trailer_size; + mach_port_seqno_t msgh_seqno; +} mach_msg_seqno_trailer_t; + +typedef struct{ + unsigned int val[2]; +} security_token_t; + +typedef struct{ + mach_msg_trailer_type_t msgh_trailer_type; + mach_msg_trailer_size_t msgh_trailer_size; + mach_port_seqno_t msgh_seqno; + security_token_t msgh_sender; +} mach_msg_security_trailer_t; + +/* + * The audit token is an opaque token which identifies + * Mach tasks and senders of Mach messages as subjects + * to the BSM audit system. Only the appropriate BSM + * library routines should be used to interpret the + * contents of the audit token as the representation + * of the subject identity within the token may change + * over time. + */ +typedef struct{ + unsigned int val[8]; +} audit_token_t; + +typedef struct{ + mach_msg_trailer_type_t msgh_trailer_type; + mach_msg_trailer_size_t msgh_trailer_size; + mach_port_seqno_t msgh_seqno; + security_token_t msgh_sender; + audit_token_t msgh_audit; +} mach_msg_audit_trailer_t; + +typedef struct{ + mach_msg_trailer_type_t msgh_trailer_type; + mach_msg_trailer_size_t msgh_trailer_size; + mach_port_seqno_t msgh_seqno; + security_token_t msgh_sender; + audit_token_t msgh_audit; + mach_port_context_t msgh_context; +} mach_msg_context_trailer_t; + + + +typedef struct{ + mach_port_name_t sender; +} msg_labels_t; + +/* + * Trailer type to pass MAC policy label info as a mach message trailer. + * + */ + +typedef struct{ + mach_msg_trailer_type_t msgh_trailer_type; + mach_msg_trailer_size_t msgh_trailer_size; + mach_port_seqno_t msgh_seqno; + security_token_t msgh_sender; + audit_token_t msgh_audit; + mach_port_context_t msgh_context; + int msgh_ad; + msg_labels_t msgh_labels; +} mach_msg_mac_trailer_t; + + +#define MACH_MSG_TRAILER_MINIMUM_SIZE sizeof(mach_msg_trailer_t) + +/* + * These values can change from release to release - but clearly + * code cannot request additional trailer elements one was not + * compiled to understand. Therefore, it is safe to use this + * constant when the same module specified the receive options. + * Otherwise, you run the risk that the options requested by + * another module may exceed the local modules notion of + * MAX_TRAILER_SIZE. + */ + +typedef mach_msg_mac_trailer_t mach_msg_max_trailer_t; +#define MAX_TRAILER_SIZE ((mach_msg_size_t)sizeof(mach_msg_max_trailer_t)) + +/* + * Legacy requirements keep us from ever updating these defines (even + * when the format_0 trailers gain new option data fields in the future). + * Therefore, they shouldn't be used going forward. Instead, the sizes + * should be compared against the specific element size requested using + * REQUESTED_TRAILER_SIZE. + */ +typedef mach_msg_security_trailer_t mach_msg_format_0_trailer_t; + +/*typedef mach_msg_mac_trailer_t mach_msg_format_0_trailer_t; + */ + +#define MACH_MSG_TRAILER_FORMAT_0_SIZE sizeof(mach_msg_format_0_trailer_t) + +#define KERNEL_SECURITY_TOKEN_VALUE { {0, 1} } +extern const security_token_t KERNEL_SECURITY_TOKEN; + +#define KERNEL_AUDIT_TOKEN_VALUE { {0, 0, 0, 0, 0, 0, 0, 0} } +extern const audit_token_t KERNEL_AUDIT_TOKEN; + +typedef integer_t mach_msg_options_t; + +typedef struct{ + mach_msg_header_t header; +} mach_msg_empty_send_t; + +typedef struct{ + mach_msg_header_t header; + mach_msg_trailer_t trailer; +} mach_msg_empty_rcv_t; + +typedef union{ + mach_msg_empty_send_t send; + mach_msg_empty_rcv_t rcv; +} mach_msg_empty_t; + +#pragma pack(pop) + +/* utility to round the message size - will become machine dependent */ +#define round_msg(x) (((mach_msg_size_t)(x) + sizeof (natural_t) - 1) & \ + ~(sizeof (natural_t) - 1)) + + +/* + * There is no fixed upper bound to the size of Mach messages. + */ +#define MACH_MSG_SIZE_MAX ((mach_msg_size_t) ~0) + +#if defined(__APPLE_API_PRIVATE) +/* + * But architectural limits of a given implementation, or + * temporal conditions may cause unpredictable send failures + * for messages larger than MACH_MSG_SIZE_RELIABLE. + * + * In either case, waiting for memory is [currently] outside + * the scope of send timeout values provided to IPC. + */ +#define MACH_MSG_SIZE_RELIABLE ((mach_msg_size_t) 256 * 1024) +#endif +/* + * Compatibility definitions, for code written + * when there was a msgh_kind instead of msgh_seqno. + */ +#define MACH_MSGH_KIND_NORMAL 0x00000000 +#define MACH_MSGH_KIND_NOTIFICATION 0x00000001 +#define msgh_kind msgh_seqno +#define mach_msg_kind_t mach_port_seqno_t + +typedef natural_t mach_msg_type_size_t; +typedef natural_t mach_msg_type_number_t; + +/* + * Values received/carried in messages. Tells the receiver what + * sort of port right he now has. + * + * MACH_MSG_TYPE_PORT_NAME is used to transfer a port name + * which should remain uninterpreted by the kernel. (Port rights + * are not transferred, just the port name.) + */ + +#define MACH_MSG_TYPE_PORT_NONE 0 + +#define MACH_MSG_TYPE_PORT_NAME 15 +#define MACH_MSG_TYPE_PORT_RECEIVE MACH_MSG_TYPE_MOVE_RECEIVE +#define MACH_MSG_TYPE_PORT_SEND MACH_MSG_TYPE_MOVE_SEND +#define MACH_MSG_TYPE_PORT_SEND_ONCE MACH_MSG_TYPE_MOVE_SEND_ONCE + +#define MACH_MSG_TYPE_LAST 22 /* Last assigned */ + +/* + * A dummy value. Mostly used to indicate that the actual value + * will be filled in later, dynamically. + */ + +#define MACH_MSG_TYPE_POLYMORPHIC ((mach_msg_type_name_t) -1) + +/* + * Is a given item a port type? + */ + +#define MACH_MSG_TYPE_PORT_ANY(x) \ + (((x) >= MACH_MSG_TYPE_MOVE_RECEIVE) && \ + ((x) <= MACH_MSG_TYPE_MAKE_SEND_ONCE)) + +#define MACH_MSG_TYPE_PORT_ANY_SEND(x) \ + (((x) >= MACH_MSG_TYPE_MOVE_SEND) && \ + ((x) <= MACH_MSG_TYPE_MAKE_SEND_ONCE)) + +#define MACH_MSG_TYPE_PORT_ANY_RIGHT(x) \ + (((x) >= MACH_MSG_TYPE_MOVE_RECEIVE) && \ + ((x) <= MACH_MSG_TYPE_MOVE_SEND_ONCE)) + +typedef integer_t mach_msg_option_t; + +#define MACH_MSG_OPTION_NONE 0x00000000 + +#define MACH_SEND_MSG 0x00000001 +#define MACH_RCV_MSG 0x00000002 + +#define MACH_RCV_LARGE 0x00000004 /* report large message sizes */ +#define MACH_RCV_LARGE_IDENTITY 0x00000008 /* identify source of large messages */ + +#define MACH_SEND_TIMEOUT 0x00000010 /* timeout value applies to send */ +#define MACH_SEND_OVERRIDE 0x00000020 /* priority override for send */ +#define MACH_SEND_INTERRUPT 0x00000040 /* don't restart interrupted sends */ +#define MACH_SEND_NOTIFY 0x00000080 /* arm send-possible notify */ +#define MACH_SEND_ALWAYS 0x00010000 /* ignore qlimits - kernel only */ +#define MACH_SEND_TRAILER 0x00020000 /* sender-provided trailer */ +#define MACH_SEND_NOIMPORTANCE 0x00040000 /* msg won't carry importance */ +#define MACH_SEND_NODENAP MACH_SEND_NOIMPORTANCE +#define MACH_SEND_IMPORTANCE 0x00080000 /* msg carries importance - kernel only */ +#define MACH_SEND_SYNC_OVERRIDE 0x00100000 /* msg should do sync ipc override */ +#define MACH_SEND_PROPAGATE_QOS 0x00200000 /* IPC should propagate the caller's QoS */ +#define MACH_SEND_SYNC_USE_THRPRI MACH_SEND_PROPAGATE_QOS /* obsolete name */ +#define MACH_SEND_KERNEL 0x00400000 /* full send from kernel space - kernel only */ +#define MACH_SEND_SYNC_BOOTSTRAP_CHECKIN 0x00800000 /* special reply port should boost thread doing sync bootstrap checkin */ + +#define MACH_RCV_TIMEOUT 0x00000100 /* timeout value applies to receive */ +#define MACH_RCV_NOTIFY 0x00000000 /* legacy name (value was: 0x00000200) */ +#define MACH_RCV_INTERRUPT 0x00000400 /* don't restart interrupted receive */ +#define MACH_RCV_VOUCHER 0x00000800 /* willing to receive voucher port */ +#define MACH_RCV_OVERWRITE 0x00000000 /* scatter receive (deprecated) */ +#define MACH_RCV_GUARDED_DESC 0x00001000 /* Can receive new guarded descriptor */ +#define MACH_RCV_SYNC_WAIT 0x00004000 /* sync waiter waiting for rcv */ +#define MACH_RCV_SYNC_PEEK 0x00008000 /* sync waiter waiting to peek */ + +#define MACH_MSG_STRICT_REPLY 0x00000200 /* Enforce specific properties about the reply port, and + * the context in which a thread replies to a message. + * This flag must be passed on both the SEND and RCV */ + + +/* + * NOTE: a 0x00------ RCV mask implies to ask for + * a MACH_MSG_TRAILER_FORMAT_0 with 0 Elements, + * which is equivalent to a mach_msg_trailer_t. + * + * XXXMAC: unlike the rest of the MACH_RCV_* flags, MACH_RCV_TRAILER_LABELS + * needs its own private bit since we only calculate its fields when absolutely + * required. + */ +#define MACH_RCV_TRAILER_NULL 0 +#define MACH_RCV_TRAILER_SEQNO 1 +#define MACH_RCV_TRAILER_SENDER 2 +#define MACH_RCV_TRAILER_AUDIT 3 +#define MACH_RCV_TRAILER_CTX 4 +#define MACH_RCV_TRAILER_AV 7 +#define MACH_RCV_TRAILER_LABELS 8 + +#define MACH_RCV_TRAILER_TYPE(x) (((x) & 0xf) << 28) +#define MACH_RCV_TRAILER_ELEMENTS(x) (((x) & 0xf) << 24) +#define MACH_RCV_TRAILER_MASK ((0xf << 24)) + +#define GET_RCV_ELEMENTS(y) (((y) >> 24) & 0xf) + + +/* + * XXXMAC: note that in the case of MACH_RCV_TRAILER_LABELS, + * we just fall through to mach_msg_max_trailer_t. + * This is correct behavior since mach_msg_max_trailer_t is defined as + * mac_msg_mac_trailer_t which is used for the LABELS trailer. + * It also makes things work properly if MACH_RCV_TRAILER_LABELS is ORed + * with one of the other options. + */ + +#define REQUESTED_TRAILER_SIZE_NATIVE(y) \ + ((mach_msg_trailer_size_t) \ + ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_NULL) ? \ + sizeof(mach_msg_trailer_t) : \ + ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_SEQNO) ? \ + sizeof(mach_msg_seqno_trailer_t) : \ + ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_SENDER) ? \ + sizeof(mach_msg_security_trailer_t) : \ + ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_AUDIT) ? \ + sizeof(mach_msg_audit_trailer_t) : \ + ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_CTX) ? \ + sizeof(mach_msg_context_trailer_t) : \ + ((GET_RCV_ELEMENTS(y) == MACH_RCV_TRAILER_AV) ? \ + sizeof(mach_msg_mac_trailer_t) : \ + sizeof(mach_msg_max_trailer_t)))))))) + + +#define REQUESTED_TRAILER_SIZE(y) REQUESTED_TRAILER_SIZE_NATIVE(y) + +/* + * Much code assumes that mach_msg_return_t == kern_return_t. + * This definition is useful for descriptive purposes. + * + * See for the format of error codes. + * IPC errors are system 4. Send errors are subsystem 0; + * receive errors are subsystem 1. The code field is always non-zero. + * The high bits of the code field communicate extra information + * for some error codes. MACH_MSG_MASK masks off these special bits. + */ + +typedef kern_return_t mach_msg_return_t; + +#define MACH_MSG_SUCCESS 0x00000000 + + +#define MACH_MSG_MASK 0x00003e00 +/* All special error code bits defined below. */ +#define MACH_MSG_IPC_SPACE 0x00002000 +/* No room in IPC name space for another capability name. */ +#define MACH_MSG_VM_SPACE 0x00001000 +/* No room in VM address space for out-of-line memory. */ +#define MACH_MSG_IPC_KERNEL 0x00000800 +/* Kernel resource shortage handling an IPC capability. */ +#define MACH_MSG_VM_KERNEL 0x00000400 +/* Kernel resource shortage handling out-of-line memory. */ + +#define MACH_SEND_IN_PROGRESS 0x10000001 +/* Thread is waiting to send. (Internal use only.) */ +#define MACH_SEND_INVALID_DATA 0x10000002 +/* Bogus in-line data. */ +#define MACH_SEND_INVALID_DEST 0x10000003 +/* Bogus destination port. */ +#define MACH_SEND_TIMED_OUT 0x10000004 +/* Message not sent before timeout expired. */ +#define MACH_SEND_INVALID_VOUCHER 0x10000005 +/* Bogus voucher port. */ +#define MACH_SEND_INTERRUPTED 0x10000007 +/* Software interrupt. */ +#define MACH_SEND_MSG_TOO_SMALL 0x10000008 +/* Data doesn't contain a complete message. */ +#define MACH_SEND_INVALID_REPLY 0x10000009 +/* Bogus reply port. */ +#define MACH_SEND_INVALID_RIGHT 0x1000000a +/* Bogus port rights in the message body. */ +#define MACH_SEND_INVALID_NOTIFY 0x1000000b +/* Bogus notify port argument. */ +#define MACH_SEND_INVALID_MEMORY 0x1000000c +/* Invalid out-of-line memory pointer. */ +#define MACH_SEND_NO_BUFFER 0x1000000d +/* No message buffer is available. */ +#define MACH_SEND_TOO_LARGE 0x1000000e +/* Send is too large for port */ +#define MACH_SEND_INVALID_TYPE 0x1000000f +/* Invalid msg-type specification. */ +#define MACH_SEND_INVALID_HEADER 0x10000010 +/* A field in the header had a bad value. */ +#define MACH_SEND_INVALID_TRAILER 0x10000011 +/* The trailer to be sent does not match kernel format. */ +#define MACH_SEND_INVALID_CONTEXT 0x10000012 +/* The sending thread context did not match the context on the dest port */ +#define MACH_SEND_INVALID_RT_OOL_SIZE 0x10000015 +/* compatibility: no longer a returned error */ +#define MACH_SEND_NO_GRANT_DEST 0x10000016 +/* The destination port doesn't accept ports in body */ + +#define MACH_RCV_IN_PROGRESS 0x10004001 +/* Thread is waiting for receive. (Internal use only.) */ +#define MACH_RCV_INVALID_NAME 0x10004002 +/* Bogus name for receive port/port-set. */ +#define MACH_RCV_TIMED_OUT 0x10004003 +/* Didn't get a message within the timeout value. */ +#define MACH_RCV_TOO_LARGE 0x10004004 +/* Message buffer is not large enough for inline data. */ +#define MACH_RCV_INTERRUPTED 0x10004005 +/* Software interrupt. */ +#define MACH_RCV_PORT_CHANGED 0x10004006 +/* compatibility: no longer a returned error */ +#define MACH_RCV_INVALID_NOTIFY 0x10004007 +/* Bogus notify port argument. */ +#define MACH_RCV_INVALID_DATA 0x10004008 +/* Bogus message buffer for inline data. */ +#define MACH_RCV_PORT_DIED 0x10004009 +/* Port/set was sent away/died during receive. */ +#define MACH_RCV_IN_SET 0x1000400a +/* compatibility: no longer a returned error */ +#define MACH_RCV_HEADER_ERROR 0x1000400b +/* Error receiving message header. See special bits. */ +#define MACH_RCV_BODY_ERROR 0x1000400c +/* Error receiving message body. See special bits. */ +#define MACH_RCV_INVALID_TYPE 0x1000400d +/* Invalid msg-type specification in scatter list. */ +#define MACH_RCV_SCATTER_SMALL 0x1000400e +/* Out-of-line overwrite region is not large enough */ +#define MACH_RCV_INVALID_TRAILER 0x1000400f +/* trailer type or number of trailer elements not supported */ +#define MACH_RCV_IN_PROGRESS_TIMED 0x10004011 +/* Waiting for receive with timeout. (Internal use only.) */ +#define MACH_RCV_INVALID_REPLY 0x10004012 +/* invalid reply port used in a STRICT_REPLY message */ + + + +__BEGIN_DECLS + +/* + * Routine: mach_msg_overwrite + * Purpose: + * Send and/or receive a message. If the message operation + * is interrupted, and the user did not request an indication + * of that fact, then restart the appropriate parts of the + * operation silently (trap version does not restart). + * + * Distinct send and receive buffers may be specified. If + * no separate receive buffer is specified, the msg parameter + * will be used for both send and receive operations. + * + * In addition to a distinct receive buffer, that buffer may + * already contain scatter control information to direct the + * receiving of the message. + */ +__WATCHOS_PROHIBITED __TVOS_PROHIBITED +extern mach_msg_return_t mach_msg_overwrite( + mach_msg_header_t *msg, + mach_msg_option_t option, + mach_msg_size_t send_size, + mach_msg_size_t rcv_size, + mach_port_name_t rcv_name, + mach_msg_timeout_t timeout, + mach_port_name_t notify, + mach_msg_header_t *rcv_msg, + mach_msg_size_t rcv_limit); + + +/* + * Routine: mach_msg + * Purpose: + * Send and/or receive a message. If the message operation + * is interrupted, and the user did not request an indication + * of that fact, then restart the appropriate parts of the + * operation silently (trap version does not restart). + */ +__WATCHOS_PROHIBITED __TVOS_PROHIBITED +extern mach_msg_return_t mach_msg( + mach_msg_header_t *msg, + mach_msg_option_t option, + mach_msg_size_t send_size, + mach_msg_size_t rcv_size, + mach_port_name_t rcv_name, + mach_msg_timeout_t timeout, + mach_port_name_t notify); + +/* + * Routine: mach_voucher_deallocate + * Purpose: + * Deallocate a mach voucher created or received in a message. Drops + * one (send right) reference to the voucher. + */ +__WATCHOS_PROHIBITED __TVOS_PROHIBITED +extern kern_return_t mach_voucher_deallocate( + mach_port_name_t voucher); + + +__END_DECLS + +#endif /* _MACH_MESSAGE_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mig.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mig.h new file mode 100644 index 00000000..066ffa75 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mig.h @@ -0,0 +1,180 @@ +/* + * Copyright (c) 2000-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ + +/* + * Mach MIG Subsystem Interfaces + */ + +#ifndef _MACH_MIG_H_ +#define _MACH_MIG_H_ + +#include +#include +#include +#include + +#include + +#if defined(MACH_KERNEL) + +#if !defined(__MigTypeCheck) +/* Turn MIG type checking on by default for kernel */ +#define __MigTypeCheck 1 +#endif + +#define __MigKernelSpecificCode 1 +#define _MIG_KERNEL_SPECIFIC_CODE_ 1 + +#elif !defined(__MigTypeCheck) + +#if defined(TypeCheck) +/* use legacy setting (temporary) */ +#define __MigTypeCheck TypeCheck +#else +/* default MIG type checking on */ +#define __MigTypeCheck 1 +#endif + +#endif /* !defined(MACH_KERNEL) && !defined(__MigTypeCheck) */ + +/* + * Pack MIG message structs. + * This is an indicator of the need to view shared structs in a + * binary-compatible format - and MIG message structs are no different. + */ +#define __MigPackStructs 1 + +/* + * Definition for MIG-generated server stub routines. These routines + * unpack the request message, call the server procedure, and pack the + * reply message. + */ +typedef void (*mig_stub_routine_t) (mach_msg_header_t *InHeadP, + mach_msg_header_t *OutHeadP); + +typedef mig_stub_routine_t mig_routine_t; + +/* + * Definition for MIG-generated server routine. This routine takes a + * message, and returns the appropriate stub function for handling that + * message. + */ +typedef mig_routine_t (*mig_server_routine_t) (mach_msg_header_t *InHeadP); + +/* + * Generic definition for implementation routines. These routines do + * the real work associated with this request. This generic type is + * used for keeping the pointers in the subsystem array. + */ +typedef kern_return_t (*mig_impl_routine_t)(void); + +typedef mach_msg_type_descriptor_t routine_arg_descriptor; +typedef mach_msg_type_descriptor_t *routine_arg_descriptor_t; +typedef mach_msg_type_descriptor_t *mig_routine_arg_descriptor_t; + +#define MIG_ROUTINE_ARG_DESCRIPTOR_NULL ((mig_routine_arg_descriptor_t)0) + +struct routine_descriptor { + mig_impl_routine_t impl_routine; /* Server work func pointer */ + mig_stub_routine_t stub_routine; /* Unmarshalling func pointer */ + unsigned int argc; /* Number of argument words */ + unsigned int descr_count; /* Number complex descriptors */ + routine_arg_descriptor_t + arg_descr; /* pointer to descriptor array*/ + unsigned int max_reply_msg; /* Max size for reply msg */ +}; +typedef struct routine_descriptor *routine_descriptor_t; + +typedef struct routine_descriptor mig_routine_descriptor; +typedef mig_routine_descriptor *mig_routine_descriptor_t; + +#define MIG_ROUTINE_DESCRIPTOR_NULL ((mig_routine_descriptor_t)0) + +typedef struct mig_subsystem { + mig_server_routine_t server; /* pointer to demux routine */ + mach_msg_id_t start; /* Min routine number */ + mach_msg_id_t end; /* Max routine number + 1 */ + mach_msg_size_t maxsize; /* Max reply message size */ + vm_address_t reserved; /* reserved for MIG use */ + mig_routine_descriptor + routine[1]; /* Routine descriptor array */ +} *mig_subsystem_t; + +#define MIG_SUBSYSTEM_NULL ((mig_subsystem_t)0) + +typedef struct mig_symtab { + char *ms_routine_name; + int ms_routine_number; + void (*ms_routine)(void); /* Since the functions in the + * symbol table have unknown + * signatures, this is the best + * we can do... + */ +} mig_symtab_t; + +/* + * A compiler attribute for annotating all MIG server routines and other + * functions that should behave similarly. Allows the compiler to perform + * additional static bug-finding over them. + */ +#if __has_attribute(mig_server_routine) +#define MIG_SERVER_ROUTINE __attribute__((mig_server_routine)) +#else +#define MIG_SERVER_ROUTINE +#endif + + +__BEGIN_DECLS + +/* Client side reply port allocate */ +extern mach_port_t mig_get_reply_port(void); + +/* Client side reply port deallocate */ +extern void mig_dealloc_reply_port(mach_port_t reply_port); + +/* Client side reply port "deallocation" */ +extern void mig_put_reply_port(mach_port_t reply_port); + +/* Bounded string copy */ +extern int mig_strncpy(char *dest, const char *src, int len); +extern int mig_strncpy_zerofill(char *dest, const char *src, int len); + + +/* Allocate memory for out-of-line mig structures */ +extern void mig_allocate(vm_address_t *, vm_size_t); + +/* Deallocate memory used for out-of-line mig structures */ +extern void mig_deallocate(vm_address_t, vm_size_t); + + +__END_DECLS + +#endif /* _MACH_MIG_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mig_errors.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mig_errors.h new file mode 100644 index 00000000..418a05da --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mig_errors.h @@ -0,0 +1,125 @@ +/* + * Copyright (c) 2000-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * Mach Interface Generator errors + * + */ + +#ifndef _MACH_MIG_ERRORS_H_ +#define _MACH_MIG_ERRORS_H_ + +#include +#include +#include +#include + +#include + +/* + * These error codes should be specified as system 4, subsytem 2. + * But alas backwards compatibility makes that impossible. + * The problem is old clients of new servers (eg, the kernel) + * which get strange large error codes when there is a Mig problem + * in the server. Unfortunately, the IPC system doesn't have + * the knowledge to convert the codes in this situation. + */ + +#define MIG_TYPE_ERROR -300 /* client type check failure */ +#define MIG_REPLY_MISMATCH -301 /* wrong reply message ID */ +#define MIG_REMOTE_ERROR -302 /* server detected error */ +#define MIG_BAD_ID -303 /* bad request message ID */ +#define MIG_BAD_ARGUMENTS -304 /* server type check failure */ +#define MIG_NO_REPLY -305 /* no reply should be send */ +#define MIG_EXCEPTION -306 /* server raised exception */ +#define MIG_ARRAY_TOO_LARGE -307 /* array not large enough */ +#define MIG_SERVER_DIED -308 /* server died */ +#define MIG_TRAILER_ERROR -309 /* trailer has an unknown format */ + +/* + * Whenever MIG detects an error, it sends back a generic + * mig_reply_error_t format message. Clients must accept + * these in addition to the expected reply message format. + */ +#pragma pack(4) +typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; +} mig_reply_error_t; +#pragma pack() + + +__BEGIN_DECLS + +#if !defined(__NDR_convert__mig_reply_error_t__defined) +#define __NDR_convert__mig_reply_error_t__defined + +static __inline__ void +__NDR_convert__mig_reply_error_t(__unused mig_reply_error_t *x) +{ +#if defined(__NDR_convert__int_rep__kern_return_t__defined) + if (x->NDR.int_rep != NDR_record.int_rep) { + __NDR_convert__int_rep__kern_return_t(&x->RetCode, x->NDR.int_rep); + } +#endif /* __NDR_convert__int_rep__kern_return_t__defined */ +} +#endif /* !defined(__NDR_convert__mig_reply_error_t__defined) */ + +__END_DECLS + +#endif /* _MACH_MIG_ERRORS_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mig_strncpy_zerofill_support.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mig_strncpy_zerofill_support.h new file mode 100644 index 00000000..92d0ff8e --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mig_strncpy_zerofill_support.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2017 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +//This dummy header file is created for mig to check when to call mig_strncpy_zerofill. +//Mig checks if this file is available to include and knows that Libsyscall has the new mig_strncpy_zerofill symbols to link to. +//Do not delete this file, mig will stop calling mig_strncpy_zerofill. + +#ifndef __MACH_MIG_STRNCPY_ZEROFILL_SUPPORT__ +#define __MACH_MIG_STRNCPY_ZEROFILL_SUPPORT__ + +#endif // __MACH_MIG_STRNCPY_ZEROFILL_SUPPORT__ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mig_voucher_support.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mig_voucher_support.h new file mode 100644 index 00000000..27e6b601 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/mig_voucher_support.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2017 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +//This dummy header file is created for mig to check when to include voucher code. +//Mig checks if this file is available to include and knows that Libsyscall has the new voucher symbols to link to. +//Do not delete this file, mig will stop including vouchers code. + +#ifndef __MACH_MIG_VOUCHER_SUPPORT__ +#define __MACH_MIG_VOUCHER_SUPPORT__ + +#endif // __MACH_MIG_VOUCHER_SUPPORT__ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/ndr.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/ndr.h new file mode 100644 index 00000000..61c00ff1 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/ndr.h @@ -0,0 +1,207 @@ +/* + * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ + +#ifndef _MACH_NDR_H_ +#define _MACH_NDR_H_ + +#include +#include +#include + + +typedef struct { + unsigned char mig_vers; + unsigned char if_vers; + unsigned char reserved1; + unsigned char mig_encoding; + unsigned char int_rep; + unsigned char char_rep; + unsigned char float_rep; + unsigned char reserved2; +} NDR_record_t; + +/* + * MIG supported protocols for Network Data Representation + */ +#define NDR_PROTOCOL_2_0 0 + +/* + * NDR 2.0 format flag type definition and values. + */ +#define NDR_INT_BIG_ENDIAN 0 +#define NDR_INT_LITTLE_ENDIAN 1 +#define NDR_FLOAT_IEEE 0 +#define NDR_FLOAT_VAX 1 +#define NDR_FLOAT_CRAY 2 +#define NDR_FLOAT_IBM 3 +#define NDR_CHAR_ASCII 0 +#define NDR_CHAR_EBCDIC 1 + +extern NDR_record_t NDR_record; + +/* NDR conversion off by default */ + +#if !defined(__NDR_convert__) +#define __NDR_convert__ 0 +#endif /* !defined(__NDR_convert__) */ + +#ifndef __NDR_convert__int_rep__ +#define __NDR_convert__int_rep__ __NDR_convert__ +#endif /* __NDR_convert__int_rep__ */ + +#ifndef __NDR_convert__char_rep__ +#define __NDR_convert__char_rep__ 0 +#endif /* __NDR_convert__char_rep__ */ + +#ifndef __NDR_convert__float_rep__ +#define __NDR_convert__float_rep__ 0 +#endif /* __NDR_convert__float_rep__ */ + +#if __NDR_convert__ + +#define __NDR_convert__NOOP do ; while (0) +#define __NDR_convert__UNKNOWN(s) __NDR_convert__NOOP +#define __NDR_convert__SINGLE(a, f, r) do { r((a), (f)); } while (0) +#define __NDR_convert__ARRAY(a, f, c, r) \ + do { int __i__, __C__ = (c); \ + for (__i__ = 0; __i__ < __C__; __i__++) \ + r(&(a)[__i__], f); } while (0) +#define __NDR_convert__2DARRAY(a, f, s, c, r) \ + do { int __i__, __C__ = (c), __S__ = (s); \ + for (__i__ = 0; __i__ < __C__; __i__++) \ + r(&(a)[__i__ * __S__], f, __S__); } while (0) + +#if __NDR_convert__int_rep__ + +#define __NDR_READSWAP_assign(a, rs) do { *(a) = rs(a); } while (0) + +#define __NDR_READSWAP__uint16_t(a) OSReadSwapInt16((void *)a, 0) +#define __NDR_READSWAP__int16_t(a) (int16_t)OSReadSwapInt16((void *)a, 0) +#define __NDR_READSWAP__uint32_t(a) OSReadSwapInt32((void *)a, 0) +#define __NDR_READSWAP__int32_t(a) (int32_t)OSReadSwapInt32((void *)a, 0) +#define __NDR_READSWAP__uint64_t(a) OSReadSwapInt64((void *)a, 0) +#define __NDR_READSWAP__int64_t(a) (int64_t)OSReadSwapInt64((void *)a, 0) + +__BEGIN_DECLS + +static __inline__ float +__NDR_READSWAP__float(float *argp) +{ + union { + float sv; + uint32_t ull; + } result; + result.ull = __NDR_READSWAP__uint32_t((uint32_t *)argp); + return result.sv; +} + +static __inline__ double +__NDR_READSWAP__double(double *argp) +{ + union { + double sv; + uint64_t ull; + } result; + result.ull = __NDR_READSWAP__uint64_t((uint64_t *)argp); + return result.sv; +} + +__END_DECLS + +#define __NDR_convert__int_rep__int16_t__defined +#define __NDR_convert__int_rep__int16_t(v, f) \ + __NDR_READSWAP_assign(v, __NDR_READSWAP__int16_t) + +#define __NDR_convert__int_rep__uint16_t__defined +#define __NDR_convert__int_rep__uint16_t(v, f) \ + __NDR_READSWAP_assign(v, __NDR_READSWAP__uint16_t) + +#define __NDR_convert__int_rep__int32_t__defined +#define __NDR_convert__int_rep__int32_t(v, f) \ + __NDR_READSWAP_assign(v, __NDR_READSWAP__int32_t) + +#define __NDR_convert__int_rep__uint32_t__defined +#define __NDR_convert__int_rep__uint32_t(v, f) \ + __NDR_READSWAP_assign(v, __NDR_READSWAP__uint32_t) + +#define __NDR_convert__int_rep__int64_t__defined +#define __NDR_convert__int_rep__int64_t(v, f) \ + __NDR_READSWAP_assign(v, __NDR_READSWAP__int64_t) + +#define __NDR_convert__int_rep__uint64_t__defined +#define __NDR_convert__int_rep__uint64_t(v, f) \ + __NDR_READSWAP_assign(v, __NDR_READSWAP__uint64_t) + +#define __NDR_convert__int_rep__float__defined +#define __NDR_convert__int_rep__float(v, f) \ + __NDR_READSWAP_assign(v, __NDR_READSWAP__float) + +#define __NDR_convert__int_rep__double__defined +#define __NDR_convert__int_rep__double(v, f) \ + __NDR_READSWAP_assign(v, __NDR_READSWAP__double) + +#define __NDR_convert__int_rep__boolean_t__defined +#define __NDR_convert__int_rep__boolean_t(v, f) \ + __NDR_convert__int_rep__int32_t(v,f) + +#define __NDR_convert__int_rep__kern_return_t__defined +#define __NDR_convert__int_rep__kern_return_t(v, f) \ + __NDR_convert__int_rep__int32_t(v,f) + +#define __NDR_convert__int_rep__mach_port_name_t__defined +#define __NDR_convert__int_rep__mach_port_name_t(v, f) \ + __NDR_convert__int_rep__uint32_t(v,f) + +#define __NDR_convert__int_rep__mach_msg_type_number_t__defined +#define __NDR_convert__int_rep__mach_msg_type_number_t(v, f) \ + __NDR_convert__int_rep__uint32_t(v,f) + +#endif /* __NDR_convert__int_rep__ */ + +#if __NDR_convert__char_rep__ + +#warning NDR character representation conversions not implemented yet! +#define __NDR_convert__char_rep__char(v, f) __NDR_convert__NOOP +#define __NDR_convert__char_rep__string(v, f, l) __NDR_convert__NOOP + +#endif /* __NDR_convert__char_rep__ */ + +#if __NDR_convert__float_rep__ + +#warning NDR floating point representation conversions not implemented yet! +#define __NDR_convert__float_rep__float(v, f) __NDR_convert__NOOP +#define __NDR_convert__float_rep__double(v, f) __NDR_convert__NOOP + +#endif /* __NDR_convert__float_rep__ */ + +#endif /* __NDR_convert__ */ + +#endif /* _MACH_NDR_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/notify.defs b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/notify.defs new file mode 100644 index 00000000..4aece97b --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/notify.defs @@ -0,0 +1,134 @@ +/* + * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ + +subsystem +#if KERNEL_USER + KernelUser +#endif + notify 64; + +#include + +#if SEQNOS +serverprefix do_seqnos_; +serverdemux seqnos_notify_server; +#else /* !SEQNOS */ +serverprefix do_; +serverdemux notify_server; +#endif /* SEQNOS */ + +/* MACH_NOTIFY_FIRST: 0100 */ +skip; + +/* MACH_NOTIFY_PORT_DELETED: 0101 */ +simpleroutine mach_notify_port_deleted( + notify : mach_port_move_send_once_t; +#if SEQNOS + msgseqno seqno : mach_port_seqno_t; +#endif /* SEQNOS */ + name : mach_port_name_t); + +#if (KERNEL_USER | MACH_NOTIFY_SEND_POSSIBLE_EXPECTED) +/* MACH_NOTIFY_SEND_POSSIBLE: 0102 */ +simpleroutine mach_notify_send_possible( + notify : mach_port_move_send_once_t; +#if SEQNOS + msgseqno seqno : mach_port_seqno_t; +#endif /* SEQNOS */ + name : mach_port_name_t); +#else +skip; +#endif + +skip; /* was NOTIFY_OWNERSHIP_RIGHTS: 0103 */ + +skip; /* was NOTIFY_RECEIVE_RIGHTS: 0104 */ + +/* MACH_NOTIFY_PORT_DESTROYED: 0105 */ +simpleroutine mach_notify_port_destroyed( + notify : mach_port_move_send_once_t; +#if SEQNOS + msgseqno seqno : mach_port_seqno_t; +#endif /* SEQNOS */ + rights : mach_port_move_receive_t); + +/* MACH_NOTIFY_NO_SENDERS: 0106 */ +simpleroutine mach_notify_no_senders( + notify : mach_port_move_send_once_t; +#if SEQNOS + msgseqno seqno : mach_port_seqno_t; +#endif /* SEQNOS */ + mscount : mach_port_mscount_t); + +/* MACH_NOTIFY_SEND_ONCE: 0107 */ +simpleroutine mach_notify_send_once( + notify : mach_port_move_send_once_t +#if SEQNOS +; msgseqno seqno : mach_port_seqno_t +#endif /* SEQNOS */ + ); + +/* MACH_NOTIFY_DEAD_NAME: 0110 */ +simpleroutine mach_notify_dead_name( + notify : mach_port_move_send_once_t; +#if SEQNOS + msgseqno seqno : mach_port_seqno_t; +#endif /* SEQNOS */ + name : mach_port_name_t); + +/* vim: set ft=c : */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/notify.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/notify.h new file mode 100644 index 00000000..5737dbc9 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/notify.h @@ -0,0 +1,141 @@ +/* + * Copyright (c) 2000-2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * File: mach/notify.h + * + * Kernel notification message definitions. + */ + +#ifndef _MACH_NOTIFY_H_ +#define _MACH_NOTIFY_H_ + +#include +#include +#include + +/* + * An alternative specification of the notification interface + * may be found in mach/notify.defs. + */ + +#define MACH_NOTIFY_FIRST 0100 +#define MACH_NOTIFY_PORT_DELETED (MACH_NOTIFY_FIRST + 001) +/* A send or send-once right was deleted. */ +#define MACH_NOTIFY_SEND_POSSIBLE (MACH_NOTIFY_FIRST + 002) +/* Now possible to send using specified right */ +#define MACH_NOTIFY_PORT_DESTROYED (MACH_NOTIFY_FIRST + 005) +/* A receive right was (would have been) deallocated */ +#define MACH_NOTIFY_NO_SENDERS (MACH_NOTIFY_FIRST + 006) +/* Receive right has no extant send rights */ +#define MACH_NOTIFY_SEND_ONCE (MACH_NOTIFY_FIRST + 007) +/* An extant send-once right died */ +#define MACH_NOTIFY_DEAD_NAME (MACH_NOTIFY_FIRST + 010) +/* Send or send-once right died, leaving a dead-name */ +#define MACH_NOTIFY_LAST (MACH_NOTIFY_FIRST + 015) + +typedef mach_port_t notify_port_t; + +/* + * Hard-coded message structures for receiving Mach port notification + * messages. However, they are not actual large enough to receive + * the largest trailers current exported by Mach IPC (so they cannot + * be used for space allocations in situations using these new larger + * trailers). Instead, the MIG-generated server routines (and + * related prototypes should be used). + */ +typedef struct { + mach_msg_header_t not_header; + NDR_record_t NDR; + mach_port_name_t not_port;/* MACH_MSG_TYPE_PORT_NAME */ + mach_msg_format_0_trailer_t trailer; +} mach_port_deleted_notification_t; + +typedef struct { + mach_msg_header_t not_header; + NDR_record_t NDR; + mach_port_name_t not_port;/* MACH_MSG_TYPE_PORT_NAME */ + mach_msg_format_0_trailer_t trailer; +} mach_send_possible_notification_t; + +typedef struct { + mach_msg_header_t not_header; + mach_msg_body_t not_body; + mach_msg_port_descriptor_t not_port;/* MACH_MSG_TYPE_PORT_RECEIVE */ + mach_msg_format_0_trailer_t trailer; +} mach_port_destroyed_notification_t; + +typedef struct { + mach_msg_header_t not_header; + NDR_record_t NDR; + mach_msg_type_number_t not_count; + mach_msg_format_0_trailer_t trailer; +} mach_no_senders_notification_t; + +typedef struct { + mach_msg_header_t not_header; + mach_msg_format_0_trailer_t trailer; +} mach_send_once_notification_t; + +typedef struct { + mach_msg_header_t not_header; + NDR_record_t NDR; + mach_port_name_t not_port;/* MACH_MSG_TYPE_PORT_NAME */ + mach_msg_format_0_trailer_t trailer; +} mach_dead_name_notification_t; + +#endif /* _MACH_NOTIFY_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/policy.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/policy.h new file mode 100644 index 00000000..836b95f7 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/policy.h @@ -0,0 +1,235 @@ +/* + * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ + +#ifndef _MACH_POLICY_H_ +#define _MACH_POLICY_H_ + +/* + * mach/policy.h + * + * Definitions for scheduing policy. + */ + +/* + * All interfaces defined here are obsolete. + */ + +#include +#include +#include + +/* + * Old scheduling control interface + */ +typedef int policy_t; +typedef integer_t *policy_info_t; +typedef integer_t *policy_base_t; +typedef integer_t *policy_limit_t; + +/* + * Policy definitions. Policies should be powers of 2, + * but cannot be or'd together other than to test for a + * policy 'class'. + */ +#define POLICY_NULL 0 /* none */ +#define POLICY_TIMESHARE 1 /* timesharing */ +#define POLICY_RR 2 /* fixed round robin */ +#define POLICY_FIFO 4 /* fixed fifo */ + +#define __NEW_SCHEDULING_FRAMEWORK__ + +/* + * Check if policy is of 'class' fixed-priority. + */ +#define POLICYCLASS_FIXEDPRI (POLICY_RR | POLICY_FIFO) + +/* + * Check if policy is valid. + */ +#define invalid_policy(policy) \ + ((policy) != POLICY_TIMESHARE && \ + (policy) != POLICY_RR && \ + (policy) != POLICY_FIFO) + + +/* + * Types for TIMESHARE policy + */ +struct policy_timeshare_base { + integer_t base_priority; +}; +struct policy_timeshare_limit { + integer_t max_priority; +}; +struct policy_timeshare_info { + integer_t max_priority; + integer_t base_priority; + integer_t cur_priority; + boolean_t depressed; + integer_t depress_priority; +}; + +typedef struct policy_timeshare_base *policy_timeshare_base_t; +typedef struct policy_timeshare_limit *policy_timeshare_limit_t; +typedef struct policy_timeshare_info *policy_timeshare_info_t; + +typedef struct policy_timeshare_base policy_timeshare_base_data_t; +typedef struct policy_timeshare_limit policy_timeshare_limit_data_t; +typedef struct policy_timeshare_info policy_timeshare_info_data_t; + + +#define POLICY_TIMESHARE_BASE_COUNT ((mach_msg_type_number_t) \ + (sizeof(struct policy_timeshare_base)/sizeof(integer_t))) +#define POLICY_TIMESHARE_LIMIT_COUNT ((mach_msg_type_number_t) \ + (sizeof(struct policy_timeshare_limit)/sizeof(integer_t))) +#define POLICY_TIMESHARE_INFO_COUNT ((mach_msg_type_number_t) \ + (sizeof(struct policy_timeshare_info)/sizeof(integer_t))) + + +/* + * Types for the ROUND ROBIN (RR) policy + */ +struct policy_rr_base { + integer_t base_priority; + integer_t quantum; +}; +struct policy_rr_limit { + integer_t max_priority; +}; +struct policy_rr_info { + integer_t max_priority; + integer_t base_priority; + integer_t quantum; + boolean_t depressed; + integer_t depress_priority; +}; + +typedef struct policy_rr_base *policy_rr_base_t; +typedef struct policy_rr_limit *policy_rr_limit_t; +typedef struct policy_rr_info *policy_rr_info_t; + +typedef struct policy_rr_base policy_rr_base_data_t; +typedef struct policy_rr_limit policy_rr_limit_data_t; +typedef struct policy_rr_info policy_rr_info_data_t; + +#define POLICY_RR_BASE_COUNT ((mach_msg_type_number_t) \ + (sizeof(struct policy_rr_base)/sizeof(integer_t))) +#define POLICY_RR_LIMIT_COUNT ((mach_msg_type_number_t) \ + (sizeof(struct policy_rr_limit)/sizeof(integer_t))) +#define POLICY_RR_INFO_COUNT ((mach_msg_type_number_t) \ + (sizeof(struct policy_rr_info)/sizeof(integer_t))) + + +/* + * Types for the FIRST-IN-FIRST-OUT (FIFO) policy + */ +struct policy_fifo_base { + integer_t base_priority; +}; +struct policy_fifo_limit { + integer_t max_priority; +}; +struct policy_fifo_info { + integer_t max_priority; + integer_t base_priority; + boolean_t depressed; + integer_t depress_priority; +}; + +typedef struct policy_fifo_base *policy_fifo_base_t; +typedef struct policy_fifo_limit *policy_fifo_limit_t; +typedef struct policy_fifo_info *policy_fifo_info_t; + +typedef struct policy_fifo_base policy_fifo_base_data_t; +typedef struct policy_fifo_limit policy_fifo_limit_data_t; +typedef struct policy_fifo_info policy_fifo_info_data_t; + +#define POLICY_FIFO_BASE_COUNT ((mach_msg_type_number_t) \ + (sizeof(struct policy_fifo_base)/sizeof(integer_t))) +#define POLICY_FIFO_LIMIT_COUNT ((mach_msg_type_number_t) \ + (sizeof(struct policy_fifo_limit)/sizeof(integer_t))) +#define POLICY_FIFO_INFO_COUNT ((mach_msg_type_number_t) \ + (sizeof(struct policy_fifo_info)/sizeof(integer_t))) + +/* + * Aggregate policy types + */ + +struct policy_bases { + policy_timeshare_base_data_t ts; + policy_rr_base_data_t rr; + policy_fifo_base_data_t fifo; +}; + +struct policy_limits { + policy_timeshare_limit_data_t ts; + policy_rr_limit_data_t rr; + policy_fifo_limit_data_t fifo; +}; + +struct policy_infos { + policy_timeshare_info_data_t ts; + policy_rr_info_data_t rr; + policy_fifo_info_data_t fifo; +}; + +typedef struct policy_bases policy_base_data_t; +typedef struct policy_limits policy_limit_data_t; +typedef struct policy_infos policy_info_data_t; + +#endif /* _MACH_POLICY_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/port.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/port.h new file mode 100644 index 00000000..bd1fc19f --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/port.h @@ -0,0 +1,422 @@ +/* + * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * NOTICE: This file was modified by McAfee Research in 2004 to introduce + * support for mandatory and extensible security protections. This notice + * is included in support of clause 2.2 (b) of the Apple Public License, + * Version 2.0. + */ +/* + */ +/* + * File: mach/port.h + * + * Definition of a Mach port + * + * Mach ports are the endpoints to Mach-implemented communications + * channels (usually uni-directional message queues, but other types + * also exist). + * + * Unique collections of these endpoints are maintained for each + * Mach task. Each Mach port in the task's collection is given a + * [task-local] name to identify it - and the the various "rights" + * held by the task for that specific endpoint. + * + * This header defines the types used to identify these Mach ports + * and the various rights associated with them. For more info see: + * + * - manipulation of port rights in a given space + * - message queue [and port right passing] mechanism + * + */ + +#ifndef _MACH_PORT_H_ +#define _MACH_PORT_H_ + +#include +#include +#include +#include + +/* + * mach_port_name_t - the local identity for a Mach port + * + * The name is Mach port namespace specific. It is used to + * identify the rights held for that port by the task whose + * namespace is implied [or specifically provided]. + * + * Use of this type usually implies just a name - no rights. + * See mach_port_t for a type that implies a "named right." + * + */ + +typedef natural_t mach_port_name_t; +typedef mach_port_name_t *mach_port_name_array_t; + + +/* + * mach_port_t - a named port right + * + * In user-space, "rights" are represented by the name of the + * right in the Mach port namespace. Even so, this type is + * presented as a unique one to more clearly denote the presence + * of a right coming along with the name. + * + * Often, various rights for a port held in a single name space + * will coalesce and are, therefore, be identified by a single name + * [this is the case for send and receive rights]. But not + * always [send-once rights currently get a unique name for + * each right]. + * + */ + +#include +#include + + +typedef mach_port_t *mach_port_array_t; + +/* + * MACH_PORT_NULL is a legal value that can be carried in messages. + * It indicates the absence of any port or port rights. (A port + * argument keeps the message from being "simple", even if the + * value is MACH_PORT_NULL.) The value MACH_PORT_DEAD is also a legal + * value that can be carried in messages. It indicates + * that a port right was present, but it died. + */ + +#define MACH_PORT_NULL 0 /* intentional loose typing */ +#define MACH_PORT_DEAD ((mach_port_name_t) ~0) +#define MACH_PORT_VALID(name) \ + (((name) != MACH_PORT_NULL) && \ + ((name) != MACH_PORT_DEAD)) + + +/* + * For kernel-selected [assigned] port names, the name is + * comprised of two parts: a generation number and an index. + * This approach keeps the exact same name from being generated + * and reused too quickly [to catch right/reference counting bugs]. + * The dividing line between the constituent parts is exposed so + * that efficient "mach_port_name_t to data structure pointer" + * conversion implementation can be made. But it is possible + * for user-level code to assign their own names to Mach ports. + * These are not required to participate in this algorithm. So + * care should be taken before "assuming" this model. + * + */ + +#ifndef NO_PORT_GEN + +#define MACH_PORT_INDEX(name) ((name) >> 8) +#define MACH_PORT_GEN(name) (((name) & 0xff) << 24) +#define MACH_PORT_MAKE(index, gen) \ + (((index) << 8) | (gen) >> 24) + +#else /* NO_PORT_GEN */ + +#define MACH_PORT_INDEX(name) (name) +#define MACH_PORT_GEN(name) (0) +#define MACH_PORT_MAKE(index, gen) (index) + +#endif /* NO_PORT_GEN */ + + +/* + * These are the different rights a task may have for a port. + * The MACH_PORT_RIGHT_* definitions are used as arguments + * to mach_port_allocate, mach_port_get_refs, etc, to specify + * a particular right to act upon. The mach_port_names and + * mach_port_type calls return bitmasks using the MACH_PORT_TYPE_* + * definitions. This is because a single name may denote + * multiple rights. + */ + +typedef natural_t mach_port_right_t; + +#define MACH_PORT_RIGHT_SEND ((mach_port_right_t) 0) +#define MACH_PORT_RIGHT_RECEIVE ((mach_port_right_t) 1) +#define MACH_PORT_RIGHT_SEND_ONCE ((mach_port_right_t) 2) +#define MACH_PORT_RIGHT_PORT_SET ((mach_port_right_t) 3) +#define MACH_PORT_RIGHT_DEAD_NAME ((mach_port_right_t) 4) +#define MACH_PORT_RIGHT_LABELH ((mach_port_right_t) 5) /* obsolete right */ +#define MACH_PORT_RIGHT_NUMBER ((mach_port_right_t) 6) /* right not implemented */ + + +typedef natural_t mach_port_type_t; +typedef mach_port_type_t *mach_port_type_array_t; + +#define MACH_PORT_TYPE(right) \ + ((mach_port_type_t)(((mach_port_type_t) 1) \ + << ((right) + ((mach_port_right_t) 16)))) +#define MACH_PORT_TYPE_NONE ((mach_port_type_t) 0L) +#define MACH_PORT_TYPE_SEND MACH_PORT_TYPE(MACH_PORT_RIGHT_SEND) +#define MACH_PORT_TYPE_RECEIVE MACH_PORT_TYPE(MACH_PORT_RIGHT_RECEIVE) +#define MACH_PORT_TYPE_SEND_ONCE MACH_PORT_TYPE(MACH_PORT_RIGHT_SEND_ONCE) +#define MACH_PORT_TYPE_PORT_SET MACH_PORT_TYPE(MACH_PORT_RIGHT_PORT_SET) +#define MACH_PORT_TYPE_DEAD_NAME MACH_PORT_TYPE(MACH_PORT_RIGHT_DEAD_NAME) +#define MACH_PORT_TYPE_LABELH MACH_PORT_TYPE(MACH_PORT_RIGHT_LABELH) /* obsolete */ + + + +/* Convenient combinations. */ + +#define MACH_PORT_TYPE_SEND_RECEIVE \ + (MACH_PORT_TYPE_SEND|MACH_PORT_TYPE_RECEIVE) +#define MACH_PORT_TYPE_SEND_RIGHTS \ + (MACH_PORT_TYPE_SEND|MACH_PORT_TYPE_SEND_ONCE) +#define MACH_PORT_TYPE_PORT_RIGHTS \ + (MACH_PORT_TYPE_SEND_RIGHTS|MACH_PORT_TYPE_RECEIVE) +#define MACH_PORT_TYPE_PORT_OR_DEAD \ + (MACH_PORT_TYPE_PORT_RIGHTS|MACH_PORT_TYPE_DEAD_NAME) +#define MACH_PORT_TYPE_ALL_RIGHTS \ + (MACH_PORT_TYPE_PORT_OR_DEAD|MACH_PORT_TYPE_PORT_SET) + +/* Dummy type bits that mach_port_type/mach_port_names can return. */ + +#define MACH_PORT_TYPE_DNREQUEST 0x80000000 +#define MACH_PORT_TYPE_SPREQUEST 0x40000000 +#define MACH_PORT_TYPE_SPREQUEST_DELAYED 0x20000000 + +/* User-references for capabilities. */ + +typedef natural_t mach_port_urefs_t; +typedef integer_t mach_port_delta_t; /* change in urefs */ + +/* Attributes of ports. (See mach_port_get_receive_status.) */ + +typedef natural_t mach_port_seqno_t; /* sequence number */ +typedef natural_t mach_port_mscount_t; /* make-send count */ +typedef natural_t mach_port_msgcount_t; /* number of msgs */ +typedef natural_t mach_port_rights_t; /* number of rights */ + +/* + * Are there outstanding send rights for a given port? + */ +#define MACH_PORT_SRIGHTS_NONE 0 /* no srights */ +#define MACH_PORT_SRIGHTS_PRESENT 1 /* srights */ +typedef unsigned int mach_port_srights_t; /* status of send rights */ + +typedef struct mach_port_status { + mach_port_rights_t mps_pset; /* count of containing port sets */ + mach_port_seqno_t mps_seqno; /* sequence number */ + mach_port_mscount_t mps_mscount; /* make-send count */ + mach_port_msgcount_t mps_qlimit; /* queue limit */ + mach_port_msgcount_t mps_msgcount; /* number in the queue */ + mach_port_rights_t mps_sorights; /* how many send-once rights */ + boolean_t mps_srights; /* do send rights exist? */ + boolean_t mps_pdrequest; /* port-deleted requested? */ + boolean_t mps_nsrequest; /* no-senders requested? */ + natural_t mps_flags; /* port flags */ +} mach_port_status_t; + +/* System-wide values for setting queue limits on a port */ +#define MACH_PORT_QLIMIT_ZERO (0) +#define MACH_PORT_QLIMIT_BASIC (5) +#define MACH_PORT_QLIMIT_SMALL (16) +#define MACH_PORT_QLIMIT_LARGE (1024) +#define MACH_PORT_QLIMIT_KERNEL (65534) +#define MACH_PORT_QLIMIT_MIN MACH_PORT_QLIMIT_ZERO +#define MACH_PORT_QLIMIT_DEFAULT MACH_PORT_QLIMIT_BASIC +#define MACH_PORT_QLIMIT_MAX MACH_PORT_QLIMIT_LARGE + +typedef struct mach_port_limits { + mach_port_msgcount_t mpl_qlimit; /* number of msgs */ +} mach_port_limits_t; + +/* Possible values for mps_flags (part of mach_port_status_t) */ +#define MACH_PORT_STATUS_FLAG_TEMPOWNER 0x01 +#define MACH_PORT_STATUS_FLAG_GUARDED 0x02 +#define MACH_PORT_STATUS_FLAG_STRICT_GUARD 0x04 +#define MACH_PORT_STATUS_FLAG_IMP_DONATION 0x08 +#define MACH_PORT_STATUS_FLAG_REVIVE 0x10 +#define MACH_PORT_STATUS_FLAG_TASKPTR 0x20 +#define MACH_PORT_STATUS_FLAG_GUARD_IMMOVABLE_RECEIVE 0x40 +#define MACH_PORT_STATUS_FLAG_NO_GRANT 0x80 + +typedef struct mach_port_info_ext { + mach_port_status_t mpie_status; + mach_port_msgcount_t mpie_boost_cnt; + uint32_t reserved[6]; +} mach_port_info_ext_t; + +typedef integer_t *mach_port_info_t; /* varying array of natural_t */ + +/* Flavors for mach_port_get/set_attributes() */ +typedef int mach_port_flavor_t; +#define MACH_PORT_LIMITS_INFO 1 /* uses mach_port_limits_t */ +#define MACH_PORT_RECEIVE_STATUS 2 /* uses mach_port_status_t */ +#define MACH_PORT_DNREQUESTS_SIZE 3 /* info is int */ +#define MACH_PORT_TEMPOWNER 4 /* indicates receive right will be reassigned to another task */ +#define MACH_PORT_IMPORTANCE_RECEIVER 5 /* indicates recieve right accepts priority donation */ +#define MACH_PORT_DENAP_RECEIVER 6 /* indicates receive right accepts de-nap donation */ +#define MACH_PORT_INFO_EXT 7 /* uses mach_port_info_ext_t */ + +#define MACH_PORT_LIMITS_INFO_COUNT ((natural_t) \ + (sizeof(mach_port_limits_t)/sizeof(natural_t))) +#define MACH_PORT_RECEIVE_STATUS_COUNT ((natural_t) \ + (sizeof(mach_port_status_t)/sizeof(natural_t))) +#define MACH_PORT_DNREQUESTS_SIZE_COUNT 1 +#define MACH_PORT_INFO_EXT_COUNT ((natural_t) \ + (sizeof(mach_port_info_ext_t)/sizeof(natural_t))) +/* + * Structure used to pass information about port allocation requests. + * Must be padded to 64-bits total length. + */ +typedef struct mach_port_qos { + unsigned int name:1; /* name given */ + unsigned int prealloc:1; /* prealloced message */ + boolean_t pad1:30; + natural_t len; +} mach_port_qos_t; + +/* Mach Port Guarding definitions */ + +/* + * Flags for mach_port_options (used for + * invocation of mach_port_construct). + * Indicates attributes to be set for the newly + * allocated port. + */ +#define MPO_CONTEXT_AS_GUARD 0x01 /* Add guard to the port */ +#define MPO_QLIMIT 0x02 /* Set qlimit for the port msg queue */ +#define MPO_TEMPOWNER 0x04 /* Set the tempowner bit of the port */ +#define MPO_IMPORTANCE_RECEIVER 0x08 /* Mark the port as importance receiver */ +#define MPO_INSERT_SEND_RIGHT 0x10 /* Insert a send right for the port */ +#define MPO_STRICT 0x20 /* Apply strict guarding for port */ +#define MPO_DENAP_RECEIVER 0x40 /* Mark the port as App de-nap receiver */ +#define MPO_IMMOVABLE_RECEIVE 0x80 /* Mark the port as immovable; protected by the guard context */ +/* + * Structure to define optional attributes for a newly + * constructed port. + */ +typedef struct mach_port_options { + uint32_t flags; /* Flags defining attributes for port */ + mach_port_limits_t mpl; /* Message queue limit for port */ + uint64_t reserved[2]; /* Reserved */ +}mach_port_options_t; + +typedef mach_port_options_t *mach_port_options_ptr_t; + +/* + * EXC_GUARD represents a guard violation for both + * mach ports and file descriptors. GUARD_TYPE_ is used + * to differentiate among them. + */ +#define GUARD_TYPE_MACH_PORT 0x1 + +/* Reasons for exception for a guarded mach port */ +enum mach_port_guard_exception_codes { + kGUARD_EXC_DESTROY = 1u << 0, + kGUARD_EXC_MOD_REFS = 1u << 1, + kGUARD_EXC_SET_CONTEXT = 1u << 2, + kGUARD_EXC_UNGUARDED = 1u << 3, + kGUARD_EXC_INCORRECT_GUARD = 1u << 4, + kGUARD_EXC_IMMOVABLE = 1u << 5, + kGUARD_EXC_STRICT_REPLY = 1u << 6, + /* start of [optionally] non-fatal guards */ + kGUARD_EXC_INVALID_RIGHT = 1u << 8, + kGUARD_EXC_INVALID_NAME = 1u << 9, + kGUARD_EXC_INVALID_VALUE = 1u << 10, + kGUARD_EXC_INVALID_ARGUMENT = 1u << 11, + kGUARD_EXC_RIGHT_EXISTS = 1u << 12, + kGUARD_EXC_KERN_NO_SPACE = 1u << 13, + kGUARD_EXC_KERN_FAILURE = 1u << 14, + kGUARD_EXC_KERN_RESOURCE = 1u << 15, + kGUARD_EXC_SEND_INVALID_REPLY = 1u << 16, + kGUARD_EXC_SEND_INVALID_VOUCHER = 1u << 17, + kGUARD_EXC_SEND_INVALID_RIGHT = 1u << 18, + kGUARD_EXC_RCV_INVALID_NAME = 1u << 19, + kGUARD_EXC_RCV_GUARDED_DESC = 1u << 20, /* should never be fatal; for development only */ +}; + +#define MAX_FATAL_kGUARD_EXC_CODE (1u << 6) + +/* + * These flags are used as bits in the subcode of kGUARD_EXC_STRICT_REPLY exceptions. + */ +#define MPG_FLAGS_STRICT_REPLY_INVALID_REPLY_DISP (0x01ull << 56) +#define MPG_FLAGS_STRICT_REPLY_INVALID_REPLY_PORT (0x02ull << 56) +#define MPG_FLAGS_STRICT_REPLY_INVALID_VOUCHER (0x04ull << 56) +#define MPG_FLAGS_STRICT_REPLY_NO_BANK_ATTR (0x08ull << 56) +#define MPG_FLAGS_STRICT_REPLY_MISMATCHED_PERSONA (0x10ull << 56) +#define MPG_FLAGS_STRICT_REPLY_MASK (0xffull << 56) + +/* + * Flags for mach_port_guard_with_flags. These flags extend + * the attributes associated with a guarded port. + */ +#define MPG_STRICT 0x01 /* Apply strict guarding for a port */ +#define MPG_IMMOVABLE_RECEIVE 0x02 /* Receive right cannot be moved out of the space */ + +#if !__DARWIN_UNIX03 && !defined(_NO_PORT_T_FROM_MACH) +/* + * Mach 3.0 renamed everything to have mach_ in front of it. + * These types and macros are provided for backward compatibility + * but are deprecated. + */ +typedef mach_port_t port_t; +typedef mach_port_name_t port_name_t; +typedef mach_port_name_t *port_name_array_t; + +#define PORT_NULL ((port_t) 0) +#define PORT_DEAD ((port_t) ~0) +#define PORT_VALID(name) \ + ((port_t)(name) != PORT_NULL && (port_t)(name) != PORT_DEAD) + +#endif /* !__DARWIN_UNIX03 && !_NO_PORT_T_FROM_MACH */ + +#endif /* _MACH_PORT_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/port_obj.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/port_obj.h new file mode 100644 index 00000000..99165c74 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/port_obj.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2003 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ + +/* + * Define a service to map from a kernel-generated port name + * to server-defined "type" and "value" data to be associated + * with the port. + */ + +#ifndef PORT_OBJ_H +#define PORT_OBJ_H + +#include + +struct port_obj_tentry { + void *pos_value; + int pos_type; +}; + +#include + +__BEGIN_DECLS +extern void port_obj_init(int); +__END_DECLS + +extern struct port_obj_tentry *port_obj_table; +extern int port_obj_table_size; + +#ifndef PORT_OBJ_ASSERT + +#define port_set_obj_value_type(pname, value, type) \ +do { \ + int ndx; \ + \ + if (!port_obj_table) \ + port_obj_init(port_obj_table_size); \ + ndx = MACH_PORT_INDEX(pname); \ + port_obj_table[ndx].pos_value = (value); \ + port_obj_table[ndx].pos_type = (type); \ +} while (0) + +#define port_get_obj_value(pname) \ + (port_obj_table[MACH_PORT_INDEX(pname)].pos_value) + +#define port_get_obj_type(pname) \ + (port_obj_table[MACH_PORT_INDEX(pname)].pos_type) + +#else /* PORT_OBJ_ASSERT */ + +#define port_set_obj_value_type(pname, value, type) \ +do { \ + int ndx; \ + \ + if (!port_obj_table) \ + port_obj_init(port_obj_table_size); \ + ndx = MACH_PORT_INDEX(pname); \ + assert(ndx > 0); \ + assert(ndx < port_obj_table_size); \ + port_obj_table[ndx].pos_value = (value); \ + port_obj_table[ndx].pos_type = (type); \ +} while (0) + +#define port_get_obj_value(pname) \ + ((MACH_PORT_INDEX(pname) < (unsigned)port_obj_table_size) ? \ + port_obj_table[MACH_PORT_INDEX(pname)].pos_value : \ + (panic("port_get_obj_value: index too big"), (void *)-1)) + +#define port_get_obj_type(pname) \ + ((MACH_PORT_INDEX(pname) < (unsigned)port_obj_table_size) ? \ + port_obj_table[MACH_PORT_INDEX(pname)].pos_type : \ + (panic("port_get_obj_type: index too big"), -1)) + +#endif /* PORT_OBJ_ASSERT */ + +#endif /* PORT_OBJ_H */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/processor.defs b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/processor.defs new file mode 100644 index 00000000..1503c313 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/processor.defs @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_FREE_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * File: mach/mach_port.defs + * Author: Rich Draves + * + * Exported kernel calls. + */ + +subsystem +#if KERNEL_SERVER + KernelServer +#endif /* KERNEL_SERVER */ + processor 3000; + +#include +#include + +/* + * References to processor objects are returned by: + * host_processors(host_priv_t,...); + */ +/* + * Start processor. + */ + +#ifdef KERNEL_SERVER +routine processor_start_from_user( + processor : processor_t); +#else +routine processor_start( + processor : processor_t); +#endif + +/* + * Exit processor -- may not be restartable. + */ + +#ifdef KERNEL_SERVER +routine processor_exit_from_user( + processor : processor_t); +#else +routine processor_exit( + processor : processor_t); +#endif + +/* + * Return information about this processor. + */ +routine processor_info( + processor : processor_t; + flavor : processor_flavor_t; + out host : host_t; + out processor_info_out: processor_info_t, CountInOut); + + +/* + * Do something machine-dependent to processor. + */ +routine processor_control( + processor : processor_t; + processor_cmd : processor_info_t); + +/* + * JMM - Keep processor_set related stuff at the end because + * they likely will be removed. + */ + +/* + * Assign processor to processor set. + */ +routine processor_assign( + processor : processor_t; + new_set : processor_set_t; + wait : boolean_t); + +/* + * Get current assignment for processor. + */ +routine processor_get_assignment( + processor : processor_t; + out assigned_set : processor_set_name_t); + +/* vim: set ft=c : */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/processor.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/processor.h new file mode 100644 index 00000000..a1b9c3ba --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/processor.h @@ -0,0 +1,360 @@ +#ifndef _processor_user_ +#define _processor_user_ + +/* Module processor */ + +#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 processor_MSG_COUNT +#define processor_MSG_COUNT 6 +#endif /* processor_MSG_COUNT */ + +#include +#include +#include +#include + +#ifdef __BeforeMigUserHeader +__BeforeMigUserHeader +#endif /* __BeforeMigUserHeader */ + +#include +__BEGIN_DECLS + + +/* Routine processor_start */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_start +( + processor_t processor +); + +/* Routine processor_exit */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_exit +( + processor_t processor +); + +/* Routine processor_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_info +( + processor_t processor, + processor_flavor_t flavor, + host_t *host, + processor_info_t processor_info_out, + mach_msg_type_number_t *processor_info_outCnt +); + +/* Routine processor_control */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_control +( + processor_t processor, + processor_info_t processor_cmd, + mach_msg_type_number_t processor_cmdCnt +); + +/* Routine processor_assign */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_assign +( + processor_t processor, + processor_set_t new_set, + boolean_t wait +); + +/* Routine processor_get_assignment */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_get_assignment +( + processor_t processor, + processor_set_name_t *assigned_set +); + +__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__processor_subsystem__defined +#define __Request__processor_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__processor_start_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__processor_exit_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + processor_flavor_t flavor; + mach_msg_type_number_t processor_info_outCnt; + } __Request__processor_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_msg_type_number_t processor_cmdCnt; + integer_t processor_cmd[20]; + } __Request__processor_control_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 new_set; + /* end of the kernel processed data */ + NDR_record_t NDR; + boolean_t wait; + } __Request__processor_assign_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__processor_get_assignment_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Request__processor_subsystem__defined */ + +/* union of all requests */ + +#ifndef __RequestUnion__processor_subsystem__defined +#define __RequestUnion__processor_subsystem__defined +union __RequestUnion__processor_subsystem { + __Request__processor_start_t Request_processor_start; + __Request__processor_exit_t Request_processor_exit; + __Request__processor_info_t Request_processor_info; + __Request__processor_control_t Request_processor_control; + __Request__processor_assign_t Request_processor_assign; + __Request__processor_get_assignment_t Request_processor_get_assignment; +}; +#endif /* !__RequestUnion__processor_subsystem__defined */ +/* typedefs for all replies */ + +#ifndef __Reply__processor_subsystem__defined +#define __Reply__processor_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__processor_start_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__processor_exit_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 host; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t processor_info_outCnt; + integer_t processor_info_out[20]; + } __Reply__processor_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__processor_control_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__processor_assign_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 assigned_set; + /* end of the kernel processed data */ + } __Reply__processor_get_assignment_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Reply__processor_subsystem__defined */ + +/* union of all replies */ + +#ifndef __ReplyUnion__processor_subsystem__defined +#define __ReplyUnion__processor_subsystem__defined +union __ReplyUnion__processor_subsystem { + __Reply__processor_start_t Reply_processor_start; + __Reply__processor_exit_t Reply_processor_exit; + __Reply__processor_info_t Reply_processor_info; + __Reply__processor_control_t Reply_processor_control; + __Reply__processor_assign_t Reply_processor_assign; + __Reply__processor_get_assignment_t Reply_processor_get_assignment; +}; +#endif /* !__RequestUnion__processor_subsystem__defined */ + +#ifndef subsystem_to_name_map_processor +#define subsystem_to_name_map_processor \ + { "processor_start", 3000 },\ + { "processor_exit", 3001 },\ + { "processor_info", 3002 },\ + { "processor_control", 3003 },\ + { "processor_assign", 3004 },\ + { "processor_get_assignment", 3005 } +#endif + +#ifdef __AfterMigUserHeader +__AfterMigUserHeader +#endif /* __AfterMigUserHeader */ + +#endif /* _processor_user_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/processor_info.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/processor_info.h new file mode 100644 index 00000000..85537607 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/processor_info.h @@ -0,0 +1,153 @@ +/* + * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ + +/* + * File: mach/processor_info.h + * Author: David L. Black + * Date: 1988 + * + * Data structure definitions for processor_info, processor_set_info + */ + +#ifndef _MACH_PROCESSOR_INFO_H_ +#define _MACH_PROCESSOR_INFO_H_ + +#include +#include +#include + +/* + * Generic information structure to allow for expansion. + */ +typedef integer_t *processor_info_t; /* varying array of int. */ +typedef integer_t *processor_info_array_t; /* varying array of int */ + +#define PROCESSOR_INFO_MAX (1024) /* max array size */ +typedef integer_t processor_info_data_t[PROCESSOR_INFO_MAX]; + + +typedef integer_t *processor_set_info_t; /* varying array of int. */ + +#define PROCESSOR_SET_INFO_MAX (1024) /* max array size */ +typedef integer_t processor_set_info_data_t[PROCESSOR_SET_INFO_MAX]; + +/* + * Currently defined information. + */ +typedef int processor_flavor_t; +#define PROCESSOR_BASIC_INFO 1 /* basic information */ +#define PROCESSOR_CPU_LOAD_INFO 2 /* cpu load information */ +#define PROCESSOR_PM_REGS_INFO 0x10000001 /* performance monitor register info */ +#define PROCESSOR_TEMPERATURE 0x10000002 /* Processor core temperature */ + +struct processor_basic_info { + cpu_type_t cpu_type; /* type of cpu */ + cpu_subtype_t cpu_subtype; /* subtype of cpu */ + boolean_t running; /* is processor running */ + int slot_num; /* slot number */ + boolean_t is_master; /* is this the master processor */ +}; + +typedef struct processor_basic_info processor_basic_info_data_t; +typedef struct processor_basic_info *processor_basic_info_t; +#define PROCESSOR_BASIC_INFO_COUNT ((mach_msg_type_number_t) \ + (sizeof(processor_basic_info_data_t)/sizeof(natural_t))) + +struct processor_cpu_load_info { /* number of ticks while running... */ + unsigned int cpu_ticks[CPU_STATE_MAX]; /* ... in the given mode */ +}; + +typedef struct processor_cpu_load_info processor_cpu_load_info_data_t; +typedef struct processor_cpu_load_info *processor_cpu_load_info_t; +#define PROCESSOR_CPU_LOAD_INFO_COUNT ((mach_msg_type_number_t) \ + (sizeof(processor_cpu_load_info_data_t)/sizeof(natural_t))) + +/* + * Scaling factor for load_average, mach_factor. + */ +#define LOAD_SCALE 1000 + +typedef int processor_set_flavor_t; +#define PROCESSOR_SET_BASIC_INFO 5 /* basic information */ + +struct processor_set_basic_info { + int processor_count; /* How many processors */ + int default_policy; /* When others not enabled */ +}; + +typedef struct processor_set_basic_info processor_set_basic_info_data_t; +typedef struct processor_set_basic_info *processor_set_basic_info_t; +#define PROCESSOR_SET_BASIC_INFO_COUNT ((mach_msg_type_number_t) \ + (sizeof(processor_set_basic_info_data_t)/sizeof(natural_t))) + +#define PROCESSOR_SET_LOAD_INFO 4 /* scheduling statistics */ + +struct processor_set_load_info { + int task_count; /* How many tasks */ + int thread_count; /* How many threads */ + integer_t load_average; /* Scaled */ + integer_t mach_factor; /* Scaled */ +}; + +typedef struct processor_set_load_info processor_set_load_info_data_t; +typedef struct processor_set_load_info *processor_set_load_info_t; +#define PROCESSOR_SET_LOAD_INFO_COUNT ((mach_msg_type_number_t) \ + (sizeof(processor_set_load_info_data_t)/sizeof(natural_t))) + + +#endif /* _MACH_PROCESSOR_INFO_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/processor_set.defs b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/processor_set.defs new file mode 100644 index 00000000..dc0f4077 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/processor_set.defs @@ -0,0 +1,161 @@ +/* + * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_FREE_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * File: mach/mach_port.defs + * Author: Rich Draves + * + * Exported kernel calls. + */ + +subsystem +#if KERNEL_SERVER + KernelServer +#endif /* KERNEL_SERVER */ + processor_set 4000; + +#include +#include + +/* + * Return scheduling statistics for a processor set. + */ +routine processor_set_statistics( + pset : processor_set_name_t; + flavor : processor_set_flavor_t; + out info_out : processor_set_info_t, CountInOut); + + +/* + * Destroy processor set. + */ +routine processor_set_destroy( + set : processor_set_t); + + +/* + * Set max priority for processor_set. + */ +routine processor_set_max_priority( + processor_set : processor_set_t; + max_priority : int; + change_threads : boolean_t); + +/* + * Enable policy for processor set + */ +routine processor_set_policy_enable( + processor_set : processor_set_t; + policy : int); + +/* + * Disable policy for processor set + */ +routine processor_set_policy_disable( + processor_set : processor_set_t; + policy : int; + change_threads : boolean_t); + +/* + * List all tasks in processor set. + */ +routine processor_set_tasks( + processor_set : processor_set_t; + out task_list : task_array_t); + +/* + * List all threads in processor set. + */ +routine processor_set_threads( + processor_set : processor_set_t; + out thread_list : thread_act_array_t); + +/* + * Controls the scheduling attributes governing the processor set. + * Allows control of enabled policies, and per-policy base and limit + * priorities. + */ +routine processor_set_policy_control( + pset : processor_set_t; + flavor : processor_set_flavor_t; + policy_info : processor_set_info_t; + change : boolean_t); + + +/* + * Debug Info + * This call is only valid on MACH_DEBUG kernels. + * Otherwise, KERN_FAILURE is returned. + */ +routine processor_set_stack_usage( + pset : processor_set_t; + out ltotal : unsigned; + out space : vm_size_t; + out resident : vm_size_t; + out maxusage : vm_size_t; + out maxstack : vm_offset_t); + +/* + * Get information about processor set. + */ +routine processor_set_info( + set_name : processor_set_name_t; + flavor : int; + out host : host_t; + out info_out : processor_set_info_t, CountInOut); + +/* vim: set ft=c : */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/processor_set.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/processor_set.h new file mode 100644 index 00000000..c306155f --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/processor_set.h @@ -0,0 +1,540 @@ +#ifndef _processor_set_user_ +#define _processor_set_user_ + +/* Module processor_set */ + +#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 processor_set_MSG_COUNT +#define processor_set_MSG_COUNT 10 +#endif /* processor_set_MSG_COUNT */ + +#include +#include +#include +#include + +#ifdef __BeforeMigUserHeader +__BeforeMigUserHeader +#endif /* __BeforeMigUserHeader */ + +#include +__BEGIN_DECLS + + +/* Routine processor_set_statistics */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_set_statistics +( + processor_set_name_t pset, + processor_set_flavor_t flavor, + processor_set_info_t info_out, + mach_msg_type_number_t *info_outCnt +); + +/* Routine processor_set_destroy */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_set_destroy +( + processor_set_t set +); + +/* Routine processor_set_max_priority */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_set_max_priority +( + processor_set_t processor_set, + int max_priority, + boolean_t change_threads +); + +/* Routine processor_set_policy_enable */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_set_policy_enable +( + processor_set_t processor_set, + int policy +); + +/* Routine processor_set_policy_disable */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_set_policy_disable +( + processor_set_t processor_set, + int policy, + boolean_t change_threads +); + +/* Routine processor_set_tasks */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_set_tasks +( + processor_set_t processor_set, + task_array_t *task_list, + mach_msg_type_number_t *task_listCnt +); + +/* Routine processor_set_threads */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_set_threads +( + processor_set_t processor_set, + thread_act_array_t *thread_list, + mach_msg_type_number_t *thread_listCnt +); + +/* Routine processor_set_policy_control */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_set_policy_control +( + processor_set_t pset, + processor_set_flavor_t flavor, + processor_set_info_t policy_info, + mach_msg_type_number_t policy_infoCnt, + boolean_t change +); + +/* Routine processor_set_stack_usage */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_set_stack_usage +( + processor_set_t pset, + unsigned *ltotal, + vm_size_t *space, + vm_size_t *resident, + vm_size_t *maxusage, + vm_offset_t *maxstack +); + +/* Routine processor_set_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t processor_set_info +( + processor_set_name_t set_name, + int flavor, + host_t *host, + processor_set_info_t info_out, + mach_msg_type_number_t *info_outCnt +); + +__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__processor_set_subsystem__defined +#define __Request__processor_set_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + processor_set_flavor_t flavor; + mach_msg_type_number_t info_outCnt; + } __Request__processor_set_statistics_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__processor_set_destroy_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int max_priority; + boolean_t change_threads; + } __Request__processor_set_max_priority_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int policy; + } __Request__processor_set_policy_enable_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int policy; + boolean_t change_threads; + } __Request__processor_set_policy_disable_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__processor_set_tasks_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__processor_set_threads_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + processor_set_flavor_t flavor; + mach_msg_type_number_t policy_infoCnt; + integer_t policy_info[5]; + boolean_t change; + } __Request__processor_set_policy_control_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__processor_set_stack_usage_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int flavor; + mach_msg_type_number_t info_outCnt; + } __Request__processor_set_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Request__processor_set_subsystem__defined */ + +/* union of all requests */ + +#ifndef __RequestUnion__processor_set_subsystem__defined +#define __RequestUnion__processor_set_subsystem__defined +union __RequestUnion__processor_set_subsystem { + __Request__processor_set_statistics_t Request_processor_set_statistics; + __Request__processor_set_destroy_t Request_processor_set_destroy; + __Request__processor_set_max_priority_t Request_processor_set_max_priority; + __Request__processor_set_policy_enable_t Request_processor_set_policy_enable; + __Request__processor_set_policy_disable_t Request_processor_set_policy_disable; + __Request__processor_set_tasks_t Request_processor_set_tasks; + __Request__processor_set_threads_t Request_processor_set_threads; + __Request__processor_set_policy_control_t Request_processor_set_policy_control; + __Request__processor_set_stack_usage_t Request_processor_set_stack_usage; + __Request__processor_set_info_t Request_processor_set_info; +}; +#endif /* !__RequestUnion__processor_set_subsystem__defined */ +/* typedefs for all replies */ + +#ifndef __Reply__processor_set_subsystem__defined +#define __Reply__processor_set_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t info_outCnt; + integer_t info_out[5]; + } __Reply__processor_set_statistics_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__processor_set_destroy_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__processor_set_max_priority_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__processor_set_policy_enable_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__processor_set_policy_disable_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_ool_ports_descriptor_t task_list; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t task_listCnt; + } __Reply__processor_set_tasks_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_ool_ports_descriptor_t thread_list; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t thread_listCnt; + } __Reply__processor_set_threads_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__processor_set_policy_control_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + unsigned ltotal; + vm_size_t space; + vm_size_t resident; + vm_size_t maxusage; + vm_offset_t maxstack; + } __Reply__processor_set_stack_usage_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 host; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t info_outCnt; + integer_t info_out[5]; + } __Reply__processor_set_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Reply__processor_set_subsystem__defined */ + +/* union of all replies */ + +#ifndef __ReplyUnion__processor_set_subsystem__defined +#define __ReplyUnion__processor_set_subsystem__defined +union __ReplyUnion__processor_set_subsystem { + __Reply__processor_set_statistics_t Reply_processor_set_statistics; + __Reply__processor_set_destroy_t Reply_processor_set_destroy; + __Reply__processor_set_max_priority_t Reply_processor_set_max_priority; + __Reply__processor_set_policy_enable_t Reply_processor_set_policy_enable; + __Reply__processor_set_policy_disable_t Reply_processor_set_policy_disable; + __Reply__processor_set_tasks_t Reply_processor_set_tasks; + __Reply__processor_set_threads_t Reply_processor_set_threads; + __Reply__processor_set_policy_control_t Reply_processor_set_policy_control; + __Reply__processor_set_stack_usage_t Reply_processor_set_stack_usage; + __Reply__processor_set_info_t Reply_processor_set_info; +}; +#endif /* !__RequestUnion__processor_set_subsystem__defined */ + +#ifndef subsystem_to_name_map_processor_set +#define subsystem_to_name_map_processor_set \ + { "processor_set_statistics", 4000 },\ + { "processor_set_destroy", 4001 },\ + { "processor_set_max_priority", 4002 },\ + { "processor_set_policy_enable", 4003 },\ + { "processor_set_policy_disable", 4004 },\ + { "processor_set_tasks", 4005 },\ + { "processor_set_threads", 4006 },\ + { "processor_set_policy_control", 4007 },\ + { "processor_set_stack_usage", 4008 },\ + { "processor_set_info", 4009 } +#endif + +#ifdef __AfterMigUserHeader +__AfterMigUserHeader +#endif /* __AfterMigUserHeader */ + +#endif /* _processor_set_user_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/rpc.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/rpc.h new file mode 100644 index 00000000..f3361d76 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/rpc.h @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2002,2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ + +/* + * Mach RPC Subsystem Interfaces + */ + +#ifndef _MACH_RPC_H_ +#define _MACH_RPC_H_ + +#include +#include +#include +#include + +#include +#include +#include +#include + +/* + * These are the types for RPC-specific variants of the MIG routine + * descriptor and subsystem data types. + * + * THIS IS ONLY FOR COMPATIBILITY. WE WILL NOT BE IMPLEMENTING THIS. + */ + +/* + * Basic mach rpc types. + */ +typedef unsigned int routine_arg_type; +typedef unsigned int routine_arg_offset; +typedef unsigned int routine_arg_size; + +/* + * Definitions for a signature's argument and routine descriptor's. + */ +struct rpc_routine_arg_descriptor { + routine_arg_type type; /* Port, Array, etc. */ + routine_arg_size size; /* element size in bytes */ + routine_arg_size count; /* number of elements */ + routine_arg_offset offset; /* Offset in list of routine args */ +}; +typedef struct rpc_routine_arg_descriptor *rpc_routine_arg_descriptor_t; + +struct rpc_routine_descriptor { + mig_impl_routine_t impl_routine; /* Server work func pointer */ + mig_stub_routine_t stub_routine; /* Unmarshalling func pointer */ + unsigned int argc; /* Number of argument words */ + unsigned int descr_count; /* Number of complex argument */ + /* descriptors */ + rpc_routine_arg_descriptor_t + arg_descr; /* Pointer to beginning of */ + /* the arg_descr array */ + unsigned int max_reply_msg; /* Max size for reply msg */ +}; +typedef struct rpc_routine_descriptor *rpc_routine_descriptor_t; + +#define RPC_DESCR_SIZE(x) ((x)->descr_count * \ + sizeof(struct rpc_routine_arg_descriptor)) + +struct rpc_signature { + struct rpc_routine_descriptor rd; + struct rpc_routine_arg_descriptor rad[1]; +}; + +#define RPC_SIGBUF_SIZE 8 + +/* + * A subsystem describes a set of server routines that can be invoked by + * mach_rpc() on the ports that are registered with the subsystem. For + * each routine, the routine number is given, along with the + * address of the implementation function in the server and a + * description of the arguments of the routine (it's "signature"). + * + * This structure definition is only a template for what is really a + * variable-length structure (generated by MIG for each subsystem). + * The actual structures do not always have one entry in the routine + * array, and also have a varying number of entries in the arg_descr + * array. Each routine has an array of zero or more arg descriptors + * one for each complex arg. These arrays are all catenated together + * to form the arg_descr field of the subsystem struct. The + * arg_descr field of each routine entry points to a unique sub-sequence + * within this catenated array. The goal is to keep everything + * contiguous. + */ +struct rpc_subsystem { + void *reserved; /* Reserved for system use */ + + mach_msg_id_t start; /* Min routine number */ + mach_msg_id_t end; /* Max routine number + 1 */ + unsigned int maxsize; /* Max mach_msg size */ + vm_address_t base_addr; /* Address of this struct in user */ + + struct rpc_routine_descriptor /* Array of routine descriptors */ + routine[1 /* Actually, (start-end+1) */ + ]; + + struct rpc_routine_arg_descriptor + arg_descriptor[1 /* Actually, the sum of the descr_ */ + ]; /* count fields for all routines */ +}; +typedef struct rpc_subsystem *rpc_subsystem_t; + +#define RPC_SUBSYSTEM_NULL ((rpc_subsystem_t) 0) + +#endif /* _MACH_RPC_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/sdt.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/sdt.h new file mode 100644 index 00000000..dd604aea --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/sdt.h @@ -0,0 +1,32 @@ +/* + * CDDL HEADER START + * + * The contents of this file are subject to the terms of the + * Common Development and Distribution License, Version 1.0 only + * (the "License"). You may not use this file except in compliance + * with the License. + * + * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE + * or http://www.opensolaris.org/os/licensing. + * See the License for the specific language governing permissions + * and limitations under the License. + * + * When distributing Covered Code, include this CDDL HEADER in each + * file and include the License file at usr/src/OPENSOLARIS.LICENSE. + * If applicable, add the following below this CDDL HEADER, with the + * fields enclosed by brackets "[]" replaced with your own identifying + * information: Portions Copyright [yyyy] [name of copyright owner] + * + * CDDL HEADER END + */ +/* + * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +#ifndef _MACH_SDT_H +#define _MACH_SDT_H + +#include + +#endif /* _MACH_SDT_H */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/semaphore.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/semaphore.h new file mode 100644 index 00000000..1ff46e41 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/semaphore.h @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2000-2008 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _MACH_SEMAPHORE_H_ +#define _MACH_SEMAPHORE_H_ + +#include +#include +#include +#include + +/* + * Forward Declarations + * + * The semaphore creation and deallocation routines are + * defined with the Mach task APIs in . + * + * kern_return_t semaphore_create(task_t task, + * semaphore_t *new_semaphore, + * sync_policy_t policy, + * int value); + * + * kern_return_t semaphore_destroy(task_t task, + * semaphore_t semaphore); + */ + +#include +__BEGIN_DECLS + +extern kern_return_t semaphore_signal(semaphore_t semaphore); +extern kern_return_t semaphore_signal_all(semaphore_t semaphore); + +extern kern_return_t semaphore_wait(semaphore_t semaphore); + + +extern kern_return_t semaphore_timedwait(semaphore_t semaphore, + mach_timespec_t wait_time); + +extern kern_return_t semaphore_timedwait_signal(semaphore_t wait_semaphore, + semaphore_t signal_semaphore, + mach_timespec_t wait_time); + +extern kern_return_t semaphore_wait_signal(semaphore_t wait_semaphore, + semaphore_t signal_semaphore); + +extern kern_return_t semaphore_signal_thread(semaphore_t semaphore, + thread_t thread); + + +__END_DECLS + + +#endif /* _MACH_SEMAPHORE_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/shared_memory_server.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/shared_memory_server.h new file mode 100644 index 00000000..e0622c52 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/shared_memory_server.h @@ -0,0 +1,133 @@ +/* + * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * + * File: mach/shared_memory_server.h + * + * protos and struct definitions for shared library + * server and interface + */ + +/* + * XXX + * + * NOTE: this file is deprecated and will be removed in the near future. + * Any project that includes this file should be changed to: + * 1. use instead of this file, + * 2. handle the new shared regions, now available on more platforms + */ + +#ifndef _MACH_SHARED_MEMORY_SERVER_H_ +#define _MACH_SHARED_MEMORY_SERVER_H_ + +#warning " is deprecated. Please use instead." + +#include +#include +#include +#include + +#define VM_PROT_COW 0x8 /* must not interfere with normal prot assignments */ +#define VM_PROT_ZF 0x10 /* must not interfere with normal prot assignments */ + +#define GLOBAL_SHARED_TEXT_SEGMENT 0x90000000U +#define GLOBAL_SHARED_DATA_SEGMENT 0xA0000000U +#define GLOBAL_SHARED_SEGMENT_MASK 0xF0000000U + +#define SHARED_TEXT_REGION_SIZE 0x10000000 +#define SHARED_DATA_REGION_SIZE 0x10000000 + +#if !defined(__LP64__) + +#define SHARED_LIBRARY_SERVER_SUPPORTED + +#define SHARED_ALTERNATE_LOAD_BASE 0x09000000 + +/* + * Note: the two masks below are useful because the assumption is + * made that these shared regions will always be mapped on natural boundaries + * i.e. if the size is 0x10000000 the object can be mapped at + * 0x20000000, or 0x30000000, but not 0x1000000 + */ +#define SHARED_TEXT_REGION_MASK 0x0FFFFFFF +#define SHARED_DATA_REGION_MASK 0x0FFFFFFF + + +/* flags field aliases for copyin_shared_file and load_shared_file */ + +/* IN */ +#define ALTERNATE_LOAD_SITE 0x1 +#define NEW_LOCAL_SHARED_REGIONS 0x2 +#define QUERY_IS_SYSTEM_REGION 0x4 + +/* OUT */ +#define SF_PREV_LOADED 0x1 +#define SYSTEM_REGION_BACKED 0x2 + + +struct sf_mapping { + vm_offset_t mapping_offset; + vm_size_t size; + vm_offset_t file_offset; + vm_prot_t protection; /* read/write/execute/COW/ZF */ + vm_offset_t cksum; +}; +typedef struct sf_mapping sf_mapping_t; + +#endif /* !defined(__LP64__) */ + +/* + * All shared_region_* declarations are a private interface + * between dyld and the kernel. + * + */ +struct shared_file_mapping_np { + mach_vm_address_t sfm_address; + mach_vm_size_t sfm_size; + mach_vm_offset_t sfm_file_offset; + vm_prot_t sfm_max_prot; + vm_prot_t sfm_init_prot; +}; + +struct shared_region_range_np { + mach_vm_address_t srr_address; + mach_vm_size_t srr_size; +}; + + +__BEGIN_DECLS +int shared_region_map_file_np(int fd, + uint32_t mappingCount, + const struct shared_file_mapping_np *mappings, + int64_t *slide_p); +int shared_region_make_private_np(uint32_t rangeCount, + const struct shared_region_range_np *ranges); +__END_DECLS + + +#endif /* _MACH_SHARED_MEMORY_SERVER_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/shared_region.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/shared_region.h new file mode 100644 index 00000000..0e8f2820 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/shared_region.h @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2007 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@ + */ +/* + * + * File: mach/shared_region.h + * + * protos and struct definitions for shared region + */ + +#ifndef _MACH_SHARED_REGION_H_ +#define _MACH_SHARED_REGION_H_ + +#include +#include +#include +#include + +#define SHARED_REGION_BASE_I386 0x90000000ULL +#define SHARED_REGION_SIZE_I386 0x20000000ULL +#define SHARED_REGION_NESTING_BASE_I386 0x90000000ULL +#define SHARED_REGION_NESTING_SIZE_I386 0x20000000ULL +#define SHARED_REGION_NESTING_MIN_I386 0x00200000ULL +#define SHARED_REGION_NESTING_MAX_I386 0xFFE00000ULL + +#define SHARED_REGION_BASE_X86_64 0x00007FFF00000000ULL +#define SHARED_REGION_SIZE_X86_64 0x00000000FFE00000ULL +#define SHARED_REGION_NESTING_BASE_X86_64 0x00007FFF00000000ULL +#define SHARED_REGION_NESTING_SIZE_X86_64 0x00000000FFE00000ULL +#define SHARED_REGION_NESTING_MIN_X86_64 0x0000000000200000ULL +#define SHARED_REGION_NESTING_MAX_X86_64 0xFFFFFFFFFFE00000ULL + +#define SHARED_REGION_BASE_PPC 0x90000000ULL +#define SHARED_REGION_SIZE_PPC 0x20000000ULL +#define SHARED_REGION_NESTING_BASE_PPC 0x90000000ULL +#define SHARED_REGION_NESTING_SIZE_PPC 0x10000000ULL +#define SHARED_REGION_NESTING_MIN_PPC 0x10000000ULL +#define SHARED_REGION_NESTING_MAX_PPC 0x10000000ULL + +#define SHARED_REGION_BASE_PPC64 0x00007FFF60000000ULL +#define SHARED_REGION_SIZE_PPC64 0x00000000A0000000ULL +#define SHARED_REGION_NESTING_BASE_PPC64 0x00007FFF60000000ULL +#define SHARED_REGION_NESTING_SIZE_PPC64 0x00000000A0000000ULL +#define SHARED_REGION_NESTING_MIN_PPC64 0x0000000010000000ULL +#define SHARED_REGION_NESTING_MAX_PPC64 0x0000000010000000ULL + +#define SHARED_REGION_BASE_ARM 0x40000000ULL +#define SHARED_REGION_SIZE_ARM 0x40000000ULL +#define SHARED_REGION_NESTING_BASE_ARM 0x40000000ULL +#define SHARED_REGION_NESTING_SIZE_ARM 0x40000000ULL +#define SHARED_REGION_NESTING_MIN_ARM ? +#define SHARED_REGION_NESTING_MAX_ARM ? + +#define SHARED_REGION_BASE_ARM64_32 0x1A000000ULL +#define SHARED_REGION_SIZE_ARM64_32 0x40000000ULL +#define SHARED_REGION_NESTING_BASE_ARM64_32 0x1A000000ULL +#define SHARED_REGION_NESTING_SIZE_ARM64_32 0x40000000ULL +#define SHARED_REGION_NESTING_MIN_ARM64_32 ? +#define SHARED_REGION_NESTING_MAX_ARM64_32 ? + +#define SHARED_REGION_BASE_ARM64 0x180000000ULL +#define SHARED_REGION_SIZE_ARM64 0x100000000ULL +#define SHARED_REGION_NESTING_BASE_ARM64 0x180000000ULL +#define SHARED_REGION_NESTING_SIZE_ARM64 0x100000000ULL +#define SHARED_REGION_NESTING_MIN_ARM64 ? +#define SHARED_REGION_NESTING_MAX_ARM64 ? + +#if defined(__i386__) +#define SHARED_REGION_BASE SHARED_REGION_BASE_I386 +#define SHARED_REGION_SIZE SHARED_REGION_SIZE_I386 +#define SHARED_REGION_NESTING_BASE SHARED_REGION_NESTING_BASE_I386 +#define SHARED_REGION_NESTING_SIZE SHARED_REGION_NESTING_SIZE_I386 +#define SHARED_REGION_NESTING_MIN SHARED_REGION_NESTING_MIN_I386 +#define SHARED_REGION_NESTING_MAX SHARED_REGION_NESTING_MAX_I386 +#elif defined(__x86_64__) +#define SHARED_REGION_BASE SHARED_REGION_BASE_X86_64 +#define SHARED_REGION_SIZE SHARED_REGION_SIZE_X86_64 +#define SHARED_REGION_NESTING_BASE SHARED_REGION_NESTING_BASE_X86_64 +#define SHARED_REGION_NESTING_SIZE SHARED_REGION_NESTING_SIZE_X86_64 +#define SHARED_REGION_NESTING_MIN SHARED_REGION_NESTING_MIN_X86_64 +#define SHARED_REGION_NESTING_MAX SHARED_REGION_NESTING_MAX_X86_64 +#endif + +/* + * All shared_region_* declarations are a private interface + * between dyld and the kernel. + * + */ +struct shared_file_mapping_np { + mach_vm_address_t sfm_address; + mach_vm_size_t sfm_size; + mach_vm_offset_t sfm_file_offset; + vm_prot_t sfm_max_prot; + vm_prot_t sfm_init_prot; +}; +#define VM_PROT_COW 0x8 /* must not interfere with normal prot assignments */ +#define VM_PROT_ZF 0x10 /* must not interfere with normal prot assignments */ +#define VM_PROT_SLIDE 0x20 /* must not interfere with normal prot assignments */ + + +__BEGIN_DECLS +int shared_region_check_np(uint64_t *startaddress); +int shared_region_map_np(int fd, + uint32_t mappingCount, + const struct shared_file_mapping_np *mappings); +int shared_region_slide_np(void); +__END_DECLS + + +#endif /* _MACH_SHARED_REGION_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/std_types.defs b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/std_types.defs new file mode 100644 index 00000000..0b483836 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/std_types.defs @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2002,2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * Mach kernel standard interface type declarations + */ + +#ifndef _MACH_STD_TYPES_DEFS_ +#define _MACH_STD_TYPES_DEFS_ + +/* from ISO/IEC 988:1999 spec */ +/* 7.18.1.1 Exact-width integer types */ + +type int8_t = MACH_MSG_TYPE_INTEGER_8; +type uint8_t = MACH_MSG_TYPE_INTEGER_8; +type int16_t = MACH_MSG_TYPE_INTEGER_16; +type uint16_t = MACH_MSG_TYPE_INTEGER_16; +type int32_t = MACH_MSG_TYPE_INTEGER_32; +type uint32_t = MACH_MSG_TYPE_INTEGER_32; +type int64_t = MACH_MSG_TYPE_INTEGER_64; +type uint64_t = MACH_MSG_TYPE_INTEGER_64; + +/* + * Legacy fixed-length Mach types which should + * be replaced with the Standard types from above. + */ +type int32 = int32_t; +type unsigned32 = uint32_t; +type int64 = int64_t; +type unsigned64 = uint64_t; + +/* + * Other fixed length Mach types. + */ +type char = MACH_MSG_TYPE_CHAR; +type boolean_t = MACH_MSG_TYPE_BOOLEAN; + +#include + +type kern_return_t = int; + +type pointer_t = ^array[] of MACH_MSG_TYPE_BYTE + ctype: vm_offset_t; + + +type mach_port_t = MACH_MSG_TYPE_COPY_SEND; +type mach_port_array_t = array[] of mach_port_t; + +type mach_port_name_t = MACH_MSG_TYPE_PORT_NAME; +type mach_port_name_array_t = array[] of mach_port_name_t; + +type mach_port_right_t = natural_t; + +type mach_port_type_t = natural_t; +type mach_port_type_array_t = array[] of mach_port_type_t; + +type mach_port_urefs_t = natural_t; +type mach_port_delta_t = integer_t; +type mach_port_seqno_t = natural_t; +type mach_port_mscount_t = unsigned; +type mach_port_msgcount_t = unsigned; +type mach_port_rights_t = unsigned; +type mach_msg_id_t = integer_t; +type mach_msg_size_t = natural_t; +type mach_msg_type_name_t = unsigned; +type mach_msg_options_t = integer_t; + +type mach_port_move_receive_t = MACH_MSG_TYPE_MOVE_RECEIVE + ctype: mach_port_t; +type mach_port_copy_send_t = MACH_MSG_TYPE_COPY_SEND + ctype: mach_port_t; +type mach_port_make_send_t = MACH_MSG_TYPE_MAKE_SEND + ctype: mach_port_t; +type mach_port_move_send_t = MACH_MSG_TYPE_MOVE_SEND + ctype: mach_port_t; +type mach_port_make_send_once_t = MACH_MSG_TYPE_MAKE_SEND_ONCE + ctype: mach_port_t; +type mach_port_move_send_once_t = MACH_MSG_TYPE_MOVE_SEND_ONCE + ctype: mach_port_t; + +type mach_port_receive_t = MACH_MSG_TYPE_PORT_RECEIVE + ctype: mach_port_t; +type mach_port_send_t = MACH_MSG_TYPE_PORT_SEND + ctype: mach_port_t; +type mach_port_send_once_t = MACH_MSG_TYPE_PORT_SEND_ONCE + ctype: mach_port_t; + +type mach_port_poly_t = polymorphic + ctype: mach_port_t; + +import ; +import ; + +#endif /* _MACH_STD_TYPES_DEFS_ */ + +/* vim: set ft=c : */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/std_types.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/std_types.h new file mode 100644 index 00000000..5815302d --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/std_types.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2002,2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * Mach standard external interface type definitions. + * + */ + +#ifndef _MACH_STD_TYPES_H_ +#define _MACH_STD_TYPES_H_ + +#include +#include +#include +#include +#include + +#include +#include + +#endif /* _MACH_STD_TYPES_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/sync.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/sync.h new file mode 100644 index 00000000..b3057205 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/sync.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* +** This file contains compatibilty wrapper header for things that used +** to be generated from mach/sync.defs. Now that code is split into two +** different interface generator files, so include the two resulting +** headers here. +*/ +#include +#include diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/sync_policy.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/sync_policy.h new file mode 100644 index 00000000..ff487f6a --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/sync_policy.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ + +#ifndef _MACH_SYNC_POLICY_H_ +#define _MACH_SYNC_POLICY_H_ + +typedef int sync_policy_t; + +/* + * These options define the wait ordering of the synchronizers + */ +#define SYNC_POLICY_FIFO 0x0 +#define SYNC_POLICY_FIXED_PRIORITY 0x1 +#define SYNC_POLICY_REVERSED 0x2 +#define SYNC_POLICY_ORDER_MASK 0x3 +#define SYNC_POLICY_LIFO (SYNC_POLICY_FIFO|SYNC_POLICY_REVERSED) + + +#define SYNC_POLICY_MAX 0x7 + +#endif /* _MACH_SYNC_POLICY_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/task.defs b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/task.defs new file mode 100644 index 00000000..8723a525 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/task.defs @@ -0,0 +1,522 @@ +/* + * Copyright (c) 2000-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_FREE_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * File: mach/mach_port.defs + * Author: Rich Draves + * + * Exported kernel calls. + */ + +subsystem +#if KERNEL_SERVER + KernelServer +#endif /* KERNEL_SERVER */ + task 3400; + +#include +#include +#include + +/* + * Create a new task with an empty set of IPC rights, + * and having an address space constructed from the + * target task (or empty, if inherit_memory is FALSE). + */ +routine task_create( + target_task : task_t; + ledgers : ledger_array_t; + inherit_memory : boolean_t; + out child_task : task_t); + +/* + * Destroy the target task, causing all of its threads + * to be destroyed, all of its IPC rights to be deallocated, + * and all of its address space to be deallocated. + */ +routine task_terminate( + target_task : task_t); + +/* + * Returns the set of threads belonging to the target task. + */ +routine task_threads( + target_task : task_inspect_t; + out act_list : thread_act_array_t); + +/* + * Stash a handful of ports for the target task; child + * tasks inherit this stash at task_create time. + */ +routine mach_ports_register( + target_task : task_t; + init_port_set : mach_port_array_t = + ^array[] of mach_port_t); + +/* + * Retrieve the stashed ports for the target task. + */ +routine mach_ports_lookup( + target_task : task_t; + out init_port_set : mach_port_array_t = + ^array[] of mach_port_t); + +/* + * Returns information about the target task. + */ +#ifdef KERNEL_SERVER +routine task_info_from_user( + target_task : mach_port_t; + flavor : task_flavor_t; + out task_info_out : task_info_t, CountInOut); +#else +routine task_info( + target_task : task_name_t; + flavor : task_flavor_t; + out task_info_out : task_info_t, CountInOut); + +#endif +/* + * Set task information. + */ +routine task_set_info( + target_task : task_t; + flavor : task_flavor_t; + task_info_in : task_info_t); + +/* + * Increment the suspend count for the target task. + * No threads within a task may run when the suspend + * count for that task is non-zero. + */ +routine task_suspend( + target_task : task_t); + + +/* + * Decrement the suspend count for the target task, + * if the count is currently non-zero. If the resulting + * suspend count is zero, then threads within the task + * that also have non-zero suspend counts may execute. + */ +routine task_resume( + target_task : task_t); + +/* + * Returns the current value of the selected special port + * associated with the target task. + */ +routine task_get_special_port( + task : task_inspect_t; + which_port : int; + out special_port : mach_port_t); + +/* + * Set one of the special ports associated with the + * target task. + */ +routine task_set_special_port( + task : task_t; + which_port : int; + special_port : mach_port_t); + +/* + * Create a new thread within the target task, returning + * the port representing the first thr_act in that new thread. The + * initial execution state of the thread is undefined. + */ +routine +#ifdef KERNEL_SERVER +thread_create_from_user( +#else +thread_create( +#endif + parent_task : task_t; + out child_act : thread_act_t); + +/* + * Create a new thread within the target task, returning + * the port representing that new thread. The new thread + * is not suspended; its initial execution state is given + * by flavor and new_state. Returns the port representing + * the new thread. + */ +routine +#ifdef KERNEL_SERVER +thread_create_running_from_user( +#else +thread_create_running( +#endif + parent_task : task_t; + flavor : thread_state_flavor_t; + new_state : thread_state_t; + out child_act : thread_act_t); + +/* + * Set an exception handler for a task on one or more exception types. + * These handlers are invoked for all threads in the task if there are + * no thread-specific exception handlers or those handlers returned an + * error. + */ +routine task_set_exception_ports( + task : task_t; + exception_mask : exception_mask_t; + new_port : mach_port_t; + behavior : exception_behavior_t; + new_flavor : thread_state_flavor_t); + + +/* + * Lookup some of the old exception handlers for a task + */ +routine task_get_exception_ports( + task : task_inspect_t; + exception_mask : exception_mask_t; + out masks : exception_mask_array_t; + out old_handlers : exception_handler_array_t, SameCount; + out old_behaviors : exception_behavior_array_t, SameCount; + out old_flavors : exception_flavor_array_t, SameCount); + + +/* + * Set an exception handler for a thread on one or more exception types. + * At the same time, return the previously defined exception handlers for + * those types. + */ +routine task_swap_exception_ports( + task : task_t; + exception_mask : exception_mask_t; + new_port : mach_port_t; + behavior : exception_behavior_t; + new_flavor : thread_state_flavor_t; + out masks : exception_mask_array_t; + out old_handlerss : exception_handler_array_t, SameCount; + out old_behaviors : exception_behavior_array_t, SameCount; + out old_flavors : exception_flavor_array_t, SameCount); + +/* + * OBSOLETE interface. + */ +routine lock_set_create( + task : task_t; + out new_lock_set : lock_set_t; + n_ulocks : int; + policy : int); + +/* + * OBSOLETE interface. + */ +routine lock_set_destroy( + task : task_t; + lock_set : lock_set_t); + +/* + * Create and destroy semaphore synchronizers on a + * per-task basis (i.e. the task owns them). + */ + +routine semaphore_create( + task : task_t; + out semaphore : semaphore_t; + policy : int; + value : int); + +routine semaphore_destroy( + task : task_t; + semaphore : semaphore_consume_ref_t); + +/* + * Set/get policy information for a task. + * (Approved Mac OS X microkernel interface) + */ + +routine task_policy_set( + task : task_t; + flavor : task_policy_flavor_t; + policy_info : task_policy_t); + +routine task_policy_get( + task : task_t; + flavor : task_policy_flavor_t; +out policy_info : task_policy_t, CountInOut; +inout get_default : boolean_t); + +/* + * Removed from the kernel. + */ +#if KERNEL_SERVER +skip; +#else +routine task_sample( + task : task_t; + reply : mach_port_make_send_t); +#endif + +/* + * JMM - Everything from here down is likely to go away soon + */ +/* + * OBSOLETE interface. + */ +routine task_policy( + task : task_t; + policy : policy_t; + base : policy_base_t; + set_limit : boolean_t; + change : boolean_t); + + +/* + * Establish a user-level handler for the specified + * system call. + */ +routine task_set_emulation( + target_port : task_t; + routine_entry_pt: vm_address_t; + routine_number : int); + +/* + * Get user-level handler entry points for all + * emulated system calls. + */ +routine task_get_emulation_vector( + task : task_t; + out vector_start : int; + out emulation_vector: emulation_vector_t); + +/* + * Establish user-level handlers for the specified + * system calls. Non-emulated system calls are specified + * with emulation_vector[i] == EML_ROUTINE_NULL. + */ +routine task_set_emulation_vector( + task : task_t; + vector_start : int; + emulation_vector: emulation_vector_t); + + +/* + * Establish restart pc for interrupted atomic sequences. + */ +routine task_set_ras_pc( + target_task : task_t; + basepc : vm_address_t; + boundspc : vm_address_t); + + +/* + * Return zone info as seen/used by this task. + */ +routine task_zone_info( + target_task : task_t; + out names : mach_zone_name_array_t, + Dealloc; + out info : task_zone_info_array_t, + Dealloc); + + +/* + * JMM - Want to eliminate processor_set so keep them at the end. + */ + +/* + * Assign task to processor set. + */ +routine task_assign( + task : task_t; + new_set : processor_set_t; + assign_threads : boolean_t); + +/* + * Assign task to default set. + */ +routine task_assign_default( + task : task_t; + assign_threads : boolean_t); + +/* + * Get current assignment for task. + */ +routine task_get_assignment( + task : task_t; + out assigned_set : processor_set_name_t); + +/* + * OBSOLETE interface. + */ +routine task_set_policy( + task : task_t; + pset : processor_set_t; + policy : policy_t; + base : policy_base_t; + limit : policy_limit_t; + change : boolean_t); + +/* + * Read the selected state which is to be installed on new + * threads in the task as they are created. + */ +routine task_get_state( + task : task_t; + flavor : thread_state_flavor_t; + out old_state : thread_state_t, CountInOut); + +/* + * Set the selected state information to be installed on + * all subsequently created threads in the task. + */ +routine task_set_state( + task : task_t; + flavor : thread_state_flavor_t; + new_state : thread_state_t); + +/* + * Change the task's physical footprint limit (in MB). + */ +routine task_set_phys_footprint_limit( + task : task_t; + new_limit : int; + out old_limit : int); + +routine task_suspend2( + target_task : task_t; + out suspend_token : task_suspension_token_t); + +routine task_resume2( + suspend_token : task_suspension_token_t); + +routine task_purgable_info( + task : task_t; + out stats : task_purgable_info_t); + +routine task_get_mach_voucher( + task : task_t; + which : mach_voucher_selector_t; + out voucher : ipc_voucher_t); + +routine task_set_mach_voucher( + task : task_t; + voucher : ipc_voucher_t); + +routine task_swap_mach_voucher( + task : task_t; + new_voucher : ipc_voucher_t; + inout old_voucher : ipc_voucher_t); + +routine task_generate_corpse( + task :task_t; + out corpse_task_port:mach_port_t); + +routine task_map_corpse_info( + task :task_t; + corspe_task :task_t; + out kcd_addr_begin :vm_address_t; + out kcd_size :uint32_t); + +routine task_register_dyld_image_infos( + task :task_t; + dyld_images :dyld_kernel_image_info_array_t); + +routine task_unregister_dyld_image_infos( + task :task_t; + dyld_images :dyld_kernel_image_info_array_t); + +routine task_get_dyld_image_infos( + task :task_inspect_t; + out dyld_images :dyld_kernel_image_info_array_t); + +routine task_register_dyld_shared_cache_image_info( + task :task_t; + dyld_cache_image :dyld_kernel_image_info_t; + no_cache :boolean_t; + private_cache :boolean_t); + +routine task_register_dyld_set_dyld_state( + task :task_t; + dyld_state :uint8_t); + +routine task_register_dyld_get_process_state( + task :task_t; + out dyld_process_state :dyld_kernel_process_info_t); + +routine task_map_corpse_info_64( + task :task_t; + corspe_task :task_t; + out kcd_addr_begin :mach_vm_address_t; + out kcd_size :mach_vm_size_t); + +routine task_inspect( + task : task_inspect_t; + flavor : task_inspect_flavor_t; + out info_out : task_inspect_info_t, CountInOut); + +routine task_get_exc_guard_behavior( + task : task_inspect_t; + out behavior : task_exc_guard_behavior_t); + +routine task_set_exc_guard_behavior( + task : task_t; + behavior : task_exc_guard_behavior_t); + +routine task_create_suid_cred( + task : task_t; + path : suid_cred_path_t; + uid : suid_cred_uid_t; + out delegation : suid_cred_t); + +/* vim: set ft=c : */ + diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/task.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/task.h new file mode 100644 index 00000000..20019654 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/task.h @@ -0,0 +1,2523 @@ +#ifndef _task_user_ +#define _task_user_ + +/* Module task */ + +#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 task_MSG_COUNT +#define task_MSG_COUNT 55 +#endif /* task_MSG_COUNT */ + +#include +#include +#include +#include +#include + +#ifdef __BeforeMigUserHeader +__BeforeMigUserHeader +#endif /* __BeforeMigUserHeader */ + +#include +__BEGIN_DECLS + + +/* Routine task_create */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t task_create +( + task_t target_task, + ledger_array_t ledgers, + mach_msg_type_number_t ledgersCnt, + boolean_t inherit_memory, + task_t *child_task +); + +/* Routine task_terminate */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t task_terminate +( + task_t target_task +); + +/* Routine task_threads */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t task_threads +( + task_inspect_t target_task, + thread_act_array_t *act_list, + mach_msg_type_number_t *act_listCnt +); + +/* Routine mach_ports_register */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t mach_ports_register +( + task_t target_task, + mach_port_array_t init_port_set, + mach_msg_type_number_t init_port_setCnt +); + +/* Routine mach_ports_lookup */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t mach_ports_lookup +( + task_t target_task, + mach_port_array_t *init_port_set, + mach_msg_type_number_t *init_port_setCnt +); + +/* Routine task_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t task_info +( + task_name_t target_task, + task_flavor_t flavor, + task_info_t task_info_out, + mach_msg_type_number_t *task_info_outCnt +); + +/* Routine task_set_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t task_set_info +( + task_t target_task, + task_flavor_t flavor, + task_info_t task_info_in, + mach_msg_type_number_t task_info_inCnt +); + +/* Routine task_suspend */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t task_suspend +( + task_t target_task +); + +/* Routine task_resume */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t task_resume +( + task_t target_task +); + +/* Routine task_get_special_port */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t task_get_special_port +( + task_inspect_t task, + int which_port, + mach_port_t *special_port +); + +/* Routine task_set_special_port */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t task_set_special_port +( + task_t task, + int which_port, + mach_port_t special_port +); + +/* Routine thread_create */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t thread_create +( + task_t parent_task, + thread_act_t *child_act +); + +/* Routine thread_create_running */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t thread_create_running +( + task_t parent_task, + thread_state_flavor_t flavor, + thread_state_t new_state, + mach_msg_type_number_t new_stateCnt, + thread_act_t *child_act +); + +/* Routine task_set_exception_ports */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t task_set_exception_ports +( + task_t task, + exception_mask_t exception_mask, + mach_port_t new_port, + exception_behavior_t behavior, + thread_state_flavor_t new_flavor +); + +/* Routine task_get_exception_ports */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t task_get_exception_ports +( + task_inspect_t task, + exception_mask_t exception_mask, + exception_mask_array_t masks, + mach_msg_type_number_t *masksCnt, + exception_handler_array_t old_handlers, + exception_behavior_array_t old_behaviors, + exception_flavor_array_t old_flavors +); + +/* Routine task_swap_exception_ports */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t task_swap_exception_ports +( + task_t task, + exception_mask_t exception_mask, + mach_port_t new_port, + exception_behavior_t behavior, + thread_state_flavor_t new_flavor, + exception_mask_array_t masks, + mach_msg_type_number_t *masksCnt, + exception_handler_array_t old_handlerss, + exception_behavior_array_t old_behaviors, + exception_flavor_array_t old_flavors +); + +/* Routine lock_set_create */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t lock_set_create +( + task_t task, + lock_set_t *new_lock_set, + int n_ulocks, + int policy +); + +/* Routine lock_set_destroy */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t lock_set_destroy +( + task_t task, + lock_set_t lock_set +); + +/* Routine semaphore_create */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t semaphore_create +( + task_t task, + semaphore_t *semaphore, + int policy, + int value +); + +/* Routine semaphore_destroy */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t semaphore_destroy +( + task_t task, + semaphore_t semaphore +); + +/* Routine task_policy_set */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t task_policy_set +( + task_t task, + task_policy_flavor_t flavor, + task_policy_t policy_info, + mach_msg_type_number_t policy_infoCnt +); + +/* Routine task_policy_get */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t task_policy_get +( + task_t task, + task_policy_flavor_t flavor, + task_policy_t policy_info, + mach_msg_type_number_t *policy_infoCnt, + boolean_t *get_default +); + +/* Routine task_sample */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t task_sample +( + task_t task, + mach_port_t reply +); + +/* Routine task_policy */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t task_policy +( + task_t task, + policy_t policy, + policy_base_t base, + mach_msg_type_number_t baseCnt, + boolean_t set_limit, + boolean_t change +); + +/* Routine task_set_emulation */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t task_set_emulation +( + task_t target_port, + vm_address_t routine_entry_pt, + int routine_number +); + +/* Routine task_get_emulation_vector */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t task_get_emulation_vector +( + task_t task, + int *vector_start, + emulation_vector_t *emulation_vector, + mach_msg_type_number_t *emulation_vectorCnt +); + +/* Routine task_set_emulation_vector */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t task_set_emulation_vector +( + task_t task, + int vector_start, + emulation_vector_t emulation_vector, + mach_msg_type_number_t emulation_vectorCnt +); + +/* Routine task_set_ras_pc */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t task_set_ras_pc +( + task_t target_task, + vm_address_t basepc, + vm_address_t boundspc +); + +/* Routine task_zone_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t task_zone_info +( + task_t target_task, + mach_zone_name_array_t *names, + mach_msg_type_number_t *namesCnt, + task_zone_info_array_t *info, + mach_msg_type_number_t *infoCnt +); + +/* Routine task_assign */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t task_assign +( + task_t task, + processor_set_t new_set, + boolean_t assign_threads +); + +/* Routine task_assign_default */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t task_assign_default +( + task_t task, + boolean_t assign_threads +); + +/* Routine task_get_assignment */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t task_get_assignment +( + task_t task, + processor_set_name_t *assigned_set +); + +/* Routine task_set_policy */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t task_set_policy +( + task_t task, + processor_set_t pset, + policy_t policy, + policy_base_t base, + mach_msg_type_number_t baseCnt, + policy_limit_t limit, + mach_msg_type_number_t limitCnt, + boolean_t change +); + +/* Routine task_get_state */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t task_get_state +( + task_t task, + thread_state_flavor_t flavor, + thread_state_t old_state, + mach_msg_type_number_t *old_stateCnt +); + +/* Routine task_set_state */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t task_set_state +( + task_t task, + thread_state_flavor_t flavor, + thread_state_t new_state, + mach_msg_type_number_t new_stateCnt +); + +/* Routine task_set_phys_footprint_limit */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t task_set_phys_footprint_limit +( + task_t task, + int new_limit, + int *old_limit +); + +/* Routine task_suspend2 */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t task_suspend2 +( + task_t target_task, + task_suspension_token_t *suspend_token +); + +/* Routine task_resume2 */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t task_resume2 +( + task_suspension_token_t suspend_token +); + +/* Routine task_purgable_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t task_purgable_info +( + task_t task, + task_purgable_info_t *stats +); + +/* Routine task_get_mach_voucher */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t task_get_mach_voucher +( + task_t task, + mach_voucher_selector_t which, + ipc_voucher_t *voucher +); + +/* Routine task_set_mach_voucher */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t task_set_mach_voucher +( + task_t task, + ipc_voucher_t voucher +); + +/* Routine task_swap_mach_voucher */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t task_swap_mach_voucher +( + task_t task, + ipc_voucher_t new_voucher, + ipc_voucher_t *old_voucher +); + +/* Routine task_generate_corpse */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t task_generate_corpse +( + task_t task, + mach_port_t *corpse_task_port +); + +/* Routine task_map_corpse_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t task_map_corpse_info +( + task_t task, + task_t corspe_task, + vm_address_t *kcd_addr_begin, + uint32_t *kcd_size +); + +/* Routine task_register_dyld_image_infos */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t task_register_dyld_image_infos +( + task_t task, + dyld_kernel_image_info_array_t dyld_images, + mach_msg_type_number_t dyld_imagesCnt +); + +/* Routine task_unregister_dyld_image_infos */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t task_unregister_dyld_image_infos +( + task_t task, + dyld_kernel_image_info_array_t dyld_images, + mach_msg_type_number_t dyld_imagesCnt +); + +/* Routine task_get_dyld_image_infos */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t task_get_dyld_image_infos +( + task_inspect_t task, + dyld_kernel_image_info_array_t *dyld_images, + mach_msg_type_number_t *dyld_imagesCnt +); + +/* Routine task_register_dyld_shared_cache_image_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t task_register_dyld_shared_cache_image_info +( + task_t task, + dyld_kernel_image_info_t dyld_cache_image, + boolean_t no_cache, + boolean_t private_cache +); + +/* Routine task_register_dyld_set_dyld_state */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t task_register_dyld_set_dyld_state +( + task_t task, + uint8_t dyld_state +); + +/* Routine task_register_dyld_get_process_state */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t task_register_dyld_get_process_state +( + task_t task, + dyld_kernel_process_info_t *dyld_process_state +); + +/* Routine task_map_corpse_info_64 */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t task_map_corpse_info_64 +( + task_t task, + task_t corspe_task, + mach_vm_address_t *kcd_addr_begin, + mach_vm_size_t *kcd_size +); + +/* Routine task_inspect */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t task_inspect +( + task_inspect_t task, + task_inspect_flavor_t flavor, + task_inspect_info_t info_out, + mach_msg_type_number_t *info_outCnt +); + +/* Routine task_get_exc_guard_behavior */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t task_get_exc_guard_behavior +( + task_inspect_t task, + task_exc_guard_behavior_t *behavior +); + +/* Routine task_set_exc_guard_behavior */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t task_set_exc_guard_behavior +( + task_t task, + task_exc_guard_behavior_t behavior +); + +/* Routine task_create_suid_cred */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t task_create_suid_cred +( + task_t task, + suid_cred_path_t path, + suid_cred_uid_t uid, + suid_cred_t *delegation +); + +__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__task_subsystem__defined +#define __Request__task_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_ool_ports_descriptor_t ledgers; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t ledgersCnt; + boolean_t inherit_memory; + } __Request__task_create_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__task_terminate_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__task_threads_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_ool_ports_descriptor_t init_port_set; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t init_port_setCnt; + } __Request__mach_ports_register_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__mach_ports_lookup_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + task_flavor_t flavor; + mach_msg_type_number_t task_info_outCnt; + } __Request__task_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + task_flavor_t flavor; + mach_msg_type_number_t task_info_inCnt; + integer_t task_info_in[87]; + } __Request__task_set_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__task_suspend_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__task_resume_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int which_port; + } __Request__task_get_special_port_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 special_port; + /* end of the kernel processed data */ + NDR_record_t NDR; + int which_port; + } __Request__task_set_special_port_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__thread_create_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + thread_state_flavor_t flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[614]; + } __Request__thread_create_running_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 new_port; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_mask_t exception_mask; + exception_behavior_t behavior; + thread_state_flavor_t new_flavor; + } __Request__task_set_exception_ports_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + exception_mask_t exception_mask; + } __Request__task_get_exception_ports_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 new_port; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_mask_t exception_mask; + exception_behavior_t behavior; + thread_state_flavor_t new_flavor; + } __Request__task_swap_exception_ports_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int n_ulocks; + int policy; + } __Request__lock_set_create_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 lock_set; + /* end of the kernel processed data */ + } __Request__lock_set_destroy_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int policy; + int value; + } __Request__semaphore_create_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 semaphore; + /* end of the kernel processed data */ + } __Request__semaphore_destroy_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + task_policy_flavor_t flavor; + mach_msg_type_number_t policy_infoCnt; + integer_t policy_info[16]; + } __Request__task_policy_set_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + task_policy_flavor_t flavor; + mach_msg_type_number_t policy_infoCnt; + boolean_t get_default; + } __Request__task_policy_get_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 reply; + /* end of the kernel processed data */ + } __Request__task_sample_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + policy_t policy; + mach_msg_type_number_t baseCnt; + integer_t base[5]; + boolean_t set_limit; + boolean_t change; + } __Request__task_policy_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t routine_entry_pt; + int routine_number; + } __Request__task_set_emulation_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__task_get_emulation_vector_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 emulation_vector; + /* end of the kernel processed data */ + NDR_record_t NDR; + int vector_start; + mach_msg_type_number_t emulation_vectorCnt; + } __Request__task_set_emulation_vector_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t basepc; + vm_address_t boundspc; + } __Request__task_set_ras_pc_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__task_zone_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 new_set; + /* end of the kernel processed data */ + NDR_record_t NDR; + boolean_t assign_threads; + } __Request__task_assign_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + boolean_t assign_threads; + } __Request__task_assign_default_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__task_get_assignment_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 pset; + /* end of the kernel processed data */ + NDR_record_t NDR; + policy_t policy; + mach_msg_type_number_t baseCnt; + integer_t base[5]; + mach_msg_type_number_t limitCnt; + integer_t limit[1]; + boolean_t change; + } __Request__task_set_policy_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + thread_state_flavor_t flavor; + mach_msg_type_number_t old_stateCnt; + } __Request__task_get_state_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + thread_state_flavor_t flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[614]; + } __Request__task_set_state_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int new_limit; + } __Request__task_set_phys_footprint_limit_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__task_suspend2_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__task_resume2_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__task_purgable_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_voucher_selector_t which; + } __Request__task_get_mach_voucher_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 voucher; + /* end of the kernel processed data */ + } __Request__task_set_mach_voucher_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 new_voucher; + mach_msg_port_descriptor_t old_voucher; + /* end of the kernel processed data */ + } __Request__task_swap_mach_voucher_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__task_generate_corpse_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 corspe_task; + /* end of the kernel processed data */ + } __Request__task_map_corpse_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 dyld_images; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t dyld_imagesCnt; + } __Request__task_register_dyld_image_infos_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 dyld_images; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t dyld_imagesCnt; + } __Request__task_unregister_dyld_image_infos_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__task_get_dyld_image_infos_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + dyld_kernel_image_info_t dyld_cache_image; + boolean_t no_cache; + boolean_t private_cache; + } __Request__task_register_dyld_shared_cache_image_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + uint8_t dyld_state; + char dyld_statePad[3]; + } __Request__task_register_dyld_set_dyld_state_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__task_register_dyld_get_process_state_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 corspe_task; + /* end of the kernel processed data */ + } __Request__task_map_corpse_info_64_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + task_inspect_flavor_t flavor; + mach_msg_type_number_t info_outCnt; + } __Request__task_inspect_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__task_get_exc_guard_behavior_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + task_exc_guard_behavior_t behavior; + } __Request__task_set_exc_guard_behavior_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_msg_type_number_t pathOffset; /* MiG doesn't use it */ + mach_msg_type_number_t pathCnt; + char path[1024]; + suid_cred_uid_t uid; + } __Request__task_create_suid_cred_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Request__task_subsystem__defined */ + +/* union of all requests */ + +#ifndef __RequestUnion__task_subsystem__defined +#define __RequestUnion__task_subsystem__defined +union __RequestUnion__task_subsystem { + __Request__task_create_t Request_task_create; + __Request__task_terminate_t Request_task_terminate; + __Request__task_threads_t Request_task_threads; + __Request__mach_ports_register_t Request_mach_ports_register; + __Request__mach_ports_lookup_t Request_mach_ports_lookup; + __Request__task_info_t Request_task_info; + __Request__task_set_info_t Request_task_set_info; + __Request__task_suspend_t Request_task_suspend; + __Request__task_resume_t Request_task_resume; + __Request__task_get_special_port_t Request_task_get_special_port; + __Request__task_set_special_port_t Request_task_set_special_port; + __Request__thread_create_t Request_thread_create; + __Request__thread_create_running_t Request_thread_create_running; + __Request__task_set_exception_ports_t Request_task_set_exception_ports; + __Request__task_get_exception_ports_t Request_task_get_exception_ports; + __Request__task_swap_exception_ports_t Request_task_swap_exception_ports; + __Request__lock_set_create_t Request_lock_set_create; + __Request__lock_set_destroy_t Request_lock_set_destroy; + __Request__semaphore_create_t Request_semaphore_create; + __Request__semaphore_destroy_t Request_semaphore_destroy; + __Request__task_policy_set_t Request_task_policy_set; + __Request__task_policy_get_t Request_task_policy_get; + __Request__task_sample_t Request_task_sample; + __Request__task_policy_t Request_task_policy; + __Request__task_set_emulation_t Request_task_set_emulation; + __Request__task_get_emulation_vector_t Request_task_get_emulation_vector; + __Request__task_set_emulation_vector_t Request_task_set_emulation_vector; + __Request__task_set_ras_pc_t Request_task_set_ras_pc; + __Request__task_zone_info_t Request_task_zone_info; + __Request__task_assign_t Request_task_assign; + __Request__task_assign_default_t Request_task_assign_default; + __Request__task_get_assignment_t Request_task_get_assignment; + __Request__task_set_policy_t Request_task_set_policy; + __Request__task_get_state_t Request_task_get_state; + __Request__task_set_state_t Request_task_set_state; + __Request__task_set_phys_footprint_limit_t Request_task_set_phys_footprint_limit; + __Request__task_suspend2_t Request_task_suspend2; + __Request__task_resume2_t Request_task_resume2; + __Request__task_purgable_info_t Request_task_purgable_info; + __Request__task_get_mach_voucher_t Request_task_get_mach_voucher; + __Request__task_set_mach_voucher_t Request_task_set_mach_voucher; + __Request__task_swap_mach_voucher_t Request_task_swap_mach_voucher; + __Request__task_generate_corpse_t Request_task_generate_corpse; + __Request__task_map_corpse_info_t Request_task_map_corpse_info; + __Request__task_register_dyld_image_infos_t Request_task_register_dyld_image_infos; + __Request__task_unregister_dyld_image_infos_t Request_task_unregister_dyld_image_infos; + __Request__task_get_dyld_image_infos_t Request_task_get_dyld_image_infos; + __Request__task_register_dyld_shared_cache_image_info_t Request_task_register_dyld_shared_cache_image_info; + __Request__task_register_dyld_set_dyld_state_t Request_task_register_dyld_set_dyld_state; + __Request__task_register_dyld_get_process_state_t Request_task_register_dyld_get_process_state; + __Request__task_map_corpse_info_64_t Request_task_map_corpse_info_64; + __Request__task_inspect_t Request_task_inspect; + __Request__task_get_exc_guard_behavior_t Request_task_get_exc_guard_behavior; + __Request__task_set_exc_guard_behavior_t Request_task_set_exc_guard_behavior; + __Request__task_create_suid_cred_t Request_task_create_suid_cred; +}; +#endif /* !__RequestUnion__task_subsystem__defined */ +/* typedefs for all replies */ + +#ifndef __Reply__task_subsystem__defined +#define __Reply__task_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 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 child_task; + /* end of the kernel processed data */ + } __Reply__task_create_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__task_terminate_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_ool_ports_descriptor_t act_list; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t act_listCnt; + } __Reply__task_threads_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__mach_ports_register_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + /* start of the kernel processed data */ + mach_msg_body_t msgh_body; + mach_msg_ool_ports_descriptor_t init_port_set; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t init_port_setCnt; + } __Reply__mach_ports_lookup_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t task_info_outCnt; + integer_t task_info_out[87]; + } __Reply__task_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__task_set_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__task_suspend_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__task_resume_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 special_port; + /* end of the kernel processed data */ + } __Reply__task_get_special_port_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__task_set_special_port_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 child_act; + /* end of the kernel processed data */ + } __Reply__thread_create_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 child_act; + /* end of the kernel processed data */ + } __Reply__thread_create_running_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__task_set_exception_ports_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 old_handlers[32]; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t masksCnt; + exception_mask_t masks[32]; + exception_behavior_t old_behaviors[32]; + thread_state_flavor_t old_flavors[32]; + } __Reply__task_get_exception_ports_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 old_handlerss[32]; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t masksCnt; + exception_mask_t masks[32]; + exception_behavior_t old_behaviors[32]; + thread_state_flavor_t old_flavors[32]; + } __Reply__task_swap_exception_ports_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 new_lock_set; + /* end of the kernel processed data */ + } __Reply__lock_set_create_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__lock_set_destroy_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 semaphore; + /* end of the kernel processed data */ + } __Reply__semaphore_create_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__semaphore_destroy_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__task_policy_set_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t policy_infoCnt; + integer_t policy_info[16]; + boolean_t get_default; + } __Reply__task_policy_get_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__task_sample_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__task_policy_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__task_set_emulation_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 emulation_vector; + /* end of the kernel processed data */ + NDR_record_t NDR; + int vector_start; + mach_msg_type_number_t emulation_vectorCnt; + } __Reply__task_get_emulation_vector_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__task_set_emulation_vector_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__task_set_ras_pc_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 names; + mach_msg_ool_descriptor_t info; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t namesCnt; + mach_msg_type_number_t infoCnt; + } __Reply__task_zone_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__task_assign_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__task_assign_default_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 assigned_set; + /* end of the kernel processed data */ + } __Reply__task_get_assignment_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__task_set_policy_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[614]; + } __Reply__task_get_state_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__task_set_state_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int old_limit; + } __Reply__task_set_phys_footprint_limit_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 suspend_token; + /* end of the kernel processed data */ + } __Reply__task_suspend2_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__task_resume2_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + task_purgable_info_t stats; + } __Reply__task_purgable_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 voucher; + /* end of the kernel processed data */ + } __Reply__task_get_mach_voucher_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__task_set_mach_voucher_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 old_voucher; + /* end of the kernel processed data */ + } __Reply__task_swap_mach_voucher_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 corpse_task_port; + /* end of the kernel processed data */ + } __Reply__task_generate_corpse_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + vm_address_t kcd_addr_begin; + uint32_t kcd_size; + } __Reply__task_map_corpse_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__task_register_dyld_image_infos_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__task_unregister_dyld_image_infos_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 dyld_images; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t dyld_imagesCnt; + } __Reply__task_get_dyld_image_infos_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__task_register_dyld_shared_cache_image_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__task_register_dyld_set_dyld_state_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + dyld_kernel_process_info_t dyld_process_state; + } __Reply__task_register_dyld_get_process_state_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_vm_address_t kcd_addr_begin; + mach_vm_size_t kcd_size; + } __Reply__task_map_corpse_info_64_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t info_outCnt; + integer_t info_out[4]; + } __Reply__task_inspect_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + task_exc_guard_behavior_t behavior; + } __Reply__task_get_exc_guard_behavior_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__task_set_exc_guard_behavior_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 delegation; + /* end of the kernel processed data */ + } __Reply__task_create_suid_cred_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Reply__task_subsystem__defined */ + +/* union of all replies */ + +#ifndef __ReplyUnion__task_subsystem__defined +#define __ReplyUnion__task_subsystem__defined +union __ReplyUnion__task_subsystem { + __Reply__task_create_t Reply_task_create; + __Reply__task_terminate_t Reply_task_terminate; + __Reply__task_threads_t Reply_task_threads; + __Reply__mach_ports_register_t Reply_mach_ports_register; + __Reply__mach_ports_lookup_t Reply_mach_ports_lookup; + __Reply__task_info_t Reply_task_info; + __Reply__task_set_info_t Reply_task_set_info; + __Reply__task_suspend_t Reply_task_suspend; + __Reply__task_resume_t Reply_task_resume; + __Reply__task_get_special_port_t Reply_task_get_special_port; + __Reply__task_set_special_port_t Reply_task_set_special_port; + __Reply__thread_create_t Reply_thread_create; + __Reply__thread_create_running_t Reply_thread_create_running; + __Reply__task_set_exception_ports_t Reply_task_set_exception_ports; + __Reply__task_get_exception_ports_t Reply_task_get_exception_ports; + __Reply__task_swap_exception_ports_t Reply_task_swap_exception_ports; + __Reply__lock_set_create_t Reply_lock_set_create; + __Reply__lock_set_destroy_t Reply_lock_set_destroy; + __Reply__semaphore_create_t Reply_semaphore_create; + __Reply__semaphore_destroy_t Reply_semaphore_destroy; + __Reply__task_policy_set_t Reply_task_policy_set; + __Reply__task_policy_get_t Reply_task_policy_get; + __Reply__task_sample_t Reply_task_sample; + __Reply__task_policy_t Reply_task_policy; + __Reply__task_set_emulation_t Reply_task_set_emulation; + __Reply__task_get_emulation_vector_t Reply_task_get_emulation_vector; + __Reply__task_set_emulation_vector_t Reply_task_set_emulation_vector; + __Reply__task_set_ras_pc_t Reply_task_set_ras_pc; + __Reply__task_zone_info_t Reply_task_zone_info; + __Reply__task_assign_t Reply_task_assign; + __Reply__task_assign_default_t Reply_task_assign_default; + __Reply__task_get_assignment_t Reply_task_get_assignment; + __Reply__task_set_policy_t Reply_task_set_policy; + __Reply__task_get_state_t Reply_task_get_state; + __Reply__task_set_state_t Reply_task_set_state; + __Reply__task_set_phys_footprint_limit_t Reply_task_set_phys_footprint_limit; + __Reply__task_suspend2_t Reply_task_suspend2; + __Reply__task_resume2_t Reply_task_resume2; + __Reply__task_purgable_info_t Reply_task_purgable_info; + __Reply__task_get_mach_voucher_t Reply_task_get_mach_voucher; + __Reply__task_set_mach_voucher_t Reply_task_set_mach_voucher; + __Reply__task_swap_mach_voucher_t Reply_task_swap_mach_voucher; + __Reply__task_generate_corpse_t Reply_task_generate_corpse; + __Reply__task_map_corpse_info_t Reply_task_map_corpse_info; + __Reply__task_register_dyld_image_infos_t Reply_task_register_dyld_image_infos; + __Reply__task_unregister_dyld_image_infos_t Reply_task_unregister_dyld_image_infos; + __Reply__task_get_dyld_image_infos_t Reply_task_get_dyld_image_infos; + __Reply__task_register_dyld_shared_cache_image_info_t Reply_task_register_dyld_shared_cache_image_info; + __Reply__task_register_dyld_set_dyld_state_t Reply_task_register_dyld_set_dyld_state; + __Reply__task_register_dyld_get_process_state_t Reply_task_register_dyld_get_process_state; + __Reply__task_map_corpse_info_64_t Reply_task_map_corpse_info_64; + __Reply__task_inspect_t Reply_task_inspect; + __Reply__task_get_exc_guard_behavior_t Reply_task_get_exc_guard_behavior; + __Reply__task_set_exc_guard_behavior_t Reply_task_set_exc_guard_behavior; + __Reply__task_create_suid_cred_t Reply_task_create_suid_cred; +}; +#endif /* !__RequestUnion__task_subsystem__defined */ + +#ifndef subsystem_to_name_map_task +#define subsystem_to_name_map_task \ + { "task_create", 3400 },\ + { "task_terminate", 3401 },\ + { "task_threads", 3402 },\ + { "mach_ports_register", 3403 },\ + { "mach_ports_lookup", 3404 },\ + { "task_info", 3405 },\ + { "task_set_info", 3406 },\ + { "task_suspend", 3407 },\ + { "task_resume", 3408 },\ + { "task_get_special_port", 3409 },\ + { "task_set_special_port", 3410 },\ + { "thread_create", 3411 },\ + { "thread_create_running", 3412 },\ + { "task_set_exception_ports", 3413 },\ + { "task_get_exception_ports", 3414 },\ + { "task_swap_exception_ports", 3415 },\ + { "lock_set_create", 3416 },\ + { "lock_set_destroy", 3417 },\ + { "semaphore_create", 3418 },\ + { "semaphore_destroy", 3419 },\ + { "task_policy_set", 3420 },\ + { "task_policy_get", 3421 },\ + { "task_sample", 3422 },\ + { "task_policy", 3423 },\ + { "task_set_emulation", 3424 },\ + { "task_get_emulation_vector", 3425 },\ + { "task_set_emulation_vector", 3426 },\ + { "task_set_ras_pc", 3427 },\ + { "task_zone_info", 3428 },\ + { "task_assign", 3429 },\ + { "task_assign_default", 3430 },\ + { "task_get_assignment", 3431 },\ + { "task_set_policy", 3432 },\ + { "task_get_state", 3433 },\ + { "task_set_state", 3434 },\ + { "task_set_phys_footprint_limit", 3435 },\ + { "task_suspend2", 3436 },\ + { "task_resume2", 3437 },\ + { "task_purgable_info", 3438 },\ + { "task_get_mach_voucher", 3439 },\ + { "task_set_mach_voucher", 3440 },\ + { "task_swap_mach_voucher", 3441 },\ + { "task_generate_corpse", 3442 },\ + { "task_map_corpse_info", 3443 },\ + { "task_register_dyld_image_infos", 3444 },\ + { "task_unregister_dyld_image_infos", 3445 },\ + { "task_get_dyld_image_infos", 3446 },\ + { "task_register_dyld_shared_cache_image_info", 3447 },\ + { "task_register_dyld_set_dyld_state", 3448 },\ + { "task_register_dyld_get_process_state", 3449 },\ + { "task_map_corpse_info_64", 3450 },\ + { "task_inspect", 3451 },\ + { "task_get_exc_guard_behavior", 3452 },\ + { "task_set_exc_guard_behavior", 3453 },\ + { "task_create_suid_cred", 3454 } +#endif + +#ifdef __AfterMigUserHeader +__AfterMigUserHeader +#endif /* __AfterMigUserHeader */ + +#endif /* _task_user_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/task_access.defs b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/task_access.defs new file mode 100644 index 00000000..1696fd3c --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/task_access.defs @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ + +subsystem +#if KERNEL_USER + KernelUser +#endif /* KERN_USER */ + task_access 27000; + +#include +#include + +/* + * Verify task_for_pid access for the given pid + * Access granted by return value (success/failure) + */ +routine check_task_access( + task_access_port : mach_port_t; + calling_pid : int32_t; + calling_gid : uint32_t; + target_pid : int32_t; + ServerAuditToken caller_cred : audit_token_t); + +/* + * Search for a code signature for unsigned executables + */ +routine find_code_signature( + task_access_port : mach_port_t; + new_pid : int32_t); + +/* vim: set ft=c : */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/task_info.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/task_info.h new file mode 100644 index 00000000..86cfdb34 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/task_info.h @@ -0,0 +1,478 @@ +/* + * Copyright (c) 2000-2007, 2015 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * Machine-independent task information structures and definitions. + * + * The definitions in this file are exported to the user. The kernel + * will translate its internal data structures to these structures + * as appropriate. + * + */ + +#ifndef _MACH_TASK_INFO_H_ +#define _MACH_TASK_INFO_H_ + +#include +#include +#include +#include +#include /* for vm_extmod_statistics_data_t */ +#include + +#include + +/* + * Generic information structure to allow for expansion. + */ +typedef natural_t task_flavor_t; +typedef integer_t *task_info_t; /* varying array of int */ + +/* Deprecated, use per structure _data_t's instead */ +#define TASK_INFO_MAX (1024) /* maximum array size */ +typedef integer_t task_info_data_t[TASK_INFO_MAX]; + +/* + * Currently defined information structures. + */ + +#pragma pack(push, 4) + +/* Don't use this, use MACH_TASK_BASIC_INFO instead */ +#define TASK_BASIC_INFO_32 4 /* basic information */ +#define TASK_BASIC2_INFO_32 6 + +struct task_basic_info_32 { + integer_t suspend_count; /* suspend count for task */ + natural_t virtual_size; /* virtual memory size (bytes) */ + natural_t resident_size; /* resident memory size (bytes) */ + time_value_t user_time; /* total user run time for + * terminated threads */ + time_value_t system_time; /* total system run time for + * terminated threads */ + policy_t policy; /* default policy for new threads */ +}; +typedef struct task_basic_info_32 task_basic_info_32_data_t; +typedef struct task_basic_info_32 *task_basic_info_32_t; +#define TASK_BASIC_INFO_32_COUNT \ + (sizeof(task_basic_info_32_data_t) / sizeof(natural_t)) + +/* Don't use this, use MACH_TASK_BASIC_INFO instead */ +struct task_basic_info_64 { + integer_t suspend_count; /* suspend count for task */ + mach_vm_size_t virtual_size; /* virtual memory size (bytes) */ + mach_vm_size_t resident_size; /* resident memory size (bytes) */ + time_value_t user_time; /* total user run time for + * terminated threads */ + time_value_t system_time; /* total system run time for + * terminated threads */ + policy_t policy; /* default policy for new threads */ +}; +typedef struct task_basic_info_64 task_basic_info_64_data_t; +typedef struct task_basic_info_64 *task_basic_info_64_t; + +#define TASK_BASIC_INFO_64 5 /* 64-bit capable basic info */ +#define TASK_BASIC_INFO_64_COUNT \ + (sizeof(task_basic_info_64_data_t) / sizeof(natural_t)) + + +/* localized structure - cannot be safely passed between tasks of differing sizes */ +/* Don't use this, use MACH_TASK_BASIC_INFO instead */ +struct task_basic_info { + integer_t suspend_count; /* suspend count for task */ + vm_size_t virtual_size; /* virtual memory size (bytes) */ + vm_size_t resident_size; /* resident memory size (bytes) */ + time_value_t user_time; /* total user run time for + * terminated threads */ + time_value_t system_time; /* total system run time for + * terminated threads */ + policy_t policy; /* default policy for new threads */ +}; + +typedef struct task_basic_info task_basic_info_data_t; +typedef struct task_basic_info *task_basic_info_t; +#define TASK_BASIC_INFO_COUNT \ + (sizeof(task_basic_info_data_t) / sizeof(natural_t)) +#if !defined(__LP64__) +#define TASK_BASIC_INFO TASK_BASIC_INFO_32 +#else +#define TASK_BASIC_INFO TASK_BASIC_INFO_64 +#endif + + + +#define TASK_EVENTS_INFO 2 /* various event counts */ + +struct task_events_info { + integer_t faults; /* number of page faults */ + integer_t pageins; /* number of actual pageins */ + integer_t cow_faults; /* number of copy-on-write faults */ + integer_t messages_sent; /* number of messages sent */ + integer_t messages_received; /* number of messages received */ + integer_t syscalls_mach; /* number of mach system calls */ + integer_t syscalls_unix; /* number of unix system calls */ + integer_t csw; /* number of context switches */ +}; +typedef struct task_events_info task_events_info_data_t; +typedef struct task_events_info *task_events_info_t; +#define TASK_EVENTS_INFO_COUNT ((mach_msg_type_number_t) \ + (sizeof(task_events_info_data_t) / sizeof(natural_t))) + +#define TASK_THREAD_TIMES_INFO 3 /* total times for live threads - + * only accurate if suspended */ + +struct task_thread_times_info { + time_value_t user_time; /* total user run time for + * live threads */ + time_value_t system_time; /* total system run time for + * live threads */ +}; + +typedef struct task_thread_times_info task_thread_times_info_data_t; +typedef struct task_thread_times_info *task_thread_times_info_t; +#define TASK_THREAD_TIMES_INFO_COUNT ((mach_msg_type_number_t) \ + (sizeof(task_thread_times_info_data_t) / sizeof(natural_t))) + +#define TASK_ABSOLUTETIME_INFO 1 + +struct task_absolutetime_info { + uint64_t total_user; + uint64_t total_system; + uint64_t threads_user; /* existing threads only */ + uint64_t threads_system; +}; + +typedef struct task_absolutetime_info task_absolutetime_info_data_t; +typedef struct task_absolutetime_info *task_absolutetime_info_t; +#define TASK_ABSOLUTETIME_INFO_COUNT ((mach_msg_type_number_t) \ + (sizeof (task_absolutetime_info_data_t) / sizeof (natural_t))) + +#define TASK_KERNELMEMORY_INFO 7 + +struct task_kernelmemory_info { + uint64_t total_palloc; /* private kernel mem alloc'ed */ + uint64_t total_pfree; /* private kernel mem freed */ + uint64_t total_salloc; /* shared kernel mem alloc'ed */ + uint64_t total_sfree; /* shared kernel mem freed */ +}; + +typedef struct task_kernelmemory_info task_kernelmemory_info_data_t; +typedef struct task_kernelmemory_info *task_kernelmemory_info_t; +#define TASK_KERNELMEMORY_INFO_COUNT ((mach_msg_type_number_t) \ + (sizeof (task_kernelmemory_info_data_t) / sizeof (natural_t))) + +#define TASK_SECURITY_TOKEN 13 +#define TASK_SECURITY_TOKEN_COUNT ((mach_msg_type_number_t) \ + (sizeof(security_token_t) / sizeof(natural_t))) + +#define TASK_AUDIT_TOKEN 15 +#define TASK_AUDIT_TOKEN_COUNT \ + (sizeof(audit_token_t) / sizeof(natural_t)) + + +#define TASK_AFFINITY_TAG_INFO 16 /* This is experimental. */ + +struct task_affinity_tag_info { + integer_t set_count; + integer_t min; + integer_t max; + integer_t task_count; +}; +typedef struct task_affinity_tag_info task_affinity_tag_info_data_t; +typedef struct task_affinity_tag_info *task_affinity_tag_info_t; +#define TASK_AFFINITY_TAG_INFO_COUNT \ + (sizeof(task_affinity_tag_info_data_t) / sizeof(natural_t)) + +#define TASK_DYLD_INFO 17 + +struct task_dyld_info { + mach_vm_address_t all_image_info_addr; + mach_vm_size_t all_image_info_size; + integer_t all_image_info_format; +}; +typedef struct task_dyld_info task_dyld_info_data_t; +typedef struct task_dyld_info *task_dyld_info_t; +#define TASK_DYLD_INFO_COUNT \ + (sizeof(task_dyld_info_data_t) / sizeof(natural_t)) +#define TASK_DYLD_ALL_IMAGE_INFO_32 0 /* format value */ +#define TASK_DYLD_ALL_IMAGE_INFO_64 1 /* format value */ + + +#define TASK_EXTMOD_INFO 19 + +struct task_extmod_info { + unsigned char task_uuid[16]; + vm_extmod_statistics_data_t extmod_statistics; +}; +typedef struct task_extmod_info task_extmod_info_data_t; +typedef struct task_extmod_info *task_extmod_info_t; +#define TASK_EXTMOD_INFO_COUNT \ + (sizeof(task_extmod_info_data_t) / sizeof(natural_t)) + + +#define MACH_TASK_BASIC_INFO 20 /* always 64-bit basic info */ +struct mach_task_basic_info { + mach_vm_size_t virtual_size; /* virtual memory size (bytes) */ + mach_vm_size_t resident_size; /* resident memory size (bytes) */ + mach_vm_size_t resident_size_max; /* maximum resident memory size (bytes) */ + time_value_t user_time; /* total user run time for + * terminated threads */ + time_value_t system_time; /* total system run time for + * terminated threads */ + policy_t policy; /* default policy for new threads */ + integer_t suspend_count; /* suspend count for task */ +}; +typedef struct mach_task_basic_info mach_task_basic_info_data_t; +typedef struct mach_task_basic_info *mach_task_basic_info_t; +#define MACH_TASK_BASIC_INFO_COUNT \ + (sizeof(mach_task_basic_info_data_t) / sizeof(natural_t)) + + +#define TASK_POWER_INFO 21 + +struct task_power_info { + uint64_t total_user; + uint64_t total_system; + uint64_t task_interrupt_wakeups; + uint64_t task_platform_idle_wakeups; + uint64_t task_timer_wakeups_bin_1; + uint64_t task_timer_wakeups_bin_2; +}; + +typedef struct task_power_info task_power_info_data_t; +typedef struct task_power_info *task_power_info_t; +#define TASK_POWER_INFO_COUNT ((mach_msg_type_number_t) \ + (sizeof (task_power_info_data_t) / sizeof (natural_t))) + + + +#define TASK_VM_INFO 22 +#define TASK_VM_INFO_PURGEABLE 23 +struct task_vm_info { + mach_vm_size_t virtual_size; /* virtual memory size (bytes) */ + integer_t region_count; /* number of memory regions */ + integer_t page_size; + mach_vm_size_t resident_size; /* resident memory size (bytes) */ + mach_vm_size_t resident_size_peak; /* peak resident size (bytes) */ + + mach_vm_size_t device; + mach_vm_size_t device_peak; + mach_vm_size_t internal; + mach_vm_size_t internal_peak; + mach_vm_size_t external; + mach_vm_size_t external_peak; + mach_vm_size_t reusable; + mach_vm_size_t reusable_peak; + mach_vm_size_t purgeable_volatile_pmap; + mach_vm_size_t purgeable_volatile_resident; + mach_vm_size_t purgeable_volatile_virtual; + mach_vm_size_t compressed; + mach_vm_size_t compressed_peak; + mach_vm_size_t compressed_lifetime; + + /* added for rev1 */ + mach_vm_size_t phys_footprint; + + /* added for rev2 */ + mach_vm_address_t min_address; + mach_vm_address_t max_address; + + /* added for rev3 */ + int64_t ledger_phys_footprint_peak; + int64_t ledger_purgeable_nonvolatile; + int64_t ledger_purgeable_novolatile_compressed; + int64_t ledger_purgeable_volatile; + int64_t ledger_purgeable_volatile_compressed; + int64_t ledger_tag_network_nonvolatile; + int64_t ledger_tag_network_nonvolatile_compressed; + int64_t ledger_tag_network_volatile; + int64_t ledger_tag_network_volatile_compressed; + int64_t ledger_tag_media_footprint; + int64_t ledger_tag_media_footprint_compressed; + int64_t ledger_tag_media_nofootprint; + int64_t ledger_tag_media_nofootprint_compressed; + int64_t ledger_tag_graphics_footprint; + int64_t ledger_tag_graphics_footprint_compressed; + int64_t ledger_tag_graphics_nofootprint; + int64_t ledger_tag_graphics_nofootprint_compressed; + int64_t ledger_tag_neural_footprint; + int64_t ledger_tag_neural_footprint_compressed; + int64_t ledger_tag_neural_nofootprint; + int64_t ledger_tag_neural_nofootprint_compressed; + + /* added for rev4 */ + uint64_t limit_bytes_remaining; + + /* added for rev5 */ + integer_t decompressions; +}; +typedef struct task_vm_info task_vm_info_data_t; +typedef struct task_vm_info *task_vm_info_t; +#define TASK_VM_INFO_COUNT ((mach_msg_type_number_t) \ + (sizeof (task_vm_info_data_t) / sizeof (natural_t))) +#define TASK_VM_INFO_REV5_COUNT TASK_VM_INFO_COUNT +#define TASK_VM_INFO_REV4_COUNT /* doesn't include decompressions */ \ + ((mach_msg_type_number_t) (TASK_VM_INFO_REV5_COUNT - 1)) +#define TASK_VM_INFO_REV3_COUNT /* doesn't include limit bytes */ \ + ((mach_msg_type_number_t) (TASK_VM_INFO_REV4_COUNT - 2)) +#define TASK_VM_INFO_REV2_COUNT /* doesn't include extra ledgers info */ \ + ((mach_msg_type_number_t) (TASK_VM_INFO_REV3_COUNT - 42)) +#define TASK_VM_INFO_REV1_COUNT /* doesn't include min and max address */ \ + ((mach_msg_type_number_t) (TASK_VM_INFO_REV2_COUNT - 4)) +#define TASK_VM_INFO_REV0_COUNT /* doesn't include phys_footprint */ \ + ((mach_msg_type_number_t) (TASK_VM_INFO_REV1_COUNT - 2)) + +typedef struct vm_purgeable_info task_purgable_info_t; + + +#define TASK_TRACE_MEMORY_INFO 24 +struct task_trace_memory_info { + uint64_t user_memory_address; /* address of start of trace memory buffer */ + uint64_t buffer_size; /* size of buffer in bytes */ + uint64_t mailbox_array_size; /* size of mailbox area in bytes */ +}; +typedef struct task_trace_memory_info task_trace_memory_info_data_t; +typedef struct task_trace_memory_info * task_trace_memory_info_t; +#define TASK_TRACE_MEMORY_INFO_COUNT ((mach_msg_type_number_t) \ + (sizeof(task_trace_memory_info_data_t) / sizeof(natural_t))) + +#define TASK_WAIT_STATE_INFO 25 /* deprecated. */ +struct task_wait_state_info { + uint64_t total_wait_state_time; /* Time that all threads past and present have been in a wait state */ + uint64_t total_wait_sfi_state_time; /* Time that threads have been in SFI wait (should be a subset of total wait state time */ + uint32_t _reserved[4]; +}; +typedef struct task_wait_state_info task_wait_state_info_data_t; +typedef struct task_wait_state_info * task_wait_state_info_t; +#define TASK_WAIT_STATE_INFO_COUNT ((mach_msg_type_number_t) \ + (sizeof(task_wait_state_info_data_t) / sizeof(natural_t))) + +#define TASK_POWER_INFO_V2 26 + +typedef struct { + uint64_t task_gpu_utilisation; + uint64_t task_gpu_stat_reserved0; + uint64_t task_gpu_stat_reserved1; + uint64_t task_gpu_stat_reserved2; +} gpu_energy_data; + +typedef gpu_energy_data *gpu_energy_data_t; +struct task_power_info_v2 { + task_power_info_data_t cpu_energy; + gpu_energy_data gpu_energy; + uint64_t task_ptime; + uint64_t task_pset_switches; +}; + +typedef struct task_power_info_v2 task_power_info_v2_data_t; +typedef struct task_power_info_v2 *task_power_info_v2_t; +#define TASK_POWER_INFO_V2_COUNT_OLD \ + ((mach_msg_type_number_t) (sizeof (task_power_info_v2_data_t) - sizeof(uint64_t)*2) / sizeof (natural_t)) +#define TASK_POWER_INFO_V2_COUNT \ + ((mach_msg_type_number_t) (sizeof (task_power_info_v2_data_t) / sizeof (natural_t))) + +#define TASK_VM_INFO_PURGEABLE_ACCOUNT 27 /* Used for xnu purgeable vm unit tests */ + + +#define TASK_FLAGS_INFO 28 /* return t_flags field */ +struct task_flags_info { + uint32_t flags; /* task flags */ +}; +typedef struct task_flags_info task_flags_info_data_t; +typedef struct task_flags_info * task_flags_info_t; +#define TASK_FLAGS_INFO_COUNT ((mach_msg_type_number_t) \ + (sizeof(task_flags_info_data_t) / sizeof (natural_t))) + +#define TF_LP64 0x00000001 /* task has 64-bit addressing */ +#define TF_64B_DATA 0x00000002 /* task has 64-bit data registers */ + +#define TASK_DEBUG_INFO_INTERNAL 29 /* Used for kernel internal development tests. */ + + +/* + * Type to control EXC_GUARD delivery options for a task + * via task_get/set_exc_guard_behavior interface(s). + */ +typedef uint32_t task_exc_guard_behavior_t; + +/* EXC_GUARD optional delivery settings on a per-task basis */ +#define TASK_EXC_GUARD_VM_DELIVER 0x01 /* Deliver virtual memory EXC_GUARD exceptions */ +#define TASK_EXC_GUARD_VM_ONCE 0x02 /* Deliver them only once */ +#define TASK_EXC_GUARD_VM_CORPSE 0x04 /* Deliver them via a forked corpse */ +#define TASK_EXC_GUARD_VM_FATAL 0x08 /* Virtual Memory EXC_GUARD delivery is fatal */ +#define TASK_EXC_GUARD_VM_ALL 0x0f + +#define TASK_EXC_GUARD_MP_DELIVER 0x10 /* Deliver mach port EXC_GUARD exceptions */ +#define TASK_EXC_GUARD_MP_ONCE 0x20 /* Deliver them only once */ +#define TASK_EXC_GUARD_MP_CORPSE 0x40 /* Deliver them via a forked corpse */ +#define TASK_EXC_GUARD_MP_FATAL 0x80 /* mach port EXC_GUARD delivery is fatal */ +#define TASK_EXC_GUARD_MP_ALL 0xf0 + +#define TASK_EXC_GUARD_ALL 0xff /* All optional deliver settings */ + + +/* + * Obsolete interfaces. + */ + +#define TASK_SCHED_TIMESHARE_INFO 10 +#define TASK_SCHED_RR_INFO 11 +#define TASK_SCHED_FIFO_INFO 12 + +#define TASK_SCHED_INFO 14 + +#pragma pack(pop) + +#endif /* _MACH_TASK_INFO_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/task_inspect.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/task_inspect.h new file mode 100644 index 00000000..b13310f7 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/task_inspect.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2017 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef MACH_TASK_INSPECT_H +#define MACH_TASK_INSPECT_H + +/* + * XXX These interfaces are still in development -- they are subject to change + * without notice. + */ + +typedef natural_t task_inspect_flavor_t; + +enum task_inspect_flavor { + TASK_INSPECT_BASIC_COUNTS = 1, +}; + +struct task_inspect_basic_counts { + uint64_t instructions; + uint64_t cycles; +}; +#define TASK_INSPECT_BASIC_COUNTS_COUNT \ + (sizeof(struct task_inspect_basic_counts) / sizeof(natural_t)) +typedef struct task_inspect_basic_counts task_inspect_basic_counts_data_t; +typedef struct task_inspect_basic_counts *task_inspect_basic_counts_t; + +typedef integer_t *task_inspect_info_t; + +#endif /* !defined(MACH_TASK_INSPECT_H) */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/task_policy.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/task_policy.h new file mode 100644 index 00000000..04970a5b --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/task_policy.h @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2000-2005 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _MACH_TASK_POLICY_H_ +#define _MACH_TASK_POLICY_H_ + +#include + +/* + * These are the calls for accessing the policy parameters + * of a particular task. + * + * The extra 'get_default' parameter to the second call is + * IN/OUT as follows: + * 1) if asserted on the way in it indicates that the default + * values should be returned, not the ones currently set, in + * this case 'get_default' will always be asserted on return; + * 2) if unasserted on the way in, the current settings are + * desired and if still unasserted on return, then the info + * returned reflects the current settings, otherwise if + * 'get_default' returns asserted, it means that there are no + * current settings due to other parameters taking precedence, + * and the default ones are being returned instead. + */ + +typedef natural_t task_policy_flavor_t; +typedef integer_t *task_policy_t; + +/* + * kern_return_t task_policy_set( + * task_t task, + * task_policy_flavor_t flavor, + * task_policy_t policy_info, + * mach_msg_type_number_t count); + * + * kern_return_t task_policy_get( + * task_t task, + * task_policy_flavor_t flavor, + * task_policy_t policy_info, + * mach_msg_type_number_t *count, + * boolean_t *get_default); + */ + +/* + * Defined flavors. + */ +/* + * TASK_CATEGORY_POLICY: + * + * This provides information to the kernel about the role + * of the task in the system. + * + * Parameters: + * + * role: Enumerated as follows: + * + * TASK_UNSPECIFIED is the default, since the role is not + * inherited from the parent. + * + * TASK_FOREGROUND_APPLICATION should be assigned when the + * task is a normal UI application in the foreground from + * the HI point of view. + * **N.B. There may be more than one of these at a given time. + * + * TASK_BACKGROUND_APPLICATION should be assigned when the + * task is a normal UI application in the background from + * the HI point of view. + * + * TASK_CONTROL_APPLICATION should be assigned to the unique + * UI application which implements the pop-up application dialog. + * There can only be one task at a time with this designation, + * which is assigned FCFS. + * + * TASK_GRAPHICS_SERVER should be assigned to the graphics + * management (window) server. There can only be one task at + * a time with this designation, which is assigned FCFS. + */ + +#define TASK_CATEGORY_POLICY 1 + +#define TASK_SUPPRESSION_POLICY 3 +#define TASK_POLICY_STATE 4 +#define TASK_BASE_QOS_POLICY 8 +#define TASK_OVERRIDE_QOS_POLICY 9 +#define TASK_BASE_LATENCY_QOS_POLICY 10 +#define TASK_BASE_THROUGHPUT_QOS_POLICY 11 + + +enum task_role { + TASK_RENICED = -1, + TASK_UNSPECIFIED = 0, + TASK_FOREGROUND_APPLICATION = 1, + TASK_BACKGROUND_APPLICATION = 2, + TASK_CONTROL_APPLICATION = 3, + TASK_GRAPHICS_SERVER = 4, + TASK_THROTTLE_APPLICATION = 5, + TASK_NONUI_APPLICATION = 6, + TASK_DEFAULT_APPLICATION = 7, + TASK_DARWINBG_APPLICATION = 8, +}; + +typedef integer_t task_role_t; + +struct task_category_policy { + task_role_t role; +}; + +typedef struct task_category_policy task_category_policy_data_t; +typedef struct task_category_policy *task_category_policy_t; + +#define TASK_CATEGORY_POLICY_COUNT ((mach_msg_type_number_t) \ + (sizeof (task_category_policy_data_t) / sizeof (integer_t))) + + +enum task_latency_qos { + LATENCY_QOS_TIER_UNSPECIFIED = 0x0, + LATENCY_QOS_TIER_0 = ((0xFF << 16) | 1), + LATENCY_QOS_TIER_1 = ((0xFF << 16) | 2), + LATENCY_QOS_TIER_2 = ((0xFF << 16) | 3), + LATENCY_QOS_TIER_3 = ((0xFF << 16) | 4), + LATENCY_QOS_TIER_4 = ((0xFF << 16) | 5), + LATENCY_QOS_TIER_5 = ((0xFF << 16) | 6) +}; +typedef integer_t task_latency_qos_t; +enum task_throughput_qos { + THROUGHPUT_QOS_TIER_UNSPECIFIED = 0x0, + THROUGHPUT_QOS_TIER_0 = ((0xFE << 16) | 1), + THROUGHPUT_QOS_TIER_1 = ((0xFE << 16) | 2), + THROUGHPUT_QOS_TIER_2 = ((0xFE << 16) | 3), + THROUGHPUT_QOS_TIER_3 = ((0xFE << 16) | 4), + THROUGHPUT_QOS_TIER_4 = ((0xFE << 16) | 5), + THROUGHPUT_QOS_TIER_5 = ((0xFE << 16) | 6), +}; + +#define LATENCY_QOS_LAUNCH_DEFAULT_TIER LATENCY_QOS_TIER_3 +#define THROUGHPUT_QOS_LAUNCH_DEFAULT_TIER THROUGHPUT_QOS_TIER_3 + +typedef integer_t task_throughput_qos_t; + +struct task_qos_policy { + task_latency_qos_t task_latency_qos_tier; + task_throughput_qos_t task_throughput_qos_tier; +}; + +typedef struct task_qos_policy *task_qos_policy_t; +#define TASK_QOS_POLICY_COUNT ((mach_msg_type_number_t) \ + (sizeof (struct task_qos_policy) / sizeof (integer_t))) + +/* These should be removed - they belong in proc_info.h */ +#define PROC_FLAG_DARWINBG 0x8000 /* process in darwin background */ +#define PROC_FLAG_EXT_DARWINBG 0x10000 /* process in darwin background - external enforcement */ +#define PROC_FLAG_IOS_APPLEDAEMON 0x20000 /* process is apple ios daemon */ +#define PROC_FLAG_IOS_IMPPROMOTION 0x80000 /* process is apple ios daemon */ +#define PROC_FLAG_ADAPTIVE 0x100000 /* Process is adaptive */ +#define PROC_FLAG_ADAPTIVE_IMPORTANT 0x200000 /* Process is adaptive, and is currently important */ +#define PROC_FLAG_IMPORTANCE_DONOR 0x400000 /* Process is marked as an importance donor */ +#define PROC_FLAG_SUPPRESSED 0x800000 /* Process is suppressed */ +#define PROC_FLAG_APPLICATION 0x1000000 /* Process is an application */ +#define PROC_FLAG_IOS_APPLICATION PROC_FLAG_APPLICATION /* Process is an application */ + + + + +#endif /* _MACH_TASK_POLICY_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/task_special_ports.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/task_special_ports.h new file mode 100644 index 00000000..ded90941 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/task_special_ports.h @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2000-2010 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * File: mach/task_special_ports.h + * + * Defines codes for special_purpose task ports. These are NOT + * port identifiers - they are only used for the task_get_special_port + * and task_set_special_port routines. + * + */ + +#ifndef _MACH_TASK_SPECIAL_PORTS_H_ +#define _MACH_TASK_SPECIAL_PORTS_H_ + +typedef int task_special_port_t; + +#define TASK_KERNEL_PORT 1 /* Represents task to the outside + * world.*/ + +#define TASK_HOST_PORT 2 /* The host (priv) port for task. */ + +#define TASK_NAME_PORT 3 /* the name (unpriv) port for task */ + +#define TASK_BOOTSTRAP_PORT 4 /* Bootstrap environment for task. */ + +/* + * Evolving and likely to change. + */ + +#define TASK_SEATBELT_PORT 7 /* Seatbelt compiler/DEM port for task. */ + +/* PORT 8 was the GSSD TASK PORT which transformed to a host port */ + +#define TASK_ACCESS_PORT 9 /* Permission check for task_for_pid. */ + +#define TASK_DEBUG_CONTROL_PORT 10 /* debug control port */ + +#define TASK_RESOURCE_NOTIFY_PORT 11 /* overrides host special RN port */ + +#define TASK_MAX_SPECIAL_PORT TASK_RESOURCE_NOTIFY_PORT + +/* + * Definitions for ease of use + */ + +#define task_get_kernel_port(task, port) \ + (task_get_special_port((task), TASK_KERNEL_PORT, (port))) + +#define task_set_kernel_port(task, port) \ + (task_set_special_port((task), TASK_KERNEL_PORT, (port))) + +#define task_get_host_port(task, port) \ + (task_get_special_port((task), TASK_HOST_PORT, (port))) + +#define task_set_host_port(task, port) \ + (task_set_special_port((task), TASK_HOST_PORT, (port))) + +#define task_get_bootstrap_port(task, port) \ + (task_get_special_port((task), TASK_BOOTSTRAP_PORT, (port))) + +#define task_get_debug_control_port(task, port) \ + (task_get_special_port((task), TASK_DEBUG_CONTROL_PORT, (port))) + +#define task_set_bootstrap_port(task, port) \ + (task_set_special_port((task), TASK_BOOTSTRAP_PORT, (port))) + +#define task_get_task_access_port(task, port) \ + (task_get_special_port((task), TASK_ACCESS_PORT, (port))) + +#define task_set_task_access_port(task, port) \ + (task_set_special_port((task), TASK_ACCESS_PORT, (port))) + +#define task_set_task_debug_control_port(task, port) \ + (task_set_special_port((task), TASK_DEBUG_CONTROL_PORT, (port))) + + +#endif /* _MACH_TASK_SPECIAL_PORTS_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/telemetry_notification.defs b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/telemetry_notification.defs new file mode 100644 index 00000000..4b9f8a59 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/telemetry_notification.defs @@ -0,0 +1,20 @@ +/* + * Copyright (c) 2012, Apple Inc. All rights reserved. + */ + + /* + * Interface definition for the telemetry facility. + */ + +subsystem +#if KERNEL_USER + KernelUser +#endif /* KERNEL_USER */ + telemetry_notification 5100; + +#include +#include + +simpleroutine telemetry_notification( + RequestPort telemetry_port : mach_port_t; + in flags : uint32_t); diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/thread_act.defs b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/thread_act.defs new file mode 100644 index 00000000..205fff54 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/thread_act.defs @@ -0,0 +1,367 @@ +/* + * Copyright (c) 2000-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_FREE_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * File: mach/mach_port.defs + * Author: Rich Draves + * + * Exported kernel calls. + */ + +subsystem +#if KERNEL_SERVER + KernelServer +#endif /* KERNEL_SERVER */ + thread_act 3600; + +#include +#include + +#if !KERNEL && !LIBSYSCALL_INTERFACE +#define PREFIX(NAME) _kernelrpc_ ## NAME +#else +#define PREFIX(NAME) NAME +#endif + +/* + * Destroy the target thread. + * + * JMM - For legacy reasons this consumes a reference to the + * target thread. This will have to change in the future because + * we want the interfaces to be able to be defined in more standard + * IDLs and transports, and most of them do not support the notion + * of reference ownership transfers (just sharing). + */ +routine thread_terminate( + target_act : thread_act_consume_ref_t); + + +/* + * Return the selected state information for the target + * thr_act. If the thr_act is currently executing, the results + * may be stale. [Flavor THREAD_STATE_FLAVOR_LIST provides a + * list of valid flavors for the target thread.] + */ +routine +#ifdef KERNEL_SERVER +act_get_state_to_user( +#else +act_get_state( +#endif + target_act : thread_act_t; + flavor : int; + out old_state : thread_state_t, CountInOut); + +/* + * Set the selected state information for the target thread. + * If the thread is currently executing, the state change + * may be ill-defined. + */ +routine +#ifdef KERNEL_SERVER +act_set_state_from_user( +#else +act_set_state( +#endif + target_act : thread_act_t; + flavor : int; + new_state : thread_state_t); + +/* + * Backward compatible old-style thread routines. + * These have different semantics than the new activation versions. + * + * Return the selected state information for the target + * thread. If the thread is currently executing, the results + * may be stale. [Flavor THREAD_STATE_FLAVOR_LIST provides a + * list of valid flavors for the target thr_act.] + */ +routine +#ifdef KERNEL_SERVER +thread_get_state_to_user( +#else +thread_get_state( +#endif + target_act : thread_act_t; + flavor : thread_state_flavor_t; + out old_state : thread_state_t, CountInOut); + +/* + * Set the selected state information for the target thread. + * If the thread is currently executing, the state change + * may be ill-defined. + */ +routine +#ifdef KERNEL_SERVER +thread_set_state_from_user( +#else +thread_set_state( +#endif + target_act : thread_act_t; + flavor : thread_state_flavor_t; + new_state : thread_state_t); + +/* + * Increment the suspend count for the target thread. + * Once this call has completed, the thread will not + * execute any further user or meta- instructions. + * Once suspended, a thread may not execute again until + * its suspend count is zero, and the suspend count + * for its task is also zero. + */ +routine thread_suspend( + target_act : thread_act_t); + +/* + * Decrement the suspend count for the target thread, + * if that count is not already zero. + */ +routine thread_resume( + target_act : thread_act_t); + +/* + * Cause any user or meta- instructions currently being + * executed by the target thread to be aborted. [Meta- + * instructions consist of the basic traps for IPC + * (e.g., msg_send, msg_receive) and self-identification + * (e.g., task_self, thread_self, thread_reply). Calls + * described by MiG interfaces are not meta-instructions + * themselves.] + */ +routine thread_abort( + target_act : thread_act_t); + +/* + * Cause any user or meta- instructions currently being + * executed by the target thread to be aborted so that + * they are transparently restartable. This call fails + * if the abort would result in a non-restartable condition. + * Retry is the caller's responsibility. [Meta- + * instructions consist of the basic traps for IPC + * (e.g., msg_send, msg_receive) and self-identification + * (e.g., task_self, thread_self, thread_reply). Calls + * described by MiG interfaces are not meta-instructions + * themselves.] + */ +routine thread_abort_safely( + target_act : thread_act_t); + + +routine +#ifdef KERNEL_SERVER +thread_depress_abort_from_user( +#else +thread_depress_abort( +#endif + thread : thread_act_t); + + +/* + * Returns the current value of the selected special port + * associated with the target thread. + */ +routine thread_get_special_port( + thr_act : thread_act_t; + which_port : int; + out special_port : mach_port_t); + +/* + * Set one of the special ports associated with the + * target thread. + */ +routine thread_set_special_port( + thr_act : thread_act_t; + which_port : int; + special_port : mach_port_t); + +/* + * Returns information about the target thread. + */ +routine thread_info( + target_act : thread_inspect_t; + flavor : thread_flavor_t; + out thread_info_out : thread_info_t, CountInOut); + +/* + * Set an exception handler for a thread on one or more exception types + */ +routine thread_set_exception_ports( + thread : thread_act_t; + exception_mask : exception_mask_t; + new_port : mach_port_t; + behavior : exception_behavior_t; + new_flavor : thread_state_flavor_t); + +/* + * Lookup some of the old exception handlers for a thread + */ +routine thread_get_exception_ports( + thread : thread_inspect_t; + exception_mask : exception_mask_t; + out masks : exception_mask_array_t; + out old_handlers : exception_handler_array_t, SameCount; + out old_behaviors : exception_behavior_array_t, SameCount; + out old_flavors : exception_flavor_array_t, SameCount); + +/* + * Set an exception handler for a thread on one or more exception types. + * At the same time, return the previously defined exception handlers for + * those types. + */ +routine thread_swap_exception_ports( + thread : thread_act_t; + exception_mask : exception_mask_t; + new_port : mach_port_t; + behavior : exception_behavior_t; + new_flavor : thread_state_flavor_t; + out masks : exception_mask_array_t; + out old_handlers : exception_handler_array_t, SameCount; + out old_behaviors : exception_behavior_array_t, SameCount; + out old_flavors : exception_flavor_array_t, SameCount); + +/* + * OBSOLETE interface. + */ +routine PREFIX(thread_policy)( + thr_act : thread_act_t; + policy : policy_t; + base : policy_base_t; + set_limit : boolean_t); + +/* + * Set/get policy information for a thread. + * (Approved Mac OS X microkernel interface) + */ + +routine PREFIX(thread_policy_set)( + thread : thread_act_t; + flavor : thread_policy_flavor_t; + policy_info : thread_policy_t); + +routine thread_policy_get( + thread : thread_inspect_t; + flavor : thread_policy_flavor_t; +out policy_info : thread_policy_t, CountInOut; +inout get_default : boolean_t); + +/* + * Removed from the kernel. + */ +#if KERNEL_SERVER +skip; +#else +routine thread_sample( + thread : thread_act_t; + reply : mach_port_make_send_t); +#endif + +/* + * ETAP has been removed from the kernel. + */ +#if KERNEL_SERVER +skip; +#else +routine etap_trace_thread( + target_act : thread_act_t; + trace_status : boolean_t); +#endif + +/* + * Assign thread to processor set. + */ +routine thread_assign( + thread : thread_act_t; + new_set : processor_set_t); + +/* + * Assign thread to default set. + */ +routine thread_assign_default( + thread : thread_act_t); + +/* + * Get current assignment for thread. + */ +routine thread_get_assignment( + thread : thread_act_t; + out assigned_set : processor_set_name_t); + +/* + * OBSOLETE interface. + */ +routine PREFIX(thread_set_policy)( + thr_act : thread_act_t; + pset : processor_set_t; + policy : policy_t; + base : policy_base_t; + limit : policy_limit_t); + +routine thread_get_mach_voucher( + thr_act : thread_act_t; + which : mach_voucher_selector_t; + out voucher : ipc_voucher_t); + +routine thread_set_mach_voucher( + thr_act : thread_act_t; + voucher : ipc_voucher_t); + +routine thread_swap_mach_voucher( + thr_act : thread_act_t; + new_voucher : ipc_voucher_t; + inout old_voucher : ipc_voucher_t); + +/* vim: set ft=c : */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/thread_act.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/thread_act.h new file mode 100644 index 00000000..5a21aa7e --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/thread_act.h @@ -0,0 +1,1336 @@ +#ifndef _thread_act_user_ +#define _thread_act_user_ + +/* Module thread_act */ + +#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 thread_act_MSG_COUNT +#define thread_act_MSG_COUNT 28 +#endif /* thread_act_MSG_COUNT */ + +#include +#include +#include +#include + +#ifdef __BeforeMigUserHeader +__BeforeMigUserHeader +#endif /* __BeforeMigUserHeader */ + +#include +__BEGIN_DECLS + + +/* Routine thread_terminate */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t thread_terminate +( + thread_act_t target_act +); + +/* Routine act_get_state */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t act_get_state +( + thread_act_t target_act, + int flavor, + thread_state_t old_state, + mach_msg_type_number_t *old_stateCnt +); + +/* Routine act_set_state */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t act_set_state +( + thread_act_t target_act, + int flavor, + thread_state_t new_state, + mach_msg_type_number_t new_stateCnt +); + +/* Routine thread_get_state */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +kern_return_t thread_get_state +( + thread_act_t target_act, + thread_state_flavor_t flavor, + thread_state_t old_state, + mach_msg_type_number_t *old_stateCnt +); + +/* Routine thread_set_state */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +kern_return_t thread_set_state +( + thread_act_t target_act, + thread_state_flavor_t flavor, + thread_state_t new_state, + mach_msg_type_number_t new_stateCnt +); + +/* Routine thread_suspend */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +kern_return_t thread_suspend +( + thread_act_t target_act +); + +/* Routine thread_resume */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +kern_return_t thread_resume +( + thread_act_t target_act +); + +/* Routine thread_abort */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +kern_return_t thread_abort +( + thread_act_t target_act +); + +/* Routine thread_abort_safely */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +kern_return_t thread_abort_safely +( + thread_act_t target_act +); + +/* Routine thread_depress_abort */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t thread_depress_abort +( + thread_act_t thread +); + +/* Routine thread_get_special_port */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t thread_get_special_port +( + thread_act_t thr_act, + int which_port, + mach_port_t *special_port +); + +/* Routine thread_set_special_port */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t thread_set_special_port +( + thread_act_t thr_act, + int which_port, + mach_port_t special_port +); + +/* Routine thread_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t thread_info +( + thread_inspect_t target_act, + thread_flavor_t flavor, + thread_info_t thread_info_out, + mach_msg_type_number_t *thread_info_outCnt +); + +/* Routine thread_set_exception_ports */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t thread_set_exception_ports +( + thread_act_t thread, + exception_mask_t exception_mask, + mach_port_t new_port, + exception_behavior_t behavior, + thread_state_flavor_t new_flavor +); + +/* Routine thread_get_exception_ports */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t thread_get_exception_ports +( + thread_inspect_t thread, + exception_mask_t exception_mask, + exception_mask_array_t masks, + mach_msg_type_number_t *masksCnt, + exception_handler_array_t old_handlers, + exception_behavior_array_t old_behaviors, + exception_flavor_array_t old_flavors +); + +/* Routine thread_swap_exception_ports */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t thread_swap_exception_ports +( + thread_act_t thread, + exception_mask_t exception_mask, + mach_port_t new_port, + exception_behavior_t behavior, + thread_state_flavor_t new_flavor, + exception_mask_array_t masks, + mach_msg_type_number_t *masksCnt, + exception_handler_array_t old_handlers, + exception_behavior_array_t old_behaviors, + exception_flavor_array_t old_flavors +); + +/* Routine thread_policy */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t thread_policy +( + thread_act_t thr_act, + policy_t policy, + policy_base_t base, + mach_msg_type_number_t baseCnt, + boolean_t set_limit +); + +/* Routine thread_policy_set */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t thread_policy_set +( + thread_act_t thread, + thread_policy_flavor_t flavor, + thread_policy_t policy_info, + mach_msg_type_number_t policy_infoCnt +); + +/* Routine thread_policy_get */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t thread_policy_get +( + thread_inspect_t thread, + thread_policy_flavor_t flavor, + thread_policy_t policy_info, + mach_msg_type_number_t *policy_infoCnt, + boolean_t *get_default +); + +/* Routine thread_sample */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t thread_sample +( + thread_act_t thread, + mach_port_t reply +); + +/* Routine etap_trace_thread */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t etap_trace_thread +( + thread_act_t target_act, + boolean_t trace_status +); + +/* Routine thread_assign */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t thread_assign +( + thread_act_t thread, + processor_set_t new_set +); + +/* Routine thread_assign_default */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t thread_assign_default +( + thread_act_t thread +); + +/* Routine thread_get_assignment */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t thread_get_assignment +( + thread_act_t thread, + processor_set_name_t *assigned_set +); + +/* Routine thread_set_policy */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t thread_set_policy +( + thread_act_t thr_act, + processor_set_t pset, + policy_t policy, + policy_base_t base, + mach_msg_type_number_t baseCnt, + policy_limit_t limit, + mach_msg_type_number_t limitCnt +); + +/* Routine thread_get_mach_voucher */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t thread_get_mach_voucher +( + thread_act_t thr_act, + mach_voucher_selector_t which, + ipc_voucher_t *voucher +); + +/* Routine thread_set_mach_voucher */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t thread_set_mach_voucher +( + thread_act_t thr_act, + ipc_voucher_t voucher +); + +/* Routine thread_swap_mach_voucher */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t thread_swap_mach_voucher +( + thread_act_t thr_act, + ipc_voucher_t new_voucher, + ipc_voucher_t *old_voucher +); + +__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__thread_act_subsystem__defined +#define __Request__thread_act_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__thread_terminate_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int flavor; + mach_msg_type_number_t old_stateCnt; + } __Request__act_get_state_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[614]; + } __Request__act_set_state_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + thread_state_flavor_t flavor; + mach_msg_type_number_t old_stateCnt; + } __Request__thread_get_state_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + thread_state_flavor_t flavor; + mach_msg_type_number_t new_stateCnt; + natural_t new_state[614]; + } __Request__thread_set_state_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__thread_suspend_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__thread_resume_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__thread_abort_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__thread_abort_safely_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__thread_depress_abort_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + int which_port; + } __Request__thread_get_special_port_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 special_port; + /* end of the kernel processed data */ + NDR_record_t NDR; + int which_port; + } __Request__thread_set_special_port_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + thread_flavor_t flavor; + mach_msg_type_number_t thread_info_outCnt; + } __Request__thread_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 new_port; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_mask_t exception_mask; + exception_behavior_t behavior; + thread_state_flavor_t new_flavor; + } __Request__thread_set_exception_ports_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + exception_mask_t exception_mask; + } __Request__thread_get_exception_ports_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 new_port; + /* end of the kernel processed data */ + NDR_record_t NDR; + exception_mask_t exception_mask; + exception_behavior_t behavior; + thread_state_flavor_t new_flavor; + } __Request__thread_swap_exception_ports_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + policy_t policy; + mach_msg_type_number_t baseCnt; + integer_t base[5]; + boolean_t set_limit; + } __Request__thread_policy_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + thread_policy_flavor_t flavor; + mach_msg_type_number_t policy_infoCnt; + integer_t policy_info[16]; + } __Request__thread_policy_set_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + thread_policy_flavor_t flavor; + mach_msg_type_number_t policy_infoCnt; + boolean_t get_default; + } __Request__thread_policy_get_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 reply; + /* end of the kernel processed data */ + } __Request__thread_sample_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + boolean_t trace_status; + } __Request__etap_trace_thread_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 new_set; + /* end of the kernel processed data */ + } __Request__thread_assign_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__thread_assign_default_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__thread_get_assignment_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 pset; + /* end of the kernel processed data */ + NDR_record_t NDR; + policy_t policy; + mach_msg_type_number_t baseCnt; + integer_t base[5]; + mach_msg_type_number_t limitCnt; + integer_t limit[1]; + } __Request__thread_set_policy_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + mach_voucher_selector_t which; + } __Request__thread_get_mach_voucher_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 voucher; + /* end of the kernel processed data */ + } __Request__thread_set_mach_voucher_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 new_voucher; + mach_msg_port_descriptor_t old_voucher; + /* end of the kernel processed data */ + } __Request__thread_swap_mach_voucher_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Request__thread_act_subsystem__defined */ + +/* union of all requests */ + +#ifndef __RequestUnion__thread_act_subsystem__defined +#define __RequestUnion__thread_act_subsystem__defined +union __RequestUnion__thread_act_subsystem { + __Request__thread_terminate_t Request_thread_terminate; + __Request__act_get_state_t Request_act_get_state; + __Request__act_set_state_t Request_act_set_state; + __Request__thread_get_state_t Request_thread_get_state; + __Request__thread_set_state_t Request_thread_set_state; + __Request__thread_suspend_t Request_thread_suspend; + __Request__thread_resume_t Request_thread_resume; + __Request__thread_abort_t Request_thread_abort; + __Request__thread_abort_safely_t Request_thread_abort_safely; + __Request__thread_depress_abort_t Request_thread_depress_abort; + __Request__thread_get_special_port_t Request_thread_get_special_port; + __Request__thread_set_special_port_t Request_thread_set_special_port; + __Request__thread_info_t Request_thread_info; + __Request__thread_set_exception_ports_t Request_thread_set_exception_ports; + __Request__thread_get_exception_ports_t Request_thread_get_exception_ports; + __Request__thread_swap_exception_ports_t Request_thread_swap_exception_ports; + __Request__thread_policy_t Request_thread_policy; + __Request__thread_policy_set_t Request_thread_policy_set; + __Request__thread_policy_get_t Request_thread_policy_get; + __Request__thread_sample_t Request_thread_sample; + __Request__etap_trace_thread_t Request_etap_trace_thread; + __Request__thread_assign_t Request_thread_assign; + __Request__thread_assign_default_t Request_thread_assign_default; + __Request__thread_get_assignment_t Request_thread_get_assignment; + __Request__thread_set_policy_t Request_thread_set_policy; + __Request__thread_get_mach_voucher_t Request_thread_get_mach_voucher; + __Request__thread_set_mach_voucher_t Request_thread_set_mach_voucher; + __Request__thread_swap_mach_voucher_t Request_thread_swap_mach_voucher; +}; +#endif /* !__RequestUnion__thread_act_subsystem__defined */ +/* typedefs for all replies */ + +#ifndef __Reply__thread_act_subsystem__defined +#define __Reply__thread_act_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__thread_terminate_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[614]; + } __Reply__act_get_state_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__act_set_state_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t old_stateCnt; + natural_t old_state[614]; + } __Reply__thread_get_state_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__thread_set_state_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__thread_suspend_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__thread_resume_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__thread_abort_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__thread_abort_safely_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__thread_depress_abort_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 special_port; + /* end of the kernel processed data */ + } __Reply__thread_get_special_port_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__thread_set_special_port_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t thread_info_outCnt; + integer_t thread_info_out[32]; + } __Reply__thread_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__thread_set_exception_ports_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 old_handlers[32]; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t masksCnt; + exception_mask_t masks[32]; + exception_behavior_t old_behaviors[32]; + thread_state_flavor_t old_flavors[32]; + } __Reply__thread_get_exception_ports_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 old_handlers[32]; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t masksCnt; + exception_mask_t masks[32]; + exception_behavior_t old_behaviors[32]; + thread_state_flavor_t old_flavors[32]; + } __Reply__thread_swap_exception_ports_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__thread_policy_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__thread_policy_set_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_msg_type_number_t policy_infoCnt; + integer_t policy_info[16]; + boolean_t get_default; + } __Reply__thread_policy_get_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__thread_sample_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__etap_trace_thread_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__thread_assign_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__thread_assign_default_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 assigned_set; + /* end of the kernel processed data */ + } __Reply__thread_get_assignment_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__thread_set_policy_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 voucher; + /* end of the kernel processed data */ + } __Reply__thread_get_mach_voucher_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__thread_set_mach_voucher_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 old_voucher; + /* end of the kernel processed data */ + } __Reply__thread_swap_mach_voucher_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Reply__thread_act_subsystem__defined */ + +/* union of all replies */ + +#ifndef __ReplyUnion__thread_act_subsystem__defined +#define __ReplyUnion__thread_act_subsystem__defined +union __ReplyUnion__thread_act_subsystem { + __Reply__thread_terminate_t Reply_thread_terminate; + __Reply__act_get_state_t Reply_act_get_state; + __Reply__act_set_state_t Reply_act_set_state; + __Reply__thread_get_state_t Reply_thread_get_state; + __Reply__thread_set_state_t Reply_thread_set_state; + __Reply__thread_suspend_t Reply_thread_suspend; + __Reply__thread_resume_t Reply_thread_resume; + __Reply__thread_abort_t Reply_thread_abort; + __Reply__thread_abort_safely_t Reply_thread_abort_safely; + __Reply__thread_depress_abort_t Reply_thread_depress_abort; + __Reply__thread_get_special_port_t Reply_thread_get_special_port; + __Reply__thread_set_special_port_t Reply_thread_set_special_port; + __Reply__thread_info_t Reply_thread_info; + __Reply__thread_set_exception_ports_t Reply_thread_set_exception_ports; + __Reply__thread_get_exception_ports_t Reply_thread_get_exception_ports; + __Reply__thread_swap_exception_ports_t Reply_thread_swap_exception_ports; + __Reply__thread_policy_t Reply_thread_policy; + __Reply__thread_policy_set_t Reply_thread_policy_set; + __Reply__thread_policy_get_t Reply_thread_policy_get; + __Reply__thread_sample_t Reply_thread_sample; + __Reply__etap_trace_thread_t Reply_etap_trace_thread; + __Reply__thread_assign_t Reply_thread_assign; + __Reply__thread_assign_default_t Reply_thread_assign_default; + __Reply__thread_get_assignment_t Reply_thread_get_assignment; + __Reply__thread_set_policy_t Reply_thread_set_policy; + __Reply__thread_get_mach_voucher_t Reply_thread_get_mach_voucher; + __Reply__thread_set_mach_voucher_t Reply_thread_set_mach_voucher; + __Reply__thread_swap_mach_voucher_t Reply_thread_swap_mach_voucher; +}; +#endif /* !__RequestUnion__thread_act_subsystem__defined */ + +#ifndef subsystem_to_name_map_thread_act +#define subsystem_to_name_map_thread_act \ + { "thread_terminate", 3600 },\ + { "act_get_state", 3601 },\ + { "act_set_state", 3602 },\ + { "thread_get_state", 3603 },\ + { "thread_set_state", 3604 },\ + { "thread_suspend", 3605 },\ + { "thread_resume", 3606 },\ + { "thread_abort", 3607 },\ + { "thread_abort_safely", 3608 },\ + { "thread_depress_abort", 3609 },\ + { "thread_get_special_port", 3610 },\ + { "thread_set_special_port", 3611 },\ + { "thread_info", 3612 },\ + { "thread_set_exception_ports", 3613 },\ + { "thread_get_exception_ports", 3614 },\ + { "thread_swap_exception_ports", 3615 },\ + { "thread_policy", 3616 },\ + { "thread_policy_set", 3617 },\ + { "thread_policy_get", 3618 },\ + { "thread_sample", 3619 },\ + { "etap_trace_thread", 3620 },\ + { "thread_assign", 3621 },\ + { "thread_assign_default", 3622 },\ + { "thread_get_assignment", 3623 },\ + { "thread_set_policy", 3624 },\ + { "thread_get_mach_voucher", 3625 },\ + { "thread_set_mach_voucher", 3626 },\ + { "thread_swap_mach_voucher", 3627 } +#endif + +#ifdef __AfterMigUserHeader +__AfterMigUserHeader +#endif /* __AfterMigUserHeader */ + +#endif /* _thread_act_user_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/thread_info.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/thread_info.h new file mode 100644 index 00000000..c31a27b0 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/thread_info.h @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2000-2005, 2015 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * File: mach/thread_info + * + * Thread information structure and definitions. + * + * The defintions in this file are exported to the user. The kernel + * will translate its internal data structures to these structures + * as appropriate. + * + */ + +#ifndef _MACH_THREAD_INFO_H_ +#define _MACH_THREAD_INFO_H_ + +#include +#include +#include +#include +#include + +/* + * Generic information structure to allow for expansion. + */ +typedef natural_t thread_flavor_t; +typedef integer_t *thread_info_t; /* varying array of int */ + +#define THREAD_INFO_MAX (32) /* maximum array size */ +typedef integer_t thread_info_data_t[THREAD_INFO_MAX]; + +/* + * Currently defined information. + */ +#define THREAD_BASIC_INFO 3 /* basic information */ + +struct thread_basic_info { + time_value_t user_time; /* user run time */ + time_value_t system_time; /* system run time */ + integer_t cpu_usage; /* scaled cpu usage percentage */ + policy_t policy; /* scheduling policy in effect */ + integer_t run_state; /* run state (see below) */ + integer_t flags; /* various flags (see below) */ + integer_t suspend_count; /* suspend count for thread */ + integer_t sleep_time; /* number of seconds that thread + * has been sleeping */ +}; + +typedef struct thread_basic_info thread_basic_info_data_t; +typedef struct thread_basic_info *thread_basic_info_t; +#define THREAD_BASIC_INFO_COUNT ((mach_msg_type_number_t) \ + (sizeof(thread_basic_info_data_t) / sizeof(natural_t))) + +#define THREAD_IDENTIFIER_INFO 4 /* thread id and other information */ + +struct thread_identifier_info { + uint64_t thread_id; /* system-wide unique 64-bit thread id */ + uint64_t thread_handle; /* handle to be used by libproc */ + uint64_t dispatch_qaddr; /* libdispatch queue address */ +}; + +typedef struct thread_identifier_info thread_identifier_info_data_t; +typedef struct thread_identifier_info *thread_identifier_info_t; +#define THREAD_IDENTIFIER_INFO_COUNT ((mach_msg_type_number_t) \ + (sizeof(thread_identifier_info_data_t) / sizeof(natural_t))) + +/* + * Scale factor for usage field. + */ + +#define TH_USAGE_SCALE 1000 + +/* + * Thread run states (state field). + */ + +#define TH_STATE_RUNNING 1 /* thread is running normally */ +#define TH_STATE_STOPPED 2 /* thread is stopped */ +#define TH_STATE_WAITING 3 /* thread is waiting normally */ +#define TH_STATE_UNINTERRUPTIBLE 4 /* thread is in an uninterruptible + * wait */ +#define TH_STATE_HALTED 5 /* thread is halted at a + * clean point */ + +/* + * Thread flags (flags field). + */ +#define TH_FLAGS_SWAPPED 0x1 /* thread is swapped out */ +#define TH_FLAGS_IDLE 0x2 /* thread is an idle thread */ +#define TH_FLAGS_GLOBAL_FORCED_IDLE 0x4 /* thread performs global forced idle */ + +/* + * Thread extended info (returns same info as proc_pidinfo(...,PROC_PIDTHREADINFO,...) + */ +#define THREAD_EXTENDED_INFO 5 +#define MAXTHREADNAMESIZE 64 +struct thread_extended_info { // same as proc_threadinfo (from proc_info.h) & proc_threadinfo_internal (from bsd_taskinfo.h) + uint64_t pth_user_time; /* user run time */ + uint64_t pth_system_time; /* system run time */ + int32_t pth_cpu_usage; /* scaled cpu usage percentage */ + int32_t pth_policy; /* scheduling policy in effect */ + int32_t pth_run_state; /* run state (see below) */ + int32_t pth_flags; /* various flags (see below) */ + int32_t pth_sleep_time; /* number of seconds that thread */ + int32_t pth_curpri; /* cur priority*/ + int32_t pth_priority; /* priority*/ + int32_t pth_maxpriority; /* max priority*/ + char pth_name[MAXTHREADNAMESIZE]; /* thread name, if any */ +}; +typedef struct thread_extended_info thread_extended_info_data_t; +typedef struct thread_extended_info * thread_extended_info_t; +#define THREAD_EXTENDED_INFO_COUNT ((mach_msg_type_number_t) \ + (sizeof(thread_extended_info_data_t) / sizeof (natural_t))) + +#define THREAD_DEBUG_INFO_INTERNAL 6 /* for kernel development internal info */ + + +#define IO_NUM_PRIORITIES 4 + +#define UPDATE_IO_STATS(info, size) \ +{ \ + info.count++; \ + info.size += size; \ +} + +#define UPDATE_IO_STATS_ATOMIC(info, io_size) \ +{ \ + OSIncrementAtomic64((SInt64 *)&(info.count)); \ + OSAddAtomic64(io_size, (SInt64 *)&(info.size)); \ +} + +struct io_stat_entry { + uint64_t count; + uint64_t size; +}; + +struct io_stat_info { + struct io_stat_entry disk_reads; + struct io_stat_entry io_priority[IO_NUM_PRIORITIES]; + struct io_stat_entry paging; + struct io_stat_entry metadata; + struct io_stat_entry total_io; +}; + +typedef struct io_stat_info *io_stat_info_t; + + +/* + * Obsolete interfaces. + */ + +#define THREAD_SCHED_TIMESHARE_INFO 10 +#define THREAD_SCHED_RR_INFO 11 +#define THREAD_SCHED_FIFO_INFO 12 + +#endif /* _MACH_THREAD_INFO_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/thread_policy.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/thread_policy.h new file mode 100644 index 00000000..d5c8c1ba --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/thread_policy.h @@ -0,0 +1,266 @@ +/* + * Copyright (c) 2000-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _MACH_THREAD_POLICY_H_ +#define _MACH_THREAD_POLICY_H_ + +#include + +/* + * These are the calls for accessing the policy parameters + * of a particular thread. + * + * The extra 'get_default' parameter to the second call is + * IN/OUT as follows: + * 1) if asserted on the way in it indicates that the default + * values should be returned, not the ones currently set, in + * this case 'get_default' will always be asserted on return; + * 2) if unasserted on the way in, the current settings are + * desired and if still unasserted on return, then the info + * returned reflects the current settings, otherwise if + * 'get_default' returns asserted, it means that there are no + * current settings due to other parameters taking precedence, + * and the default ones are being returned instead. + */ + +typedef natural_t thread_policy_flavor_t; +typedef integer_t *thread_policy_t; + +/* + * kern_return_t thread_policy_set( + * thread_t thread, + * thread_policy_flavor_t flavor, + * thread_policy_t policy_info, + * mach_msg_type_number_t count); + * + * kern_return_t thread_policy_get( + * thread_t thread, + * thread_policy_flavor_t flavor, + * thread_policy_t policy_info, + * mach_msg_type_number_t *count, + * boolean_t *get_default); + */ + +/* + * Defined flavors. + */ +/* + * THREAD_STANDARD_POLICY: + * + * This is the standard (fair) scheduling mode, assigned to new + * threads. The thread will be given processor time in a manner + * which apportions approximately equal share to long running + * computations. + * + * Parameters: + * [none] + */ + +#define THREAD_STANDARD_POLICY 1 + +struct thread_standard_policy { + natural_t no_data; +}; + +typedef struct thread_standard_policy thread_standard_policy_data_t; +typedef struct thread_standard_policy *thread_standard_policy_t; + +#define THREAD_STANDARD_POLICY_COUNT 0 + +/* + * THREAD_EXTENDED_POLICY: + * + * Extended form of THREAD_STANDARD_POLICY, which supplies a + * hint indicating whether this is a long running computation. + * + * Parameters: + * + * timeshare: TRUE (the default) results in identical scheduling + * behavior as THREAD_STANDARD_POLICY. + */ + +#define THREAD_EXTENDED_POLICY 1 + +struct thread_extended_policy { + boolean_t timeshare; +}; + +typedef struct thread_extended_policy thread_extended_policy_data_t; +typedef struct thread_extended_policy *thread_extended_policy_t; + +#define THREAD_EXTENDED_POLICY_COUNT ((mach_msg_type_number_t) \ + (sizeof (thread_extended_policy_data_t) / sizeof (integer_t))) + +/* + * THREAD_TIME_CONSTRAINT_POLICY: + * + * This scheduling mode is for threads which have real time + * constraints on their execution. + * + * Parameters: + * + * period: This is the nominal amount of time between separate + * processing arrivals, specified in absolute time units. A + * value of 0 indicates that there is no inherent periodicity in + * the computation. + * + * computation: This is the nominal amount of computation + * time needed during a separate processing arrival, specified + * in absolute time units. + * + * constraint: This is the maximum amount of real time that + * may elapse from the start of a separate processing arrival + * to the end of computation for logically correct functioning, + * specified in absolute time units. Must be (>= computation). + * Note that latency = (constraint - computation). + * + * preemptible: This indicates that the computation may be + * interrupted, subject to the constraint specified above. + */ + +#define THREAD_TIME_CONSTRAINT_POLICY 2 + +struct thread_time_constraint_policy { + uint32_t period; + uint32_t computation; + uint32_t constraint; + boolean_t preemptible; +}; + +typedef struct thread_time_constraint_policy \ + thread_time_constraint_policy_data_t; +typedef struct thread_time_constraint_policy \ + *thread_time_constraint_policy_t; + +#define THREAD_TIME_CONSTRAINT_POLICY_COUNT ((mach_msg_type_number_t) \ + (sizeof (thread_time_constraint_policy_data_t) / sizeof (integer_t))) + +/* + * THREAD_PRECEDENCE_POLICY: + * + * This may be used to indicate the relative value of the + * computation compared to the other threads in the task. + * + * Parameters: + * + * importance: The importance is specified as a signed value. + */ + +#define THREAD_PRECEDENCE_POLICY 3 + +struct thread_precedence_policy { + integer_t importance; +}; + +typedef struct thread_precedence_policy thread_precedence_policy_data_t; +typedef struct thread_precedence_policy *thread_precedence_policy_t; + +#define THREAD_PRECEDENCE_POLICY_COUNT ((mach_msg_type_number_t) \ + (sizeof (thread_precedence_policy_data_t) / sizeof (integer_t))) + +/* + * THREAD_AFFINITY_POLICY: + * + * This policy is experimental. + * This may be used to express affinity relationships + * between threads in the task. Threads with the same affinity tag will + * be scheduled to share an L2 cache if possible. That is, affinity tags + * are a hint to the scheduler for thread placement. + * + * The namespace of affinity tags is generally local to one task. However, + * a child task created after the assignment of affinity tags by its parent + * will share that namespace. In particular, a family of forked processes + * may be created with a shared affinity namespace. + * + * Parameters: + * tag: The affinity set identifier. + */ + +#define THREAD_AFFINITY_POLICY 4 + +struct thread_affinity_policy { + integer_t affinity_tag; +}; + +#define THREAD_AFFINITY_TAG_NULL 0 + +typedef struct thread_affinity_policy thread_affinity_policy_data_t; +typedef struct thread_affinity_policy *thread_affinity_policy_t; + +#define THREAD_AFFINITY_POLICY_COUNT ((mach_msg_type_number_t) \ + (sizeof (thread_affinity_policy_data_t) / sizeof (integer_t))) + +/* + * THREAD_BACKGROUND_POLICY: + */ + +#define THREAD_BACKGROUND_POLICY 5 + +struct thread_background_policy { + integer_t priority; +}; + +#define THREAD_BACKGROUND_POLICY_DARWIN_BG 0x1000 + +typedef struct thread_background_policy thread_background_policy_data_t; +typedef struct thread_background_policy *thread_background_policy_t; + +#define THREAD_BACKGROUND_POLICY_COUNT ((mach_msg_type_number_t) \ + (sizeof (thread_background_policy_data_t) / sizeof (integer_t))) + + +#define THREAD_LATENCY_QOS_POLICY 7 +typedef integer_t thread_latency_qos_t; + +struct thread_latency_qos_policy { + thread_latency_qos_t thread_latency_qos_tier; +}; + +typedef struct thread_latency_qos_policy thread_latency_qos_policy_data_t; +typedef struct thread_latency_qos_policy *thread_latency_qos_policy_t; + +#define THREAD_LATENCY_QOS_POLICY_COUNT ((mach_msg_type_number_t) \ + (sizeof (thread_latency_qos_policy_data_t) / sizeof (integer_t))) + +#define THREAD_THROUGHPUT_QOS_POLICY 8 +typedef integer_t thread_throughput_qos_t; + +struct thread_throughput_qos_policy { + thread_throughput_qos_t thread_throughput_qos_tier; +}; + +typedef struct thread_throughput_qos_policy thread_throughput_qos_policy_data_t; +typedef struct thread_throughput_qos_policy *thread_throughput_qos_policy_t; + +#define THREAD_THROUGHPUT_QOS_POLICY_COUNT ((mach_msg_type_number_t) \ + (sizeof (thread_throughput_qos_policy_data_t) / sizeof (integer_t))) + + + + +#endif /* _MACH_THREAD_POLICY_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/thread_special_ports.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/thread_special_ports.h new file mode 100644 index 00000000..02199835 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/thread_special_ports.h @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * File: mach/thread_special_ports.h + * + * Defines codes for special_purpose thread ports. These are NOT + * port identifiers - they are only used for the thread_get_special_port + * and thread_set_special_port routines. + * + */ + +#ifndef _MACH_THREAD_SPECIAL_PORTS_H_ +#define _MACH_THREAD_SPECIAL_PORTS_H_ + +#define THREAD_KERNEL_PORT 1 /* Represents the thread to the outside + * world.*/ + +/* + * Definitions for ease of use + */ + +#define thread_get_kernel_port(thread, port) \ + (thread_get_special_port((thread), THREAD_KERNEL_PORT, (port))) + +#define thread_set_kernel_port(thread, port) \ + (thread_set_special_port((thread), THREAD_KERNEL_PORT, (port))) + +#endif /* _MACH_THREAD_SPECIAL_PORTS_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/thread_state.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/thread_state.h new file mode 100644 index 00000000..77b492e1 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/thread_state.h @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2015 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _MACH_THREAD_STATE_H_ +#define _MACH_THREAD_STATE_H_ + +#include +#include + +#ifndef KERNEL +/* + * Gets all register values in the target thread with pointer-like contents. + * + * There is no guarantee that the returned values are valid pointers, but all + * valid pointers will be returned. The order and count of the provided + * register values is unspecified and may change; registers with values that + * are not valid pointers may be omitted, so the number of pointers returned + * may vary from call to call. + * + * sp is an out parameter that will contain the stack pointer. + * length is an in/out parameter for the length of the values array. + * values is an array of pointers. + * + * This may only be called on threads in the current task. If the current + * platform defines a stack red zone, the stack pointer returned will be + * adjusted to account for red zone. + * + * If length is insufficient, KERN_INSUFFICIENT_BUFFER_SIZE will be returned + * and length set to the amount of memory required. Callers MUST NOT assume + * that any particular size of buffer will be sufficient and should retry with + * an appropriately sized buffer upon this error. + */ +__API_AVAILABLE(macosx(10.14), ios(12.0), tvos(9.0), watchos(5.0)) +kern_return_t thread_get_register_pointer_values(thread_t thread, + uintptr_t *sp, size_t *length, uintptr_t *values); +#endif + +#endif /* _MACH_THREAD_STATE_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/thread_status.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/thread_status.h new file mode 100644 index 00000000..a91b936e --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/thread_status.h @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * File: mach/thread_status.h + * Author: Avadis Tevanian, Jr. + * + * This file contains the structure definitions for the user-visible + * thread state. This thread state is examined with the thread_get_state + * kernel call and may be changed with the thread_set_state kernel call. + * + */ + +#ifndef _MACH_THREAD_STATUS_H_ +#define _MACH_THREAD_STATUS_H_ + +/* + * The actual structure that comprises the thread state is defined + * in the machine dependent module. + */ +#include +#include +#include + +/* + * Generic definition for machine-dependent thread status. + */ + +typedef natural_t *thread_state_t; /* Variable-length array */ + +/* THREAD_STATE_MAX is now defined in */ +typedef natural_t thread_state_data_t[THREAD_STATE_MAX]; + +#define THREAD_STATE_FLAVOR_LIST 0 /* List of valid flavors */ +#define THREAD_STATE_FLAVOR_LIST_NEW 128 +#define THREAD_STATE_FLAVOR_LIST_10_9 129 +#define THREAD_STATE_FLAVOR_LIST_10_13 130 +#define THREAD_STATE_FLAVOR_LIST_10_15 131 + +typedef int thread_state_flavor_t; +typedef thread_state_flavor_t *thread_state_flavor_array_t; + +#endif /* _MACH_THREAD_STATUS_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/thread_switch.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/thread_switch.h new file mode 100644 index 00000000..4ac56bfa --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/thread_switch.h @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ + +#ifndef _MACH_THREAD_SWITCH_H_ +#define _MACH_THREAD_SWITCH_H_ + +#include +#include +#include +#include + +/* + * Constant definitions for thread_switch trap. + */ + +#define SWITCH_OPTION_NONE 0 +#define SWITCH_OPTION_DEPRESS 1 +#define SWITCH_OPTION_WAIT 2 + +#define valid_switch_option(opt) (0 <= (opt) && (opt) <= 5) + +#endif /* _MACH_THREAD_SWITCH_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/time_value.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/time_value.h new file mode 100644 index 00000000..8cfd37d7 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/time_value.h @@ -0,0 +1,96 @@ +/* + * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ + +#ifndef _MACH_TIME_VALUE_H_ +#define _MACH_TIME_VALUE_H_ + +#include + +/* + * Time value returned by kernel. + */ + +struct time_value { + integer_t seconds; + integer_t microseconds; +}; + +typedef struct time_value time_value_t; + +/* + * Macros to manipulate time values. Assume that time values + * are normalized (microseconds <= 999999). + */ +#define TIME_MICROS_MAX (1000000) + +#define time_value_add_usec(val, micros) { \ + if (((val)->microseconds += (micros)) \ + >= TIME_MICROS_MAX) { \ + (val)->microseconds -= TIME_MICROS_MAX; \ + (val)->seconds++; \ + } \ +} + +#define time_value_add(result, addend) { \ + (result)->microseconds += (addend)->microseconds; \ + (result)->seconds += (addend)->seconds; \ + if ((result)->microseconds >= TIME_MICROS_MAX) { \ + (result)->microseconds -= TIME_MICROS_MAX; \ + (result)->seconds++; \ + } \ +} + +#endif /* _MACH_TIME_VALUE_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/vm_attributes.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/vm_attributes.h new file mode 100644 index 00000000..bac0993c --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/vm_attributes.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * File: mach/vm_attributes.h + * Author: Alessandro Forin + * + * Virtual memory attributes definitions. + * + * These definitions are in addition to the machine-independent + * ones (e.g. protection), and are only selectively supported + * on specific machine architectures. + * + */ + +#ifndef _MACH_VM_ATTRIBUTES_H_ +#define _MACH_VM_ATTRIBUTES_H_ + +/* + * Types of machine-dependent attributes + */ +typedef unsigned int vm_machine_attribute_t; + +#define MATTR_CACHE 1 /* cachability */ +#define MATTR_MIGRATE 2 /* migrability */ +#define MATTR_REPLICATE 4 /* replicability */ + +/* + * Values for the above, e.g. operations on attribute + */ +typedef int vm_machine_attribute_val_t; + +#define MATTR_VAL_OFF 0 /* (generic) turn attribute off */ +#define MATTR_VAL_ON 1 /* (generic) turn attribute on */ +#define MATTR_VAL_GET 2 /* (generic) return current value */ + +#define MATTR_VAL_CACHE_FLUSH 6 /* flush from all caches */ +#define MATTR_VAL_DCACHE_FLUSH 7 /* flush from data caches */ +#define MATTR_VAL_ICACHE_FLUSH 8 /* flush from instruction caches */ +#define MATTR_VAL_CACHE_SYNC 9 /* sync I+D caches */ +#define MATTR_VAL_CACHE_SYNC 9 /* sync I+D caches */ + +#define MATTR_VAL_GET_INFO 10 /* get page info (stats) */ + +#endif /* _MACH_VM_ATTRIBUTES_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/vm_behavior.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/vm_behavior.h new file mode 100644 index 00000000..727980d5 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/vm_behavior.h @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * File: mach/vm_behavior.h + * + * Virtual memory map behavior definitions. + * + */ + +#ifndef _MACH_VM_BEHAVIOR_H_ +#define _MACH_VM_BEHAVIOR_H_ + +/* + * Types defined: + * + * vm_behavior_t behavior codes. + */ + +typedef int vm_behavior_t; + +/* + * Enumeration of valid values for vm_behavior_t. + * These describe expected page reference behavior for + * for a given range of virtual memory. For implementation + * details see vm/vm_fault.c + */ + + +/* + * The following behaviors affect the memory region's future behavior + * and are stored in the VM map entry data structure. + */ +#define VM_BEHAVIOR_DEFAULT ((vm_behavior_t) 0) /* default */ +#define VM_BEHAVIOR_RANDOM ((vm_behavior_t) 1) /* random */ +#define VM_BEHAVIOR_SEQUENTIAL ((vm_behavior_t) 2) /* forward sequential */ +#define VM_BEHAVIOR_RSEQNTL ((vm_behavior_t) 3) /* reverse sequential */ + +/* + * The following "behaviors" affect the memory region only at the time of the + * call and are not stored in the VM map entry. + */ +#define VM_BEHAVIOR_WILLNEED ((vm_behavior_t) 4) /* will need in near future */ +#define VM_BEHAVIOR_DONTNEED ((vm_behavior_t) 5) /* dont need in near future */ +#define VM_BEHAVIOR_FREE ((vm_behavior_t) 6) /* free memory without write-back */ +#define VM_BEHAVIOR_ZERO_WIRED_PAGES ((vm_behavior_t) 7) /* zero out the wired pages of an entry if it is being deleted without unwiring them first */ +#define VM_BEHAVIOR_REUSABLE ((vm_behavior_t) 8) +#define VM_BEHAVIOR_REUSE ((vm_behavior_t) 9) +#define VM_BEHAVIOR_CAN_REUSE ((vm_behavior_t) 10) +#define VM_BEHAVIOR_PAGEOUT ((vm_behavior_t) 11) + +#endif /*_MACH_VM_BEHAVIOR_H_*/ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/vm_inherit.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/vm_inherit.h new file mode 100644 index 00000000..528d6917 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/vm_inherit.h @@ -0,0 +1,89 @@ +/* + * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * File: mach/vm_inherit.h + * Author: Avadis Tevanian, Jr., Michael Wayne Young + * + * Virtual memory map inheritance definitions. + * + */ + +#ifndef _MACH_VM_INHERIT_H_ +#define _MACH_VM_INHERIT_H_ + +/* + * Types defined: + * + * vm_inherit_t inheritance codes. + */ + +typedef unsigned int vm_inherit_t; /* might want to change this */ + +/* + * Enumeration of valid values for vm_inherit_t. + */ + +#define VM_INHERIT_SHARE ((vm_inherit_t) 0) /* share with child */ +#define VM_INHERIT_COPY ((vm_inherit_t) 1) /* copy into child */ +#define VM_INHERIT_NONE ((vm_inherit_t) 2) /* absent from child */ +#define VM_INHERIT_DONATE_COPY ((vm_inherit_t) 3) /* copy and delete */ + +#define VM_INHERIT_DEFAULT VM_INHERIT_COPY +#define VM_INHERIT_LAST_VALID VM_INHERIT_NONE + +#endif /* _MACH_VM_INHERIT_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/vm_map.defs b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/vm_map.defs new file mode 100644 index 00000000..7caa9263 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/vm_map.defs @@ -0,0 +1,510 @@ +/* + * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_FREE_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * File: mach/vm_map.defs + * + * Exported (native-sized) kernel VM calls. + */ + +subsystem +#if KERNEL_SERVER + KernelServer +#endif /* KERNEL_SERVER */ + vm_map 3800; + +#include +#include +#include + +#define CONCAT(a,b) a ## b +#if !KERNEL && !LIBSYSCALL_INTERFACE +#define PREFIX(NAME) CONCAT(_kernelrpc_, NAME) +#else +#define PREFIX(NAME) NAME +#endif + +#if KERNEL_SERVER +#define KERNEL_SERVER_SUFFIX(NAME) CONCAT(NAME, _external) +#else +#define KERNEL_SERVER_SUFFIX(NAME) NAME +#endif + +/* + * Returns information about the contents of the virtual + * address space of the target task at the specified + * address. The returned protection, inheritance, sharing + * and memory object values apply to the entire range described + * by the address range returned; the memory object offset + * corresponds to the beginning of the address range. + * [If the specified address is not allocated, the next + * highest address range is described. If no addresses beyond + * the one specified are allocated, the call returns KERN_NO_SPACE.] + */ +routine vm_region( + target_task : vm_map_t; + inout address : vm_address_t; + out size : vm_size_t; + flavor : vm_region_flavor_t; + out info : vm_region_info_t, CountInOut; + out object_name : memory_object_name_t = + MACH_MSG_TYPE_MOVE_SEND + ctype: mach_port_t); + +/* + * Allocate zero-filled memory in the address space + * of the target task, either at the specified address, + * or wherever space can be found (if anywhere is TRUE), + * of the specified size. The address at which the + * allocation actually took place is returned. + */ + +#if !KERNEL && !LIBSYSCALL_INTERFACE +skip; +#else +routine PREFIX(KERNEL_SERVER_SUFFIX(vm_allocate))( + target_task : vm_task_entry_t; + inout address : vm_address_t; + size : vm_size_t; + flags : int); + +#endif + +/* + * Deallocate the specified range from the virtual + * address space of the target task. + */ + +#if !KERNEL && !LIBSYSCALL_INTERFACE +skip; +#else +routine PREFIX(vm_deallocate)( + target_task : vm_task_entry_t; + address : vm_address_t; + size : vm_size_t); + +#endif + +/* + * Set the current or maximum protection attribute + * for the specified range of the virtual address + * space of the target task. The current protection + * limits the memory access rights of threads within + * the task; the maximum protection limits the accesses + * that may be given in the current protection. + * Protections are specified as a set of {read, write, execute} + * *permissions*. + */ + +#if !KERNEL && !LIBSYSCALL_INTERFACE +skip; +#else +routine PREFIX(vm_protect)( + target_task : vm_task_entry_t; + address : vm_address_t; + size : vm_size_t; + set_maximum : boolean_t; + new_protection : vm_prot_t); +#endif + +/* + * Set the inheritance attribute for the specified range + * of the virtual address space of the target task. + * The inheritance value is one of {none, copy, share}, and + * specifies how the child address space should acquire + * this memory at the time of a task_create call. + */ +routine vm_inherit( + target_task : vm_task_entry_t; + address : vm_address_t; + size : vm_size_t; + new_inheritance : vm_inherit_t); + +/* + * Returns the contents of the specified range of the + * virtual address space of the target task. [The + * range must be aligned on a virtual page boundary, + * and must be a multiple of pages in extent. The + * protection on the specified range must permit reading.] + */ +routine PREFIX(vm_read) ( + target_task : vm_map_t; + address : vm_address_t; + size : vm_size_t; + out data : pointer_t); + +/* + * List corrollary to vm_read, returns mapped contents of specified + * ranges within target address space. + */ +routine vm_read_list( + target_task : vm_map_t; + inout data_list : vm_read_entry_t; + count : natural_t); + +/* + * Writes the contents of the specified range of the + * virtual address space of the target task. [The + * range must be aligned on a virtual page boundary, + * and must be a multiple of pages in extent. The + * protection on the specified range must permit writing.] + */ +routine vm_write( + target_task : vm_map_t; + address : vm_address_t; + data : pointer_t); + +/* + * Copy the contents of the source range of the virtual + * address space of the target task to the destination + * range in that same address space. [Both of the + * ranges must be aligned on a virtual page boundary, + * and must be multiples of pages in extent. The + * protection on the source range must permit reading, + * and the protection on the destination range must + * permit writing.] + */ +routine vm_copy( + target_task : vm_map_t; + source_address : vm_address_t; + size : vm_size_t; + dest_address : vm_address_t); + +/* + * Returns the contents of the specified range of the + * virtual address space of the target task. [There + * are no alignment restrictions, and the results will + * overwrite the area pointed to by data - which must + * already exist. The protection on the specified range + * must permit reading.] + */ +routine vm_read_overwrite( + target_task : vm_map_t; + address : vm_address_t; + size : vm_size_t; + data : vm_address_t; + out outsize : vm_size_t); + + +routine vm_msync( + target_task : vm_map_t; + address : vm_address_t; + size : vm_size_t; + sync_flags : vm_sync_t ); + +/* + * Set the paging behavior attribute for the specified range + * of the virtual address space of the target task. + * The behavior value is one of {default, random, forward + * sequential, reverse sequential} and indicates the expected + * page reference pattern for the specified range. + */ +routine vm_behavior_set( + target_task : vm_map_t; + address : vm_address_t; + size : vm_size_t; + new_behavior : vm_behavior_t); + + +/* + * Map a user-defined memory object into the virtual address + * space of the target task. If desired (anywhere is TRUE), + * the kernel will find a suitable address range of the + * specified size; else, the specific address will be allocated. + * + * The beginning address of the range will be aligned on a virtual + * page boundary, be at or beyond the address specified, and + * meet the mask requirements (bits turned on in the mask must not + * be turned on in the result); the size of the range, in bytes, + * will be rounded up to an integral number of virtual pages. + * + * The memory in the resulting range will be associated with the + * specified memory object, with the beginning of the memory range + * referring to the specified offset into the memory object. + * + * The mapping will take the current and maximum protections and + * the inheritance attributes specified; see the vm_protect and + * vm_inherit calls for a description of these attributes. + * + * If desired (copy is TRUE), the memory range will be filled + * with a copy of the data from the memory object; this copy will + * be private to this mapping in this target task. Otherwise, + * the memory in this mapping will be shared with other mappings + * of the same memory object at the same offset (in this task or + * in other tasks). [The Mach kernel only enforces shared memory + * consistency among mappings on one host with similar page alignments. + * The user-defined memory manager for this object is responsible + * for further consistency.] + */ +routine PREFIX(KERNEL_SERVER_SUFFIX(vm_map)) ( + target_task : vm_task_entry_t; + inout address : vm_address_t; + size : vm_size_t; + mask : vm_address_t; + flags : int; + object : mem_entry_name_port_t; + offset : vm_offset_t; + copy : boolean_t; + cur_protection : vm_prot_t; + max_protection : vm_prot_t; + inheritance : vm_inherit_t); + +/* + * Set/Get special properties of memory associated + * to some virtual address range, such as cachability, + * migrability, replicability. Machine-dependent. + */ +routine vm_machine_attribute( + target_task : vm_map_t; + address : vm_address_t; + size : vm_size_t; + attribute : vm_machine_attribute_t; + inout value : vm_machine_attribute_val_t); + +/* + * Map portion of a task's address space. + */ +routine PREFIX(KERNEL_SERVER_SUFFIX(vm_remap)) ( + target_task : vm_map_t; + inout target_address : vm_address_t; + size : vm_size_t; + mask : vm_address_t; + flags : int; + src_task : vm_map_t; + src_address : vm_address_t; + copy : boolean_t; + out cur_protection : vm_prot_t; + out max_protection : vm_prot_t; + inheritance : vm_inherit_t); + +/* + * Require that all future virtual memory allocation + * allocates wired memory. Setting must_wire to FALSE + * disables the wired future feature. + */ +routine task_wire( + target_task : vm_map_t; + must_wire : boolean_t); + + +/* + * Allow application level processes to create named entries which + * correspond to mapped portions of their address space. These named + * entries can then be manipulated, shared with other processes in + * other address spaces and ultimately mapped in ohter address spaces + */ + +routine mach_make_memory_entry( + target_task :vm_map_t; + inout size :vm_size_t; + offset :vm_offset_t; + permission :vm_prot_t; + out object_handle :mem_entry_name_port_move_send_t; + parent_entry :mem_entry_name_port_t); + +/* + * Give the caller information on the given location in a virtual + * address space. If a page is mapped return ref and dirty info. + */ +routine vm_map_page_query( + target_map :vm_map_t; + offset :vm_offset_t; + out disposition :integer_t; + out ref_count :integer_t); + +/* + * Returns information about a region of memory. + * Includes info about the chain of objects rooted at that region. + * Only available in MACH_VM_DEBUG compiled kernels, + * otherwise returns KERN_FAILURE. + */ +routine mach_vm_region_info( + task : vm_map_t; + address : vm_address_t; + out region : vm_info_region_t; + out objects : vm_info_object_array_t); + +routine vm_mapped_pages_info( + task : vm_map_t; + out pages : page_address_array_t); + +#if 0 +/* + * Allow application level processes to create named entries which + * are backed by sub-maps which describe regions of address space. + * These regions of space can have objects mapped into them and + * in turn, can be mapped into target address spaces + */ + +routine vm_region_object_create( + target_task :vm_map_t; + in size :vm_size_t; + out region_object :mach_port_move_send_t); +#else +skip; /* was vm_region_object_create */ +#endif + +/* + * A recursive form of vm_region which probes submaps withint the + * address space. + */ +routine vm_region_recurse( + target_task : vm_map_t; + inout address : vm_address_t; + out size : vm_size_t; + inout nesting_depth : natural_t; + out info : vm_region_recurse_info_t,CountInOut); + + +/* + * The routines below are temporary, meant for transitional use + * as their counterparts are moved from 32 to 64 bit data path + */ + + +routine vm_region_recurse_64( + target_task : vm_map_t; + inout address : vm_address_t; + out size : vm_size_t; + inout nesting_depth : natural_t; + out info : vm_region_recurse_info_t,CountInOut); + +routine mach_vm_region_info_64( + task : vm_map_t; + address : vm_address_t; + out region : vm_info_region_64_t; + out objects : vm_info_object_array_t); + +routine vm_region_64( + target_task : vm_map_t; + inout address : vm_address_t; + out size : vm_size_t; + flavor : vm_region_flavor_t; + out info : vm_region_info_t, CountInOut; + out object_name : memory_object_name_t = + MACH_MSG_TYPE_MOVE_SEND + ctype: mach_port_t); + +routine mach_make_memory_entry_64( + target_task :vm_map_t; + inout size :memory_object_size_t; + offset :memory_object_offset_t; + permission :vm_prot_t; + out object_handle :mach_port_move_send_t; + parent_entry :mem_entry_name_port_t); + + + +routine KERNEL_SERVER_SUFFIX(vm_map_64)( + target_task : vm_task_entry_t; + inout address : vm_address_t; + size : vm_size_t; + mask : vm_address_t; + flags : int; + object : mem_entry_name_port_t; + offset : memory_object_offset_t; + copy : boolean_t; + cur_protection : vm_prot_t; + max_protection : vm_prot_t; + inheritance : vm_inherit_t); + +#if 0 +/* + * The UPL interfaces are not ready for user-level export. + */ +routine vm_map_get_upl( + target_task : vm_map_t; + address : vm_map_offset_t; + inout size : vm_size_t; + out upl : upl_t; + out page_info : upl_page_info_array_t, CountInOut; + inout flags : integer_t; + force_data_sync : integer_t); + +routine vm_upl_map( + target_task : vm_map_t; + upl : upl_t; + inout address : vm_address_t); + +routine vm_upl_unmap( + target_task : vm_map_t; + upl : upl_t); +#else +skip; /* was vm_map_get_upl */ +skip; /* was vm_upl_map */ +skip; /* was vm_upl_unmap */ +#endif + +/* + * Control behavior and investigate state of a "purgable" object in + * the virtual address space of the target task. A purgable object is + * created via a call to vm_allocate() with VM_FLAGS_PURGABLE + * specified. See the routine implementation for a complete + * definition of the routine. + */ +routine PREFIX(vm_purgable_control) ( + target_task : vm_map_t; + address : vm_address_t; + control : vm_purgable_t; + inout state : int); + + +routine vm_map_exec_lockdown( + target_task : vm_map_t); + + +/* vim: set ft=c : */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/vm_map.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/vm_map.h new file mode 100644 index 00000000..6c419075 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/vm_map.h @@ -0,0 +1,1440 @@ +#ifndef _vm_map_user_ +#define _vm_map_user_ + +/* Module vm_map */ + +#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 vm_map_MSG_COUNT +#define vm_map_MSG_COUNT 32 +#endif /* vm_map_MSG_COUNT */ + +#include +#include +#include +#include +#include + +#ifdef __BeforeMigUserHeader +__BeforeMigUserHeader +#endif /* __BeforeMigUserHeader */ + +#include +__BEGIN_DECLS + + +/* Routine vm_region */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_region +( + vm_map_t target_task, + vm_address_t *address, + 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 vm_allocate */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_allocate +( + vm_map_t target_task, + vm_address_t *address, + vm_size_t size, + int flags +); + +/* Routine vm_deallocate */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_deallocate +( + vm_map_t target_task, + vm_address_t address, + vm_size_t size +); + +/* Routine vm_protect */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_protect +( + vm_map_t target_task, + vm_address_t address, + vm_size_t size, + boolean_t set_maximum, + vm_prot_t new_protection +); + +/* Routine vm_inherit */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_inherit +( + vm_map_t target_task, + vm_address_t address, + vm_size_t size, + vm_inherit_t new_inheritance +); + +/* Routine vm_read */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_read +( + vm_map_t target_task, + vm_address_t address, + vm_size_t size, + vm_offset_t *data, + mach_msg_type_number_t *dataCnt +); + +/* Routine vm_read_list */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_read_list +( + vm_map_t target_task, + vm_read_entry_t data_list, + natural_t count +); + +/* Routine vm_write */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_write +( + vm_map_t target_task, + vm_address_t address, + vm_offset_t data, + mach_msg_type_number_t dataCnt +); + +/* Routine vm_copy */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_copy +( + vm_map_t target_task, + vm_address_t source_address, + vm_size_t size, + vm_address_t dest_address +); + +/* Routine vm_read_overwrite */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_read_overwrite +( + vm_map_t target_task, + vm_address_t address, + vm_size_t size, + vm_address_t data, + vm_size_t *outsize +); + +/* Routine vm_msync */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_msync +( + vm_map_t target_task, + vm_address_t address, + vm_size_t size, + vm_sync_t sync_flags +); + +/* Routine vm_behavior_set */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_behavior_set +( + vm_map_t target_task, + vm_address_t address, + vm_size_t size, + vm_behavior_t new_behavior +); + +/* Routine vm_map */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_map +( + vm_map_t target_task, + vm_address_t *address, + vm_size_t size, + vm_address_t mask, + int flags, + mem_entry_name_port_t object, + vm_offset_t offset, + boolean_t copy, + vm_prot_t cur_protection, + vm_prot_t max_protection, + vm_inherit_t inheritance +); + +/* Routine vm_machine_attribute */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_machine_attribute +( + vm_map_t target_task, + vm_address_t address, + vm_size_t size, + vm_machine_attribute_t attribute, + vm_machine_attribute_val_t *value +); + +/* Routine vm_remap */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_remap +( + vm_map_t target_task, + vm_address_t *target_address, + vm_size_t size, + vm_address_t mask, + int flags, + vm_map_t src_task, + vm_address_t src_address, + boolean_t copy, + vm_prot_t *cur_protection, + vm_prot_t *max_protection, + vm_inherit_t inheritance +); + +/* Routine task_wire */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +__WATCHOS_PROHIBITED +__TVOS_PROHIBITED +kern_return_t task_wire +( + vm_map_t target_task, + boolean_t must_wire +); + +/* 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, + vm_size_t *size, + vm_offset_t offset, + vm_prot_t permission, + mem_entry_name_port_t *object_handle, + mem_entry_name_port_t parent_entry +); + +/* Routine vm_map_page_query */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_map_page_query +( + vm_map_t target_map, + vm_offset_t offset, + integer_t *disposition, + integer_t *ref_count +); + +/* Routine mach_vm_region_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_vm_region_info +( + vm_map_t task, + vm_address_t address, + vm_info_region_t *region, + vm_info_object_array_t *objects, + mach_msg_type_number_t *objectsCnt +); + +/* Routine vm_mapped_pages_info */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_mapped_pages_info +( + vm_map_t task, + page_address_array_t *pages, + mach_msg_type_number_t *pagesCnt +); + +/* Routine vm_region_recurse */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_region_recurse +( + vm_map_t target_task, + vm_address_t *address, + vm_size_t *size, + natural_t *nesting_depth, + vm_region_recurse_info_t info, + mach_msg_type_number_t *infoCnt +); + +/* Routine vm_region_recurse_64 */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_region_recurse_64 +( + vm_map_t target_task, + vm_address_t *address, + vm_size_t *size, + natural_t *nesting_depth, + vm_region_recurse_info_t info, + mach_msg_type_number_t *infoCnt +); + +/* Routine mach_vm_region_info_64 */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_vm_region_info_64 +( + vm_map_t task, + vm_address_t address, + vm_info_region_64_t *region, + vm_info_object_array_t *objects, + mach_msg_type_number_t *objectsCnt +); + +/* Routine vm_region_64 */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_region_64 +( + vm_map_t target_task, + vm_address_t *address, + 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_64 */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t mach_make_memory_entry_64 +( + vm_map_t target_task, + memory_object_size_t *size, + memory_object_offset_t offset, + vm_prot_t permission, + mach_port_t *object_handle, + mem_entry_name_port_t parent_entry +); + +/* Routine vm_map_64 */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_map_64 +( + vm_map_t target_task, + vm_address_t *address, + vm_size_t size, + vm_address_t mask, + int flags, + mem_entry_name_port_t object, + memory_object_offset_t offset, + boolean_t copy, + vm_prot_t cur_protection, + vm_prot_t max_protection, + vm_inherit_t inheritance +); + +/* Routine vm_purgable_control */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_purgable_control +( + vm_map_t target_task, + vm_address_t address, + vm_purgable_t control, + int *state +); + +/* Routine vm_map_exec_lockdown */ +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ +kern_return_t vm_map_exec_lockdown +( + vm_map_t target_task +); + +__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__vm_map_subsystem__defined +#define __Request__vm_map_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t address; + vm_region_flavor_t flavor; + mach_msg_type_number_t infoCnt; + } __Request__vm_region_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t address; + vm_size_t size; + int flags; + } __Request__vm_allocate_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t address; + vm_size_t size; + } __Request__vm_deallocate_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t address; + vm_size_t size; + boolean_t set_maximum; + vm_prot_t new_protection; + } __Request__vm_protect_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t address; + vm_size_t size; + vm_inherit_t new_inheritance; + } __Request__vm_inherit_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t address; + vm_size_t size; + } __Request__vm_read_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_read_entry_t data_list; + natural_t count; + } __Request__vm_read_list_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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; + vm_address_t address; + mach_msg_type_number_t dataCnt; + } __Request__vm_write_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t source_address; + vm_size_t size; + vm_address_t dest_address; + } __Request__vm_copy_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t address; + vm_size_t size; + vm_address_t data; + } __Request__vm_read_overwrite_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t address; + vm_size_t size; + vm_sync_t sync_flags; + } __Request__vm_msync_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t address; + vm_size_t size; + vm_behavior_t new_behavior; + } __Request__vm_behavior_set_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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; + vm_address_t address; + vm_size_t size; + vm_address_t mask; + int flags; + vm_offset_t offset; + boolean_t copy; + vm_prot_t cur_protection; + vm_prot_t max_protection; + vm_inherit_t inheritance; + } __Request__vm_map_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t address; + vm_size_t size; + vm_machine_attribute_t attribute; + vm_machine_attribute_val_t value; + } __Request__vm_machine_attribute_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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; + vm_address_t target_address; + vm_size_t size; + vm_address_t mask; + int flags; + vm_address_t src_address; + boolean_t copy; + vm_inherit_t inheritance; + } __Request__vm_remap_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + boolean_t must_wire; + } __Request__task_wire_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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_entry; + /* end of the kernel processed data */ + NDR_record_t NDR; + vm_size_t size; + vm_offset_t offset; + vm_prot_t permission; + } __Request__mach_make_memory_entry_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_offset_t offset; + } __Request__vm_map_page_query_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t address; + } __Request__mach_vm_region_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__vm_mapped_pages_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t address; + natural_t nesting_depth; + mach_msg_type_number_t infoCnt; + } __Request__vm_region_recurse_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t address; + natural_t nesting_depth; + mach_msg_type_number_t infoCnt; + } __Request__vm_region_recurse_64_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t address; + } __Request__mach_vm_region_info_64_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t address; + vm_region_flavor_t flavor; + mach_msg_type_number_t infoCnt; + } __Request__vm_region_64_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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_entry; + /* 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_64_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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; + vm_address_t address; + vm_size_t size; + vm_address_t mask; + int flags; + memory_object_offset_t offset; + boolean_t copy; + vm_prot_t cur_protection; + vm_prot_t max_protection; + vm_inherit_t inheritance; + } __Request__vm_map_64_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + vm_address_t address; + vm_purgable_t control; + int state; + } __Request__vm_purgable_control_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + } __Request__vm_map_exec_lockdown_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Request__vm_map_subsystem__defined */ + +/* union of all requests */ + +#ifndef __RequestUnion__vm_map_subsystem__defined +#define __RequestUnion__vm_map_subsystem__defined +union __RequestUnion__vm_map_subsystem { + __Request__vm_region_t Request_vm_region; + __Request__vm_allocate_t Request_vm_allocate; + __Request__vm_deallocate_t Request_vm_deallocate; + __Request__vm_protect_t Request_vm_protect; + __Request__vm_inherit_t Request_vm_inherit; + __Request__vm_read_t Request_vm_read; + __Request__vm_read_list_t Request_vm_read_list; + __Request__vm_write_t Request_vm_write; + __Request__vm_copy_t Request_vm_copy; + __Request__vm_read_overwrite_t Request_vm_read_overwrite; + __Request__vm_msync_t Request_vm_msync; + __Request__vm_behavior_set_t Request_vm_behavior_set; + __Request__vm_map_t Request_vm_map; + __Request__vm_machine_attribute_t Request_vm_machine_attribute; + __Request__vm_remap_t Request_vm_remap; + __Request__task_wire_t Request_task_wire; + __Request__mach_make_memory_entry_t Request_mach_make_memory_entry; + __Request__vm_map_page_query_t Request_vm_map_page_query; + __Request__mach_vm_region_info_t Request_mach_vm_region_info; + __Request__vm_mapped_pages_info_t Request_vm_mapped_pages_info; + __Request__vm_region_recurse_t Request_vm_region_recurse; + __Request__vm_region_recurse_64_t Request_vm_region_recurse_64; + __Request__mach_vm_region_info_64_t Request_mach_vm_region_info_64; + __Request__vm_region_64_t Request_vm_region_64; + __Request__mach_make_memory_entry_64_t Request_mach_make_memory_entry_64; + __Request__vm_map_64_t Request_vm_map_64; + __Request__vm_purgable_control_t Request_vm_purgable_control; + __Request__vm_map_exec_lockdown_t Request_vm_map_exec_lockdown; +}; +#endif /* !__RequestUnion__vm_map_subsystem__defined */ +/* typedefs for all replies */ + +#ifndef __Reply__vm_map_subsystem__defined +#define __Reply__vm_map_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 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; + vm_address_t address; + vm_size_t size; + mach_msg_type_number_t infoCnt; + int info[10]; + } __Reply__vm_region_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + vm_address_t address; + } __Reply__vm_allocate_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__vm_deallocate_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__vm_protect_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__vm_inherit_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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__vm_read_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + vm_read_entry_t data_list; + } __Reply__vm_read_list_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__vm_write_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__vm_copy_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + vm_size_t outsize; + } __Reply__vm_read_overwrite_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__vm_msync_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__vm_behavior_set_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + vm_address_t address; + } __Reply__vm_map_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + vm_machine_attribute_val_t value; + } __Reply__vm_machine_attribute_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + vm_address_t target_address; + vm_prot_t cur_protection; + vm_prot_t max_protection; + } __Reply__vm_remap_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__task_wire_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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; + vm_size_t size; + } __Reply__mach_make_memory_entry_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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__vm_map_page_query_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 objects; + /* end of the kernel processed data */ + NDR_record_t NDR; + vm_info_region_t region; + mach_msg_type_number_t objectsCnt; + } __Reply__mach_vm_region_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 pages; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_msg_type_number_t pagesCnt; + } __Reply__vm_mapped_pages_info_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + vm_address_t address; + vm_size_t size; + natural_t nesting_depth; + mach_msg_type_number_t infoCnt; + int info[19]; + } __Reply__vm_region_recurse_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + vm_address_t address; + vm_size_t size; + natural_t nesting_depth; + mach_msg_type_number_t infoCnt; + int info[19]; + } __Reply__vm_region_recurse_64_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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 objects; + /* end of the kernel processed data */ + NDR_record_t NDR; + vm_info_region_64_t region; + mach_msg_type_number_t objectsCnt; + } __Reply__mach_vm_region_info_64_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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; + vm_address_t address; + vm_size_t size; + mach_msg_type_number_t infoCnt; + int info[10]; + } __Reply__vm_region_64_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 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_64_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + vm_address_t address; + } __Reply__vm_map_64_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + int state; + } __Reply__vm_purgable_control_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + } __Reply__vm_map_exec_lockdown_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Reply__vm_map_subsystem__defined */ + +/* union of all replies */ + +#ifndef __ReplyUnion__vm_map_subsystem__defined +#define __ReplyUnion__vm_map_subsystem__defined +union __ReplyUnion__vm_map_subsystem { + __Reply__vm_region_t Reply_vm_region; + __Reply__vm_allocate_t Reply_vm_allocate; + __Reply__vm_deallocate_t Reply_vm_deallocate; + __Reply__vm_protect_t Reply_vm_protect; + __Reply__vm_inherit_t Reply_vm_inherit; + __Reply__vm_read_t Reply_vm_read; + __Reply__vm_read_list_t Reply_vm_read_list; + __Reply__vm_write_t Reply_vm_write; + __Reply__vm_copy_t Reply_vm_copy; + __Reply__vm_read_overwrite_t Reply_vm_read_overwrite; + __Reply__vm_msync_t Reply_vm_msync; + __Reply__vm_behavior_set_t Reply_vm_behavior_set; + __Reply__vm_map_t Reply_vm_map; + __Reply__vm_machine_attribute_t Reply_vm_machine_attribute; + __Reply__vm_remap_t Reply_vm_remap; + __Reply__task_wire_t Reply_task_wire; + __Reply__mach_make_memory_entry_t Reply_mach_make_memory_entry; + __Reply__vm_map_page_query_t Reply_vm_map_page_query; + __Reply__mach_vm_region_info_t Reply_mach_vm_region_info; + __Reply__vm_mapped_pages_info_t Reply_vm_mapped_pages_info; + __Reply__vm_region_recurse_t Reply_vm_region_recurse; + __Reply__vm_region_recurse_64_t Reply_vm_region_recurse_64; + __Reply__mach_vm_region_info_64_t Reply_mach_vm_region_info_64; + __Reply__vm_region_64_t Reply_vm_region_64; + __Reply__mach_make_memory_entry_64_t Reply_mach_make_memory_entry_64; + __Reply__vm_map_64_t Reply_vm_map_64; + __Reply__vm_purgable_control_t Reply_vm_purgable_control; + __Reply__vm_map_exec_lockdown_t Reply_vm_map_exec_lockdown; +}; +#endif /* !__RequestUnion__vm_map_subsystem__defined */ + +#ifndef subsystem_to_name_map_vm_map +#define subsystem_to_name_map_vm_map \ + { "vm_region", 3800 },\ + { "vm_allocate", 3801 },\ + { "vm_deallocate", 3802 },\ + { "vm_protect", 3803 },\ + { "vm_inherit", 3804 },\ + { "vm_read", 3805 },\ + { "vm_read_list", 3806 },\ + { "vm_write", 3807 },\ + { "vm_copy", 3808 },\ + { "vm_read_overwrite", 3809 },\ + { "vm_msync", 3810 },\ + { "vm_behavior_set", 3811 },\ + { "vm_map", 3812 },\ + { "vm_machine_attribute", 3813 },\ + { "vm_remap", 3814 },\ + { "task_wire", 3815 },\ + { "mach_make_memory_entry", 3816 },\ + { "vm_map_page_query", 3817 },\ + { "mach_vm_region_info", 3818 },\ + { "vm_mapped_pages_info", 3819 },\ + { "vm_region_recurse", 3821 },\ + { "vm_region_recurse_64", 3822 },\ + { "mach_vm_region_info_64", 3823 },\ + { "vm_region_64", 3824 },\ + { "mach_make_memory_entry_64", 3825 },\ + { "vm_map_64", 3826 },\ + { "vm_purgable_control", 3830 },\ + { "vm_map_exec_lockdown", 3831 } +#endif + +#ifdef __AfterMigUserHeader +__AfterMigUserHeader +#endif /* __AfterMigUserHeader */ + +#endif /* _vm_map_user_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/vm_page_size.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/vm_page_size.h new file mode 100644 index 00000000..26d7a730 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/vm_page_size.h @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2013 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ + +#ifndef _VM_PAGE_SIZE_H_ +#define _VM_PAGE_SIZE_H_ + +#include +#include +#include + +__BEGIN_DECLS + +/* + * Globally interesting numbers. + * These macros assume vm_page_size is a power-of-2. + */ +extern vm_size_t vm_page_size; +extern vm_size_t vm_page_mask; +extern int vm_page_shift; + +/* + * These macros assume vm_page_size is a power-of-2. + */ +#define trunc_page(x) ((x) & (~(vm_page_size - 1))) +#define round_page(x) trunc_page((x) + (vm_page_size - 1)) + +/* + * Page-size rounding macros for the fixed-width VM types. + */ +#define mach_vm_trunc_page(x) ((mach_vm_offset_t)(x) & ~((signed)vm_page_mask)) +#define mach_vm_round_page(x) (((mach_vm_offset_t)(x) + vm_page_mask) & ~((signed)vm_page_mask)) + + +extern vm_size_t vm_kernel_page_size __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); +extern vm_size_t vm_kernel_page_mask __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); +extern int vm_kernel_page_shift __OSX_AVAILABLE_STARTING(__MAC_10_9, __IPHONE_7_0); + +#define trunc_page_kernel(x) ((x) & (~vm_kernel_page_mask)) +#define round_page_kernel(x) trunc_page_kernel((x) + vm_kernel_page_mask) + +__END_DECLS + +#endif diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/vm_param.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/vm_param.h new file mode 100644 index 00000000..e836267f --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/vm_param.h @@ -0,0 +1,73 @@ +/* + * Copyright (c) 2000-2006 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * File: mach/vm_param.h + * Author: Avadis Tevanian, Jr., Michael Wayne Young + * Date: 1985 + * + * Machine independent virtual memory parameters. + * + */ + +#ifndef _MACH_VM_PARAM_H_ +#define _MACH_VM_PARAM_H_ + +#include + + +#endif /* _MACH_VM_PARAM_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/vm_prot.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/vm_prot.h new file mode 100644 index 00000000..8914da23 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/vm_prot.h @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * File: mach/vm_prot.h + * Author: Avadis Tevanian, Jr., Michael Wayne Young + * + * Virtual memory protection definitions. + * + */ + +#ifndef _MACH_VM_PROT_H_ +#define _MACH_VM_PROT_H_ + +/* + * Types defined: + * + * vm_prot_t VM protection values. + */ + +typedef int vm_prot_t; + +/* + * Protection values, defined as bits within the vm_prot_t type + */ + +#define VM_PROT_NONE ((vm_prot_t) 0x00) + +#define VM_PROT_READ ((vm_prot_t) 0x01) /* read permission */ +#define VM_PROT_WRITE ((vm_prot_t) 0x02) /* write permission */ +#define VM_PROT_EXECUTE ((vm_prot_t) 0x04) /* execute permission */ + +/* + * The default protection for newly-created virtual memory + */ + +#define VM_PROT_DEFAULT (VM_PROT_READ|VM_PROT_WRITE) + +/* + * The maximum privileges possible, for parameter checking. + */ + +#define VM_PROT_ALL (VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE) + +/* + * An invalid protection value. + * Used only by memory_object_lock_request to indicate no change + * to page locks. Using -1 here is a bad idea because it + * looks like VM_PROT_ALL and then some. + */ + +#define VM_PROT_NO_CHANGE ((vm_prot_t) 0x08) + +/* + * When a caller finds that he cannot obtain write permission on a + * mapped entry, the following flag can be used. The entry will + * be made "needs copy" effectively copying the object (using COW), + * and write permission will be added to the maximum protections + * for the associated entry. + */ + +#define VM_PROT_COPY ((vm_prot_t) 0x10) + + +/* + * Another invalid protection value. + * Used only by memory_object_data_request upon an object + * which has specified a copy_call copy strategy. It is used + * when the kernel wants a page belonging to a copy of the + * object, and is only asking the object as a result of + * following a shadow chain. This solves the race between pages + * being pushed up by the memory manager and the kernel + * walking down the shadow chain. + */ + +#define VM_PROT_WANTS_COPY ((vm_prot_t) 0x10) + + +/* + * Another invalid protection value. + * Indicates that the other protection bits are to be applied as a mask + * against the actual protection bits of the map entry. + */ +#define VM_PROT_IS_MASK ((vm_prot_t) 0x40) + +/* + * Another invalid protection value to support execute-only protection. + * VM_PROT_STRIP_READ is a special marker that tells mprotect to not + * set VM_PROT_READ. We have to do it this way because existing code + * expects the system to set VM_PROT_READ if VM_PROT_EXECUTE is set. + * VM_PROT_EXECUTE_ONLY is just a convenience value to indicate that + * the memory should be executable and explicitly not readable. It will + * be ignored on platforms that do not support this type of protection. + */ +#define VM_PROT_STRIP_READ ((vm_prot_t) 0x80) +#define VM_PROT_EXECUTE_ONLY (VM_PROT_EXECUTE|VM_PROT_STRIP_READ) + +#endif /* _MACH_VM_PROT_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/vm_purgable.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/vm_purgable.h new file mode 100644 index 00000000..80ea756d --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/vm_purgable.h @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2003-2007 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ + +/* + * Virtual memory map purgeable object definitions. + * Objects that will be needed in the future (forward cached objects) should be queued LIFO. + * Objects that have been used and are cached for reuse (backward cached) should be queued FIFO. + * Every user of purgeable memory is entitled to using the highest volatile group (7). + * Only if a client wants some of its objects to definitely be purged earlier, it can put those in + * another group. This could be used to make all FIFO objects (in the lower group) go away before + * any LIFO objects (in the higher group) go away. + * Objects that should not get any chance to stay around can be marked as "obsolete". They will + * be emptied before any other objects or pages are reclaimed. Obsolete objects are not emptied + * in any particular order. + * 'purgeable' is recognized as the correct spelling. For historical reasons, definitions + * in this file are spelled 'purgable'. + */ + +#ifndef _MACH_VM_PURGABLE_H_ +#define _MACH_VM_PURGABLE_H_ + +/* + * Types defined: + * + * vm_purgable_t purgeable object control codes. + */ + +typedef int vm_purgable_t; + +/* + * Enumeration of valid values for vm_purgable_t. + */ +#define VM_PURGABLE_SET_STATE ((vm_purgable_t) 0) /* set state of purgeable object */ +#define VM_PURGABLE_GET_STATE ((vm_purgable_t) 1) /* get state of purgeable object */ +#define VM_PURGABLE_PURGE_ALL ((vm_purgable_t) 2) /* purge all volatile objects now */ +#define VM_PURGABLE_SET_STATE_FROM_KERNEL ((vm_purgable_t) 3) /* set state from kernel */ + +/* + * Purgeable state: + * + * 31 15 14 13 12 11 10 8 7 6 5 4 3 2 1 0 + * +-----+--+-----+--+----+-+-+---+---+---+ + * | |NA|DEBUG| | GRP| |B|ORD| |STA| + * +-----+--+-----+--+----+-+-+---+---+---+ + * " ": unused (i.e. reserved) + * STA: purgeable state + * see: VM_PURGABLE_NONVOLATILE=0 to VM_PURGABLE_DENY=3 + * ORD: order + * see:VM_VOLATILE_ORDER_* + * B: behavior + * see: VM_PURGABLE_BEHAVIOR_* + * GRP: group + * see: VM_VOLATILE_GROUP_* + * DEBUG: debug + * see: VM_PURGABLE_DEBUG_* + * NA: no aging + * see: VM_PURGABLE_NO_AGING* + */ + +#define VM_PURGABLE_NO_AGING_SHIFT 16 +#define VM_PURGABLE_NO_AGING_MASK (0x1 << VM_PURGABLE_NO_AGING_SHIFT) +#define VM_PURGABLE_NO_AGING (0x1 << VM_PURGABLE_NO_AGING_SHIFT) + +#define VM_PURGABLE_DEBUG_SHIFT 12 +#define VM_PURGABLE_DEBUG_MASK (0x3 << VM_PURGABLE_DEBUG_SHIFT) +#define VM_PURGABLE_DEBUG_EMPTY (0x1 << VM_PURGABLE_DEBUG_SHIFT) +#define VM_PURGABLE_DEBUG_FAULT (0x2 << VM_PURGABLE_DEBUG_SHIFT) + +/* + * Volatile memory ordering groups (group zero objects are purged before group 1, etc... + * It is implementation dependent as to whether these groups are global or per-address space. + * (for the moment, they are global). + */ +#define VM_VOLATILE_GROUP_SHIFT 8 +#define VM_VOLATILE_GROUP_MASK (7 << VM_VOLATILE_GROUP_SHIFT) +#define VM_VOLATILE_GROUP_DEFAULT VM_VOLATILE_GROUP_0 + +#define VM_VOLATILE_GROUP_0 (0 << VM_VOLATILE_GROUP_SHIFT) +#define VM_VOLATILE_GROUP_1 (1 << VM_VOLATILE_GROUP_SHIFT) +#define VM_VOLATILE_GROUP_2 (2 << VM_VOLATILE_GROUP_SHIFT) +#define VM_VOLATILE_GROUP_3 (3 << VM_VOLATILE_GROUP_SHIFT) +#define VM_VOLATILE_GROUP_4 (4 << VM_VOLATILE_GROUP_SHIFT) +#define VM_VOLATILE_GROUP_5 (5 << VM_VOLATILE_GROUP_SHIFT) +#define VM_VOLATILE_GROUP_6 (6 << VM_VOLATILE_GROUP_SHIFT) +#define VM_VOLATILE_GROUP_7 (7 << VM_VOLATILE_GROUP_SHIFT) + +/* + * Purgeable behavior + * Within the same group, FIFO objects will be emptied before objects that are added later. + * LIFO objects will be emptied after objects that are added later. + * - Input only, not returned on state queries. + */ +#define VM_PURGABLE_BEHAVIOR_SHIFT 6 +#define VM_PURGABLE_BEHAVIOR_MASK (1 << VM_PURGABLE_BEHAVIOR_SHIFT) +#define VM_PURGABLE_BEHAVIOR_FIFO (0 << VM_PURGABLE_BEHAVIOR_SHIFT) +#define VM_PURGABLE_BEHAVIOR_LIFO (1 << VM_PURGABLE_BEHAVIOR_SHIFT) + +/* + * Obsolete object. + * Disregard volatile group, and put object into obsolete queue instead, so it is the next object + * to be purged. + * - Input only, not returned on state queries. + */ +#define VM_PURGABLE_ORDERING_SHIFT 5 +#define VM_PURGABLE_ORDERING_MASK (1 << VM_PURGABLE_ORDERING_SHIFT) +#define VM_PURGABLE_ORDERING_OBSOLETE (1 << VM_PURGABLE_ORDERING_SHIFT) +#define VM_PURGABLE_ORDERING_NORMAL (0 << VM_PURGABLE_ORDERING_SHIFT) + + +/* + * Obsolete parameter - do not use + */ +#define VM_VOLATILE_ORDER_SHIFT 4 +#define VM_VOLATILE_ORDER_MASK (1 << VM_VOLATILE_ORDER_SHIFT) +#define VM_VOLATILE_MAKE_FIRST_IN_GROUP (1 << VM_VOLATILE_ORDER_SHIFT) +#define VM_VOLATILE_MAKE_LAST_IN_GROUP (0 << VM_VOLATILE_ORDER_SHIFT) + +/* + * Valid states of a purgeable object. + */ +#define VM_PURGABLE_STATE_MIN 0 /* minimum purgeable object state value */ +#define VM_PURGABLE_STATE_MAX 3 /* maximum purgeable object state value */ +#define VM_PURGABLE_STATE_MASK 3 /* mask to separate state from group */ + +#define VM_PURGABLE_NONVOLATILE 0 /* purgeable object is non-volatile */ +#define VM_PURGABLE_VOLATILE 1 /* purgeable object is volatile */ +#define VM_PURGABLE_EMPTY 2 /* purgeable object is volatile and empty */ +#define VM_PURGABLE_DENY 3 /* (mark) object not purgeable */ + +#define VM_PURGABLE_ALL_MASKS (VM_PURGABLE_STATE_MASK | \ + VM_VOLATILE_ORDER_MASK | \ + VM_PURGABLE_ORDERING_MASK | \ + VM_PURGABLE_BEHAVIOR_MASK | \ + VM_VOLATILE_GROUP_MASK | \ + VM_PURGABLE_DEBUG_MASK | \ + VM_PURGABLE_NO_AGING_MASK) +#endif /* _MACH_VM_PURGABLE_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/vm_region.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/vm_region.h new file mode 100644 index 00000000..f6f371fa --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/vm_region.h @@ -0,0 +1,349 @@ +/* + * Copyright (c) 2000-2016 Apple Computer, Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * File: mach/vm_region.h + * + * Define the attributes of a task's memory region + * + */ + +#ifndef _MACH_VM_REGION_H_ +#define _MACH_VM_REGION_H_ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#pragma pack(push, 4) + +// LP64todo: all the current tools are 32bit, obviously never worked for 64b +// so probably should be a real 32b ID vs. ptr. +// Current users just check for equality +typedef uint32_t vm32_object_id_t; + +/* + * Types defined: + * + * vm_region_info_t memory region attributes + */ + +#define VM_REGION_INFO_MAX (1024) +typedef int *vm_region_info_t; +typedef int *vm_region_info_64_t; +typedef int *vm_region_recurse_info_t; +typedef int *vm_region_recurse_info_64_t; +typedef int vm_region_flavor_t; +typedef int vm_region_info_data_t[VM_REGION_INFO_MAX]; + +#define VM_REGION_BASIC_INFO_64 9 +struct vm_region_basic_info_64 { + vm_prot_t protection; + vm_prot_t max_protection; + vm_inherit_t inheritance; + boolean_t shared; + boolean_t reserved; + memory_object_offset_t offset; + vm_behavior_t behavior; + unsigned short user_wired_count; +}; +typedef struct vm_region_basic_info_64 *vm_region_basic_info_64_t; +typedef struct vm_region_basic_info_64 vm_region_basic_info_data_64_t; + +#define VM_REGION_BASIC_INFO_COUNT_64 ((mach_msg_type_number_t) \ + (sizeof(vm_region_basic_info_data_64_t)/sizeof(int))) + +/* + * Passing VM_REGION_BASIC_INFO to vm_region_64 + * automatically converts it to a VM_REGION_BASIC_INFO_64. + * Please use that explicitly instead. + */ +#define VM_REGION_BASIC_INFO 10 + +/* + * This is the legacy basic info structure. It is + * deprecated because it passes only a 32-bit memory object + * offset back - too small for many larger objects (e.g. files). + */ +struct vm_region_basic_info { + vm_prot_t protection; + vm_prot_t max_protection; + vm_inherit_t inheritance; + boolean_t shared; + boolean_t reserved; + uint32_t offset; /* too small for a real offset */ + vm_behavior_t behavior; + unsigned short user_wired_count; +}; + +typedef struct vm_region_basic_info *vm_region_basic_info_t; +typedef struct vm_region_basic_info vm_region_basic_info_data_t; + +#define VM_REGION_BASIC_INFO_COUNT ((mach_msg_type_number_t) \ + (sizeof(vm_region_basic_info_data_t)/sizeof(int))) + +#define SM_COW 1 +#define SM_PRIVATE 2 +#define SM_EMPTY 3 +#define SM_SHARED 4 +#define SM_TRUESHARED 5 +#define SM_PRIVATE_ALIASED 6 +#define SM_SHARED_ALIASED 7 +#define SM_LARGE_PAGE 8 + +/* + * For submap info, the SM flags above are overlayed when a submap + * is encountered. The field denotes whether or not machine level mapping + * information is being shared. PTE's etc. When such sharing is taking + * place the value returned is SM_TRUESHARED otherwise SM_PRIVATE is passed + * back. + */ + + + + +#define VM_REGION_EXTENDED_INFO 13 +struct vm_region_extended_info { + vm_prot_t protection; + unsigned int user_tag; + unsigned int pages_resident; + unsigned int pages_shared_now_private; + unsigned int pages_swapped_out; + unsigned int pages_dirtied; + unsigned int ref_count; + unsigned short shadow_depth; + unsigned char external_pager; + unsigned char share_mode; + unsigned int pages_reusable; +}; +typedef struct vm_region_extended_info *vm_region_extended_info_t; +typedef struct vm_region_extended_info vm_region_extended_info_data_t; +#define VM_REGION_EXTENDED_INFO_COUNT \ + ((mach_msg_type_number_t) \ + (sizeof (vm_region_extended_info_data_t) / sizeof (natural_t))) + + + + +#define VM_REGION_TOP_INFO 12 + +struct vm_region_top_info { + unsigned int obj_id; + unsigned int ref_count; + unsigned int private_pages_resident; + unsigned int shared_pages_resident; + unsigned char share_mode; +}; + +typedef struct vm_region_top_info *vm_region_top_info_t; +typedef struct vm_region_top_info vm_region_top_info_data_t; + +#define VM_REGION_TOP_INFO_COUNT \ + ((mach_msg_type_number_t) \ + (sizeof(vm_region_top_info_data_t) / sizeof(natural_t))) + + + +/* + * vm_region_submap_info will return information on a submap or object. + * The user supplies a nesting level on the call. When a walk of the + * user's map is done and a submap is encountered, the nesting count is + * checked. If the nesting count is greater than 1 the submap is entered and + * the offset relative to the address in the base map is examined. If the + * nesting count is zero, the information on the submap is returned. + * The caller may thus learn about a submap and its contents by judicious + * choice of the base map address and nesting count. The nesting count + * allows penetration of recursively mapped submaps. If a submap is + * encountered as a mapped entry of another submap, the caller may bump + * the nesting count and call vm_region_recurse again on the target address + * range. The "is_submap" field tells the caller whether or not a submap + * has been encountered. + * + * Object only fields are filled in through a walking of the object shadow + * chain (where one is present), and a walking of the resident page queue. + * + */ + +struct vm_region_submap_info { + vm_prot_t protection; /* present access protection */ + vm_prot_t max_protection; /* max avail through vm_prot */ + vm_inherit_t inheritance;/* behavior of map/obj on fork */ + uint32_t offset; /* offset into object/map */ + unsigned int user_tag; /* user tag on map entry */ + unsigned int pages_resident; /* only valid for objects */ + unsigned int pages_shared_now_private; /* only for objects */ + unsigned int pages_swapped_out; /* only for objects */ + unsigned int pages_dirtied; /* only for objects */ + unsigned int ref_count; /* obj/map mappers, etc */ + unsigned short shadow_depth; /* only for obj */ + unsigned char external_pager; /* only for obj */ + unsigned char share_mode; /* see enumeration */ + boolean_t is_submap; /* submap vs obj */ + vm_behavior_t behavior; /* access behavior hint */ + vm32_object_id_t object_id; /* obj/map name, not a handle */ + unsigned short user_wired_count; +}; + +typedef struct vm_region_submap_info *vm_region_submap_info_t; +typedef struct vm_region_submap_info vm_region_submap_info_data_t; + +#define VM_REGION_SUBMAP_INFO_COUNT \ + ((mach_msg_type_number_t) \ + (sizeof(vm_region_submap_info_data_t) / sizeof(natural_t))) + +struct vm_region_submap_info_64 { + vm_prot_t protection; /* present access protection */ + vm_prot_t max_protection; /* max avail through vm_prot */ + vm_inherit_t inheritance;/* behavior of map/obj on fork */ + memory_object_offset_t offset; /* offset into object/map */ + unsigned int user_tag; /* user tag on map entry */ + unsigned int pages_resident; /* only valid for objects */ + unsigned int pages_shared_now_private; /* only for objects */ + unsigned int pages_swapped_out; /* only for objects */ + unsigned int pages_dirtied; /* only for objects */ + unsigned int ref_count; /* obj/map mappers, etc */ + unsigned short shadow_depth; /* only for obj */ + unsigned char external_pager; /* only for obj */ + unsigned char share_mode; /* see enumeration */ + boolean_t is_submap; /* submap vs obj */ + vm_behavior_t behavior; /* access behavior hint */ + vm32_object_id_t object_id; /* obj/map name, not a handle */ + unsigned short user_wired_count; + unsigned int pages_reusable; + vm_object_id_t object_id_full; +}; + +typedef struct vm_region_submap_info_64 *vm_region_submap_info_64_t; +typedef struct vm_region_submap_info_64 vm_region_submap_info_data_64_t; + +#define VM_REGION_SUBMAP_INFO_V2_SIZE \ + (sizeof (vm_region_submap_info_data_64_t)) +#define VM_REGION_SUBMAP_INFO_V1_SIZE \ + (VM_REGION_SUBMAP_INFO_V2_SIZE - \ + sizeof (vm_object_id_t) /* object_id_full */ ) +#define VM_REGION_SUBMAP_INFO_V0_SIZE \ + (VM_REGION_SUBMAP_INFO_V1_SIZE - \ + sizeof (unsigned int) /* pages_reusable */ ) + +#define VM_REGION_SUBMAP_INFO_V2_COUNT_64 \ + ((mach_msg_type_number_t) \ + (VM_REGION_SUBMAP_INFO_V2_SIZE / sizeof (natural_t))) +#define VM_REGION_SUBMAP_INFO_V1_COUNT_64 \ + ((mach_msg_type_number_t) \ + (VM_REGION_SUBMAP_INFO_V1_SIZE / sizeof (natural_t))) +#define VM_REGION_SUBMAP_INFO_V0_COUNT_64 \ + ((mach_msg_type_number_t) \ + (VM_REGION_SUBMAP_INFO_V0_SIZE / sizeof (natural_t))) + +/* set this to the latest version */ +#define VM_REGION_SUBMAP_INFO_COUNT_64 VM_REGION_SUBMAP_INFO_V2_COUNT_64 + +struct vm_region_submap_short_info_64 { + vm_prot_t protection; /* present access protection */ + vm_prot_t max_protection; /* max avail through vm_prot */ + vm_inherit_t inheritance;/* behavior of map/obj on fork */ + memory_object_offset_t offset; /* offset into object/map */ + unsigned int user_tag; /* user tag on map entry */ + unsigned int ref_count; /* obj/map mappers, etc */ + unsigned short shadow_depth; /* only for obj */ + unsigned char external_pager; /* only for obj */ + unsigned char share_mode; /* see enumeration */ + boolean_t is_submap; /* submap vs obj */ + vm_behavior_t behavior; /* access behavior hint */ + vm32_object_id_t object_id; /* obj/map name, not a handle */ + unsigned short user_wired_count; +}; + +typedef struct vm_region_submap_short_info_64 *vm_region_submap_short_info_64_t; +typedef struct vm_region_submap_short_info_64 vm_region_submap_short_info_data_64_t; + +#define VM_REGION_SUBMAP_SHORT_INFO_COUNT_64 \ + ((mach_msg_type_number_t) \ + (sizeof (vm_region_submap_short_info_data_64_t) / sizeof (natural_t))) + +struct mach_vm_read_entry { + mach_vm_address_t address; + mach_vm_size_t size; +}; + +struct vm_read_entry { + vm_address_t address; + vm_size_t size; +}; + +#ifdef VM32_SUPPORT +struct vm32_read_entry { + vm32_address_t address; + vm32_size_t size; +}; +#endif + + +#define VM_MAP_ENTRY_MAX (256) + +typedef struct mach_vm_read_entry mach_vm_read_entry_t[VM_MAP_ENTRY_MAX]; +typedef struct vm_read_entry vm_read_entry_t[VM_MAP_ENTRY_MAX]; +#ifdef VM32_SUPPORT +typedef struct vm32_read_entry vm32_read_entry_t[VM_MAP_ENTRY_MAX]; +#endif + +#pragma pack(pop) + + +#define VM_PAGE_INFO_MAX +typedef int *vm_page_info_t; +typedef int vm_page_info_data_t[VM_PAGE_INFO_MAX]; +typedef int vm_page_info_flavor_t; + +#define VM_PAGE_INFO_BASIC 1 +struct vm_page_info_basic { + int disposition; + int ref_count; + vm_object_id_t object_id; + memory_object_offset_t offset; + int depth; + int __pad; /* pad to 64-bit boundary */ +}; +typedef struct vm_page_info_basic *vm_page_info_basic_t; +typedef struct vm_page_info_basic vm_page_info_basic_data_t; + +#define VM_PAGE_INFO_BASIC_COUNT ((mach_msg_type_number_t) \ + (sizeof(vm_page_info_basic_data_t)/sizeof(int))) + + +#endif /*_MACH_VM_REGION_H_*/ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/vm_statistics.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/vm_statistics.h new file mode 100644 index 00000000..0a2ee5b7 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/vm_statistics.h @@ -0,0 +1,523 @@ +/* + * Copyright (c) 2000-2019 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + */ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + */ +/* + * File: mach/vm_statistics.h + * Author: Avadis Tevanian, Jr., Michael Wayne Young, David Golub + * + * Virtual memory statistics structure. + * + */ + +#ifndef _MACH_VM_STATISTICS_H_ +#define _MACH_VM_STATISTICS_H_ + +#include + + +/* + * vm_statistics + * + * History: + * rev0 - original structure. + * rev1 - added purgable info (purgable_count and purges). + * rev2 - added speculative_count. + * + * Note: you cannot add any new fields to this structure. Add them below in + * vm_statistics64. + */ + +struct vm_statistics { + natural_t free_count; /* # of pages free */ + natural_t active_count; /* # of pages active */ + natural_t inactive_count; /* # of pages inactive */ + natural_t wire_count; /* # of pages wired down */ + natural_t zero_fill_count; /* # of zero fill pages */ + natural_t reactivations; /* # of pages reactivated */ + natural_t pageins; /* # of pageins */ + natural_t pageouts; /* # of pageouts */ + natural_t faults; /* # of faults */ + natural_t cow_faults; /* # of copy-on-writes */ + natural_t lookups; /* object cache lookups */ + natural_t hits; /* object cache hits */ + + /* added for rev1 */ + natural_t purgeable_count; /* # of pages purgeable */ + natural_t purges; /* # of pages purged */ + + /* added for rev2 */ + /* + * NB: speculative pages are already accounted for in "free_count", + * so "speculative_count" is the number of "free" pages that are + * used to hold data that was read speculatively from disk but + * haven't actually been used by anyone so far. + */ + natural_t speculative_count; /* # of pages speculative */ +}; + +/* Used by all architectures */ +typedef struct vm_statistics *vm_statistics_t; +typedef struct vm_statistics vm_statistics_data_t; + +/* + * vm_statistics64 + * + * History: + * rev0 - original structure. + * rev1 - added purgable info (purgable_count and purges). + * rev2 - added speculative_count. + * ---- + * rev3 - changed name to vm_statistics64. + * changed some fields in structure to 64-bit on + * arm, i386 and x86_64 architectures. + * rev4 - require 64-bit alignment for efficient access + * in the kernel. No change to reported data. + * + */ + +struct vm_statistics64 { + natural_t free_count; /* # of pages free */ + natural_t active_count; /* # of pages active */ + natural_t inactive_count; /* # of pages inactive */ + natural_t wire_count; /* # of pages wired down */ + uint64_t zero_fill_count; /* # of zero fill pages */ + uint64_t reactivations; /* # of pages reactivated */ + uint64_t pageins; /* # of pageins */ + uint64_t pageouts; /* # of pageouts */ + uint64_t faults; /* # of faults */ + uint64_t cow_faults; /* # of copy-on-writes */ + uint64_t lookups; /* object cache lookups */ + uint64_t hits; /* object cache hits */ + uint64_t purges; /* # of pages purged */ + natural_t purgeable_count; /* # of pages purgeable */ + /* + * NB: speculative pages are already accounted for in "free_count", + * so "speculative_count" is the number of "free" pages that are + * used to hold data that was read speculatively from disk but + * haven't actually been used by anyone so far. + */ + natural_t speculative_count; /* # of pages speculative */ + + /* added for rev1 */ + uint64_t decompressions; /* # of pages decompressed */ + uint64_t compressions; /* # of pages compressed */ + uint64_t swapins; /* # of pages swapped in (via compression segments) */ + uint64_t swapouts; /* # of pages swapped out (via compression segments) */ + natural_t compressor_page_count; /* # of pages used by the compressed pager to hold all the compressed data */ + natural_t throttled_count; /* # of pages throttled */ + natural_t external_page_count; /* # of pages that are file-backed (non-swap) */ + natural_t internal_page_count; /* # of pages that are anonymous */ + uint64_t total_uncompressed_pages_in_compressor; /* # of pages (uncompressed) held within the compressor. */ +} __attribute__((aligned(8))); + +typedef struct vm_statistics64 *vm_statistics64_t; +typedef struct vm_statistics64 vm_statistics64_data_t; + +/* + * VM_STATISTICS_TRUNCATE_TO_32_BIT + * + * This is used by host_statistics() to truncate and peg the 64-bit in-kernel values from + * vm_statistics64 to the 32-bit values of the older structure above (vm_statistics). + */ +#define VM_STATISTICS_TRUNCATE_TO_32_BIT(value) ((uint32_t)(((value) > UINT32_MAX ) ? UINT32_MAX : (value))) + +/* + * vm_extmod_statistics + * + * Structure to record modifications to a task by an + * external agent. + * + * History: + * rev0 - original structure. + */ + +struct vm_extmod_statistics { + int64_t task_for_pid_count; /* # of times task port was looked up */ + int64_t task_for_pid_caller_count; /* # of times this task called task_for_pid */ + int64_t thread_creation_count; /* # of threads created in task */ + int64_t thread_creation_caller_count; /* # of threads created by task */ + int64_t thread_set_state_count; /* # of register state sets in task */ + int64_t thread_set_state_caller_count; /* # of register state sets by task */ +} __attribute__((aligned(8))); + +typedef struct vm_extmod_statistics *vm_extmod_statistics_t; +typedef struct vm_extmod_statistics vm_extmod_statistics_data_t; + +typedef struct vm_purgeable_stat { + uint64_t count; + uint64_t size; +}vm_purgeable_stat_t; + +struct vm_purgeable_info { + vm_purgeable_stat_t fifo_data[8]; + vm_purgeable_stat_t obsolete_data; + vm_purgeable_stat_t lifo_data[8]; +}; + +typedef struct vm_purgeable_info *vm_purgeable_info_t; + +/* included for the vm_map_page_query call */ + +#define VM_PAGE_QUERY_PAGE_PRESENT 0x1 +#define VM_PAGE_QUERY_PAGE_FICTITIOUS 0x2 +#define VM_PAGE_QUERY_PAGE_REF 0x4 +#define VM_PAGE_QUERY_PAGE_DIRTY 0x8 +#define VM_PAGE_QUERY_PAGE_PAGED_OUT 0x10 +#define VM_PAGE_QUERY_PAGE_COPIED 0x20 +#define VM_PAGE_QUERY_PAGE_SPECULATIVE 0x40 +#define VM_PAGE_QUERY_PAGE_EXTERNAL 0x80 +#define VM_PAGE_QUERY_PAGE_CS_VALIDATED 0x100 +#define VM_PAGE_QUERY_PAGE_CS_TAINTED 0x200 +#define VM_PAGE_QUERY_PAGE_CS_NX 0x400 +#define VM_PAGE_QUERY_PAGE_REUSABLE 0x800 + + +/* + * VM allocation flags: + * + * VM_FLAGS_FIXED + * (really the absence of VM_FLAGS_ANYWHERE) + * Allocate new VM region at the specified virtual address, if possible. + * + * VM_FLAGS_ANYWHERE + * Allocate new VM region anywhere it would fit in the address space. + * + * VM_FLAGS_PURGABLE + * Create a purgable VM object for that new VM region. + * + * VM_FLAGS_4GB_CHUNK + * The new VM region will be chunked up into 4GB sized pieces. + * + * VM_FLAGS_NO_PMAP_CHECK + * (for DEBUG kernel config only, ignored for other configs) + * Do not check that there is no stale pmap mapping for the new VM region. + * This is useful for kernel memory allocations at bootstrap when building + * the initial kernel address space while some memory is already in use. + * + * VM_FLAGS_OVERWRITE + * The new VM region can replace existing VM regions if necessary + * (to be used in combination with VM_FLAGS_FIXED). + * + * VM_FLAGS_NO_CACHE + * Pages brought in to this VM region are placed on the speculative + * queue instead of the active queue. In other words, they are not + * cached so that they will be stolen first if memory runs low. + */ + +#define VM_FLAGS_FIXED 0x0000 +#define VM_FLAGS_ANYWHERE 0x0001 +#define VM_FLAGS_PURGABLE 0x0002 +#define VM_FLAGS_4GB_CHUNK 0x0004 +#define VM_FLAGS_RANDOM_ADDR 0x0008 +#define VM_FLAGS_NO_CACHE 0x0010 +#define VM_FLAGS_RESILIENT_CODESIGN 0x0020 +#define VM_FLAGS_RESILIENT_MEDIA 0x0040 +#define VM_FLAGS_OVERWRITE 0x4000 /* delete any existing mappings first */ +/* + * VM_FLAGS_SUPERPAGE_MASK + * 3 bits that specify whether large pages should be used instead of + * base pages (!=0), as well as the requested page size. + */ +#define VM_FLAGS_SUPERPAGE_MASK 0x70000 /* bits 0x10000, 0x20000, 0x40000 */ +#define VM_FLAGS_RETURN_DATA_ADDR 0x100000 /* Return address of target data, rather than base of page */ +#define VM_FLAGS_RETURN_4K_DATA_ADDR 0x800000 /* Return 4K aligned address of target data */ +#define VM_FLAGS_ALIAS_MASK 0xFF000000 +#define VM_GET_FLAGS_ALIAS(flags, alias) \ + (alias) = ((flags) & VM_FLAGS_ALIAS_MASK) >> 24 +#define VM_SET_FLAGS_ALIAS(flags, alias) \ + (flags) = (((flags) & ~VM_FLAGS_ALIAS_MASK) | \ + (((alias) & ~VM_FLAGS_ALIAS_MASK) << 24)) + +/* These are the flags that we accept from user-space */ +#define VM_FLAGS_USER_ALLOCATE (VM_FLAGS_FIXED | \ + VM_FLAGS_ANYWHERE | \ + VM_FLAGS_PURGABLE | \ + VM_FLAGS_4GB_CHUNK | \ + VM_FLAGS_RANDOM_ADDR | \ + VM_FLAGS_NO_CACHE | \ + VM_FLAGS_OVERWRITE | \ + VM_FLAGS_SUPERPAGE_MASK | \ + VM_FLAGS_ALIAS_MASK) +#define VM_FLAGS_USER_MAP (VM_FLAGS_USER_ALLOCATE | \ + VM_FLAGS_RETURN_4K_DATA_ADDR | \ + VM_FLAGS_RETURN_DATA_ADDR) +#define VM_FLAGS_USER_REMAP (VM_FLAGS_FIXED | \ + VM_FLAGS_ANYWHERE | \ + VM_FLAGS_RANDOM_ADDR | \ + VM_FLAGS_OVERWRITE| \ + VM_FLAGS_RETURN_DATA_ADDR | \ + VM_FLAGS_RESILIENT_CODESIGN | \ + VM_FLAGS_RESILIENT_MEDIA) + +#define VM_FLAGS_SUPERPAGE_SHIFT 16 +#define SUPERPAGE_NONE 0 /* no superpages, if all bits are 0 */ +#define SUPERPAGE_SIZE_ANY 1 +#define VM_FLAGS_SUPERPAGE_NONE (SUPERPAGE_NONE << VM_FLAGS_SUPERPAGE_SHIFT) +#define VM_FLAGS_SUPERPAGE_SIZE_ANY (SUPERPAGE_SIZE_ANY << VM_FLAGS_SUPERPAGE_SHIFT) +#define SUPERPAGE_SIZE_2MB 2 +#define VM_FLAGS_SUPERPAGE_SIZE_2MB (SUPERPAGE_SIZE_2MB< diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/vm_types.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/vm_types.h new file mode 100644 index 00000000..1367f255 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/mach/vm_types.h @@ -0,0 +1,95 @@ +/* + * Copyright (c) 2000-2018 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + */ +/* + * @OSF_COPYRIGHT@ + * + */ +#ifndef _MACH_VM_TYPES_H_ +#define _MACH_VM_TYPES_H_ + +#include +#include + +#include + +typedef vm_offset_t pointer_t; +typedef vm_offset_t vm_address_t; + +/* + * We use addr64_t for 64-bit addresses that are used on both + * 32 and 64-bit machines. On PPC, they are passed and returned as + * two adjacent 32-bit GPRs. We use addr64_t in places where + * common code must be useable both on 32 and 64-bit machines. + */ +typedef uint64_t addr64_t; /* Basic effective address */ + +/* + * We use reg64_t for addresses that are 32 bits on a 32-bit + * machine, and 64 bits on a 64-bit machine, but are always + * passed and returned in a single GPR on PPC. This type + * cannot be used in generic 32-bit c, since on a 64-bit + * machine the upper half of the register will be ignored + * by the c compiler in 32-bit mode. In c, we can only use the + * type in prototypes of functions that are written in and called + * from assembly language. This type is basically a comment. + */ +typedef uint32_t reg64_t; + +/* + * To minimize the use of 64-bit fields, we keep some physical + * addresses (that are page aligned) as 32-bit page numbers. + * This limits the physical address space to 16TB of RAM. + */ +typedef uint32_t ppnum_t; /* Physical page number */ +#define PPNUM_MAX UINT32_MAX + + + +typedef mach_port_t vm_map_t; + + +#define VM_MAP_NULL ((vm_map_t) 0) + +/* + * Evolving definitions, likely to change. + */ + +typedef uint64_t vm_object_offset_t; +typedef uint64_t vm_object_size_t; + + + + +typedef mach_port_t upl_t; +typedef mach_port_t vm_named_entry_t; + + +#define UPL_NULL ((upl_t) 0) +#define VM_NAMED_ENTRY_NULL ((vm_named_entry_t) 0) + +#endif /* _MACH_VM_TYPES_H_ */ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/syscall_sw.c b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/syscall_sw.c new file mode 100644 index 00000000..61b35541 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/syscall_sw.c @@ -0,0 +1,136 @@ +#define MACH_TRAP_TABLE_COUNT 128 + +const char *mach_syscall_name_table[MACH_TRAP_TABLE_COUNT] = { + /* 0 */ "kern_invalid", + /* 1 */ "kern_invalid", + /* 2 */ "kern_invalid", + /* 3 */ "kern_invalid", + /* 4 */ "kern_invalid", + /* 5 */ "kern_invalid", + /* 6 */ "kern_invalid", + /* 7 */ "kern_invalid", + /* 8 */ "kern_invalid", + /* 9 */ "kern_invalid", + /* 10 */ "_kernelrpc_mach_vm_allocate_trap", + /* 11 */ "kern_invalid", + /* 12 */ "_kernelrpc_mach_vm_deallocate_trap", + /* 13 */ "kern_invalid", + /* 14 */ "_kernelrpc_mach_vm_protect_trap", + /* 15 */ "_kernelrpc_mach_vm_map_trap", + /* 16 */ "_kernelrpc_mach_port_allocate_trap", + /* 17 */ "_kernelrpc_mach_port_destroy_trap", + /* 18 */ "_kernelrpc_mach_port_deallocate_trap", + /* 19 */ "_kernelrpc_mach_port_mod_refs_trap", + /* 20 */ "_kernelrpc_mach_port_move_member_trap", + /* 21 */ "_kernelrpc_mach_port_insert_right_trap", + /* 22 */ "_kernelrpc_mach_port_insert_member_trap", + /* 23 */ "_kernelrpc_mach_port_extract_member_trap", + /* 24 */ "_kernelrpc_mach_port_construct_trap", + /* 25 */ "_kernelrpc_mach_port_destruct_trap", + /* 26 */ "mach_reply_port", + /* 27 */ "thread_self_trap", + /* 28 */ "task_self_trap", + /* 29 */ "host_self_trap", + /* 30 */ "kern_invalid", + /* 31 */ "mach_msg_trap", + /* 32 */ "mach_msg_overwrite_trap", + /* 33 */ "semaphore_signal_trap", + /* 34 */ "semaphore_signal_all_trap", + /* 35 */ "semaphore_signal_thread_trap", + /* 36 */ "semaphore_wait_trap", + /* 37 */ "semaphore_wait_signal_trap", + /* 38 */ "semaphore_timedwait_trap", + /* 39 */ "semaphore_timedwait_signal_trap", + /* 40 */ "kern_invalid", + /* 41 */ "_kernelrpc_mach_port_guard_trap", + /* 42 */ "_kernelrpc_mach_port_unguard_trap", + /* 43 */ "mach_generate_activity_id", + /* 44 */ "task_name_for_pid", + /* 45 */ "task_for_pid", + /* 46 */ "pid_for_task", + /* 47 */ "kern_invalid", + /* 48 */ "macx_swapon", + /* 49 */ "macx_swapoff", + /* 50 */ "thread_get_special_reply_port", + /* 51 */ "macx_triggers", + /* 52 */ "macx_backing_store_suspend", + /* 53 */ "macx_backing_store_recovery", + /* 54 */ "kern_invalid", + /* 55 */ "kern_invalid", + /* 56 */ "kern_invalid", + /* 57 */ "kern_invalid", + /* 58 */ "pfz_exit", + /* 59 */ "swtch_pri", + /* 60 */ "swtch", + /* 61 */ "thread_switch", + /* 62 */ "clock_sleep_trap", + /* 63 */ "kern_invalid", + /* traps 64 - 95 reserved (debo) */ + /* 64 */ "kern_invalid", + /* 65 */ "kern_invalid", + /* 66 */ "kern_invalid", + /* 67 */ "kern_invalid", + /* 68 */ "kern_invalid", + /* 69 */ "kern_invalid", + /* 70 */ "host_create_mach_voucher_trap", + /* 71 */ "kern_invalid", + /* 72 */ "mach_voucher_extract_attr_recipe_trap", + /* 73 */ "kern_invalid", + /* 74 */ "kern_invalid", + /* 75 */ "kern_invalid", + /* 76 */ "kern_invalid", + /* 77 */ "_kernelrpc_mach_port_type_trap", + /* 78 */ "_kernelrpc_mach_port_request_notification_trap", + /* 79 */ "kern_invalid", + /* 80 */ "kern_invalid", + /* 81 */ "kern_invalid", + /* 82 */ "kern_invalid", + /* 83 */ "kern_invalid", + /* 84 */ "kern_invalid", + /* 85 */ "kern_invalid", + /* 86 */ "kern_invalid", + /* 87 */ "kern_invalid", + /* 88 */ "kern_invalid", + /* 89 */ "mach_timebase_info_trap", + /* 90 */ "mach_wait_until_trap", + /* 91 */ "mk_timer_create_trap", + /* 92 */ "mk_timer_destroy_trap", + /* 93 */ "mk_timer_arm_trap", + /* 94 */ "mk_timer_cancel_trap", + /* 95 */ "kern_invalid", + /* traps 64 - 95 reserved (debo) */ + /* 96 */ "debug_control_port_for_pid", + /* 97 */ "kern_invalid", + /* 98 */ "kern_invalid", + /* 99 */ "kern_invalid", + /* traps 100-107 reserved for iokit (esb) */ + /* 100 */ "iokit_user_client_trap", + /* 101 */ "kern_invalid", + /* 102 */ "kern_invalid", + /* 103 */ "kern_invalid", + /* 104 */ "kern_invalid", + /* 105 */ "kern_invalid", + /* 106 */ "kern_invalid", + /* 107 */ "kern_invalid", + /* traps 108-127 unused */ + /* 108 */ "kern_invalid", + /* 109 */ "kern_invalid", + /* 110 */ "kern_invalid", + /* 111 */ "kern_invalid", + /* 112 */ "kern_invalid", + /* 113 */ "kern_invalid", + /* 114 */ "kern_invalid", + /* 115 */ "kern_invalid", + /* 116 */ "kern_invalid", + /* 117 */ "kern_invalid", + /* 118 */ "kern_invalid", + /* 119 */ "kern_invalid", + /* 120 */ "kern_invalid", + /* 121 */ "kern_invalid", + /* 122 */ "kern_invalid", + /* 123 */ "kern_invalid", + /* 124 */ "kern_invalid", + /* 125 */ "kern_invalid", + /* 126 */ "kern_invalid", + /* 127 */ "kern_invalid", +}; diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/syscalls.c b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/syscalls.c new file mode 100644 index 00000000..8e2a1642 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/XnuInternal/syscalls.c @@ -0,0 +1,824 @@ +/* + * Copyright (c) 2004-2008 Apple Inc. All rights reserved. + * + * @APPLE_OSREFERENCE_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. The rights granted to you under the License + * may not be used to create, or enable the creation or redistribution of, + * unlawful or unlicensed copies of an Apple operating system, or to + * circumvent, violate, or enable the circumvention or violation of, any + * terms of an Apple operating system software license agreement. + * + * 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_OSREFERENCE_LICENSE_HEADER_END@ + * + * + * System call switch table. + * + * DO NOT EDIT-- this file is automatically generated. + * created from /Users/adam/Documents/sources/xnu/build/xnu-6153.11.26/bsd/kern/syscalls.master + */ + +#define SOCKETS 1 +#define PSYNCH 1 +#define CONFIG_WORKQUEUE 1 +#define OLD_SEMWAIT_SIGNAL 1 + +const char *syscallnames[] = { + "syscall", /* 0 = syscall indirect syscall */ + "exit", /* 1 = exit */ + "fork", /* 2 = fork */ + "read", /* 3 = read */ + "write", /* 4 = write */ + "open", /* 5 = open */ + "close", /* 6 = close */ + "wait4", /* 7 = wait4 */ + "#8", /* 8 = old creat */ + "link", /* 9 = link */ + "unlink", /* 10 = unlink */ + "#11", /* 11 = old execv */ + "chdir", /* 12 = chdir */ + "fchdir", /* 13 = fchdir */ + "mknod", /* 14 = mknod */ + "chmod", /* 15 = chmod */ + "chown", /* 16 = chown */ + "#17", /* 17 = old break */ + "getfsstat", /* 18 = getfsstat */ + "#19", /* 19 = old lseek */ + "getpid", /* 20 = getpid */ + "#21", /* 21 = old mount */ + "#22", /* 22 = old umount */ + "setuid", /* 23 = setuid */ + "getuid", /* 24 = getuid */ + "geteuid", /* 25 = geteuid */ + "ptrace", /* 26 = ptrace */ +#if SOCKETS + "recvmsg", /* 27 = recvmsg */ + "sendmsg", /* 28 = sendmsg */ + "recvfrom", /* 29 = recvfrom */ + "accept", /* 30 = accept */ + "getpeername", /* 31 = getpeername */ + "getsockname", /* 32 = getsockname */ +#else + "#27", /* 27 = */ + "#28", /* 28 = */ + "#29", /* 29 = */ + "#30", /* 30 = */ + "#31", /* 31 = */ + "#32", /* 32 = */ +#endif /* SOCKETS */ + "access", /* 33 = access */ + "chflags", /* 34 = chflags */ + "fchflags", /* 35 = fchflags */ + "sync", /* 36 = sync */ + "kill", /* 37 = kill */ + "#38", /* 38 = old stat */ + "getppid", /* 39 = getppid */ + "#40", /* 40 = old lstat */ + "dup", /* 41 = dup */ + "pipe", /* 42 = pipe */ + "getegid", /* 43 = getegid */ + "#44", /* 44 = old profil */ + "#45", /* 45 = old ktrace */ + "sigaction", /* 46 = sigaction */ + "getgid", /* 47 = getgid */ + "sigprocmask", /* 48 = sigprocmask */ + "getlogin", /* 49 = getlogin */ + "setlogin", /* 50 = setlogin */ + "acct", /* 51 = acct */ + "sigpending", /* 52 = sigpending */ + "sigaltstack", /* 53 = sigaltstack */ + "ioctl", /* 54 = ioctl */ + "reboot", /* 55 = reboot */ + "revoke", /* 56 = revoke */ + "symlink", /* 57 = symlink */ + "readlink", /* 58 = readlink */ + "execve", /* 59 = execve */ + "umask", /* 60 = umask */ + "chroot", /* 61 = chroot */ + "#62", /* 62 = old fstat */ + "#63", /* 63 = used internally and reserved */ + "#64", /* 64 = old getpagesize */ + "msync", /* 65 = msync */ + "vfork", /* 66 = vfork */ + "#67", /* 67 = old vread */ + "#68", /* 68 = old vwrite */ + "#69", /* 69 = old sbrk */ + "#70", /* 70 = old sstk */ + "#71", /* 71 = old mmap */ + "#72", /* 72 = old vadvise */ + "munmap", /* 73 = munmap */ + "mprotect", /* 74 = mprotect */ + "madvise", /* 75 = madvise */ + "#76", /* 76 = old vhangup */ + "#77", /* 77 = old vlimit */ + "mincore", /* 78 = mincore */ + "getgroups", /* 79 = getgroups */ + "setgroups", /* 80 = setgroups */ + "getpgrp", /* 81 = getpgrp */ + "setpgid", /* 82 = setpgid */ + "setitimer", /* 83 = setitimer */ + "#84", /* 84 = old wait */ + "swapon", /* 85 = swapon */ + "getitimer", /* 86 = getitimer */ + "#87", /* 87 = old gethostname */ + "#88", /* 88 = old sethostname */ + "getdtablesize", /* 89 = getdtablesize */ + "dup2", /* 90 = dup2 */ + "#91", /* 91 = old getdopt */ + "fcntl", /* 92 = fcntl */ + "select", /* 93 = select */ + "#94", /* 94 = old setdopt */ + "fsync", /* 95 = fsync */ + "setpriority", /* 96 = setpriority */ +#if SOCKETS + "socket", /* 97 = socket */ + "connect", /* 98 = connect */ +#else + "#97", /* 97 = */ + "#98", /* 98 = */ +#endif /* SOCKETS */ + "#99", /* 99 = old accept */ + "getpriority", /* 100 = getpriority */ + "#101", /* 101 = old send */ + "#102", /* 102 = old recv */ + "#103", /* 103 = old sigreturn */ +#if SOCKETS + "bind", /* 104 = bind */ + "setsockopt", /* 105 = setsockopt */ + "listen", /* 106 = listen */ +#else + "#104", /* 104 = */ + "#105", /* 105 = */ + "#106", /* 106 = */ +#endif /* SOCKETS */ + "#107", /* 107 = old vtimes */ + "#108", /* 108 = old sigvec */ + "#109", /* 109 = old sigblock */ + "#110", /* 110 = old sigsetmask */ + "sigsuspend", /* 111 = sigsuspend */ + "#112", /* 112 = old sigstack */ +#if SOCKETS + "#113", /* 113 = old recvmsg */ + "#114", /* 114 = old sendmsg */ +#else + "#113", /* 113 = */ + "#114", /* 114 = */ +#endif /* SOCKETS */ + "#115", /* 115 = old vtrace */ + "gettimeofday", /* 116 = gettimeofday */ + "getrusage", /* 117 = getrusage */ +#if SOCKETS + "getsockopt", /* 118 = getsockopt */ +#else + "#118", /* 118 = */ +#endif /* SOCKETS */ + "#119", /* 119 = old resuba */ + "readv", /* 120 = readv */ + "writev", /* 121 = writev */ + "settimeofday", /* 122 = settimeofday */ + "fchown", /* 123 = fchown */ + "fchmod", /* 124 = fchmod */ + "#125", /* 125 = old recvfrom */ + "setreuid", /* 126 = setreuid */ + "setregid", /* 127 = setregid */ + "rename", /* 128 = rename */ + "#129", /* 129 = old truncate */ + "#130", /* 130 = old ftruncate */ + "flock", /* 131 = flock */ + "mkfifo", /* 132 = mkfifo */ +#if SOCKETS + "sendto", /* 133 = sendto */ + "shutdown", /* 134 = shutdown */ + "socketpair", /* 135 = socketpair */ +#else + "#133", /* 133 = */ + "#134", /* 134 = */ + "#135", /* 135 = */ +#endif /* SOCKETS */ + "mkdir", /* 136 = mkdir */ + "rmdir", /* 137 = rmdir */ + "utimes", /* 138 = utimes */ + "futimes", /* 139 = futimes */ + "adjtime", /* 140 = adjtime */ + "#141", /* 141 = old getpeername */ + "gethostuuid", /* 142 = gethostuuid */ + "#143", /* 143 = old sethostid */ + "#144", /* 144 = old getrlimit */ + "#145", /* 145 = old setrlimit */ + "#146", /* 146 = old killpg */ + "setsid", /* 147 = setsid */ + "#148", /* 148 = old setquota */ + "#149", /* 149 = old qquota */ + "#150", /* 150 = old getsockname */ + "getpgid", /* 151 = getpgid */ + "setprivexec", /* 152 = setprivexec */ + "pread", /* 153 = pread */ + "pwrite", /* 154 = pwrite */ +#if NFSSERVER + "nfssvc", /* 155 = nfssvc */ +#else + "#155", /* 155 = */ +#endif + "#156", /* 156 = old getdirentries */ + "statfs", /* 157 = statfs */ + "fstatfs", /* 158 = fstatfs */ + "unmount", /* 159 = unmount */ + "#160", /* 160 = old async_daemon */ +#if NFSSERVER + "getfh", /* 161 = getfh */ +#else + "#161", /* 161 = */ +#endif + "#162", /* 162 = old getdomainname */ + "#163", /* 163 = old setdomainname */ + "#164", /* 164 = */ + "quotactl", /* 165 = quotactl */ + "#166", /* 166 = old exportfs */ + "mount", /* 167 = mount */ + "#168", /* 168 = old ustat */ + "csops", /* 169 = csops */ + "csops_audittoken", /* 170 = csops_audittoken */ + "#171", /* 171 = old wait3 */ + "#172", /* 172 = old rpause */ + "waitid", /* 173 = waitid */ + "#174", /* 174 = old getdents */ + "#175", /* 175 = old gc_control */ + "#176", /* 176 = old add_profil */ + "kdebug_typefilter", /* 177 = kdebug_typefilter */ + "kdebug_trace_string", /* 178 = kdebug_trace_string */ + "kdebug_trace64", /* 179 = kdebug_trace64 */ + "kdebug_trace", /* 180 = kdebug_trace */ + "setgid", /* 181 = setgid */ + "setegid", /* 182 = setegid */ + "seteuid", /* 183 = seteuid */ + "sigreturn", /* 184 = sigreturn */ + "#185", /* 185 = old chud */ + "thread_selfcounts", /* 186 = thread_selfcounts */ + "fdatasync", /* 187 = fdatasync */ + "stat", /* 188 = stat */ + "fstat", /* 189 = fstat */ + "lstat", /* 190 = lstat */ + "pathconf", /* 191 = pathconf */ + "fpathconf", /* 192 = fpathconf */ + "#193", /* 193 = old getfsstat */ + "getrlimit", /* 194 = getrlimit */ + "setrlimit", /* 195 = setrlimit */ + "getdirentries", /* 196 = getdirentries */ + "mmap", /* 197 = mmap */ + "#198", /* 198 = old __syscall */ + "lseek", /* 199 = lseek */ + "truncate", /* 200 = truncate */ + "ftruncate", /* 201 = ftruncate */ + "sysctl", /* 202 = sysctl */ + "mlock", /* 203 = mlock */ + "munlock", /* 204 = munlock */ + "undelete", /* 205 = undelete */ + "#206", /* 206 = old ATsocket */ + "#207", /* 207 = old ATgetmsg */ + "#208", /* 208 = old ATputmsg */ + "#209", /* 209 = old ATsndreq */ + "#210", /* 210 = old ATsndrsp */ + "#211", /* 211 = old ATgetreq */ + "#212", /* 212 = old ATgetrsp */ + "#213", /* 213 = Reserved for AppleTalk */ + "#214", /* 214 = */ + "#215", /* 215 = */ + "open_dprotected_np", /* 216 = open_dprotected_np */ + "fsgetpath_ext", /* 217 = fsgetpath_ext */ + "#218", /* 218 = old lstatv */ + "#219", /* 219 = old fstatv */ + "getattrlist", /* 220 = getattrlist */ + "setattrlist", /* 221 = setattrlist */ + "getdirentriesattr", /* 222 = getdirentriesattr */ + "exchangedata", /* 223 = exchangedata */ + "#224", /* 224 = old checkuseraccess or fsgetpath */ + "searchfs", /* 225 = searchfs */ + "delete", /* 226 = delete private delete ( Carbon semantics ) */ + "copyfile", /* 227 = copyfile */ + "fgetattrlist", /* 228 = fgetattrlist */ + "fsetattrlist", /* 229 = fsetattrlist */ + "poll", /* 230 = poll */ + "watchevent", /* 231 = watchevent */ + "waitevent", /* 232 = waitevent */ + "modwatch", /* 233 = modwatch */ + "getxattr", /* 234 = getxattr */ + "fgetxattr", /* 235 = fgetxattr */ + "setxattr", /* 236 = setxattr */ + "fsetxattr", /* 237 = fsetxattr */ + "removexattr", /* 238 = removexattr */ + "fremovexattr", /* 239 = fremovexattr */ + "listxattr", /* 240 = listxattr */ + "flistxattr", /* 241 = flistxattr */ + "fsctl", /* 242 = fsctl */ + "initgroups", /* 243 = initgroups */ + "posix_spawn", /* 244 = posix_spawn */ + "ffsctl", /* 245 = ffsctl */ + "#246", /* 246 = */ +#if NFSCLIENT + "nfsclnt", /* 247 = nfsclnt */ +#else + "#247", /* 247 = */ +#endif +#if NFSSERVER + "fhopen", /* 248 = fhopen */ +#else + "#248", /* 248 = */ +#endif + "#249", /* 249 = */ + "minherit", /* 250 = minherit */ +#if SYSV_SEM + "semsys", /* 251 = semsys */ +#else + "#251", /* 251 = */ +#endif +#if SYSV_MSG + "msgsys", /* 252 = msgsys */ +#else + "#252", /* 252 = */ +#endif +#if SYSV_SHM + "shmsys", /* 253 = shmsys */ +#else + "#253", /* 253 = */ +#endif +#if SYSV_SEM + "semctl", /* 254 = semctl */ + "semget", /* 255 = semget */ + "semop", /* 256 = semop */ + "#257", /* 257 = old semconfig */ +#else + "#254", /* 254 = */ + "#255", /* 255 = */ + "#256", /* 256 = */ + "#257", /* 257 = */ +#endif +#if SYSV_MSG + "msgctl", /* 258 = msgctl */ + "msgget", /* 259 = msgget */ + "msgsnd", /* 260 = msgsnd */ + "msgrcv", /* 261 = msgrcv */ +#else + "#258", /* 258 = */ + "#259", /* 259 = */ + "#260", /* 260 = */ + "#261", /* 261 = */ +#endif +#if SYSV_SHM + "shmat", /* 262 = shmat */ + "shmctl", /* 263 = shmctl */ + "shmdt", /* 264 = shmdt */ + "shmget", /* 265 = shmget */ +#else + "#262", /* 262 = */ + "#263", /* 263 = */ + "#264", /* 264 = */ + "#265", /* 265 = */ +#endif + "shm_open", /* 266 = shm_open */ + "shm_unlink", /* 267 = shm_unlink */ + "sem_open", /* 268 = sem_open */ + "sem_close", /* 269 = sem_close */ + "sem_unlink", /* 270 = sem_unlink */ + "sem_wait", /* 271 = sem_wait */ + "sem_trywait", /* 272 = sem_trywait */ + "sem_post", /* 273 = sem_post */ + "sysctlbyname", /* 274 = sysctlbyname */ + "#275", /* 275 = old sem_init */ + "#276", /* 276 = old sem_destroy */ + "open_extended", /* 277 = open_extended */ + "umask_extended", /* 278 = umask_extended */ + "stat_extended", /* 279 = stat_extended */ + "lstat_extended", /* 280 = lstat_extended */ + "fstat_extended", /* 281 = fstat_extended */ + "chmod_extended", /* 282 = chmod_extended */ + "fchmod_extended", /* 283 = fchmod_extended */ + "access_extended", /* 284 = access_extended */ + "settid", /* 285 = settid */ + "gettid", /* 286 = gettid */ + "setsgroups", /* 287 = setsgroups */ + "getsgroups", /* 288 = getsgroups */ + "setwgroups", /* 289 = setwgroups */ + "getwgroups", /* 290 = getwgroups */ + "mkfifo_extended", /* 291 = mkfifo_extended */ + "mkdir_extended", /* 292 = mkdir_extended */ +#if CONFIG_EXT_RESOLVER + "identitysvc", /* 293 = identitysvc */ +#else + "#293", /* 293 = */ +#endif + "shared_region_check_np", /* 294 = shared_region_check_np */ + "#295", /* 295 = old shared_region_map_np */ + "vm_pressure_monitor", /* 296 = vm_pressure_monitor */ +#if PSYNCH + "psynch_rw_longrdlock", /* 297 = psynch_rw_longrdlock */ + "psynch_rw_yieldwrlock", /* 298 = psynch_rw_yieldwrlock */ + "psynch_rw_downgrade", /* 299 = psynch_rw_downgrade */ + "psynch_rw_upgrade", /* 300 = psynch_rw_upgrade */ + "psynch_mutexwait", /* 301 = psynch_mutexwait */ + "psynch_mutexdrop", /* 302 = psynch_mutexdrop */ + "psynch_cvbroad", /* 303 = psynch_cvbroad */ + "psynch_cvsignal", /* 304 = psynch_cvsignal */ + "psynch_cvwait", /* 305 = psynch_cvwait */ + "psynch_rw_rdlock", /* 306 = psynch_rw_rdlock */ + "psynch_rw_wrlock", /* 307 = psynch_rw_wrlock */ + "psynch_rw_unlock", /* 308 = psynch_rw_unlock */ + "psynch_rw_unlock2", /* 309 = psynch_rw_unlock2 */ +#else + "#297", /* 297 = old reset_shared_file */ + "#298", /* 298 = old new_system_shared_regions */ + "#299", /* 299 = old shared_region_map_file_np */ + "#300", /* 300 = old shared_region_make_private_np */ + "#301", /* 301 = */ + "#302", /* 302 = */ + "#303", /* 303 = */ + "#304", /* 304 = */ + "#305", /* 305 = */ + "#306", /* 306 = */ + "#307", /* 307 = */ + "#308", /* 308 = */ + "#309", /* 309 = */ +#endif + "getsid", /* 310 = getsid */ + "settid_with_pid", /* 311 = settid_with_pid */ +#if PSYNCH + "psynch_cvclrprepost", /* 312 = psynch_cvclrprepost */ +#else + "#312", /* 312 = old __pthread_cond_timedwait */ +#endif + "aio_fsync", /* 313 = aio_fsync */ + "aio_return", /* 314 = aio_return */ + "aio_suspend", /* 315 = aio_suspend */ + "aio_cancel", /* 316 = aio_cancel */ + "aio_error", /* 317 = aio_error */ + "aio_read", /* 318 = aio_read */ + "aio_write", /* 319 = aio_write */ + "lio_listio", /* 320 = lio_listio */ + "#321", /* 321 = old __pthread_cond_wait */ + "iopolicysys", /* 322 = iopolicysys */ + "process_policy", /* 323 = process_policy */ + "mlockall", /* 324 = mlockall */ + "munlockall", /* 325 = munlockall */ + "#326", /* 326 = */ + "issetugid", /* 327 = issetugid */ + "__pthread_kill", /* 328 = __pthread_kill */ + "__pthread_sigmask", /* 329 = __pthread_sigmask */ + "__sigwait", /* 330 = __sigwait */ + "__disable_threadsignal", /* 331 = __disable_threadsignal */ + "__pthread_markcancel", /* 332 = __pthread_markcancel */ + "__pthread_canceled", /* 333 = __pthread_canceled */ + "__semwait_signal", /* 334 = __semwait_signal */ + "#335", /* 335 = old utrace */ + "proc_info", /* 336 = proc_info */ +#if SENDFILE + "sendfile", /* 337 = sendfile */ +#else /* !SENDFILE */ + "#337", /* 337 = */ +#endif /* SENDFILE */ + "stat64", /* 338 = stat64 */ + "fstat64", /* 339 = fstat64 */ + "lstat64", /* 340 = lstat64 */ + "stat64_extended", /* 341 = stat64_extended */ + "lstat64_extended", /* 342 = lstat64_extended */ + "fstat64_extended", /* 343 = fstat64_extended */ + "getdirentries64", /* 344 = getdirentries64 */ + "statfs64", /* 345 = statfs64 */ + "fstatfs64", /* 346 = fstatfs64 */ + "getfsstat64", /* 347 = getfsstat64 */ + "__pthread_chdir", /* 348 = __pthread_chdir */ + "__pthread_fchdir", /* 349 = __pthread_fchdir */ + "audit", /* 350 = audit */ + "auditon", /* 351 = auditon */ + "#352", /* 352 = */ + "getauid", /* 353 = getauid */ + "setauid", /* 354 = setauid */ + "#355", /* 355 = old getaudit */ + "#356", /* 356 = old setaudit */ + "getaudit_addr", /* 357 = getaudit_addr */ + "setaudit_addr", /* 358 = setaudit_addr */ + "auditctl", /* 359 = auditctl */ +#if CONFIG_WORKQUEUE + "bsdthread_create", /* 360 = bsdthread_create */ + "bsdthread_terminate", /* 361 = bsdthread_terminate */ +#else + "#360", /* 360 = */ + "#361", /* 361 = */ +#endif /* CONFIG_WORKQUEUE */ + "kqueue", /* 362 = kqueue */ + "kevent", /* 363 = kevent */ + "lchown", /* 364 = lchown */ + "#365", /* 365 = old stack_snapshot */ +#if CONFIG_WORKQUEUE + "bsdthread_register", /* 366 = bsdthread_register */ + "workq_open", /* 367 = workq_open */ + "workq_kernreturn", /* 368 = workq_kernreturn */ +#else + "#366", /* 366 = */ + "#367", /* 367 = */ + "#368", /* 368 = */ +#endif /* CONFIG_WORKQUEUE */ + "kevent64", /* 369 = kevent64 */ +#if OLD_SEMWAIT_SIGNAL + "__old_semwait_signal", /* 370 = __old_semwait_signal */ + "__old_semwait_signal_nocancel", /* 371 = __old_semwait_signal_nocancel */ +#else + "#370", /* 370 = old __semwait_signal */ + "#371", /* 371 = old __semwait_signal */ +#endif + "thread_selfid", /* 372 = thread_selfid */ + "ledger", /* 373 = ledger */ + "kevent_qos", /* 374 = kevent_qos */ + "kevent_id", /* 375 = kevent_id */ + "#376", /* 376 = */ + "#377", /* 377 = */ + "#378", /* 378 = */ + "#379", /* 379 = */ + "__mac_execve", /* 380 = __mac_execve */ +#if CONFIG_MACF + "__mac_syscall", /* 381 = __mac_syscall */ + "__mac_get_file", /* 382 = __mac_get_file */ + "__mac_set_file", /* 383 = __mac_set_file */ + "__mac_get_link", /* 384 = __mac_get_link */ + "__mac_set_link", /* 385 = __mac_set_link */ + "__mac_get_proc", /* 386 = __mac_get_proc */ + "__mac_set_proc", /* 387 = __mac_set_proc */ + "__mac_get_fd", /* 388 = __mac_get_fd */ + "__mac_set_fd", /* 389 = __mac_set_fd */ + "__mac_get_pid", /* 390 = __mac_get_pid */ +#else + "#381", /* 381 = */ + "#382", /* 382 = */ + "#383", /* 383 = */ + "#384", /* 384 = */ + "#385", /* 385 = */ + "#386", /* 386 = */ + "#387", /* 387 = */ + "#388", /* 388 = */ + "#389", /* 389 = */ + "#390", /* 390 = */ +#endif + "#391", /* 391 = */ + "#392", /* 392 = */ + "#393", /* 393 = */ + "pselect", /* 394 = pselect */ + "pselect_nocancel", /* 395 = pselect_nocancel */ + "read_nocancel", /* 396 = read_nocancel */ + "write_nocancel", /* 397 = write_nocancel */ + "open_nocancel", /* 398 = open_nocancel */ + "close_nocancel", /* 399 = close_nocancel */ + "wait4_nocancel", /* 400 = wait4_nocancel */ +#if SOCKETS + "recvmsg_nocancel", /* 401 = recvmsg_nocancel */ + "sendmsg_nocancel", /* 402 = sendmsg_nocancel */ + "recvfrom_nocancel", /* 403 = recvfrom_nocancel */ + "accept_nocancel", /* 404 = accept_nocancel */ +#else + "#401", /* 401 = */ + "#402", /* 402 = */ + "#403", /* 403 = */ + "#404", /* 404 = */ +#endif /* SOCKETS */ + "msync_nocancel", /* 405 = msync_nocancel */ + "fcntl_nocancel", /* 406 = fcntl_nocancel */ + "select_nocancel", /* 407 = select_nocancel */ + "fsync_nocancel", /* 408 = fsync_nocancel */ +#if SOCKETS + "connect_nocancel", /* 409 = connect_nocancel */ +#else + "#409", /* 409 = */ +#endif /* SOCKETS */ + "sigsuspend_nocancel", /* 410 = sigsuspend_nocancel */ + "readv_nocancel", /* 411 = readv_nocancel */ + "writev_nocancel", /* 412 = writev_nocancel */ +#if SOCKETS + "sendto_nocancel", /* 413 = sendto_nocancel */ +#else + "#413", /* 413 = */ +#endif /* SOCKETS */ + "pread_nocancel", /* 414 = pread_nocancel */ + "pwrite_nocancel", /* 415 = pwrite_nocancel */ + "waitid_nocancel", /* 416 = waitid_nocancel */ + "poll_nocancel", /* 417 = poll_nocancel */ +#if SYSV_MSG + "msgsnd_nocancel", /* 418 = msgsnd_nocancel */ + "msgrcv_nocancel", /* 419 = msgrcv_nocancel */ +#else + "#418", /* 418 = */ + "#419", /* 419 = */ +#endif + "sem_wait_nocancel", /* 420 = sem_wait_nocancel */ + "aio_suspend_nocancel", /* 421 = aio_suspend_nocancel */ + "__sigwait_nocancel", /* 422 = __sigwait_nocancel */ + "__semwait_signal_nocancel", /* 423 = __semwait_signal_nocancel */ + "__mac_mount", /* 424 = __mac_mount */ +#if CONFIG_MACF + "__mac_get_mount", /* 425 = __mac_get_mount */ +#else + "#425", /* 425 = */ +#endif + "__mac_getfsstat", /* 426 = __mac_getfsstat */ + "fsgetpath", /* 427 = fsgetpath private fsgetpath ( File Manager SPI ) */ + "audit_session_self", /* 428 = audit_session_self */ + "audit_session_join", /* 429 = audit_session_join */ + "fileport_makeport", /* 430 = fileport_makeport */ + "fileport_makefd", /* 431 = fileport_makefd */ + "audit_session_port", /* 432 = audit_session_port */ + "pid_suspend", /* 433 = pid_suspend */ + "pid_resume", /* 434 = pid_resume */ +#if CONFIG_EMBEDDED + "pid_hibernate", /* 435 = pid_hibernate */ +#else + "#435", /* 435 = */ +#endif +#if SOCKETS + "pid_shutdown_sockets", /* 436 = pid_shutdown_sockets */ +#else + "#436", /* 436 = */ +#endif + "#437", /* 437 = old shared_region_slide_np */ + "shared_region_map_and_slide_np", /* 438 = shared_region_map_and_slide_np */ + "kas_info", /* 439 = kas_info */ +#if CONFIG_MEMORYSTATUS + "memorystatus_control", /* 440 = memorystatus_control */ +#else + "#440", /* 440 = */ +#endif + "guarded_open_np", /* 441 = guarded_open_np */ + "guarded_close_np", /* 442 = guarded_close_np */ + "guarded_kqueue_np", /* 443 = guarded_kqueue_np */ + "change_fdguard_np", /* 444 = change_fdguard_np */ + "usrctl", /* 445 = usrctl */ + "proc_rlimit_control", /* 446 = proc_rlimit_control */ +#if SOCKETS + "connectx", /* 447 = connectx */ + "disconnectx", /* 448 = disconnectx */ + "peeloff", /* 449 = peeloff */ + "socket_delegate", /* 450 = socket_delegate */ +#else + "#447", /* 447 = */ + "#448", /* 448 = */ + "#449", /* 449 = */ + "#450", /* 450 = */ +#endif /* SOCKETS */ + "telemetry", /* 451 = telemetry */ +#if CONFIG_PROC_UUID_POLICY + "proc_uuid_policy", /* 452 = proc_uuid_policy */ +#else + "#452", /* 452 = */ +#endif +#if CONFIG_MEMORYSTATUS + "memorystatus_get_level", /* 453 = memorystatus_get_level */ +#else + "#453", /* 453 = */ +#endif + "system_override", /* 454 = system_override */ + "vfs_purge", /* 455 = vfs_purge */ + "sfi_ctl", /* 456 = sfi_ctl */ + "sfi_pidctl", /* 457 = sfi_pidctl */ +#if CONFIG_COALITIONS + "coalition", /* 458 = coalition */ + "coalition_info", /* 459 = coalition_info */ +#else + "#458", /* 458 = */ + "#459", /* 459 = */ +#endif /* COALITIONS */ +#if NECP + "necp_match_policy", /* 460 = necp_match_policy */ +#else + "#460", /* 460 = */ +#endif /* NECP */ + "getattrlistbulk", /* 461 = getattrlistbulk */ + "clonefileat", /* 462 = clonefileat */ + "openat", /* 463 = openat */ + "openat_nocancel", /* 464 = openat_nocancel */ + "renameat", /* 465 = renameat */ + "faccessat", /* 466 = faccessat */ + "fchmodat", /* 467 = fchmodat */ + "fchownat", /* 468 = fchownat */ + "fstatat", /* 469 = fstatat */ + "fstatat64", /* 470 = fstatat64 */ + "linkat", /* 471 = linkat */ + "unlinkat", /* 472 = unlinkat */ + "readlinkat", /* 473 = readlinkat */ + "symlinkat", /* 474 = symlinkat */ + "mkdirat", /* 475 = mkdirat */ + "getattrlistat", /* 476 = getattrlistat */ + "proc_trace_log", /* 477 = proc_trace_log */ + "bsdthread_ctl", /* 478 = bsdthread_ctl */ + "openbyid_np", /* 479 = openbyid_np */ +#if SOCKETS + "recvmsg_x", /* 480 = recvmsg_x */ + "sendmsg_x", /* 481 = sendmsg_x */ +#else + "#480", /* 480 = */ + "#481", /* 481 = */ +#endif /* SOCKETS */ + "thread_selfusage", /* 482 = thread_selfusage */ +#if CONFIG_CSR + "csrctl", /* 483 = csrctl */ +#else + "#483", /* 483 = */ +#endif /* CSR */ + "guarded_open_dprotected_np", /* 484 = guarded_open_dprotected_np */ + "guarded_write_np", /* 485 = guarded_write_np */ + "guarded_pwrite_np", /* 486 = guarded_pwrite_np */ + "guarded_writev_np", /* 487 = guarded_writev_np */ + "renameatx_np", /* 488 = renameatx_np */ +#if CONFIG_CODE_DECRYPTION + "mremap_encrypted", /* 489 = mremap_encrypted */ +#else + "#489", /* 489 = */ +#endif +#if NETWORKING + "netagent_trigger", /* 490 = netagent_trigger */ +#else + "#490", /* 490 = */ +#endif /* NETWORKING */ + "stack_snapshot_with_config", /* 491 = stack_snapshot_with_config */ +#if CONFIG_TELEMETRY + "microstackshot", /* 492 = microstackshot */ +#else + "#492", /* 492 = */ +#endif /* CONFIG_TELEMETRY */ +#if PGO + "grab_pgo_data", /* 493 = grab_pgo_data */ +#else + "#493", /* 493 = */ +#endif +#if CONFIG_PERSONAS + "persona", /* 494 = persona */ +#else + "#494", /* 494 = */ +#endif + "#495", /* 495 = */ + "#496", /* 496 = */ + "#497", /* 497 = */ + "#498", /* 498 = */ + "work_interval_ctl", /* 499 = work_interval_ctl */ + "getentropy", /* 500 = getentropy */ +#if NECP + "necp_open", /* 501 = necp_open */ + "necp_client_action", /* 502 = necp_client_action */ +#else + "#501", /* 501 = */ + "#502", /* 502 = */ +#endif /* NECP */ + "#503", /* 503 = */ + "#504", /* 504 = */ + "#505", /* 505 = */ + "#506", /* 506 = */ + "#507", /* 507 = */ + "#508", /* 508 = */ + "#509", /* 509 = */ + "#510", /* 510 = */ + "#511", /* 511 = */ + "#512", /* 512 = */ + "#513", /* 513 = */ + "#514", /* 514 = */ + "ulock_wait", /* 515 = ulock_wait */ + "ulock_wake", /* 516 = ulock_wake */ + "fclonefileat", /* 517 = fclonefileat */ + "fs_snapshot", /* 518 = fs_snapshot */ + "#519", /* 519 = */ + "terminate_with_payload", /* 520 = terminate_with_payload */ + "abort_with_payload", /* 521 = abort_with_payload */ +#if NECP + "necp_session_open", /* 522 = necp_session_open */ + "necp_session_action", /* 523 = necp_session_action */ +#else /* NECP */ + "#522", /* 522 = */ + "#523", /* 523 = */ +#endif /* NECP */ + "setattrlistat", /* 524 = setattrlistat */ + "net_qos_guideline", /* 525 = net_qos_guideline */ + "fmount", /* 526 = fmount */ + "ntp_adjtime", /* 527 = ntp_adjtime */ + "ntp_gettime", /* 528 = ntp_gettime */ + "os_fault_with_payload", /* 529 = os_fault_with_payload */ +#if CONFIG_WORKQUEUE + "kqueue_workloop_ctl", /* 530 = kqueue_workloop_ctl */ +#else + "#530", /* 530 = */ +#endif // CONFIG_WORKQUEUE + "__mach_bridge_remote_time", /* 531 = __mach_bridge_remote_time */ +#if CONFIG_COALITIONS + "coalition_ledger", /* 532 = coalition_ledger */ +#else + "#532", /* 532 = */ +#endif // CONFIG_COALITIONS + "log_data", /* 533 = log_data */ + "memorystatus_available_memory", /* 534 = memorystatus_available_memory */ +}; \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/deprecated/mach_system_call.cc b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/deprecated/mach_system_call.cc new file mode 100644 index 00000000..d8243da0 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/deprecated/mach_system_call.cc @@ -0,0 +1,82 @@ +#include "dobby_internal.h" + +#include "MachUtility.h" + +#include "PlatformUtil/ProcessRuntimeUtility.h" + +#include +#include + +#include + +#include "misc-helper/async_logger.h" + +extern char *mach_msg_to_str(mach_msg_header_t *msg); + +#if 0 +typeof(mach_msg) *orig_mach_msg = NULL; + +mach_msg_return_t fake_mach_msg(mach_msg_header_t *msg, mach_msg_option_t option, mach_msg_size_t send_size, + mach_msg_size_t rcv_size, mach_port_name_t rcv_name, mach_msg_timeout_t timeout, + mach_port_name_t notify) { + char buffer[256] = {0}; + char *mach_msg_name = mach_msg_to_str(msg); + if(mach_msg_name) { + sprintf(buffer, "[%d][mach_msg] %s\n",i++, mach_msg_name); + async_logger_print(buffer); + } +#if 0 + { + write(STDOUT_FILENO, buffer, strlen(buffer) + 1); + } +#endif + return orig_mach_msg(msg, option, send_size, rcv_size, rcv_name, timeout, notify); +} + +void mach_system_call_monitor() { + void *mach_msg_ptr = (void *)DobbySymbolResolver(NULL, "mach_msg"); + log_set_level(1); + DobbyHook(mach_msg_ptr, (void *)fake_mach_msg, (void **)&orig_mach_msg); +} +#endif + +static addr_t getCallFirstArg(RegisterContext *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 void common_handler(RegisterContext *ctx, const HookEntryInfo *info) { + addr_t caller = get_caller_from_main_binary(ctx); + if (caller == 0) + return; + + char buffer[256] = {0}; + 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 %p] %s\n", caller, mach_msg_name); + } else { + buffer[0] = 0; + } + if (buffer[0]) + async_logger_print(buffer); +} + +void mach_system_call_monitor() { + void *mach_msg_ptr = (void *)DobbySymbolResolver(NULL, "mach_msg"); + log_set_level(1); + DobbyInstrument(mach_msg_ptr, common_handler); +} diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/deprecated/system_call.cc b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/deprecated/system_call.cc new file mode 100644 index 00000000..22f05d9a --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/deprecated/system_call.cc @@ -0,0 +1,119 @@ +#include "dobby_internal.h" + +#include "PlatformUtil/ProcessRuntimeUtility.h" + +#include + +#include +#include + +#include + +#include +#include +#include + +#include "misc-helper/async_logger.h" + +static addr_t getCallFirstArg(RegisterContext *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; +} + +extern const char *syscall_num_to_str(int num); + +extern const char *mach_syscall_num_to_str(int num); + +extern char *mach_msg_to_str(mach_msg_header_t *msg); + +static void common_handler(RegisterContext *ctx, const HookEntryInfo *info) { + char buffer[256] = {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 == -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, "[svc-%d] %s\n", syscall_rum, syscall_num_to_str(syscall_rum)); + } else { + sprintf(buffer, "[mach svc-%d] %s\n", syscall_rum, mach_syscall_num_to_str(syscall_rum)); + } + async_logger_print(buffer); +} + +typedef int32_t arm64_instr_t; + +void monitor_libsystem_kernel_dylib() { + auto libsystem_c = ProcessRuntimeUtility::GetProcessModule("libsystem_kernel.dylib"); + addr_t libsystem_c_header = (addr_t)libsystem_c.load_address; + auto text_section = + mach_kit::macho_get_section_by_name_64((struct mach_header_64 *)libsystem_c_header, "__TEXT", "__text"); + + addr_t shared_cache_load_addr = (addr_t)mach_kit::macho_get_shared_cache(); + 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(arm64_instr_t)) { + if (*(arm64_instr_t *)insn_addr == 0xd4001001) { + dobby_enable_near_branch_trampoline(); + if (insn_addr == write_svc_addr) + continue; + + if (insn_addr == __psynch_mutexwait_svc_addr) + continue; + DobbyInstrument((void *)insn_addr, common_handler); + LOG(2, "instrument svc at %p", insn_addr); + } + } +} + +void monitor_main_binary() { + auto main = ProcessRuntimeUtility::GetProcessModuleMap()[0]; + addr_t main_header = (addr_t)main.load_address; + auto text_section = mach_kit::macho_get_section_by_name_64((struct mach_header_64 *)main_header, "__TEXT", "__text"); + + addr_t insn_addr = main_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(arm64_instr_t)) { + if (*(arm64_instr_t *)insn_addr == 0xd4001001) { + DobbyInstrument((void *)insn_addr, common_handler); + LOG(2, "instrument svc at %p", insn_addr); + } + } +} + +void system_call_monitor() { +#if 0 + monitor_libsystem_kernel_dylib(); +#endif + + monitor_main_binary(); +} diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/mach_system_call_log_handler.cc b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/mach_system_call_log_handler.cc new file mode 100644 index 00000000..fac21886 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/mach_system_call_log_handler.cc @@ -0,0 +1,193 @@ +#include "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(RegisterContext *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(RegisterContext *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(RegisterContext *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(RegisterContext *ctx, const HookEntryInfo *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/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/misc_utility.cc b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/misc_utility.cc new file mode 100644 index 00000000..2a0a05bc --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/misc_utility.cc @@ -0,0 +1,44 @@ +#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/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/misc_utility.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/misc_utility.h new file mode 100644 index 00000000..1c356c03 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/misc_utility.h @@ -0,0 +1,28 @@ +#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/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/sensitive_api_monitor.cc b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/sensitive_api_monitor.cc new file mode 100644 index 00000000..23a759bf --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/sensitive_api_monitor.cc @@ -0,0 +1,95 @@ +#include "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(RegisterContext *ctx, const HookEntryInfo *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; + // LOG(2, "syscall svc ptrace deny"); + } + } + if (syscall_rum == SYS_exit) { + // LOG(2, "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; + // LOG(2, "svc ptrace deny"); + } + } + if (syscall_rum == SYS_exit) { + // LOG(2, "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) { + LOG(2, "not found func %s", sensitive_func_array[i]); + continue; + } + int func_svc_offset = get_func_svc_offset(func_addr); + if (func_svc_offset == 0) { + LOG(2, "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/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/supervisor_call_monitor.cc b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/supervisor_call_monitor.cc new file mode 100644 index 00000000..d4b7d3e2 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/supervisor_call_monitor.cc @@ -0,0 +1,138 @@ +#include "SupervisorCallMonitor/misc_utility.h" +#include "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(RegisterContext *ctx, const HookEntryInfo *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)) { + LOG(2, "[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"); + LOG(2, "HOME: %s", logger_path); + async_logger_init(logger_path); + + dobby_enable_near_branch_trampoline(); +} diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/supervisor_call_monitor.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/supervisor_call_monitor.h new file mode 100644 index 00000000..45bde0a4 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/supervisor_call_monitor.h @@ -0,0 +1,24 @@ +#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/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/system_call_log_handler.cc b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/system_call_log_handler.cc new file mode 100644 index 00000000..90f9209d --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/system_call_log_handler.cc @@ -0,0 +1,98 @@ +#include "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(RegisterContext *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(RegisterContext *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(RegisterContext *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 syscall_log_handler(RegisterContext *ctx, const HookEntryInfo *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/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/test_supervisor_call_monitor.cc b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/test_supervisor_call_monitor.cc new file mode 100644 index 00000000..862c4e1c --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SupervisorCallMonitor/test_supervisor_call_monitor.cc @@ -0,0 +1,16 @@ + +#include "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/Bcore/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/CMakeLists.txt b/Bcore/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/CMakeLists.txt new file mode 100644 index 00000000..2164bb40 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/CMakeLists.txt @@ -0,0 +1,35 @@ +set(SOURCE_FILE_LIST ) + +if(NOT DEFINED DOBBY_DIR) + message(FATAL_ERROR "DOBBY_DIR must be set!") +endif() + +if(SYSTEM.Darwin) + set(SOURCE_FILE_LIST ${SOURCE_FILE_LIST} + ${CMAKE_CURRENT_SOURCE_DIR}/macho/dyld_shared_cache_symbol_table_iterator.cc + ${CMAKE_CURRENT_SOURCE_DIR}/macho/dobby_symbol_resolver.cc + + ${DOBBY_DIR}/source/UserMode/PlatformUtil/Darwin/ProcessRuntimeUtility.cc + ) +endif() +if(SYSTEM.Linux OR SYSTEM.Android) + set(SOURCE_FILE_LIST ${SOURCE_FILE_LIST} + ${CMAKE_CURRENT_SOURCE_DIR}/elf/dobby_symbol_resolver.cc + + ${DOBBY_DIR}/source/UserMode/PlatformUtil/Linux/ProcessRuntimeUtility.cc + ) +endif() +if(SYSTEM.Windows) + set(SOURCE_FILE_LIST ${SOURCE_FILE_LIST} + ${DOBBY_DIR}/source/UserMode/PlatformUtil/Windows/ProcessRuntimeUtility.cc + ) +endif() + +add_library(symbol_resolver STATIC + ${SOURCE_FILE_LIST} + ) + +include_directories( + . +) + diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/dobby_symbol_resolver.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/dobby_symbol_resolver.h new file mode 100644 index 00000000..96acfb3d --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/dobby_symbol_resolver.h @@ -0,0 +1,14 @@ +#ifndef DOBBY_SYMBOL_RESOLVER_H +#define DOBBY_SYMBOL_RESOLVER_H + +#ifdef __cplusplus +extern "C" { +#endif + +void *DobbySymbolResolver(const char *image_name, const char *symbol_name); + +#ifdef __cplusplus +} +#endif + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/elf/dobby_symbol_resolver.cc b/Bcore/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/elf/dobby_symbol_resolver.cc new file mode 100644 index 00000000..fb0cd28f --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/elf/dobby_symbol_resolver.cc @@ -0,0 +1,292 @@ +#include "SymbolResolver/dobby_symbol_resolver.h" +#include "common_header.h" + +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include "PlatformUtil/ProcessRuntimeUtility.h" + +#include + +#undef LOG_TAG +#define LOG_TAG "DobbySymbolResolver" + +static void file_mmap(const char *file_path, uint8_t **data_ptr, size_t *data_size_ptr) { + uint8_t *mmap_data = NULL; + size_t file_size = 0; + + int fd = open(file_path, O_RDONLY, 0); + if (fd < 0) { + ERROR_LOG("%s open failed", file_path); + goto finished; + } + + { + struct stat s; + int rt = fstat(fd, &s); + if (rt != 0) { + ERROR_LOG("mmap failed"); + goto finished; + } + file_size = s.st_size; + } + + // auto align + mmap_data = (uint8_t *)mmap(0, file_size, PROT_READ | PROT_WRITE, MAP_FILE | MAP_PRIVATE, fd, 0); + if (mmap_data == MAP_FAILED) { + ERROR_LOG("mmap failed"); + goto finished; + } + +finished: + close(fd); + + if (data_size_ptr) + *data_size_ptr = file_size; + if (data_ptr) + *data_ptr = mmap_data; +} + +static void file_unmap(void *data, size_t data_size) { + int ret = munmap(data, data_size); + if (ret != 0) { + ERROR_LOG("munmap failed"); + return; + } +} + +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); + + uint8_t *file_mem = NULL; + size_t file_mem_size = 0; + if (module.load_address) + file_mmap(module.path, &file_mem, &file_mem_size); + + 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 (file_mem) + file_unmap(file_mem, file_mem_size); + } + + if (!result) { + std::vector ProcessModuleMap = ProcessRuntimeUtility::GetProcessModuleMap(); + for (auto module : ProcessModuleMap) { + uint8_t *file_mem = NULL; + size_t file_mem_size = 0; + + if (module.load_address) + file_mmap(module.path, &file_mem, &file_mem_size); + + 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 (file_mem) + file_unmap(file_mem, file_mem_size); + + 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/Bcore/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/dobby_symbol_resolver.cc b/Bcore/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/dobby_symbol_resolver.cc new file mode 100644 index 00000000..88cbe90b --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/dobby_symbol_resolver.cc @@ -0,0 +1,464 @@ +#include +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include + +#include "SymbolResolver/dobby_symbol_resolver.h" +#include "SymbolResolver/macho/shared_cache_internal.h" + +#include "common_header.h" + +#include "logging/logging.h" + +#include "PlatformUtil/ProcessRuntimeUtility.h" + +#undef LOG_TAG +#define LOG_TAG "DobbySymbolResolver" + +typedef struct macho_ctx { + mach_header_t *header; + + uintptr_t slide; + uintptr_t linkedit_base; + + segment_command_t *segments[16]; + int segments_count; + + segment_command_t *text_seg; + segment_command_t *data_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; + + nlist_t *symtab; + char *strtab; + uint32_t *indirect_symtab; + +} macho_ctx_t; + +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 +uint8_t *walk_exported_trie(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; + // skip flag == EXPORT_SYMBOL_FLAGS_REEXPORT + read_uleb128(&p, end); + return (uint8_t *)read_uleb128(&p, end); + } + 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 NULL; + } + } 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 NULL; + } + 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; + if (visitedNodeOffsetCount >= 128) { + // diag.error("malformed trie too deep\n"); + return NULL; + } + p = &start[nodeOffset]; + } else + p = end; + } + return NULL; +} + +uintptr_t iterate_exported_symbol(mach_header_t *header, const char *symbol_name, uint64_t *out_flags) { + segment_command_t *curr_seg_cmd; + struct dyld_info_command *dyld_info_cmd = NULL; + struct linkedit_data_command *exports_trie_cmd = NULL; + segment_command_t *text_segment, *data_segment, *linkedit_segment; + + curr_seg_cmd = (segment_command_t *)((uintptr_t)header + sizeof(mach_header_t)); + for (int i = 0; i < header->ncmds; i++) { + switch (curr_seg_cmd->cmd) { + case LC_SEGMENT_ARCH_DEPENDENT: { + if (strcmp(curr_seg_cmd->segname, "__LINKEDIT") == 0) { + linkedit_segment = curr_seg_cmd; + } else if (strcmp(curr_seg_cmd->segname, "__TEXT") == 0) { + text_segment = curr_seg_cmd; + } + } break; + case LC_DYLD_EXPORTS_TRIE: { + exports_trie_cmd = (struct linkedit_data_command *)curr_seg_cmd; + } break; + case LC_DYLD_INFO: + case LC_DYLD_INFO_ONLY: { + dyld_info_cmd = (struct dyld_info_command *)curr_seg_cmd; + } break; + default: + break; + }; + curr_seg_cmd = (segment_command_t *)((uintptr_t)curr_seg_cmd + curr_seg_cmd->cmdsize); + } + + if (text_segment == NULL || linkedit_segment == NULL) { + return 0; + } + + 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; + + uintptr_t slide = (uintptr_t)header - (uintptr_t)text_segment->vmaddr; + uintptr_t linkedit_base = (uintptr_t)slide + linkedit_segment->vmaddr - linkedit_segment->fileoff; + + void *exports = (void *)(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 *)walk_exported_trie(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 (flags & EXPORT_SYMBOL_FLAGS_REEXPORT) { + return 0; + } + if (out_flags) + *out_flags = flags; + 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 +} + +void macho_ctx_init(macho_ctx_t *ctx, mach_header_t *header) { + ctx->header = header; + segment_command_t *curr_seg_cmd; + segment_command_t *text_segment, *data_segment, *data_const_segment, *linkedit_segment; + struct symtab_command *symtab_cmd = NULL; + struct dysymtab_command *dysymtab_cmd = NULL; + struct dyld_info_command *dyld_info_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 + ctx->segments[ctx->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 (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; + } + 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; + + ctx->text_seg = text_segment; + ctx->data_seg = data_segment; + ctx->data_const_seg = data_const_segment; + ctx->linkedit_seg = linkedit_segment; + + ctx->symtab_cmd = symtab_cmd; + ctx->dysymtab_cmd = dysymtab_cmd; + ctx->dyld_info_cmd = dyld_info_cmd; + + ctx->slide = slide; + ctx->linkedit_base = linkedit_base; + + ctx->symtab = (nlist_t *)(ctx->linkedit_base + ctx->symtab_cmd->symoff); + ctx->strtab = (char *)(ctx->linkedit_base + ctx->symtab_cmd->stroff); + ctx->indirect_symtab = (uint32_t *)(ctx->linkedit_base + ctx->dysymtab_cmd->indirectsymoff); +} + +uintptr_t iterate_symbol_table(char *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 + LOG(1, "> %s", symbol_name); +#endif + if (strcmp(name_pattern, symbol_name) == 0) { + return symtab[i].n_value; + } + if (symbol_name[0] == '_') { + if (strcmp(name_pattern, &symbol_name[1]) == 0) { + return symtab[i].n_value; + } + } + } + } + return 0; +} + +static uintptr_t macho_kit_get_slide(mach_header_t *header) { + uintptr_t slide = 0; + + segment_command_t *curr_seg_cmd; + + 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 (strcmp(curr_seg_cmd->segname, "__TEXT") == 0) { + slide = (uintptr_t)header - curr_seg_cmd->vmaddr; + return slide; + } + } + curr_seg_cmd = (segment_command_t *)((addr_t)curr_seg_cmd + curr_seg_cmd->cmdsize); + } + return 0; +} + +PUBLIC void *DobbySymbolResolver(const char *image_name, const char *symbol_name_pattern) { + uintptr_t result = 0; + + std::vector ProcessModuleMap = ProcessRuntimeUtility::GetProcessModuleMap(); + + for (auto module : ProcessModuleMap) { + if (image_name != NULL && strstr(module.path, image_name) == NULL) + continue; + + mach_header_t *header = (mach_header_t *)module.load_address; + size_t slide = 0; + + if (header) { + if (header->magic == MH_MAGIC_64) + slide = macho_kit_get_slide(header); + } + +#if 0 + LOG(1, "resolve image: %s", path); +#endif + + nlist_t *symtab = NULL; + uint32_t symtab_count = 0; + char *strtab = NULL; + +#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; + memset(&shared_cache_ctx, 0, sizeof(shared_cache_ctx_t)); + shared_cache_ctx_init(&shared_cache_ctx); + } + if (shared_cache_ctx.runtime_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); + } + } +#endif + if (symtab && strtab) { + result = iterate_symbol_table((char *)symbol_name_pattern, symtab, symtab_count, strtab); + } + if (result) { + result = result + slide; + break; + } + + // binary symbol table + macho_ctx_t macho_ctx; + memset(&macho_ctx, 0, sizeof(macho_ctx_t)); + macho_ctx_init(&macho_ctx, header); + result = iterate_symbol_table((char *)symbol_name_pattern, macho_ctx.symtab, macho_ctx.symtab_cmd->nsyms, + macho_ctx.strtab); + if (result) { + result = result + slide; + break; + } + + // binary exported table(uleb128) + uint64_t flags; + result = iterate_exported_symbol((mach_header_t *)header, symbol_name_pattern, &flags); + if (result) { + switch (flags & EXPORT_SYMBOL_FLAGS_KIND_MASK) { + case EXPORT_SYMBOL_FLAGS_KIND_REGULAR: { + result += (uintptr_t)header; + } break; + case EXPORT_SYMBOL_FLAGS_KIND_THREAD_LOCAL: { + result += (uintptr_t)header; + } break; + case EXPORT_SYMBOL_FLAGS_KIND_ABSOLUTE: { + } break; + default: + break; + } + return (void *)result; + } + } + + 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; + memset(&dyld_ctx, 0, sizeof(macho_ctx_t)); + macho_ctx_init(&dyld_ctx, dyld_header); + result = + iterate_symbol_table((char *)symbol_name_pattern, dyld_ctx.symtab, dyld_ctx.symtab_cmd->nsyms, dyld_ctx.strtab); + if (result) { + result = result + (addr_t)dyld_header; + } + } + + return (void *)result; +} + +#if defined(DOBBY_DEBUG) && 0 +__attribute__((constructor)) static void ctor() { + mach_header_t *header = NULL; + header = (mach_header_t *)_dyld_get_image_header(0); + + void *addr = (void *)((addr_t)iterate_exported_symbol(header, "_mainxx") + (addr_t)header); + LOG(1, "export %p", addr); +} +#endif diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/dyld_shared_cache_symbol_table_iterator.cc b/Bcore/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/dyld_shared_cache_symbol_table_iterator.cc new file mode 100644 index 00000000..27e1dc54 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/dyld_shared_cache_symbol_table_iterator.cc @@ -0,0 +1,240 @@ +#include +#include +#include +#include + +#include // pthread_once +#include // mmap +#include // open + +#include "SymbolResolver/macho/shared_cache_internal.h" +#include "SymbolResolver/macho/shared-cache/dyld_cache_format.h" + +#include "logging/logging.h" + +#undef LOG_TAG +#define LOG_TAG "DobbySymbolResolverCache" + +#if 0 +extern "C" { +int __shared_region_check_np(uint64_t *startaddress); +} +#endif + +extern "C" const char *dyld_shared_cache_file_path(); + +static pthread_once_t mmap_dyld_shared_cache_once = PTHREAD_ONCE_INIT; + +extern "C" int __shared_region_check_np(uint64_t *startaddress); + +#include + +static char *fast_get_shared_cache_path() { +#if defined(_M_IX86) || defined(__i386__) || defined(_M_X64) || defined(__x86_64__) + return NULL; +#endif + char *result = NULL; + char path_buffer[2048] = {0}; + + const char *path = NULL; + do { + path = dyld_shared_cache_file_path(); + if (path != NULL) { + break; + } else { + struct stat statbuf; + int r = 0; + + path = IPHONE_DYLD_SHARED_CACHE_DIR DYLD_SHARED_CACHE_BASE_NAME "arm64"; + r = stat(path, &statbuf); + if (r == 0) { + break; + } + path = IPHONE_DYLD_SHARED_CACHE_DIR DYLD_SHARED_CACHE_BASE_NAME "arm64e"; + r = stat(path, &statbuf); + if (r == 0) { + break; + } + path = MACOSX_MRM_DYLD_SHARED_CACHE_DIR DYLD_SHARED_CACHE_BASE_NAME "arm64"; + r = stat(path, &statbuf); + if (r == 0) { + break; + } + path = MACOSX_MRM_DYLD_SHARED_CACHE_DIR DYLD_SHARED_CACHE_BASE_NAME "arm64e"; + r = stat(path, &statbuf); + if (r == 0) { + break; + } + } + } while (0); + + if (path != NULL) { + strcpy(path_buffer, path); + result = (char *)malloc(strlen(path_buffer) + 1); + strcpy(result, path_buffer); + } + + return result; +} + +#include +#include +#include +struct dyld_cache_header *shared_cache_get_load_addr() { + static struct dyld_cache_header *shared_cache_load_addr = 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; + shared_cache_load_addr = (struct dyld_cache_header *)infos->sharedCacheBaseAddress; + + return shared_cache_load_addr; + +#if 0 + if (shared_cache_load_addr) + return shared_cache_load_addr; +#if 0 + if (syscall(294, &shared_cache_load_addr) == 0) { +#else + if (__shared_region_check_np((uint64_t *)&shared_cache_load_addr) != 0) { +#endif + shared_cache_load_addr = 0; +} +#endif + return shared_cache_load_addr; +} + +int shared_cache_ctx_init(shared_cache_ctx_t *ctx) { + int fd; + const char *cache_file_path = NULL; + + cache_file_path = fast_get_shared_cache_path(); + if (cache_file_path == NULL) { + return -1; + } + + fd = open(cache_file_path, O_RDONLY, 0); + if (fd == -1) { + return KERN_FAILURE; + } + + struct dyld_cache_header *runtime_shared_cache; + struct dyld_cache_header *mmap_shared_cache; + + // auto align + runtime_shared_cache = shared_cache_get_load_addr(); + if (runtime_shared_cache == NULL) { + return KERN_FAILURE; + } + + // maybe shared cache is apple silicon + if (runtime_shared_cache->localSymbolsSize == 0) { + return KERN_FAILURE; + } + + size_t mmap_length = runtime_shared_cache->localSymbolsSize; + off_t mmap_offset = runtime_shared_cache->localSymbolsOffset; + mmap_shared_cache = + (struct dyld_cache_header *)mmap(0, mmap_length, PROT_READ, MAP_FILE | MAP_PRIVATE, fd, mmap_offset); + if (mmap_shared_cache == MAP_FAILED) { + DLOG(0, "mmap shared cache failed"); + return KERN_FAILURE; + } + + // fake shared cache header + mmap_shared_cache = + (struct dyld_cache_header *)((addr_t)mmap_shared_cache - runtime_shared_cache->localSymbolsOffset); + + ctx->runtime_shared_cache = runtime_shared_cache; + ctx->mmap_shared_cache = mmap_shared_cache; + + // shared cache slide + const struct dyld_cache_mapping_info *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; + + // shared cache symbol table + static struct dyld_cache_local_symbols_info *localInfo = NULL; + localInfo = + (struct dyld_cache_local_symbols_info *)((char *)mmap_shared_cache + runtime_shared_cache->localSymbolsOffset); + + static struct dyld_cache_local_symbols_entry *localEntries = NULL; + localEntries = (struct dyld_cache_local_symbols_entry *)((char *)localInfo + localInfo->entriesOffset); + + ctx->local_symbols_info = localInfo; + ctx->local_symbols_entries = localEntries; + + ctx->symtab = (nlist_t *)((char *)localInfo + localInfo->nlistOffset); + ctx->strtab = ((char *)localInfo) + localInfo->stringsOffset; + 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(); + } + + const struct dyld_cache_mapping_info *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); + uintptr_t unslidStart = (uintptr_t)addr - slide; + + // quick out if after end of cache + if (unslidStart > (mappings[2].address + mappings[2].size)) + return false; + + // walk cache regions + const struct dyld_cache_mapping_info *mappingsEnd = &mappings[runtime_shared_cache->mappingCount]; + uintptr_t unslidEnd = unslidStart + length; + for (const struct dyld_cache_mapping_info *m = mappings; m < mappingsEnd; ++m) { + if ((unslidStart >= m->address) && (unslidEnd < (m->address + m->size))) { + 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) { + struct dyld_cache_header *runtime_shared_cache = NULL; + + runtime_shared_cache = ctx->runtime_shared_cache; + + uint64_t textOffsetInCache = (uint64_t)image_header - (uint64_t)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->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]; + +#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; + LOG(1, "dyld image: %s", image_name); +#endif + } + } + *out_symtab = localNlists; + *out_symtab_count = (uint32_t)localNlistCount; + *out_strtab = (char *)ctx->strtab; + return 0; +} diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/shared-cache/dyld_cache_format.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/shared-cache/dyld_cache_format.h new file mode 100644 index 00000000..714291cd --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/shared-cache/dyld_cache_format.h @@ -0,0 +1,481 @@ +/* -*- 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 + +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 imagesOffset; // file offset to first dyld_cache_image_info + uint32_t imagesCount; // number of dyld_cache_image_info entries + 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 + uint32_t branchPoolsOffset; // file offset to table of uint64_t pool addresses + uint32_t branchPoolsCount; // number of uint64_t entries + uint64_t accelerateInfoAddr; // (unslid) address of optimization info + uint64_t accelerateInfoSize; // size of optimization info + 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 of region cache can be mapped into + 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 +}; + +// 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, +}; + +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_patch_info { + uint64_t patchTableArrayAddr; // (unslid) address of array for dyld_cache_image_patches for each image + uint64_t patchTableArrayCount; // count of patch table entries + uint64_t patchExportArrayAddr; // (unslid) address of array for patch exports for each image + uint64_t patchExportArrayCount; // count of patch exports entries + uint64_t patchLocationArrayAddr; // (unslid) address of array for patch locations for each patch + uint64_t patchLocationArrayCount; // count of patch location entries + uint64_t patchExportNamesAddr; // blob of strings of export names for patches + uint64_t patchExportNamesSize; // size of string blob of export names for patches +}; + +struct dyld_cache_image_patches { + uint32_t patchExportsStartIndex; + uint32_t patchExportsCount; +}; + +struct dyld_cache_patchable_export { + uint32_t cacheOffsetOfImpl; + uint32_t patchLocationsStartIndex; + uint32_t patchLocationsCount; + uint32_t exportNameOffset; +}; + +struct dyld_cache_patchable_location { + uint64_t cacheOffset : 32, high7 : 7, + addend : 5, // 0..31 + authenticated : 1, usesAddressDiversity : 1, key : 2, discriminator : 16; +}; + +// 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/" +#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" + +static const uint64_t kDyldSharedCacheTypeDevelopment = 0; +static const uint64_t kDyldSharedCacheTypeProduction = 1; + +#endif // __DYLD_CACHE_FORMAT__ diff --git a/Bcore/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/shared_cache_internal.h b/Bcore/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/shared_cache_internal.h new file mode 100644 index 00000000..928cbe3e --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/builtin-plugin/SymbolResolver/macho/shared_cache_internal.h @@ -0,0 +1,70 @@ +#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 + +#if __i386__ +#define ARCH_NAME "i386" +#define ARCH_CACHE_MAGIC "dyld_v1 i386" +#elif __x86_64__ +#define ARCH_NAME "x86_64" +#define ARCH_CACHE_MAGIC "dyld_v1 x86_64" +#define ARCH_NAME_H "x86_64h" +#define ARCH_CACHE_MAGIC_H "dyld_v1 x86_64h" +#elif __ARM_ARCH_7K__ +#define ARCH_NAME "armv7k" +#define ARCH_CACHE_MAGIC "dyld_v1 armv7k" +#elif __ARM_ARCH_7A__ +#define ARCH_NAME "armv7" +#define ARCH_CACHE_MAGIC "dyld_v1 armv7" +#elif __ARM_ARCH_7S__ +#define ARCH_NAME "armv7s" +#define ARCH_CACHE_MAGIC "dyld_v1 armv7s" +#elif __arm64e__ +#define ARCH_NAME "arm64e" +#define ARCH_CACHE_MAGIC "dyld_v1 arm64e" +#elif __arm64__ +#if __LP64__ +#define ARCH_NAME "arm64" +#define ARCH_CACHE_MAGIC "dyld_v1 arm64" +#else +#define ARCH_NAME "arm64_32" +#define ARCH_CACHE_MAGIC "dyld_v1arm64_32" +#endif +#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; + + struct dyld_cache_local_symbols_info *local_symbols_info; + struct dyld_cache_local_symbols_entry *local_symbols_entries; + + nlist_t *symtab; + char *strtab; + +} shared_cache_ctx_t; + +int shared_cache_ctx_init(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); diff --git a/Bcore/src/main/cpp/Dobby/cmake/AutoFiles.cmake b/Bcore/src/main/cpp/Dobby/cmake/AutoFiles.cmake new file mode 100644 index 00000000..86caa7df --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/cmake/AutoFiles.cmake @@ -0,0 +1,32 @@ +function (AutoFiles _folder _base _pattern) + if (ARGC GREATER 3) + set(_exclude ${ARGN}) + else () + set(_exclude) + endif () + file (GLOB _files RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}/ ${_folder}/*) + set (folderFiles) + foreach (_fname ${_files}) + if (IS_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/${_fname}) + AutoFiles ("${_fname}" "${_base}" "${_pattern}" "${_exclude}") + elseif (_fname MATCHES ${_pattern}) + if(_exclude) + if (NOT _fname MATCHES ${_exclude}) + set(folderFiles ${folderFiles} ${_fname}) + endif () + else () + set(folderFiles ${folderFiles} ${_fname}) + endif () + endif () + endforeach () + + string(REPLACE "./" "" _folder2 ${_folder}) + string(REPLACE "/" "\\" _folder2 ${_folder2}) + if (_folder2 STREQUAL ".") + source_group(${_base} FILES ${folderFiles}) + else () + source_group(${_base}\\${_folder2} FILES ${folderFiles}) + endif () + + set(AUTO_FILES_RESULT ${AUTO_FILES_RESULT} ${folderFiles} PARENT_SCOPE) +endfunction () \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/cmake/Globals.cmake b/Bcore/src/main/cpp/Dobby/cmake/Globals.cmake new file mode 100644 index 00000000..7da0b900 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/cmake/Globals.cmake @@ -0,0 +1,88 @@ +# The Lib Prefix +if (UNIX) + set(LIB_PFX "lib") + if (APPLE) + set(LIB_EXT ".dylib") + else () + set(LIB_EXT ".so") + endif () +else (UNIX) + set(LIB_PFX "") + set(LIB_EXT ".dll") +endif (UNIX) + +message(STATUS "") +message(STATUS "********* build-environment-detected ***********") + + +# The Compilter 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() + +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") + set(SYSTEM.iOS 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/Bcore/src/main/cpp/Dobby/cmake/Macros.cmake b/Bcore/src/main/cpp/Dobby/cmake/Macros.cmake new file mode 100644 index 00000000..5774bef5 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/cmake/Macros.cmake @@ -0,0 +1,3 @@ +macro(SET_OPTION option value) + set(${option} ${value} CACHE INTERNAL "" FORCE) +endmacro() \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/cmake/Util.cmake b/Bcore/src/main/cpp/Dobby/cmake/Util.cmake new file mode 100644 index 00000000..6a722a20 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/cmake/Util.cmake @@ -0,0 +1,19 @@ +# 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() diff --git a/Bcore/src/main/cpp/Dobby/cmake/XcodeGenerator.cmake b/Bcore/src/main/cpp/Dobby/cmake/XcodeGenerator.cmake new file mode 100644 index 00000000..243593dc --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/cmake/XcodeGenerator.cmake @@ -0,0 +1,9 @@ +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/Bcore/src/main/cpp/Dobby/cmake/dobby.xcode.source.cmake b/Bcore/src/main/cpp/Dobby/cmake/dobby.xcode.source.cmake new file mode 100644 index 00000000..0949c5f3 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/cmake/dobby.xcode.source.cmake @@ -0,0 +1,96 @@ +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/modules/assembler/assembler.cc + source/core/modules/assembler/assembler-arm.cc + source/core/modules/assembler/assembler-arm64.cc + source/core/modules/assembler/assembler-ia32.cc + source/core/modules/assembler/assembler-x64.cc + + # codegen + source/core/modules/codegen/codegen-arm.cc + source/core/modules/codegen/codegen-arm64.cc + source/core/modules/codegen/codegen-ia32.cc + source/core/modules/codegen/codegen-x64.cc + + # executable memory - code buffer + source/MemoryAllocator/CodeBuffer/CodeBufferBase.cc + source/MemoryAllocator/CodeBuffer/code-buffer-arm.cc + source/MemoryAllocator/CodeBuffer/code-buffer-arm64.cc + source/MemoryAllocator/CodeBuffer/code-buffer-x86.cc + source/MemoryAllocator/CodeBuffer/code-buffer-x64.cc + + # executable memory + source/MemoryAllocator/AssemblyCodeBuilder.cc + source/MemoryAllocator/MemoryArena.cc + + # instruction relocation + source/InstructionRelocation/arm/ARMInstructionRelocation.cc + source/InstructionRelocation/arm64/ARM64InstructionRelocation.cc + source/InstructionRelocation/x86/X86InstructionRelocation.cc + source/InstructionRelocation/x64/X64InstructionRelocation.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 + ) + +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/ARMAssemblyClosureTrampoline.cc + + source/TrampolineBridge/ClosureTrampolineBridge/arm64/helper-arm64.cc + source/TrampolineBridge/ClosureTrampolineBridge/arm64/closure-bridge-arm64.cc + source/TrampolineBridge/ClosureTrampolineBridge/arm64/ARM64AssemblyClosureTrampoline.cc + + source/TrampolineBridge/ClosureTrampolineBridge/x64/helper-x64.cc + source/TrampolineBridge/ClosureTrampolineBridge/x64/closure-bridge-x64.cc + source/TrampolineBridge/ClosureTrampolineBridge/x64/X64AssemblyClosureTrampoline.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/Bcore/src/main/cpp/Dobby/cmake/ios.toolchain.cmake b/Bcore/src/main/cpp/Dobby/cmake/ios.toolchain.cmake new file mode 100644 index 00000000..df6485b6 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/cmake/ios.toolchain.cmake @@ -0,0 +1,641 @@ +# This file is part of the ios-cmake project. It was retrieved from +# https://github.com/cristeab/ios-cmake.git, which is a fork of +# https://code.google.com/p/ios-cmake/. Which in turn is based off of +# the Platform/Darwin.cmake and Platform/UnixPaths.cmake files which +# are included with CMake 2.8.4 +# +# The ios-cmake project is licensed under the new BSD license. +# +# Copyright (c) 2014, Bogdan Cristea and LTE Engineering Software, +# Kitware, Inc., Insight Software Consortium. All rights reserved. +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions +# are met: +# 1. Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# +# 3. Neither the name of the copyright holder nor the names of its +# contributors may be used to endorse or promote products derived from +# this software without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS +# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE +# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, +# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN +# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. +# +# This file is based off of the Platform/Darwin.cmake and +# Platform/UnixPaths.cmake files which are included with CMake 2.8.4 +# It has been altered for iOS development. +# +# Updated by Alex Stewart (alexs.mac@gmail.com) +# +# ***************************************************************************** +# Now maintained by Alexander Widerberg (widerbergaren [at] gmail.com) +# under the BSD-3-Clause license +# https://github.com/leetal/ios-cmake +# ***************************************************************************** +# +# INFORMATION / HELP +# +# The following arguments control the behaviour of this toolchain: +# +# PLATFORM: (default "OS") +# OS = Build for iPhoneOS. +# OS64 = Build for arm64 iphoneOS. +# OS64COMBINED = Build for arm64 x86_64 iphoneOS. Combined into FAT STATIC lib (supported on 3.14+ of CMakewith "-G Xcode" argument ONLY) +# SIMULATOR = Build for x86 i386 iphoneOS Simulator. +# SIMULATOR64 = Build for x86_64 iphoneOS Simulator. +# TVOS = Build for arm64 tvOS. +# TVOSCOMBINED = Build for arm64 x86_64 tvOS. Combined into FAT STATIC lib (supported on 3.14+ of CMake with "-G Xcode" argument ONLY) +# SIMULATOR_TVOS = Build for x86_64 tvOS Simulator. +# WATCHOS = Build for armv7k arm64_32 for watchOS. +# WATCHOSCOMBINED = Build for armv7k arm64_32 x86_64 watchOS. Combined into FAT STATIC lib (supported on 3.14+ of CMake with "-G Xcode" argument ONLY) +# SIMULATOR_WATCHOS = Build for x86_64 for watchOS Simulator. +# +# CMAKE_OSX_SYSROOT: Path to the SDK to use. By default this is +# automatically determined from PLATFORM and xcodebuild, but +# automatically determined from PLATFORM and xcodebuild, but +# can also be manually specified (although this should not be required). +# +# CMAKE_DEVELOPER_ROOT: Path to the Developer directory for the platform +# being compiled for. By default this is automatically determined from +# CMAKE_OSX_SYSROOT, but can also be manually specified (although this should +# not be required). +# +# DEPLOYMENT_TARGET: Minimum SDK version to target. Default 2.0 on watchOS and 9.0 on tvOS+iOS +# +# ENABLE_BITCODE: (1|0) Enables or disables bitcode support. Default 1 (true) +# +# ENABLE_ARC: (1|0) Enables or disables ARC support. Default 1 (true, ARC enabled by default) +# +# ENABLE_VISIBILITY: (1|0) Enables or disables symbol visibility support. Default 0 (false, visibility hidden by default) +# +# ARCHS: (armv7 armv7s armv7k arm64 arm64_32 i386 x86_64) If specified, will override the default architectures for the given PLATFORM +# OS = armv7 armv7s arm64 (if applicable) +# OS64 = arm64 (if applicable) +# SIMULATOR = i386 +# SIMULATOR64 = x86_64 +# TVOS = arm64 +# SIMULATOR_TVOS = x86_64 (i386 has since long been deprecated) +# WATCHOS = armv7k arm64_32 (if applicable) +# SIMULATOR_WATCHOS = x86_64 (i386 has since long been deprecated) +# +# This toolchain defines the following variables for use externally: +# +# XCODE_VERSION: Version number (not including Build version) of Xcode detected. +# SDK_VERSION: Version of SDK being used. +# CMAKE_OSX_ARCHITECTURES: Architectures being compiled for (generated from PLATFORM). +# +# This toolchain defines the following macros for use externally: +# +# set_xcode_property (TARGET XCODE_PROPERTY XCODE_VALUE XCODE_VARIANT) +# A convenience macro for setting xcode specific properties on targets. +# Available variants are: All, Release, RelWithDebInfo, Debug, MinSizeRel +# example: set_xcode_property (myioslib IPHONEOS_DEPLOYMENT_TARGET "3.1" "all"). +# +# find_host_package (PROGRAM ARGS) +# A macro used to find executable programs on the host system, not within the +# environment. Thanks to the android-cmake project for providing the +# command. +# +# ******************************** DEPRECATIONS ******************************* +# +# IOS_DEPLOYMENT_TARGET: (Deprecated) Alias to DEPLOYMENT_TARGET +# CMAKE_IOS_DEVELOPER_ROOT: (Deprecated) Alias to CMAKE_DEVELOPER_ROOT +# IOS_PLATFORM: (Deprecated) Alias to PLATFORM +# IOS_ARCH: (Deprecated) Alias to ARCHS +# +# ***************************************************************************** +# + +# Fix for PThread library not in path +set(CMAKE_THREAD_LIBS_INIT "-lpthread") +set(CMAKE_HAVE_THREADS_LIBRARY 1) +set(CMAKE_USE_WIN32_THREADS_INIT 0) +set(CMAKE_USE_PTHREADS_INIT 1) + +# Cache what generator is used +set(USED_CMAKE_GENERATOR "${CMAKE_GENERATOR}" CACHE STRING "Expose CMAKE_GENERATOR" FORCE) + +if(${CMAKE_VERSION} VERSION_GREATER_EQUAL "3.14") + set(MODERN_CMAKE YES) + message(STATUS "Merging integrated CMake 3.14+ iOS,tvOS,watchOS,macOS toolchain(s) with this toolchain!") +endif() + +# Get the Xcode version being used. +execute_process(COMMAND xcodebuild -version + OUTPUT_VARIABLE XCODE_VERSION + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) +string(REGEX MATCH "Xcode [0-9\\.]+" XCODE_VERSION "${XCODE_VERSION}") +string(REGEX REPLACE "Xcode ([0-9\\.]+)" "\\1" XCODE_VERSION "${XCODE_VERSION}") +message(STATUS "Building with Xcode version: ${XCODE_VERSION}") + +######## ALIASES (DEPRECATION WARNINGS) + +if(DEFINED IOS_PLATFORM) + set(PLATFORM ${IOS_PLATFORM}) + message(DEPRECATION "IOS_PLATFORM argument is DEPRECATED. Consider using the new PLATFORM argument instead.") +endif() + +if(DEFINED IOS_DEPLOYMENT_TARGET) + set(DEPLOYMENT_TARGET ${IOS_DEPLOYMENT_TARGET}) + message(DEPRECATION "CMAKE_IOS_DEVELOPER_ROOT argument is DEPRECATED. Consider using the new CMAKE_DEVELOPER_ROOT argument instead.") +endif() + +if(DEFINED CMAKE_IOS_DEVELOPER_ROOT) + set(CMAKE_DEVELOPER_ROOT ${CMAKE_IOS_DEVELOPER_ROOT}) + message(DEPRECATION "CMAKE_IOS_DEVELOPER_ROOT argument is DEPRECATED. Consider using the new CMAKE_DEVELOPER_ROOT argument instead.") +endif() + +if(DEFINED IOS_ARCH) + set(ARCHS ${IOS_ARCH}) + message(DEPRECATION "IOS_ARCH argument is DEPRECATED. Consider using the new ARCHS argument instead.") +endif() + +######## END ALIASES + +# Default to building for iPhoneOS if not specified otherwise, and we cannot +# determine the platform from the CMAKE_OSX_ARCHITECTURES variable. The use +# of CMAKE_OSX_ARCHITECTURES is such that try_compile() projects can correctly +# determine the value of PLATFORM from the root project, as +# CMAKE_OSX_ARCHITECTURES is propagated to them by CMake. +if (NOT DEFINED PLATFORM) + if (CMAKE_OSX_ARCHITECTURES) + if(CMAKE_OSX_ARCHITECTURES MATCHES ".*arm.*" AND CMAKE_OSX_SYSROOT MATCHES ".*iphoneos.*") + set(PLATFORM "OS") + elseif(CMAKE_OSX_ARCHITECTURES MATCHES "i386" AND CMAKE_OSX_SYSROOT MATCHES ".*iphonesimulator.*") + set(PLATFORM "SIMULATOR") + elseif(CMAKE_OSX_ARCHITECTURES MATCHES "x86_64" AND CMAKE_OSX_SYSROOT MATCHES ".*iphonesimulator.*") + set(PLATFORM "SIMULATOR64") + elseif(CMAKE_OSX_ARCHITECTURES MATCHES "arm64" AND CMAKE_OSX_SYSROOT MATCHES ".*appletvos.*") + set(PLATFORM "TVOS") + elseif(CMAKE_OSX_ARCHITECTURES MATCHES "x86_64" AND CMAKE_OSX_SYSROOT MATCHES ".*appletvsimulator.*") + set(PLATFORM "SIMULATOR_TVOS") + elseif(CMAKE_OSX_ARCHITECTURES MATCHES ".*armv7k.*" AND CMAKE_OSX_SYSROOT MATCHES ".*watchos.*") + set(PLATFORM "WATCHOS") + elseif(CMAKE_OSX_ARCHITECTURES MATCHES "i386" AND CMAKE_OSX_SYSROOT MATCHES ".*watchsimulator.*") + set(PLATFORM "SIMULATOR_WATCHOS") + endif() + endif() + if (NOT PLATFORM) + set(PLATFORM "OS") + endif() +endif() + +set(PLATFORM_INT "${PLATFORM}" CACHE STRING "Type of platform for which the build targets.") + +# Handle the case where we are targeting iOS and a version above 10.0 (32-bit support dropped officially) +if(PLATFORM_INT STREQUAL "OS" AND DEPLOYMENT_TARGET VERSION_GREATER_EQUAL 10.0) + set(PLATFORM_INT "OS64") + message(STATUS "Targeting minimum SDK version ${DEPLOYMENT_TARGET}. Dropping 32-bit support.") +elseif(PLATFORM_INT STREQUAL "SIMULATOR" AND DEPLOYMENT_TARGET VERSION_GREATER_EQUAL 10.0) + set(PLATFORM_INT "SIMULATOR64") + message(STATUS "Targeting minimum SDK version ${DEPLOYMENT_TARGET}. Dropping 32-bit support.") +endif() + +# Determine the platform name and architectures for use in xcodebuild commands +# from the specified PLATFORM name. +if(PLATFORM_INT STREQUAL "OS") + set(SDK_NAME iphoneos) + if(NOT ARCHS) + set(ARCHS armv7 armv7s arm64) + endif() +elseif(PLATFORM_INT STREQUAL "OS64") + set(SDK_NAME iphoneos) + if(NOT ARCHS) + if (XCODE_VERSION VERSION_GREATER 10.0) + set(ARCHS arm64) # Add arm64e when Apple have fixed the integration issues with it, libarclite_iphoneos.a is currently missung bitcode markers for example + else() + set(ARCHS arm64) + endif() + endif() +elseif(PLATFORM_INT STREQUAL "OS64COMBINED") + set(SDK_NAME iphoneos) + if(MODERN_CMAKE) + if(NOT ARCHS) + if (XCODE_VERSION VERSION_GREATER 10.0) + set(ARCHS arm64 x86_64) # Add arm64e when Apple have fixed the integration issues with it, libarclite_iphoneos.a is currently missung bitcode markers for example + else() + set(ARCHS arm64 x86_64) + endif() + endif() + else() + message(FATAL_ERROR "Please make sure that you are running CMake 3.14+ to make the OS64COMBINED setting work") + endif() +elseif(PLATFORM_INT STREQUAL "SIMULATOR") + set(SDK_NAME iphonesimulator) + if(NOT ARCHS) + set(ARCHS i386) + endif() + message(DEPRECATION "SIMULATOR IS DEPRECATED. Consider using SIMULATOR64 instead.") +elseif(PLATFORM_INT STREQUAL "SIMULATOR64") + set(SDK_NAME iphonesimulator) + if(NOT ARCHS) + set(ARCHS x86_64) + endif() +elseif(PLATFORM_INT STREQUAL "TVOS") + set(SDK_NAME appletvos) + if(NOT ARCHS) + set(ARCHS arm64) + endif() +elseif (PLATFORM_INT STREQUAL "TVOSCOMBINED") + set(SDK_NAME appletvos) + if(MODERN_CMAKE) + if(NOT ARCHS) + set(ARCHS arm64 x86_64) + endif() + else() + message(FATAL_ERROR "Please make sure that you are running CMake 3.14+ to make the TVOSCOMBINED setting work") + endif() +elseif(PLATFORM_INT STREQUAL "SIMULATOR_TVOS") + set(SDK_NAME appletvsimulator) + if(NOT ARCHS) + set(ARCHS x86_64) + endif() +elseif(PLATFORM_INT STREQUAL "WATCHOS") + set(SDK_NAME watchos) + if(NOT ARCHS) + if (XCODE_VERSION VERSION_GREATER 10.0) + set(ARCHS armv7k arm64_32) + else() + set(ARCHS armv7k) + endif() + endif() +elseif(PLATFORM_INT STREQUAL "WATCHOSCOMBINED") + set(SDK_NAME watchos) + if(MODERN_CMAKE) + if(NOT ARCHS) + if (XCODE_VERSION VERSION_GREATER 10.0) + set(ARCHS armv7k arm64_32 i386) + else() + set(ARCHS armv7k i386) + endif() + endif() + else() + message(FATAL_ERROR "Please make sure that you are running CMake 3.14+ to make the WATCHOSCOMBINED setting work") + endif() +elseif(PLATFORM_INT STREQUAL "SIMULATOR_WATCHOS") + set(SDK_NAME watchsimulator) + if(NOT ARCHS) + set(ARCHS i386) + endif() +else() + message(FATAL_ERROR "Invalid PLATFORM: ${PLATFORM_INT}") +endif() +message(STATUS "Configuring ${SDK_NAME} build for platform: ${PLATFORM_INT}, architecture(s): ${ARCHS}") + +if(MODERN_CMAKE AND PLATFORM_INT MATCHES ".*COMBINED" AND NOT USED_CMAKE_GENERATOR MATCHES "Xcode") + message(FATAL_ERROR "The COMBINED options only work with Xcode generator, -G Xcode") +endif() + +# If user did not specify the SDK root to use, then query xcodebuild for it. +execute_process(COMMAND xcodebuild -version -sdk ${SDK_NAME} Path + OUTPUT_VARIABLE CMAKE_OSX_SYSROOT_INT + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) +if (NOT DEFINED CMAKE_OSX_SYSROOT_INT AND NOT DEFINED CMAKE_OSX_SYSROOT) + message(SEND_ERROR "Please make sure that Xcode is installed and that the toolchain" + "is pointing to the correct path. Please run:" + "sudo xcode-select -s /Applications/Xcode.app/Contents/Developer" + "and see if that fixes the problem for you.") + message(FATAL_ERROR "Invalid CMAKE_OSX_SYSROOT: ${CMAKE_OSX_SYSROOT} " + "does not exist.") +elseif(DEFINED CMAKE_OSX_SYSROOT) + message(STATUS "Using manually set SDK: ${CMAKE_OSX_SYSROOT} for platform: ${PLATFORM_INT}") +elseif(DEFINED CMAKE_OSX_SYSROOT_INT) + message(STATUS "Using SDK: ${CMAKE_OSX_SYSROOT_INT} for platform: ${PLATFORM_INT}") + set(CMAKE_OSX_SYSROOT "${CMAKE_OSX_SYSROOT_INT}" CACHE INTERNAL "") +endif() + +# Set Xcode property for SDKROOT as well if Xcode generator is used +if(USED_CMAKE_GENERATOR MATCHES "Xcode") + set(CMAKE_OSX_SYSROOT "${SDK_NAME}" CACHE INTERNAL "") + if(NOT DEFINED CMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM) + set(CMAKE_XCODE_ATTRIBUTE_DEVELOPMENT_TEAM 123456789A CACHE INTERNAL "") + endif() +endif() + +# Specify minimum version of deployment target. +if(NOT DEFINED DEPLOYMENT_TARGET) + if (PLATFORM_INT STREQUAL "WATCHOS" OR PLATFORM_INT STREQUAL "SIMULATOR_WATCHOS") + # Unless specified, SDK version 2.0 is used by default as minimum target version (watchOS). + set(DEPLOYMENT_TARGET "2.0" + CACHE STRING "Minimum SDK version to build for." ) + else() + # Unless specified, SDK version 9.0 is used by default as minimum target version (iOS, tvOS). + set(DEPLOYMENT_TARGET "9.0" + CACHE STRING "Minimum SDK version to build for." ) + endif() + message(STATUS "Using the default min-version since DEPLOYMENT_TARGET not provided!") +endif() +# Use bitcode or not +if(NOT DEFINED ENABLE_BITCODE AND NOT ARCHS MATCHES "((^|, )(i386|x86_64))+") + # Unless specified, enable bitcode support by default + message(STATUS "Enabling bitcode support by default. ENABLE_BITCODE not provided!") + set(ENABLE_BITCODE TRUE) +elseif(NOT DEFINED ENABLE_BITCODE) + message(STATUS "Disabling bitcode support by default on simulators. ENABLE_BITCODE not provided for override!") + set(ENABLE_BITCODE FALSE) +endif() +set(ENABLE_BITCODE_INT ${ENABLE_BITCODE} CACHE BOOL "Whether or not to enable bitcode" FORCE) +# Use ARC or not +if(NOT DEFINED ENABLE_ARC) + # Unless specified, enable ARC support by default + set(ENABLE_ARC TRUE) + message(STATUS "Enabling ARC support by default. ENABLE_ARC not provided!") +endif() +set(ENABLE_ARC_INT ${ENABLE_ARC} CACHE BOOL "Whether or not to enable ARC" FORCE) +# Use hidden visibility or not +if(NOT DEFINED ENABLE_VISIBILITY) + # Unless specified, disable symbols visibility by default + set(ENABLE_VISIBILITY FALSE) + message(STATUS "Hiding symbols visibility by default. ENABLE_VISIBILITY not provided!") +endif() +set(ENABLE_VISIBILITY_INT ${ENABLE_VISIBILITY} CACHE BOOL "Whether or not to hide symbols (-fvisibility=hidden)" FORCE) +# Get the SDK version information. +execute_process(COMMAND xcodebuild -sdk ${CMAKE_OSX_SYSROOT} -version SDKVersion + OUTPUT_VARIABLE SDK_VERSION + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + +# Find the Developer root for the specific iOS platform being compiled for +# from CMAKE_OSX_SYSROOT. Should be ../../ from SDK specified in +# CMAKE_OSX_SYSROOT. There does not appear to be a direct way to obtain +# this information from xcrun or xcodebuild. +if (NOT DEFINED CMAKE_DEVELOPER_ROOT AND NOT USED_CMAKE_GENERATOR MATCHES "Xcode") + get_filename_component(IOS_PLATFORM_SDK_DIR ${CMAKE_OSX_SYSROOT} PATH) + get_filename_component(CMAKE_DEVELOPER_ROOT ${IOS_PLATFORM_SDK_DIR} PATH) + + if (NOT DEFINED CMAKE_DEVELOPER_ROOT) + message(FATAL_ERROR "Invalid CMAKE_DEVELOPER_ROOT: " + "${CMAKE_DEVELOPER_ROOT} does not exist.") + endif() +endif() +# Find the C & C++ compilers for the specified SDK. +if(NOT CMAKE_C_COMPILER) + execute_process(COMMAND xcrun -sdk ${CMAKE_OSX_SYSROOT} -find clang + OUTPUT_VARIABLE CMAKE_C_COMPILER + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + message(STATUS "Using C compiler: ${CMAKE_C_COMPILER}") +endif() +if(NOT CMAKE_CXX_COMPILER) + execute_process(COMMAND xcrun -sdk ${CMAKE_OSX_SYSROOT} -find clang++ + OUTPUT_VARIABLE CMAKE_CXX_COMPILER + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) + message(STATUS "Using CXX compiler: ${CMAKE_CXX_COMPILER}") +endif() +# Find (Apple's) libtool. +execute_process(COMMAND xcrun -sdk ${CMAKE_OSX_SYSROOT} -find libtool + OUTPUT_VARIABLE BUILD_LIBTOOL + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) +message(STATUS "Using libtool: ${BUILD_LIBTOOL}") +# Configure libtool to be used instead of ar + ranlib to build static libraries. +# This is required on Xcode 7+, but should also work on previous versions of +# Xcode. +set(CMAKE_C_CREATE_STATIC_LIBRARY + "${BUILD_LIBTOOL} -static -o ") +set(CMAKE_CXX_CREATE_STATIC_LIBRARY + "${BUILD_LIBTOOL} -static -o ") +# Get the version of Darwin (OS X) of the host. +execute_process(COMMAND uname -r + OUTPUT_VARIABLE CMAKE_HOST_SYSTEM_VERSION + ERROR_QUIET + OUTPUT_STRIP_TRAILING_WHITESPACE) +# CMake 3.14+ support building for iOS, watchOS and tvOS out of the box. +if(MODERN_CMAKE) + if(SDK_NAME MATCHES "iphone") + set(CMAKE_SYSTEM_NAME iOS CACHE INTERNAL "" FORCE) + elseif(SDK_NAME MATCHES "appletv") + set(CMAKE_SYSTEM_NAME tvOS CACHE INTERNAL "" FORCE) + elseif(SDK_NAME MATCHES "watch") + set(CMAKE_SYSTEM_NAME watchOS CACHE INTERNAL "" FORCE) + endif() + + # Provide flags for a combined FAT library build on newer CMake versions + if(PLATFORM_INT MATCHES ".*COMBINED") + set(CMAKE_XCODE_ATTRIBUTE_ONLY_ACTIVE_ARCH NO CACHE INTERNAL "") + set(CMAKE_IOS_INSTALL_COMBINED YES CACHE INTERNAL "") + message(STATUS "Will combine built (static) artifacts into FAT lib...") + endif() +else() + # Legacy code path prior to CMake 3.14 + set(CMAKE_SYSTEM_NAME Darwin CACHE INTERNAL "" FORCE) +endif() +# Standard settings. +set(CMAKE_SYSTEM_VERSION ${SDK_VERSION} CACHE INTERNAL "") +set(UNIX TRUE CACHE BOOL "") +set(APPLE TRUE CACHE BOOL "") +set(IOS TRUE CACHE BOOL "") +set(CMAKE_AR ar CACHE FILEPATH "" FORCE) +set(CMAKE_RANLIB ranlib CACHE FILEPATH "" FORCE) +# Set the architectures for which to build. +set(CMAKE_OSX_ARCHITECTURES ${ARCHS} CACHE STRING "Build architecture for iOS") +# Change the type of target generated for try_compile() so it'll work when cross-compiling +set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) +# All iOS/Darwin specific settings - some may be redundant. +set(CMAKE_SHARED_LIBRARY_PREFIX "lib") +set(CMAKE_SHARED_LIBRARY_SUFFIX ".dylib") +set(CMAKE_SHARED_MODULE_PREFIX "lib") +set(CMAKE_SHARED_MODULE_SUFFIX ".so") +set(CMAKE_C_COMPILER_ABI ELF) +set(CMAKE_CXX_COMPILER_ABI ELF) +set(CMAKE_C_HAS_ISYSROOT 1) +set(CMAKE_CXX_HAS_ISYSROOT 1) +set(CMAKE_MODULE_EXISTS 1) +set(CMAKE_DL_LIBS "") +set(CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG "-compatibility_version ") +set(CMAKE_C_OSX_CURRENT_VERSION_FLAG "-current_version ") +set(CMAKE_CXX_OSX_COMPATIBILITY_VERSION_FLAG "${CMAKE_C_OSX_COMPATIBILITY_VERSION_FLAG}") +set(CMAKE_CXX_OSX_CURRENT_VERSION_FLAG "${CMAKE_C_OSX_CURRENT_VERSION_FLAG}") + +if(ARCHS MATCHES "((^|, )(arm64|arm64e|x86_64))+") + set(CMAKE_C_SIZEOF_DATA_PTR 8) + set(CMAKE_CXX_SIZEOF_DATA_PTR 8) + message(STATUS "Using a data_ptr size of 8") +else() + set(CMAKE_C_SIZEOF_DATA_PTR 4) + set(CMAKE_CXX_SIZEOF_DATA_PTR 4) + message(STATUS "Using a data_ptr size of 4") +endif() + +message(STATUS "Building for minimum ${SDK_NAME} version: ${DEPLOYMENT_TARGET}" + " (SDK version: ${SDK_VERSION})") +# Note that only Xcode 7+ supports the newer more specific: +# -m${SDK_NAME}-version-min flags, older versions of Xcode use: +# -m(ios/ios-simulator)-version-min instead. +if(PLATFORM_INT STREQUAL "OS" OR PLATFORM_INT STREQUAL "OS64") + if(XCODE_VERSION VERSION_LESS 7.0) + set(SDK_NAME_VERSION_FLAGS + "-mios-version-min=${DEPLOYMENT_TARGET}") + else() + # Xcode 7.0+ uses flags we can build directly from SDK_NAME. + set(SDK_NAME_VERSION_FLAGS + "-m${SDK_NAME}-version-min=${DEPLOYMENT_TARGET}") + endif() +elseif(PLATFORM_INT STREQUAL "TVOS") + set(SDK_NAME_VERSION_FLAGS + "-mtvos-version-min=${DEPLOYMENT_TARGET}") +elseif(PLATFORM_INT STREQUAL "SIMULATOR_TVOS") + set(SDK_NAME_VERSION_FLAGS + "-mtvos-simulator-version-min=${DEPLOYMENT_TARGET}") +elseif(PLATFORM_INT STREQUAL "WATCHOS") + set(SDK_NAME_VERSION_FLAGS + "-mwatchos-version-min=${DEPLOYMENT_TARGET}") +elseif(PLATFORM_INT STREQUAL "SIMULATOR_WATCHOS") + set(SDK_NAME_VERSION_FLAGS + "-mwatchos-simulator-version-min=${DEPLOYMENT_TARGET}") +else() + # SIMULATOR or SIMULATOR64 both use -mios-simulator-version-min. + set(SDK_NAME_VERSION_FLAGS + "-mios-simulator-version-min=${DEPLOYMENT_TARGET}") +endif() +message(STATUS "Version flags set to: ${SDK_NAME_VERSION_FLAGS}") +set(CMAKE_OSX_DEPLOYMENT_TARGET ${DEPLOYMENT_TARGET} CACHE STRING + "Set CMake deployment target" FORCE) + +if(ENABLE_BITCODE_INT) + set(BITCODE "-fembed-bitcode") + set(HEADER_PAD "") + set(CMAKE_XCODE_ATTRIBUTE_BITCODE_GENERATION_MODE bitcode CACHE INTERNAL "") + message(STATUS "Enabling bitcode support.") +else() + set(BITCODE "") + set(HEADER_PAD "-headerpad_max_install_names") + set(CMAKE_XCODE_ATTRIBUTE_ENABLE_BITCODE NO CACHE INTERNAL "") + message(STATUS "Disabling bitcode support.") +endif() + +if(ENABLE_ARC_INT) + set(FOBJC_ARC "-fobjc-arc") + set(CMAKE_XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES CACHE INTERNAL "") + message(STATUS "Enabling ARC support.") +else() + set(FOBJC_ARC "-fno-objc-arc") + set(CMAKE_XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC NO CACHE INTERNAL "") + message(STATUS "Disabling ARC support.") +endif() + +if(NOT ENABLE_VISIBILITY_INT) + set(VISIBILITY "-fvisibility=hidden") + set(CMAKE_XCODE_ATTRIBUTE_GCC_SYMBOLS_PRIVATE_EXTERN YES CACHE INTERNAL "") + message(STATUS "Hiding symbols (-fvisibility=hidden).") +else() + set(VISIBILITY "") + set(CMAKE_XCODE_ATTRIBUTE_GCC_SYMBOLS_PRIVATE_EXTERN NO CACHE INTERNAL "") +endif() + +#Check if Xcode generator is used, since that will handle these flags automagically +if(USED_CMAKE_GENERATOR MATCHES "Xcode") + message(STATUS "Not setting any manual command-line buildflags, since Xcode is selected as generator.") +else() + set(CMAKE_C_FLAGS + "${SDK_NAME_VERSION_FLAGS} ${BITCODE} -fobjc-abi-version=2 ${FOBJC_ARC} ${CMAKE_C_FLAGS}") + # Hidden visibilty is required for C++ on iOS. + set(CMAKE_CXX_FLAGS + "${SDK_NAME_VERSION_FLAGS} ${BITCODE} ${VISIBILITY} -fvisibility-inlines-hidden -fobjc-abi-version=2 ${FOBJC_ARC} ${CMAKE_CXX_FLAGS}") + set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} -O0 -g ${CMAKE_CXX_FLAGS_DEBUG}") + set(CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS} -DNDEBUG -Os -ffast-math ${CMAKE_CXX_FLAGS_MINSIZEREL}") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS} -DNDEBUG -O2 -g -ffast-math ${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") + set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -DNDEBUG -O3 -ffast-math ${CMAKE_CXX_FLAGS_RELEASE}") + set(CMAKE_C_LINK_FLAGS "${SDK_NAME_VERSION_FLAGS} -Wl,-search_paths_first ${CMAKE_C_LINK_FLAGS}") + set(CMAKE_CXX_LINK_FLAGS "${SDK_NAME_VERSION_FLAGS} -Wl,-search_paths_first ${CMAKE_CXX_LINK_FLAGS}") + + # In order to ensure that the updated compiler flags are used in try_compile() + # tests, we have to forcibly set them in the CMake cache, not merely set them + # in the local scope. + list(APPEND VARS_TO_FORCE_IN_CACHE + CMAKE_C_FLAGS + CMAKE_CXX_FLAGS + CMAKE_CXX_FLAGS_DEBUG + CMAKE_CXX_FLAGS_RELWITHDEBINFO + CMAKE_CXX_FLAGS_MINSIZEREL + CMAKE_CXX_FLAGS_RELEASE + CMAKE_C_LINK_FLAGS + CMAKE_CXX_LINK_FLAGS) + foreach(VAR_TO_FORCE ${VARS_TO_FORCE_IN_CACHE}) + set(${VAR_TO_FORCE} "${${VAR_TO_FORCE}}" CACHE STRING "") + endforeach() +endif() + +set(CMAKE_PLATFORM_HAS_INSTALLNAME 1) +set(CMAKE_SHARED_LINKER_FLAGS "-rpath @executable_path/Frameworks -rpath @loader_path/Frameworks") +set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-dynamiclib ${HEADER_PAD}") +set(CMAKE_SHARED_MODULE_CREATE_C_FLAGS "-bundle ${HEADER_PAD}") +set(CMAKE_SHARED_MODULE_LOADER_C_FLAG "-Wl,-bundle_loader,") +set(CMAKE_SHARED_MODULE_LOADER_CXX_FLAG "-Wl,-bundle_loader,") +set(CMAKE_FIND_LIBRARY_SUFFIXES ".dylib" ".so" ".a") + +# Hack: if a new cmake (which uses CMAKE_INSTALL_NAME_TOOL) runs on an old +# build tree (where install_name_tool was hardcoded) and where +# CMAKE_INSTALL_NAME_TOOL isn't in the cache and still cmake didn't fail in +# CMakeFindBinUtils.cmake (because it isn't rerun) hardcode +# CMAKE_INSTALL_NAME_TOOL here to install_name_tool, so it behaves as it did +# before, Alex. +if(NOT DEFINED CMAKE_INSTALL_NAME_TOOL) + find_program(CMAKE_INSTALL_NAME_TOOL install_name_tool) +endif (NOT DEFINED CMAKE_INSTALL_NAME_TOOL) + +# Set the find root to the iOS developer roots and to user defined paths. +set(CMAKE_FIND_ROOT_PATH ${CMAKE_DEVELOPER_ROOT} ${CMAKE_OSX_SYSROOT} + ${CMAKE_PREFIX_PATH} CACHE STRING "SKD find search path root" FORCE) +# Default to searching for frameworks first. +set(CMAKE_FIND_FRAMEWORK FIRST) +# Set up the default search directories for frameworks. +set(CMAKE_SYSTEM_FRAMEWORK_PATH + ${CMAKE_OSX_SYSROOT}/System/Library/Frameworks + ${CMAKE_OSX_SYSROOT}/System/Library/PrivateFrameworks + ${CMAKE_OSX_SYSROOT}/Developer/Library/Frameworks) +# Only search the specified iOS SDK, not the remainder of the host filesystem. +if( NOT CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ) + set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY ) +endif() +if( NOT CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ) + set( CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY ) +endif() +if( NOT CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ) + set( CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY ) +endif() + +# +# Some helper-macros below to simplify and beautify the CMakeFile +# + +# This little macro lets you set any XCode specific property. +macro(set_xcode_property TARGET XCODE_PROPERTY XCODE_VALUE XCODE_RELVERSION) + set(XCODE_RELVERSION_I "${XCODE_RELVERSION}") + if(XCODE_RELVERSION_I STREQUAL "All") + set_property(TARGET ${TARGET} PROPERTY + XCODE_ATTRIBUTE_${XCODE_PROPERTY} "${XCODE_VALUE}") + else() + set_property(TARGET ${TARGET} PROPERTY + XCODE_ATTRIBUTE_${XCODE_PROPERTY}[variant=${XCODE_RELVERSION_I}] "${XCODE_VALUE}") + endif() +endmacro(set_xcode_property) +# This macro lets you find executable programs on the host system. +macro(find_host_package) + set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY NEVER) + set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE NEVER) + set(IOS FALSE) + find_package(${ARGN}) + set(IOS TRUE) + set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY) + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY) + set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY) +endmacro(find_host_package) diff --git a/Bcore/src/main/cpp/Dobby/docs/.nojekyll b/Bcore/src/main/cpp/Dobby/docs/.nojekyll new file mode 100644 index 00000000..e69de29b diff --git a/Bcore/src/main/cpp/Dobby/docs/_cover_page.md b/Bcore/src/main/cpp/Dobby/docs/_cover_page.md new file mode 100755 index 00000000..d4a99e57 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/docs/_cover_page.md @@ -0,0 +1,6 @@ +# Dobby beta + +> An exploit hook framework + +[GitHub](https://github.com/jmpews/dobby) +[Get Started](#intro) diff --git a/Bcore/src/main/cpp/Dobby/docs/_nav_bar.md b/Bcore/src/main/cpp/Dobby/docs/_nav_bar.md new file mode 100755 index 00000000..579b5b33 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/docs/_nav_bar.md @@ -0,0 +1,2 @@ +* [Release Note](https://github.com/jmpews/Dobby/commits/master) +* [Download](https://github.com/jmpews/Dobby/releases/tag/latest) \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/docs/_side_bar.md b/Bcore/src/main/cpp/Dobby/docs/_side_bar.md new file mode 100755 index 00000000..541edaa8 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/docs/_side_bar.md @@ -0,0 +1,10 @@ +- [Home](/) +- [Installation](build-documentation.md) +- [Getting Started](get-started.md) +- [Getting Started Within iOS](get-started-ios.md) +- [Getting Started Within Android](get-started-android.md) +- Setup + - [Installation](build-documentation.md) + - [Getting Started](get-started.md) + - [Getting Started Within iOS](get-started-ios.md) + - [Getting Started Within Android](get-started-android.md) diff --git a/Bcore/src/main/cpp/Dobby/docs/build-documentation.md b/Bcore/src/main/cpp/Dobby/docs/build-documentation.md new file mode 100755 index 00000000..270fafac --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/docs/build-documentation.md @@ -0,0 +1,116 @@ +# Build + +## Cmake build options + +``` +option(DOBBY_GENERATE_SHARED "Build shared library" ON) + +option(DOBBY_DEBUG "Enable debug logging" ON) + +option(NearBranch "Enable Near Branch Trampoline" ON) + +option(DynamicBinaryInstrument "Enable Dynamic Binary Instrument" ON) + +option(FullFloatingPointRegisterPack "Save and pack all floating-point registers" OFF) + +option(Plugin.SymbolResolver "Resolve symbol by [DobbySymbolResolver] " ON) + +option(Plugin.GlobalOffsetTableHook "Global Offset Table Hook by [DobbyGlobalOffsetTableReplace] " ON) + +option(Plugin.LinkerLoadCallback "Register image load callback " OFF) +``` + +## Build script + +refer: [build-workspace/auto-build.sh](build-workspace/auto-build.sh) + +## Build for host + +``` +cd Dobby && mkdir build_for_host && cd build_for_host + +cmake .. + +make -j4 +``` + +## Build for iOS / macOS + +#### Manual build for macOS X64 host + +``` +cd Dobby && mkdir build_for_macos_x64 && cd build_for_macos_x64 + +cmake .. \ +-DCMAKE_BUILD_TYPE=Release \ + +make -j4 +``` + +#### Manual build for iOS [ARM/ARM64] + +``` +cd Dobby && mkdir build_for_ios_arm64 && cd build_for_ios_arm64 + +cmake .. -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_SYSTEM_PROCESSOR=arm64 -DCMAKE_OSX_DEPLOYMENT_TARGET=9.3 + +make -j4 +``` + +if you want generate Xcode Project, just replace with `cmake -G Xcode`. + +## Build for Android + +#### Manual build for Android ARM64 + +``` +export ANDROID_NDK=/Users/jmpews/Library/Android/sdk/ndk-bundle + +cd Dobby && mkdir build_for_android_arm64 && cd build_for_android_arm64 + +cmake .. \ +-DCMAKE_BUILD_TYPE=Release \ +-DCMAKE_SYSTEM_NAME=Android -DCMAKE_ANDROID_ARCH_ABI="arm64-v8a" -DCMAKE_ANDROID_NDK=$ANDROID_NDK -DCMAKE_SYSTEM_VERSION=21 -DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=clang + +make -j4 +``` + +#### Manual build for Android ARM + +``` +export ANDROID_NDK=/Users/jmpews/Library/Android/sdk/ndk-bundle + +cd Dobby && mkdir build_for_android_arm && cd build_for_android_arm + +-DCMAKE_BUILD_TYPE=Release \ +-DCMAKE_SYSTEM_NAME=Android -DCMAKE_ANDROID_ARCH_ABI="armeabi-v7a" -DCMAKE_ANDROID_NDK=$ANDROID_NDK -DCMAKE_SYSTEM_VERSION=16 -DCMAKE_ANDROID_NDK_TOOLCHAIN_VERSION=clang + +make -j4 +``` + +#### 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}/example/android_common_api.cc + + native-lib.cpp) +``` \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/docs/get-started-android.md b/Bcore/src/main/cpp/Dobby/docs/get-started-android.md new file mode 100755 index 00000000..5615028e --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/docs/get-started-android.md @@ -0,0 +1,56 @@ +# Getting Started + +## create native project and update CMakeLists.txt + +``` +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}/example/android_common_api.cc + + native-lib.cpp) +``` + +## replace hook function + +ref source `builtin-plugin/ApplicationEventMonitor/dynamic_loader_monitor.cc` + +ref source `builtin-plugin/ApplicationEventMonitor/posix_file_descriptor_operation_monitor.cc` + +## instrument function + +ref source `builtin-plugin/ApplicationEventMonitor/memory_operation_instrument.cc` + +## Android Linker Restriction + +ref source `builtin-plugin/AndroidRestriction/android_restriction_demo.cc` + +```c +# impl at SymbolResolver/elf/dobby_symbol_resolver.cc +void *__loader_dlopen = DobbySymbolResolver(NULL, "__loader_dlopen"); +DobbyHook((void *)__loader_dlopen, (void *)fake_loader_dlopen, (void **)&orig_loader_dlopen); +``` + +``` +# impl at AndroidRestriction/android_restriction.cc +linker_disable_namespace_restriction(); +void *handle = NULL; +handle = dlopen(lib, RTLD_LAZY); +vm = dlsym(handle, "_ZN7android14AndroidRuntime7mJavaVME"); +``` \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/docs/get-started-ios.md b/Bcore/src/main/cpp/Dobby/docs/get-started-ios.md new file mode 100755 index 00000000..f234b950 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/docs/get-started-ios.md @@ -0,0 +1,37 @@ +# Getting Started + +## add DobbyX.framework to your project + +``` +cmake .. -G Xcode -DCMAKE_SYSTEM_NAME=iOS -DCMAKE_OSX_ARCHITECTURES=arm64 -DCMAKE_SYSTEM_PROCESSOR=arm64 -DCMAKE_OSX_DEPLOYMENT_TARGET=9.3 + +``` + +**drag the `DobbyX.xcodeproj` to your project** + + +## replace hook function + +ref source `builtin-plugin/ApplicationEventMonitor/dynamic_loader_monitor.cc` + +ref source `builtin-plugin/ApplicationEventMonitor/posix_file_descriptor_operation_monitor.cc` + +## instrument function + +ref source `builtin-plugin/ApplicationEventMonitor/MGCopyAnswerMonitor.cc` + +## replace pac function + +``` +void *posix_spawn_ptr = __builtin_ptrauth_strip((void *)posix_spawn, ptrauth_key_asia); +void *fake_posix_spawn_ptr = __builtin_ptrauth_strip((void *)fake_posix_spawn, ptrauth_key_asia); + +DobbyHook((void *)posix_spawn_ptr, (void *)fake_posix_spawn_ptr, (void **)&orig_posix_spawn); + +*(void **)&orig_posix_spawn = (void *)ptrauth_sign_unauthenticated((void *)orig_posix_spawn, ptrauth_key_asia, 0); +``` + + +## objective-c toolkit + +invoke `DobbyOCReturnConstant("XXClass", "isVip", true);` will hook the objective-c instance/class method, and return the constant 1 automatically. diff --git a/Bcore/src/main/cpp/Dobby/docs/get-started.md b/Bcore/src/main/cpp/Dobby/docs/get-started.md new file mode 100755 index 00000000..2cc63fde --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/docs/get-started.md @@ -0,0 +1,73 @@ +# Getting Started + +## replace hook function + +``` +extern "C" { + extern int DobbyHook(void *function_address, void *replace_call, void **origin_call); +} + +size_t (*origin_fread)(void * ptr, size_t size, size_t nitems, FILE * stream); + +size_t (fake_fread)(void * ptr, size_t size, size_t nitems, FILE * stream) { + // Do What you Want. + return origin_fread(ptr, size, nitems, stream); +} + +DobbyHook((void *)fread, (void *)fake_fread, (void **)&origin_fread); +``` + +## instrument function + +``` + +uintptr_t getCallFirstArg(RegisterContext *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 = 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(RegisterContext *ctx, const HookEntryInfo *info) { + size_t size_ = 0; + size_ = getCallFirstArg(ctx); + char *buffer = "[-] function malloc first arg: 0x00000000.\n"; + format_integer_manually(strchr(buffer, '.') - 1, size_); + puts(buffer); +} + +DobbyInstrument((void *)malloc, malloc_handler) +``` + +## replace pac function + +``` +void *posix_spawn_ptr = __builtin_ptrauth_strip((void *)posix_spawn, ptrauth_key_asia); +void *fake_posix_spawn_ptr = __builtin_ptrauth_strip((void *)fake_posix_spawn, ptrauth_key_asia); + +DobbyHook((void *)posix_spawn_ptr, (void *)fake_posix_spawn_ptr, (void **)&orig_posix_spawn); + +*(void **)&orig_posix_spawn = (void *)ptrauth_sign_unauthenticated((void *)orig_posix_spawn, ptrauth_key_asia, 0); +``` \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/docs/images/vue-logo.png b/Bcore/src/main/cpp/Dobby/docs/images/vue-logo.png new file mode 100755 index 00000000..8bbf9841 Binary files /dev/null and b/Bcore/src/main/cpp/Dobby/docs/images/vue-logo.png differ diff --git a/Bcore/src/main/cpp/Dobby/docs/index.html b/Bcore/src/main/cpp/Dobby/docs/index.html new file mode 100755 index 00000000..d230e179 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/docs/index.html @@ -0,0 +1,61 @@ + + + + + + + Dobby - a lightweight, multi-platform, multi-architecture hook framework. + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/docs/intro-board.md b/Bcore/src/main/cpp/Dobby/docs/intro-board.md new file mode 100755 index 00000000..e99ddb12 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/docs/intro-board.md @@ -0,0 +1,14 @@ +# Intro + +a lightweight, multi-platform, multi-architecture exploit hook framework. + +**tips: any question [go to Telegram](https://t.me/dobby_group)** + +- Minimal and modular library +- Multi-platform support(Windows/macOS/iOS/Android/Linux) +- Multiple architecture support(X86-64, ARM, ARM64) +- Clean code without STL(port to kernel easily) +- Plugin support(DobbyDrill ?) +- iOS kernel exploit support(Gollum ?) + +**[CHANGELOG]()** diff --git a/Bcore/src/main/cpp/Dobby/docs/scripts/imagesloaded.pkgd.min.js b/Bcore/src/main/cpp/Dobby/docs/scripts/imagesloaded.pkgd.min.js new file mode 100755 index 00000000..6db7e38a --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/docs/scripts/imagesloaded.pkgd.min.js @@ -0,0 +1,7 @@ +/*! + * imagesLoaded PACKAGED v4.1.2 + * JavaScript is all like "You images are done yet or what?" + * MIT License + */ + +!function(t,e){"function"==typeof define&&define.amd?define("ev-emitter/ev-emitter",e):"object"==typeof module&&module.exports?module.exports=e():t.EvEmitter=e()}("undefined"!=typeof window?window:this,function(){function t(){}var e=t.prototype;return e.on=function(t,e){if(t&&e){var i=this._events=this._events||{},n=i[t]=i[t]||[];return-1==n.indexOf(e)&&n.push(e),this}},e.once=function(t,e){if(t&&e){this.on(t,e);var i=this._onceEvents=this._onceEvents||{},n=i[t]=i[t]||{};return n[e]=!0,this}},e.off=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var n=i.indexOf(e);return-1!=n&&i.splice(n,1),this}},e.emitEvent=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var n=0,o=i[n];e=e||[];for(var r=this._onceEvents&&this._onceEvents[t];o;){var s=r&&r[o];s&&(this.off(t,o),delete r[o]),o.apply(this,e),n+=s?0:1,o=i[n]}return this}},t}),function(t,e){"use strict";"function"==typeof define&&define.amd?define(["ev-emitter/ev-emitter"],function(i){return e(t,i)}):"object"==typeof module&&module.exports?module.exports=e(t,require("ev-emitter")):t.imagesLoaded=e(t,t.EvEmitter)}("undefined"!=typeof window?window:this,function(t,e){function i(t,e){for(var i in e)t[i]=e[i];return t}function n(t){var e=[];if(Array.isArray(t))e=t;else if("number"==typeof t.length)for(var i=0;ie?1:0},sum:function(t,e){var n={};return t.reduce(e?function(t,r,o){return n.index=o,t+e.call(n,r)}:function(t,e){return t+e},0)},max:function(t,e){return Math.max.apply(null,e?n.map(t,e):t)}},r=function(){function t(t,e,n){return(t<<2*u)+(e<>l,o=e[1]>>l,a=e[2]>>l,n=t(r,o,a),s[n]=(s[n]||0)+1}),s}function i(t,e){var n,o,a,i=1e6,s=0,c=1e6,u=0,f=1e6,p=0;return t.forEach(function(t){n=t[0]>>l,o=t[1]>>l,a=t[2]>>l,ns&&(s=n),ou&&(u=o),ap&&(p=a)}),new r(i,s,c,u,f,p,e)}function s(e,r){if(r.count()){var o=r.r2-r.r1+1,a=r.g2-r.g1+1,i=r.b2-r.b1+1,s=n.max([o,a,i]);if(1==r.count())return[r.copy()];var c,u,l,f,p,v=0,g=[],h=[];if(s==o)for(c=r.r1;c<=r.r2;c++){for(f=0,u=r.g1;u<=r.g2;u++)for(l=r.b1;l<=r.b2;l++)p=t(c,u,l),f+=e[p]||0;v+=f,g[c]=v}else if(s==a)for(c=r.g1;c<=r.g2;c++){for(f=0,u=r.r1;u<=r.r2;u++)for(l=r.b1;l<=r.b2;l++)p=t(u,c,l),f+=e[p]||0;v+=f,g[c]=v}else for(c=r.b1;c<=r.b2;c++){for(f=0,u=r.r1;u<=r.r2;u++)for(l=r.g1;l<=r.g2;l++)p=t(u,l,c),f+=e[p]||0;v+=f,g[c]=v}return g.forEach(function(t,e){h[e]=v-t}),function(t){var e,n,o,a,i,s=t+"1",u=t+"2",l=0;for(c=r[s];c<=r[u];c++)if(g[c]>v/2){for(o=r.copy(),a=r.copy(),e=c-r[s],n=r[u]-c,i=e<=n?Math.min(r[u]-1,~~(c+n/2)):Math.max(r[s],~~(c-1-e/2));!g[i];)i++;for(l=h[i];!l&&g[i-1];)l=h[--i];return o[u]=i,a[s]=o[u]+1,[o,a]}}(s==o?"r":s==a?"g":"b")}}function c(t,r){function c(t,e){for(var n,r=1,o=0;o=e)return;if(o++>f)return}else t.push(n),o++}if(!t.length||r<2||r>256)return!1;var u=a(t),l=0;u.forEach(function(){l++});var v=i(t,u),g=new e(function(t,e){return n.naturalOrder(t.count(),e.count())});g.push(v),c(g,p*r);for(var h=new e(function(t,e){return n.naturalOrder(t.count()*t.volume(),e.count()*e.volume())});g.size();)h.push(g.pop());c(h,r-h.size());for(var y=new o;h.size();)y.push(h.pop());return y}var u=5,l=8-u,f=1e3,p=.75;return r.prototype={volume:function(t){var e=this;return e._volume&&!t||(e._volume=(e.r2-e.r1+1)*(e.g2-e.g1+1)*(e.b2-e.b1+1)),e._volume},count:function(e){var n=this,r=n.histo;if(!n._count_set||e){var o,a,i,s,c=0;for(a=n.r1;a<=n.r2;a++)for(i=n.g1;i<=n.g2;i++)for(s=n.b1;s<=n.b2;s++)o=t(a,i,s),c+=r[o]||0;n._count=c,n._count_set=!0}return n._count},copy:function(){var t=this;return new r(t.r1,t.r2,t.g1,t.g2,t.b1,t.b2,t.histo)},avg:function(e){var n=this,r=n.histo;if(!n._avg||e){var o,a,i,s,c,l=0,f=1<<8-u,p=0,v=0,g=0;for(a=n.r1;a<=n.r2;a++)for(i=n.g1;i<=n.g2;i++)for(s=n.b1;s<=n.b2;s++)c=t(a,i,s),o=r[c]||0,l+=o,p+=o*(a+.5)*f,v+=o*(i+.5)*f,g+=o*(s+.5)*f;n._avg=l?[~~(p/l),~~(v/l),~~(g/l)]:[~~(f*(n.r1+n.r2+1)/2),~~(f*(n.g1+n.g2+1)/2),~~(f*(n.b1+n.b2+1)/2)]}return n._avg},contains:function(t){var e=this,n=t[0]>>l,r=t[1]>>l,o=t[2]>>l;return n>=e.r1&&n<=e.r2&&r>=e.g1&&r<=e.g2&&o>=e.b1&&o<=e.b2}},o.prototype={push:function(t){this.vboxes.push({vbox:t,color:t.avg()})},palette:function(){return this.vboxes.map(function(t){return t.color})},size:function(){return this.vboxes.size()},map:function(t){for(var e=this.vboxes,n=0;n251&&o[1]>251&&o[2]>251&&(t[r].color=[255,255,255])}},{quantize:c}}();return t.prototype.getColor=function(t,e){return this.getPalette(t,5,e)[0]},t.prototype.getPalette=function(t,n,o){(void 0===n||n<2||n>256)&&(n=10),(void 0===o||o<1)&&(o=10);for(var a,i,s,c,u=new e(t),l=u.getImageData(),f=l.data,p=u.getPixelCount(),v=[],g=0;g=125&&(i>250&&s>250&&c>250||v.push([i,s,c]));var h=r.quantize(v,n),y=h?h.palette():null;return u.removeCanvas(),y},t.prototype.getColorFromUrl=function(t,e,n){sourceImage=document.createElement("img");var r=this;sourceImage.addEventListener("load",function(){e(r.getPalette(sourceImage,5,n)[0],t)}),sourceImage.src=t},t.prototype.getImageData=function(t,e){xhr=new XMLHttpRequest,xhr.open("GET",t,!0),xhr.responseType="arraybuffer",xhr.onload=function(t){if(200==this.status){uInt8Array=new Uint8Array(this.response),n=uInt8Array.length,binaryString=new Array(n);for(var n=0;n.auto{width:auto}.grid-x>.shrink{width:auto}.grid-x>.small-shrink,.grid-x>.small-full,.grid-x>.small-1,.grid-x>.small-2,.grid-x>.small-3,.grid-x>.small-4,.grid-x>.small-5,.grid-x>.small-6,.grid-x>.small-7,.grid-x>.small-8,.grid-x>.small-9,.grid-x>.small-10,.grid-x>.small-11,.grid-x>.small-12{-ms-flex-preferred-size:auto;flex-basis:auto}@media print, screen and (min-width: 40em){.grid-x>.medium-shrink,.grid-x>.medium-full,.grid-x>.medium-1,.grid-x>.medium-2,.grid-x>.medium-3,.grid-x>.medium-4,.grid-x>.medium-5,.grid-x>.medium-6,.grid-x>.medium-7,.grid-x>.medium-8,.grid-x>.medium-9,.grid-x>.medium-10,.grid-x>.medium-11,.grid-x>.medium-12{-ms-flex-preferred-size:auto;flex-basis:auto}}@media print, screen and (min-width: 64em){.grid-x>.large-shrink,.grid-x>.large-full,.grid-x>.large-1,.grid-x>.large-2,.grid-x>.large-3,.grid-x>.large-4,.grid-x>.large-5,.grid-x>.large-6,.grid-x>.large-7,.grid-x>.large-8,.grid-x>.large-9,.grid-x>.large-10,.grid-x>.large-11,.grid-x>.large-12{-ms-flex-preferred-size:auto;flex-basis:auto}}.grid-x>.small-1{width:8.33333%}.grid-x>.small-2{width:16.66667%}.grid-x>.small-3{width:25%}.grid-x>.small-4{width:33.33333%}.grid-x>.small-5{width:41.66667%}.grid-x>.small-6{width:50%}.grid-x>.small-7{width:58.33333%}.grid-x>.small-8{width:66.66667%}.grid-x>.small-9{width:75%}.grid-x>.small-10{width:83.33333%}.grid-x>.small-11{width:91.66667%}.grid-x>.small-12{width:100%}@media print, screen and (min-width: 40em){.grid-x>.medium-auto{-webkit-box-flex:1;-ms-flex:1 1 0px;flex:1 1 0px;width:auto}.grid-x>.medium-shrink{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.grid-x>.medium-1{width:8.33333%}.grid-x>.medium-2{width:16.66667%}.grid-x>.medium-3{width:25%}.grid-x>.medium-4{width:33.33333%}.grid-x>.medium-5{width:41.66667%}.grid-x>.medium-6{width:50%}.grid-x>.medium-7{width:58.33333%}.grid-x>.medium-8{width:66.66667%}.grid-x>.medium-9{width:75%}.grid-x>.medium-10{width:83.33333%}.grid-x>.medium-11{width:91.66667%}.grid-x>.medium-12{width:100%}}@media print, screen and (min-width: 64em){.grid-x>.large-auto{-webkit-box-flex:1;-ms-flex:1 1 0px;flex:1 1 0px;width:auto}.grid-x>.large-shrink{-webkit-box-flex:0;-ms-flex:0 0 auto;flex:0 0 auto;width:auto}.grid-x>.large-1{width:8.33333%}.grid-x>.large-2{width:16.66667%}.grid-x>.large-3{width:25%}.grid-x>.large-4{width:33.33333%}.grid-x>.large-5{width:41.66667%}.grid-x>.large-6{width:50%}.grid-x>.large-7{width:58.33333%}.grid-x>.large-8{width:66.66667%}.grid-x>.large-9{width:75%}.grid-x>.large-10{width:83.33333%}.grid-x>.large-11{width:91.66667%}.grid-x>.large-12{width:100%}}.grid-margin-x:not(.grid-x)>.cell{width:auto}.grid-margin-y:not(.grid-y)>.cell{height:auto}.grid-margin-x{margin-left:-.625rem;margin-right:-.625rem}@media print, screen and (min-width: 40em){.grid-margin-x{margin-left:-.9375rem;margin-right:-.9375rem}}.grid-margin-x>.cell{width:calc(100% - 1.25rem);margin-left:.625rem;margin-right:.625rem}@media print, screen and (min-width: 40em){.grid-margin-x>.cell{width:calc(100% - 1.875rem);margin-left:.9375rem;margin-right:.9375rem}}.grid-margin-x>.auto{width:auto}.grid-margin-x>.shrink{width:auto}.grid-margin-x>.small-1{width:calc(8.33333% - 1.25rem)}.grid-margin-x>.small-2{width:calc(16.66667% - 1.25rem)}.grid-margin-x>.small-3{width:calc(25% - 1.25rem)}.grid-margin-x>.small-4{width:calc(33.33333% - 1.25rem)}.grid-margin-x>.small-5{width:calc(41.66667% - 1.25rem)}.grid-margin-x>.small-6{width:calc(50% - 1.25rem)}.grid-margin-x>.small-7{width:calc(58.33333% - 1.25rem)}.grid-margin-x>.small-8{width:calc(66.66667% - 1.25rem)}.grid-margin-x>.small-9{width:calc(75% - 1.25rem)}.grid-margin-x>.small-10{width:calc(83.33333% - 1.25rem)}.grid-margin-x>.small-11{width:calc(91.66667% - 1.25rem)}.grid-margin-x>.small-12{width:calc(100% - 1.25rem)}@media print, screen and (min-width: 40em){.grid-margin-x>.auto{width:auto}.grid-margin-x>.shrink{width:auto}.grid-margin-x>.small-1{width:calc(8.33333% - 1.875rem)}.grid-margin-x>.small-2{width:calc(16.66667% - 1.875rem)}.grid-margin-x>.small-3{width:calc(25% - 1.875rem)}.grid-margin-x>.small-4{width:calc(33.33333% - 1.875rem)}.grid-margin-x>.small-5{width:calc(41.66667% - 1.875rem)}.grid-margin-x>.small-6{width:calc(50% - 1.875rem)}.grid-margin-x>.small-7{width:calc(58.33333% - 1.875rem)}.grid-margin-x>.small-8{width:calc(66.66667% - 1.875rem)}.grid-margin-x>.small-9{width:calc(75% - 1.875rem)}.grid-margin-x>.small-10{width:calc(83.33333% - 1.875rem)}.grid-margin-x>.small-11{width:calc(91.66667% - 1.875rem)}.grid-margin-x>.small-12{width:calc(100% - 1.875rem)}.grid-margin-x>.medium-auto{width:auto}.grid-margin-x>.medium-shrink{width:auto}.grid-margin-x>.medium-1{width:calc(8.33333% - 1.875rem)}.grid-margin-x>.medium-2{width:calc(16.66667% - 1.875rem)}.grid-margin-x>.medium-3{width:calc(25% - 1.875rem)}.grid-margin-x>.medium-4{width:calc(33.33333% - 1.875rem)}.grid-margin-x>.medium-5{width:calc(41.66667% - 1.875rem)}.grid-margin-x>.medium-6{width:calc(50% - 1.875rem)}.grid-margin-x>.medium-7{width:calc(58.33333% - 1.875rem)}.grid-margin-x>.medium-8{width:calc(66.66667% - 1.875rem)}.grid-margin-x>.medium-9{width:calc(75% - 1.875rem)}.grid-margin-x>.medium-10{width:calc(83.33333% - 1.875rem)}.grid-margin-x>.medium-11{width:calc(91.66667% - 1.875rem)}.grid-margin-x>.medium-12{width:calc(100% - 1.875rem)}}@media print, screen and (min-width: 64em){.grid-margin-x>.large-auto{width:auto}.grid-margin-x>.large-shrink{width:auto}.grid-margin-x>.large-1{width:calc(8.33333% - 1.875rem)}.grid-margin-x>.large-2{width:calc(16.66667% - 1.875rem)}.grid-margin-x>.large-3{width:calc(25% - 1.875rem)}.grid-margin-x>.large-4{width:calc(33.33333% - 1.875rem)}.grid-margin-x>.large-5{width:calc(41.66667% - 1.875rem)}.grid-margin-x>.large-6{width:calc(50% - 1.875rem)}.grid-margin-x>.large-7{width:calc(58.33333% - 1.875rem)}.grid-margin-x>.large-8{width:calc(66.66667% - 1.875rem)}.grid-margin-x>.large-9{width:calc(75% - 1.875rem)}.grid-margin-x>.large-10{width:calc(83.33333% - 1.875rem)}.grid-margin-x>.large-11{width:calc(91.66667% - 1.875rem)}.grid-margin-x>.large-12{width:calc(100% - 1.875rem)}}.grid-padding-x .grid-padding-x{margin-right:-.625rem;margin-left:-.625rem}@media print, screen and (min-width: 40em){.grid-padding-x .grid-padding-x{margin-right:-.9375rem;margin-left:-.9375rem}}.grid-container:not(.full)>.grid-padding-x{margin-right:-.625rem;margin-left:-.625rem}@media print, screen and (min-width: 40em){.grid-container:not(.full)>.grid-padding-x{margin-right:-.9375rem;margin-left:-.9375rem}}.grid-padding-x>.cell{padding-right:.625rem;padding-left:.625rem}@media print, screen and (min-width: 40em){.grid-padding-x>.cell{padding-right:.9375rem;padding-left:.9375rem}}.small-up-1>.cell{width:100%}.small-up-2>.cell{width:50%}.small-up-3>.cell{width:33.33333%}.small-up-4>.cell{width:25%}.small-up-5>.cell{width:20%}.small-up-6>.cell{width:16.66667%}.small-up-7>.cell{width:14.28571%}.small-up-8>.cell{width:12.5%}@media print, screen and (min-width: 40em){.medium-up-1>.cell{width:100%}.medium-up-2>.cell{width:50%}.medium-up-3>.cell{width:33.33333%}.medium-up-4>.cell{width:25%}.medium-up-5>.cell{width:20%}.medium-up-6>.cell{width:16.66667%}.medium-up-7>.cell{width:14.28571%}.medium-up-8>.cell{width:12.5%}}@media print, screen and (min-width: 64em){.large-up-1>.cell{width:100%}.large-up-2>.cell{width:50%}.large-up-3>.cell{width:33.33333%}.large-up-4>.cell{width:25%}.large-up-5>.cell{width:20%}.large-up-6>.cell{width:16.66667%}.large-up-7>.cell{width:14.28571%}.large-up-8>.cell{width:12.5%}}.grid-margin-x.small-up-1>.cell{width:calc(100% - 1.25rem)}.grid-margin-x.small-up-2>.cell{width:calc(50% - 1.25rem)}.grid-margin-x.small-up-3>.cell{width:calc(33.33333% - 1.25rem)}.grid-margin-x.small-up-4>.cell{width:calc(25% - 1.25rem)}.grid-margin-x.small-up-5>.cell{width:calc(20% - 1.25rem)}.grid-margin-x.small-up-6>.cell{width:calc(16.66667% - 1.25rem)}.grid-margin-x.small-up-7>.cell{width:calc(14.28571% - 1.25rem)}.grid-margin-x.small-up-8>.cell{width:calc(12.5% - 1.25rem)}@media print, screen and (min-width: 40em){.grid-margin-x.small-up-1>.cell{width:calc(100% - 1.25rem)}.grid-margin-x.small-up-2>.cell{width:calc(50% - 1.25rem)}.grid-margin-x.small-up-3>.cell{width:calc(33.33333% - 1.25rem)}.grid-margin-x.small-up-4>.cell{width:calc(25% - 1.25rem)}.grid-margin-x.small-up-5>.cell{width:calc(20% - 1.25rem)}.grid-margin-x.small-up-6>.cell{width:calc(16.66667% - 1.25rem)}.grid-margin-x.small-up-7>.cell{width:calc(14.28571% - 1.25rem)}.grid-margin-x.small-up-8>.cell{width:calc(12.5% - 1.25rem)}.grid-margin-x.medium-up-1>.cell{width:calc(100% - 1.875rem)}.grid-margin-x.medium-up-2>.cell{width:calc(50% - 1.875rem)}.grid-margin-x.medium-up-3>.cell{width:calc(33.33333% - 1.875rem)}.grid-margin-x.medium-up-4>.cell{width:calc(25% - 1.875rem)}.grid-margin-x.medium-up-5>.cell{width:calc(20% - 1.875rem)}.grid-margin-x.medium-up-6>.cell{width:calc(16.66667% - 1.875rem)}.grid-margin-x.medium-up-7>.cell{width:calc(14.28571% - 1.875rem)}.grid-margin-x.medium-up-8>.cell{width:calc(12.5% - 1.875rem)}}@media print, screen and (min-width: 64em){.grid-margin-x.large-up-1>.cell{width:calc(100% - 1.875rem)}.grid-margin-x.large-up-2>.cell{width:calc(50% - 1.875rem)}.grid-margin-x.large-up-3>.cell{width:calc(33.33333% - 1.875rem)}.grid-margin-x.large-up-4>.cell{width:calc(25% - 1.875rem)}.grid-margin-x.large-up-5>.cell{width:calc(20% - 1.875rem)}.grid-margin-x.large-up-6>.cell{width:calc(16.66667% - 1.875rem)}.grid-margin-x.large-up-7>.cell{width:calc(14.28571% - 1.875rem)}.grid-margin-x.large-up-8>.cell{width:calc(12.5% - 1.875rem)}}.small-margin-collapse{margin-right:0;margin-left:0}.small-margin-collapse>.cell{margin-right:0;margin-left:0}.small-margin-collapse>.small-1{width:8.33333%}.small-margin-collapse>.small-2{width:16.66667%}.small-margin-collapse>.small-3{width:25%}.small-margin-collapse>.small-4{width:33.33333%}.small-margin-collapse>.small-5{width:41.66667%}.small-margin-collapse>.small-6{width:50%}.small-margin-collapse>.small-7{width:58.33333%}.small-margin-collapse>.small-8{width:66.66667%}.small-margin-collapse>.small-9{width:75%}.small-margin-collapse>.small-10{width:83.33333%}.small-margin-collapse>.small-11{width:91.66667%}.small-margin-collapse>.small-12{width:100%}@media print, screen and (min-width: 40em){.small-margin-collapse>.medium-1{width:8.33333%}.small-margin-collapse>.medium-2{width:16.66667%}.small-margin-collapse>.medium-3{width:25%}.small-margin-collapse>.medium-4{width:33.33333%}.small-margin-collapse>.medium-5{width:41.66667%}.small-margin-collapse>.medium-6{width:50%}.small-margin-collapse>.medium-7{width:58.33333%}.small-margin-collapse>.medium-8{width:66.66667%}.small-margin-collapse>.medium-9{width:75%}.small-margin-collapse>.medium-10{width:83.33333%}.small-margin-collapse>.medium-11{width:91.66667%}.small-margin-collapse>.medium-12{width:100%}}@media print, screen and (min-width: 64em){.small-margin-collapse>.large-1{width:8.33333%}.small-margin-collapse>.large-2{width:16.66667%}.small-margin-collapse>.large-3{width:25%}.small-margin-collapse>.large-4{width:33.33333%}.small-margin-collapse>.large-5{width:41.66667%}.small-margin-collapse>.large-6{width:50%}.small-margin-collapse>.large-7{width:58.33333%}.small-margin-collapse>.large-8{width:66.66667%}.small-margin-collapse>.large-9{width:75%}.small-margin-collapse>.large-10{width:83.33333%}.small-margin-collapse>.large-11{width:91.66667%}.small-margin-collapse>.large-12{width:100%}}.small-padding-collapse{margin-right:0;margin-left:0}.small-padding-collapse>.cell{padding-right:0;padding-left:0}@media print, screen and (min-width: 40em){.medium-margin-collapse{margin-right:0;margin-left:0}.medium-margin-collapse>.cell{margin-right:0;margin-left:0}}@media print, screen and (min-width: 40em){.medium-margin-collapse>.small-1{width:8.33333%}.medium-margin-collapse>.small-2{width:16.66667%}.medium-margin-collapse>.small-3{width:25%}.medium-margin-collapse>.small-4{width:33.33333%}.medium-margin-collapse>.small-5{width:41.66667%}.medium-margin-collapse>.small-6{width:50%}.medium-margin-collapse>.small-7{width:58.33333%}.medium-margin-collapse>.small-8{width:66.66667%}.medium-margin-collapse>.small-9{width:75%}.medium-margin-collapse>.small-10{width:83.33333%}.medium-margin-collapse>.small-11{width:91.66667%}.medium-margin-collapse>.small-12{width:100%}}@media print, screen and (min-width: 40em){.medium-margin-collapse>.medium-1{width:8.33333%}.medium-margin-collapse>.medium-2{width:16.66667%}.medium-margin-collapse>.medium-3{width:25%}.medium-margin-collapse>.medium-4{width:33.33333%}.medium-margin-collapse>.medium-5{width:41.66667%}.medium-margin-collapse>.medium-6{width:50%}.medium-margin-collapse>.medium-7{width:58.33333%}.medium-margin-collapse>.medium-8{width:66.66667%}.medium-margin-collapse>.medium-9{width:75%}.medium-margin-collapse>.medium-10{width:83.33333%}.medium-margin-collapse>.medium-11{width:91.66667%}.medium-margin-collapse>.medium-12{width:100%}}@media print, screen and (min-width: 64em){.medium-margin-collapse>.large-1{width:8.33333%}.medium-margin-collapse>.large-2{width:16.66667%}.medium-margin-collapse>.large-3{width:25%}.medium-margin-collapse>.large-4{width:33.33333%}.medium-margin-collapse>.large-5{width:41.66667%}.medium-margin-collapse>.large-6{width:50%}.medium-margin-collapse>.large-7{width:58.33333%}.medium-margin-collapse>.large-8{width:66.66667%}.medium-margin-collapse>.large-9{width:75%}.medium-margin-collapse>.large-10{width:83.33333%}.medium-margin-collapse>.large-11{width:91.66667%}.medium-margin-collapse>.large-12{width:100%}}@media print, screen and (min-width: 40em){.medium-padding-collapse{margin-right:0;margin-left:0}.medium-padding-collapse>.cell{padding-right:0;padding-left:0}}@media print, screen and (min-width: 64em){.large-margin-collapse{margin-right:0;margin-left:0}.large-margin-collapse>.cell{margin-right:0;margin-left:0}}@media print, screen and (min-width: 64em){.large-margin-collapse>.small-1{width:8.33333%}.large-margin-collapse>.small-2{width:16.66667%}.large-margin-collapse>.small-3{width:25%}.large-margin-collapse>.small-4{width:33.33333%}.large-margin-collapse>.small-5{width:41.66667%}.large-margin-collapse>.small-6{width:50%}.large-margin-collapse>.small-7{width:58.33333%}.large-margin-collapse>.small-8{width:66.66667%}.large-margin-collapse>.small-9{width:75%}.large-margin-collapse>.small-10{width:83.33333%}.large-margin-collapse>.small-11{width:91.66667%}.large-margin-collapse>.small-12{width:100%}}@media print, screen and (min-width: 64em){.large-margin-collapse>.medium-1{width:8.33333%}.large-margin-collapse>.medium-2{width:16.66667%}.large-margin-collapse>.medium-3{width:25%}.large-margin-collapse>.medium-4{width:33.33333%}.large-margin-collapse>.medium-5{width:41.66667%}.large-margin-collapse>.medium-6{width:50%}.large-margin-collapse>.medium-7{width:58.33333%}.large-margin-collapse>.medium-8{width:66.66667%}.large-margin-collapse>.medium-9{width:75%}.large-margin-collapse>.medium-10{width:83.33333%}.large-margin-collapse>.medium-11{width:91.66667%}.large-margin-collapse>.medium-12{width:100%}}@media print, screen and (min-width: 64em){.large-margin-collapse>.large-1{width:8.33333%}.large-margin-collapse>.large-2{width:16.66667%}.large-margin-collapse>.large-3{width:25%}.large-margin-collapse>.large-4{width:33.33333%}.large-margin-collapse>.large-5{width:41.66667%}.large-margin-collapse>.large-6{width:50%}.large-margin-collapse>.large-7{width:58.33333%}.large-margin-collapse>.large-8{width:66.66667%}.large-margin-collapse>.large-9{width:75%}.large-margin-collapse>.large-10{width:83.33333%}.large-margin-collapse>.large-11{width:91.66667%}.large-margin-collapse>.large-12{width:100%}}@media print, screen and (min-width: 64em){.large-padding-collapse{margin-right:0;margin-left:0}.large-padding-collapse>.cell{padding-right:0;padding-left:0}}.small-offset-0{margin-left:0%}.grid-margin-x>.small-offset-0{margin-left:calc(0% + .625rem)}.small-offset-1{margin-left:8.33333%}.grid-margin-x>.small-offset-1{margin-left:calc(8.33333% + .625rem)}.small-offset-2{margin-left:16.66667%}.grid-margin-x>.small-offset-2{margin-left:calc(16.66667% + .625rem)}.small-offset-3{margin-left:25%}.grid-margin-x>.small-offset-3{margin-left:calc(25% + .625rem)}.small-offset-4{margin-left:33.33333%}.grid-margin-x>.small-offset-4{margin-left:calc(33.33333% + .625rem)}.small-offset-5{margin-left:41.66667%}.grid-margin-x>.small-offset-5{margin-left:calc(41.66667% + .625rem)}.small-offset-6{margin-left:50%}.grid-margin-x>.small-offset-6{margin-left:calc(50% + .625rem)}.small-offset-7{margin-left:58.33333%}.grid-margin-x>.small-offset-7{margin-left:calc(58.33333% + .625rem)}.small-offset-8{margin-left:66.66667%}.grid-margin-x>.small-offset-8{margin-left:calc(66.66667% + .625rem)}.small-offset-9{margin-left:75%}.grid-margin-x>.small-offset-9{margin-left:calc(75% + .625rem)}.small-offset-10{margin-left:83.33333%}.grid-margin-x>.small-offset-10{margin-left:calc(83.33333% + .625rem)}.small-offset-11{margin-left:91.66667%}.grid-margin-x>.small-offset-11{margin-left:calc(91.66667% + .625rem)}@media print, screen and (min-width: 40em){.medium-offset-0{margin-left:0%}.grid-margin-x>.medium-offset-0{margin-left:calc(0% + .9375rem)}.medium-offset-1{margin-left:8.33333%}.grid-margin-x>.medium-offset-1{margin-left:calc(8.33333% + .9375rem)}.medium-offset-2{margin-left:16.66667%}.grid-margin-x>.medium-offset-2{margin-left:calc(16.66667% + .9375rem)}.medium-offset-3{margin-left:25%}.grid-margin-x>.medium-offset-3{margin-left:calc(25% + .9375rem)}.medium-offset-4{margin-left:33.33333%}.grid-margin-x>.medium-offset-4{margin-left:calc(33.33333% + .9375rem)}.medium-offset-5{margin-left:41.66667%}.grid-margin-x>.medium-offset-5{margin-left:calc(41.66667% + .9375rem)}.medium-offset-6{margin-left:50%}.grid-margin-x>.medium-offset-6{margin-left:calc(50% + .9375rem)}.medium-offset-7{margin-left:58.33333%}.grid-margin-x>.medium-offset-7{margin-left:calc(58.33333% + .9375rem)}.medium-offset-8{margin-left:66.66667%}.grid-margin-x>.medium-offset-8{margin-left:calc(66.66667% + .9375rem)}.medium-offset-9{margin-left:75%}.grid-margin-x>.medium-offset-9{margin-left:calc(75% + .9375rem)}.medium-offset-10{margin-left:83.33333%}.grid-margin-x>.medium-offset-10{margin-left:calc(83.33333% + .9375rem)}.medium-offset-11{margin-left:91.66667%}.grid-margin-x>.medium-offset-11{margin-left:calc(91.66667% + .9375rem)}}@media print, screen and (min-width: 64em){.large-offset-0{margin-left:0%}.grid-margin-x>.large-offset-0{margin-left:calc(0% + .9375rem)}.large-offset-1{margin-left:8.33333%}.grid-margin-x>.large-offset-1{margin-left:calc(8.33333% + .9375rem)}.large-offset-2{margin-left:16.66667%}.grid-margin-x>.large-offset-2{margin-left:calc(16.66667% + .9375rem)}.large-offset-3{margin-left:25%}.grid-margin-x>.large-offset-3{margin-left:calc(25% + .9375rem)}.large-offset-4{margin-left:33.33333%}.grid-margin-x>.large-offset-4{margin-left:calc(33.33333% + .9375rem)}.large-offset-5{margin-left:41.66667%}.grid-margin-x>.large-offset-5{margin-left:calc(41.66667% + .9375rem)}.large-offset-6{margin-left:50%}.grid-margin-x>.large-offset-6{margin-left:calc(50% + .9375rem)}.large-offset-7{margin-left:58.33333%}.grid-margin-x>.large-offset-7{margin-left:calc(58.33333% + .9375rem)}.large-offset-8{margin-left:66.66667%}.grid-margin-x>.large-offset-8{margin-left:calc(66.66667% + .9375rem)}.large-offset-9{margin-left:75%}.grid-margin-x>.large-offset-9{margin-left:calc(75% + .9375rem)}.large-offset-10{margin-left:83.33333%}.grid-margin-x>.large-offset-10{margin-left:calc(83.33333% + .9375rem)}.large-offset-11{margin-left:91.66667%}.grid-margin-x>.large-offset-11{margin-left:calc(91.66667% + .9375rem)}}.grid-y{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-flow:column nowrap;flex-flow:column nowrap}.grid-y>.cell{width:auto}.grid-y>.auto{height:auto}.grid-y>.shrink{height:auto}.grid-y>.small-shrink,.grid-y>.small-full,.grid-y>.small-1,.grid-y>.small-2,.grid-y>.small-3,.grid-y>.small-4,.grid-y>.small-5,.grid-y>.small-6,.grid-y>.small-7,.grid-y>.small-8,.grid-y>.small-9,.grid-y>.small-10,.grid-y>.small-11,.grid-y>.small-12{-ms-flex-preferred-size:auto;flex-basis:auto}@media print, screen and (min-width: 40em){.grid-y>.medium-shrink,.grid-y>.medium-full,.grid-y>.medium-1,.grid-y>.medium-2,.grid-y>.medium-3,.grid-y>.medium-4,.grid-y>.medium-5,.grid-y>.medium-6,.grid-y>.medium-7,.grid-y>.medium-8,.grid-y>.medium-9,.grid-y>.medium-10,.grid-y>.medium-11,.grid-y>.medium-12{-ms-flex-preferred-size:auto;flex-basis:auto}}@media print, screen and (min-width: 64em){.grid-y>.large-shrink,.grid-y>.large-full,.grid-y>.large-1,.grid-y>.large-2,.grid-y>.large-3,.grid-y>.large-4,.grid-y>.large-5,.grid-y>.large-6,.grid-y>.large-7,.grid-y>.large-8,.grid-y>.large-9,.grid-y>.large-10,.grid-y>.large-11,.grid-y>.large-12{-ms-flex-preferred-size:auto;flex-basis:auto}}.grid-y>.small-1{height:8.33333%}.grid-y>.small-2{height:16.66667%}.grid-y>.small-3{height:25%}.grid-y>.small-4{height:33.33333%}.grid-y>.small-5{height:41.66667%}.grid-y>.small-6{height:50%}.grid-y>.small-7{height:58.33333%}.grid-y>.small-8{height:66.66667%}.grid-y>.small-9{height:75%}.grid-y>.small-10{height:83.33333%}.grid-y>.small-11{height:91.66667%}.grid-y>.small-12{height:100%}@media print, screen and (min-width: 40em){.grid-y>.medium-auto{-webkit-box-flex:1;-ms-flex:1 1 0px;flex:1 1 0px;height:auto}.grid-y>.medium-shrink{height:auto}.grid-y>.medium-1{height:8.33333%}.grid-y>.medium-2{height:16.66667%}.grid-y>.medium-3{height:25%}.grid-y>.medium-4{height:33.33333%}.grid-y>.medium-5{height:41.66667%}.grid-y>.medium-6{height:50%}.grid-y>.medium-7{height:58.33333%}.grid-y>.medium-8{height:66.66667%}.grid-y>.medium-9{height:75%}.grid-y>.medium-10{height:83.33333%}.grid-y>.medium-11{height:91.66667%}.grid-y>.medium-12{height:100%}}@media print, screen and (min-width: 64em){.grid-y>.large-auto{-webkit-box-flex:1;-ms-flex:1 1 0px;flex:1 1 0px;height:auto}.grid-y>.large-shrink{height:auto}.grid-y>.large-1{height:8.33333%}.grid-y>.large-2{height:16.66667%}.grid-y>.large-3{height:25%}.grid-y>.large-4{height:33.33333%}.grid-y>.large-5{height:41.66667%}.grid-y>.large-6{height:50%}.grid-y>.large-7{height:58.33333%}.grid-y>.large-8{height:66.66667%}.grid-y>.large-9{height:75%}.grid-y>.large-10{height:83.33333%}.grid-y>.large-11{height:91.66667%}.grid-y>.large-12{height:100%}}.grid-padding-y .grid-padding-y{margin-top:-.625rem;margin-bottom:-.625rem}@media print, screen and (min-width: 40em){.grid-padding-y .grid-padding-y{margin-top:-.9375rem;margin-bottom:-.9375rem}}.grid-padding-y>.cell{padding-top:.625rem;padding-bottom:.625rem}@media print, screen and (min-width: 40em){.grid-padding-y>.cell{padding-top:.9375rem;padding-bottom:.9375rem}}.grid-margin-y{margin-top:-.625rem;margin-bottom:-.625rem}@media print, screen and (min-width: 40em){.grid-margin-y{margin-top:-.9375rem;margin-bottom:-.9375rem}}.grid-margin-y>.cell{height:calc(100% - 1.25rem);margin-top:.625rem;margin-bottom:.625rem}@media print, screen and (min-width: 40em){.grid-margin-y>.cell{height:calc(100% - 1.875rem);margin-top:.9375rem;margin-bottom:.9375rem}}.grid-margin-y>.auto{height:auto}.grid-margin-y>.shrink{height:auto}.grid-margin-y>.small-1{height:calc(8.33333% - 1.25rem)}.grid-margin-y>.small-2{height:calc(16.66667% - 1.25rem)}.grid-margin-y>.small-3{height:calc(25% - 1.25rem)}.grid-margin-y>.small-4{height:calc(33.33333% - 1.25rem)}.grid-margin-y>.small-5{height:calc(41.66667% - 1.25rem)}.grid-margin-y>.small-6{height:calc(50% - 1.25rem)}.grid-margin-y>.small-7{height:calc(58.33333% - 1.25rem)}.grid-margin-y>.small-8{height:calc(66.66667% - 1.25rem)}.grid-margin-y>.small-9{height:calc(75% - 1.25rem)}.grid-margin-y>.small-10{height:calc(83.33333% - 1.25rem)}.grid-margin-y>.small-11{height:calc(91.66667% - 1.25rem)}.grid-margin-y>.small-12{height:calc(100% - 1.25rem)}@media print, screen and (min-width: 40em){.grid-margin-y>.auto{height:auto}.grid-margin-y>.shrink{height:auto}.grid-margin-y>.small-1{height:calc(8.33333% - 1.875rem)}.grid-margin-y>.small-2{height:calc(16.66667% - 1.875rem)}.grid-margin-y>.small-3{height:calc(25% - 1.875rem)}.grid-margin-y>.small-4{height:calc(33.33333% - 1.875rem)}.grid-margin-y>.small-5{height:calc(41.66667% - 1.875rem)}.grid-margin-y>.small-6{height:calc(50% - 1.875rem)}.grid-margin-y>.small-7{height:calc(58.33333% - 1.875rem)}.grid-margin-y>.small-8{height:calc(66.66667% - 1.875rem)}.grid-margin-y>.small-9{height:calc(75% - 1.875rem)}.grid-margin-y>.small-10{height:calc(83.33333% - 1.875rem)}.grid-margin-y>.small-11{height:calc(91.66667% - 1.875rem)}.grid-margin-y>.small-12{height:calc(100% - 1.875rem)}.grid-margin-y>.medium-auto{height:auto}.grid-margin-y>.medium-shrink{height:auto}.grid-margin-y>.medium-1{height:calc(8.33333% - 1.875rem)}.grid-margin-y>.medium-2{height:calc(16.66667% - 1.875rem)}.grid-margin-y>.medium-3{height:calc(25% - 1.875rem)}.grid-margin-y>.medium-4{height:calc(33.33333% - 1.875rem)}.grid-margin-y>.medium-5{height:calc(41.66667% - 1.875rem)}.grid-margin-y>.medium-6{height:calc(50% - 1.875rem)}.grid-margin-y>.medium-7{height:calc(58.33333% - 1.875rem)}.grid-margin-y>.medium-8{height:calc(66.66667% - 1.875rem)}.grid-margin-y>.medium-9{height:calc(75% - 1.875rem)}.grid-margin-y>.medium-10{height:calc(83.33333% - 1.875rem)}.grid-margin-y>.medium-11{height:calc(91.66667% - 1.875rem)}.grid-margin-y>.medium-12{height:calc(100% - 1.875rem)}}@media print, screen and (min-width: 64em){.grid-margin-y>.large-auto{height:auto}.grid-margin-y>.large-shrink{height:auto}.grid-margin-y>.large-1{height:calc(8.33333% - 1.875rem)}.grid-margin-y>.large-2{height:calc(16.66667% - 1.875rem)}.grid-margin-y>.large-3{height:calc(25% - 1.875rem)}.grid-margin-y>.large-4{height:calc(33.33333% - 1.875rem)}.grid-margin-y>.large-5{height:calc(41.66667% - 1.875rem)}.grid-margin-y>.large-6{height:calc(50% - 1.875rem)}.grid-margin-y>.large-7{height:calc(58.33333% - 1.875rem)}.grid-margin-y>.large-8{height:calc(66.66667% - 1.875rem)}.grid-margin-y>.large-9{height:calc(75% - 1.875rem)}.grid-margin-y>.large-10{height:calc(83.33333% - 1.875rem)}.grid-margin-y>.large-11{height:calc(91.66667% - 1.875rem)}.grid-margin-y>.large-12{height:calc(100% - 1.875rem)}}.grid-frame{overflow:hidden;position:relative;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch;width:100vw}.cell .grid-frame{width:100%}.cell-block{overflow-x:auto;max-width:100%;-webkit-overflow-scrolling:touch;-ms-overflow-stype:-ms-autohiding-scrollbar}.cell-block-y{overflow-y:auto;max-height:100%;-webkit-overflow-scrolling:touch;-ms-overflow-stype:-ms-autohiding-scrollbar}.cell-block-container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;max-height:100%}.cell-block-container>.grid-x{max-height:100%;-ms-flex-wrap:nowrap;flex-wrap:nowrap}@media print, screen and (min-width: 40em){.medium-grid-frame{overflow:hidden;position:relative;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch;width:100vw}.cell .medium-grid-frame{width:100%}.medium-cell-block{overflow-x:auto;max-width:100%;-webkit-overflow-scrolling:touch;-ms-overflow-stype:-ms-autohiding-scrollbar}.medium-cell-block-container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;max-height:100%}.medium-cell-block-container>.grid-x{max-height:100%;-ms-flex-wrap:nowrap;flex-wrap:nowrap}.medium-cell-block-y{overflow-y:auto;max-height:100%;-webkit-overflow-scrolling:touch;-ms-overflow-stype:-ms-autohiding-scrollbar}}@media print, screen and (min-width: 64em){.large-grid-frame{overflow:hidden;position:relative;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch;width:100vw}.cell .large-grid-frame{width:100%}.large-cell-block{overflow-x:auto;max-width:100%;-webkit-overflow-scrolling:touch;-ms-overflow-stype:-ms-autohiding-scrollbar}.large-cell-block-container{display:-webkit-box;display:-ms-flexbox;display:flex;-webkit-box-orient:vertical;-webkit-box-direction:normal;-ms-flex-direction:column;flex-direction:column;max-height:100%}.large-cell-block-container>.grid-x{max-height:100%;-ms-flex-wrap:nowrap;flex-wrap:nowrap}.large-cell-block-y{overflow-y:auto;max-height:100%;-webkit-overflow-scrolling:touch;-ms-overflow-stype:-ms-autohiding-scrollbar}}.grid-y.grid-frame{width:auto;overflow:hidden;position:relative;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch;height:100vh}@media print, screen and (min-width: 40em){.grid-y.medium-grid-frame{width:auto;overflow:hidden;position:relative;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch;height:100vh}}@media print, screen and (min-width: 64em){.grid-y.large-grid-frame{width:auto;overflow:hidden;position:relative;-ms-flex-wrap:nowrap;flex-wrap:nowrap;-webkit-box-align:stretch;-ms-flex-align:stretch;align-items:stretch;height:100vh}}.cell .grid-y.grid-frame{height:100%}@media print, screen and (min-width: 40em){.cell .grid-y.medium-grid-frame{height:100%}}@media print, screen and (min-width: 64em){.cell .grid-y.large-grid-frame{height:100%}}.grid-margin-y{margin-top:-.625rem;margin-bottom:-.625rem}@media print, screen and (min-width: 40em){.grid-margin-y{margin-top:-.9375rem;margin-bottom:-.9375rem}}.grid-margin-y>.cell{height:calc(100% - 1.25rem);margin-top:.625rem;margin-bottom:.625rem}@media print, screen and (min-width: 40em){.grid-margin-y>.cell{height:calc(100% - 1.875rem);margin-top:.9375rem;margin-bottom:.9375rem}}.grid-margin-y>.auto{height:auto}.grid-margin-y>.shrink{height:auto}.grid-margin-y>.small-1{height:calc(8.33333% - 1.25rem)}.grid-margin-y>.small-2{height:calc(16.66667% - 1.25rem)}.grid-margin-y>.small-3{height:calc(25% - 1.25rem)}.grid-margin-y>.small-4{height:calc(33.33333% - 1.25rem)}.grid-margin-y>.small-5{height:calc(41.66667% - 1.25rem)}.grid-margin-y>.small-6{height:calc(50% - 1.25rem)}.grid-margin-y>.small-7{height:calc(58.33333% - 1.25rem)}.grid-margin-y>.small-8{height:calc(66.66667% - 1.25rem)}.grid-margin-y>.small-9{height:calc(75% - 1.25rem)}.grid-margin-y>.small-10{height:calc(83.33333% - 1.25rem)}.grid-margin-y>.small-11{height:calc(91.66667% - 1.25rem)}.grid-margin-y>.small-12{height:calc(100% - 1.25rem)}@media print, screen and (min-width: 40em){.grid-margin-y>.auto{height:auto}.grid-margin-y>.shrink{height:auto}.grid-margin-y>.small-1{height:calc(8.33333% - 1.875rem)}.grid-margin-y>.small-2{height:calc(16.66667% - 1.875rem)}.grid-margin-y>.small-3{height:calc(25% - 1.875rem)}.grid-margin-y>.small-4{height:calc(33.33333% - 1.875rem)}.grid-margin-y>.small-5{height:calc(41.66667% - 1.875rem)}.grid-margin-y>.small-6{height:calc(50% - 1.875rem)}.grid-margin-y>.small-7{height:calc(58.33333% - 1.875rem)}.grid-margin-y>.small-8{height:calc(66.66667% - 1.875rem)}.grid-margin-y>.small-9{height:calc(75% - 1.875rem)}.grid-margin-y>.small-10{height:calc(83.33333% - 1.875rem)}.grid-margin-y>.small-11{height:calc(91.66667% - 1.875rem)}.grid-margin-y>.small-12{height:calc(100% - 1.875rem)}.grid-margin-y>.medium-auto{height:auto}.grid-margin-y>.medium-shrink{height:auto}.grid-margin-y>.medium-1{height:calc(8.33333% - 1.875rem)}.grid-margin-y>.medium-2{height:calc(16.66667% - 1.875rem)}.grid-margin-y>.medium-3{height:calc(25% - 1.875rem)}.grid-margin-y>.medium-4{height:calc(33.33333% - 1.875rem)}.grid-margin-y>.medium-5{height:calc(41.66667% - 1.875rem)}.grid-margin-y>.medium-6{height:calc(50% - 1.875rem)}.grid-margin-y>.medium-7{height:calc(58.33333% - 1.875rem)}.grid-margin-y>.medium-8{height:calc(66.66667% - 1.875rem)}.grid-margin-y>.medium-9{height:calc(75% - 1.875rem)}.grid-margin-y>.medium-10{height:calc(83.33333% - 1.875rem)}.grid-margin-y>.medium-11{height:calc(91.66667% - 1.875rem)}.grid-margin-y>.medium-12{height:calc(100% - 1.875rem)}}@media print, screen and (min-width: 64em){.grid-margin-y>.large-auto{height:auto}.grid-margin-y>.large-shrink{height:auto}.grid-margin-y>.large-1{height:calc(8.33333% - 1.875rem)}.grid-margin-y>.large-2{height:calc(16.66667% - 1.875rem)}.grid-margin-y>.large-3{height:calc(25% - 1.875rem)}.grid-margin-y>.large-4{height:calc(33.33333% - 1.875rem)}.grid-margin-y>.large-5{height:calc(41.66667% - 1.875rem)}.grid-margin-y>.large-6{height:calc(50% - 1.875rem)}.grid-margin-y>.large-7{height:calc(58.33333% - 1.875rem)}.grid-margin-y>.large-8{height:calc(66.66667% - 1.875rem)}.grid-margin-y>.large-9{height:calc(75% - 1.875rem)}.grid-margin-y>.large-10{height:calc(83.33333% - 1.875rem)}.grid-margin-y>.large-11{height:calc(91.66667% - 1.875rem)}.grid-margin-y>.large-12{height:calc(100% - 1.875rem)}}.grid-frame.grid-margin-y{height:calc(100vh + 1.25rem)}@media print, screen and (min-width: 40em){.grid-frame.grid-margin-y{height:calc(100vh + 1.875rem)}}@media print, screen and (min-width: 64em){.grid-frame.grid-margin-y{height:calc(100vh + 1.875rem)}}@media print, screen and (min-width: 40em){.grid-margin-y.medium-grid-frame{height:calc(100vh + 1.875rem)}}@media print, screen and (min-width: 64em){.grid-margin-y.large-grid-frame{height:calc(100vh + 1.875rem)}} diff --git a/Bcore/src/main/cpp/Dobby/docs/styles/palettify.min.css b/Bcore/src/main/cpp/Dobby/docs/styles/palettify.min.css new file mode 100755 index 00000000..1696ea92 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/docs/styles/palettify.min.css @@ -0,0 +1 @@ +.diagonalBackground .figure{position:relative;overflow:hidden;min-width:220px;max-height:220px;text-align:center}.diagonalBackground .figure:hover .diagonal,.diagonalBackground .figure.hover .diagonal{-webkit-transform:skew(-45deg) scaleX(1);transform:skew(-45deg) scaleX(1);-webkit-transition:all 400ms cubic-bezier(0.175, 0.885, 0.32, 1.275);transition:all 400ms cubic-bezier(0.175, 0.885, 0.32, 1.275)}.diagonalBackground .figure:hover .caption .title,.diagonalBackground .figure:hover .caption .desc{-webkit-transform:translate3d(0%, 0%, 0);transform:translate3d(0%, 0%, 0);-webkit-transition-delay:0.2s;transition-delay:0.2s}.diagonalBackground .figure:hover .caption .title{opacity:1}.diagonalBackground .figure:hover .caption .desc{opacity:0.7}.diagonalBackground .figure *{-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-transition:all 0.6s ease;transition:all 0.6s ease}.diagonalBackground .figure img{opacity:1;-webkit-transition:opacity 0.35s;transition:opacity 0.35s;display:block}.diagonalBackground .figure .diagonal{width:100%;height:100%;position:absolute;left:0;bottom:0;opacity:0.90;-webkit-transform:skew(-45deg) scaleX(0);transform:skew(-45deg) scaleX(0);-webkit-transition:all 0.3s ease-in-out;transition:all 0.3s ease-in-out;background:#fff}.diagonalBackground .figure .caption{position:absolute;top:50%;left:0;width:100%;-webkit-transform:translateY(-50%);transform:translateY(-50%);z-index:1}.diagonalBackground .figure .title,.diagonalBackground .figure .desc{margin:0;width:100%;opacity:0;color:inherit}.diagonalBackground .figure .title{padding:0 30px;display:inline-block;font-weight:400;text-transform:uppercase}.diagonalBackground .figure .desc{padding:0 50px;font-size:0.8em;font-weight:500}.diagonalBackground .figure a{left:0;right:0;top:0;bottom:0;position:absolute;z-index:1}.zoomOutRight .figure{position:relative;min-width:230px;min-height:220px;text-align:right;line-height:1.4em;font-size:16px}.zoomOutRight .figure *{-webkit-box-sizing:border-box;box-sizing:border-box;-webkit-transition:all 0.35s ease;transition:all 0.35s ease}.zoomOutRight .figure .image{position:absolute;right:0;top:0;opacity:1;width:100%;height:100%;background:center/cover no-repeat}.zoomOutRight .figure .caption{position:absolute;width:50%;top:50%;left:0;-webkit-transform:translateY(-50%);transform:translateY(-50%);padding:20px 0 20px 20px}.zoomOutRight .figure .title,.zoomOutRight .figure .desc{margin:0;width:100%;-webkit-transform:translateX(20px);transform:translateX(20px);opacity:0;color:inherit}.zoomOutRight .figure .title{text-transform:uppercase;margin-bottom:5px}.zoomOutRight .figure .desc{font-size:0.8em}.zoomOutRight .figure a{position:absolute;top:0;bottom:0;left:0;right:0;z-index:1}.zoomOutRight .figure:hover{z-index:2}.zoomOutRight .figure:hover .image{right:-50%;-webkit-transform:scale(0.7);transform:scale(0.7);z-index:1}.zoomOutRight .figure:hover .caption .title,.zoomOutRight .figure:hover .caption .desc{-webkit-transform:translateX(0);transform:translateX(0);opacity:1} diff --git a/Bcore/src/main/cpp/Dobby/docs/styles/style.css b/Bcore/src/main/cpp/Dobby/docs/styles/style.css new file mode 100755 index 00000000..bafe8f26 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/docs/styles/style.css @@ -0,0 +1,79 @@ +.image-list { + list-style: none; + display: flex; + flex-flow: row wrap; + margin: auto -15px !important; +} + +.image-list .hoverTarget { + flex: 0 0 33%; + padding: 15px; +} + +.image-list .imageTarget { + transition: .3s linear 0s; + display: block; + height: auto; +} + +.imageTarget { + transition: .3s; +} + +.attachTo { + transition: .3s; + display: block; +} + +.image-on-background { + height: 200px; + background-size: cover; +} + +.grid-margin-x-bottom > .cell { + margin-bottom: 30px; +} + +/* Docsify styles */ +.sidebar-toggle { + top: 0; + bottom: auto; +} + +.sidebar-toggle, body.close .sidebar-toggle span { + background: #42b983; +} + +.sidebar-toggle span { + background: #ffffff; + transition: .3s; +} + +body.close .sidebar-toggle { + transition: none; +} + +body.close .sidebar-toggle span:first-of-type { + transform: translate(0px, 4px) rotateZ(45deg); +} + +body.close .sidebar-toggle span:nth-of-type(2) { + transform: translate(0px, -2px) rotateZ(-45deg); +} + +body.close .sidebar-toggle span:last-of-type { + opacity: 0; + transform: translateY(-8px); +} + +@media screen and (max-width: 768px) { + .hoverTarget { + flex: 1 1 50%; + } +} + +@media screen and (min-width: 769px) { + .sidebar-toggle { + display: none; + } +} diff --git a/Bcore/src/main/cpp/Dobby/example/CMakeLists.txt b/Bcore/src/main/cpp/Dobby/example/CMakeLists.txt new file mode 100644 index 00000000..b1d08db8 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/example/CMakeLists.txt @@ -0,0 +1,21 @@ +if(SYSTEM.Darwin) + add_executable(darwin_example + main.cc + darwin_common_api.cc + ) + + target_link_libraries(darwin_example + DobbyX + ) +endif() + +if(SYSTEM.Android) + add_executable(android_example + main.cc + android_common_api.cc + ) + + target_link_libraries(android_example + blackdex_d + ) +endif() \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/example/android_common_api.cc b/Bcore/src/main/cpp/Dobby/example/android_common_api.cc new file mode 100644 index 00000000..5213f6fe --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/example/android_common_api.cc @@ -0,0 +1,182 @@ + +#include "dobby.h" + +#include "logging/logging.h" + +#include +#include +#include +#include +#include + +#include + +std::map *func_map; + +void common_handler(RegisterContext *ctx, const HookEntryInfo *info) { + auto iter = func_map->find(info->function_address); + if (iter != func_map->end()) { + LOG(1, "func %s:%p invoke", iter->second, iter->first); + } +} + +// clang-format off +const char *func_array[] = { + "__loader_dlopen", + "dlsym", + "dlclose", + + "open", + "write", + "read", + "close", + + "socket", + "connect", + "bind", + "listen", + "accept", + "send", + "recv", + + // art::gc::Heap::PreZygoteFork + "_ZN3art2gc4Heap13PreZygoteForkEv", + + // art::ClassLinker::DefineClass + "_ZN3art11ClassLinker11DefineClassEPNS_6ThreadEPKcmNS_6HandleINS_6mirror11ClassLoaderEEERKNS_7DexFileERKNS_3dex8ClassDefE", + + // art::ClassLinker::ShouldUseInterpreterEntrypoint + "_ZN3art11ClassLinker30ShouldUseInterpreterEntrypointEPNS_9ArtMethodEPKv", + + "_ZN3art11ClassLinkerC2EPNS_11InternTableE", + "_ZN3art11ClassLinkerC2EPNS_11InternTableEb", + "_ZN3art9hiddenapi6detail28ShouldDenyAccessToMemberImplINS_9ArtMethodEEEbPT_NS0_7ApiListENS0_12AccessMethodE", + "_ZN3art9hiddenapi6detail28ShouldDenyAccessToMemberImplINS_8ArtFieldEEEbPT_NS0_7ApiListENS0_12AccessMethodE", + "_ZN3art14OatFileManager24SetOnlyUseSystemOatFilesEbb", + "_ZN3art7Runtime4InitEONS_18RuntimeArgumentMapE", + "_ZN3art2gc4Heap13PreZygoteForkEv", + "_ZN3art6mirror5Class15IsInSamePackageENS_6ObjPtrIS1_EE", + "_ZNK23FileDescriptorWhitelist9IsAllowedERKNSt3__112basic_stringIcNS0_11char_traitsIcEENS0_9allocatorIcEEEE", +}; +// clang-format on + +namespace art { +namespace gc { +namespace Heap { +namespace _11 { +uint8_t PreZygoteFork[] = { + 0x2D, 0xE9, 0xF0, 0x4F, 0xAD, 0xF2, 0x04, 0x4D, 0x07, 0x46, +}; +} +} // namespace Heap +} // namespace gc +} // namespace art + +#if 1 +__attribute__((constructor)) static void ctor() { + void *func = NULL; + log_set_level(0); + + 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) { + LOG(1, "func %s not resolve", func_array[i]); + continue; + } + func_map->insert(std::pair(func, func_array[i])); + DobbyInstrument(func, common_handler); + } + return; + + DobbyInstrument((void *)((addr_t)art::gc::Heap::_11::PreZygoteFork + 1), common_handler); + + pthread_t socket_server; + uint64_t socket_demo_server(void *ctx); + pthread_create(&socket_server, NULL, (void *(*)(void *))socket_demo_server, NULL); + + usleep(1000); + pthread_t socket_client; + uint64_t socket_demo_client(void *ctx); + pthread_create(&socket_client, NULL, (void *(*)(void *))socket_demo_client, NULL); +} + +#include +#include +#include +#define PORT 8080 + +uint64_t socket_demo_server(void *ctx) { + int server_fd, new_socket, valread; + struct sockaddr_in address; + int opt = 1; + int addrlen = sizeof(address); + char buffer[1024] = {0}; + char *hello = "Hello from server"; + + // Creating socket file descriptor + if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { + perror("socket failed"); + exit(EXIT_FAILURE); + } + + // Forcefully attaching socket to the port 8080 + if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR | SO_REUSEPORT, &opt, sizeof(opt))) { + perror("setsockopt"); + exit(EXIT_FAILURE); + } + address.sin_family = AF_INET; + address.sin_addr.s_addr = INADDR_ANY; + address.sin_port = htons(PORT); + + // Forcefully attaching socket to the port 8080 + if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { + perror("bind failed"); + exit(EXIT_FAILURE); + } + if (listen(server_fd, 3) < 0) { + perror("listen"); + exit(EXIT_FAILURE); + } + if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t *)&addrlen)) < 0) { + perror("accept"); + exit(EXIT_FAILURE); + } + valread = recv(new_socket, buffer, 1024, 0); + printf("%s\n", buffer); + send(new_socket, hello, strlen(hello), 0); + printf("Hello message sent\n"); + return 0; +} + +uint64_t socket_demo_client(void *ctx) { + int sock = 0, valread; + struct sockaddr_in serv_addr; + char *hello = "Hello from client"; + char buffer[1024] = {0}; + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + printf("\n Socket creation error \n"); + 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) { + printf("\nInvalid address/ Address not supported \n"); + return -1; + } + + if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { + printf("\nConnection Failed \n"); + return -1; + } + send(sock, hello, strlen(hello), 0); + printf("Hello message sent\n"); + valread = recv(sock, buffer, 1024, 0); + printf("%s\n", buffer); + return 0; +} +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/example/darwin_common_api.cc b/Bcore/src/main/cpp/Dobby/example/darwin_common_api.cc new file mode 100644 index 00000000..eb5f52ae --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/example/darwin_common_api.cc @@ -0,0 +1,164 @@ + +#include "dobby.h" + +#include "logging/logging.h" + +#include +#include +#include +#include +#include + +#include + +std::map *func_map; + +void common_handler(RegisterContext *ctx, const HookEntryInfo *info) { + auto iter = func_map->find(info->function_address); + if (iter != func_map->end()) { + LOG(1, "func %s:%p invoke", iter->second, iter->first); + } +} + +// clang-format off +const char *func_array[] = { + "__loader_dlopen", + "dlsym", + "dlclose", + + "open", + "write", + "read", + "close", + + "socket", + "connect", + "bind", + "listen", + "accept", + "send", + "recv", + +}; +// clang-format on + +typeof(pthread_create) *orig_pthread_create; +int fake_pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) { + LOG(1, "pthread_create: %p", start_routine); + return orig_pthread_create(thread, attr, start_routine, arg); +} + +#if 1 +__attribute__((constructor)) static void ctor() { + void *func = NULL; + log_set_level(1); + + 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) { + LOG(1, "func %s not resolve", func_array[i]); + continue; + } + func_map->insert(std::pair(func, func_array[i])); + } + + for (auto i = func_map->begin(), e = func_map->end(); i != e; i++) { + DobbyInstrument(i->first, common_handler); + } + + DobbyGlobalOffsetTableReplace(NULL, "_pthread_create", (void *)fake_pthread_create, (void **)&orig_pthread_create); + + pthread_t socket_server; + uint64_t socket_demo_server(void *ctx); + pthread_create(&socket_server, NULL, (void *(*)(void *))socket_demo_server, NULL); + + usleep(1000); + pthread_t socket_client; + uint64_t socket_demo_client(void *ctx); + 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 8989 + +uint64_t socket_demo_server(void *ctx) { + int server_fd, new_socket, valread; + struct sockaddr_in address; + int opt = 1; + int addrlen = sizeof(address); + char buffer[1024] = {0}; + char *hello = "Hello from server"; + + // Creating socket file descriptor + if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1) { + perror("socket failed"); + exit(EXIT_FAILURE); + } + + // Forcefully attaching socket to the port 8080 + if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt))) { + perror("setsockopt"); + exit(EXIT_FAILURE); + } + + address.sin_family = AF_INET; + address.sin_addr.s_addr = INADDR_ANY; + address.sin_port = htons(PORT); + + // Forcefully attaching socket to the port 8080 + if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) { + perror("bind failed"); + exit(EXIT_FAILURE); + } + if (listen(server_fd, 3) < 0) { + perror("listen"); + exit(EXIT_FAILURE); + } + if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t *)&addrlen)) < 0) { + perror("accept"); + exit(EXIT_FAILURE); + } + valread = recv(new_socket, buffer, 1024, 0); + printf("%s\n", buffer); + send(new_socket, hello, strlen(hello), 0); + printf("Hello message sent\n"); + return 0; +} + +uint64_t socket_demo_client(void *ctx) { + int sock = 0, valread; + struct sockaddr_in serv_addr; + char *hello = "Hello from client"; + char buffer[1024] = {0}; + if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { + printf("\n Socket creation error \n"); + 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) { + printf("\nInvalid address/ Address not supported \n"); + return -1; + } + + if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) { + printf("\nConnection Failed \n"); + return -1; + } + send(sock, hello, strlen(hello), 0); + printf("Hello message sent\n"); + valread = recv(sock, buffer, 1024, 0); + printf("%s\n", buffer); + return 0; +} +#endif diff --git a/Bcore/src/main/cpp/Dobby/example/main.cc b/Bcore/src/main/cpp/Dobby/example/main.cc new file mode 100644 index 00000000..b50e9950 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/example/main.cc @@ -0,0 +1,9 @@ +#include +#include + +int main(int argc, char const *argv[]) { + + std::cout << "Start..." << std::endl; + + return 0; +} \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/external/logging/CMakeLists.txt b/Bcore/src/main/cpp/Dobby/external/logging/CMakeLists.txt new file mode 100644 index 00000000..db01ceef --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/external/logging/CMakeLists.txt @@ -0,0 +1,11 @@ +include_directories(.) + +set(SOURCE_FILE_LIST + ${CMAKE_CURRENT_SOURCE_DIR}/cxxlogging.cc + ${CMAKE_CURRENT_SOURCE_DIR}/logging.c +) + +add_library(logging STATIC + ${SOURCE_FILE_LIST} + ${SOURCE_HEADER_LIST} +) \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/external/logging/cxxlogging.cc b/Bcore/src/main/cpp/Dobby/external/logging/cxxlogging.cc new file mode 100644 index 00000000..8db8a8f4 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/external/logging/cxxlogging.cc @@ -0,0 +1,23 @@ +#include "logging/cxxlogging.h" + +#include +#include +#include +#include + +void Logger::setLogLevel(LogLevel level) { + log_level_ = level; +} + +void Logger::log(LogLevel level, const char *tag, const char *fmt, ...) { + if (level > log_level_) { + va_list ap; + + va_start(ap, fmt); + vprintf(fmt, ap); + va_end(ap); + } +} + +void Logger::LogFatal(const char *fmt, ...) { +} \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/external/logging/logging.c b/Bcore/src/main/cpp/Dobby/external/logging/logging.c new file mode 100644 index 00000000..b4900610 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/external/logging/logging.c @@ -0,0 +1,106 @@ +#include "logging/logging.h" + +#include +#include // va_start + +#include +#include + +#if defined(_POSIX_VERSION) || defined(__APPLE__) +#include +#include +#endif + +#if defined(_WIN32) +#define PUBLIC +#else +#define PUBLIC __attribute__((visibility("default"))) +#define INTERNAL __attribute__((visibility("internal"))) +#endif + +static int _log_level = 1; + +PUBLIC void log_set_level(int level) { + _log_level = level; +} + +static int _syslog_enabled = 0; + +PUBLIC void log_switch_to_syslog(void) { + _syslog_enabled = 1; +} + +static int _file_log_enabled = 0; +static const char *log_file_path = NULL; +static int log_file_fd = -1; +static FILE * log_file_stream = NULL; + +PUBLIC void log_switch_to_file(const char *path) { + _file_log_enabled = 1; + log_file_path = strdup(path); + +#if 0 + log_file_fd = open(log_file_path, O_WRONLY | O_CREAT | O_APPEND, 0666); +#endif + log_file_stream = fopen(log_file_path, "a+"); +} + +static int check_log_file_available() { + if (log_file_stream) + return 1; + + if (log_file_path) { + log_file_stream = fopen(log_file_path, "a+"); + } + + if (log_file_stream) + return 1; + + return 0; +} + +PUBLIC int log_internal_impl(unsigned int level, const char *fmt, ...) { + if (level < _log_level) + return 0; + + va_list ap; + va_start(ap, fmt); +#pragma clang diagnostic ignored "-Wformat" +#if defined(_POSIX_VERSION) || defined(__APPLE__) + if (_syslog_enabled) { + vsyslog(LOG_ERR, fmt, ap); + } +#endif + if (_file_log_enabled) { + if (check_log_file_available()) { +#define MAX_PRINT_BUFFER_SIZE 1024 + char buffer[MAX_PRINT_BUFFER_SIZE] = {0}; + vsnprintf(buffer, MAX_PRINT_BUFFER_SIZE - 1, fmt, ap); + if (fwrite(buffer, sizeof(char), strlen(buffer) + 1, log_file_stream) == -1) { + // log_file_fd invalid + log_file_stream = NULL; + if (check_log_file_available()) { + // try again + fwrite(buffer, sizeof(char), strlen(buffer) + 1, log_file_stream); + } + } + fflush(log_file_stream); + } else { + vprintf(fmt, ap); + } + } + + if (!_syslog_enabled && !_file_log_enabled) { +#if defined(__ANDROID__) +#define ANDROID_LOG_TAG "Dobby" +#include + __android_log_vprint(ANDROID_LOG_INFO, ANDROID_LOG_TAG, fmt, ap); +#else + vprintf(fmt, ap); +#endif + } + +#pragma clang diagnostic warning "-Wformat" + va_end(ap); + return 0; +} diff --git a/Bcore/src/main/cpp/Dobby/external/logging/logging/check_logging.h b/Bcore/src/main/cpp/Dobby/external/logging/logging/check_logging.h new file mode 100644 index 00000000..d13e947d --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/external/logging/logging/check_logging.h @@ -0,0 +1,87 @@ + +#ifndef CHECK_LOGGING_H_ +#define CHECK_LOGGING_H_ + +#include "logging.h" + +#define CHECK_WITH_MSG(condition, message) \ + do { \ + if (!(condition)) { \ + FATAL("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("%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(" Check failed: %s.\n", #lhs " " #op " " #rhs); \ + } \ + } while (0) + +#define DCHECK_OP(name, op, lhs, rhs) \ + do { \ + if (!((lhs)op(rhs))) { \ + FATAL("%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/Bcore/src/main/cpp/Dobby/external/logging/logging/cxxlogging.h b/Bcore/src/main/cpp/Dobby/external/logging/logging/cxxlogging.h new file mode 100644 index 00000000..1ccea1f1 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/external/logging/logging/cxxlogging.h @@ -0,0 +1,26 @@ +#ifndef CXXLOGGING_H_ +#define CXXLOGGING_H_ + +#include "logging.h" + +typedef enum { + LOG_LEVEL_FATAL = 0, + LOG_LEVEL_ERROR = 1, + LOG_LEVEL_WARNING = 2, + LOG_LEVEL_DEBUG = 3, + LOG_LEVEL_VERBOSE = 4 +} LogLevel; + +class Logger { +public: + void setLogLevel(LogLevel level); + + void log(LogLevel level, const char *tag, const char *fmt, ...); + + void LogFatal(const char *fmt, ...); + +private: + LogLevel log_level_; +}; + +#endif diff --git a/Bcore/src/main/cpp/Dobby/external/logging/logging/logging.h b/Bcore/src/main/cpp/Dobby/external/logging/logging/logging.h new file mode 100644 index 00000000..af7c6945 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/external/logging/logging/logging.h @@ -0,0 +1,89 @@ +#ifndef LOGGING_H +#define LOGGING_H + +#include +#include + +#include // strerror + +#define LOG_TAG NULL + +#if 1 +#ifdef __cplusplus +extern "C" { +#endif + +void log_set_level(int level); + +void log_switch_to_syslog(); + +void log_switch_to_file(const char *path); + +#if !defined(LOG_FUNCTION_IMPL) +#define LOG_FUNCTION_IMPL log_internal_impl +#endif +int log_internal_impl(unsigned int level, const char *, ...); + +#if defined(LOGGING_DISABLE) +#define LOG_FUNCTION_IMPL(...) +#endif + +#ifdef __cplusplus +} +#endif +#else +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef __cplusplus +} +#endif +#endif + +#define LOG(level, fmt, ...) \ + do { \ + if (LOG_TAG) \ + LOG_FUNCTION_IMPL(level, "[*] [%s] " fmt "\n", LOG_TAG, ##__VA_ARGS__); \ + else \ + LOG_FUNCTION_IMPL(level, "[*] " fmt "\n", ##__VA_ARGS__); \ + } while (0) + +#define RAW_LOG(level, fmt, ...) \ + do { \ + LOG_FUNCTION_IMPL(level, fmt, ##__VA_ARGS__); \ + } while (0) + +#define FATAL(fmt, ...) \ + do { \ + RAW_LOG(-1, "[!] [%s:%d:%s]: \n", __FILE__, __LINE__, __func__); \ + RAW_LOG(-1, "[!] " fmt "\n", ##__VA_ARGS__); \ + abort(); \ + } while (0) + +#define ERROR_LOG(fmt, ...) \ + do { \ + RAW_LOG(-1, "[!] [%s:%d:%s]: \n", __FILE__, __LINE__, __func__); \ + RAW_LOG(-1, "[!] " fmt "\n", ##__VA_ARGS__); \ + } while (0) + +#define ERROR_TRACE_LOG() \ + do { \ + RAW_LOG(-1, "[!] %s:%d:%s\n", __FILE__, __LINE__, __func__); \ + } while (0) + +#define INVOKE_TRACE_LOG() \ + do { \ + RAW_LOG(-1, "[%s] %s:%d:%s\n", __TIME__, __FILE_NAME__, __LINE__, __func__); \ + } while (0) + +#if defined(LOGGING_DEBUG) +#define DLOG(level, fmt, ...) LOG(level, fmt, ##__VA_ARGS__) +#else +#define DLOG(level, fmt, ...) +#endif + +#define UNIMPLEMENTED() FATAL("%s\n", "unimplemented code!!!") +#define UNREACHABLE() FATAL("%s\n", "unreachable code!!!") + +#endif diff --git a/Bcore/src/main/cpp/Dobby/external/misc-helper/CMakeLists.txt b/Bcore/src/main/cpp/Dobby/external/misc-helper/CMakeLists.txt new file mode 100644 index 00000000..98365460 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/external/misc-helper/CMakeLists.txt @@ -0,0 +1,14 @@ +include_directories(.) + +set(SOURCE_FILE_LIST + # memory cache database + ${CMAKE_CURRENT_SOURCE_DIR}/variable_cache.c + + # async logger + ${CMAKE_CURRENT_SOURCE_DIR}/async_logger.cc +) + +add_library(misc_helper STATIC + ${SOURCE_FILE_LIST} + ${SOURCE_HEADER_LIST} +) \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/external/misc-helper/async_logger.cc b/Bcore/src/main/cpp/Dobby/external/misc-helper/async_logger.cc new file mode 100644 index 00000000..49b11cb2 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/external/misc-helper/async_logger.cc @@ -0,0 +1,65 @@ +#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/Bcore/src/main/cpp/Dobby/external/misc-helper/misc-helper/async_logger.h b/Bcore/src/main/cpp/Dobby/external/misc-helper/misc-helper/async_logger.h new file mode 100644 index 00000000..03e0d4e1 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/external/misc-helper/misc-helper/async_logger.h @@ -0,0 +1,8 @@ +#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/Bcore/src/main/cpp/Dobby/external/misc-helper/misc-helper/variable_cache.h b/Bcore/src/main/cpp/Dobby/external/misc-helper/misc-helper/variable_cache.h new file mode 100644 index 00000000..ca3a1fa8 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/external/misc-helper/misc-helper/variable_cache.h @@ -0,0 +1,18 @@ +#ifndef VARIABLE_CACHE_H +#define VARIABLE_CACHE_H + +#include +#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/Bcore/src/main/cpp/Dobby/external/misc-helper/variable_cache.c b/Bcore/src/main/cpp/Dobby/external/misc-helper/variable_cache.c new file mode 100644 index 00000000..07b83e7b --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/external/misc-helper/variable_cache.c @@ -0,0 +1,118 @@ +#include "misc-helper/variable_cache.h" + +#include +#include +#include +#include + +#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; +} + +#include + +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/Bcore/src/main/cpp/Dobby/external/xnucxx/CMakeLists.txt b/Bcore/src/main/cpp/Dobby/external/xnucxx/CMakeLists.txt new file mode 100644 index 00000000..e6031df6 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/external/xnucxx/CMakeLists.txt @@ -0,0 +1,19 @@ + +include_directories(.) + +if(KERNELMODE) + add_definitions(-DKERNELMODE) +endif() + +set(xnucxx.SOURCE_FILE_LIST + ${CMAKE_CURRENT_SOURCE_DIR}/LiteMemOpt.cc + ${CMAKE_CURRENT_SOURCE_DIR}/LiteObject.cc + ${CMAKE_CURRENT_SOURCE_DIR}/LiteIterator.cc + ${CMAKE_CURRENT_SOURCE_DIR}/LiteCollection.cc + ${CMAKE_CURRENT_SOURCE_DIR}/LiteMutableBuffer.cc + ${CMAKE_CURRENT_SOURCE_DIR}/LiteMutableArray.cc +) + +add_library(xnucxx STATIC + ${xnucxx.SOURCE_FILE_LIST} +) \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/external/xnucxx/LiteCollection.cc b/Bcore/src/main/cpp/Dobby/external/xnucxx/LiteCollection.cc new file mode 100644 index 00000000..8890d976 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/external/xnucxx/LiteCollection.cc @@ -0,0 +1 @@ +#include "xnucxx/LiteCollection.h" diff --git a/Bcore/src/main/cpp/Dobby/external/xnucxx/LiteIterator.cc b/Bcore/src/main/cpp/Dobby/external/xnucxx/LiteIterator.cc new file mode 100644 index 00000000..2df5b41c --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/external/xnucxx/LiteIterator.cc @@ -0,0 +1,31 @@ +#include "xnucxx/LiteIterator.h" +#include "xnucxx/LiteCollection.h" +#include "xnucxx/LiteMemOpt.h" + +void LiteCollectionIterator::reset() { + collection->initIterator(innerIterator); +} + +bool LiteCollectionIterator::initWithCollection(const LiteCollectionInterface *inCollection) { + int *ndxPtr = (int *)LiteMemOpt::alloc(sizeof(int)); + innerIterator = (void *)ndxPtr; + + inCollection->initIterator(this->innerIterator); + collection = inCollection; + + return true; +} + +LiteObject *LiteCollectionIterator::getNextObject() { + LiteObject *retObj; + collection->getNextObjectForIterator(this->innerIterator, &retObj); + return retObj; +} + +void LiteCollectionIterator::release() { + if (innerIterator) { + LiteMemOpt::free(innerIterator, sizeof(int)); + + innerIterator = NULL; + } +} diff --git a/Bcore/src/main/cpp/Dobby/external/xnucxx/LiteMemOpt.cc b/Bcore/src/main/cpp/Dobby/external/xnucxx/LiteMemOpt.cc new file mode 100644 index 00000000..f3cb5674 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/external/xnucxx/LiteMemOpt.cc @@ -0,0 +1,22 @@ +#include "xnucxx/LiteMemOpt.h" +#include +#include + +#if 1 +void *_memcpy(void *dest, const void *src, int len) { + return memcpy(dest, src, len); +} + +void *_memset(void *dest, int ch, int count) { + return memset(dest, ch, count); +} +#endif + +void *LiteMemOpt::alloc(int size) { + void *result = malloc(size); + return result; +} + +void LiteMemOpt::free(void *address, int size) { + return ::free(address); +} diff --git a/Bcore/src/main/cpp/Dobby/external/xnucxx/LiteMutableArray.cc b/Bcore/src/main/cpp/Dobby/external/xnucxx/LiteMutableArray.cc new file mode 100644 index 00000000..fc5d48cc --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/external/xnucxx/LiteMutableArray.cc @@ -0,0 +1,101 @@ +#include "xnucxx/LiteMutableArray.h" +#include "xnucxx/LiteMemOpt.h" + +LiteMutableArray::LiteMutableArray(int initCapacity) { + unsigned int arraySize = 0; + arraySize = initCapacity * sizeof(LiteObject *); + array = (const LiteObject **)LiteMemOpt::alloc(arraySize); + array_count = 0; + array_capacity = initCapacity; +} + +LiteMutableArray::~LiteMutableArray() { + release(); +} + +LiteObject *LiteMutableArray::getObject(const int index) { + return (LiteObject *)array[index]; +} + +bool LiteMutableArray::pushObject(const LiteObject *object) { + unsigned int newCount = array_count + 1; + if (newCount > array_capacity && newCount > ensureCapacity(newCount)) + return false; + + array[array_count] = object; + array_count++; + return true; +} + +unsigned int LiteMutableArray::getCount() { + return array_count; +} + +unsigned int LiteMutableArray::getCapacity() { + return array_capacity; +} + +unsigned int LiteMutableArray::ensureCapacity(unsigned int newCapacity) { + if (newCapacity <= array_capacity) + return array_capacity; + +#define CAPACITY_STEP 64 + newCapacity = (int)ALIGN(newCapacity + CAPACITY_STEP, CAPACITY_STEP); + + // alloc new buffer + int newSize; + const LiteObject **newArray; + newSize = sizeof(LiteObject *) * newCapacity; + newArray = (const LiteObject **)LiteMemOpt::alloc(newSize); + if (newArray == nullptr) { + return 0; + } + + // clear buffer content + _memset(newArray, 'A', newSize); + + // copy the origin content + int originContentSize = sizeof(LiteObject *) * array_count; + _memcpy(newArray, array, originContentSize); + + // free the origin + int originArraySize = array_capacity * sizeof(LiteObject *); + LiteMemOpt::free(array, originArraySize); + + // update info + this->array = newArray; + this->array_capacity = newCapacity; + + return newCapacity; +} + +// impl iterator delegate +bool LiteMutableArray::initIterator(void *iterator) const { + unsigned int *ndxPtr = (unsigned int *)iterator; + *ndxPtr = 0; + return true; +} + +// impl iterator delegate +bool LiteMutableArray::getNextObjectForIterator(void *iterator, LiteObject **ret) const { + unsigned int *ndxPtr = (unsigned int *)iterator; + unsigned int ndx = (*ndxPtr)++; + + if (ndx < array_count) { + *ret = (LiteObject *)array[ndx]; + return true; + } else { + *ret = nullptr; + return false; + } +} + +void LiteMutableArray::release() { + if (array != NULL) { + unsigned int arraySize = 0; + arraySize = array_capacity * sizeof(LiteObject *); + LiteMemOpt::free(array, arraySize); + + array = NULL; + } +} \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/external/xnucxx/LiteMutableBuffer.cc b/Bcore/src/main/cpp/Dobby/external/xnucxx/LiteMutableBuffer.cc new file mode 100644 index 00000000..5d0246f6 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/external/xnucxx/LiteMutableBuffer.cc @@ -0,0 +1,54 @@ +#include "xnucxx/LiteMutableBuffer.h" +#include "xnucxx/LiteMemOpt.h" + +bool LiteMutableBuffer::initWithCapacity(uint32_t initCapacity) { + if (initCapacity <= 0) + return false; + + this->buffer = (uint8_t *)LiteMemOpt::alloc(initCapacity); + this->buffer_cursor = buffer; + this->buffer_capacity = initCapacity; + return true; +} + +uint32_t LiteMutableBuffer::ensureCapacity(uint32_t newCapacity) { + if (newCapacity <= buffer_capacity) + return buffer_capacity; + + // or use step + newCapacity = newCapacity + (uint32_t)newCapacity / 2; + + // alloc new buffer + uint8_t *newBuffer; + newBuffer = (uint8_t *)LiteMemOpt::alloc(newCapacity); + if (newBuffer == nullptr) { + return 0; + } + + // clear buffer content + _memset(newBuffer, 'A', newCapacity); + + // copy the origin content + uint32_t originContentSize = (uint32_t)(buffer_cursor - buffer); + _memcpy(newBuffer, buffer, originContentSize); + + // free the origin + uint32_t originBufferSize = buffer_capacity; + LiteMemOpt::free(buffer, originBufferSize); + + // update info + this->buffer = newBuffer; + this->buffer_cursor = newBuffer + originContentSize; + this->buffer_capacity = newCapacity; + + return newCapacity; +} + +void LiteMutableBuffer::release() { + if (buffer != NULL) { + uint32_t originBufferSize = buffer_capacity; + LiteMemOpt::free(buffer, originBufferSize); + + buffer = NULL; + } +} \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/external/xnucxx/LiteObject.cc b/Bcore/src/main/cpp/Dobby/external/xnucxx/LiteObject.cc new file mode 100644 index 00000000..f8d9b8fa --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/external/xnucxx/LiteObject.cc @@ -0,0 +1,9 @@ +#include "xnucxx/LiteObject.h" + +void LiteObject::free() { + return; +} + +void LiteObject::release() { + return; +} \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/external/xnucxx/xnucxx/LiteCollection.h b/Bcore/src/main/cpp/Dobby/external/xnucxx/xnucxx/LiteCollection.h new file mode 100644 index 00000000..2c29331b --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/external/xnucxx/xnucxx/LiteCollection.h @@ -0,0 +1,20 @@ +#ifndef LITE_COLLECTION_H +#define LITE_COLLECTION_H + +#include "xnucxx/LiteObject.h" +#include "xnucxx/LiteIterator.h" + +class LiteCollectionInterface : public LiteObject, public LiteIteratorInterface::Delegate { +public: + virtual unsigned int getCount() = 0; + + virtual unsigned int getCapacity() = 0; + + virtual unsigned int ensureCapacity(unsigned int newCapacity) = 0; + + virtual bool initIterator(void *iterator) const = 0; + + virtual bool getNextObjectForIterator(void *iterator, LiteObject **ret) const = 0; +}; + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/external/xnucxx/xnucxx/LiteIterator.h b/Bcore/src/main/cpp/Dobby/external/xnucxx/xnucxx/LiteIterator.h new file mode 100644 index 00000000..60586b99 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/external/xnucxx/xnucxx/LiteIterator.h @@ -0,0 +1,48 @@ +#ifndef LITE_ITERATOR_H +#define LITE_ITERATOR_H + +#include "xnucxx/LiteObject.h" + +class LiteIteratorInterface : public LiteObject { +public: + class Delegate { + public: + virtual bool initIterator(void *iterationContext) const = 0; + + virtual bool getNextObjectForIterator(void *iterationContext, LiteObject **nextObject) const = 0; + }; + +public: + virtual void reset() = 0; + + virtual LiteObject *getNextObject() = 0; +}; + +class LiteCollectionInterface; +class LiteCollectionIterator : public LiteIteratorInterface { +protected: + const LiteCollectionInterface *collection; + + void *innerIterator; + +public: + explicit LiteCollectionIterator(const LiteCollectionInterface *collection) { + initWithCollection(collection); + } + + ~LiteCollectionIterator() { + release(); + } + + // === LiteObject override === + void release() override; + + // === LiteIteratorInterface override === + void reset() override; + + LiteObject *getNextObject() override; + + bool initWithCollection(const LiteCollectionInterface *collection); +}; + +#endif diff --git a/Bcore/src/main/cpp/Dobby/external/xnucxx/xnucxx/LiteMemOpt.h b/Bcore/src/main/cpp/Dobby/external/xnucxx/xnucxx/LiteMemOpt.h new file mode 100644 index 00000000..7e3eddc1 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/external/xnucxx/xnucxx/LiteMemOpt.h @@ -0,0 +1,17 @@ +#ifndef LITE_MEM_OPT_H +#define LITE_MEM_OPT_H + +extern void *_memcpy(void *, const void *, int); + +extern void _bzero(void *, int); + +extern void *_memset(void *, int, int); + +class LiteMemOpt { +public: + static void *alloc(int size); + + static void free(void *address, int size); +}; + +#endif diff --git a/Bcore/src/main/cpp/Dobby/external/xnucxx/xnucxx/LiteMutableArray.h b/Bcore/src/main/cpp/Dobby/external/xnucxx/xnucxx/LiteMutableArray.h new file mode 100644 index 00000000..82ced375 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/external/xnucxx/xnucxx/LiteMutableArray.h @@ -0,0 +1,40 @@ +#ifndef LITE_MUTABLE_ARRAY_H +#define LITE_MUTABLE_ARRAY_H + +#include "xnucxx/LiteCollection.h" +#include "xnucxx/LiteIterator.h" + +class LiteMutableArray : public LiteCollectionInterface { +protected: + const LiteObject **array; + + unsigned int array_count; + + unsigned int array_capacity; + +public: + explicit LiteMutableArray(int count); + + ~LiteMutableArray(); + + // === LiteObject override == + void release() override; + + // === LiteCollectionInterface override == + unsigned int getCount() override; + + unsigned int getCapacity() override; + + unsigned int ensureCapacity(unsigned int newCapacity) override; + + // === LiteIteratorInterface::Delegate override == + bool initIterator(void *iterator) const override; + + bool getNextObjectForIterator(void *iterator, LiteObject **ret) const override; + + virtual LiteObject *getObject(int index); + + virtual bool pushObject(const LiteObject *object); +}; + +#endif diff --git a/Bcore/src/main/cpp/Dobby/external/xnucxx/xnucxx/LiteMutableBuffer.h b/Bcore/src/main/cpp/Dobby/external/xnucxx/xnucxx/LiteMutableBuffer.h new file mode 100644 index 00000000..8afb6a42 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/external/xnucxx/xnucxx/LiteMutableBuffer.h @@ -0,0 +1,51 @@ +#ifndef LITE_MUTABLE_BUFFER_H +#define LITE_MUTABLE_BUFFER_H + +#include "xnucxx/LiteObject.h" + +class LiteMutableBuffer : public LiteObject { +protected: + uint8_t *buffer; + + uint8_t *buffer_cursor; + + uint32_t buffer_capacity; + +public: + LiteMutableBuffer() { + initWithCapacity(8); + } + + LiteMutableBuffer(uint32_t size) { + initWithCapacity(size); + } + + ~LiteMutableBuffer() { + release(); + } + + // === LiteObject override == + void release() override; + + virtual bool initWithCapacity(uint32_t initCapacity); + + virtual uint32_t ensureCapacity(uint32_t newCapacity); + + virtual inline uint32_t getSize() { + return (uint32_t)(buffer_cursor - buffer); + } + + virtual inline uint32_t getCapacity() { + return buffer_capacity; + } + + virtual inline void *getCursor() { + return buffer_cursor; + } + + virtual inline void *getRawBuffer() { + return buffer; + } +}; + +#endif diff --git a/Bcore/src/main/cpp/Dobby/external/xnucxx/xnucxx/LiteObject.h b/Bcore/src/main/cpp/Dobby/external/xnucxx/xnucxx/LiteObject.h new file mode 100644 index 00000000..a4c0f208 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/external/xnucxx/xnucxx/LiteObject.h @@ -0,0 +1,13 @@ +#ifndef LITE_OBJECT_H +#define LITE_OBJECT_H + +#include "common_header.h" + +class LiteObject { +public: + virtual void free(); + + virtual void release(); +}; + +#endif diff --git a/Bcore/src/main/cpp/Dobby/include/dobby.h b/Bcore/src/main/cpp/Dobby/include/dobby.h new file mode 100644 index 00000000..384707c8 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/include/dobby.h @@ -0,0 +1,186 @@ +#ifndef dobby_h +#define dobby_h + +// obfuscated interface +#if 0 +#define DobbyBuildVersion c343f74888dffad84d9ad08d9c433456 +#define DobbyHook c8dc3ffa44f22dbd10ccae213dd8b1f8 +#define DobbyInstrument b71e27bca2c362de90c1034f19d839f9 +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +typedef enum { + kMemoryOperationSuccess, + kMemoryOperationError, + kNotSupportAllocateExecutableMemory, + kNotEnough, + kNone +} MemoryOperationError; + +#define PLATFORM_INTERFACE_CODE_PATCH_TOOL_H +MemoryOperationError CodePatch(void *address, uint8_t *buffer, uint32_t buffer_size); + +typedef uintptr_t addr_t; +typedef uint32_t addr32_t; +typedef uint64_t addr64_t; + +#if defined(__arm64__) || defined(__aarch64__) + +#define ARM64_TMP_REG_NDX_0 17 + +// float register +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 _RegisterContext { + 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; +} RegisterContext; +#elif defined(__arm__) +typedef struct _RegisterContext { + 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; +} RegisterContext; +#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; + +} RegisterContext; +#elif defined(_M_X64) || defined(__x86_64__) +typedef struct _RegisterContext { + 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; +} RegisterContext; +#endif + +#define RT_FAILED -1 +#define RT_SUCCESS 0 +typedef enum _RetStatus { RS_FAILED = -1, RS_SUCCESS = 0 } RetStatus; + +typedef struct _HookEntryInfo { + int hook_id; + union { + void *target_address; + void *function_address; + void *instruction_address; + }; +} HookEntryInfo; + +// DobbyWrap <==> DobbyInstrument, so use DobbyInstrument instead of DobbyWrap +#if 0 +// wrap function with pre_call and post_call +typedef void (*PreCallTy)(RegisterContext *ctx, const HookEntryInfo *info); +typedef void (*PostCallTy)(RegisterContext *ctx, const HookEntryInfo *info); +int DobbyWrap(void *function_address, PreCallTy pre_call, PostCallTy post_call); +#endif + +// return dobby build date +const char *DobbyBuildVersion(); + +// replace function +int DobbyHook(void *address, void *replace_call, void **origin_call); + +// dynamic binary instrument for instruction +// [!!! READ ME !!!] +// for Arm64, can't access q8 - q31, unless you enable full floating-point register pack +typedef void (*DBICallTy)(RegisterContext *ctx, const HookEntryInfo *info); +int DobbyInstrument(void *address, DBICallTy dbi_call); + +// destory and restore hook +int DobbyDestroy(void *address); + +// iterate symbol table and find symbol +void *DobbySymbolResolver(const char *image_name, const char *symbol_name); + +// global offset table +int DobbyGlobalOffsetTableReplace(char *image_name, char *symbol_name, void *fake_func, void **orig_func); + +// [!!! READ ME !!!] +// for arm, Arm64, dobby will use b xxx instead of ldr absolute indirect branch +// for x64, dobby always use absolute indirect jump +#if defined(__arm__) || defined(__arm64__) || defined(__aarch64__) || defined(_M_X64) || defined(__x86_64__) +void dobby_enable_near_branch_trampoline(); +void dobby_disable_near_branch_trampoline(); +#endif + +// register linker load image callback +typedef void (*linker_load_callback_t)(const char *image_name, void *handle); +void dobby_register_image_load_callback(linker_load_callback_t func); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/InstructionRelocation.h b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/InstructionRelocation.h new file mode 100644 index 00000000..69f5cb6e --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/InstructionRelocation.h @@ -0,0 +1,3 @@ +#include "dobby_internal.h" + +void GenRelocateCodeAndBranch(void *buffer, AssemblyCodeChunk *origin, AssemblyCodeChunk *relocated); diff --git a/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/arm/ARMInstructionRelocation.cc b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/arm/ARMInstructionRelocation.cc new file mode 100644 index 00000000..c0ceb833 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/arm/ARMInstructionRelocation.cc @@ -0,0 +1,870 @@ +#include "platform_macro.h" +#if defined(TARGET_ARCH_ARM) + +#include "InstructionRelocation/arm/ARMInstructionRelocation.h" + +#include "dobby_internal.h" + +#include "core/arch/arm/registers-arm.h" +#include "core/modules/assembler/assembler-arm.h" +#include "core/modules/codegen/codegen-arm.h" + +using namespace zz; +using namespace zz::arm; + +typedef struct ReloMapEntry { + addr32_t orig_instr; + addr32_t relocated_instr; + int relocated_code_len; +} ReloMapEntry; + +static bool is_thumb2(uint32_t instr) { + uint16_t inst1, inst2; + inst1 = instr & 0x0000ffff; + inst2 = (instr & 0xffff0000) >> 16; + // refer: Top level T32 instruction set encoding + uint32_t op0 = bits(inst1, 13, 15); + uint32_t op1 = bits(inst1, 11, 12); + + if (op0 == 0b111 && op1 != 0b00) { + return true; + } + return false; +} + +static void ARMRelocateSingleInstr(TurboAssembler *turbo_assembler, int32_t instr, addr32_t from_pc, addr32_t to_pc, + addr32_t *execute_state_changed_pc_ptr) { + bool is_instr_relocated = false; +#define _ turbo_assembler-> + // top level encoding + uint32_t cond, op0, op1; + cond = bits(instr, 28, 31); + op0 = bits(instr, 25, 27); + op1 = bit(instr, 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(instr, 24); + U = bit(instr, 23); + W = bit(instr, 21); + imm12 = bits(instr, 0, 11); + Rn = bits(instr, 16, 19); + Rt = bits(instr, 12, 15); + o1 = bit(instr, 20); + o2 = bit(instr, 22); + uint32_t P_W = (P << 1) | W; + do { + // LDR (literal) + 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 target_address = 0; + if (U == 0b1) + target_address = from_pc + imm12; + else + target_address = from_pc - imm12; + Register regRt = Register::R(Rt); + + RelocLabelEntry *pseudoDataLabel = new RelocLabelEntry(target_address); + _ AppendRelocLabelEntry(pseudoDataLabel); + + // === + if (regRt.code() == pc.code()) { + _ Ldr(VOLATILE_REGISTER, pseudoDataLabel); + _ ldr(regRt, MemOperand(VOLATILE_REGISTER)); + } else { + _ Ldr(regRt, pseudoDataLabel); + _ ldr(regRt, MemOperand(regRt)); + } + // === + is_instr_relocated = true; + } while (0); + } + + // Data-processing and miscellaneous instructions + if (cond != 0b1111 && (op0 & 0b110) == 0b000) { + uint32_t op0, op1, op2, op3, op4; + op0 = bit(instr, 25); + // Data-processing immediate + if (op0 == 1) { + uint32_t op0, op1; + op0 = bits(instr, 23, 24); + op1 = bits(instr, 20, 21); + // Integer Data Processing (two register and immediate) + if ((op0 & 0b10) == 0b00) { + uint32_t opc, S, Rn; + opc = bits(instr, 21, 23); + S = bit(instr, 20); + Rn = bits(instr, 16, 19); + do { + uint32_t target_address; + int Rd = bits(instr, 12, 15); + int imm12 = bits(instr, 0, 11); + int label = imm12; + if (opc == 0b010 && S == 0b0 && Rn == 0b1111) { + // ADR - A2 variant + // add = FALSE + target_address = from_pc - imm12; + } else if (opc == 0b100 && S == 0b0 && Rn == 0b1111) { + // ADR - A1 variant + // add = TRUE + target_address = from_pc + imm12; + } else + break; + + Register regRd = Register::R(Rd); + RelocLabelEntry *pseudoDataLabel = new RelocLabelEntry(target_address); + _ AppendRelocLabelEntry(pseudoDataLabel); + // === + _ Ldr(regRd, pseudoDataLabel); + // === + is_instr_relocated = true; + } while (0); + + // EXample + if (opc == 0b111 && S == 0b1 && Rn == 0b1111) { + // do something + } + } + } + } + + // Branch, branch with link, and block data transfer + if ((op0 & 0b110) == 0b100) { + uint32_t cond, op0; + cond = bits(instr, 28, 31); + op0 = bit(instr, 25); + // Branch (immediate) + if (op0 == 1) { + uint32_t cond = 0, H = 0, imm24 = 0; + bool flag_link; + do { + int imm24 = bits(instr, 0, 23); + int label = imm24 << 2; + uint32_t target_address = from_pc + label; + if (cond != 0b1111 && H == 0) { + // B + flag_link = false; + } else if (cond != 0b1111 && H == 1) { + // BL, BLX (immediate) - A1 variant + flag_link = true; + } else if (cond == 0b1111) { + // BL, BLX (immediate) - A2 variant + flag_link = true; + } else + break; + + // === + // just modify orin instruction label bits, and keep the link and cond bits, the next instruction `b_imm` will + // do the rest work. + label = 0x4; + imm24 = label >> 2; + _ EmitARMInst((instr & 0xff000000) | imm24); + if (flag_link) { + _ bl(0); + _ b(4); + } else { + _ b(4); + } + _ ldr(pc, MemOperand(pc, -4)); + _ EmitAddress(target_address); + is_instr_relocated = true; + } while (0); + } + } + + // if the instr do not needed relocate, just rewrite the origin + if (!is_instr_relocated) { + _ EmitARMInst(instr); + } +} + +// relocate thumb-1 instructions +static void Thumb1RelocateSingleInstr(ThumbTurboAssembler *turbo_assembler, LiteMutableArray *thumb_labels, + int16_t instr, addr32_t from_pc, addr32_t to_pc, + addr32_t *execute_state_changed_pc_ptr) { + bool is_instr_relocated = false; + + _ AlignThumbNop(); + + uint32_t val = 0, 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(instr, 10, 15); + // [F3.2.3 Special data instructions and branch and exchange] + if (op0 == 0b010001) { + op0 = bits(instr, 8, 9); + // [Add, subtract, compare, move (two high registers)] + if (op0 != 0b11) { + int rs = bits(instr, 3, 6); + // rs is PC register + if (rs == 15) { + val = from_pc; + + uint16_t rewrite_inst = 0; + rewrite_inst = (instr & 0xff87) | LeftShift((VOLATILE_REGISTER.code()), 4, 3); + + ThumbRelocLabelEntry *label = new ThumbRelocLabelEntry(val, false); + _ AppendRelocLabelEntry(label); + + _ T2_Ldr(VOLATILE_REGISTER, label); + _ EmitInt16(rewrite_inst); + + is_instr_relocated = true; + } + } + + // Branch and exchange + if (op0 == 0b11) { + int32_t L = bit(instr, 7); + // BX + if (L == 0b0) { + rm = bits(instr, 3, 6); + if (rm == pc.code()) { + val = from_pc; + ThumbRelocLabelEntry *label = new ThumbRelocLabelEntry(val, true); + _ AppendRelocLabelEntry(label); + + _ T2_Ldr(pc, label); + + *execute_state_changed_pc_ptr = val; + is_instr_relocated = true; + } + } + // BLX + if (L == 0b1) { + if (rm == pc.code()) { + val = from_pc; + ThumbRelocLabelEntry *label = new ThumbRelocLabelEntry(val, true); + _ AppendRelocLabelEntry(label); + + int label_branch_off = 4, label_continue_off = 4; + _ t2_bl(label_branch_off); + _ t2_b(label_continue_off); + /* Label: branch */ + _ T2_Ldr(pc, label); + /* Label: continue */ + + *execute_state_changed_pc_ptr = val; + is_instr_relocated = true; + } + } + } + } + + // ldr literal + if ((instr & 0xf800) == 0x4800) { + int32_t imm8 = bits(instr, 0, 7); + int32_t offset = imm8 << 2; + val = from_pc + offset; + val = ALIGN_FLOOR(val, 4); + rt = bits(instr, 8, 10); + + ThumbRelocLabelEntry *label = new ThumbRelocLabelEntry(val, false); + _ AppendRelocLabelEntry(label); + + _ T2_Ldr(Register::R(rt), label); + _ t2_ldr(Register::R(rt), MemOperand(Register::R(rt), 0)); + + is_instr_relocated = true; + } + + // adr + if ((instr & 0xf800) == 0xa000) { + rd = bits(instr, 8, 10); + uint16_t imm8 = bits(instr, 0, 7); + val = from_pc + imm8; + + ThumbRelocLabelEntry *label = new ThumbRelocLabelEntry(val, false); + _ AppendRelocLabelEntry(label); + + _ T2_Ldr(Register::R(rd), label); + + if (pc.code() == rd) + val += 1; + is_instr_relocated = true; + } + + // b + if ((instr & 0xf000) == 0xd000) { + uint16_t cond = bits(instr, 8, 11); + // cond != 111x + if (cond >= 0b1110) { + UNREACHABLE(); + } + uint16_t imm8 = bits(instr, 0, 7); + uint32_t offset = imm8 << 1; + val = from_pc + offset; + + ThumbRelocLabelEntry *label = new ThumbRelocLabelEntry(val + 1, true); + _ AppendRelocLabelEntry(label); + + // modify imm8 field + imm8 = 0x4 >> 1; + + _ EmitInt16((instr & 0xfff0) | imm8); + _ t1_nop(); // manual align + _ t2_b(4); + _ T2_Ldr(pc, label); + + is_instr_relocated = true; + } + + // compare branch (cbz, cbnz) + if ((instr & 0xf500) == 0xb100) { + uint16_t imm5 = bits(instr, 3, 7); + uint16_t i = bit(instr, 9); + uint32_t offset = (i << 6) | (imm5 << 1); + val = from_pc + offset; + rn = bits(instr, 0, 2); + + ThumbRelocLabelEntry *label = new ThumbRelocLabelEntry(val + 1, true); + _ AppendRelocLabelEntry(label); + + imm5 = bits(0x4 >> 1, 1, 5); + i = bit(0x4 >> 1, 6); + + _ EmitInt16((instr & 0xfd07) | imm5 << 3 | i << 9); + _ t1_nop(); // manual align + _ t2_b(0); + _ T2_Ldr(pc, label); + + is_instr_relocated = true; + } + + // unconditional branch + if ((instr & 0xf800) == 0xe000) { + uint16_t imm11 = bits(instr, 0, 10); + uint32_t offset = imm11 << 1; + val = from_pc + offset; + + ThumbRelocLabelEntry *label = new ThumbRelocLabelEntry(val + 1, true); + _ AppendRelocLabelEntry(label); + + _ T2_Ldr(pc, label); + + is_instr_relocated = true; + } + + // if the instr do not needed relocate, just rewrite the origin + if (!is_instr_relocated) { +#if 0 + if (from_pc % Thumb2_INST_LEN) + _ t1_nop(); +#endif + _ EmitInt16(instr); + } +} + +static void Thumb2RelocateSingleInstr(ThumbTurboAssembler *turbo_assembler, LiteMutableArray *thumb_labels, + thumb1_inst_t inst1, thumb1_inst_t inst2, addr32_t from_pc, addr32_t to_pc) { + + bool is_instr_relocated = false; + + // if (turbo_assembler->pc_offset() % 4) { + // _ t1_nop(); + // } + + _ AlignThumbNop(); + + // Branches and miscellaneous control + if ((inst1 & 0xf800) == 0xf000 && (inst2 & 0x8000) == 0x8000) { + uint32_t op1 = 0, op3 = 0; + op1 = bits(inst1, 6, 9); + op3 = bits(inst2, 12, 14); + + // B-T3 AKA b.cond + if (((op1 & 0b1110) != 0b1110) && ((op3 & 0b101) == 0b000)) { + + int S = sbits(inst1, 10, 10); + int J1 = bit(inst2, 13); + int J2 = bit(inst2, 11); + int imm6 = bits(inst1, 0, 5); + int imm11 = bits(inst2, 0, 10); + + int32_t label = (S << 20) | (J2 << 19) | (J1 << 18) | (imm6 << 12) | (imm11 << 1); + addr32_t val = from_pc + label; + + // === + imm11 = 0x4 >> 1; + _ EmitInt16(inst1 & 0xffc0); // clear imm6 + _ EmitInt16((inst2 & 0xd000) | imm11); // 1. clear J1, J2, origin_imm12 2. set new imm11 + + _ t2_b(4); + _ t2_ldr(pc, MemOperand(pc, 0)); + _ EmitAddress(val + THUMB_ADDRESS_FLAG); + // === + is_instr_relocated = true; + } + + // B-T4 AKA b.w + if ((op3 & 0b101) == 0b001) { + int S = bit(inst1, 10); + int J1 = bit(inst2, 13); + int J2 = bit(inst2, 11); + int imm10 = bits(inst1, 0, 9); + int imm11 = bits(inst2, 0, 10); + int i1 = !(J1 ^ S); + int i2 = !(J2 ^ S); + + int32_t label = (-S << 24) | (i1 << 23) | (i2 << 22) | (imm10 << 12) | (imm11 << 1); + addr32_t val = from_pc + label; + + _ t2_ldr(pc, MemOperand(pc, 0)); + _ EmitAddress(val + THUMB_ADDRESS_FLAG); + // === + is_instr_relocated = true; + } + + // BL, BLX (immediate) - T1 variant AKA bl + if ((op3 & 0b101) == 0b101) { + int S = bit(inst1, 10); + int J1 = bit(inst2, 13); + int J2 = bit(inst2, 11); + int i1 = !(J1 ^ S); + int i2 = !(J2 ^ S); + int imm11 = bits(inst2, 0, 10); + int imm10 = bits(inst1, 0, 9); + // S is sign-bit, '-S' maybe not better + int32_t label = (imm11 << 1) | (imm10 << 12) | (i2 << 22) | (i1 << 23) | (-S << 24); + addr32_t val = from_pc + label; + + _ t2_bl(4); + _ t2_b(8); + _ t2_ldr(pc, MemOperand(pc, 0)); + _ EmitAddress(val + THUMB_ADDRESS_FLAG); + // ===== + is_instr_relocated = true; + } + + // BL, BLX (immediate) - T2 variant AKA blx + if ((op3 & 0b101) == 0b100) { + int S = bit(inst1, 10); + int J1 = bit(inst2, 13); + int J2 = bit(inst2, 11); + int i1 = !(J1 ^ S); + int i2 = !(J2 ^ S); + int imm10h = bits(inst1, 0, 9); + int imm10l = bits(inst2, 1, 10); + // S is sign-bit, '-S' maybe not better + int32_t label = (imm10l << 2) | (imm10h << 12) | (i2 << 22) | (i1 << 23) | (-S << 24); + addr32_t val = ALIGN(from_pc, 4) + label; + + _ t2_bl(4); + _ t2_b(8); + _ t2_ldr(pc, MemOperand(pc, 0)); + _ EmitAddress(val); + // ===== + is_instr_relocated = true; + } + } + + // Data-processing (plain binary immediate) + if ((inst1 & (0xfa10)) == 0xf200 & (inst2 & 0x8000) == 0) { + uint32_t op0 = 0, op1 = 0; + op0 = bit(inst1, 8); + op1 = bits(inst2, 5, 6); + + // Data-processing (simple immediate) + if (op0 == 0 && (op1 & 0b10) == 0b00) { + int o1 = bit(inst1, 7); + int o2 = bit(inst1, 5); + int rn = bits(inst1, 0, 3); + + // ADR + if (((o1 == 0 && o2 == 0) || (o1 == 1 && o2 == 1)) && rn == 0b1111) { + uint32_t i = bit(inst1, 10); + uint32_t imm3 = bits(inst2, 12, 14); + uint32_t imm8 = bits(inst2, 0, 7); + uint32_t rd = bits(inst2, 8, 11); + uint32_t label = imm8 | (imm3 << 8) | (i << 11); + addr32_t val = 0; + + if (o1 == 0 && o2 == 0) { // ADR - T3 + // ADR - T3 variant + // adr with add + val = from_pc + label; + } else if (o1 == 1 && o2 == 1) { // ADR - T2 + // ADR - T2 variant + // adr with sub + val = from_pc - label; + } else { + UNREACHABLE(); + } + + // === + _ t2_ldr(Register::R(rd), MemOperand(pc, 4)); + _ t2_b(0); + _ EmitAddress(val); + // === + is_instr_relocated = true; + } + } + } + + // LDR literal (T2) + if ((inst1 & 0xff7f) == 0xf85f) { + uint32_t U = bit(inst1, 7); + uint32_t imm12 = bits(inst2, 0, 11); + uint16_t rt = bits(inst2, 12, 15); + + uint32_t label = imm12; + addr32_t val = 0; + if (U == 1) { + val = from_pc + label; + } else { + val = from_pc - label; + } + + val = ALIGN_FLOOR(val, 4); + + Register regRt = Register::R(rt); + // ===== + _ t2_ldr(regRt, MemOperand(pc, 4)); + _ t2_b(4); + _ EmitAddress(val); + _ t2_ldr(regRt, MemOperand(regRt, 0)); + // ===== + is_instr_relocated = true; + } + + // if the instr do not needed relocate, just rewrite the origin + if (!is_instr_relocated) { +#if 0 + if (from_pc % Thumb2_INST_LEN) + _ t1_nop(); +#endif + _ EmitInt16(inst1); + _ EmitInt16(inst2); + } +} + +void gen_arm_relocate_code(LiteMutableArray *relo_map, TurboAssembler *turbo_assembler_, void *buffer, + AssemblyCodeChunk *origin, AssemblyCodeChunk *relocated, + addr32_t *execute_state_changed_pc_ptr) { +#undef _ +#define _ turbo_assembler_-> + addr32_t curr_orig_pc = origin->raw_instruction_start() + ARM_PC_OFFSET; + addr32_t curr_relo_pc = relocated->raw_instruction_start() + ARM_PC_OFFSET + turbo_assembler_->pc_offset(); + + addr_t buffer_cursor = (addr_t)buffer; + arm_inst_t instr = *(arm_inst_t *)buffer_cursor; + + int predefined_relocate_size = origin->raw_instruction_size(); + + addr32_t execute_state_changed_pc = 0; + + while (buffer_cursor < ((addr_t)buffer + predefined_relocate_size)) { + int last_relo_offset = turbo_assembler_->GetCodeBuffer()->getSize(); + + ARMRelocateSingleInstr(turbo_assembler_, instr, curr_orig_pc, curr_relo_pc, execute_state_changed_pc_ptr); + DLOG(0, "[arm] Relocate arm instr: 0x%x", instr); + + { + // 1 orignal instrution => ? relocated instruction + int relo_offset = turbo_assembler_->GetCodeBuffer()->getSize(); + int relo_len = relo_offset - last_relo_offset; + + ReloMapEntry *map = new ReloMapEntry{.orig_instr = curr_orig_pc - ARM_PC_OFFSET, + .relocated_instr = curr_relo_pc - ARM_PC_OFFSET, + .relocated_code_len = relo_len}; + relo_map->pushObject(reinterpret_cast(map)); + } + + curr_relo_pc = relocated->raw_instruction_start() + ARM_PC_OFFSET + turbo_assembler_->pc_offset(); + + // Move to next instruction + curr_orig_pc += ARM_INST_LEN; + buffer_cursor += ARM_INST_LEN; + + // execute state changed + addr32_t next_instr_addr = curr_orig_pc - ARM_PC_OFFSET; + if (execute_state_changed_pc != 0 && next_instr_addr == execute_state_changed_pc) { + break; + } + + instr = *(arm_inst_t *)buffer_cursor; + } + + // update origin + int new_origin_len = curr_orig_pc - origin->raw_instruction_start() - ARM_PC_OFFSET; + origin->re_init_region_range(origin->raw_instruction_start(), new_origin_len); + + bool is_relocate_interrupted = buffer_cursor < ((addr_t)buffer + predefined_relocate_size); + if (is_relocate_interrupted) { + *execute_state_changed_pc_ptr = execute_state_changed_pc; + } +} + +void gen_thumb_relocate_code(LiteMutableArray *relo_map, ThumbTurboAssembler *turbo_assembler_, void *buffer, + AssemblyCodeChunk *origin, AssemblyCodeChunk *relocated, + addr32_t *execute_state_changed_pc_ptr) { + LiteMutableArray thumb_labels(8); +#define _ turbo_assembler_-> + + addr32_t curr_orig_pc = origin->raw_instruction_start() + Thumb_PC_OFFSET; + addr32_t curr_relo_pc = relocated->raw_instruction_start() + Thumb_PC_OFFSET; + + addr_t buffer_cursor = (addr_t)buffer; + thumb2_inst_t instr = *(thumb2_inst_t *)buffer_cursor; + + int predefined_relocate_size = origin->raw_instruction_size(); + DLOG(0, "[arm] Thumb relocate %d start >>>>>", predefined_relocate_size); + + addr32_t execute_state_changed_pc = 0; + + while (buffer_cursor < ((addr_t)buffer + predefined_relocate_size)) { + // align nop + _ t1_nop(); + + int last_relo_offset = turbo_assembler_->GetCodeBuffer()->getSize(); + if (is_thumb2(instr)) { + Thumb2RelocateSingleInstr(turbo_assembler_, &thumb_labels, (uint16_t)instr, (uint16_t)(instr >> 16), curr_orig_pc, + curr_relo_pc); + + DLOG(0, "[arm] Relocate thumb2 instr: 0x%x", instr); + } else { + Thumb1RelocateSingleInstr(turbo_assembler_, &thumb_labels, (uint16_t)instr, curr_orig_pc, curr_relo_pc, + &execute_state_changed_pc); + + DLOG(0, "[arm] Relocate thumb1 instr: 0x%x", (uint16_t)instr); + } + + { + // 1 orignal instrution => ? relocated instruction + int relo_offset = turbo_assembler_->GetCodeBuffer()->getSize(); + int relo_len = relo_offset - last_relo_offset; + + ReloMapEntry *map = new ReloMapEntry{.orig_instr = curr_orig_pc - Thumb_PC_OFFSET, + .relocated_instr = curr_relo_pc - Thumb_PC_OFFSET, + .relocated_code_len = relo_len}; + relo_map->pushObject(reinterpret_cast(map)); + } + + curr_relo_pc = relocated->raw_instruction_start() + Thumb_PC_OFFSET + turbo_assembler_->pc_offset(); + + // Move to next instruction + if (is_thumb2(instr)) { + curr_orig_pc += Thumb2_INST_LEN; + buffer_cursor += Thumb2_INST_LEN; + } else { + curr_orig_pc += Thumb1_INST_LEN; + buffer_cursor += Thumb1_INST_LEN; + } + + // execute state changed + addr32_t next_instr_addr = curr_orig_pc - Thumb_PC_OFFSET; + if (execute_state_changed_pc != 0 && next_instr_addr == execute_state_changed_pc) { + break; + } + + instr = *(thumb2_inst_t *)buffer_cursor; + } + + // update origin + int new_origin_len = curr_orig_pc - origin->raw_instruction_start() - Thumb_PC_OFFSET; + origin->re_init_region_range(origin->raw_instruction_start(), new_origin_len); + + /* + .thumb1 bx pc + .thumb1 mov r8, r8 + .arm ldr pc, [pc, #-4] + */ + + bool is_relocate_interrupted = buffer_cursor < ((addr_t)buffer + predefined_relocate_size); + if (is_relocate_interrupted) { + *execute_state_changed_pc_ptr = execute_state_changed_pc; + turbo_assembler_->SetExecuteState(ARMExecuteState); + } +} + +static addr32_t get_orig_instr_relocated_addr(LiteMutableArray *relo_map, addr32_t orig_pc) { + for (size_t i = 0; i < relo_map->getCount(); i++) { + ReloMapEntry *relo_entry = (ReloMapEntry *)relo_map->getObject(i); + if (relo_entry->orig_instr == orig_pc) { + return relo_entry->relocated_instr; + } + } + return 0; +} + +static void reloc_label_fixup(AssemblyCodeChunk *origin, LiteMutableArray *relo_map, + ThumbTurboAssembler *thumb_turbo_assembler, TurboAssembler *arm_turbo_assembler) { + addr32_t origin_instr_start = origin->raw_instruction_start(); + addr32_t origin_instr_end = origin_instr_start + origin->raw_instruction_size(); + + LiteMutableArray *labels = NULL; + labels = thumb_turbo_assembler->GetLabels(); + if (labels) { + for (size_t i = 0; i < labels->getCount(); i++) { + ThumbRelocLabelEntry *label = (ThumbRelocLabelEntry *)labels->getObject(i); + if (label->used_for_branch() == false) + continue; + addr32_t val = label->data(); + + if (val >= origin_instr_start && val < origin_instr_end) { + DLOG(0, "[reloc label fixup warning] found thumb instr branch / access in origin code range"); + addr32_t fixup_val = get_orig_instr_relocated_addr(relo_map, val); + fixup_val += (addr_t)thumb_turbo_assembler->GetRealizedAddress(); + label->fixup_data(fixup_val); + thumb_turbo_assembler->RelocBindFixup(label); + } + } + } + + labels = arm_turbo_assembler->GetLabels(); + if (labels) { + for (size_t i = 0; i < labels->getCount(); i++) { + RelocLabelEntry *label = (RelocLabelEntry *)labels->getObject(i); + addr32_t val = label->data(); + + if (val >= origin_instr_start && val < origin_instr_end) { + DLOG(0, "[reloc label fixup warning]found thumb instr branch / access in origin code range"); + addr32_t fixup_val = get_orig_instr_relocated_addr(relo_map, val); + fixup_val += (addr_t)arm_turbo_assembler->GetRealizedAddress(); + label->fixup_data(fixup_val); + arm_turbo_assembler->RelocBindFixup(label); + } + } + } +} + +void GenRelocateCodeAndBranch(void *buffer, AssemblyCodeChunk *origin, AssemblyCodeChunk *relocated) { + CodeBuffer *code_buffer = new CodeBuffer(64); + + ThumbTurboAssembler thumb_turbo_assembler_(0, code_buffer); +#define thumb_ thumb_turbo_assembler_. + TurboAssembler arm_turbo_assembler_(0, code_buffer); +#define arm_ arm_turbo_assembler_. + + Assembler *curr_assembler_ = NULL; + + AssemblyCodeChunk origin_chunk; + origin_chunk.init_region_range(origin->raw_instruction_start(), origin->raw_instruction_size()); + + bool entry_is_thumb = origin->raw_instruction_start() % 2; + if (entry_is_thumb) { + origin->re_init_region_range(origin->raw_instruction_start() - THUMB_ADDRESS_FLAG, origin->raw_instruction_size()); + } + + LiteMutableArray relo_map(8); + +relocate_remain: + addr32_t execute_state_changed_pc = 0; + + bool is_thumb = origin_chunk.raw_instruction_start() % 2; + if (is_thumb) { + curr_assembler_ = &thumb_turbo_assembler_; + + buffer = (void *)((addr_t)buffer - THUMB_ADDRESS_FLAG); + + addr32_t origin_code_start_aligned = origin_chunk.raw_instruction_start() - THUMB_ADDRESS_FLAG; + // remove thumb address flag + origin_chunk.re_init_region_range(origin_code_start_aligned, origin_chunk.raw_instruction_size()); + + gen_thumb_relocate_code(&relo_map, &thumb_turbo_assembler_, buffer, &origin_chunk, relocated, + &execute_state_changed_pc); + if (thumb_turbo_assembler_.GetExecuteState() == ARMExecuteState) { + // relocate interrupt as execute state changed + if (execute_state_changed_pc < origin_chunk.raw_instruction_start() + origin_chunk.raw_instruction_size()) { + // re-init the origin + int relocate_remain_size = + origin_chunk.raw_instruction_start() + origin_chunk.raw_instruction_size() - execute_state_changed_pc; + // current execute state is ARMExecuteState, so not need `+ THUMB_ADDRESS_FLAG` + origin_chunk.re_init_region_range(execute_state_changed_pc, relocate_remain_size); + + // update buffer + buffer = (void *)((addr_t)buffer + (execute_state_changed_pc - origin_code_start_aligned)); + + // add nop to align ARM + if (thumb_turbo_assembler_.pc_offset() % 4) + thumb_turbo_assembler_.t1_nop(); + goto relocate_remain; + } + } + } else { + curr_assembler_ = &arm_turbo_assembler_; + + gen_arm_relocate_code(&relo_map, &arm_turbo_assembler_, buffer, &origin_chunk, relocated, + &execute_state_changed_pc); + if (arm_turbo_assembler_.GetExecuteState() == ThumbExecuteState) { + // relocate interrupt as execute state changed + if (execute_state_changed_pc < origin_chunk.raw_instruction_start() + origin_chunk.raw_instruction_size()) { + // re-init the origin + int relocate_remain_size = + origin_chunk.raw_instruction_start() + origin_chunk.raw_instruction_size() - execute_state_changed_pc; + // current execute state is ThumbExecuteState, add THUMB_ADDRESS_FLAG + origin_chunk.re_init_region_range(execute_state_changed_pc + THUMB_ADDRESS_FLAG, relocate_remain_size); + + // update buffer + buffer = (void *)((addr_t)buffer + (execute_state_changed_pc - origin_chunk.raw_instruction_start())); + goto relocate_remain; + } + } + } + + // TODO: + // if last instr is unlink branch, skip + addr32_t rest_instr_addr = origin_chunk.raw_instruction_start() + origin_chunk.raw_instruction_size(); + if (curr_assembler_ == &thumb_turbo_assembler_) { + // Branch to the rest of instructions + thumb_ AlignThumbNop(); + thumb_ t2_ldr(pc, MemOperand(pc, 0)); + // Get the real branch address + thumb_ EmitAddress(rest_instr_addr + THUMB_ADDRESS_FLAG); + } else { + // Branch to the rest of instructions + CodeGen codegen(&arm_turbo_assembler_); + // Get the real branch address + codegen.LiteralLdrBranch(rest_instr_addr); + } + + // Realize all the Pseudo-Label-Data + thumb_turbo_assembler_.RelocBind(); + + // Realize all the Pseudo-Label-Data + arm_turbo_assembler_.RelocBind(); + + // Generate executable code + { + // assembler without specific memory address + AssemblyCodeChunk *cchunk; + cchunk = MemoryArena::AllocateCodeChunk(code_buffer->getSize()); + if (cchunk == nullptr) + return; + + thumb_turbo_assembler_.SetRealizedAddress(cchunk->address); + arm_turbo_assembler_.SetRealizedAddress(cchunk->address); + + // fixup the instr branch into trampoline(has been modified) + reloc_label_fixup(origin, &relo_map, &thumb_turbo_assembler_, &arm_turbo_assembler_); + + AssemblyCodeChunk *code = NULL; + code = AssemblyCodeBuilder::FinalizeFromTurboAssembler(curr_assembler_); + relocated->re_init_region_range(code->raw_instruction_start(), code->raw_instruction_size()); + delete code; + } + + // thumb + if (entry_is_thumb) { + // add thumb address flag + relocated->re_init_region_range(relocated->raw_instruction_start() + THUMB_ADDRESS_FLAG, + relocated->raw_instruction_size()); + } + + // clean + { + thumb_turbo_assembler_.ClearCodeBuffer(); + arm_turbo_assembler_.ClearCodeBuffer(); + + delete code_buffer; + } +} + +#endif diff --git a/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/arm/ARMInstructionRelocation.h b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/arm/ARMInstructionRelocation.h new file mode 100644 index 00000000..1573adf1 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/arm/ARMInstructionRelocation.h @@ -0,0 +1,360 @@ +#ifndef INSTRUCTION_RELOCATION_ARM_H +#define INSTRUCTION_RELOCATION_ARM_H + +#include "dobby_internal.h" + +#include "core/arch/arm/constants-arm.h" +#include "core/modules/assembler/assembler-arm.h" + +namespace zz { +namespace arm { + +// custom thumb pseudo label for thumb/thumb2 +class ThumbPseudoLabel : public PseudoLabel { +public: + // thumb1/thumb2 pseudo label type, only support Thumb1-Ldr | Thumb2-Ldr + enum CustomThumbPseudoLabelType { kThumb1Ldr, kThumb2LiteralLdr }; + + // fix the instruction which not link to the label yet. + void link_confused_instructions(CodeBuffer *buffer = nullptr) { + CodeBuffer *_buffer; + if (buffer) + _buffer = buffer; + + for (size_t i = 0; i < instructions_.getCount(); i++) { + PseudoLabelInstruction *instruction = (PseudoLabelInstruction *)instructions_.getObject(i); + + // instruction offset to label + const thumb2_inst_t instr = _buffer->LoadThumb2Inst(instruction->position_); + const thumb1_inst_t inst1 = _buffer->LoadThumb1Inst(instruction->position_); + const thumb1_inst_t inst2 = _buffer->LoadThumb1Inst(instruction->position_ + sizeof(thumb1_inst_t)); + + switch (instruction->type_) { + case kThumb1Ldr: { + UNREACHABLE(); + } break; + case kThumb2LiteralLdr: { + int32_t offset = pos() - ALIGN(instruction->position_, 4) - Thumb_PC_OFFSET; + uint32_t imm12 = offset; + CHECK(imm12 < (1 << 12)); + uint16_t encoding = inst2 & 0xf000; + encoding = encoding | imm12; + _buffer->RewriteThumb1Inst(instruction->position_, inst1 | B7); // add = (U == '1'); + _buffer->RewriteThumb1Inst(instruction->position_ + Thumb1_INST_LEN, encoding); + + DLOG(0, "[thumb label link] insn offset %d link offset %d", instruction->position_, offset); + } break; + default: + UNREACHABLE(); + break; + } + } + +#if 0 + for (auto instruction : instructions_) { + // instruction offset to label + int32_t offset = pos() - instruction.position_ - Thumb_PC_OFFSET; + const int32_t instr = _buffer->Load(instruction.position_); + const int16_t inst1 = _buffer->Load(instruction.position_); + const int16_t inst2 = _buffer->Load(instruction.position_ + sizeof(int16_t)); + + switch (instruction.type_) { + case kThumb1Ldr: { + UNREACHABLE(); + } break; + case kThumb2LiteralLdr: { + uint32_t imm12 = offset; + CHECK(imm12 < (1 << 12)); + uint16_t encoding = inst2 & 0xf000; + encoding = encoding | imm12; + _buffer->Store(instruction.position_, inst1 | B7); // add = (U == '1'); + _buffer->Store(instruction.position_ + Thumb1_INST_LEN, encoding); + } break; + default: + UNREACHABLE(); + break; + } + } +#endif + } +}; + +class ThumbRelocLabelEntry : public ThumbPseudoLabel { +public: + explicit ThumbRelocLabelEntry(uint32_t data, bool used_for_branch) + : data_size_(0), used_for_branch_(used_for_branch) { + data_ = data; + } + + uint32_t data() { + return data_; + } + + void fixup_data(uint32_t data) { + data_ = data; + } + + bool used_for_branch() { + return used_for_branch_; + } + +private: + uint32_t data_; + + int data_size_; + + bool used_for_branch_; +}; + +// ================================================================ +// ThumbAssembler + +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)); + } + } +}; + +// ================================================================ +// ThumbTurboAssembler + +class ThumbTurboAssembler : public ThumbAssembler { +public: + ThumbTurboAssembler(void *address) : ThumbAssembler(address) { + data_labels_ = NULL; + } + + ThumbTurboAssembler(void *address, CodeBuffer *buffer) : ThumbAssembler(address, buffer) { + data_labels_ = NULL; + } + + ~ThumbTurboAssembler() { + if (data_labels_) { + for (size_t i = 0; i < data_labels_->getCount(); i++) { + RelocLabelEntry *label = (RelocLabelEntry *)data_labels_->getObject(i); + delete label; + } + + delete data_labels_; + } + } + + 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->is_bound()) { + int offset = label->pos() - buffer_->getSize(); + t2_ldr(rt, MemOperand(pc, offset)); + } else { + // record this ldr, and fix later. + label->link_to(buffer_->getSize(), ThumbPseudoLabel::kThumb2LiteralLdr); + t2_ldr(rt, MemOperand(pc, 0)); + } + } + + void AlignThumbNop() { + addr32_t pc = this->GetCodeBuffer()->getSize() + (addr32_t)GetRealizedAddress(); + if (pc % Thumb2_INST_LEN) { + t1_nop(); + } else { + } + } + + // ================================================================ + // ThumbRelocLabelEntry + + void ThumbPseudoBind(ThumbPseudoLabel *label) { + if (label->is_unused() == true) { + const addr32_t bound_pc = buffer_->getSize(); + 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(this->GetCodeBuffer()); + } + } + + void RelocBindFixup(ThumbRelocLabelEntry *label) { + buffer_->RewriteAddr(label->pos(), label->data()); + } + + void RelocBind() { + if (data_labels_ == NULL) + return; + for (size_t i = 0; i < data_labels_->getCount(); i++) { + ThumbRelocLabelEntry *label = (ThumbRelocLabelEntry *)data_labels_->getObject(i); + ThumbPseudoBind(label); + EmitAddress(label->data()); + DLOG(0, "[thumb label data] %p", label->data()); + } + } + + void AppendRelocLabelEntry(ThumbRelocLabelEntry *label) { + if (data_labels_ == NULL) { + data_labels_ = new LiteMutableArray(8); + } + data_labels_->pushObject((LiteObject *)label); + } + + LiteMutableArray *GetLabels() { + return data_labels_; + } + +private: + LiteMutableArray *data_labels_; +}; + +#if 0 +void GenRelocateCodeAndBranch(void *buffer, AssemblyCodeChunk *origin, AssemblyCodeChunk *relocated); +#endif + +} // namespace arm +} // namespace zz + +#endif diff --git a/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/arm64/ARM64InstructionRelocation.cc b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/arm64/ARM64InstructionRelocation.cc new file mode 100644 index 00000000..f116b7bf --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/arm64/ARM64InstructionRelocation.cc @@ -0,0 +1,318 @@ +#include "platform_macro.h" +#if defined(TARGET_ARCH_ARM64) + +#include "InstructionRelocation/arm64/ARM64InstructionRelocation.h" + +#include "dobby_internal.h" + +#include "core/arch/arm64/registers-arm64.h" +#include "core/modules/assembler/assembler-arm64.h" +#include "core/modules/codegen/codegen-arm64.h" + +using namespace zz::arm64; + +// 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, + TBZ = TestBranchFixed | 0x00000000, + TBNZ = TestBranchFixed | 0x01000000 +}; + +static inline int64_t SignExtend(unsigned long x, int M, int N) { +#if 0 + char sign_bit = bit(x, M - 1); + unsigned long sign_mask = 0 - sign_bit; + x |= ((sign_mask >> M) << M); +#else + x = (long)(x << (N - M)) >> (N - M); +#endif + return x; +} + +#if 0 +static inline unsigned long set_bit(obj, st, unsigned long bit) { + return (((~(1 << st)) & obj) | (bit << st)); +} +static inline unsigned long set_bits(obj, st, fn, unsigned long bits) { + return (((~(submask(fn - st) << st)) & obj) | (bits << st)); +} +#endif + +static inline int64_t decode_imm14_offset(uint32_t instr) { + int64_t offset; + { + int64_t imm19 = bits(instr, 5, 18); + offset = (imm19 << 2); + } + offset = SignExtend(offset, 2 + 14, 64); + return offset; +} + +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 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 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 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 int decode_rt(uint32_t instr) { + return bits(instr, 0, 4); +} + +static inline int decode_rd(uint32_t instr) { + return bits(instr, 0, 4); +} + +#if defined(DOBBY_DEBUG) +#define debug_nop() _ nop() +#else +#define debug_nop() +#endif + +void GenRelocateCodeAndBranch(void *buffer, AssemblyCodeChunk *origin, AssemblyCodeChunk *relocated) { + TurboAssembler turbo_assembler_(0); +#define _ turbo_assembler_. + + uint64_t curr_orig_pc = origin->raw_instruction_start(); + uint64_t curr_relo_pc = relocated->raw_instruction_start(); + + addr_t buffer_cursor = (addr_t)buffer; + arm64_inst_t instr = *(arm64_inst_t *)buffer_cursor; + + int predefined_relocate_size = origin->raw_instruction_size(); + + while (buffer_cursor < ((addr_t)buffer + predefined_relocate_size)) { + int last_relo_offset = turbo_assembler_.GetCodeBuffer()->getSize(); + + if ((instr & LoadRegLiteralFixedMask) == LoadRegLiteralFixed) { // ldr x0, #16 + int rt = decode_rt(instr); + char opc = bits(instr, 30, 31); + addr64_t memory_address = decode_imm19_offset(instr) + curr_orig_pc; + +#define MEM(reg, offset) MemOperand(reg, offset) + debug_nop(); // for debug + { + _ Mov(TMP_REG_0, memory_address); // should we replace with `Ldr` to set X17 ? + if (opc == 0b00) + _ ldr(W(rt), MEM(TMP_REG_0, 0)); + else if (opc == 0b01) + _ ldr(X(rt), MEM(TMP_REG_0, 0)); + else { + UNIMPLEMENTED(); + } + } + debug_nop(); + } else if ((instr & PCRelAddressingFixedMask) == PCRelAddressingFixed) { + int rd = decode_rd(instr); + + int64_t imm = 0; + addr64_t runtime_address = 0; + if ((instr & PCRelAddressingMask) == ADR) { + imm = decode_immhi_immlo_offset(instr); + runtime_address = curr_orig_pc + imm; + } else { + imm = decode_immhi_immlo_zero12_offset(instr); + runtime_address = ALIGN_FLOOR(curr_orig_pc, (1 << 12)) + imm; + } + + /* output Mov */ + debug_nop(); + { + _ Mov(X(rd), runtime_address); // should we replace with `Ldr` to set X17 ? + } + debug_nop(); + + } else if ((instr & UnconditionalBranchFixedMask) == UnconditionalBranchFixed) { // b xxx + addr_t branch_address = decode_imm26_offset(instr) + curr_orig_pc; + RelocLabelEntry *branchAddressLabel = new RelocLabelEntry(branch_address); + _ AppendRelocLabelEntry(branchAddressLabel); + + debug_nop(); + { + _ Ldr(TMP_REG_0, branchAddressLabel); // should we replace with `Mov` to set X17 ? + if ((instr & UnconditionalBranchMask) == BL) { + _ blr(TMP_REG_0); + } else { + _ br(TMP_REG_0); + } + } + debug_nop(); + } else if ((instr & TestBranchFixedMask) == TestBranchFixed) { // tbz, tbnz + addr64_t branch_address = decode_imm14_offset(instr) + curr_orig_pc; + RelocLabelEntry *branchAddressLabel = new RelocLabelEntry(branch_address); + _ AppendRelocLabelEntry(branchAddressLabel); + + arm64_inst_t branch_instr = instr; + + char op = bit(instr, 24); + op = op ^ 1; + set_bit(branch_instr, 24, op); + + int64_t offset = 4 * 3; // branch_instr; ldr x17, #label; br x17 + uint32_t imm14 = offset >> 2; + set_bits(branch_instr, 5, 18, imm14); + + debug_nop(); + { + _ Emit(branch_instr); + { + _ Ldr(TMP_REG_0, branchAddressLabel); // should we replace with `Mov` to set X17 ? + _ br(TMP_REG_0); + } + } + debug_nop(); + + } else if ((instr & CompareBranchFixedMask) == CompareBranchFixed) { // cbz cbnz + addr64_t branch_address = decode_imm19_offset(instr) + curr_orig_pc; + + arm64_inst_t branch_instr = instr; + + char op = bit(instr, 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); + + RelocLabelEntry *branchAddressLabel = new RelocLabelEntry(branch_address); + _ AppendRelocLabelEntry(branchAddressLabel); + + debug_nop(); + { + _ Emit(branch_instr); + { + _ Ldr(TMP_REG_0, branchAddressLabel); // should we replace with `Mov` to set X17 ? + _ br(TMP_REG_0); + } + } + debug_nop(); + } else if ((instr & ConditionalBranchFixedMask) == ConditionalBranchFixed) { // b.cond + addr64_t branch_address = decode_imm19_offset(instr) + curr_orig_pc; + + arm64_inst_t branch_instr = instr; + + char cond = bits(instr, 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); + + RelocLabelEntry *branchAddressLabel = new RelocLabelEntry(branch_address); + _ AppendRelocLabelEntry(branchAddressLabel); + + debug_nop(); + { + _ Emit(branch_instr); + { + _ Ldr(TMP_REG_0, branchAddressLabel); // should we replace with `Mov` to set X17 ? + _ br(TMP_REG_0); + } + } + debug_nop(); + } else { + // origin write the instruction bytes + _ Emit(instr); + } + + // Move to next instruction + curr_orig_pc += 4; + buffer_cursor += 4; + +#if 0 + { + // 1 orignal instrution => ? relocated instruction + int relo_offset = turbo_assembler_.GetCodeBuffer()->getSize(); + int relo_len = relo_offset - last_relo_offset; + curr_relo_pc += relo_len; + } +#endif + + curr_relo_pc = relocated->raw_instruction_start() + turbo_assembler_.pc_offset(); + + instr = *(arm64_inst_t *)buffer_cursor; + } + +#if 0 + // check branch in relocate-code range + { + for (size_t i = 0; i < data_labels->getCount(); i++) { + RelocLabelEntry *pseudoLabel = (RelocLabelEntry *)data_labels->getObject(i); + if (pseudoLabel->address == curr_orig_pc) { + FATAL("label(%p) in relo code %p, please enable b-xxx branch plugin.", pseudoLabel->address, curr_orig_pc); + } + } + } +#endif + + // TODO: if last instr is unlink branch, skip + // Branch to the rest of instructions + CodeGen codegen(&turbo_assembler_); + codegen.LiteralLdrBranch(curr_orig_pc); + + _ RelocBind(); + + // Generate executable code + { + AssemblyCodeChunk *code = NULL; + code = AssemblyCodeBuilder::FinalizeFromTurboAssembler(&turbo_assembler_); + relocated->re_init_region_range(code->raw_instruction_start(), code->raw_instruction_size()); + delete code; + } +} + +#endif diff --git a/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/arm64/ARM64InstructionRelocation.h b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/arm64/ARM64InstructionRelocation.h new file mode 100644 index 00000000..93396631 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/arm64/ARM64InstructionRelocation.h @@ -0,0 +1,16 @@ +#ifndef INSTRUCTION_RELOCATION_ARM64_H +#define INSTRUCTION_RELOCATION_ARM64_H + +#include "dobby_internal.h" + +#include "core/arch/arm64/constants-arm64.h" + +#if 0 +namespace zz { +namespace arm64 { +void GenRelocateCodeAndBranch(void *buffer, AssemblyCodeChunk *origin, AssemblyCodeChunk *relocated); +} // namespace arm64 +} // namespace zz +#endif + +#endif diff --git a/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/arm64/ARM64PCLiteralInstructionTable.h b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/arm64/ARM64PCLiteralInstructionTable.h new file mode 100644 index 00000000..6d974321 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/arm64/ARM64PCLiteralInstructionTable.h @@ -0,0 +1,8 @@ +// +// Created by jmpews on 2019/1/26. +// + +#ifndef ARM64_PC_LITERAL_INSTRUCTION_TABLE_H +#define ARM64_PC_LITERAL_INSTRUCTION_TABLE_H + +#endif diff --git a/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x64/X64InstructionRelocation.cc b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x64/X64InstructionRelocation.cc new file mode 100644 index 00000000..fd5543b0 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x64/X64InstructionRelocation.cc @@ -0,0 +1,162 @@ +#include "platform_macro.h" +#if defined(TARGET_ARCH_X64) + +#include "InstructionRelocation/x64/X64InstructionRelocation.h" + +#include + +#include "dobby_internal.h" + +#include "InstructionRelocation/x86/x86_insn_decode/x86_insn_decode.h" + +#include "core/arch/x64/registers-x64.h" +#include "core/modules/assembler/assembler-x64.h" +#include "core/modules/codegen/codegen-x64.h" + +using namespace zz::x64; + +static int GenRelocateCodeFixed(void *buffer, AssemblyCodeChunk *origin, AssemblyCodeChunk *relocated) { + TurboAssembler turbo_assembler_(0); + // Set fixed executable code chunk address + turbo_assembler_.SetRealizedAddress((void *)relocated->raw_instruction_start()); +#define _ turbo_assembler_. +#define __ turbo_assembler_.GetCodeBuffer()-> + + addr64_t curr_orig_ip = origin->raw_instruction_start(); + addr64_t curr_relo_ip = relocated->raw_instruction_start(); + + addr_t buffer_cursor = (addr_t)buffer; + + x86_options_t conf = {0}; + conf.mode = 64; + + int predefined_relocate_size = origin->raw_instruction_size(); + + while ((buffer_cursor < ((addr_t)buffer + predefined_relocate_size))) { + int last_relo_offset = turbo_assembler_.GetCodeBuffer()->getSize(); + + x86_insn_decode_t insn = {0}; + memset(&insn, 0, sizeof(insn)); + // decode x86 insn + x86_insn_decode(&insn, (uint8_t *)buffer_cursor, &conf); + + if (insn.primary_opcode >= 0x70 && insn.primary_opcode <= 0x7F) { // jc rel8 + DLOG(0, "[x86 relo] jc rel8, %p", buffer_cursor); + + int8_t orig_offset = insn.immediate; + int new_offset = (int)(curr_orig_ip + orig_offset - curr_relo_ip); + uint8_t opcode = 0x80 | (insn.primary_opcode & 0x0f); + + __ Emit8(0x0F); + __ Emit8(opcode); + __ Emit32(new_offset); + } else if (insn.primary_opcode == 0xEB) { // jmp rel8 + DLOG(0, "[x86 relo] jmp rel8, %p", buffer_cursor); + + int8_t orig_offset = insn.immediate; + int8_t new_offset = (int8_t)(curr_orig_ip + orig_offset - curr_relo_ip); + + __ Emit8(0xE9); + __ Emit32(new_offset); + } else if ((insn.flags & X86_INSN_DECODE_FLAG_IP_RELATIVE) && (insn.operands[1].mem.base == RIP)) { // RIP + DLOG(0, "[x86 relo] rip, %p", buffer_cursor); + + // dword orig_disp = *(dword *)(buffer_cursor + insn.operands[1].mem.disp); + dword orig_disp = insn.operands[1].mem.disp; + dword new_disp = (dword)(curr_orig_ip + orig_disp - curr_relo_ip); + + __ EmitBuffer((void *)buffer_cursor, insn.displacement_offset); + __ Emit32(new_disp); + if (insn.immediate_offset) { + __ EmitBuffer((void *)(buffer_cursor + insn.immediate_offset), insn.length - insn.immediate_offset); + } + } else if (insn.primary_opcode == 0xE8 || insn.primary_opcode == 0xE9) { // call or jmp rel32 + DLOG(0, "[x86 relo] jmp or call rel32, %p", buffer_cursor); + + dword orig_offset = insn.immediate; + dword offset = (dword)(curr_orig_ip + orig_offset - curr_relo_ip); + + __ EmitBuffer((void *)buffer_cursor, insn.immediate_offset); + __ Emit32(offset); + } 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 { + // Emit the origin instrution + __ EmitBuffer((void *)buffer_cursor, insn.length); + } + + // go next + curr_orig_ip += insn.length; + buffer_cursor += insn.length; + +#if 0 + { + // 1 orignal instrution => ? relocated instruction + int relo_offset = turbo_assembler_.GetCodeBuffer()->getSize(); + int relo_len = relo_offset - last_relo_offset; + curr_relo_ip += relo_len; + } +#endif + curr_relo_ip = relocated->raw_instruction_start() + turbo_assembler_.ip_offset(); + } + + // jmp to the origin rest instructions + 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 - origin->raw_instruction_start(); + origin->re_init_region_range(origin->raw_instruction_start(), new_origin_len); + + int relo_len = turbo_assembler_.GetCodeBuffer()->getSize(); + if (relo_len > relocated->raw_instruction_size()) { + DLOG(0, "pre-alloc code chunk not enough"); + return RT_FAILED; + } + + // Generate executable code + { + AssemblyCodeChunk *code = NULL; + code = AssemblyCodeBuilder::FinalizeFromTurboAssembler(&turbo_assembler_); + delete code; + } + + return RT_SUCCESS; +} + +void GenRelocateCodeAndBranch(void *buffer, AssemblyCodeChunk *origin, AssemblyCodeChunk *relocated) { + // pre-alloc code chunk + AssemblyCodeChunk *cchunk = NULL; + + int relo_code_chunk_size = 32; + const int chunk_size_step = 16; + +x64_try_again: + if (relocated->raw_instruction_start() == 0) { + cchunk = MemoryArena::AllocateCodeChunk(relo_code_chunk_size); + if (cchunk == nullptr) { + return; + } + relocated->re_init_region_range((addr_t)cchunk->address, (int)cchunk->length); + } + + int ret = GenRelocateCodeFixed(buffer, origin, relocated); + if (ret != RT_SUCCESS) { + // free the cchunk + MemoryArena::Destroy(cchunk); + + relo_code_chunk_size += chunk_size_step; + relocated->re_init_region_range(0, 0); + + goto x64_try_again; + } +} + +#endif diff --git a/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x64/X64InstructionRelocation.h b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x64/X64InstructionRelocation.h new file mode 100644 index 00000000..ceff7777 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x64/X64InstructionRelocation.h @@ -0,0 +1,10 @@ +#ifndef INSTRUCTION_RELOCATION_X64_H +#define INSTRUCTION_RELOCATION_X64_H + +#include "common_header.h" + +#include "core/arch/x64/constants-x64.h" + +#include "MemoryAllocator/AssemblyCodeBuilder.h" + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/X86InstructionRelocation.cc b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/X86InstructionRelocation.cc new file mode 100644 index 00000000..eb0a2081 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/X86InstructionRelocation.cc @@ -0,0 +1,148 @@ +#include "platform_macro.h" +#if defined(TARGET_ARCH_IA32) + +#include "InstructionRelocation/x86//X86InstructionRelocation.h" + +#include + +#include "dobby_internal.h" + +#include "InstructionRelocation/x86/x86_insn_decode/x86_insn_decode.h" + +#include "core/arch/x86/registers-x86.h" +#include "core/modules/assembler/assembler-ia32.h" +#include "core/modules/codegen/codegen-ia32.h" + +using namespace zz::x86; + +static int GenRelocateCodeFixed(void *buffer, AssemblyCodeChunk *origin, AssemblyCodeChunk *relocated) { + TurboAssembler turbo_assembler_(0); + // Set fixed executable code chunk address + turbo_assembler_.SetRealizedAddress((void *)relocated->raw_instruction_start()); +#define _ turbo_assembler_. +#define __ turbo_assembler_.GetCodeBuffer()-> + + addr64_t curr_orig_ip = origin->raw_instruction_start(); + addr64_t curr_relo_ip = relocated->raw_instruction_start(); + + addr_t buffer_cursor = (addr_t)buffer; + + x86_options_t conf = {0}; + conf.mode = 32; + + int predefined_relocate_size = origin->raw_instruction_size(); + + while ((buffer_cursor < ((addr_t)buffer + predefined_relocate_size))) { + int last_relo_offset = turbo_assembler_.GetCodeBuffer()->getSize(); + + x86_insn_decode_t insn = {0}; + memset(&insn, 0, sizeof(insn)); + // decode x86 insn + x86_insn_decode(&insn, (uint8_t *)buffer_cursor, &conf); + + if (insn.primary_opcode >= 0x70 && insn.primary_opcode <= 0x7F) { // jc rel8 + DLOG(0, "[x86 relo] jc rel8, %p", buffer_cursor); + + int8_t orig_offset = insn.immediate; + int new_offset = (int)(curr_orig_ip + orig_offset - curr_relo_ip); + uint8_t opcode = 0x80 | (insn.primary_opcode & 0x0f); + + __ Emit8(0x0F); + __ Emit8(opcode); + __ Emit32(new_offset); + } else if (insn.primary_opcode == 0xEB) { // jmp rel8 + DLOG(0, "[x86 relo] jmp rel8, %p", buffer_cursor); + + int8_t orig_offset = insn.immediate; + int8_t new_offset = (int8_t)(curr_orig_ip + orig_offset - curr_relo_ip); + + __ Emit8(0xE9); + __ Emit32(new_offset); + } else if (insn.primary_opcode == 0xE8 || insn.primary_opcode == 0xE9) { // call or jmp rel32 + DLOG(0, "[x86 relo] jmp or call rel32, %p", buffer_cursor); + + dword orig_offset = insn.immediate; + dword offset = (dword)(curr_orig_ip + orig_offset - curr_relo_ip); + + __ EmitBuffer((void *)buffer_cursor, insn.immediate_offset); + __ Emit32(offset); + } 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 { + // Emit the origin instrution + __ EmitBuffer((void *)buffer_cursor, insn.length); + } + + // go next + curr_orig_ip += insn.length; + buffer_cursor += insn.length; + +#if 0 + { + // 1 orignal instrution => ? relocated instruction + int relo_offset = turbo_assembler_.GetCodeBuffer()->getSize(); + int relo_len = relo_offset - last_relo_offset; + curr_relo_ip += relo_len; + } +#endif + curr_relo_ip = relocated->raw_instruction_start() + turbo_assembler_.ip_offset(); + } + + // jmp to the origin rest instructions + CodeGen codegen(&turbo_assembler_); + addr64_t stub_addr = curr_relo_ip + 6; + codegen.JmpNear(curr_orig_ip); + + // update origin + int new_origin_len = curr_orig_ip - origin->raw_instruction_start(); + origin->re_init_region_range(origin->raw_instruction_start(), new_origin_len); + + int relo_len = turbo_assembler_.GetCodeBuffer()->getSize(); + if (relo_len > relocated->raw_instruction_size()) { + DLOG(0, "pre-alloc code chunk not enough"); + return RT_FAILED; + } + + // Generate executable code + { + AssemblyCodeChunk *code = NULL; + code = AssemblyCodeBuilder::FinalizeFromTurboAssembler(&turbo_assembler_); + delete code; + } + + return RT_SUCCESS; +} + +void GenRelocateCodeAndBranch(void *buffer, AssemblyCodeChunk *origin, AssemblyCodeChunk *relocated) { + // pre-alloc code chunk + AssemblyCodeChunk *cchunk = NULL; + + int relo_code_chunk_size = 32; + const int chunk_size_step = 16; + +x86_try_again: + if (relocated->raw_instruction_start() == 0) { + cchunk = MemoryArena::AllocateCodeChunk(relo_code_chunk_size); + if (cchunk == nullptr) { + return; + } + relocated->re_init_region_range((addr_t)cchunk->address, (int)cchunk->length); + } + + int ret = GenRelocateCodeFixed(buffer, origin, relocated); + if (ret != RT_SUCCESS) { + // free the cchunk + MemoryArena::Destroy(cchunk); + + relo_code_chunk_size += chunk_size_step; + relocated->re_init_region_range(0, 0); + + goto x86_try_again; + } +} + +#endif diff --git a/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/X86InstructionRelocation.h b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/X86InstructionRelocation.h new file mode 100644 index 00000000..9dea6628 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/X86InstructionRelocation.h @@ -0,0 +1,10 @@ +#ifndef INSTRUCTION_RELOCATION_X64_H +#define INSTRUCTION_RELOCATION_X64_H + +#include "common_header.h" + +#include "core/arch/x86/constants-x86.h" + +#include "MemoryAllocator/AssemblyCodeBuilder.h" + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/deprecated/Ia32Disassembler.cc b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/deprecated/Ia32Disassembler.cc new file mode 100644 index 00000000..e9774d12 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/deprecated/Ia32Disassembler.cc @@ -0,0 +1,388 @@ +#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 { \ + DLOG(0, "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/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/deprecated/X86OpcodoDecodeTable.cc b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/deprecated/X86OpcodoDecodeTable.cc new file mode 100644 index 00000000..84bfad76 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/deprecated/X86OpcodoDecodeTable.cc @@ -0,0 +1,604 @@ +#include "platform_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/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/deprecated/X86OpcodoDecodeTable.h b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/deprecated/X86OpcodoDecodeTable.h new file mode 100644 index 00000000..778fdb30 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/deprecated/X86OpcodoDecodeTable.h @@ -0,0 +1,142 @@ +#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/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/build_config.h b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/build_config.h new file mode 100644 index 00000000..6206267e --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/build_config.h @@ -0,0 +1,144 @@ +#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/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_insn_decode.c b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_insn_decode.c new file mode 100644 index 00000000..087ac982 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_insn_decode.c @@ -0,0 +1,562 @@ +#include "./x86_insn_decode.h" + +#include +#include +#include + +#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 = (REX_B(insn->rex) << 3) | modrm.rm; + reg = (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 { + FATAL("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 = sib.base | (REX_B(insn->rex) << 3); + uint8_t index = sib.index | (REX_X(insn->rex) << 3); + uint8_t scale = 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 = 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; + } + + 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 = 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 + DLOG(0, "[x86 insn] %s", insn->insn_spec.name); +#endif + + // set insn length + insn->length = rd.buffer_cursor - rd.buffer; +} diff --git a/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_insn_decode.h b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_insn_decode.h new file mode 100644 index 00000000..bb395fde --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_insn_decode.h @@ -0,0 +1,200 @@ +#ifndef X86_INSN_DECODE_H +#define X86_INSN_DECODE_H + +#include +#include "common_header.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/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_insn_reader.c b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_insn_reader.c new file mode 100644 index 00000000..cfea5341 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_insn_reader.c @@ -0,0 +1,87 @@ +/* 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) { + DLOG(0, "[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) { + DLOG(0, "[x86 insn reader] %p - 2", rd->buffer_cursor); + + const unsigned char *p = rd->buffer_cursor; + rd->buffer_cursor += 2; + return (uint16_t)p[0] | ((uint16_t)p[1] << 8); +} + +#define read_uint32 read_dword +static uint32_t read_dword(x86_insn_reader_t *rd) { + DLOG(0, "[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) { + DLOG(0, "[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) { + DLOG(0, "[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/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_modrm_reg_group.c b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_modrm_reg_group.c new file mode 100644 index 00000000..352ea1a1 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_modrm_reg_group.c @@ -0,0 +1,218 @@ +/* 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/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_one_byte.c b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_one_byte.c new file mode 100644 index 00000000..44b14627 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_one_byte.c @@ -0,0 +1,215 @@ +// 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/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_sse_group.c b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_sse_group.c new file mode 100644 index 00000000..8e56a9b3 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_sse_group.c @@ -0,0 +1,545 @@ +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/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_two_byte.c b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_two_byte.c new file mode 100644 index 00000000..900d0b3a --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InstructionRelocation/x86/x86_insn_decode/x86_opcode_two_byte.c @@ -0,0 +1,249 @@ + +// 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/Bcore/src/main/cpp/Dobby/source/InterceptRouting/InterceptRouting.cpp b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/InterceptRouting.cpp new file mode 100644 index 00000000..a78079f8 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/InterceptRouting.cpp @@ -0,0 +1,88 @@ +#include "dobby_internal.h" + +#include "InterceptRouting/InterceptRouting.h" +#include "InterceptRouting/RoutingPlugin/RoutingPlugin.h" + +using namespace zz; + +void InterceptRouting::Prepare() { +} + +// Generate relocated code +bool InterceptRouting::GenerateRelocatedCode(int tramp_size) { + // generate original code + AssemblyCodeChunk *origin = NULL; + origin = AssemblyCodeBuilder::FinalizeFromAddress((addr_t)entry_->target_address, tramp_size); + origin_ = origin; + + // generate the relocated code + AssemblyCodeChunk *relocated = NULL; + relocated = AssemblyCodeBuilder::FinalizeFromAddress(0, 0); + relocated_ = relocated; + + void *relocate_buffer = NULL; + relocate_buffer = entry_->target_address; + + GenRelocateCodeAndBranch(relocate_buffer, origin, relocated); + if (relocated->raw_instruction_start() == 0) + return false; + + // set the relocated instruction address + entry_->relocated_origin_instructions = (void *)relocated->raw_instruction_start(); + DLOG(0, "[insn relocate] origin %p - %d", origin->raw_instruction_start(), origin->raw_instruction_size()); + DLOG(0, "[insn relocate] relocated %p - %d", relocated->raw_instruction_start(), relocated->raw_instruction_size()); + + // save original prologue + memcpy((void *)entry_->origin_chunk_.chunk_buffer, (void *)origin_->raw_instruction_start(), + origin_->raw_instruction_size()); + entry_->origin_chunk_.chunk.re_init_region_range(origin_); + return true; +} + +bool InterceptRouting::GenerateTrampolineBuffer(void *src, void *dst) { + CodeBufferBase *trampoline_buffer = NULL; + // if near branch trampoline plugin enabled + if (RoutingPluginManager::near_branch_trampoline) { + RoutingPluginInterface *plugin = NULL; + plugin = reinterpret_cast(RoutingPluginManager::near_branch_trampoline); + if (plugin->GenerateTrampolineBuffer(this, src, dst) == false) { + DLOG(0, "Failed enable near branch trampoline plugin"); + } + } + + if (this->GetTrampolineBuffer() == NULL) { + trampoline_buffer = GenerateNormalTrampolineBuffer((addr_t)src, (addr_t)dst); + this->SetTrampolineBuffer(trampoline_buffer); + + DLOG(0, "[trampoline] Generate trampoline buffer %p -> %p", src, dst); + } + return true; +} + +// Active routing, will patch the origin insturctions, and forward to our custom routing. +// Patch the address with branch instr +void InterceptRouting::Active() { + void *patch_address = NULL; + patch_address = (void *)origin_->raw_instruction_start(); + + CodePatch(patch_address, (uint8_t *)trampoline_buffer_->getRawBuffer(), trampoline_buffer_->getSize()); + DLOG(0, "[intercept routing] Active patch %p", patch_address); +} + +void InterceptRouting::Commit() { + this->Active(); +} + +#if 0 +int InterceptRouting::PredefinedTrampolineSize() { +#if __arm64__ + return 12; +#elif __arm__ + return 8; +#endif +} +#endif + +HookEntry *InterceptRouting::GetHookEntry() { + return entry_; +}; diff --git a/Bcore/src/main/cpp/Dobby/source/InterceptRouting/InterceptRouting.h b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/InterceptRouting.h new file mode 100644 index 00000000..5917cd49 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/InterceptRouting.h @@ -0,0 +1,64 @@ +#ifndef INTERCEPT_ROUTING_H +#define INTERCEPT_ROUTING_H + +#include "Interceptor.h" +#include "MemoryAllocator/AssemblyCodeBuilder.h" +#include "InstructionRelocation/InstructionRelocation.h" +#include "TrampolineBridge/Trampoline/Trampoline.h" + +class InterceptRouting { +public: + InterceptRouting(HookEntry *entry) : entry_(entry) { + entry->route = this; + + trampoline_ = NULL; + trampoline_buffer_ = NULL; + trampoline_target_ = NULL; + } + + virtual void DispatchRouting() = 0; + + virtual void Prepare(); + + virtual void Active(); + + void Commit(); + + HookEntry *GetHookEntry(); + + void SetTrampolineBuffer(CodeBufferBase *buffer) { + trampoline_buffer_ = buffer; + } + + CodeBufferBase *GetTrampolineBuffer() { + return trampoline_buffer_; + } + + void SetTrampolineTarget(void *address) { + trampoline_target_ = address; + } + + void *GetTrampolineTarget() { + return trampoline_target_; + } + +protected: + bool GenerateRelocatedCode(int tramp_size); + + bool GenerateTrampolineBuffer(void *src, void *dst); + +protected: + HookEntry *entry_; + + AssemblyCodeChunk *origin_; + + AssemblyCodeChunk *relocated_; + + AssemblyCodeChunk *trampoline_; + + // trampoline buffer before active + CodeBufferBase *trampoline_buffer_; + + void *trampoline_target_; +}; +#endif diff --git a/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/DynamicBinaryInstrument/DynamicBinaryInstrumentExport.cc b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/DynamicBinaryInstrument/DynamicBinaryInstrumentExport.cc new file mode 100644 index 00000000..ff573151 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/DynamicBinaryInstrument/DynamicBinaryInstrumentExport.cc @@ -0,0 +1,37 @@ +#include "dobby_internal.h" + +#include "InterceptRouting/InterceptRouting.h" +#include "InterceptRouting/Routing/DynamicBinaryInstrument/dynamic-binary-instrument.h" + +PUBLIC int DobbyInstrument(void *address, DBICallTy handler) { + if (!address) { + ERROR_LOG("the function address is 0x0.\n"); + return RS_FAILED; + } + + RAW_LOG(1, "\n\n"); + DLOG(0, "[DobbyInstrument] Initialize at %p", address); + + // check if we already instruemnt + HookEntry *entry = Interceptor::SharedInstance()->FindHookEntry(address); + if (entry) { + DynamicBinaryInstrumentRouting *route = (DynamicBinaryInstrumentRouting *)entry->route; + if (route->handler == handler) { + ERROR_LOG("instruction %s already been instrumented.", address); + return RS_FAILED; + } + } + + entry = new HookEntry(); + entry->id = Interceptor::SharedInstance()->GetHookEntryCount(); + entry->type = kDynamicBinaryInstrument; + entry->instruction_address = address; + + DynamicBinaryInstrumentRouting *route = new DynamicBinaryInstrumentRouting(entry, (void *)handler); + route->Prepare(); + route->DispatchRouting(); + Interceptor::SharedInstance()->AddHookEntry(entry); + route->Commit(); + + return RS_SUCCESS; +} diff --git a/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/DynamicBinaryInstrument/dynamic-binary-instrument.cc b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/DynamicBinaryInstrument/dynamic-binary-instrument.cc new file mode 100644 index 00000000..54335f0c --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/DynamicBinaryInstrument/dynamic-binary-instrument.cc @@ -0,0 +1,41 @@ +#include "InterceptRouting/Routing/DynamicBinaryInstrument/dynamic-binary-instrument.h" + +#include "dobby_internal.h" + +#include "TrampolineBridge/ClosureTrampolineBridge/AssemblyClosureTrampoline.h" + +#include "InterceptRouting/Routing/DynamicBinaryInstrument/intercept_routing_handler.h" + +void DynamicBinaryInstrumentRouting::DispatchRouting() { + BuildDynamicBinaryInstrumentRouting(); + + // generate relocated code which size == trampoline size + GenerateRelocatedCode(trampoline_buffer_->getSize()); +} + +// Add dbi_call handler before running the origin instructions +void DynamicBinaryInstrumentRouting::BuildDynamicBinaryInstrumentRouting() { + // create closure trampoline jump to prologue_routing_dispath with the `entry_` data + ClosureTrampolineEntry *closure_trampoline; + + void *handler = (void *)instrument_routing_dispatch; +#if __APPLE__ +#if __has_feature(ptrauth_calls) + handler = __builtin_ptrauth_strip(handler, ptrauth_key_asia); +#endif +#endif + + closure_trampoline = ClosureTrampoline::CreateClosureTrampoline(entry_, handler); + this->SetTrampolineTarget(closure_trampoline->address); + DLOG(0, "[closure bridge] Carry data %p ", entry_); + DLOG(0, "[closure bridge] Create prologue_dispatch_bridge %p", closure_trampoline->address); + + // generate trampoline buffer, run before `GenerateRelocatedCode` + GenerateTrampolineBuffer(entry_->target_address, GetTrampolineTarget()); +} + +#if 0 +void *DynamicBinaryInstrumentRouting::GetTrampolineTarget() { + return this->prologue_dispatch_bridge; +} +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/DynamicBinaryInstrument/dynamic-binary-instrument.h b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/DynamicBinaryInstrument/dynamic-binary-instrument.h new file mode 100644 index 00000000..b098233d --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/DynamicBinaryInstrument/dynamic-binary-instrument.h @@ -0,0 +1,35 @@ +#ifndef DYNAMIC_BINARY_INSTRUMENT_H +#define DYNAMIC_BINARY_INSTRUMENT_H + +#include "dobby_internal.h" + +#include "Interceptor.h" + +#include "InterceptRouting/InterceptRouting.h" + +#include "TrampolineBridge/ClosureTrampolineBridge/AssemblyClosureTrampoline.h" + +#define X64InterceptRouting InterceptRouting +#define ARM64InterceptRouting InterceptRouting + +class DynamicBinaryInstrumentRouting : public X64InterceptRouting { +public: + DynamicBinaryInstrumentRouting(HookEntry *entry, void *handler) : X64InterceptRouting(entry) { + this->handler = handler; + } + + void DispatchRouting(); + +public: + void *handler; + +private: + virtual void BuildDynamicBinaryInstrumentRouting(); + +private: + void *prologue_dispatch_bridge; + + ; +}; + +#endif diff --git a/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/DynamicBinaryInstrument/intercept_routing_handler.cc b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/DynamicBinaryInstrument/intercept_routing_handler.cc new file mode 100644 index 00000000..bd43afd2 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/DynamicBinaryInstrument/intercept_routing_handler.cc @@ -0,0 +1,27 @@ +#include "InterceptRouting/Routing/DynamicBinaryInstrument/intercept_routing_handler.h" + +#include "dobby_internal.h" + +#include "InterceptRouting/Routing/DynamicBinaryInstrument/dynamic-binary-instrument.h" + +#include "TrampolineBridge/ClosureTrampolineBridge/common-bridge-handler.h" + +void instrument_call_forward_handler(RegisterContext *ctx, HookEntry *entry) { + DynamicBinaryInstrumentRouting *route = (DynamicBinaryInstrumentRouting *)entry->route; + if (route->handler) { + DBICallTy handler; + HookEntryInfo entry_info; + entry_info.hook_id = entry->id; + entry_info.instruction_address = entry->instruction_address; + handler = (DBICallTy)route->handler; + (*handler)(ctx, (const HookEntryInfo *)&entry_info); + } + + // set prologue bridge next hop address with origin instructions that have been relocated(patched) + set_routing_bridge_next_hop(ctx, entry->relocated_origin_instructions); +} + +void instrument_routing_dispatch(RegisterContext *ctx, ClosureTrampolineEntry *closure_trampoline_entry) { + HookEntry *entry = (HookEntry *)closure_trampoline_entry->carry_data; + instrument_call_forward_handler(ctx, entry); +} diff --git a/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/DynamicBinaryInstrument/intercept_routing_handler.h b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/DynamicBinaryInstrument/intercept_routing_handler.h new file mode 100644 index 00000000..75a24ebe --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/DynamicBinaryInstrument/intercept_routing_handler.h @@ -0,0 +1,12 @@ +#ifndef INTERCEPT_ROUTING_HANDLER_H +#define INTERCEPT_ROUTING_HANDLER_H + +#include "dobby_internal.h" + +#include "TrampolineBridge/ClosureTrampolineBridge/AssemblyClosureTrampoline.h" + +extern "C" { +void instrument_routing_dispatch(RegisterContext *ctx, ClosureTrampolineEntry *entry); +} + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionInlineReplace/FunctionInlineReplaceExport.cc b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionInlineReplace/FunctionInlineReplaceExport.cc new file mode 100644 index 00000000..0252e196 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionInlineReplace/FunctionInlineReplaceExport.cc @@ -0,0 +1,42 @@ +#include "dobby_internal.h" + +#include "Interceptor.h" +#include "InterceptRouting/InterceptRouting.h" +#include "InterceptRouting/Routing/FunctionInlineReplace/function-inline-replace.h" + +PUBLIC int DobbyHook(void *address, void *replace_call, void **origin_call) { + if (!address) { + ERROR_LOG("function address is 0x0"); + return RS_FAILED; + } + + DLOG(0, "[DobbyHook] Initialize at %p", address); + + // check if already hooked + HookEntry *entry = Interceptor::SharedInstance()->FindHookEntry(address); + if (entry) { + FunctionInlineReplaceRouting *route = (FunctionInlineReplaceRouting *)entry->route; + if (route->GetTrampolineTarget() == replace_call) { + ERROR_LOG("function %p already been hooked.", address); + return RS_FAILED; + } + } + + entry = new HookEntry(); + entry->id = Interceptor::SharedInstance()->GetHookEntryCount(); + entry->type = kFunctionInlineHook; + entry->function_address = address; + + FunctionInlineReplaceRouting *route = new FunctionInlineReplaceRouting(entry, replace_call); + route->Prepare(); + route->DispatchRouting(); + Interceptor::SharedInstance()->AddHookEntry(entry); + + // set origin call with relocated function + *origin_call = entry->relocated_origin_function; + + // code patch & hijack original control flow entry + route->Commit(); + + return RS_SUCCESS; +} diff --git a/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionInlineReplace/function-inline-replace.cc b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionInlineReplace/function-inline-replace.cc new file mode 100644 index 00000000..4e17d6d9 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionInlineReplace/function-inline-replace.cc @@ -0,0 +1,24 @@ +#include "InterceptRouting/Routing/FunctionInlineReplace/function-inline-replace.h" + +#include "dobby_internal.h" + +void FunctionInlineReplaceRouting::DispatchRouting() { + BuildReplaceRouting(); + + // generate relocated code which size == trampoline size + GenerateRelocatedCode(trampoline_buffer_->getSize()); +} + +void FunctionInlineReplaceRouting::BuildReplaceRouting() { + this->SetTrampolineTarget(this->replace_call); + DLOG(0, "[inline] Set trampoline target => %p", GetTrampolineTarget()); + + // generate trampoline buffer, run before `GenerateRelocatedCode` + GenerateTrampolineBuffer(entry_->target_address, GetTrampolineTarget()); +} + +#if 0 +void *FunctionInlineReplaceRouting::GetTrampolineTarget() { + return this->replace_call; +} +#endif diff --git a/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionInlineReplace/function-inline-replace.h b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionInlineReplace/function-inline-replace.h new file mode 100644 index 00000000..ff7e1f38 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionInlineReplace/function-inline-replace.h @@ -0,0 +1,26 @@ +#ifndef FUNCTION_INLINE_REPLACE_H +#define FUNCTION_INLINE_REPLACE_H + +#include "dobby_internal.h" + +#include "InterceptRouting/InterceptRouting.h" +#include "Interceptor.h" + +#include "TrampolineBridge/ClosureTrampolineBridge/AssemblyClosureTrampoline.h" + +class FunctionInlineReplaceRouting : public InterceptRouting { +public: + FunctionInlineReplaceRouting(HookEntry *entry, void *replace_call) : InterceptRouting(entry) { + this->replace_call = replace_call; + } + + void DispatchRouting() override; + +private: + virtual void BuildReplaceRouting(); + +private: + void *replace_call; +}; + +#endif diff --git a/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/FunctionWrapperExport.cc b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/FunctionWrapperExport.cc new file mode 100644 index 00000000..cc8301d2 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/FunctionWrapperExport.cc @@ -0,0 +1,27 @@ +#include "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) { + DLOG(0, "Initialize 'DobbyWrap' hook at %p", function_address); + + Interceptor *interceptor = Interceptor::SharedInstance(); + + HookEntry *entry = new HookEntry(); + entry->id = interceptor->entries->getCount(); + entry->type = kFunctionWrapper; + entry->function_address = function_address; + + FunctionWrapperRouting *route = new FunctionWrapperRouting(entry); + route->DispatchRouting(); + interceptor->AddHookEntry(entry); + route->Commit(); + + DLOG(0, "Finalize %p", function_address); + return RS_SUCCESS; +} diff --git a/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/function-wrapper.cc b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/function-wrapper.cc new file mode 100644 index 00000000..2f25dc9c --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/function-wrapper.cc @@ -0,0 +1,38 @@ +#include "dobby_internal.h" + +#include "TrampolineBridge/ClosureTrampolineBridge/AssemblyClosureTrampoline.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; + + DLOG(0, "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); + DLOG(0, "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/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/function-wrapper.h b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/function-wrapper.h new file mode 100644 index 00000000..29bf5496 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/function-wrapper.h @@ -0,0 +1,40 @@ +#ifndef FUNCTION_WRAPPER_H +#define FUNCTION_WRAPPER_H + +#include "dobby_internal.h" + +#include "TrampolineBridge/ClosureTrampolineBridge/AssemblyClosureTrampoline.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(HookEntry *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/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/intercept_routing_handler.cc b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/intercept_routing_handler.cc new file mode 100644 index 00000000..189e2206 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/intercept_routing_handler.cc @@ -0,0 +1,79 @@ + +#include "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(RegisterContext *ctx, HookEntry *entry) { + FunctionWrapperRouting *route = (FunctionWrapperRouting *)entry->route; + + 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 (route->pre_call) { + PreCallTy pre_call; + HookEntryInfo entry_info; + entry_info.hook_id = entry->id; + entry_info.target_address = entry->target_address; + pre_call = route->pre_call; + // run the pre_call with the power of accessing all registers + (*pre_call)(ctx, (const HookEntryInfo *)&entry_info); + } + + // 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(RegisterContext *ctx, HookEntry *entry) { + FunctionWrapperRouting *route = (FunctionWrapperRouting *)entry->route; + + // 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 (route->post_call) { + PostCallTy post_call; + HookEntryInfo entry_info; + entry_info.hook_id = entry->id; + entry_info.target_address = entry->target_address; + post_call = route->post_call; + + // run the post_call with the power of accessing all registers + (*post_call)(ctx, (const HookEntryInfo *)&entry_info); + } + + // 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(RegisterContext *ctx, ClosureTrampolineEntry *closure_trampoline_entry) { + DLOG(0, "Catch prologue dispatch"); + HookEntry *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(RegisterContext *ctx, ClosureTrampolineEntry *closure_trampoline_entry) { + DLOG(0, "Catch epilogue dispatch"); + HookEntry *entry = static_cast(closure_trampoline_entry->carry_data); + post_call_forward_handler(ctx, entry); + return; +} \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/intercept_routing_handler.h b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/intercept_routing_handler.h new file mode 100644 index 00000000..08e91e07 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/Routing/FunctionWrapper/intercept_routing_handler.h @@ -0,0 +1,27 @@ +#ifndef FUNCTION_WRAPPER_INTERCEPT_ROUTING_HANDLER_H +#define FUNCTION_WRAPPER_INTERCEPT_ROUTING_HANDLER_H + +#include "TrampolineBridge/ClosureTrampolineBridge/AssemblyClosureTrampoline.h" +#include "Interceptor.h" +#include "dobby_internal.h" + +#ifdef __cplusplus +extern "C" { +#endif //__cplusplus + +// Dispatch the routing befor running the origin function +void prologue_routing_dispatch(RegisterContext *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(RegisterContext *ctx, ClosureTrampolineEntry *entry); + +void pre_call_forward_handler(RegisterContext *ctx, HookEntry *entry); + +void post_call_forward_handler(RegisterContext *ctx, HookEntry *entry); + +#ifdef __cplusplus +} +#endif //__cplusplus + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/NearBranchTrampoline/NeaBranchTrampoline.cc b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/NearBranchTrampoline/NeaBranchTrampoline.cc new file mode 100644 index 00000000..0b836de5 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/NearBranchTrampoline/NeaBranchTrampoline.cc @@ -0,0 +1,50 @@ +#include "InterceptRouting/RoutingPlugin/NearBranchTrampoline/NearBranchTrampoline.h" + +#include "dobby_internal.h" + +#include "MemoryAllocator/NearMemoryArena.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, void *src, void *dst) { + CodeBufferBase *trampoline_buffer; + trampoline_buffer = GenerateNearTrampolineBuffer(routing, (addr_t)src, (addr_t)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; + HookEntry *entry = routing->GetHookEntry(); + src = (addr_t)entry->target_address; + dst = (addr_t)routing->GetTrampolineTarget(); + return true; +} diff --git a/Bcore/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/NearBranchTrampoline/NearBranchTrampoline.h b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/NearBranchTrampoline/NearBranchTrampoline.h new file mode 100644 index 00000000..6ac6b72e --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/NearBranchTrampoline/NearBranchTrampoline.h @@ -0,0 +1,19 @@ +#ifndef PLUGIN_NEAR_BRANCH_TRAMPOLINE_H +#define PLUGIN_NEAR_BRANCH_TRAMPOLINE_H + +#include "dobby_internal.h" + +#include "InterceptRouting/RoutingPlugin/RoutingPlugin.h" + +class NearBranchTrampolinePlugin : public RoutingPluginInterface { + // @Return: if false will continue to iter next plugin + bool Prepare(InterceptRouting *routing) { + return false; + }; + + bool Active(InterceptRouting *routing); + + bool GenerateTrampolineBuffer(InterceptRouting *routing, void *src, void *dst); +}; + +#endif diff --git a/Bcore/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/RoutingPlugin.cc b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/RoutingPlugin.cc new file mode 100644 index 00000000..39842115 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/RoutingPlugin.cc @@ -0,0 +1,15 @@ +#include "InterceptRouting/RoutingPlugin/RoutingPlugin.h" + +LiteMutableArray *RoutingPluginManager::plugins; + +RoutingPluginInterface *RoutingPluginManager::near_branch_trampoline = NULL; + +void RoutingPluginManager::registerPlugin(const char *name, RoutingPluginInterface *plugin) { + DLOG(0, "register %s plugin", name); + + if (RoutingPluginManager::plugins == NULL) { + RoutingPluginManager::plugins = new LiteMutableArray(8); + } + + RoutingPluginManager::plugins->pushObject(reinterpret_cast(plugin)); +} diff --git a/Bcore/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/RoutingPlugin.h b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/RoutingPlugin.h new file mode 100644 index 00000000..b653a16a --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/InterceptRouting/RoutingPlugin/RoutingPlugin.h @@ -0,0 +1,36 @@ +#ifndef EXTRA_INTERNAL_PLUGIN_H +#define EXTRA_INTERNAL_PLUGIN_H + +#include "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, void *src, void *dst) = 0; + +private: + char name_[256]; +}; + +class RoutingPluginManager { +public: + static void registerPlugin(const char *name, RoutingPluginInterface *plugin); + +public: + // global plugin array + static LiteMutableArray *plugins; + + static RoutingPluginInterface *near_branch_trampoline; +}; + + + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/Interceptor.cpp b/Bcore/src/main/cpp/Dobby/source/Interceptor.cpp new file mode 100644 index 00000000..7b5f4c8a --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/Interceptor.cpp @@ -0,0 +1,71 @@ +#include "Interceptor.h" + +#include "dobby_internal.h" + +Interceptor *Interceptor::priv_interceptor_ = nullptr; + +Interceptor *Interceptor::SharedInstance() { + if (Interceptor::priv_interceptor_ == nullptr) { + Interceptor::priv_interceptor_ = new Interceptor(); + INIT_LIST_HEAD(&Interceptor::priv_interceptor_->hook_entry_list_); + } + return Interceptor::priv_interceptor_; +} + +HookEntryNode *Interceptor::find_hook_entry_node(void *address) { + HookEntryNode *entry_node = nullptr; +#if defined(_MSC_VER) +#if 0 // only valid if offsetof(HookEntryNode, list_node) == 0 + for(entry_node = (HookEntryNode *)hook_entry_list_.next; &entry_node->list_node != &hook_entry_list_; entry_node = (HookEntryNode *)entry_node->list_node.next); +#endif + struct list_head *list_node = nullptr; + for(list_node = hook_entry_list_.next; list_node != &hook_entry_list_; list_node = list_node->next) { + entry_node = (HookEntryNode *)((char *)list_node - offsetof(HookEntryNode, list_node)); +#else + list_for_each_entry(entry_node, &hook_entry_list_, list_node) { +#endif + HookEntry *entry = entry_node->entry; + if (entry->instruction_address == address) { + return entry_node; + } + } + return nullptr; +} + +HookEntry *Interceptor::FindHookEntry(void *address) { + HookEntryNode *entry_node = nullptr; + entry_node = find_hook_entry_node(address); + if (entry_node) { + return entry_node->entry; + } + + return nullptr; +} + +void Interceptor::AddHookEntry(HookEntry *entry) { + HookEntryNode *entry_node = new HookEntryNode; + entry_node->entry = entry; + + list_add(&entry_node->list_node, &hook_entry_list_); +} + +void Interceptor::RemoveHookEntry(void *address) { + if (HookEntryNode *entry_node = find_hook_entry_node(address)) { + list_del(&entry_node->list_node); + } +} + +int Interceptor::GetHookEntryCount() { + int count = 0; + HookEntryNode *entry_node = nullptr; +#if defined(_MSC_VER) + struct list_head *list_node = nullptr; + for(list_node = hook_entry_list_.next; list_node != &hook_entry_list_; list_node = list_node->next) { + entry_node = (HookEntryNode *)((char *)list_node - offsetof(HookEntryNode, list_node)); +#else + list_for_each_entry(entry_node, &hook_entry_list_, list_node) { +#endif + count += 1; + } + return count; +} diff --git a/Bcore/src/main/cpp/Dobby/source/Interceptor.h b/Bcore/src/main/cpp/Dobby/source/Interceptor.h new file mode 100644 index 00000000..2c5afb0e --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/Interceptor.h @@ -0,0 +1,37 @@ +#ifndef INTERCEPTOR_H +#define INTERCEPTOR_H + +#include "dobby_internal.h" + +#include "include/list_structure.h" + +typedef struct { + struct list_head list_node; + HookEntry *entry; +} HookEntryNode; + +class Interceptor { +public: + static Interceptor *SharedInstance(); + + HookEntry *FindHookEntry(void *address); + + void AddHookEntry(HookEntry *entry); + + void RemoveHookEntry(void *address); + + int GetHookEntryCount(); + +private: + Interceptor() { + } + + HookEntryNode *find_hook_entry_node(void *address); + +private: + struct list_head hook_entry_list_; + + static Interceptor *priv_interceptor_; +}; + +#endif diff --git a/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/AssemblyCodeBuilder.cc b/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/AssemblyCodeBuilder.cc new file mode 100644 index 00000000..2e123a6a --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/AssemblyCodeBuilder.cc @@ -0,0 +1,47 @@ +#include "MemoryAllocator/AssemblyCodeBuilder.h" + +#include "dobby_internal.h" +#include "PlatformUnifiedInterface/ExecMemory/CodePatchTool.h" + +AssemblyCodeChunk *AssemblyCodeBuilder::FinalizeFromAddress(addr_t address, int size) { + AssemblyCodeChunk *result = NULL; + result = new AssemblyCodeChunk; + result->init_region_range(address, size); + return result; +} + +AssemblyCodeChunk *AssemblyCodeBuilder::FinalizeFromTurboAssembler(AssemblerBase *assembler) { + AssemblyCodeChunk *result = NULL; + + CodeBufferBase *buffer = NULL; + buffer = (CodeBufferBase *)assembler->GetCodeBuffer(); + + void *realized_address = assembler->GetRealizedAddress(); + if (realized_address == NULL) { + int buffer_size = 0; + { + buffer_size = buffer->getSize(); +#if TARGET_ARCH_ARM64 || TARGET_ARCH_ARM + // FIXME: need it ? actually ??? + // extra bytes for align needed + buffer_size += 4; +#endif + } + + // assembler without specific memory address + result = MemoryArena::AllocateCodeChunk(buffer_size); + if (result == NULL) + return NULL; + + realized_address = (void *)result->raw_instruction_start(); + assembler->SetRealizedAddress(realized_address); + } else { + result = AssemblyCodeBuilder::FinalizeFromAddress((addr_t)realized_address, buffer->getSize()); + } + + // Realize(Relocate) the buffer_code to the executable_memory_address, remove the ExternalLabels, etc, the pc-relative + // instructions + CodePatch(realized_address, (uint8_t *)buffer->getRawBuffer(), buffer->getSize()); + + return result; +} \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/AssemblyCodeBuilder.h b/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/AssemblyCodeBuilder.h new file mode 100644 index 00000000..71292b77 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/AssemblyCodeBuilder.h @@ -0,0 +1,39 @@ +#ifndef MemoryAllocator_AssemblyCodeBuilder_h +#define MemoryAllocator_AssemblyCodeBuilder_h + +#include "MemoryAllocator/MemoryArena.h" + +#include "core/modules/assembler/assembler.h" + +using namespace zz; + +class AssemblyCodeBuilder { +public: + // realize the buffer address to runtime code, and create a corresponding Code Object + static AssemblyCodeChunk *FinalizeFromAddress(addr_t address, int size); + + // realize the buffer address to runtime code, and create a corresponding Code Object + static AssemblyCodeChunk *FinalizeFromTurboAssembler(AssemblerBase *assembler); + + // inline void init_region_range(addr_t address, int size) { + // code_range_.address = (void *)address; + // code_range_.length = size; + // } + + // inline void re_init_region_range(addr_t address, int size) { + // this->init_region_range(address, size); + // } + + // inline addr_t raw_instruction_start() { + // return (addr_t)code_range_.address; + // }; + + // inline int raw_instruction_size() { + // return (int)code_range_.length; + // }; + +private: + // AssemblyCodeChunk code_range_; +}; + +#endif diff --git a/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/CodeBufferBase.cc b/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/CodeBufferBase.cc new file mode 100644 index 00000000..5cfa7cac --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/CodeBufferBase.cc @@ -0,0 +1,68 @@ +#include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" + +#include "xnucxx/LiteMemOpt.h" + +CodeBufferBase *CodeBufferBase::Copy() { + CodeBufferBase *result = new CodeBufferBase(this->getCapacity()); + result->EmitBuffer(this->getRawBuffer(), this->getSize()); + return result; +} + +void CodeBufferBase::Emit8(uint8_t value) { + // Ensure the free space enough for the template T value + this->ensureCapacity(sizeof(uint8_t) + this->getSize()); + + *reinterpret_cast(buffer_cursor) = value; + buffer_cursor += sizeof(uint8_t); +} + +void CodeBufferBase::Emit16(uint16_t value) { + // Ensure the free space enough for the template T value + this->ensureCapacity(sizeof(uint16_t) + this->getSize()); + + *reinterpret_cast(buffer_cursor) = value; + buffer_cursor += sizeof(uint16_t); +} + +void CodeBufferBase::Emit32(uint32_t value) { + // Ensure the free space enough for the template T value + this->ensureCapacity(sizeof(uint32_t) + this->getSize()); + + *reinterpret_cast(buffer_cursor) = value; + buffer_cursor += sizeof(uint32_t); +} + +void CodeBufferBase::Emit64(uint64_t value) { + // Ensure the free space enough for the template T value + this->ensureCapacity(sizeof(uint64_t) + this->getSize()); + + *reinterpret_cast(buffer_cursor) = value; + buffer_cursor += sizeof(uint64_t); +} + +void CodeBufferBase::EmitBuffer(void *buffer, int buffer_size) { + // Ensure the free space enough for the template T value + this->ensureCapacity(buffer_size + this->getSize()); + + _memcpy(buffer_cursor, buffer, buffer_size); + + buffer_cursor += 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) + getSize()); + + *reinterpret_cast(buffer_cursor) = value; + buffer_cursor += sizeof(T); +} +#endif diff --git a/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/CodeBufferBase.h b/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/CodeBufferBase.h new file mode 100644 index 00000000..86b6356b --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/CodeBufferBase.h @@ -0,0 +1,38 @@ +#ifndef CODE_BUFFER_BASE_H +#define CODE_BUFFER_BASE_H + +#include "xnucxx/LiteMutableBuffer.h" + +class CodeBufferBase : public LiteMutableBuffer { +public: + CodeBufferBase() : LiteMutableBuffer() { + } + + CodeBufferBase(int size) : LiteMutableBuffer(size) { + } + +public: + virtual CodeBufferBase *Copy(); + + void Emit8(uint8_t data); + + void Emit16(uint16_t data); + + void Emit32(uint32_t data); + + void Emit64(uint64_t data); + + void EmitBuffer(void *buffer, int len); + + void EmitObject(LiteObject *object); + +#if 0 // Template Advanced won't enable even in userspace + template T Load(int offset); + + template void Store(int offset, T value); + + template void Emit(T value); +#endif +}; + +#endif diff --git a/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-arm.cc b/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-arm.cc new file mode 100644 index 00000000..7d985c2d --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-arm.cc @@ -0,0 +1,84 @@ +#include "platform_macro.h" +#if defined(TARGET_ARCH_ARM) + +#include + +#include "MemoryAllocator/CodeBuffer/code-buffer-arm.h" + +arm_inst_t CodeBuffer::LoadARMInst(int offset) { + return *reinterpret_cast(buffer + offset); +} + +thumb1_inst_t CodeBuffer::LoadThumb1Inst(int offset) { + return *reinterpret_cast(buffer + offset); +}; + +thumb2_inst_t CodeBuffer::LoadThumb2Inst(int offset) { + return *reinterpret_cast(buffer + offset); +}; + +void CodeBuffer::RewriteAddr(int offset, addr32_t addr) { + memcpy(buffer + offset, &addr, sizeof(addr)); +#if 0 + // SIGBUS (signal SIGBUS: illegal alignment) + *reinterpret_cast(buffer + offset) = addr; +#endif + return; +} + +void CodeBuffer::RewriteARMInst(int offset, arm_inst_t instr) { + *reinterpret_cast(buffer + offset) = instr; + return; +} + +void CodeBuffer::RewriteThumb1Inst(int offset, thumb1_inst_t instr) { + *reinterpret_cast(buffer + offset) = instr; + return; +} + +void CodeBuffer::RewriteThumb2Inst(int offset, thumb2_inst_t instr) { + memcpy(buffer + offset, &instr, sizeof(instr)); +#if 0 + // SIGBUS (signal SIGBUS: illegal alignment) + *reinterpret_cast(buffer + offset) = instr; +#endif + return; +} + +void CodeBuffer::EmitARMInst(arm_inst_t instr) { + ensureCapacity(getSize() + sizeof(arm_inst_t)); + *reinterpret_cast(buffer_cursor) = instr; + buffer_cursor += sizeof(arm_inst_t); + return; +} + +void CodeBuffer::EmitThumb1Inst(thumb1_inst_t instr) { + ensureCapacity(getSize() + sizeof(thumb1_inst_t)); + *reinterpret_cast(buffer_cursor) = instr; + buffer_cursor += sizeof(thumb1_inst_t); + return; +} + +void CodeBuffer::EmitThumb2Inst(thumb2_inst_t instr) { + ensureCapacity(getSize() + sizeof(thumb2_inst_t)); + memcpy(buffer_cursor, &instr, sizeof(instr)); +#if 0 + // SIGBUS (signal SIGBUS: illegal alignment) + *reinterpret_cast(buffer_cursor) = instr; +#endif + buffer_cursor += sizeof(thumb2_inst_t); + return; +} + +void CodeBuffer::Emit32(int32_t data) { + ensureCapacity(getSize() + sizeof(int32_t)); + memcpy(buffer_cursor, &data, sizeof(data)); +#if 0 + // SIGBUS (signal SIGBUS: illegal alignment) + *reinterpret_cast(buffer_cursor) = data; +#endif + buffer_cursor += sizeof(int32_t); + return; +} + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-arm.h b/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-arm.h new file mode 100644 index 00000000..7dcb220e --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-arm.h @@ -0,0 +1,44 @@ +#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() { + } + + CodeBuffer(int size) : CodeBufferBase(size) { + } + +public: + arm_inst_t LoadARMInst(int offset); + + thumb1_inst_t LoadThumb1Inst(int offset); + + thumb2_inst_t LoadThumb2Inst(int offset); + + void RewriteAddr(int offset, addr32_t addr); + + void RewriteARMInst(int offset, arm_inst_t instr); + + void RewriteThumb1Inst(int offset, thumb1_inst_t instr); + + void RewriteThumb2Inst(int offset, thumb2_inst_t instr); + + void EmitARMInst(arm_inst_t instr); + + void EmitThumb1Inst(thumb1_inst_t instr); + + void EmitThumb2Inst(thumb2_inst_t instr); + + void Emit32(int32_t data); +}; + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-arm64.cc b/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-arm64.cc new file mode 100644 index 00000000..cea9be1e --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-arm64.cc @@ -0,0 +1,29 @@ +#include "platform_macro.h" +#if defined(TARGET_ARCH_ARM64) + +#include "MemoryAllocator/CodeBuffer/code-buffer-arm64.h" + +arm64_inst_t CodeBuffer::LoadInst(int offset) { + return *reinterpret_cast(buffer + offset); +} + +void CodeBuffer::FixBindLabel(int offset, arm64_inst_t instr) { + *reinterpret_cast(buffer + offset) = instr; + return; +} + +void CodeBuffer::EmitInst(arm64_inst_t instr) { + ensureCapacity(getSize() + sizeof(arm64_inst_t)); + *reinterpret_cast(getCursor()) = instr; + buffer_cursor += sizeof(arm64_inst_t); + return; +} + +void CodeBuffer::Emit64(int64_t data) { + ensureCapacity(getSize() + sizeof(int64_t)); + *reinterpret_cast(getCursor()) = data; + buffer_cursor += sizeof(int64_t); + return; +} + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-arm64.h b/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-arm64.h new file mode 100644 index 00000000..e5cac682 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-arm64.h @@ -0,0 +1,27 @@ +#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() { + } + + CodeBuffer(int size) : CodeBufferBase(size) { + } + +public: + arm64_inst_t LoadInst(int offset); + + void FixBindLabel(int offset, arm64_inst_t instr); + + void EmitInst(arm64_inst_t instr); + + void Emit64(int64_t data); +}; + +#endif diff --git a/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-x64.cc b/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-x64.cc new file mode 100644 index 00000000..0c7615c4 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-x64.cc @@ -0,0 +1,25 @@ +#include "platform_macro.h" +#if defined(TARGET_ARCH_X64) + +#include "MemoryAllocator/CodeBuffer/code-buffer-x64.h" + +void CodeBuffer::Emit32(int32_t data) { + ensureCapacity(getSize() + sizeof(int32_t)); + *reinterpret_cast(getCursor()) = data; + buffer_cursor += sizeof(int32_t); + return; +} + +void CodeBuffer::Emit64(int64_t data) { + ensureCapacity(getSize() + sizeof(int64_t)); + *reinterpret_cast(getCursor()) = data; + buffer_cursor += sizeof(int64_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/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-x64.h b/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-x64.h new file mode 100644 index 00000000..926b5522 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-x64.h @@ -0,0 +1,22 @@ +#ifndef CODE_BUFFER_X64_H +#define CODE_BUFFER_X64_H + +#include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" + +class CodeBuffer : public CodeBufferBase { +public: + CodeBuffer() : CodeBufferBase() { + } + + CodeBuffer(int size) : CodeBufferBase(size) { + } + +public: + void FixBindLabel(int offset, int32_t disp); + + void Emit32(int32_t data); + + void Emit64(int64_t data); +}; + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-x86.cc b/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-x86.cc new file mode 100644 index 00000000..1f2c04bd --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-x86.cc @@ -0,0 +1,18 @@ +#include "platform_macro.h" +#if defined(TARGET_ARCH_IA32) + +#include "MemoryAllocator/CodeBuffer/code-buffer-x86.h" + +void CodeBuffer::Emit32(int32_t data) { + ensureCapacity(getSize() + 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/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-x86.h b/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-x86.h new file mode 100644 index 00000000..64775c65 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/CodeBuffer/code-buffer-x86.h @@ -0,0 +1,20 @@ +#ifndef CODE_BUFFER_X86_H +#define CODE_BUFFER_X86_H + +#include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" + +class CodeBuffer : public CodeBufferBase { +public: + CodeBuffer() : CodeBufferBase() { + } + + CodeBuffer(int size) : CodeBufferBase(size) { + } + +public: + void FixBindLabel(int offset, int32_t disp); + + void Emit32(int32_t data); +}; + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/MemoryArena.cc b/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/MemoryArena.cc new file mode 100644 index 00000000..05fe6c74 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/MemoryArena.cc @@ -0,0 +1,73 @@ +#include "MemoryAllocator/MemoryArena.h" + +#include "dobby_internal.h" + +LiteMutableArray *MemoryArena::page_chunks = NULL; + +void MemoryArena::Destroy(AssemblyCodeChunk *cchunk) { + return; +} + +MemoryChunk *MemoryArena::AllocateChunk(int alloc_size, MemoryPermission permission) { + MemoryChunk *result = NULL; + + if (page_chunks == NULL) { + page_chunks = new LiteMutableArray(8); + } + + LiteCollectionIterator iter(page_chunks); + PageChunk *page = NULL; + while ((page = reinterpret_cast(iter.getNextObject())) != NULL) { + if (page->permission == permission) { + // check the page remain space is enough for the new chunk + if ((page->page_cursor + alloc_size) < ((addr_t)page->page.address + page->page.length)) { + break; + } + } + } + + // alloc a new executable page. + if (!page) { + int pageSize = OSMemory::PageSize(); + void *pageAddress = OSMemory::Allocate(NULL, pageSize, permission); + if (pageAddress == NULL) { + ERROR_LOG("Failed to alloc page"); + return NULL; + } + + PageChunk *newPage = new PageChunk; + newPage->page.address = pageAddress; + newPage->page.length = pageSize; + newPage->page_cursor = (addr_t)pageAddress; + newPage->permission = permission; + newPage->chunks = new LiteMutableArray(8); + MemoryArena::page_chunks->pushObject(reinterpret_cast(newPage)); + page = newPage; + } + + MemoryChunk *chunk = NULL; + if (page) { + chunk = new MemoryChunk; + chunk->address = (void *)page->page_cursor; + chunk->length = alloc_size; + + // update page cursor + page->chunks->pushObject(reinterpret_cast(chunk)); + page->page_cursor += alloc_size; + } + + result = chunk; + return result; +} + +AssemblyCodeChunk *MemoryArena::AllocateCodeChunk(int alloc_size) { + return MemoryArena::AllocateChunk(alloc_size, kReadExecute); +} + +WritableDataChunk *MemoryArena::AllocateDataChunk(int alloc_size) { + return MemoryArena::AllocateChunk(alloc_size, kReadWrite); +} + +// UserMode +// Search code cave from MemoryLayout +// MemoryRegion *CodeChunk::SearchCodeCave(uword pos, uword alloc_range, size_t size) {} diff --git a/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/MemoryArena.h b/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/MemoryArena.h new file mode 100644 index 00000000..0ec6a5f6 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/MemoryArena.h @@ -0,0 +1,54 @@ +#ifndef MemoryAllocator_MemoryArena_h +#define MemoryAllocator_MemoryArena_h + +#include "xnucxx/LiteMutableArray.h" + +#include "PlatformUnifiedInterface/StdMemory.h" + +struct MemoryChunk : MemoryRange { + inline void init_region_range(addr_t address, int size) { + this->address = (void *)address; + this->length = size; + } + + inline void re_init_region_range(addr_t address, int size) { + init_region_range(address, size); + } + + inline void re_init_region_range(MemoryChunk *chunk) { + init_region_range((addr_t)chunk->address, chunk->length); + } + + inline addr_t raw_instruction_start() { + return (addr_t)address; + }; + + inline size_t raw_instruction_size() { + return length; + }; +}; + +typedef MemoryChunk AssemblyCodeChunk, WritableDataChunk; + +typedef struct { + MemoryChunk page; + addr_t page_cursor; + MemoryPermission permission; + LiteMutableArray *chunks; +} PageChunk; + +class MemoryArena { +public: + static MemoryChunk *AllocateChunk(int alloc_size, MemoryPermission permission); + + static WritableDataChunk *AllocateDataChunk(int alloc_size); + + static AssemblyCodeChunk *AllocateCodeChunk(int alloc_size); + + static void Destroy(MemoryChunk *chunk); + +public: + static LiteMutableArray *page_chunks; +}; + +#endif diff --git a/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/NearMemoryArena.cc b/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/NearMemoryArena.cc new file mode 100644 index 00000000..6782cdf3 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/NearMemoryArena.cc @@ -0,0 +1,238 @@ +#include "./NearMemoryArena.h" + +#include "dobby_internal.h" + +#include "UserMode/PlatformUtil/ProcessRuntimeUtility.h" + +#include +#include + +using namespace zz; + +#define KB (1024uLL) +#define MB (1024uLL * KB) +#define GB (1024uLL * MB) + +LiteMutableArray *NearMemoryArena::page_chunks; + +#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 ? NULL : r; + } +} +#endif + +#if 1 +static addr_t search_near_blank_page(addr_t pos, size_t alloc_range) { + addr_t min_page_addr, max_page_addr; + min_page_addr = ALIGN((pos - alloc_range), OSMemory::PageSize()) + OSMemory::PageSize(); + max_page_addr = ALIGN((pos + alloc_range), OSMemory::PageSize()) - OSMemory::PageSize(); + + // region.start sorted + std::vector process_memory_layout = ProcessRuntimeUtility::GetProcessMemoryLayout(); + + /* + * min_page_addr/--special-blank--/==region==/--right-blank--/max_page_addr + */ + + addr_t resultPageAddr = 0, assumePageAddr = min_page_addr; + + // check first region + addr_t first_region_start = (addr_t)process_memory_layout[0].address; + if (min_page_addr < first_region_start) { + resultPageAddr = first_region_start - OSMemory::PageSize(); + resultPageAddr = + (addr_t)OSMemory::Allocate((void *)assumePageAddr, OSMemory::PageSize(), MemoryPermission::kReadExecute); + if (resultPageAddr) + return resultPageAddr; + } + + // check last region + MemoryRegion last_region = process_memory_layout[process_memory_layout.size() - 1]; + addr_t last_region_end = (addr_t)last_region.address + last_region.length; + if (max_page_addr < last_region_end) { + resultPageAddr = last_region_end + OSMemory::PageSize(); + resultPageAddr = + (addr_t)OSMemory::Allocate((void *)assumePageAddr, OSMemory::PageSize(), MemoryPermission::kReadExecute); + if (resultPageAddr) + return resultPageAddr; + } + + for (int i = 0; i < process_memory_layout.size(); ++i) { + MemoryRegion region = process_memory_layout[i]; + // check if assume-page-addr in memory-layout + addr_t region_end = (addr_t)region.address + region.length; + addr_t region_start = (addr_t)region.address; + + if (region_end < max_page_addr) { + if (region_start >= min_page_addr) { + + // find the region locate in the [min_page_addr, max_page_addr] + if (assumePageAddr == min_page_addr) { + MemoryRegion prev_region; + prev_region = process_memory_layout[i - 1]; + addr_t prev_region_end = (addr_t)prev_region.address + prev_region.length; + // check if have blank cave page + if (region_start > prev_region_end) { + assumePageAddr = min_page_addr > prev_region_end ? min_page_addr : prev_region_end; + resultPageAddr = (addr_t)OSMemory::Allocate((void *)assumePageAddr, OSMemory::PageSize(), + MemoryPermission::kReadExecute); + if (resultPageAddr) + break; + } + } + + // right-blank + MemoryRegion next_region = process_memory_layout[i + 1]; + // check if have blank cave page + if (region_end < (addr_t)next_region.address) { + assumePageAddr = (addr_t)region.address + region.length; + resultPageAddr = + (addr_t)OSMemory::Allocate((void *)assumePageAddr, OSMemory::PageSize(), MemoryPermission::kReadExecute); + if (resultPageAddr) + break; + } + } + } + } + return resultPageAddr; +} + +NearMemoryArena::NearMemoryArena() { +} + +static addr_t search_near_blank_memory_chunk(addr_t pos, size_t alloc_range, int alloc_size) { + addr_t min_page_addr, max_page_addr; + min_page_addr = ALIGN((pos - alloc_range), OSMemory::PageSize()) + OSMemory::PageSize(); + max_page_addr = ALIGN((pos + alloc_range), OSMemory::PageSize()) - OSMemory::PageSize(); + + std::vector process_memory_layout = ProcessRuntimeUtility::GetProcessMemoryLayout(); + + uint8_t *blank_chunk_addr = NULL; + for (auto region : process_memory_layout) { + // check if assume-page-addr in memory-layout + if (region.permission == kReadExecute || region.permission == kRead) { + if (((addr_t)region.address + region.length) <= max_page_addr) { + if ((addr_t)region.address >= min_page_addr) { +#if defined(__APPLE__) + if (*(uint32_t *)region.address == 0xfeedfacf) + continue; +#endif + char *blank_memory = (char *)malloc(alloc_size); + memset(blank_memory, 0, alloc_size); +#if defined(__arm__) || defined(__aarch64__) + alloc_size += (4 - 1); + blank_chunk_addr = (uint8_t *)memmem(region.address, region.length, blank_memory, alloc_size); + if (blank_chunk_addr) { + int off = 4 - ((addr_t)blank_chunk_addr % 4); + blank_chunk_addr += off; + } +#else + blank_chunk_addr = (uint8_t *)memmem(region.address, region.length, blank_memory, alloc_size); +#endif + + if (blank_chunk_addr) + break; + } + } + } + } + return (addr_t)blank_chunk_addr; +} +#endif + +int NearMemoryArena::PushPage(addr_t page_addr, MemoryPermission permission) { + PageChunk *newPage = new PageChunk; + newPage->page.address = (void *)page_addr; + newPage->page.length = OSMemory::PageSize(); + newPage->page_cursor = page_addr; + newPage->permission = permission; + newPage->chunks = new LiteMutableArray(8); + NearMemoryArena::page_chunks->pushObject(reinterpret_cast(newPage)); + return RT_SUCCESS; +} + +WritableDataChunk *NearMemoryArena::AllocateDataChunk(addr_t position, size_t alloc_range, int alloc_size) { + return NearMemoryArena::AllocateChunk(position, alloc_range, alloc_size, kReadWrite); +} + +AssemblyCodeChunk *NearMemoryArena::AllocateCodeChunk(addr_t position, size_t alloc_range, int alloc_size) { + return NearMemoryArena::AllocateChunk(position, alloc_range, alloc_size, kReadExecute); +} + +MemoryChunk *NearMemoryArena::AllocateChunk(addr_t position, size_t alloc_range, int alloc_size, + MemoryPermission permission) { + + if (page_chunks == NULL) { + page_chunks = new LiteMutableArray(8); + } + MemoryChunk *result = NULL; + +search_once_more: + LiteCollectionIterator iter(NearMemoryArena::page_chunks); + PageChunk *page = NULL; + while ((page = reinterpret_cast(iter.getNextObject())) != NULL) { + if (page->permission == permission) { + if (llabs((intptr_t)(page->page_cursor - position)) < alloc_range) { + if ((page->page_cursor + alloc_size) < ((addr_t)page->page.address + page->page.length)) { + break; + } + } + } + } + + MemoryChunk *chunk = NULL; + if (page) { + chunk = new MemoryChunk; + chunk->address = (void *)page->page_cursor; + chunk->length = alloc_size; + + // update page cursor + page->chunks->pushObject(reinterpret_cast(chunk)); + page->page_cursor += alloc_size; + return chunk; + } + + addr_t blank_page_addr = 0; + blank_page_addr = search_near_blank_page(position, alloc_range); + if (blank_page_addr) { + OSMemory::SetPermission((void *)blank_page_addr, OSMemory::PageSize(), permission); + NearMemoryArena::PushPage(blank_page_addr, permission); + goto search_once_more; + } + + // TODO: fix up + if (permission == kReadWrite) { + return NULL; + } + + addr_t blank_chunk_addr = 0; + blank_chunk_addr = search_near_blank_memory_chunk(position, alloc_range, alloc_size); + if (blank_chunk_addr) { + MemoryChunk *chunk = NULL; + chunk = new MemoryChunk; + chunk->address = (void *)blank_chunk_addr; + chunk->length = alloc_size; + return chunk; + } + + return NULL; +} diff --git a/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/NearMemoryArena.h b/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/NearMemoryArena.h new file mode 100644 index 00000000..725a9177 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/MemoryAllocator/NearMemoryArena.h @@ -0,0 +1,25 @@ + +#ifndef MemoryAllocator_NearMemoryArena_h +#define MemoryAllocator_NearMemoryArena_h + +#include "MemoryAllocator/MemoryArena.h" + +class NearMemoryArena : public MemoryArena { +public: + NearMemoryArena(); + + static MemoryChunk *AllocateChunk(addr_t position, size_t alloc_range, int alloc_size, MemoryPermission permission); + + static WritableDataChunk *AllocateDataChunk(addr_t position, size_t alloc_range, int alloc_size); + + static AssemblyCodeChunk *AllocateCodeChunk(addr_t position, size_t alloc_range, int alloc_size); + + static int PushPage(addr_t page_addr, MemoryPermission permission); + + static void Destroy(MemoryChunk *chunk); + +private: + static LiteMutableArray *page_chunks; +}; + +#endif diff --git a/Bcore/src/main/cpp/Dobby/source/PlatformUnifiedInterface/ExecMemory/ClearCacheTool.h b/Bcore/src/main/cpp/Dobby/source/PlatformUnifiedInterface/ExecMemory/ClearCacheTool.h new file mode 100644 index 00000000..ee407cb9 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/PlatformUnifiedInterface/ExecMemory/ClearCacheTool.h @@ -0,0 +1,11 @@ +#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/Bcore/src/main/cpp/Dobby/source/PlatformUnifiedInterface/ExecMemory/CodePatchTool.h b/Bcore/src/main/cpp/Dobby/source/PlatformUnifiedInterface/ExecMemory/CodePatchTool.h new file mode 100644 index 00000000..d8ca4b00 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/PlatformUnifiedInterface/ExecMemory/CodePatchTool.h @@ -0,0 +1,9 @@ + +#ifndef PLATFORM_INTERFACE_CODE_PATCH_TOOL_H +#define PLATFORM_INTERFACE_CODE_PATCH_TOOL_H + +#include "PlatformUnifiedInterface/StdMemory.h" + +MemoryOperationError CodePatch(void *address, uint8_t *buffer, uint32_t buffer_size); + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/PlatformUnifiedInterface/StdMemory.h b/Bcore/src/main/cpp/Dobby/source/PlatformUnifiedInterface/StdMemory.h new file mode 100644 index 00000000..384f38cb --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/PlatformUnifiedInterface/StdMemory.h @@ -0,0 +1,21 @@ +#ifndef UNIFIED_INTERFACE_STD_MEMORY_H +#define UNIFIED_INTERFACE_STD_MEMORY_H + +#include "common_header.h" + +enum MemoryPermission { kNoAccess, kRead, kReadWrite, kReadWriteExecute, kReadExecute }; + +typedef struct _MemoryRange { + void *address; + size_t length; +} MemoryRange; + +typedef struct _MemoryRegion { + void *address; + size_t length; + MemoryPermission permission; +} MemoryRegion; + +typedef MemoryRegion MemoryPage; + +#endif diff --git a/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/AssemblyClosureTrampoline.h b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/AssemblyClosureTrampoline.h new file mode 100644 index 00000000..2c904ee4 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/AssemblyClosureTrampoline.h @@ -0,0 +1,42 @@ +#ifndef ASSEMBLY_CLOSURE_TRAMPOLINE_H +#define ASSEMBLY_CLOSURE_TRAMPOLINE_H + +#include "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 _ClosureTrampolineEntry { + void *address; + int size; + void *carry_handler; + void *carry_data; +} ClosureTrampolineEntry; + +void *get_closure_bridge(); + +#ifdef __cplusplus +} +#endif //__cplusplus + +class ClosureTrampoline { +private: + static LiteMutableArray *trampolines_; + +public: + static ClosureTrampolineEntry *CreateClosureTrampoline(void *carry_data, void *carry_handler); +}; + +#endif diff --git a/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/ARMAssemblyClosureTrampoline.cc b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/ARMAssemblyClosureTrampoline.cc new file mode 100644 index 00000000..f38e9266 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/ARMAssemblyClosureTrampoline.cc @@ -0,0 +1,51 @@ +#include "platform_macro.h" +#if defined(TARGET_ARCH_ARM) + +#include "dobby_internal.h" + +#include "core/modules/assembler/assembler-arm.h" + +#include "TrampolineBridge/ClosureTrampolineBridge/AssemblyClosureTrampoline.h" + +using namespace zz; +using namespace zz::arm; + +ClosureTrampolineEntry *ClosureTrampoline::CreateClosureTrampoline(void *carry_data, void *carry_handler) { + ClosureTrampolineEntry *entry = nullptr; + 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. + Code *code = Code::FinalizeCodeFromAddress(closure_trampoline_template, CLOSURE_TRAMPOLINE_SIZE); +#else + +// use assembler and codegen modules instead of template_code +#include "TrampolineBridge/ClosureTrampolineBridge/AssemblyClosureTrampoline.h" +#define _ turbo_assembler_. + TurboAssembler turbo_assembler_(0); + + PseudoLabel entry_label; + PseudoLabel forward_bridge_label; + + _ Ldr(r12, &entry_label); + _ Ldr(pc, &forward_bridge_label); + _ PseudoBind(&entry_label); + _ EmitAddress((uint32_t)entry); + _ PseudoBind(&forward_bridge_label); + _ EmitAddress((uint32_t)get_closure_bridge()); + + AssemblyCodeChunk *code = nullptr; + code = AssemblyCodeBuilder::FinalizeFromTurboAssembler(&turbo_assembler_); + + entry->address = (void *)code->raw_instruction_start(); + entry->size = code->raw_instruction_size(); + entry->carry_data = carry_data; + entry->carry_handler = carry_handler; + + delete code; + return entry; +#endif +} + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/closure-bridge-arm.cc b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/closure-bridge-arm.cc new file mode 100644 index 00000000..9e10d953 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/closure-bridge-arm.cc @@ -0,0 +1,90 @@ +#include "platform_macro.h" +#if defined(TARGET_ARCH_ARM) + +#include "dobby_internal.h" + +#include "core/modules/assembler/assembler-arm.h" + +#include "TrampolineBridge/ClosureTrampolineBridge/common-bridge-handler.h" + +using namespace zz; +using namespace zz::arm; + +static void *closure_bridge = NULL; + +void *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 *)intercept_routing_common_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)); + + AssemblyCodeChunk *code = AssemblyCodeBuilder::FinalizeFromTurboAssembler(&turbo_assembler_); + closure_bridge = (void *)code->raw_instruction_start(); + + DLOG(0, "[closure bridge] Build the closure bridge at %p", closure_bridge); +#endif + return (void *)closure_bridge; +} + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/dummy/closure-bridge-template-arm.cc b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/dummy/closure-bridge-template-arm.cc new file mode 100644 index 00000000..3c1cf0b2 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/dummy/closure-bridge-template-arm.cc @@ -0,0 +1,65 @@ +// .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("intercept_routing_common_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/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/dummy/closure-trampoline-template-arm.S b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/dummy/closure-trampoline-template-arm.S new file mode 100644 index 00000000..6ee7cff1 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/dummy/closure-trampoline-template-arm.S @@ -0,0 +1,40 @@ +// .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/AssemblyClosureTrampoline.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/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/helper-arm.cc b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/helper-arm.cc new file mode 100644 index 00000000..1adb0519 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm/helper-arm.cc @@ -0,0 +1,13 @@ +#include "platform_macro.h" +#if defined(TARGET_ARCH_ARM) + +#include "dobby_internal.h" + +void set_routing_bridge_next_hop(RegisterContext *ctx, void *address) { + *reinterpret_cast(&ctx->general.regs.r12) = address; +} + +void get_routing_bridge_next_hop(RegisterContext *ctx, void *address) { +} + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/ARM64AssemblyClosureTrampoline.cc b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/ARM64AssemblyClosureTrampoline.cc new file mode 100644 index 00000000..0ab57ec5 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/ARM64AssemblyClosureTrampoline.cc @@ -0,0 +1,63 @@ +#include "platform_macro.h" +#if defined(TARGET_ARCH_ARM64) + +#include "dobby_internal.h" + +#include "core/modules/assembler/assembler-arm64.h" + +#include "TrampolineBridge/ClosureTrampolineBridge/AssemblyClosureTrampoline.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 *entry = nullptr; + entry = new ClosureTrampolineEntry; + +#define _ turbo_assembler_. + TurboAssembler turbo_assembler_(0); + + PseudoLabel entry_label; + PseudoLabel forward_bridge_label; + + // 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)entry); + _ PseudoBind(&forward_bridge_label); + _ EmitInt64((uint64_t)get_closure_bridge()); + + AssemblyCodeChunk *code = nullptr; + code = AssemblyCodeBuilder::FinalizeFromTurboAssembler(reinterpret_cast(&turbo_assembler_)); + + entry->address = (void *)code->raw_instruction_start(); + entry->size = code->raw_instruction_size(); + entry->carry_data = carry_data; + entry->carry_handler = carry_handler; + + delete code; + return entry; +} + +#endif diff --git a/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/closure-bridge-arm64.cc b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/closure-bridge-arm64.cc new file mode 100644 index 00000000..d86aa2f1 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/closure-bridge-arm64.cc @@ -0,0 +1,159 @@ +#include "platform_macro.h" +#if defined(TARGET_ARCH_ARM64) + +#include "dobby_internal.h" + +#include "core/modules/assembler/assembler.h" +#include "core/modules/assembler/assembler-arm64.h" + +#include "TrampolineBridge/ClosureTrampolineBridge/common-bridge-handler.h" + +using namespace zz; +using namespace zz::arm64; + +static void *closure_bridge = NULL; + +void *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) +#define MEM_EXT(reg, offset, addrmode) MemOperand(reg, offset, addrmode) + 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(RegisterContext)) +#else +#define REGISTER_CONTEXT_SIZE (sizeof(RegisterContext) - 24 * 16) +#endif + // create function arm64 call convention + _ mov(x0, SP); // arg1: register context + // load package(closure trampoline reserved) + _ ldr(x1, MEM(SP, REGISTER_CONTEXT_SIZE + 0)); // arg2: closure trampoline package + _ CallFunction(ExternalReference((void *)intercept_routing_common_bridge_handler)); + + // restore sp placeholder stack + _ add(SP, SP, 2 * 8); + + // restore x0 + _ ldr(X(0), MEM(SP, 8)); + _ add(SP, SP, 2 * 8); + + // 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 + + AssemblyCodeChunk *code = AssemblyCodeBuilder::FinalizeFromTurboAssembler(&turbo_assembler_); + closure_bridge = (void *)code->raw_instruction_start(); + + DLOG(0, "[closure bridge] Build the closure bridge at %p", closure_bridge); +#endif + return (void *)closure_bridge; +} + +#endif diff --git a/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/dummy/closure-bridge-template-arm64.c b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/dummy/closure-bridge-template-arm64.c new file mode 100644 index 00000000..fdc08931 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/dummy/closure-bridge-template-arm64.c @@ -0,0 +1,103 @@ +#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: RegisterContext stack address + xASM("mov x0, sp"); + xASM("mov x1, x14"); + xASM("bl " xcdecl("intercept_routing_common_bridge_handler")); + + // ======= RegisterContext 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/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/dummy/closure-trampoline-template-arm64.S b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/dummy/closure-trampoline-template-arm64.S new file mode 100644 index 00000000..e80055c0 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/dummy/closure-trampoline-template-arm64.S @@ -0,0 +1,47 @@ +// .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/AssemblyClosureTrampoline.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/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/dummy/dynamic-closure-trampoline-template-arm64.S b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/dummy/dynamic-closure-trampoline-template-arm64.S new file mode 100644 index 00000000..593b57b3 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/dummy/dynamic-closure-trampoline-template-arm64.S @@ -0,0 +1,31 @@ +// .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/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/helper-arm64.cc b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/helper-arm64.cc new file mode 100644 index 00000000..5ff5be48 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/arm64/helper-arm64.cc @@ -0,0 +1,17 @@ +#include "platform_macro.h" +#if defined(TARGET_ARCH_ARM64) + +#include "core/modules/assembler/assembler-arm64.h" + +#include "dobby_internal.h" + +using namespace zz::arm64; + +void set_routing_bridge_next_hop(RegisterContext *ctx, void *address) { + *reinterpret_cast(&ctx->general.x[TMP_REG_0.code()]) = address; +} + +void get_routing_bridge_next_hop(RegisterContext *ctx, void *address) { +} + +#endif diff --git a/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/common-bridge-handler.cc b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/common-bridge-handler.cc new file mode 100644 index 00000000..f50dc8d5 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/common-bridge-handler.cc @@ -0,0 +1,22 @@ + +#include "logging/logging.h" + +#include "TrampolineBridge/ClosureTrampolineBridge/common-bridge-handler.h" + +PUBLIC void intercept_routing_common_bridge_handler(RegisterContext *ctx, ClosureTrampolineEntry *entry) { + DLOG(0, "Catch common bridge handler, carry data: %p, carry handler: %p", (HookEntry *)entry->carry_data, + entry->carry_handler); + + typedef void (*intercept_routing_handler_t)(RegisterContext * ctx, ClosureTrampolineEntry * entry); + intercept_routing_handler_t routing_handler = (intercept_routing_handler_t)entry->carry_handler; + +#if __APPLE__ +#if __has_feature(ptrauth_calls) + routing_handler = + (typeof(routing_handler))__builtin_ptrauth_sign_unauthenticated((void *)routing_handler, ptrauth_key_asia, 0); +#endif +#endif + + routing_handler(ctx, entry); + return; +} diff --git a/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/common-bridge-handler.h b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/common-bridge-handler.h new file mode 100644 index 00000000..d371e314 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/common-bridge-handler.h @@ -0,0 +1,17 @@ +#ifndef CLOSURE_TRAMPOLINE_COMMON_HANDLER_H +#define CLOSURE_TRAMPOLINE_COMMON_HANDLER_H + +#include "dobby_internal.h" + +#include "Interceptor.h" +#include "TrampolineBridge/ClosureTrampolineBridge/AssemblyClosureTrampoline.h" + +extern "C" { +void intercept_routing_common_bridge_handler(RegisterContext *ctx, ClosureTrampolineEntry *entry); +} + +void get_routing_bridge_next_hop(RegisterContext *ctx, void *address); + +void set_routing_bridge_next_hop(RegisterContext *ctx, void *address); + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/X64AssemblyClosureTrampoline.cc b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/X64AssemblyClosureTrampoline.cc new file mode 100644 index 00000000..b33fc7be --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/X64AssemblyClosureTrampoline.cc @@ -0,0 +1,44 @@ +#include "platform_macro.h" +#if defined(TARGET_ARCH_X64) + +#include "dobby_internal.h" + +#include "core/modules/assembler/assembler-x64.h" + +#include "TrampolineBridge/ClosureTrampolineBridge/AssemblyClosureTrampoline.h" + +using namespace zz; +using namespace zz::x64; + +ClosureTrampolineEntry *ClosureTrampoline::CreateClosureTrampoline(void *carry_data, void *carry_handler) { + ClosureTrampolineEntry *entry = nullptr; + entry = new ClosureTrampolineEntry; + + AssemblyCodeChunk *cchunk = MemoryArena::AllocateCodeChunk(32); + if (cchunk == nullptr) { + return NULL; + } +#define _ turbo_assembler_. +#define __ turbo_assembler_.GetCodeBuffer()-> + TurboAssembler turbo_assembler_(0); + + char *push_rip_6 = (char *)"\xff\x35\x06\x00\x00\x00"; + char *jmp_rip_8 = (char *)"\xff\x25\x08\x00\x00\x00"; + + __ EmitBuffer(push_rip_6, 6); + __ EmitBuffer(jmp_rip_8, 6); + __ Emit64((uint64_t)entry); + __ Emit64((uint64_t)get_closure_bridge()); + + entry->address = (void *)cchunk->raw_instruction_start(); + entry->size = cchunk->raw_instruction_size(); + entry->carry_data = carry_data; + entry->carry_handler = carry_handler; + + CodeBufferBase *buffer = reinterpret_cast(turbo_assembler_.GetCodeBuffer()); + CodePatch(cchunk->address, (uint8_t *)buffer->getRawBuffer(), buffer->getSize()); + + return entry; +} + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/closure-bridge-x64.cc b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/closure-bridge-x64.cc new file mode 100644 index 00000000..26ef4ad1 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/closure-bridge-x64.cc @@ -0,0 +1,141 @@ +#include "platform_macro.h" +#if defined(TARGET_ARCH_X64) + +#include "dobby_internal.h" + +#include "core/modules/assembler/assembler-x64.h" + +#include "TrampolineBridge/ClosureTrampolineBridge/common-bridge-handler.h" + +using namespace zz; +using namespace zz::x64; + +static void *closure_bridge = NULL; + +void *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()-> + + char *pushfq = (char *)"\x9c"; + char *popfq = (char *)"\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: RegisterContext 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((void *)"\x48\x89\xE0", 3); + // and rax, 0xF + __ EmitBuffer((void *)"\x48\x83\xE0\x0F", 4); + // cmp rax, 0x0 + __ EmitBuffer((void *)"\x48\x83\xF8\x00", 4); + // jnz [stack_align_call_bridge] + __ EmitBuffer((void *)"\x75\x15", 2); + } + + // LABEL: call_bridge + _ CallFunction(ExternalReference((void *)intercept_routing_common_bridge_handler)); + + // jmp [restore_stack_register] + __ EmitBuffer((void *)"\xE9\x12\x00\x00\x00", 5); + + // LABEL: stack_align_call_bridge + // push rax + __ EmitBuffer((void *)"\x50", 1); + _ CallFunction(ExternalReference((void *)intercept_routing_common_bridge_handler)); + // pop rax + __ EmitBuffer((void *)"\x58", 1); + + // ======= RegisterContext 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(); + + AssemblyCodeChunk *code = AssemblyCodeBuilder::FinalizeFromTurboAssembler(&turbo_assembler_); + closure_bridge = (void *)code->raw_instruction_start(); + + DLOG(0, "[closure bridge] Build the closure bridge at %p", closure_bridge); +#endif + return (void *)closure_bridge; +} + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/dummy/closure-bridge-template-x64.c b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/dummy/closure-bridge-template-x64.c new file mode 100644 index 00000000..ebb38d2d --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/dummy/closure-bridge-template-x64.c @@ -0,0 +1,70 @@ +#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: RegisterContext stack address + xASM("mov rdi, rsp"); + xASM("mov rsi, [rsp-16*8]"); + xASM("call " xcdecl("intercept_routing_common_bridge_handler")); + + // ======= RegisterContext 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/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/dummy/closure-trampoline-template-x64.S b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/dummy/closure-trampoline-template-x64.S new file mode 100644 index 00000000..b24b602a --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/dummy/closure-trampoline-template-x64.S @@ -0,0 +1,23 @@ +#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/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/helper-x64.cc b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/helper-x64.cc new file mode 100644 index 00000000..e0f3da9a --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x64/helper-x64.cc @@ -0,0 +1,17 @@ +#include "platform_macro.h" +#if defined(TARGET_ARCH_X64) + +#include "dobby_internal.h" + +void set_routing_bridge_next_hop(RegisterContext *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(RegisterContext *ctx, void *address) { +} + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x86/X86AssemblyClosureTrampoline.cc b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x86/X86AssemblyClosureTrampoline.cc new file mode 100644 index 00000000..b5c01352 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x86/X86AssemblyClosureTrampoline.cc @@ -0,0 +1,43 @@ +#include "platform_macro.h" +#if defined(TARGET_ARCH_IA32) + +#include "dobby_internal.h" + +#include "core/modules/assembler/assembler-ia32.h" + +#include "TrampolineBridge/ClosureTrampolineBridge/AssemblyClosureTrampoline.h" + +using namespace zz; +using namespace zz::x86; + +ClosureTrampolineEntry *ClosureTrampoline::CreateClosureTrampoline(void *carry_data, void *carry_handler) { + ClosureTrampolineEntry *entry = nullptr; + entry = new ClosureTrampolineEntry; + + AssemblyCodeChunk *cchunk = MemoryArena::AllocateCodeChunk(32); + if (cchunk == nullptr) { + return NULL; + } + +#define _ turbo_assembler_. +#define __ turbo_assembler_.GetCodeBuffer()-> + TurboAssembler turbo_assembler_(cchunk->address); + + int32_t offset = (int32_t)get_closure_bridge() - ((int32_t)cchunk->address + 18); + + _ sub(esp, Immediate(4, 32)); + _ mov(Address(esp, 4 * 0), Immediate((int32_t)entry, 32)); + _ jmp(Immediate(offset, 32)); + + entry->address = (void *)cchunk->raw_instruction_start(); + entry->size = cchunk->raw_instruction_size(); + entry->carry_data = carry_data; + entry->carry_handler = carry_handler; + + CodeBufferBase *buffer = reinterpret_cast(turbo_assembler_.GetCodeBuffer()); + CodePatch(cchunk->address, (uint8_t *)buffer->getRawBuffer(), buffer->getSize()); + + return entry; +} + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x86/closure-bridge-x86.cc b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x86/closure-bridge-x86.cc new file mode 100644 index 00000000..b55edb2e --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x86/closure-bridge-x86.cc @@ -0,0 +1,112 @@ +#include "platform_macro.h" +#if defined(TARGET_ARCH_IA32) + +#include "dobby_internal.h" + +#include "core/modules/assembler/assembler-ia32.h" + +#include "TrampolineBridge/ClosureTrampolineBridge/common-bridge-handler.h" + +using namespace zz; +using namespace zz::x86; + +static void *closure_bridge = NULL; + +void *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()-> + + char *pushfd = (char *)"\x9c"; + char *popfd = (char *)"\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 *)intercept_routing_common_bridge_handler)); + + // ======= RegisterContext 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(); + + AssemblyCodeChunk *code = AssemblyCodeBuilder::FinalizeFromTurboAssembler(&turbo_assembler_); + closure_bridge = (void *)code->raw_instruction_start(); + + DLOG(0, "[closure bridge] Build the closure bridge at %p", closure_bridge); +#endif + return (void *)closure_bridge; +} + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x86/helper-x86.cc b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x86/helper-x86.cc new file mode 100644 index 00000000..75f80fcf --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/ClosureTrampolineBridge/x86/helper-x86.cc @@ -0,0 +1,16 @@ +#include "platform_macro.h" +#if defined(TARGET_ARCH_IA32) + +#include "dobby_internal.h" + +void set_routing_bridge_next_hop(RegisterContext *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(RegisterContext *ctx, void *address) { +} + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/Trampoline.h b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/Trampoline.h new file mode 100644 index 00000000..53f3779b --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/Trampoline.h @@ -0,0 +1,5 @@ +#pragma once + +#include "MemoryAllocator/AssemblyCodeBuilder.h" + +CodeBufferBase *GenerateNormalTrampolineBuffer(addr_t from, addr_t to); \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/arm/trampoline-arm.cc b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/arm/trampoline-arm.cc new file mode 100644 index 00000000..7dfca4db --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/arm/trampoline-arm.cc @@ -0,0 +1,60 @@ +#include "platform_macro.h" +#if defined(TARGET_ARCH_ARM) + +#include "core/modules/assembler/assembler-arm.h" +#include "core/modules/codegen/codegen-arm.h" + +#include "InstructionRelocation/arm/ARMInstructionRelocation.h" + +#include "MemoryAllocator/NearMemoryArena.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 = ALIGN(from, 2); + 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/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/arm64/trampoline-arm64.cc b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/arm64/trampoline-arm64.cc new file mode 100644 index 00000000..139ca400 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/arm64/trampoline-arm64.cc @@ -0,0 +1,125 @@ +#include "platform_macro.h" +#if defined(TARGET_ARCH_ARM64) + +#include "dobby_internal.h" + +#include "core/modules/assembler/assembler-arm64.h" +#include "core/modules/codegen/codegen-arm64.h" + +#include "InstructionRelocation/arm64/ARM64InstructionRelocation.h" + +#include "MemoryAllocator/NearMemoryArena.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); + DLOG(0, "Trampoline use [Adrp, Add, Br] combine"); + } else { + // ldr, br, branch-address + CodeGen codegen(&turbo_assembler_); + codegen.LiteralLdrBranch((uint64_t)to); + DLOG(0, "Trampoline use [Ldr, Br, Label] combine"); + } + + CodeBufferBase *result = NULL; + result = turbo_assembler_.GetCodeBuffer()->Copy(); + return result; +} + +#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, if +static AssemblyCodeChunk *GenerateFastForwardTrampoline(addr_t source_address, addr_t target_address) { + AssemblyCodeChunk *cchunk = NULL; + + TurboAssembler turbo_assembler_(0); + + // Use adrp + add branch + cchunk = NearMemoryArena::AllocateCodeChunk((addr_t)source_address, ARM64_B_XXX_RANGE, 3 * 4); + if (cchunk == nullptr) { + ERROR_LOG("Can't found near code chunk"); + return NULL; + } + + // Use adrp + add branch + uint64_t distance = llabs((int64_t)((addr_t)cchunk->address - target_address)); + uint64_t adrp_range = ((uint64_t)1 << (2 + 19 + 12 - 1)); + if (distance < adrp_range) { // Use adrp + add branch == (3 * 4) trampoline size + _ AdrpAdd(TMP_REG_0, (addr_t)cchunk->address, target_address); + _ br(TMP_REG_0); + DLOG(0, "Forward Trampoline use [Adrp, Add, Br] combine"); + } else { + delete cchunk; + cchunk = NULL; + } + + // Use absolute branch + if (cchunk == NULL) { +#if 0 + // Use literal ldr == (4 * 4) trampoline size + CodeGen codegen(&turbo_assembler_); + // forward trampoline => target address + codegen.LiteralLdrBranch(target_address); + DLOG(0, "Forward Trampoline use [Ldr, Br, Label] combine"); +#else + // Use mov + br == (4 * 5) trampoline size +#define _ turbo_assembler_. + _ Mov(TMP_REG_0, target_address); + _ br(TMP_REG_0); + DLOG(0, "Forward Trampoline use [Mov, Br] combine"); +#endif + + size_t tramp_size = turbo_assembler_.GetCodeBuffer()->getSize(); + cchunk = NearMemoryArena::AllocateCodeChunk((addr_t)source_address, ARM64_B_XXX_RANGE, tramp_size); + if (cchunk == nullptr) { + ERROR_LOG("Can't found near code chunk"); + return NULL; + } + } + + turbo_assembler_.SetRealizedAddress(cchunk->address); + + AssemblyCodeChunk *result = NULL; + result = AssemblyCodeBuilder::FinalizeFromTurboAssembler(&turbo_assembler_); + + { // release + delete cchunk; + } + return result; +} + +CodeBufferBase *GenerateNearTrampolineBuffer(InterceptRouting *routing, addr_t src, addr_t dst) { + CodeBufferBase *result = NULL; + + 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 { + AssemblyCodeChunk *fast_forward_trampoline = NULL; + fast_forward_trampoline = GenerateFastForwardTrampoline(src, dst); + if (!fast_forward_trampoline) + return NULL; + // trampoline => fast_forward_trampoline + addr_t fast_forward_trampoline_addr = fast_forward_trampoline->raw_instruction_start(); + _ b(fast_forward_trampoline_addr - src); + } + + // free the original trampoline + result = turbo_assembler_.GetCodeBuffer()->Copy(); + return result; +} + +#endif diff --git a/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/x64/trampoline-x64.cc b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/x64/trampoline-x64.cc new file mode 100644 index 00000000..252f0034 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/x64/trampoline-x64.cc @@ -0,0 +1,50 @@ +#include "platform_macro.h" +#if defined(TARGET_ARCH_X64) + +#include "dobby_internal.h" + +#include "core/modules/assembler/assembler-x64.h" +#include "core/modules/codegen/codegen-x64.h" + +#include "InstructionRelocation/x64/X64InstructionRelocation.h" + +#include "MemoryAllocator/NearMemoryArena.h" +#include "InterceptRouting/RoutingPlugin/RoutingPlugin.h" + +using namespace zz::x64; + +static void **AllocIndirectStub(addr_t branch_address) { + WritableDataChunk *forwardStub = NULL; + + forwardStub = + NearMemoryArena::AllocateDataChunk((addr_t)branch_address, (size_t)2 * 1024 * 1024 * 1024, (int)sizeof(void *)); + if (forwardStub == nullptr) { + ERROR_LOG("Not found near forward stub"); + return NULL; + } + + return (void **)forwardStub->address; +} + +CodeBufferBase *GenerateNormalTrampolineBuffer(addr_t from, addr_t to) { + TurboAssembler turbo_assembler_((void *)from); +#define _ turbo_assembler_. + + // branch + void **branch_stub = AllocIndirectStub(from); + *branch_stub = (void *)to; + + CodeGen codegen(&turbo_assembler_); + codegen.JmpNearIndirect((uint64_t)branch_stub); + + CodeBufferBase *result = NULL; + result = turbo_assembler_.GetCodeBuffer()->Copy(); + return result; +} + +CodeBufferBase *GenerateNearTrampolineBuffer(InterceptRouting *routing, addr_t src, addr_t dst) { + DLOG(0, "x64 near branch trampoline enable default"); + return NULL; +} + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/x86/trampoline-x86.cc b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/x86/trampoline-x86.cc new file mode 100644 index 00000000..f86ceac9 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/TrampolineBridge/Trampoline/x86/trampoline-x86.cc @@ -0,0 +1,33 @@ +#include "platform_macro.h" +#if defined(TARGET_ARCH_IA32) + +#include "dobby_internal.h" + +#include "core/modules/assembler/assembler-ia32.h" +#include "core/modules/codegen/codegen-ia32.h" + +#include "InstructionRelocation/x86/X86InstructionRelocation.h" + +#include "MemoryAllocator/NearMemoryArena.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) { + DLOG(0, "x86 near branch trampoline enable default"); + return NULL; +} + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/clear-cache-tool-all.c b/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/clear-cache-tool-all.c new file mode 100644 index 00000000..7479587b --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/clear-cache-tool-all.c @@ -0,0 +1,165 @@ +//===-- 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 + +#if defined(__FreeBSD__) && defined(__arm__) +// clang-format off +#include +#include +// clang-format on +#endif + +#if defined(__NetBSD__) && defined(__arm__) +#include +#endif + +#if defined(__OpenBSD__) && (defined(__arm__) || defined(__mips__)) +// clang-format off +#include +#include +// clang-format on +#endif + +#if defined(__linux__) && defined(__mips__) +#include +#include +#include +#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("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__) +#define __NR_riscv_flush_icache (244 + 15) + register void * start_reg __asm("a0") = start; + const register void *end_reg __asm("a1") = end; + 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); +#else + compilerrt_abort(); +#endif +#endif +} + +void ClearCache(void *start, void *end) { + return __clear_cache(start, end); +} diff --git a/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/clear-cache-tool/clear-cache-tool-arm-dummy.cc b/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/clear-cache-tool/clear-cache-tool-arm-dummy.cc new file mode 100644 index 00000000..abe26c45 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/clear-cache-tool/clear-cache-tool-arm-dummy.cc @@ -0,0 +1,53 @@ +#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/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/clear-cache-tool/clear-cache-tool-arm64-dummy.cc b/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/clear-cache-tool/clear-cache-tool-arm64-dummy.cc new file mode 100644 index 00000000..60580a5c --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/clear-cache-tool/clear-cache-tool-arm64-dummy.cc @@ -0,0 +1,103 @@ +#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/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/code-patch-tool-darwin.cc b/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/code-patch-tool-darwin.cc new file mode 100644 index 00000000..16312a81 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/code-patch-tool-darwin.cc @@ -0,0 +1,128 @@ +#include "dobby_internal.h" +#include "core/arch/Cpu.h" +#include "PlatformUnifiedInterface/ExecMemory/ClearCacheTool.h" +#include "UnifiedInterface/platform.h" + +#include + +#ifdef __APPLE__ +#include +#include +#include +#include +#include "UserMode/UnifiedInterface/platform-darwin/mach_vm.h" +#endif + +#if defined(__APPLE__) +#include +#include +#endif + +#include "logging/check_logging.h" + +#include "platform_macro.h" + +#if defined(CODE_PATCH_WITH_SUBSTRATED) && defined(TARGET_ARCH_ARM64) +#include +#include "bootstrap.h" +#include "ExecMemory/substrated/mach_interface_support/substrated_client.h" + +#define KERN_ERROR_RETURN(err, failure) \ + do { \ + if (err != KERN_SUCCESS) { \ + return failure; \ + } \ + } while (0); + +static mach_port_t substrated_server_port = MACH_PORT_NULL; + +static mach_port_t connect_mach_service(const char *name) { + mach_port_t port = MACH_PORT_NULL; + kern_return_t kr; + +#if 0 + kr = task_get_special_port(mach_task_self(), TASK_BOOTSTRAP_PORT, &bootstrap_port); + KERN_ERROR_RETURN(kr, MACH_PORT_NULL) +#endif + + kr = bootstrap_look_up(bootstrap_port, (char *)name, &port); + KERN_ERROR_RETURN(kr, MACH_PORT_NULL); + + substrated_server_port = port; + + return port; +} + +int code_remap_with_substrated(uint8_t *buffer, uint32_t buffer_size, addr_t address) { + if (!MACH_PORT_VALID(substrated_server_port)) { + substrated_server_port = connect_mach_service("cy:com.saurik.substrated"); + } + if (!MACH_PORT_VALID(substrated_server_port)) + return -1; + + kern_return_t kr; + kr = substrated_mark(substrated_server_port, mach_task_self(), (mach_vm_address_t)buffer, buffer_size, + (mach_vm_address_t *)&address); + if (kr != KERN_SUCCESS) { + return RT_FAILED; + } + return RT_SUCCESS; +} +#endif + +PUBLIC MemoryOperationError CodePatch(void *address, uint8_t *buffer, uint32_t buffer_size) { + kern_return_t kr; + + int page_size = (int)sysconf(_SC_PAGESIZE); + addr_t page_aligned_address = ALIGN_FLOOR(address, page_size); + int offset = (int)((addr_t)address - page_aligned_address); + + static mach_port_t self_port = mach_task_self(); +#ifdef __APPLE__ + // try modify with substrated (steal from frida-gum) + addr_t remap_dummy_page = + (addr_t)mmap(0, page_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, VM_MAKE_TAG(255), 0); + if ((void *)remap_dummy_page == MAP_FAILED) + return kMemoryOperationError; + + // copy original page + memcpy((void *)remap_dummy_page, (void *)page_aligned_address, page_size); + + // patch buffer + memcpy((void *)(remap_dummy_page + offset), buffer, buffer_size); + + // change permission + mprotect((void *)remap_dummy_page, page_size, PROT_READ | PROT_WRITE); + + int ret = RT_FAILED; +#if 0 && defined(CODE_PATCH_WITH_SUBSTRATED) && defined(TARGET_ARCH_ARM64) + ret = code_remap_with_substrated((uint8_t *)remap_dummy_page, (uint32_t)page_size, (addr_t)page_aligned_address); + if (0 && ret == RT_FAILED) + DLOG(0, "substrated failed, use vm_remap"); +#endif + if (ret == RT_FAILED) { + mprotect((void *)remap_dummy_page, page_size, PROT_READ | PROT_EXEC); + mach_vm_address_t remap_dest_page = (mach_vm_address_t)page_aligned_address; + vm_prot_t curr_protection, max_protection; + kr = mach_vm_remap(self_port, (mach_vm_address_t *)&remap_dest_page, page_size, 0, + VM_FLAGS_OVERWRITE | VM_FLAGS_FIXED, self_port, (mach_vm_address_t)remap_dummy_page, TRUE, + &curr_protection, &max_protection, VM_INHERIT_COPY); + if (kr != KERN_SUCCESS) { + return kMemoryOperationError; + } + } + + // unmap the origin page + int err = munmap((void *)remap_dummy_page, (mach_vm_address_t)page_size); + if (err == -1) { + return kMemoryOperationError; + } + +#endif + + addr_t clear_start = (addr_t)page_aligned_address + offset; + DCHECK_EQ(clear_start, (addr_t)address); + + ClearCache((void *)address, (void *)((addr_t)address + buffer_size)); + return kMemoryOperationSuccess; +} diff --git a/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/code-patch-tool-posix.cc b/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/code-patch-tool-posix.cc new file mode 100644 index 00000000..1badae18 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/code-patch-tool-posix.cc @@ -0,0 +1,34 @@ + +#include "dobby_internal.h" +#include "core/arch/Cpu.h" + +#include +#include +#include + +#if !defined(__APPLE__) +PUBLIC MemoryOperationError CodePatch(void *address, uint8_t *buffer, uint32_t buffer_size) { + + int page_size = (int)sysconf(_SC_PAGESIZE); + uintptr_t page_align_address = ALIGN_FLOOR(address, page_size); + int offset = (uintptr_t)address - page_align_address; + +#if defined(__ANDROID__) || defined(__linux__) + + // change page permission as rwx + mprotect((void *)page_align_address, page_size, PROT_READ | PROT_WRITE | PROT_EXEC); + + // patch buffer + memcpy((void *)((addr_t)page_align_address + offset), buffer, buffer_size); + + // restore page permission + mprotect((void *)page_align_address, page_size, PROT_READ | PROT_EXEC); +#endif + + addr_t clear_start_ = (addr_t)page_align_address + offset; + ClearCache((void *)clear_start_, (void *)(clear_start_ + buffer_size)); + + return kMemoryOperationSuccess; +} + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/code-patch-tool-windows.cc b/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/code-patch-tool-windows.cc new file mode 100644 index 00000000..a58e46f3 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/code-patch-tool-windows.cc @@ -0,0 +1,27 @@ +#include "dobby_internal.h" + +#include + +using namespace zz; + +PUBLIC MemoryOperationError CodePatch(void *address, uint8_t *buffer, uint32_t buffer_size) { + DWORD oldProtect; + int pageSize; + + // Get page size + SYSTEM_INFO si; + GetSystemInfo(&si); + pageSize = si.dwPageSize; + + void *addressPageAlign = (void *)ALIGN(address, pageSize); + + if (!VirtualProtect(addressPageAlign, pageSize, PAGE_EXECUTE_READWRITE, &oldProtect)) + return kMemoryOperationError; + + memcpy(address, buffer, buffer_size); + + if (!VirtualProtect(addressPageAlign, pageSize, oldProtect, &oldProtect)) + return kMemoryOperationError; + + return kMemoryOperationSuccess; +} diff --git a/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/substrated/include/bootstrap.h b/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/substrated/include/bootstrap.h new file mode 100644 index 00000000..0cb0acf2 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/substrated/include/bootstrap.h @@ -0,0 +1,91 @@ +#ifndef __XPC_BOOTSTRAP_H__ +#define __XPC_BOOTSTRAP_H__ + +#ifndef __XPC_INDIRECT__ +#define __XPC_INDIRECT__ +#endif // __XPC_INDIRECT__ + +#include +#include + +// +#include + +__BEGIN_DECLS; + +#include +#include +#include +#include + +#define BOOTSTRAP_MAX_NAME_LEN 128 +#define BOOTSTRAP_MAX_CMD_LEN 512 + +typedef char name_t[BOOTSTRAP_MAX_NAME_LEN]; +typedef char cmd_t[BOOTSTRAP_MAX_CMD_LEN]; +typedef name_t *name_array_t; +typedef int bootstrap_status_t; +typedef bootstrap_status_t *bootstrap_status_array_t; +typedef unsigned int bootstrap_property_t; +typedef bootstrap_property_t *bootstrap_property_array_t; + +typedef boolean_t *bool_array_t; + +#define BOOTSTRAP_MAX_LOOKUP_COUNT 20 + +#define BOOTSTRAP_SUCCESS 0 +#define BOOTSTRAP_NOT_PRIVILEGED 1100 +#define BOOTSTRAP_NAME_IN_USE 1101 +#define BOOTSTRAP_UNKNOWN_SERVICE 1102 +#define BOOTSTRAP_SERVICE_ACTIVE 1103 +#define BOOTSTRAP_BAD_COUNT 1104 +#define BOOTSTRAP_NO_MEMORY 1105 +#define BOOTSTRAP_NO_CHILDREN 1106 + +#define BOOTSTRAP_STATUS_INACTIVE 0 +#define BOOTSTRAP_STATUS_ACTIVE 1 +#define BOOTSTRAP_STATUS_ON_DEMAND 2 + +XPC_EXPORT +mach_port_t bootstrap_port; + +__OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_7_0) +XPC_EXPORT XPC_WARN_RESULT XPC_NONNULL5 kern_return_t bootstrap_create_server(mach_port_t bp, cmd_t server_cmd, + uid_t server_uid, boolean_t on_demand, + mach_port_t *server_port); + +__OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_10, __IPHONE_2_0, __IPHONE_7_0) +XPC_EXPORT XPC_WARN_RESULT XPC_NONNULL3 kern_return_t bootstrap_subset(mach_port_t bp, mach_port_t requestor_port, + mach_port_t *subset_port); + +__OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_5, __IPHONE_2_0, __IPHONE_7_0) +XPC_EXPORT XPC_WARN_RESULT XPC_NONNULL2 kern_return_t bootstrap_unprivileged(mach_port_t bp, mach_port_t *unpriv_port); + +__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) +XPC_EXPORT XPC_WARN_RESULT XPC_NONNULL2 kern_return_t bootstrap_parent(mach_port_t bp, mach_port_t *parent_port); + +__OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_5, __IPHONE_2_0, __IPHONE_7_0) +XPC_EXPORT XPC_WARN_RESULT kern_return_t bootstrap_register(mach_port_t bp, name_t service_name, mach_port_t sp); + +__OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_6, __IPHONE_2_0, __IPHONE_7_0) +XPC_EXPORT XPC_WARN_RESULT XPC_NONNULL3 kern_return_t bootstrap_create_service(mach_port_t bp, name_t service_name, + mach_port_t *sp); + +__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) +XPC_EXPORT XPC_WARN_RESULT XPC_NONNULL3 kern_return_t bootstrap_check_in(mach_port_t bp, const name_t service_name, + mach_port_t *sp); + +// Once is fixed, we can add back in XPC_WARN_RESULT. +__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) +XPC_EXPORT XPC_NONNULL3 kern_return_t bootstrap_look_up(mach_port_t bp, const name_t service_name, mach_port_t *sp); + +__OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_4, __MAC_10_5, __IPHONE_2_0, __IPHONE_7_0) +XPC_EXPORT XPC_WARN_RESULT XPC_NONNULL2 kern_return_t bootstrap_status(mach_port_t bp, name_t service_name, + bootstrap_status_t *service_active); + +__OSX_AVAILABLE_STARTING(__MAC_10_4, __IPHONE_2_0) +XPC_EXPORT XPC_WARN_RESULT const char *bootstrap_strerror(kern_return_t r); + +__END_DECLS; + +#endif // __XPC_BOOTSTRAP_H__ diff --git a/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/substrated/include/xpc/base.h b/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/substrated/include/xpc/base.h new file mode 100644 index 00000000..87b84dbc --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/substrated/include/xpc/base.h @@ -0,0 +1,202 @@ +// Copyright (c) 2009-2011 Apple Inc. All rights reserved. + +#ifndef __XPC_BASE_H__ +#define __XPC_BASE_H__ + +#include + +__BEGIN_DECLS + +#if !defined(__has_include) +#define __has_include(x) 0 +#endif // !defined(__has_include) + +#if !defined(__has_attribute) +#define __has_attribute(x) 0 +#endif // !defined(__has_attribute) + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif // !defined(__has_feature) + +#if !defined(__has_extension) +#define __has_extension(x) 0 +#endif // !defined(__has_extension) + +#if __has_include() +#include +#else // __has_include() +#include +#endif // __has_include() + +#if XPC_SERVICE_MAIN_IN_LIBXPC +#define XPC_HOSTING_OLD_MAIN 1 +#else // XPC_SERVICE_MAIN_IN_LIBXPC +#define XPC_HOSTING_OLD_MAIN 0 +#endif // XPC_SERVICE_MAIN_IN_LIBXPC + +#ifndef __XPC_INDIRECT__ +#error "Please #include instead of this file directly." +#endif // __XPC_INDIRECT__ + +#pragma mark Attribute Shims +#ifdef __GNUC__ +#define XPC_CONSTRUCTOR __attribute__((constructor)) +#define XPC_NORETURN __attribute__((__noreturn__)) +#define XPC_NOTHROW __attribute__((__nothrow__)) +#define XPC_NONNULL1 __attribute__((__nonnull__(1))) +#define XPC_NONNULL2 __attribute__((__nonnull__(2))) +#define XPC_NONNULL3 __attribute__((__nonnull__(3))) +#define XPC_NONNULL4 __attribute__((__nonnull__(4))) +#define XPC_NONNULL5 __attribute__((__nonnull__(5))) +#define XPC_NONNULL6 __attribute__((__nonnull__(6))) +#define XPC_NONNULL7 __attribute__((__nonnull__(7))) +#define XPC_NONNULL8 __attribute__((__nonnull__(8))) +#define XPC_NONNULL9 __attribute__((__nonnull__(9))) +#define XPC_NONNULL10 __attribute__((__nonnull__(10))) +#define XPC_NONNULL11 __attribute__((__nonnull__(11))) +#define XPC_NONNULL_ALL __attribute__((__nonnull__)) +#define XPC_SENTINEL __attribute__((__sentinel__)) +#define XPC_PURE __attribute__((__pure__)) +#define XPC_WARN_RESULT __attribute__((__warn_unused_result__)) +#define XPC_MALLOC __attribute__((__malloc__)) +#define XPC_UNUSED __attribute__((__unused__)) +#define XPC_USED __attribute__((__used__)) +#define XPC_PACKED __attribute__((__packed__)) +#define XPC_PRINTF(m, n) __attribute__((format(printf, m, n))) +#define XPC_INLINE static __inline__ __attribute__((__always_inline__)) +#define XPC_NOINLINE __attribute__((noinline)) +#define XPC_NOIMPL __attribute__((unavailable)) + +#if __has_attribute(noescape) +#define XPC_NOESCAPE __attribute__((__noescape__)) +#else +#define XPC_NOESCAPE +#endif + +#if __has_extension(attribute_unavailable_with_message) +#define XPC_UNAVAILABLE(m) __attribute__((unavailable(m))) +#else // __has_extension(attribute_unavailable_with_message) +#define XPC_UNAVAILABLE(m) XPC_NOIMPL +#endif // __has_extension(attribute_unavailable_with_message) + +#define XPC_EXPORT extern __attribute__((visibility("default"))) +#define XPC_NOEXPORT __attribute__((visibility("hidden"))) +#define XPC_WEAKIMPORT extern __attribute__((weak_import)) +#define XPC_DEBUGGER_EXCL XPC_NOEXPORT XPC_USED +#define XPC_TRANSPARENT_UNION __attribute__((transparent_union)) +#if __clang__ +#define XPC_DEPRECATED(m) __attribute__((deprecated(m))) +#else // __clang__ +#define XPC_DEPRECATED(m) __attribute__((deprecated)) +#endif // __clang + +#if __XPC_TEST__ +#define XPC_TESTSTATIC +#define XPC_TESTEXTERN(x) extern x +#else // __XPC_TEST__ +#define XPC_TESTSTATIC static +#define XPC_TESTEXTERN(x) +#endif // __XPC_TEST__ + +#if __has_feature(objc_arc) +#define XPC_GIVES_REFERENCE __strong +#define XPC_UNRETAINED __unsafe_unretained +#define XPC_BRIDGE(xo) ((__bridge void *)(xo)) +#define XPC_BRIDGEREF_BEGIN(xo) ((__bridge_retained void *)(xo)) +#define XPC_BRIDGEREF_BEGIN_WITH_REF(xo) ((__bridge void *)(xo)) +#define XPC_BRIDGEREF_MIDDLE(xo) ((__bridge id)(xo)) +#define XPC_BRIDGEREF_END(xo) ((__bridge_transfer id)(xo)) +#else // __has_feature(objc_arc) +#define XPC_GIVES_REFERENCE +#define XPC_UNRETAINED +#define XPC_BRIDGE(xo) (xo) +#define XPC_BRIDGEREF_BEGIN(xo) (xo) +#define XPC_BRIDGEREF_BEGIN_WITH_REF(xo) (xo) +#define XPC_BRIDGEREF_MIDDLE(xo) (xo) +#define XPC_BRIDGEREF_END(xo) (xo) +#endif // __has_feature(objc_arc) + +#define _xpc_unreachable() __builtin_unreachable() +#else // __GNUC__ +/*! @parseOnly */ +#define XPC_CONSTRUCTOR +/*! @parseOnly */ +#define XPC_NORETURN +/*! @parseOnly */ +#define XPC_NOTHROW +/*! @parseOnly */ +#define XPC_NONNULL1 +/*! @parseOnly */ +#define XPC_NONNULL2 +/*! @parseOnly */ +#define XPC_NONNULL3 +/*! @parseOnly */ +#define XPC_NONNULL4 +/*! @parseOnly */ +#define XPC_NONNULL5 +/*! @parseOnly */ +#define XPC_NONNULL6 +/*! @parseOnly */ +#define XPC_NONNULL7 +/*! @parseOnly */ +#define XPC_NONNULL8 +/*! @parseOnly */ +#define XPC_NONNULL9 +/*! @parseOnly */ +#define XPC_NONNULL10 +/*! @parseOnly */ +#define XPC_NONNULL11 +/*! @parseOnly */ +#define XPC_NONNULL(n) +/*! @parseOnly */ +#define XPC_NONNULL_ALL +/*! @parseOnly */ +#define XPC_SENTINEL +/*! @parseOnly */ +#define XPC_PURE +/*! @parseOnly */ +#define XPC_WARN_RESULT +/*! @parseOnly */ +#define XPC_MALLOC +/*! @parseOnly */ +#define XPC_UNUSED +/*! @parseOnly */ +#define XPC_PACKED +/*! @parseOnly */ +#define XPC_PRINTF(m, n) +/*! @parseOnly */ +#define XPC_INLINE static inline +/*! @parseOnly */ +#define XPC_NOINLINE +/*! @parseOnly */ +#define XPC_NOIMPL +/*! @parseOnly */ +#define XPC_EXPORT extern +/*! @parseOnly */ +#define XPC_WEAKIMPORT +/*! @parseOnly */ +#define XPC_DEPRECATED +/*! @parseOnly */ +#define XPC_UNAVAILABLE(m) +/*! @parseOnly */ +#define XPC_NOESCAPE +#endif // __GNUC__ + +#if __has_feature(assume_nonnull) +#define XPC_ASSUME_NONNULL_BEGIN _Pragma("clang assume_nonnull begin") +#define XPC_ASSUME_NONNULL_END _Pragma("clang assume_nonnull end") +#else +#define XPC_ASSUME_NONNULL_BEGIN +#define XPC_ASSUME_NONNULL_END +#endif + +#if __has_feature(nullability_on_arrays) +#define XPC_NONNULL_ARRAY _Nonnull +#else +#define XPC_NONNULL_ARRAY +#endif + +__END_DECLS + +#endif // __XPC_BASE_H__ diff --git a/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/substrated/mach_interface_support/substrated.defs b/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/substrated/mach_interface_support/substrated.defs new file mode 100755 index 00000000..f8b1640a --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/substrated/mach_interface_support/substrated.defs @@ -0,0 +1,24 @@ +/* + * 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/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/substrated/mach_interface_support/substrated_client.c b/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/substrated/mach_interface_support/substrated_client.c new file mode 100644 index 00000000..d63af0d2 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/substrated/mach_interface_support/substrated_client.c @@ -0,0 +1,311 @@ +/* + * IDENTIFICATION: + * stub generated Tue Jan 7 03:06:18 2020 + * with a MiG generated by bootstrap_cmds-116 + * OPTIONS: + */ +#define __MIG_check__Reply__substrated_subsystem__ 1 + +#include "substrated_client.h" + +/* TODO: #include */ +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ +extern void mach_msg_destroy(mach_msg_header_t *); +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#ifndef mig_internal +#define mig_internal static __inline__ +#endif /* mig_internal */ + +#ifndef mig_external +#define mig_external +#endif /* mig_external */ + +#if !defined(__MigTypeCheck) && defined(TypeCheck) +#define __MigTypeCheck TypeCheck /* Legacy setting */ +#endif /* !defined(__MigTypeCheck) */ + +#if !defined(__MigKernelSpecificCode) && defined(_MIG_KERNEL_SPECIFIC_CODE_) +#define __MigKernelSpecificCode _MIG_KERNEL_SPECIFIC_CODE_ /* Legacy setting */ +#endif /* !defined(__MigKernelSpecificCode) */ + +#ifndef LimitCheck +#define LimitCheck 0 +#endif /* LimitCheck */ + +#ifndef min +#define min(a,b) ( ((a) < (b))? (a): (b) ) +#endif /* min */ + +#if !defined(_WALIGN_) +#define _WALIGN_(x) (((x) + 3) & ~3) +#endif /* !defined(_WALIGN_) */ + +#if !defined(_WALIGNSZ_) +#define _WALIGNSZ_(x) _WALIGN_(sizeof(x)) +#endif /* !defined(_WALIGNSZ_) */ + +#ifndef UseStaticTemplates +#define UseStaticTemplates 0 +#endif /* UseStaticTemplates */ + +#ifndef MIG_SERVER_ROUTINE +#define MIG_SERVER_ROUTINE +#endif + +#ifndef __MachMsgErrorWithTimeout +#define __MachMsgErrorWithTimeout(_R_) { \ + switch (_R_) { \ + case MACH_SEND_INVALID_DATA: \ + case MACH_SEND_INVALID_DEST: \ + case MACH_SEND_INVALID_HEADER: \ + mig_put_reply_port(InP->Head.msgh_reply_port); \ + break; \ + case MACH_SEND_TIMED_OUT: \ + case MACH_RCV_TIMED_OUT: \ + default: \ + mig_dealloc_reply_port(InP->Head.msgh_reply_port); \ + } \ +} +#endif /* __MachMsgErrorWithTimeout */ + +#ifndef __MachMsgErrorWithoutTimeout +#define __MachMsgErrorWithoutTimeout(_R_) { \ + switch (_R_) { \ + case MACH_SEND_INVALID_DATA: \ + case MACH_SEND_INVALID_DEST: \ + case MACH_SEND_INVALID_HEADER: \ + mig_put_reply_port(InP->Head.msgh_reply_port); \ + break; \ + default: \ + mig_dealloc_reply_port(InP->Head.msgh_reply_port); \ + } \ +} +#endif /* __MachMsgErrorWithoutTimeout */ + +#ifndef __DeclareSendRpc +#define __DeclareSendRpc(_NUM_, _NAME_) +#endif /* __DeclareSendRpc */ + +#ifndef __BeforeSendRpc +#define __BeforeSendRpc(_NUM_, _NAME_) +#endif /* __BeforeSendRpc */ + +#ifndef __AfterSendRpc +#define __AfterSendRpc(_NUM_, _NAME_) +#endif /* __AfterSendRpc */ + +#ifndef __DeclareSendSimple +#define __DeclareSendSimple(_NUM_, _NAME_) +#endif /* __DeclareSendSimple */ + +#ifndef __BeforeSendSimple +#define __BeforeSendSimple(_NUM_, _NAME_) +#endif /* __BeforeSendSimple */ + +#ifndef __AfterSendSimple +#define __AfterSendSimple(_NUM_, _NAME_) +#endif /* __AfterSendSimple */ + +#define msgh_request_port msgh_remote_port +#define msgh_reply_port msgh_local_port + + + +#if ( __MigTypeCheck ) +#if __MIG_check__Reply__substrated_subsystem__ +#if !defined(__MIG_check__Reply__substrated_mark_t__defined) +#define __MIG_check__Reply__substrated_mark_t__defined + +mig_internal kern_return_t __MIG_check__Reply__substrated_mark_t(__Reply__substrated_mark_t *Out0P) +{ + + typedef __Reply__substrated_mark_t __Reply __attribute__((unused)); +#if __MigTypeCheck + unsigned int msgh_size; +#endif /* __MigTypeCheck */ + if (Out0P->Head.msgh_id != 9100) { + if (Out0P->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) + { return MIG_SERVER_DIED; } + else + { return MIG_REPLY_MISMATCH; } + } + +#if __MigTypeCheck + msgh_size = Out0P->Head.msgh_size; + + if ((Out0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || + ((msgh_size != (mach_msg_size_t)sizeof(__Reply)) && + (msgh_size != (mach_msg_size_t)sizeof(mig_reply_error_t) || + Out0P->RetCode == KERN_SUCCESS))) + { return MIG_TYPE_ERROR ; } +#endif /* __MigTypeCheck */ + +#if __MigTypeCheck + if (Out0P->Head.msgh_request_port != MACH_PORT_NULL) { + return MIG_TYPE_ERROR; + } +#endif /* __MigTypeCheck */ + if (Out0P->RetCode != KERN_SUCCESS) { + return ((mig_reply_error_t *)Out0P)->RetCode; + } + + return MACH_MSG_SUCCESS; +} +#endif /* !defined(__MIG_check__Reply__substrated_mark_t__defined) */ +#endif /* __MIG_check__Reply__substrated_subsystem__ */ +#endif /* ( __MigTypeCheck ) */ + + +/* Routine substrated_mark */ +mig_external kern_return_t substrated_mark +( + mach_port_t server, + vm_map_t task, + mach_vm_address_t source_address, + mach_vm_size_t source_size, + mach_vm_address_t *target_address +) +{ + +#ifdef __MigPackStructs +#pragma pack(push, 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 task; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_vm_address_t source_address; + mach_vm_size_t source_size; + mach_vm_address_t target_address; + } Request __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_vm_address_t target_address; + mach_msg_trailer_t trailer; + } Reply __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif + typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_vm_address_t target_address; + } __Reply __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + /* + * typedef struct { + * mach_msg_header_t Head; + * NDR_record_t NDR; + * kern_return_t RetCode; + * } mig_reply_error_t; + */ + + union { + Request In; + Reply Out; + } Mess; + + Request *InP = &Mess.In; + Reply *Out0P = &Mess.Out; + + mach_msg_return_t msg_result; + +#ifdef __MIG_check__Reply__substrated_mark_t__defined + kern_return_t check_result; +#endif /* __MIG_check__Reply__substrated_mark_t__defined */ + + __DeclareSendRpc(9000, "substrated_mark") + +#if UseStaticTemplates + const static mach_msg_port_descriptor_t taskTemplate = { + /* name = */ MACH_PORT_NULL, + /* pad1 = */ 0, + /* pad2 = */ 0, + /* disp = */ 19, + /* type = */ MACH_MSG_PORT_DESCRIPTOR, + }; +#endif /* UseStaticTemplates */ + + InP->msgh_body.msgh_descriptor_count = 1; +#if UseStaticTemplates + InP->task = taskTemplate; + InP->task.name = task; +#else /* UseStaticTemplates */ + InP->task.name = task; + InP->task.disposition = 19; + InP->task.type = MACH_MSG_PORT_DESCRIPTOR; +#endif /* UseStaticTemplates */ + + InP->NDR = NDR_record; + + InP->source_address = source_address; + + InP->source_size = source_size; + + InP->target_address = *target_address; + + InP->Head.msgh_bits = MACH_MSGH_BITS_COMPLEX| + MACH_MSGH_BITS(19, MACH_MSG_TYPE_MAKE_SEND_ONCE); + /* msgh_size passed as argument */ + InP->Head.msgh_request_port = server; + InP->Head.msgh_reply_port = mig_get_reply_port(); + InP->Head.msgh_id = 9000; + InP->Head.msgh_reserved = 0; + +/* BEGIN VOUCHER CODE */ + +#ifdef USING_VOUCHERS + if (voucher_mach_msg_set != NULL) { + voucher_mach_msg_set(&InP->Head); + } +#endif // USING_VOUCHERS + +/* END VOUCHER CODE */ + + __BeforeSendRpc(9000, "substrated_mark") + msg_result = mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, (mach_msg_size_t)sizeof(Request), (mach_msg_size_t)sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); + __AfterSendRpc(9000, "substrated_mark") + if (msg_result != MACH_MSG_SUCCESS) { + __MachMsgErrorWithoutTimeout(msg_result); + } + if (msg_result != MACH_MSG_SUCCESS) { + { return msg_result; } + } + + +#if defined(__MIG_check__Reply__substrated_mark_t__defined) + check_result = __MIG_check__Reply__substrated_mark_t((__Reply__substrated_mark_t *)Out0P); + if (check_result != MACH_MSG_SUCCESS) { + mach_msg_destroy(&Out0P->Head); + { return check_result; } + } +#endif /* defined(__MIG_check__Reply__substrated_mark_t__defined) */ + + *target_address = Out0P->target_address; + + return KERN_SUCCESS; +} diff --git a/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/substrated/mach_interface_support/substrated_client.h b/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/substrated/mach_interface_support/substrated_client.h new file mode 100644 index 00000000..8c44b3fb --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/substrated/mach_interface_support/substrated_client.h @@ -0,0 +1,182 @@ +#ifndef _substrated_user_ +#define _substrated_user_ + +/* Module substrated */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* BEGIN VOUCHER CODE */ + +#ifndef KERNEL +#if defined(__has_include) +#if __has_include() +#ifndef USING_VOUCHERS +#define USING_VOUCHERS +#endif +#ifndef __VOUCHER_FORWARD_TYPE_DECLS__ +#define __VOUCHER_FORWARD_TYPE_DECLS__ +#ifdef __cplusplus +extern "C" { +#endif +extern boolean_t voucher_mach_msg_set(mach_msg_header_t *msg) __attribute__((weak_import)); +#ifdef __cplusplus +} +#endif +#endif // __VOUCHER_FORWARD_TYPE_DECLS__ +#endif // __has_include() +#endif // __has_include +#endif // !KERNEL + +/* END VOUCHER CODE */ + +/* 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 substrated_MSG_COUNT +#define substrated_MSG_COUNT 1 +#endif /* substrated_MSG_COUNT */ + +#include +#include +#include +#include + +#ifdef __BeforeMigUserHeader +__BeforeMigUserHeader +#endif /* __BeforeMigUserHeader */ + +#include + __BEGIN_DECLS + +/* Routine substrated_mark */ +#ifdef mig_external + mig_external +#else +extern +#endif /* mig_external */ + kern_return_t + substrated_mark(mach_port_t server, vm_map_t task, mach_vm_address_t source_address, + mach_vm_size_t source_size, mach_vm_address_t *target_address); + +__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__substrated_subsystem__defined +#define __Request__substrated_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 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 task; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_vm_address_t source_address; + mach_vm_size_t source_size; + mach_vm_address_t target_address; +} __Request__substrated_mark_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Request__substrated_subsystem__defined */ + +/* union of all requests */ + +#ifndef __RequestUnion__substrated_subsystem__defined +#define __RequestUnion__substrated_subsystem__defined +union __RequestUnion__substrated_subsystem { + __Request__substrated_mark_t Request_substrated_mark; +}; +#endif /* !__RequestUnion__substrated_subsystem__defined */ +/* typedefs for all replies */ + +#ifndef __Reply__substrated_subsystem__defined +#define __Reply__substrated_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif +typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_vm_address_t target_address; +} __Reply__substrated_mark_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Reply__substrated_subsystem__defined */ + +/* union of all replies */ + +#ifndef __ReplyUnion__substrated_subsystem__defined +#define __ReplyUnion__substrated_subsystem__defined +union __ReplyUnion__substrated_subsystem { + __Reply__substrated_mark_t Reply_substrated_mark; +}; +#endif /* !__RequestUnion__substrated_subsystem__defined */ + +#ifndef subsystem_to_name_map_substrated +#define subsystem_to_name_map_substrated \ + { "substrated_mark", 9000 } +#endif + +#ifdef __AfterMigUserHeader +__AfterMigUserHeader +#endif /* __AfterMigUserHeader */ + +#endif /* _substrated_user_ */ diff --git a/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/substrated/mach_interface_support/substrated_server.c b/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/substrated/mach_interface_support/substrated_server.c new file mode 100644 index 00000000..d8743080 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/substrated/mach_interface_support/substrated_server.c @@ -0,0 +1,247 @@ +/* + * IDENTIFICATION: + * stub generated Tue Jan 7 03:06:18 2020 + * with a MiG generated by bootstrap_cmds-116 + * OPTIONS: + */ + +/* Module substrated */ + +#define __MIG_check__Request__substrated_subsystem__ 1 + +#include "substrated_server.h" + +#ifndef mig_internal +#define mig_internal static __inline__ +#endif /* mig_internal */ + +#ifndef mig_external +#define mig_external +#endif /* mig_external */ + +#if !defined(__MigTypeCheck) && defined(TypeCheck) +#define __MigTypeCheck TypeCheck /* Legacy setting */ +#endif /* !defined(__MigTypeCheck) */ + +#if !defined(__MigKernelSpecificCode) && defined(_MIG_KERNEL_SPECIFIC_CODE_) +#define __MigKernelSpecificCode _MIG_KERNEL_SPECIFIC_CODE_ /* Legacy setting */ +#endif /* !defined(__MigKernelSpecificCode) */ + +#ifndef LimitCheck +#define LimitCheck 0 +#endif /* LimitCheck */ + +#ifndef min +#define min(a,b) ( ((a) < (b))? (a): (b) ) +#endif /* min */ + +#if !defined(_WALIGN_) +#define _WALIGN_(x) (((x) + 3) & ~3) +#endif /* !defined(_WALIGN_) */ + +#if !defined(_WALIGNSZ_) +#define _WALIGNSZ_(x) _WALIGN_(sizeof(x)) +#endif /* !defined(_WALIGNSZ_) */ + +#ifndef UseStaticTemplates +#define UseStaticTemplates 0 +#endif /* UseStaticTemplates */ + +#ifndef MIG_SERVER_ROUTINE +#define MIG_SERVER_ROUTINE +#endif + +#ifndef __DeclareRcvRpc +#define __DeclareRcvRpc(_NUM_, _NAME_) +#endif /* __DeclareRcvRpc */ + +#ifndef __BeforeRcvRpc +#define __BeforeRcvRpc(_NUM_, _NAME_) +#endif /* __BeforeRcvRpc */ + +#ifndef __AfterRcvRpc +#define __AfterRcvRpc(_NUM_, _NAME_) +#endif /* __AfterRcvRpc */ + +#ifndef __DeclareRcvSimple +#define __DeclareRcvSimple(_NUM_, _NAME_) +#endif /* __DeclareRcvSimple */ + +#ifndef __BeforeRcvSimple +#define __BeforeRcvSimple(_NUM_, _NAME_) +#endif /* __BeforeRcvSimple */ + +#ifndef __AfterRcvSimple +#define __AfterRcvSimple(_NUM_, _NAME_) +#endif /* __AfterRcvSimple */ + +#define novalue void + +#define msgh_request_port msgh_local_port +#define MACH_MSGH_BITS_REQUEST(bits) MACH_MSGH_BITS_LOCAL(bits) +#define msgh_reply_port msgh_remote_port +#define MACH_MSGH_BITS_REPLY(bits) MACH_MSGH_BITS_REMOTE(bits) + +#define MIG_RETURN_ERROR(X, code) {\ + ((mig_reply_error_t *)X)->RetCode = code;\ + ((mig_reply_error_t *)X)->NDR = NDR_record;\ + return;\ + } + +/* Forward Declarations */ + + +mig_internal novalue _Xsubstrated_mark + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); + + +#if ( __MigTypeCheck ) +#if __MIG_check__Request__substrated_subsystem__ +#if !defined(__MIG_check__Request__substrated_mark_t__defined) +#define __MIG_check__Request__substrated_mark_t__defined + +mig_internal kern_return_t __MIG_check__Request__substrated_mark_t(__attribute__((__unused__)) __Request__substrated_mark_t *In0P) +{ + + typedef __Request__substrated_mark_t __Request; +#if __MigTypeCheck + if (!(In0P->Head.msgh_bits & MACH_MSGH_BITS_COMPLEX) || + (In0P->msgh_body.msgh_descriptor_count != 1) || + (In0P->Head.msgh_size != (mach_msg_size_t)sizeof(__Request))) + return MIG_BAD_ARGUMENTS; +#endif /* __MigTypeCheck */ + +#if __MigTypeCheck + if (In0P->task.type != MACH_MSG_PORT_DESCRIPTOR || + In0P->task.disposition != 17) + return MIG_TYPE_ERROR; +#endif /* __MigTypeCheck */ + + return MACH_MSG_SUCCESS; +} +#endif /* !defined(__MIG_check__Request__substrated_mark_t__defined) */ +#endif /* __MIG_check__Request__substrated_subsystem__ */ +#endif /* ( __MigTypeCheck ) */ + + +/* Routine substrated_mark */ +mig_internal novalue _Xsubstrated_mark + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) +{ + +#ifdef __MigPackStructs +#pragma pack(push, 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 task; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_vm_address_t source_address; + mach_vm_size_t source_size; + mach_vm_address_t target_address; + mach_msg_trailer_t trailer; + } Request __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif + typedef __Request__substrated_mark_t __Request; + typedef __Reply__substrated_mark_t Reply __attribute__((unused)); + + /* + * typedef struct { + * mach_msg_header_t Head; + * NDR_record_t NDR; + * kern_return_t RetCode; + * } mig_reply_error_t; + */ + + Request *In0P = (Request *) InHeadP; + Reply *OutP = (Reply *) OutHeadP; +#ifdef __MIG_check__Request__substrated_mark_t__defined + kern_return_t check_result; +#endif /* __MIG_check__Request__substrated_mark_t__defined */ + + __DeclareRcvRpc(9000, "substrated_mark") + __BeforeRcvRpc(9000, "substrated_mark") + +#if defined(__MIG_check__Request__substrated_mark_t__defined) + check_result = __MIG_check__Request__substrated_mark_t((__Request *)In0P); + if (check_result != MACH_MSG_SUCCESS) + { MIG_RETURN_ERROR(OutP, check_result); } +#endif /* defined(__MIG_check__Request__substrated_mark_t__defined) */ + + OutP->RetCode = substrated_mark(In0P->Head.msgh_request_port, In0P->task.name, In0P->source_address, In0P->source_size, &In0P->target_address); + if (OutP->RetCode != KERN_SUCCESS) { + MIG_RETURN_ERROR(OutP, OutP->RetCode); + } + + OutP->NDR = NDR_record; + + + OutP->target_address = In0P->target_address; + + OutP->Head.msgh_size = (mach_msg_size_t)(sizeof(Reply)); + __AfterRcvRpc(9000, "substrated_mark") +} + + + +/* Description of this subsystem, for use in direct RPC */ +const struct substrated_subsystem substrated_subsystem = { + substrated_server_routine, + 9000, + 9001, + (mach_msg_size_t)sizeof(union __ReplyUnion__substrated_subsystem), + (vm_address_t)0, + { + { (mig_impl_routine_t) 0, + (mig_stub_routine_t) _Xsubstrated_mark, 7, 0, (routine_arg_descriptor_t)0, (mach_msg_size_t)sizeof(__Reply__substrated_mark_t)}, + } +}; + +mig_external boolean_t substrated_server + (mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP) +{ + /* + * typedef struct { + * mach_msg_header_t Head; + * NDR_record_t NDR; + * kern_return_t RetCode; + * } mig_reply_error_t; + */ + + mig_routine_t routine; + + OutHeadP->msgh_bits = MACH_MSGH_BITS(MACH_MSGH_BITS_REPLY(InHeadP->msgh_bits), 0); + OutHeadP->msgh_remote_port = InHeadP->msgh_reply_port; + /* Minimal size: routine() will update it if different */ + OutHeadP->msgh_size = (mach_msg_size_t)sizeof(mig_reply_error_t); + OutHeadP->msgh_local_port = MACH_PORT_NULL; + OutHeadP->msgh_id = InHeadP->msgh_id + 100; + OutHeadP->msgh_reserved = 0; + + if ((InHeadP->msgh_id > 9000) || (InHeadP->msgh_id < 9000) || + ((routine = substrated_subsystem.routine[InHeadP->msgh_id - 9000].stub_routine) == 0)) { + ((mig_reply_error_t *)OutHeadP)->NDR = NDR_record; + ((mig_reply_error_t *)OutHeadP)->RetCode = MIG_BAD_ID; + return FALSE; + } + (*routine) (InHeadP, OutHeadP); + return TRUE; +} + +mig_external mig_routine_t substrated_server_routine + (mach_msg_header_t *InHeadP) +{ + int msgh_id; + + msgh_id = InHeadP->msgh_id - 9000; + + if ((msgh_id > 0) || (msgh_id < 0)) + return 0; + + return substrated_subsystem.routine[msgh_id].stub_routine; +} diff --git a/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/substrated/mach_interface_support/substrated_server.h b/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/substrated/mach_interface_support/substrated_server.h new file mode 100644 index 00000000..605cc6ee --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/UserMode/ExecMemory/substrated/mach_interface_support/substrated_server.h @@ -0,0 +1,197 @@ +#ifndef _substrated_server_ +#define _substrated_server_ + +/* Module substrated */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* BEGIN VOUCHER CODE */ + +#ifndef KERNEL +#if defined(__has_include) +#if __has_include() +#ifndef USING_VOUCHERS +#define USING_VOUCHERS +#endif +#ifndef __VOUCHER_FORWARD_TYPE_DECLS__ +#define __VOUCHER_FORWARD_TYPE_DECLS__ +#ifdef __cplusplus +extern "C" { +#endif +extern boolean_t voucher_mach_msg_set(mach_msg_header_t *msg) __attribute__((weak_import)); +#ifdef __cplusplus +} +#endif +#endif // __VOUCHER_FORWARD_TYPE_DECLS__ +#endif // __has_include() +#endif // __has_include +#endif // !KERNEL + +/* END VOUCHER CODE */ + +/* 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 substrated_MSG_COUNT +#define substrated_MSG_COUNT 1 +#endif /* substrated_MSG_COUNT */ + +#include +#include +#include +#include + +#ifdef __BeforeMigServerHeader +__BeforeMigServerHeader +#endif /* __BeforeMigServerHeader */ + +#ifndef MIG_SERVER_ROUTINE +#define MIG_SERVER_ROUTINE +#endif + +/* Routine substrated_mark */ +#ifdef mig_external + mig_external +#else +extern +#endif /* mig_external */ + MIG_SERVER_ROUTINE kern_return_t + substrated_mark(mach_port_t server, vm_task_entry_t task, mach_vm_address_t source_address, + mach_vm_size_t source_size, mach_vm_address_t *target_address); + +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ + boolean_t + substrated_server(mach_msg_header_t *InHeadP, mach_msg_header_t *OutHeadP); + +#ifdef mig_external +mig_external +#else +extern +#endif /* mig_external */ + mig_routine_t + substrated_server_routine(mach_msg_header_t *InHeadP); + +/* Description of this subsystem, for use in direct RPC */ +extern const struct substrated_subsystem { + mig_server_routine_t server; /* Server routine */ + mach_msg_id_t start; /* Min routine number */ + mach_msg_id_t end; /* Max routine number + 1 */ + unsigned int maxsize; /* Max msg size */ + vm_address_t reserved; /* Reserved */ + struct routine_descriptor /*Array of routine descriptors */ + routine[1]; +} substrated_subsystem; + +/* typedefs for all requests */ + +#ifndef __Request__substrated_subsystem__defined +#define __Request__substrated_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 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 task; + /* end of the kernel processed data */ + NDR_record_t NDR; + mach_vm_address_t source_address; + mach_vm_size_t source_size; + mach_vm_address_t target_address; +} __Request__substrated_mark_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Request__substrated_subsystem__defined */ + +/* union of all requests */ + +#ifndef __RequestUnion__substrated_subsystem__defined +#define __RequestUnion__substrated_subsystem__defined +union __RequestUnion__substrated_subsystem { + __Request__substrated_mark_t Request_substrated_mark; +}; +#endif /* __RequestUnion__substrated_subsystem__defined */ +/* typedefs for all replies */ + +#ifndef __Reply__substrated_subsystem__defined +#define __Reply__substrated_subsystem__defined + +#ifdef __MigPackStructs +#pragma pack(push, 4) +#endif +typedef struct { + mach_msg_header_t Head; + NDR_record_t NDR; + kern_return_t RetCode; + mach_vm_address_t target_address; +} __Reply__substrated_mark_t __attribute__((unused)); +#ifdef __MigPackStructs +#pragma pack(pop) +#endif +#endif /* !__Reply__substrated_subsystem__defined */ + +/* union of all replies */ + +#ifndef __ReplyUnion__substrated_subsystem__defined +#define __ReplyUnion__substrated_subsystem__defined +union __ReplyUnion__substrated_subsystem { + __Reply__substrated_mark_t Reply_substrated_mark; +}; +#endif /* __ReplyUnion__substrated_subsystem__defined */ + +#ifndef subsystem_to_name_map_substrated +#define subsystem_to_name_map_substrated \ + { "substrated_mark", 9000 } +#endif + +#ifdef __AfterMigServerHeader +__AfterMigServerHeader +#endif /* __AfterMigServerHeader */ + +#endif /* _substrated_server_ */ diff --git a/Bcore/src/main/cpp/Dobby/source/UserMode/MultiThreadSupport/ThreadSupport.cpp b/Bcore/src/main/cpp/Dobby/source/UserMode/MultiThreadSupport/ThreadSupport.cpp new file mode 100644 index 00000000..30be99c8 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/UserMode/MultiThreadSupport/ThreadSupport.cpp @@ -0,0 +1,22 @@ +#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/Bcore/src/main/cpp/Dobby/source/UserMode/MultiThreadSupport/ThreadSupport.h b/Bcore/src/main/cpp/Dobby/source/UserMode/MultiThreadSupport/ThreadSupport.h new file mode 100644 index 00000000..06d997a1 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/UserMode/MultiThreadSupport/ThreadSupport.h @@ -0,0 +1,63 @@ +#ifndef USER_MODE_MULTI_THREAD_SUPPORT_H +#define USER_MODE_MULTI_THREAD_SUPPORT_H + +#include +#include + +#include "dobby_internal.h" + +#include "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 { + std::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/Bcore/src/main/cpp/Dobby/source/UserMode/PlatformUtil/Darwin/ProcessRuntimeUtility.cc b/Bcore/src/main/cpp/Dobby/source/UserMode/PlatformUtil/Darwin/ProcessRuntimeUtility.cc new file mode 100644 index 00000000..9dfb4aab --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/UserMode/PlatformUtil/Darwin/ProcessRuntimeUtility.cc @@ -0,0 +1,130 @@ +#include "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" + +#include + +// ================================================================ +// GetProcessMemoryLayout + +static bool memory_region_comparator(MemoryRegion a, MemoryRegion b) { + return (a.address < b.address); +} + +std::vector ProcessRuntimeUtility::GetProcessMemoryLayout() { + std::vector ProcessMemoryLayout; + + struct vm_region_submap_short_info_64 submap_info; + mach_msg_type_number_t count = VM_REGION_SUBMAP_SHORT_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_SHORT_INFO_COUNT_64; + kern_return_t kr = + mach_vm_region_recurse(mach_task_self(), &addr, &size, &depth, (vm_region_recurse_info_t)&submap_info, &count); + if (kr != KERN_SUCCESS) { + if (kr == KERN_INVALID_ADDRESS) { + break; + } else { + break; + } + } + + if (submap_info.is_submap) { + depth++; + } else { + MemoryPermission permission; + if ((submap_info.protection & PROT_READ) && (submap_info.protection & PROT_WRITE)) { + permission = MemoryPermission::kReadWrite; + } else if ((submap_info.protection & PROT_READ) == submap_info.protection) { + permission = MemoryPermission::kRead; + } else if ((submap_info.protection & PROT_READ) && (submap_info.protection & PROT_EXEC)) { + permission = MemoryPermission::kReadExecute; + } else { + continue; + } + MemoryRegion region = {(void *)addr, static_cast(size), permission}; +#if 0 + DLOG(0, "%p --- %p", addr, addr + size); +#endif + ProcessMemoryLayout.push_back(region); + addr += size; + } + } + + std::sort(ProcessMemoryLayout.begin(), ProcessMemoryLayout.end(), memory_region_comparator); + + return ProcessMemoryLayout; +} + +// ================================================================ +// GetProcessModuleMap + +std::vector ProcessRuntimeUtility::GetProcessModuleMap() { + std::vector ProcessModuleMap; + + 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 ProcessModuleMap; + } + + 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; + + for (int i = 0; i < infoArrayCount; ++i) { + const struct dyld_image_info *info = &infoArray[i]; + + RuntimeModule module = {0}; + { + strncpy(module.path, info->imageFilePath, sizeof(module.path)); + module.load_address = (void *)info->imageLoadAddress; + } + ProcessModuleMap.push_back(module); + } + + return ProcessModuleMap; +} + +RuntimeModule ProcessRuntimeUtility::GetProcessModule(const char *name) { + std::vector ProcessModuleMap = GetProcessModuleMap(); + for (auto module : ProcessModuleMap) { + if (strstr(module.path, name) != 0) { + return module; + } + } + return RuntimeModule{0}; +} diff --git a/Bcore/src/main/cpp/Dobby/source/UserMode/PlatformUtil/Linux/ProcessRuntimeUtility.cc b/Bcore/src/main/cpp/Dobby/source/UserMode/PlatformUtil/Linux/ProcessRuntimeUtility.cc new file mode 100644 index 00000000..97ca3965 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/UserMode/PlatformUtil/Linux/ProcessRuntimeUtility.cc @@ -0,0 +1,231 @@ +#include "PlatformUtil/ProcessRuntimeUtility.h" + +#include +#include +#include +#include + +#include +#include + +#include + +#define LINE_MAX 2048 + +// ================================================================ +// GetProcessMemoryLayout + +static bool memory_region_comparator(MemoryRegion a, MemoryRegion b) { + return ((addr_t)a.address < (addr_t)b.address); +} + +std::vector ProcessRuntimeUtility::GetProcessMemoryLayout() { + std::vector ProcessMemoryLayout; + + FILE *fp = fopen("/proc/self/maps", "r"); + if (fp == nullptr) + return ProcessMemoryLayout; + + 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) { + FATAL("/proc/self/maps parse failed!"); + fclose(fp); + return ProcessMemoryLayout; + } + + 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 + DLOG(0, "%p --- %p", region_start, region_end); +#endif + + ProcessMemoryLayout.push_back(MemoryRegion{(void *)region_start, region_end - region_start, permission}); + } + std::sort(ProcessMemoryLayout.begin(), ProcessMemoryLayout.end(), memory_region_comparator); + + fclose(fp); + return ProcessMemoryLayout; +} + +// ================================================================ +// GetProcessModuleMap + +static std::vector get_process_map_with_proc_maps() { + std::vector ProcessModuleMap; + + FILE *fp = fopen("/proc/self/maps", "r"); + if (fp == nullptr) + return ProcessModuleMap; + + 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) { + FATAL("/proc/self/maps parse failed!"); + fclose(fp); + return ProcessModuleMap; + } + + // 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)); + module.load_address = (void *)region_start; + ProcessModuleMap.push_back(module); + +#if 0 + DLOG(0, "module: %s", module.path); +#endif + } + + fclose(fp); + return ProcessModuleMap; +} + +#if defined(__LP64__) +static std::vector get_process_map_with_linker_iterator() { + std::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 + +std::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) { + std::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/Bcore/src/main/cpp/Dobby/source/UserMode/PlatformUtil/ProcessRuntimeUtility.h b/Bcore/src/main/cpp/Dobby/source/UserMode/PlatformUtil/ProcessRuntimeUtility.h new file mode 100644 index 00000000..7eed5aef --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/UserMode/PlatformUtil/ProcessRuntimeUtility.h @@ -0,0 +1,29 @@ +#ifndef GET_PROCESS_MODULE_MAP_H +#define GET_PROCESS_MODULE_MAP_H + +#include "PlatformUnifiedInterface/StdMemory.h" + +#include +#include + +typedef struct _RuntimeModule { + char path[1024]; + void *load_address; +} RuntimeModule; + +class ProcessRuntimeUtility { +public: + // ================================================================ + // Process Memory + + static std::vector GetProcessMemoryLayout(); + + // ================================================================ + // Process Module + + static std::vector GetProcessModuleMap(); + + static RuntimeModule GetProcessModule(const char *name); +}; + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/UserMode/PlatformUtil/Windows/ProcessRuntimeUtility.cc b/Bcore/src/main/cpp/Dobby/source/UserMode/PlatformUtil/Windows/ProcessRuntimeUtility.cc new file mode 100755 index 00000000..ce2d0ea5 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/UserMode/PlatformUtil/Windows/ProcessRuntimeUtility.cc @@ -0,0 +1,43 @@ +#include "PlatformUtil/ProcessRuntimeUtility.h" + +#include + +#define LINE_MAX 2048 + +// ================================================================ +// GetProcessMemoryLayout + +static bool memory_region_comparator(MemoryRegion a, MemoryRegion b) { + return (a.address > b.address); +} + +std::vector ProcessMemoryLayout; +std::vector ProcessRuntimeUtility::GetProcessMemoryLayout() { + if (!ProcessMemoryLayout.empty()) { + ProcessMemoryLayout.clear(); + } + + return ProcessMemoryLayout; +} + +// ================================================================ +// GetProcessModuleMap + +std::vector ProcessModuleMap; + +std::vector ProcessRuntimeUtility::GetProcessModuleMap() { + if (!ProcessMemoryLayout.empty()) { + ProcessMemoryLayout.clear(); + } + return ProcessModuleMap; +} + +RuntimeModule ProcessRuntimeUtility::GetProcessModule(const char *name) { + std::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/Bcore/src/main/cpp/Dobby/source/UserMode/Thread/PlatformThread.cc b/Bcore/src/main/cpp/Dobby/source/UserMode/Thread/PlatformThread.cc new file mode 100644 index 00000000..827d1250 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/UserMode/Thread/PlatformThread.cc @@ -0,0 +1,19 @@ +#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/Bcore/src/main/cpp/Dobby/source/UserMode/Thread/PlatformThread.h b/Bcore/src/main/cpp/Dobby/source/UserMode/Thread/PlatformThread.h new file mode 100644 index 00000000..ea030911 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/UserMode/Thread/PlatformThread.h @@ -0,0 +1,36 @@ +#ifndef USER_MODE_PLATFORM_THREAD_H +#define USER_MODE_PLATFORM_THREAD_H + +#include "common_header.h" + +namespace zz { + +class OSThread { +public: + typedef int LocalStorageKey; + + static int GetCurrentProcessId(); + + static int GetCurrentThreadId(); + + // Thread-local storage. + 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 + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/UserMode/Thread/platform-thread-posix.cc b/Bcore/src/main/cpp/Dobby/source/UserMode/Thread/platform-thread-posix.cc new file mode 100644 index 00000000..486618c7 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/UserMode/Thread/platform-thread-posix.cc @@ -0,0 +1,71 @@ +#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/Bcore/src/main/cpp/Dobby/source/UserMode/Thread/platform-thread-windows.cc b/Bcore/src/main/cpp/Dobby/source/UserMode/Thread/platform-thread-windows.cc new file mode 100644 index 00000000..1428bb06 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/UserMode/Thread/platform-thread-windows.cc @@ -0,0 +1,25 @@ +#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/Bcore/src/main/cpp/Dobby/source/UserMode/UnifiedInterface/platform-darwin/mach_vm.h b/Bcore/src/main/cpp/Dobby/source/UserMode/UnifiedInterface/platform-darwin/mach_vm.h new file mode 100644 index 00000000..a9cab322 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/UserMode/UnifiedInterface/platform-darwin/mach_vm.h @@ -0,0 +1,933 @@ +#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/Bcore/src/main/cpp/Dobby/source/UserMode/UnifiedInterface/platform-posix.cc b/Bcore/src/main/cpp/Dobby/source/UserMode/UnifiedInterface/platform-posix.cc new file mode 100644 index 00000000..7b9f7636 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/UserMode/UnifiedInterface/platform-posix.cc @@ -0,0 +1,217 @@ +#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 "UnifiedInterface/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; + +// ================================================================ +// base :: Thread + +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) { + FATAL("pthread create failed"); + return false; + } + return true; +} + +Thread::Thread(const char *name) { + strncpy(name_, name, sizeof(name_)); +} + +bool Thread::Start() { + if (ThreadInterface::Create(this, &handle_) == false) { + return false; + } + return true; +} + +// ================================================================ +// base :: OSMemory + +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(void *address, int size, MemoryPermission access) { + int prot = GetProtectionFromMemoryPermission(access); + + int flags = MAP_PRIVATE | MAP_ANONYMOUS; + if (address != NULL) { + flags = flags | MAP_FIXED; + } + void *result = mmap(address, size, prot, flags, kMmapFd, kMmapFdOffset); + if (result == MAP_FAILED) + return nullptr; + + return result; +} + +bool OSMemory::Free(void *address, const int size) { + DCHECK_EQ(0, reinterpret_cast(address) % PageSize()); + DCHECK_EQ(0, size % PageSize()); + + return munmap(address, size) == 0; +} + +bool OSMemory::Release(void *address, int size) { + DCHECK_EQ(0, reinterpret_cast(address) % PageSize()); + DCHECK_EQ(0, size % PageSize()); + + return munmap(address, size) == 0; +} + +// static +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); + int ret = mprotect(address, size, prot); + if (ret == 0 && access == MemoryPermission::kNoAccess) { + // This is advisory; ignore errors and continue execution. + // ReclaimInaccessibleMemory(address, size); + } + + if (ret) { + FATAL("[!] %s\n", ((const char *)strerror(errno))); + } + +// For accounting purposes, we want to call MADV_FREE_REUSE on macOS after +// changing permissions away from MemoryPermission::kNoAccess. Since this +// state is not kept at this layer, we always call this if access != kNoAccess. +// The cost is a syscall that effectively no-ops. +// TODO(erikchen): Fix this to only call MADV_FREE_REUSE when necessary. +// https://crbug.com/823915 +#if defined(OS_MACOSX) + if (access != MemoryPermission::kNoAccess) + madvise(address, size, MADV_FREE_REUSE); +#endif + + return ret == 0; +} + +// ================================================================ +// base :: OSPrint + +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 +} + +void OSPrint::PrintError(const char *format, ...) { + va_list args; + va_start(args, format); + VPrintError(format, args); + va_end(args); +} + +void OSPrint::VPrintError(const char *format, va_list args) { +#if defined(ANDROID) && !defined(ANDROID_LOG_STDOUT) + __android_log_vprint(ANDROID_LOG_ERROR, LOG_TAG, format, args); +#else + vfprintf(stderr, format, args); +#endif +} diff --git a/Bcore/src/main/cpp/Dobby/source/UserMode/UnifiedInterface/platform-windows.cc b/Bcore/src/main/cpp/Dobby/source/UserMode/UnifiedInterface/platform-windows.cc new file mode 100644 index 00000000..8043100d --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/UserMode/UnifiedInterface/platform-windows.cc @@ -0,0 +1,73 @@ +#include + +#include + + +#include "logging/logging.h" +#include "logging/check_logging.h" +#include "UnifiedInterface/platform.h" + +int GetProtectionFromMemoryPermission(MemoryPermission access) { + if (kReadWriteExecute == access) + return PAGE_EXECUTE_READWRITE; + else if (kReadExecute == access) + return PAGE_EXECUTE_READ; +} + +int OSMemory::PageSize() { + SYSTEM_INFO si; + GetSystemInfo(&si); + return si.dwPageSize; +} + +void *OSMemory::Allocate(void *address, int size, MemoryPermission access) { + DCHECK_EQ(0, reinterpret_cast(address) % PageSize()); + 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/Bcore/src/main/cpp/Dobby/source/UserMode/UnifiedInterface/platform.h b/Bcore/src/main/cpp/Dobby/source/UserMode/UnifiedInterface/platform.h new file mode 100644 index 00000000..9d28a76f --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/UserMode/UnifiedInterface/platform.h @@ -0,0 +1,100 @@ +#ifndef PLATFORM_INTERFACE_COMMON_PLATFORM_H +#define PLATFORM_INTERFACE_COMMON_PLATFORM_H + +#include + +#include "PlatformUnifiedInterface/StdMemory.h" + +namespace base { +// ================================================================ +// base :: ThreadLocalStorageInterface + +class ThreadLocalStorageInterface { + using LocalStorageKey = int32_t; + + // Thread-local storage. + 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; + } +}; + +// ================================================================ +// base :: Thread + +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 *); +}; + +class Thread : public ThreadInterface, public ThreadInterface::Delegate { +public: + Thread(const char *name); + + bool Start(); + +private: + ThreadHandle handle_; + + char name_[256]; +}; +} // namespace base + +// ================================================================ +// base :: OSMemory + +class OSMemory { +public: + static int PageSize(); + + static void *Allocate(void *address, int size, MemoryPermission access); + + static bool Free(void *address, const int size); + + static bool Release(void *address, int size); + + static bool SetPermission(void *address, int size, MemoryPermission access); +}; + +// ================================================================ +// base :: OSPrint + +class OSPrint { +public: + // Print output to console. This is mostly used for debugging output. + // On platforms that has standard terminal output, the output + // should go to stdout. + static void Print(const char *format, ...); + + static void VPrint(const char *format, va_list args); + + // Print error output to console. This is mostly used for error message + // output. On platforms that has standard terminal output, the output + // should go to stderr. + static void PrintError(const char *format, ...); + + static void VPrintError(const char *format, va_list args); +}; + +#endif diff --git a/Bcore/src/main/cpp/Dobby/source/UserMode/UnifiedInterface/semaphore.cc b/Bcore/src/main/cpp/Dobby/source/UserMode/UnifiedInterface/semaphore.cc new file mode 100644 index 00000000..12a15e02 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/UserMode/UnifiedInterface/semaphore.cc @@ -0,0 +1,160 @@ +// 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/Bcore/src/main/cpp/Dobby/source/UserMode/UnifiedInterface/semaphore.h b/Bcore/src/main/cpp/Dobby/source/UserMode/UnifiedInterface/semaphore.h new file mode 100644 index 00000000..cff4cd47 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/UserMode/UnifiedInterface/semaphore.h @@ -0,0 +1,98 @@ +// 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/Bcore/src/main/cpp/Dobby/source/core/arch/Cpu.cc b/Bcore/src/main/cpp/Dobby/source/core/arch/Cpu.cc new file mode 100644 index 00000000..07163616 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/arch/Cpu.cc @@ -0,0 +1,5 @@ + +#include "core/arch/Cpu.h" +#include "core/arch/CpuUtils.h" + +#include "xnucxx/LiteMemOpt.h" diff --git a/Bcore/src/main/cpp/Dobby/source/core/arch/Cpu.h b/Bcore/src/main/cpp/Dobby/source/core/arch/Cpu.h new file mode 100644 index 00000000..e0361a73 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/arch/Cpu.h @@ -0,0 +1,7 @@ +#ifndef CORE_ARCH_CPU_H +#define CORE_ARCH_CPU_H + +#include "CpuRegister.h" +#include "CpuFeature.h" + +#endif diff --git a/Bcore/src/main/cpp/Dobby/source/core/arch/CpuFeature.cc b/Bcore/src/main/cpp/Dobby/source/core/arch/CpuFeature.cc new file mode 100644 index 00000000..d29f1761 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/arch/CpuFeature.cc @@ -0,0 +1,7 @@ + +#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/Bcore/src/main/cpp/Dobby/source/core/arch/CpuFeature.h b/Bcore/src/main/cpp/Dobby/source/core/arch/CpuFeature.h new file mode 100644 index 00000000..302bb16a --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/arch/CpuFeature.h @@ -0,0 +1,19 @@ +#ifndef CORE_ARCH_CPU_FEATURE_H +#define CORE_ARCH_CPU_FEATURE_H + +#include "common_header.h" + +class CpuFeatures { +private: + static void FlushICache(void *start, int 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/Bcore/src/main/cpp/Dobby/source/core/arch/CpuRegister.cc b/Bcore/src/main/cpp/Dobby/source/core/arch/CpuRegister.cc new file mode 100644 index 00000000..3617e4ee --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/arch/CpuRegister.cc @@ -0,0 +1,10 @@ + +#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/Bcore/src/main/cpp/Dobby/source/core/arch/CpuRegister.h b/Bcore/src/main/cpp/Dobby/source/core/arch/CpuRegister.h new file mode 100644 index 00000000..e12aff48 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/arch/CpuRegister.h @@ -0,0 +1,25 @@ +#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/Bcore/src/main/cpp/Dobby/source/core/arch/CpuUtils.h b/Bcore/src/main/cpp/Dobby/source/core/arch/CpuUtils.h new file mode 100644 index 00000000..39423634 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/arch/CpuUtils.h @@ -0,0 +1,17 @@ +#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/Bcore/src/main/cpp/Dobby/source/core/arch/arm/constants-arm.h b/Bcore/src/main/cpp/Dobby/source/core/arch/arm/constants-arm.h new file mode 100644 index 00000000..b326d348 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/arch/arm/constants-arm.h @@ -0,0 +1,70 @@ +#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/Bcore/src/main/cpp/Dobby/source/core/arch/arm/registers-arm.h b/Bcore/src/main/cpp/Dobby/source/core/arch/arm/registers-arm.h new file mode 100644 index 00000000..88b7c2e1 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/arch/arm/registers-arm.h @@ -0,0 +1,58 @@ +#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/Bcore/src/main/cpp/Dobby/source/core/arch/arm64/constants-arm64.h b/Bcore/src/main/cpp/Dobby/source/core/arch/arm64/constants-arm64.h new file mode 100644 index 00000000..5540e6b1 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/arch/arm64/constants-arm64.h @@ -0,0 +1,387 @@ +#ifndef CORE_ARCH_CONSTANTS_ARM64_H +#define CORE_ARCH_CONSTANTS_ARM64_H + +#include "common_header.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/Bcore/src/main/cpp/Dobby/source/core/arch/arm64/registers-arm64.h b/Bcore/src/main/cpp/Dobby/source/core/arch/arm64/registers-arm64.h new file mode 100644 index 00000000..84a6d6b9 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/arch/arm64/registers-arm64.h @@ -0,0 +1,142 @@ +#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/Bcore/src/main/cpp/Dobby/source/core/arch/x64/constants-x64.h b/Bcore/src/main/cpp/Dobby/source/core/arch/x64/constants-x64.h new file mode 100644 index 00000000..d72f44f4 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/arch/x64/constants-x64.h @@ -0,0 +1,21 @@ +#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/Bcore/src/main/cpp/Dobby/source/core/arch/x64/registers-x64.h b/Bcore/src/main/cpp/Dobby/source/core/arch/x64/registers-x64.h new file mode 100644 index 00000000..4c7c612b --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/arch/x64/registers-x64.h @@ -0,0 +1,244 @@ +#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/Bcore/src/main/cpp/Dobby/source/core/arch/x86/constants-x86.h b/Bcore/src/main/cpp/Dobby/source/core/arch/x86/constants-x86.h new file mode 100644 index 00000000..a243a76d --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/arch/x86/constants-x86.h @@ -0,0 +1,19 @@ +#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/Bcore/src/main/cpp/Dobby/source/core/arch/x86/cpu-x86.cc b/Bcore/src/main/cpp/Dobby/source/core/arch/x86/cpu-x86.cc new file mode 100644 index 00000000..ce241656 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/arch/x86/cpu-x86.cc @@ -0,0 +1,99 @@ +#include "platform_macro.h" +#if defined(TARGET_ARCH_IA32) || defined(TARGET_ARCH_X64) + +#include "./cpu-x86.h" +#include "xnucxx/LiteMemOpt.h" + +X86CpuInfo::X86CpuInfo() { + icache_line_size_ = 0; + dcache_line_size_ = 0; + has_fpu_ = false; + has_cmov_ = false; + has_sahf_ = false; + has_mmx_ = false; + has_sse_ = false; + has_sse2_ = false; + has_sse3_ = false; + has_ssse3_ = false; + has_sse41_ = false; + + has_sse42_ = false; + has_osxsave_ = false; + has_avx_ = false; + has_fma3_ = false; + has_bmi1_ = false; + has_bmi2_ = false; + has_lzcnt_ = false; + has_popcnt_ = false; + is_atom_ = false; + + _memcpy(vendor_, (void *)"Unknown", 8); +#if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64 + int cpu_info[4]; + __cpuid(cpu_info, 0); + unsigned num_ids = cpu_info[0]; + std::swap(cpu_info[2], cpu_info[3]); + _memcpy(vendor_, cpu_info + 1, 12); + vendor_[12] = '\0'; + + // Interpret CPU feature information. + if (num_ids > 0) { + __cpuid(cpu_info, 1); + stepping_ = cpu_info[0] & 0xF; + model_ = ((cpu_info[0] >> 4) & 0xF) + ((cpu_info[0] >> 12) & 0xF0); + family_ = (cpu_info[0] >> 8) & 0xF; + type_ = (cpu_info[0] >> 12) & 0x3; + ext_model_ = (cpu_info[0] >> 16) & 0xF; + ext_family_ = (cpu_info[0] >> 20) & 0xFF; + has_fpu_ = (cpu_info[3] & 0x00000001) != 0; + has_cmov_ = (cpu_info[3] & 0x00008000) != 0; + has_mmx_ = (cpu_info[3] & 0x00800000) != 0; + has_sse_ = (cpu_info[3] & 0x02000000) != 0; + has_sse2_ = (cpu_info[3] & 0x04000000) != 0; + has_sse3_ = (cpu_info[2] & 0x00000001) != 0; + has_ssse3_ = (cpu_info[2] & 0x00000200) != 0; + has_sse41_ = (cpu_info[2] & 0x00080000) != 0; + has_sse42_ = (cpu_info[2] & 0x00100000) != 0; + has_popcnt_ = (cpu_info[2] & 0x00800000) != 0; + has_osxsave_ = (cpu_info[2] & 0x08000000) != 0; + has_avx_ = (cpu_info[2] & 0x10000000) != 0; + has_fma3_ = (cpu_info[2] & 0x00001000) != 0; + if (family_ == 0x6) { + switch (model_) { + case 0x1C: // SLT + case 0x26: + case 0x36: + case 0x27: + case 0x35: + case 0x37: // SLM + case 0x4A: + case 0x4D: + case 0x4C: // AMT + case 0x6E: + is_atom_ = true; + } + } + } + + // There are separate feature flags for VEX-encoded GPR instructions. + if (num_ids >= 7) { + __cpuid(cpu_info, 7); + has_bmi1_ = (cpu_info[1] & 0x00000008) != 0; + has_bmi2_ = (cpu_info[1] & 0x00000100) != 0; + } + + // Query extended IDs. + __cpuid(cpu_info, 0x80000000); + unsigned num_ext_ids = cpu_info[0]; + + // Interpret extended CPU feature information. + if (num_ext_ids > 0x80000000) { + __cpuid(cpu_info, 0x80000001); + has_lzcnt_ = (cpu_info[2] & 0x00000020) != 0; + // SAHF must be probed in long mode. + has_sahf_ = (cpu_info[2] & 0x00000001) != 0; + } +#endif +} + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/core/arch/x86/cpu-x86.h b/Bcore/src/main/cpp/Dobby/source/core/arch/x86/cpu-x86.h new file mode 100644 index 00000000..68fd62c3 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/arch/x86/cpu-x86.h @@ -0,0 +1,120 @@ +#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/Bcore/src/main/cpp/Dobby/source/core/arch/x86/registers-x86.h b/Bcore/src/main/cpp/Dobby/source/core/arch/x86/registers-x86.h new file mode 100644 index 00000000..65b06b2b --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/arch/x86/registers-x86.h @@ -0,0 +1,124 @@ +#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/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler-arch.h b/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler-arch.h new file mode 100644 index 00000000..23ae9c3b --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler-arch.h @@ -0,0 +1,28 @@ +#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/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler-arm.cc b/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler-arm.cc new file mode 100644 index 00000000..25f9d3e5 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler-arm.cc @@ -0,0 +1,20 @@ +#include "platform_macro.h" +#if TARGET_ARCH_ARM + +#include "core/modules/assembler/assembler-arm.h" + +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 \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler-arm.h b/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler-arm.h new file mode 100644 index 00000000..c4a87e89 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler-arm.h @@ -0,0 +1,490 @@ +#ifndef CORE_ASSEMBLER_ARM_H +#define CORE_ASSEMBLER_ARM_H + +#include "common_header.h" + +#include "core/arch/arm/constants-arm.h" +#include "core/arch/arm/registers-arm.h" +#include "core/modules/assembler/assembler.h" + +#include "MemoryAllocator/CodeBuffer/code-buffer-arm.h" + +#include "xnucxx/LiteMutableArray.h" +#include "xnucxx/LiteIterator.h" + +#include + +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) + +// ===== PseudoLabel ===== + +class PseudoLabel : public Label { +public: + enum PseudoLabelType { kLdrLiteral }; + + typedef struct _PseudoLabelInstruction { + int position_; + int type_; + } PseudoLabelInstruction; + +public: + PseudoLabel(void) : instructions_(8) { + } + + ~PseudoLabel(void) { + for (size_t i = 0; i < instructions_.getCount(); i++) { + PseudoLabelInstruction *item = (PseudoLabelInstruction *)instructions_.getObject(i); + delete item; + } + } + + 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_; + const int32_t inst32 = _buffer->LoadARMInst(instruction->position_); + int32_t encoded = 0; + + switch (instruction->type_) { + case kLdrLiteral: { + encoded = inst32 & 0xfffff000; + uint32_t imm12 = offset - ARM_PC_OFFSET; + ASSERT(CheckSignLength(imm12)); + encoded = encoded | imm12; + } break; + default: + UNREACHABLE(); + break; + } + _buffer->RewriteARMInst(instruction->position_, encoded); + } + }; + + // compatible for thumb with int type + void link_to(int pos, int type) { + PseudoLabelInstruction *instruction = new PseudoLabelInstruction; + instruction->position_ = pos; + instruction->type_ = type; + instructions_.pushObject((LiteObject *)instruction); + } + +protected: + LiteMutableArray instructions_; +}; + +// reloc +class RelocLabelEntry : public PseudoLabel { +public: + explicit RelocLabelEntry(uint32_t data) : data_size_(0) { + data_ = data; + } + + uint32_t data() { + return data_; + } + + void fixup_data(uint32_t data) { + data_ = data; + } + +private: + uint32_t data_; + + int data_size_; +}; + +// ================================================================ +// Operand + +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; +}; + +// ================================================================ +// MemOperand + +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; + } +}; + +// ================================================================ +// Assembler + +enum ExecuteState { ARMExecuteState, ThumbExecuteState }; + +class Assembler : public AssemblerBase { +private: + ExecuteState execute_state_; + +public: + Assembler(void *address) : AssemblerBase(address) { + execute_state_ = ARMExecuteState; + buffer_ = new CodeBuffer(64); + } + + // 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 + +// ================================================================ +// TurboAssembler + +class TurboAssembler : public Assembler { +public: + TurboAssembler(void *address) : Assembler(address) { + data_labels_ = NULL; + } + + ~TurboAssembler() { + if (data_labels_) { + for (size_t i = 0; i < data_labels_->getCount(); i++) { + RelocLabelEntry *label = (RelocLabelEntry *)data_labels_->getObject(i); + delete label; + } + + delete data_labels_; + } + } + + TurboAssembler(void *address, CodeBuffer *buffer) : Assembler(address, buffer) { + data_labels_ = NULL; + } + + void Ldr(Register rt, PseudoLabel *label) { + if (label->is_bound()) { + int offset = label->pos() - buffer_->getSize(); + ldr(rt, MemOperand(pc, offset)); + } else { + // record this ldr, and fix later. + label->link_to(buffer_->getSize(), PseudoLabel::kLdrLiteral); + 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)function.address()); + } + + void Move32Immeidate(Register rd, const Operand &x, Condition cond = AL) { + } + + // ================================================================ + // RelocLabelEntry + + void PseudoBind(PseudoLabel *label) { + if (label->is_unused() == true) { + const uint32_t bound_pc = buffer_->getSize(); + 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(this->GetCodeBuffer()); + } + } + + void RelocBindFixup(RelocLabelEntry *label) { + buffer_->RewriteAddr(label->pos(), label->data()); + } + + void RelocBind() { + if (data_labels_ == NULL) + return; + for (size_t i = 0; i < data_labels_->getCount(); i++) { + RelocLabelEntry *label = (RelocLabelEntry *)data_labels_->getObject(i); + PseudoBind(label); + EmitAddress(label->data()); + } + } + + void AppendRelocLabelEntry(RelocLabelEntry *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 arm +} // namespace zz + +#endif diff --git a/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler-arm64.cc b/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler-arm64.cc new file mode 100644 index 00000000..0b83ce43 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler-arm64.cc @@ -0,0 +1,87 @@ +#include "platform_macro.h" +#if TARGET_ARCH_ARM64 + +#include "core/modules/assembler/assembler-arm64.h" + +namespace zz { +namespace arm64 { + +void Assembler::Emit(int32_t value) { + buffer_->EmitInst(value); +} + +void Assembler::EmitInt64(int64_t value) { + buffer_->Emit64(value); +} + +void Assembler::bind(Label *label) { + const intptr_t bound_pc = pc_offset(); + while (label->is_linked()) { + int linkpos = label->pos(); + int32_t instr = buffer_->LoadInst(linkpos); + + int prevlinkpos = 0; + if ((instr & UnconditionalBranchMask) == UnconditionalBranchFixed) { + int32_t imm26 = 0; + + // fix the b-instr + int offset = bound_pc - linkpos; + imm26 = bits(offset >> 2, 0, 25); + int32_t rewrite_inst = (instr & 0xfc000000) | LeftShift(imm26, 26, 0); + buffer_->FixBindLabel(linkpos, rewrite_inst); + + // caculate next label + imm26 = bits(instr, 0, 25); + int next_label_offset = imm26 << 2; + prevlinkpos = linkpos - next_label_offset; + } + + if ((linkpos - prevlinkpos) == kStartOfLabelLinkChain) { + // AKA pos_ = 0; + label->link_to(-1); + } else { + // AKA pos_ = prevlinkpos + label->link_to(prevlinkpos); + } + } + label->bind_to(bound_pc); +} + +int Assembler::LinkAndGetByteOffsetTo(Label *label) { + int offset; + + if (label->is_bound()) { + + // The label is bound, so it does not need to be updated. Referring + // instructions must link directly to the label as they will not be + // updated. + // + // In this case, label->pos() returns the offset of the label from the + // start of the buffer. + // + // Note that offset can be zero for self-referential instructions. (This + // could be useful for ADR, for example.) + offset = label->pos() - pc_offset(); + } else { + if (label->is_linked()) { + // The label is linked, so the referring instruction should be added onto + // the end of the label's link chain. + // + // In this case, label->pos() returns the offset of the last linked + // instruction from the start of the buffer. + offset = label->pos() - pc_offset(); + } else { + // The label is unused, so it now becomes linked and the referring + // instruction is at the start of the new link chain. + offset = kStartOfLabelLinkChain; + } + // The instruction at pc is now the last link in the label's chain. + label->link_to(pc_offset()); + } + return offset; +} + +} // namespace arm64 +} // namespace zz + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler-arm64.h b/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler-arm64.h new file mode 100644 index 00000000..4aeb4c01 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler-arm64.h @@ -0,0 +1,699 @@ +#ifndef CORE_ASSEMBLER_ARM64_H +#define CORE_ASSEMBLER_ARM64_H + +#include "common_header.h" + +#include "core/arch/arm64/constants-arm64.h" +#include "core/arch/arm64/registers-arm64.h" +#include "core/modules/assembler/assembler.h" + +#include "MemoryAllocator/CodeBuffer/code-buffer-arm64.h" + +#include "xnucxx/LiteMutableArray.h" +#include "xnucxx/LiteIterator.h" + +#include "dobby_internal.h" + +static inline int32_t Low16Bits(int32_t value) { + return static_cast(value & 0xffff); +} + +static inline int32_t High16Bits(int32_t value) { + return static_cast(value >> 16); +} + +static inline int32_t Low32Bits(int64_t value) { + return static_cast(value); +} + +static inline int32_t High32Bits(int64_t value) { + return static_cast(value >> 32); +} + +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) + +// ================================================================ +// PseudoLabel + +class PseudoLabel : public Label { +public: + enum PseudoLabelType { kLdrLiteral }; + + typedef struct _PseudoLabelInstruction { + int position_; + PseudoLabelType type_; + } PseudoLabelInstruction; + +public: + PseudoLabel(void) : instructions_(8) { + } + ~PseudoLabel(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_; + const int32_t inst32 = _buffer->LoadInst(instruction->position_); + int32_t encoded = 0; + + switch (instruction->type_) { + case kLdrLiteral: { + encoded = inst32 & 0xFF00001F; + encoded = encoded | LeftShift((offset >> 2), 19, 5); + } break; + default: + UNREACHABLE(); + break; + } + _buffer->FixBindLabel(instruction->position_, encoded); + } + }; + + void link_to(int pos, PseudoLabelType type) { + PseudoLabelInstruction *instruction = new PseudoLabelInstruction; + instruction->position_ = pos; + instruction->type_ = type; + instructions_.pushObject((LiteObject *)instruction); + } + +private: +#if 0 + // From a design perspective, these fix-function write as callback, maybe beeter. + void FixLdr(PseudoLabelInstruction *instruction){ + // dummy + }; +#endif + +private: + LiteMutableArray instructions_; +}; + +class RelocLabelEntry : public PseudoLabel { +public: + explicit RelocLabelEntry(uint64_t data) : data_size_(0) { + data_ = data; + } + + uint64_t data() { + return data_; + } + +private: + uint64_t data_; + + int data_size_; +}; + +// ================================================================ +// Operand + +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_; +}; + +// ================================================================ +// MemOperand + +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_; +}; + +// ================================================================ +// OpEncode + +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; + } +}; + +// ================================================================ +// Assembler + +class Assembler : public AssemblerBase { +public: + Assembler(void *address) : AssemblerBase(address) { + buffer_ = new CodeBuffer(32); + DLOG(0, "Initialize assembler code buffer at %p", (CodeBufferBase *)buffer_->getRawBuffer()); + } + ~Assembler() { + if (buffer_) + delete buffer_; + buffer_ = NULL; + } + +public: + void SetRealizedAddress(void *address) { + DCHECK_EQ(0, reinterpret_cast(address) % 4); + AssemblerBase::SetRealizedAddress(address); + } + + void Emit(int32_t value); + + void EmitInt64(int64_t 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)); + + int64_t immlo = LeftShift(bits(imm >> 12, 0, 1), 2, 29); + int64_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); + } +}; + +// ================================================================ +// TurboAssembler + +class TurboAssembler : public Assembler { +public: + TurboAssembler(void *address) : Assembler(address) { + data_labels_ = NULL; + } + + ~TurboAssembler() { + if (data_labels_) { + for (size_t i = 0; i < data_labels_->getCount(); i++) { + RelocLabelEntry *label = (RelocLabelEntry *)data_labels_->getObject(i); + delete label; + } + + delete data_labels_; + } + } + + void CallFunction(ExternalReference function) { + Mov(TMP_REG_0, (uint64_t)function.address()); + blr(TMP_REG_0); + } + + void Ldr(Register rt, PseudoLabel *label) { + if (label->is_bound()) { + int offset = label->pos() - buffer_->getSize(); + ldr(rt, offset); + } else { + // record this ldr, and fix later. + label->link_to(buffer_->getSize(), PseudoLabel::kLdrLiteral); + 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); + } + + // ================================================================ + // PseudoLabel + + void PseudoBind(PseudoLabel *label) { + const addr_t bound_pc = buffer_->getSize(); + 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++) { + RelocLabelEntry *label = (RelocLabelEntry *)data_labels_->getObject(i); + PseudoBind(label); + EmitInt64(label->data()); + } + } + + void AppendRelocLabelEntry(RelocLabelEntry *label) { + if (data_labels_ == NULL) { + data_labels_ = new LiteMutableArray(8); + } + data_labels_->pushObject((LiteObject *)label); + } + +private: + LiteMutableArray *data_labels_; +}; + +} // namespace arm64 +} // namespace zz + +#endif diff --git a/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler-ia32.cc b/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler-ia32.cc new file mode 100644 index 00000000..6fb2cb08 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler-ia32.cc @@ -0,0 +1,17 @@ +#include "platform_macro.h" +#if TARGET_ARCH_IA32 + +#include "core/modules/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_address_; +} + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler-ia32.h b/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler-ia32.h new file mode 100644 index 00000000..44f75e2b --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler-ia32.h @@ -0,0 +1,593 @@ +#ifndef CORE_ASSEMBLER_X86_H +#define CORE_ASSEMBLER_X86_H + +#include "common_header.h" + +#include "core/arch/x86/registers-x86.h" +#include "core/modules/assembler/assembler.h" + +#include "MemoryAllocator/CodeBuffer/code-buffer-x86.h" + +#include "xnucxx/LiteMutableArray.h" +#include "xnucxx/LiteIterator.h" + +#define IsInt8(imm) (-128 <= imm && imm <= 127) + +namespace zz { +namespace x86 { + +constexpr Register VOLATILE_REGISTER = eax; + +// ================================================================ +// PseudoLabel + +class PseudoLabel : public Label { +public: + enum PseudoLabelType { kDisp32_off_7 }; + + typedef struct _PseudoLabelInstruction { + int position_; + PseudoLabelType type_; + } PseudoLabelInstruction; + +public: + PseudoLabel(void) : instructions_(8) { + } + ~PseudoLabel(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_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 = instruction->position_ - sizeof(int32_t); + _buffer->FixBindLabel(disp32_fix_pos, offset + 7); + } 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 RelocLabelEntry : public PseudoLabel { +public: + explicit RelocLabelEntry(uint32_t data) : data_size_(0) { + data_ = data; + } + + uint32_t data() { + return data_; + } + +private: + uint32_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(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_; +}; + +// ================================================================ +// 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 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]; +}; + +// ================================================================ +// Address + +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); + } +}; + +// ================================================================ +// Assembler + +class Assembler : public AssemblerBase { +public: + Assembler(void *address) : AssemblerBase(address) { + buffer_ = new CodeBuffer(32); + } + ~Assembler() { + if (buffer_) + delete buffer_; + buffer_ = NULL; + } + +public: + void Emit1(byte_t val) { + buffer_->Emit8(val); + } + + void Emit(int32_t value) { + buffer_->Emit32(value); + } + + // ================================================================ + // 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 { + UNREACHABLE(); + } + } + + // ================================================================ + // Operand Encoding + + // 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()); + } + + // ================================================================ + // 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.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)); + } + + // ================================================================ + // Opcode + void EmitOpcode(uint8_t opcode) { + Emit1(opcode); + } + + void EmitOpcode_Register(uint8_t opcode, Register reg) { + EmitOpcode(opcode | reg.code()); + } + + // ================================================================ + // Instruction + + 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); + } +}; + +// ================================================================ +// TurboAssembler + +class TurboAssembler : public Assembler { +public: + TurboAssembler(void *address) : Assembler(address) { + data_labels_ = NULL; + } + + ~TurboAssembler() { + if (data_labels_) { + for (size_t i = 0; i < data_labels_->getCount(); i++) { + RelocLabelEntry *label = (RelocLabelEntry *)data_labels_->getObject(i); + delete label; + } + + delete data_labels_; + } + } + + addr32_t CurrentIP(); + + void CallFunction(ExternalReference function) { + nop(); + MovRipToRegister(VOLATILE_REGISTER); + call(Address(VOLATILE_REGISTER, INT32_MAX)); + { + RelocLabelEntry *addrLabel = new RelocLabelEntry((uint32_t)function.address()); + addrLabel->link_to(ip_offset(), PseudoLabel::kDisp32_off_7); + this->AppendRelocLabelEntry(addrLabel); + } + nop(); + } + + void MovRipToRegister(Register dst) { + call(Immediate(0, 32)); + pop(dst); + } + + // ================================================================ + // RelocLabelEntry + + void PseudoBind(PseudoLabel *label) { + const addr_t bound_pc = buffer_->getSize(); + 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++) { + RelocLabelEntry *label = (RelocLabelEntry *)data_labels_->getObject(i); + PseudoBind(label); + Emit(label->data()); + } + } + + void AppendRelocLabelEntry(RelocLabelEntry *label) { + if (data_labels_ == NULL) { + data_labels_ = new LiteMutableArray(8); + } + data_labels_->pushObject((LiteObject *)label); + } + +private: + LiteMutableArray *data_labels_; +}; + +} // namespace x86 +} // namespace zz + +#endif diff --git a/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler-x64.cc b/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler-x64.cc new file mode 100644 index 00000000..dee32526 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler-x64.cc @@ -0,0 +1,17 @@ +#include "platform_macro.h" +#if defined(TARGET_ARCH_X64) + +#include "core/modules/assembler/assembler-x64.h" + +using namespace zz::x64; + +void Assembler::jmp(Immediate imm) { + buffer_->Emit8(0xE9); + buffer_->Emit32((int)imm.value()); +} + +uint64_t TurboAssembler::CurrentIP() { + return pc_offset() + (addr_t)realized_address_; +} + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler-x64.h b/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler-x64.h new file mode 100644 index 00000000..bf61247e --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler-x64.h @@ -0,0 +1,737 @@ +#ifndef CORE_ASSEMBLER_X86_SHARED_H +#define CORE_ASSEMBLER_X86_SHARED_H + +#include "common_header.h" + +#include "core/arch/x64/registers-x64.h" +#include "core/modules/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 x64 { + +constexpr Register VOLATILE_REGISTER = r11; + +// ================================================================ +// PseudoLabel + +class PseudoLabel : public Label { +public: + enum PseudoLabelType { kDisp32_off_9 }; + + typedef struct _PseudoLabelInstruction { + int position_; + PseudoLabelType type_; + } PseudoLabelInstruction; + +public: + PseudoLabel(void) : instructions_(8) { + } + + ~PseudoLabel(void) { + for (int 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 (int 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: { + // 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 = 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 RelocLabelEntry : public PseudoLabel { +public: + explicit RelocLabelEntry(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) : AssemblerBase(address) { + buffer_ = new CodeBuffer(32); + } + ~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); + } + + // ================================================================ + // 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 + + 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()); + } + + // ================================================================ + // 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); + + 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); + } +}; + +// ================================================================ +// TurboAssembler + +class TurboAssembler : public Assembler { +public: + TurboAssembler(void *address) : Assembler(address) { + data_labels_ = NULL; + } + + ~TurboAssembler() { + if (data_labels_) { + for (int i = 0; i < data_labels_->getCount(); i++) { + RelocLabelEntry *label = (RelocLabelEntry *)data_labels_->getObject(i); + delete label; + } + + delete data_labels_; + } + } + + 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)); + { + RelocLabelEntry *addrLabel = new RelocLabelEntry((uint64_t)function.address()); + addrLabel->link_to(ip_offset(), PseudoLabel::kDisp32_off_9); + this->AppendRelocLabelEntry(addrLabel); + } + nop(); + } + + void MovRipToRegister(Register dst) { + call(Immediate(0, 32)); + pop(dst); + } + + // ================================================================ + // RelocLabelEntry + + void PseudoBind(PseudoLabel *label) { + const addr_t bound_pc = buffer_->getSize(); + 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++) { + RelocLabelEntry *label = (RelocLabelEntry *)data_labels_->getObject(i); + PseudoBind(label); + EmitInt64(label->data()); + } + } + + void AppendRelocLabelEntry(RelocLabelEntry *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 x64 +} // namespace zz + +#endif diff --git a/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler-x86-shared.cc b/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler-x86-shared.cc new file mode 100644 index 00000000..f5f560c7 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler-x86-shared.cc @@ -0,0 +1,17 @@ +#include "platform_macro.h" +#if defined(TARGET_ARCH_X64) || defined(TARGET_ARCH_IA32) + +#include "core/modules/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_address_; +} + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler-x86-shared.h b/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler-x86-shared.h new file mode 100644 index 00000000..a5cf76d3 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler-x86-shared.h @@ -0,0 +1,710 @@ +#ifndef CORE_ASSEMBLER_X64_H +#define CORE_ASSEMBLER_X64_H + +#include "common_header.h" + +#include "core/arch/x64/registers-x64.h" +#include "core/modules/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; + +// ================================================================ +// PseudoLabel + +class PseudoLabel : public Label { +public: + enum PseudoLabelType { kDisp32_off_9 }; + + typedef struct _PseudoLabelInstruction { + int position_; + PseudoLabelType type_; + } PseudoLabelInstruction; + +public: + PseudoLabel(void) { + instructions_.initWithCapacity(8); + } + ~PseudoLabel(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 RelocLabelEntry : public PseudoLabel { +public: + explicit RelocLabelEntry(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(32); + } + ~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)); + { + RelocLabelEntry *addrLabel = new RelocLabelEntry((uint64_t)function.address()); + addrLabel->link_to(ip_offset(), PseudoLabel::kDisp32_off_9); + this->AppendRelocLabelEntry(addrLabel); + } + nop(); + } + + void MovRipToRegister(Register dst) { + call(Immediate(0, 32)); + pop(dst); + } + + // ================================================================ + // RelocLabelEntry + + void PseudoBind(PseudoLabel *label) { + const addr_t bound_pc = buffer_->getSize(); + 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++) { + RelocLabelEntry *label = (RelocLabelEntry *)data_labels_->getObject(i); + PseudoBind(label); + EmitAddr(label->data()); + } + } + + void AppendRelocLabelEntry(RelocLabelEntry *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 + +#endif diff --git a/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler.cc b/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler.cc new file mode 100644 index 00000000..33a0106a --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler.cc @@ -0,0 +1,81 @@ +#include "core/modules/assembler/assembler.h" +#include "logging/logging.h" + +namespace zz { + +// ===== Label ===== + +bool Label::is_bound() const { + return pos_ < 0; +} +bool Label::is_unused() const { + return pos_ == 0 && near_link_pos_ == 0; +} +bool Label::is_linked() const { + return pos_ > 0; +} +bool Label::is_near_linked() const { + return near_link_pos_ > 0; +} +int Label::pos() const { + if (pos_ < 0) + return -pos_ - 1; + if (pos_ > 0) + return pos_ - 1; + return 0; +} +void Label::bind_to(int pos) { + pos_ = -pos - 1; +} +void Label::link_to(int pos) { + // for special condition: link_to(0) + pos_ = pos + 1; +} + +const void *ExternalReference::address() { + return address_; +} + +AssemblerBase::AssemblerBase(void *address) { + realized_address_ = address; + + buffer_ = NULL; + + if (realized_address_ != NULL) { + DLOG(0, "[assembler] Create fixed address at %p", realized_address_); + } +} + +AssemblerBase::~AssemblerBase() { + buffer_ = NULL; +} + +// TODO: mov to x64 +int AssemblerBase::ip_offset() const { + return reinterpret_cast(buffer_)->getSize(); +} + +// TODO: mov to arm / arm64 +int AssemblerBase::pc_offset() const { + return reinterpret_cast(buffer_)->getSize(); +} + +CodeBuffer *AssemblerBase::GetCodeBuffer() { + return buffer_; +} + +void AssemblerBase::SetRealizedAddress(void *address) { + realized_address_ = address; +} + +void *AssemblerBase::GetRealizedAddress() { + return realized_address_; +} + +void AssemblerBase::FlushICache(addr_t start, int size) { +} + +void AssemblerBase::FlushICache(addr_t start, addr_t end) { +} + +} // namespace zz diff --git a/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler.h b/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler.h new file mode 100644 index 00000000..6c062be8 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/modules/assembler/assembler.h @@ -0,0 +1,102 @@ +#ifndef CORE_ASSEMBLER_H +#define CORE_ASSEMBLER_H + +#include "MemoryAllocator/CodeBuffer/CodeBufferBase.h" + +class CodeBuffer; + +namespace zz { + +class Label { +public: + Label() : pos_(0), near_link_pos_(0) { + } + +public: + bool is_bound() const; + + bool is_unused() const; + + bool is_linked() const; + + bool is_near_linked() const; + + int pos() const; + + void bind_to(int pos); + + void link_to(int pos); + +private: + // pos_: "< 0", indicate the Label is Binded, "> 0", indicate the Label is Linked, "= 0" indicate the Label is + // iter-terminal or unused + int pos_; + int near_link_pos_; +}; + +class ExternalReference { +public: + explicit ExternalReference(void *address) : address_(address) { +#if __APPLE__ +#if __has_feature(ptrauth_calls) + address_ = __builtin_ptrauth_strip(address, ptrauth_key_asia); +#endif +#endif + } + + const void *address(); + +private: + const void *address_; +}; + +class AssemblerBase { +public: + explicit AssemblerBase(void *address); + + ~AssemblerBase(); + + // === IP / PC register === + + int ip_offset() const; + + int pc_offset() const; + + // === CodeBuffer === + + CodeBuffer *GetCodeBuffer(); + + // === Realized Address === + + virtual void *GetRealizedAddress(); + + virtual void SetRealizedAddress(void *address); + + // === CPU Cache === + + static void FlushICache(addr_t start, int size); + + static void FlushICache(addr_t start, addr_t end); + +protected: + CodeBuffer *buffer_; + + void *realized_address_; +}; + +} // namespace zz + +#if 0 +#include "globals.h" +#if TARGET_ARCH_ARM +#include "core/modules/assembler/assembler-arm.h" +#elif TARGET_ARCH_ARM64 +#include "core/modules/assembler/assembler-arm64.h" +#elif TARGET_ARCH_X64 +#include "core/modules/assembler/assembler-x64.h" +#else +#error "unsupported architecture" +#endif +#endif + +#endif diff --git a/Bcore/src/main/cpp/Dobby/source/core/modules/codegen/codegen-arm.cc b/Bcore/src/main/cpp/Dobby/source/core/modules/codegen/codegen-arm.cc new file mode 100644 index 00000000..dfdff9de --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/modules/codegen/codegen-arm.cc @@ -0,0 +1,19 @@ +#include "platform_macro.h" +#if defined(TARGET_ARCH_ARM) + +#include "core/modules/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/Bcore/src/main/cpp/Dobby/source/core/modules/codegen/codegen-arm.h b/Bcore/src/main/cpp/Dobby/source/core/modules/codegen/codegen-arm.h new file mode 100644 index 00000000..da796bc3 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/modules/codegen/codegen-arm.h @@ -0,0 +1,22 @@ +#ifndef CORE_CODEGEN_ARM_H +#define CORE_CODEGEN_ARM_H + +#include "core/modules/codegen/codegen.h" +#include "core/modules/assembler/assembler.h" +#include "core/modules/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/Bcore/src/main/cpp/Dobby/source/core/modules/codegen/codegen-arm64.cc b/Bcore/src/main/cpp/Dobby/source/core/modules/codegen/codegen-arm64.cc new file mode 100644 index 00000000..dc6b12e6 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/modules/codegen/codegen-arm64.cc @@ -0,0 +1,24 @@ +#include "platform_macro.h" +#if defined(TARGET_ARCH_ARM64) + +#include "dobby_internal.h" +#include "core/modules/codegen/codegen-arm64.h" + +namespace zz { +namespace arm64 { + +void CodeGen::LiteralLdrBranch(uint64_t address) { + TurboAssembler *turbo_assembler_ = reinterpret_cast(this->assembler_); +#define _ turbo_assembler_-> + PseudoLabel address_ptr; + + _ Ldr(TMP_REG_0, &address_ptr); + _ br(TMP_REG_0); + _ PseudoBind(&address_ptr); + _ EmitInt64(address); +} + +} // namespace arm64 +} // namespace zz + +#endif diff --git a/Bcore/src/main/cpp/Dobby/source/core/modules/codegen/codegen-arm64.h b/Bcore/src/main/cpp/Dobby/source/core/modules/codegen/codegen-arm64.h new file mode 100644 index 00000000..5987d010 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/modules/codegen/codegen-arm64.h @@ -0,0 +1,21 @@ +#ifndef CORE_CODEGEN_ARM64_H +#define CORE_CODEGEN_ARM64_H + +#include "core/modules/codegen/codegen.h" +#include "core/modules/assembler/assembler.h" +#include "core/modules/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/Bcore/src/main/cpp/Dobby/source/core/modules/codegen/codegen-ia32.cc b/Bcore/src/main/cpp/Dobby/source/core/modules/codegen/codegen-ia32.cc new file mode 100644 index 00000000..3bf1b61d --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/modules/codegen/codegen-ia32.cc @@ -0,0 +1,23 @@ +#include "platform_macro.h" +#if defined(TARGET_ARCH_IA32) + +#include "core/modules/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; + dword offset = (dword)(address - currIP); + + __ Emit8(0xe9); + __ Emit32(offset); +} + +} // namespace x86 +} // namespace zz + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/core/modules/codegen/codegen-ia32.h b/Bcore/src/main/cpp/Dobby/source/core/modules/codegen/codegen-ia32.h new file mode 100644 index 00000000..d10f3e8a --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/modules/codegen/codegen-ia32.h @@ -0,0 +1,22 @@ +#ifndef CORE_CODEGEN_X86_H +#define CORE_CODEGEN_X86_H + +#include "core/modules/codegen/codegen.h" +#include "core/modules/assembler/assembler.h" +#include "core/modules/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/Bcore/src/main/cpp/Dobby/source/core/modules/codegen/codegen-x64.cc b/Bcore/src/main/cpp/Dobby/source/core/modules/codegen/codegen-x64.cc new file mode 100644 index 00000000..c3bd7606 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/modules/codegen/codegen-x64.cc @@ -0,0 +1,25 @@ +#include "platform_macro.h" +#if defined(TARGET_ARCH_X64) + +#include "core/modules/codegen/codegen-x64.h" + +namespace zz { +namespace x64 { + +void CodeGen::JmpNearIndirect(uint64_t address) { + TurboAssembler *turbo_assembler_ = reinterpret_cast(this->assembler_); +#define _ turbo_assembler_-> +#define __ turbo_assembler_->GetCodeBuffer()-> + uint64_t currIP = turbo_assembler_->CurrentIP() + 6; + dword offset = (dword)(address - currIP); + + // RIP-relative addressing + __ Emit8(0xFF); + __ Emit8(0x25); + __ Emit32(offset); +} + +} // namespace x64 +} // namespace zz + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/core/modules/codegen/codegen-x64.h b/Bcore/src/main/cpp/Dobby/source/core/modules/codegen/codegen-x64.h new file mode 100644 index 00000000..cf7c5e69 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/modules/codegen/codegen-x64.h @@ -0,0 +1,22 @@ +#ifndef CORE_CODEGEN_X64_H +#define CORE_CODEGEN_X64_H + +#include "core/modules/codegen/codegen.h" +#include "core/modules/assembler/assembler.h" +#include "core/modules/assembler/assembler-x64.h" + +namespace zz { +namespace x64 { + +class CodeGen : public CodeGenBase { +public: + CodeGen(TurboAssembler *turbo_assembler) : CodeGenBase(turbo_assembler) { + } + + void JmpNearIndirect(uint64_t address); +}; + +} // namespace x64 +} // namespace zz + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/core/modules/codegen/codegen.h b/Bcore/src/main/cpp/Dobby/source/core/modules/codegen/codegen.h new file mode 100644 index 00000000..593ee102 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/core/modules/codegen/codegen.h @@ -0,0 +1,17 @@ +#ifndef CORE_CODEGEN_H +#define CORE_CODEGEN_H + +#include "core/modules/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/Bcore/src/main/cpp/Dobby/source/core/modules/emulator/dummy.cc b/Bcore/src/main/cpp/Dobby/source/core/modules/emulator/dummy.cc new file mode 100644 index 00000000..e69de29b diff --git a/Bcore/src/main/cpp/Dobby/source/dobby.cpp b/Bcore/src/main/cpp/Dobby/source/dobby.cpp new file mode 100644 index 00000000..bd286fee --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/dobby.cpp @@ -0,0 +1,38 @@ +#if defined(__linux__) || defined(__APPLE__) +#include +#include + +#include "dobby_internal.h" + +#include "Interceptor.h" + +__attribute__((constructor)) static void ctor() { + DLOG(-1, "================================"); + DLOG(-1, "Dobby"); + DLOG(-1, "================================"); + + DLOG(-1, "dobby in debug log mode, disable with cmake flag \"-DDOBBY_DEBUG=OFF\""); +} + +PUBLIC const char *DobbyBuildVersion() { + return __DOBBY_BUILD_VERSION__; +} + +PUBLIC int DobbyDestroy(void *address) { + // check if we already hook + HookEntry *entry = Interceptor::SharedInstance()->FindHookEntry(address); + if (entry) { + uint8_t *buffer = entry->origin_chunk_.chunk_buffer; + uint32_t buffer_size = entry->origin_chunk_.chunk.length; +#if defined(TARGET_ARCH_ARM) + address = (void *)((addr_t)address - 1); +#endif + CodePatch(address, buffer, buffer_size); + Interceptor::SharedInstance()->RemoveHookEntry(address); + return RT_SUCCESS; + } + + return RT_FAILED; +} + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/dobby_internal.h b/Bcore/src/main/cpp/Dobby/source/dobby_internal.h new file mode 100644 index 00000000..b037d88a --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/dobby_internal.h @@ -0,0 +1,57 @@ +#ifndef DOBBY_INTERNAL_H +#define DOBBY_INTERNAL_H + +#include "dobby.h" + +#include "logging/logging.h" +#include "logging/check_logging.h" + +#include "xnucxx/LiteMemOpt.h" +#include "xnucxx/LiteMutableArray.h" +#include "xnucxx/LiteMutableBuffer.h" +#include "xnucxx/LiteIterator.h" + +#include "UnifiedInterface/platform.h" + +#include "PlatformUnifiedInterface/StdMemory.h" +#include "PlatformUnifiedInterface/ExecMemory/CodePatchTool.h" +#include "PlatformUnifiedInterface/ExecMemory/ClearCacheTool.h" + +#include "MemoryAllocator/MemoryArena.h" +#include "MemoryAllocator/AssemblyCodeBuilder.h" + +#include +#include +#include +#include +#include + +typedef struct _AssemblyCodeChunkBuffer { + AssemblyCodeChunk chunk; + uint8_t chunk_buffer[64]; +} AssemblyCodeChunkBuffer; + +typedef enum { kFunctionWrapper, kFunctionInlineHook, kDynamicBinaryInstrument } HookEntryType; + +typedef struct { + int id; + int type; + + union { + void *target_address; + void *function_address; + void *instruction_address; + }; + + void *route; + + // fixed-instructions which we relocated(patched) + union { + void *relocated_origin_instructions; + void *relocated_origin_function; + }; + + AssemblyCodeChunkBuffer origin_chunk_; +} HookEntry; + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/include/common_header.h b/Bcore/src/main/cpp/Dobby/source/include/common_header.h new file mode 100644 index 00000000..094bc83d --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/include/common_header.h @@ -0,0 +1,11 @@ +#ifndef COMMON_HEADER_H +#define COMMON_HEADER_H + +#include "include/type_macro.h" +#include "include/platform_macro.h" +#include "include/utility_macro.h" + +#include "logging/logging.h" +#include "logging/check_logging.h" + +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/include/list_structure.h b/Bcore/src/main/cpp/Dobby/source/include/list_structure.h new file mode 100644 index 00000000..2d179d27 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/include/list_structure.h @@ -0,0 +1,52 @@ +#pragma once + +struct list_head { + struct list_head *next; + struct list_head *prev; +}; +#define container_of(ptr, type, member) \ + ({ \ + const __typeof(((type *)0)->member) *__mptr = (ptr); \ + (type *)((char *)__mptr - offsetof(type, member)); \ + }) + +#define INIT_LIST_HEAD(ptr) \ + do { \ + (ptr)->next = (ptr); \ + (ptr)->prev = (ptr); \ + } while (0) + +static inline int list_empty(struct list_head *head) { + return head->next == head; +} + +static void __list_add(struct list_head *new_node, struct list_head *prev, struct list_head *next) { + next->prev = new_node; + new_node->next = next; + new_node->prev = prev; + prev->next = new_node; +} + +static inline void list_add(struct list_head *new_node, struct list_head *head) { + __list_add(new_node, head, head->next); +} + +static inline void __list_del(struct list_head *prev, struct list_head *next) { + next->prev = prev; + prev->next = next; +} + +static inline void list_del(struct list_head *entry) { + __list_del(entry->prev, entry->next); + entry->next = NULL; + entry->prev = NULL; +} + +#define list_entry(ptr, type, member) container_of(ptr, type, member) + +#define list_first_entry(ptr, type, member) list_entry((ptr)->next, type, member) + +#define list_next_entry(pos, member) list_entry((pos)->member.next, typeof(*(pos)), member) + +#define list_for_each_entry(pos, head, member) \ + for (pos = list_first_entry(head, typeof(*pos), member); &pos->member != (head); pos = list_next_entry(pos, member)) \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/include/platform_macro.h b/Bcore/src/main/cpp/Dobby/source/include/platform_macro.h new file mode 100644 index 00000000..95c25d7a --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/include/platform_macro.h @@ -0,0 +1,19 @@ +#pragma once + +#if defined(_M_X64) || defined(__x86_64__) +#define TARGET_ARCH_X64 1 +#elif defined(_M_IX86) || defined(__i386__) +#define TARGET_ARCH_IA32 1 +#elif defined(__AARCH64EL__) +#define TARGET_ARCH_ARM64 1 +#elif defined(__ARMEL__) +#define TARGET_ARCH_ARM 1 +#elif defined(__mips64) +#define TARGET_ARCH_MIPS64 1 +#elif defined(__MIPSEB__) || defined(__MIPSEL__) +#define TARGET_ARCH_MIPS 1 +#elif defined(_ARCH_PPC) +#define TARGET_ARCH_PPC 1 +#else +#error Target architecture was not detected as supported by Dobby +#endif diff --git a/Bcore/src/main/cpp/Dobby/source/include/type_macro.h b/Bcore/src/main/cpp/Dobby/source/include/type_macro.h new file mode 100644 index 00000000..013e9313 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/include/type_macro.h @@ -0,0 +1,38 @@ +#pragma once + +#include + +#ifndef __addr_32_64_t_defined +#define __addr_32_64_t_defined +typedef uint32_t addr32_t; +typedef uint64_t addr64_t; +#endif + +#ifndef __addr_t_defined +#define __addr_t_defined +typedef uintptr_t 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 + +#ifndef NULL +#define NULL 0 +#endif \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/source/include/utility_macro.h b/Bcore/src/main/cpp/Dobby/source/include/utility_macro.h new file mode 100644 index 00000000..74bb73d6 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/source/include/utility_macro.h @@ -0,0 +1,63 @@ +#pragma once + +// offset of struct member +#define OFFSETOF(TYPE, ELEMENT) ((size_t) & (((TYPE *)0)->ELEMENT)) + +// assert +#include +#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) ((addr_t)address & ~((addr_t)range - 1)) +#define ALIGN_CEIL(address, range) (((addr_t)address + (addr_t)range - 1) & ~((addr_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/Bcore/src/main/cpp/Dobby/tests/CMakelists.txt b/Bcore/src/main/cpp/Dobby/tests/CMakelists.txt new file mode 100644 index 00000000..2df5fe7e --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/tests/CMakelists.txt @@ -0,0 +1,40 @@ +cmake_minimum_required(VERSION 3.5) +project(test_dobby) + +set(PrimaryPath ..) + +include(${PrimaryPath}/cmake/Globals.cmake) +include(${PrimaryPath}/cmake/Macros.cmake) + +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_C_STANDARD 11) +enable_language(ASM) + + +include_directories( + ${PrimaryPath}/tests + ${PrimaryPath}/source +) + +include_directories( + ${PrimaryPath}/source + ${PrimaryPath}/source/UserMode + ${PrimaryPath}/external + ${PrimaryPath}/external/logging + ${PrimaryPath}/external/xnucxx +) + +add_subdirectory(${PrimaryPath} dobby.out) + +add_executable(tests_instr_relo_x64 + ${PrimaryPath}/source/InstructionRelocation/x64/X64IPRelativeOpcodeTable.cc + ${PrimaryPath}/tests/InstructionRelocation/x64/test_x64_instruction_relocation.cc +) + +add_executable(tests_instr_relo_aarch64 + ${PrimaryPath}/tests/InstructionRelocation/aarch64/test_aarch64_instruction_relocation.cc +) +target_link_libraries(tests_instr_relo_aarch64 + dobby +) \ No newline at end of file diff --git a/Bcore/src/main/cpp/Dobby/tests/InstructionRelocation/aarch64/test_aarch64_instruction_relocation.cc b/Bcore/src/main/cpp/Dobby/tests/InstructionRelocation/aarch64/test_aarch64_instruction_relocation.cc new file mode 100644 index 00000000..d0f2a9cc --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/tests/InstructionRelocation/aarch64/test_aarch64_instruction_relocation.cc @@ -0,0 +1,62 @@ +#include +#include + +#if defined(__WIN32__) || defined(__APPLE__) +#define xcdecl(s) "_" s +#else +#define xcdecl(s) s +#endif + +#define xASM(x) __asm(x) + +__attribute__((naked)) void pc_relative_instructions() { + xASM("ldr x0, #4"); + xASM("nop"); + xASM("nop"); + + xASM("nop"); + xASM("nop"); + xASM("ldr x0, #-4"); + + xASM("adr x0, #4"); + + xASM("adrp x0, #0x1000"); + + xASM("tbz x0, #8, #4"); + + xASM("tbz x0, #27, #-4"); + + xASM("cbz x0, #4"); + + xASM("cbz x0, #-4"); + + xASM("cmp x0, x0"); + xASM("b.eq #-4"); +} + +__attribute__((naked)) void pc_relative_instructions_end() { +} + +#include "InstructionRelocation/arm64/ARM64InstructionRelocation.h" + +extern zz::AssemblyCode *GenRelocateCodeAndBranch(void *buffer, int *relocate_size, addr_t from_pc, addr_t to_pc); + +extern "C" { +int _main(int argc, const char **argv); +} + +int _main(int argc, const char **argv) { + LOG(1, "pc_relative_instructions: %p", pc_relative_instructions); + + char *relo_buffer = (char *)malloc(0x1000); + + int relo_size = (uint64_t)pc_relative_instructions_end - (uint64_t)pc_relative_instructions; + zz::AssemblyCode *code = GenRelocateCodeAndBranch((void *)pc_relative_instructions, &relo_size, 0, 0); + + unsigned char *instruction_bytes = (unsigned char *)code->raw_instruction_start(); + for (int i = 0; i < code->raw_instruction_size(); i += 1) { + printf("%.2x ", instruction_bytes[i]); + } + + return 0; +} diff --git a/Bcore/src/main/cpp/Dobby/tests/InstructionRelocation/x64/test_x64_instruction_relocation.cc b/Bcore/src/main/cpp/Dobby/tests/InstructionRelocation/x64/test_x64_instruction_relocation.cc new file mode 100644 index 00000000..f57391c0 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/tests/InstructionRelocation/x64/test_x64_instruction_relocation.cc @@ -0,0 +1,133 @@ +#define CATCH_CONFIG_MAIN + +#include "catch.hpp" + +#include + +#include "InstructionRelocation/x64/X64IPRelativeOpcodeTable.h" + +/* + +sub_140006C30 48 89 5C 24 08 mov [rsp+arg_0], rbx +sub_140006C30+5 48 89 74 24 10 mov [rsp+arg_8], rsi +sub_140006C30+A 57 push rdi +sub_140006C30+B 48 83 EC 40 sub rsp, 40h +sub_140006C30+F 48 8B F9 mov rdi, rcx +sub_140006C30+12 48 8D 99 70 02 00 00 lea rbx, [rcx+270h] +sub_140006C30+19 8B CA mov ecx, edx +sub_140006C30+1B 8B F2 mov esi, edx +sub_140006C30+1D E8 0E CA FF FF call sub_140003660 +sub_140006C30+1D +sub_140006C30+22 48 8B 0F mov rcx, [rdi] +sub_140006C30+25 48 8D 15 24 17 07 00 lea rdx, aCDvsP4BuildSwG_1 ; +"C:\\dvs\\p4\\build\\sw\\gcomp\\dev\\src"... sub_140006C30+2C 48 89 5C 24 30 mov +[rsp+48h+var_18], rbx sub_140006C30+31 41 B9 03 00 00 00 mov r9d, 3 +sub_140006C30+37 48 89 44 24 28 mov [rsp+48h+var_20], rax +sub_140006C30+3C 41 B8 F9 00 00 00 mov r8d, 0F9h +sub_140006C30+42 48 8D 05 EF 19 07 00 lea rax, aInitiateTransi ; "Initiate +transition to %s state for %s" sub_140006C30+49 48 89 44 24 20 mov +[rsp+48h+var_28], rax sub_140006C30+4E E8 ED D5 00 00 call sub_140014270 +sub_140006C30+4E +sub_140006C30+53 48 83 BF D0 02 00 00 00 cmp qword ptr [rdi+2D0h], 0 +sub_140006C30+5B 74 10 jz short loc_140006C9D +sub_140006C30+5B +sub_140006C30+5D E8 7E CA 00 00 call sub_140013710 +sub_140006C30+5D +sub_140006C30+62 48 8B 8F D0 02 00 00 mov rcx, [rdi+2D0h] +sub_140006C30+69 48 89 41 48 mov [rcx+48h], rax +sub_140006C30+69 +sub_140006C30+6D +sub_140006C30+6D loc_140006C9D: ; CODE XREF: +sub_140006C30+5B↑j sub_140006C30+6D 8B 97 34 03 00 00 mov edx, [rdi+334h] +sub_140006C30+73 48 8B 4F 08 mov rcx, [rdi+8] +sub_140006C30+77 89 B7 B0 02 00 00 mov [rdi+2B0h], esi +sub_140006C30+7D 48 8B 5C 24 50 mov rbx, [rsp+48h+arg_0] +sub_140006C30+82 48 8B 74 24 58 mov rsi, [rsp+48h+arg_8] +sub_140006C30+87 48 83 C4 40 add rsp, 40h +sub_140006C30+8B 5F pop rdi +sub_140006C30+8C E9 2F BC FF FF jmp sub_1400028F0 + +*/ + +//------------------------------------------------------------ +//----------- Created with 010 Editor ----------- +//------ www.sweetscape.com/010editor/ ------ +// +// File : C:\Users\jmpews\Downloads\NvContainer\nvcontainer.exe +// Address : 24624 (0x6030) +// Size : 145 (0x91) +//------------------------------------------------------------ +unsigned char hexData[145] = { + 0x48, 0x89, 0x5C, 0x24, 0x08, 0x48, 0x89, 0x74, 0x24, 0x10, 0x57, 0x48, 0x83, 0xEC, 0x40, 0x48, 0x8B, 0xF9, 0x48, + 0x8D, 0x99, 0x70, 0x02, 0x00, 0x00, 0x8B, 0xCA, 0x8B, 0xF2, 0xE8, 0x0E, 0xCA, 0xFF, 0xFF, 0x48, 0x8B, 0x0F, 0x48, + 0x8D, 0x15, 0x24, 0x17, 0x07, 0x00, 0x48, 0x89, 0x5C, 0x24, 0x30, 0x41, 0xB9, 0x03, 0x00, 0x00, 0x00, 0x48, 0x89, + 0x44, 0x24, 0x28, 0x41, 0xB8, 0xF9, 0x00, 0x00, 0x00, 0x48, 0x8D, 0x05, 0xEF, 0x19, 0x07, 0x00, 0x48, 0x89, 0x44, + 0x24, 0x20, 0xE8, 0xED, 0xD5, 0x00, 0x00, 0x48, 0x83, 0xBF, 0xD0, 0x02, 0x00, 0x00, 0x00, 0x74, 0x10, 0xE8, 0x7E, + 0xCA, 0x00, 0x00, 0x48, 0x8B, 0x8F, 0xD0, 0x02, 0x00, 0x00, 0x48, 0x89, 0x41, 0x48, 0x8B, 0x97, 0x34, 0x03, 0x00, + 0x00, 0x48, 0x8B, 0x4F, 0x08, 0x89, 0xB7, 0xB0, 0x02, 0x00, 0x00, 0x48, 0x8B, 0x5C, 0x24, 0x50, 0x48, 0x8B, 0x74, + 0x24, 0x58, 0x48, 0x83, 0xC4, 0x40, 0x5F, 0xE9, 0x2F, 0xBC, 0xFF, 0xFF}; + +// clang-format off +int instrLenArray[] = { + 5, + 5, + 1, + 4, + 3, + 7, + 2, + 2, + 5, + 3, + 7, + 5, + 6, + 5, + 6, + 7, + 5, + 5, + 8, + 2, + 5, + 7, + 4, + 6, + 4, + 6, + 5, + 5, + 4, + 1, + 5 +}; +// clang-format on + +TEST_CASE(">>> InstructionRelocation/x64", "[InstructionRelocation]") { + void *TargetFunction = hexData; + uintptr_t srcIP = (uintptr_t)TargetFunction; + uintptr_t currIP = srcIP; + int funcLen = sizeof(hexData); + unsigned char opcode1 = 0; + InstrMnemonic instr = {0}; + + int i = 0; + opcode1 = *(byte *)srcIP; + + do { + OpcodeDecodeItem *decodeItem = &OpcodeDecodeTable[opcode1]; + decodeItem->DecodeHandler(&instr, (addr_t)currIP); + + REQUIRE(instr.len == instrLenArray[i]); + currIP += instr.len; + opcode1 = *(byte *)currIP; + if (instr.instr.opcode) { + printf("ndx %d: %d\n", i, instr.len); + // clear instr + memset((void *)&instr, 0, sizeof(InstrMnemonic)); + } + i++; + } while (currIP < (srcIP + funcLen)); + + printf("InstructionRelocation/x64 Done!"); +} diff --git a/Bcore/src/main/cpp/Dobby/tests/catch.hpp b/Bcore/src/main/cpp/Dobby/tests/catch.hpp new file mode 100644 index 00000000..29747ef0 --- /dev/null +++ b/Bcore/src/main/cpp/Dobby/tests/catch.hpp @@ -0,0 +1,13017 @@ +/* + * Catch v2.2.3 + * Generated: 2018-06-06 23:11:57.601416 + * ---------------------------------------------------------- + * This file has been merged from multiple headers. Please don't edit it directly + * Copyright (c) 2018 Two Blue Cubes Ltd. All rights reserved. + * + * Distributed under the Boost Software License, Version 1.0. (See accompanying + * file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) + */ +#ifndef TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED +#define TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED +// start catch.hpp + +#define CATCH_VERSION_MAJOR 2 +#define CATCH_VERSION_MINOR 2 +#define CATCH_VERSION_PATCH 3 + +#ifdef __clang__ +#pragma clang system_header +#elif defined __GNUC__ +#pragma GCC system_header +#endif + +// start catch_suppress_warnings.h + +#ifdef __clang__ +#ifdef __ICC // icpc defines the __clang__ macro +#pragma warning(push) +#pragma warning(disable : 161 1682) +#else // __ICC +#pragma clang diagnostic ignored "-Wunused-variable" +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" +#pragma clang diagnostic ignored "-Wswitch-enum" +#pragma clang diagnostic ignored "-Wcovered-switch-default" +#endif +#elif defined __GNUC__ +#pragma GCC diagnostic ignored "-Wparentheses" +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wpadded" +#endif +// end catch_suppress_warnings.h +#if defined(CATCH_CONFIG_MAIN) || defined(CATCH_CONFIG_RUNNER) +#define CATCH_IMPL +#define CATCH_CONFIG_ALL_PARTS +#endif + +// In the impl file, we want to have access to all parts of the headers +// Can also be used to sanely support PCHs +#if defined(CATCH_CONFIG_ALL_PARTS) +#define CATCH_CONFIG_EXTERNAL_INTERFACES +#if defined(CATCH_CONFIG_DISABLE_MATCHERS) +#undef CATCH_CONFIG_DISABLE_MATCHERS +#endif +#define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER +#endif + +#if !defined(CATCH_CONFIG_IMPL_ONLY) +// start catch_platform.h + +#ifdef __APPLE__ +#include +#if TARGET_OS_OSX == 1 +#define CATCH_PLATFORM_MAC +#elif TARGET_OS_IPHONE == 1 +#define CATCH_PLATFORM_IPHONE +#endif + +#elif defined(linux) || defined(__linux) || defined(__linux__) +#define CATCH_PLATFORM_LINUX + +#elif defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER) || defined(__MINGW32__) +#define CATCH_PLATFORM_WINDOWS +#endif + +// end catch_platform.h + +#ifdef CATCH_IMPL +#ifndef CLARA_CONFIG_MAIN +#define CLARA_CONFIG_MAIN_NOT_DEFINED +#define CLARA_CONFIG_MAIN +#endif +#endif + +// start catch_user_interfaces.h + +namespace Catch { +unsigned int rngSeed(); +} + +// end catch_user_interfaces.h +// start catch_tag_alias_autoregistrar.h + +// start catch_common.h + +// start catch_compiler_capabilities.h + +// Detect a number of compiler features - by compiler +// The following features are defined: +// +// CATCH_CONFIG_COUNTER : is the __COUNTER__ macro supported? +// CATCH_CONFIG_WINDOWS_SEH : is Windows SEH supported? +// CATCH_CONFIG_POSIX_SIGNALS : are POSIX signals supported? +// **************** +// Note to maintainers: if new toggles are added please document them +// in configuration.md, too +// **************** + +// In general each macro has a _NO_ form +// (e.g. CATCH_CONFIG_NO_POSIX_SIGNALS) which disables the feature. +// Many features, at point of detection, define an _INTERNAL_ macro, so they +// can be combined, en-mass, with the _NO_ forms later. + +#ifdef __cplusplus + +#if __cplusplus >= 201402L +#define CATCH_CPP14_OR_GREATER +#endif + +#if __cplusplus >= 201703L +#define CATCH_CPP17_OR_GREATER +#endif + +#endif + +#if defined(CATCH_CPP17_OR_GREATER) +#define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS +#endif + +#ifdef __clang__ + +#define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wexit-time-destructors\"") \ + _Pragma("clang diagnostic ignored \"-Wglobal-constructors\"") +#define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS _Pragma("clang diagnostic pop") + +#define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ + _Pragma("clang diagnostic push") _Pragma("clang diagnostic ignored \"-Wparentheses\"") +#define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS _Pragma("clang diagnostic pop") + +#endif // __clang__ + +//////////////////////////////////////////////////////////////////////////////// +// Assume that non-Windows platforms support posix signals by default +#if !defined(CATCH_PLATFORM_WINDOWS) +#define CATCH_INTERNAL_CONFIG_POSIX_SIGNALS +#endif + +//////////////////////////////////////////////////////////////////////////////// +// We know some environments not to support full POSIX signals +#if defined(__CYGWIN__) || defined(__QNX__) || defined(__EMSCRIPTEN__) || defined(__DJGPP__) +#define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS +#endif + +#ifdef __OS400__ +#define CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS +#define CATCH_CONFIG_COLOUR_NONE +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Android somehow still does not support std::to_string +#if defined(__ANDROID__) +#define CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Not all Windows environments support SEH properly +#if defined(__MINGW32__) +#define CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH +#endif + +//////////////////////////////////////////////////////////////////////////////// +// Cygwin +#ifdef __CYGWIN__ + +// Required for some versions of Cygwin to declare gettimeofday +// see: http://stackoverflow.com/questions/36901803/gettimeofday-not-declared-in-this-scope-cygwin +#define _BSD_SOURCE + +#endif // __CYGWIN__ + +//////////////////////////////////////////////////////////////////////////////// +// Visual C++ +#ifdef _MSC_VER + +#if _MSC_VER >= 1900 // Visual Studio 2015 or newer +#define CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS +#endif + +// Universal Windows platform does not support SEH +// Or console colours (or console at all...) +#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) +#define CATCH_CONFIG_COLOUR_NONE +#else +#define CATCH_INTERNAL_CONFIG_WINDOWS_SEH +#endif + +#endif // _MSC_VER + +//////////////////////////////////////////////////////////////////////////////// + +// DJGPP +#ifdef __DJGPP__ +#define CATCH_INTERNAL_CONFIG_NO_WCHAR +#endif // __DJGPP__ + +//////////////////////////////////////////////////////////////////////////////// + +// Use of __COUNTER__ is suppressed during code analysis in +// CLion/AppCode 2017.2.x and former, because __COUNTER__ is not properly +// handled by it. +// Otherwise all supported compilers support COUNTER macro, +// but user still might want to turn it off +#if (!defined(__JETBRAINS_IDE__) || __JETBRAINS_IDE__ >= 20170300L) +#define CATCH_INTERNAL_CONFIG_COUNTER +#endif + +#if defined(CATCH_INTERNAL_CONFIG_COUNTER) && !defined(CATCH_CONFIG_NO_COUNTER) && !defined(CATCH_CONFIG_COUNTER) +#define CATCH_CONFIG_COUNTER +#endif +#if defined(CATCH_INTERNAL_CONFIG_WINDOWS_SEH) && !defined(CATCH_CONFIG_NO_WINDOWS_SEH) && \ + !defined(CATCH_CONFIG_WINDOWS_SEH) && !defined(CATCH_INTERNAL_CONFIG_NO_WINDOWS_SEH) +#define CATCH_CONFIG_WINDOWS_SEH +#endif +// This is set by default, because we assume that unix compilers are posix-signal-compatible by default. +#if defined(CATCH_INTERNAL_CONFIG_POSIX_SIGNALS) && !defined(CATCH_INTERNAL_CONFIG_NO_POSIX_SIGNALS) && \ + !defined(CATCH_CONFIG_NO_POSIX_SIGNALS) && !defined(CATCH_CONFIG_POSIX_SIGNALS) +#define CATCH_CONFIG_POSIX_SIGNALS +#endif +// This is set by default, because we assume that compilers with no wchar_t support are just rare exceptions. +#if !defined(CATCH_INTERNAL_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_NO_WCHAR) && !defined(CATCH_CONFIG_WCHAR) +#define CATCH_CONFIG_WCHAR +#endif + +#if !defined(CATCH_INTERNAL_CONFIG_NO_CPP11_TO_STRING) && !defined(CATCH_CONFIG_NO_CPP11_TO_STRING) && \ + !defined(CATCH_CONFIG_CPP11_TO_STRING) +#define CATCH_CONFIG_CPP11_TO_STRING +#endif + +#if defined(CATCH_INTERNAL_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) && !defined(CATCH_CONFIG_NO_CPP17_UNCAUGHT_EXCEPTIONS) && \ + !defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) +#define CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS +#endif + +#if !defined(CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS) +#define CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS +#define CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS +#endif +#if !defined(CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS) +#define CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS +#define CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS +#endif + +// end catch_compiler_capabilities.h +#define INTERNAL_CATCH_UNIQUE_NAME_LINE2(name, line) name##line +#define INTERNAL_CATCH_UNIQUE_NAME_LINE(name, line) INTERNAL_CATCH_UNIQUE_NAME_LINE2(name, line) +#ifdef CATCH_CONFIG_COUNTER +#define INTERNAL_CATCH_UNIQUE_NAME(name) INTERNAL_CATCH_UNIQUE_NAME_LINE(name, __COUNTER__) +#else +#define INTERNAL_CATCH_UNIQUE_NAME(name) INTERNAL_CATCH_UNIQUE_NAME_LINE(name, __LINE__) +#endif + +#include +#include +#include + +namespace Catch { + +struct CaseSensitive { + enum Choice { Yes, No }; +}; + +class NonCopyable { + NonCopyable(NonCopyable const &) = delete; + NonCopyable(NonCopyable &&) = delete; + NonCopyable &operator=(NonCopyable const &) = delete; + NonCopyable &operator=(NonCopyable &&) = delete; + +protected: + NonCopyable(); + virtual ~NonCopyable(); +}; + +struct SourceLineInfo { + + SourceLineInfo() = delete; + SourceLineInfo(char const *_file, std::size_t _line) noexcept : file(_file), line(_line) { + } + + SourceLineInfo(SourceLineInfo const &other) = default; + SourceLineInfo(SourceLineInfo &&) = default; + SourceLineInfo &operator=(SourceLineInfo const &) = default; + SourceLineInfo &operator=(SourceLineInfo &&) = default; + + bool empty() const noexcept; + bool operator==(SourceLineInfo const &other) const noexcept; + bool operator<(SourceLineInfo const &other) const noexcept; + + char const *file; + std::size_t line; +}; + +std::ostream &operator<<(std::ostream &os, SourceLineInfo const &info); + +// Use this in variadic streaming macros to allow +// >> +StreamEndStop +// as well as +// >> stuff +StreamEndStop +struct StreamEndStop { + std::string operator+() const; +}; +template T const &operator+(T const &value, StreamEndStop) { + return value; +} +} // namespace Catch + +#define CATCH_INTERNAL_LINEINFO ::Catch::SourceLineInfo(__FILE__, static_cast(__LINE__)) + +// end catch_common.h +namespace Catch { + +struct RegistrarForTagAliases { + RegistrarForTagAliases(char const *alias, char const *tag, SourceLineInfo const &lineInfo); +}; + +} // end namespace Catch + +#define CATCH_REGISTER_TAG_ALIAS(alias, spec) \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace { \ + Catch::RegistrarForTagAliases INTERNAL_CATCH_UNIQUE_NAME(AutoRegisterTagAlias)(alias, spec, \ + CATCH_INTERNAL_LINEINFO); \ + } \ + CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS + +// end catch_tag_alias_autoregistrar.h +// start catch_test_registry.h + +// start catch_interfaces_testcase.h + +#include +#include + +namespace Catch { + +class TestSpec; + +struct ITestInvoker { + virtual void invoke() const = 0; + virtual ~ITestInvoker(); +}; + +using ITestCasePtr = std::shared_ptr; + +class TestCase; +struct IConfig; + +struct ITestCaseRegistry { + virtual ~ITestCaseRegistry(); + virtual std::vector const &getAllTests() const = 0; + virtual std::vector const &getAllTestsSorted(IConfig const &config) const = 0; +}; + +bool matchTest(TestCase const &testCase, TestSpec const &testSpec, IConfig const &config); +std::vector filterTests(std::vector const &testCases, TestSpec const &testSpec, + IConfig const &config); +std::vector const &getAllTestCasesSorted(IConfig const &config); + +} // namespace Catch + +// end catch_interfaces_testcase.h +// start catch_stringref.h + +#include +#include +#include + +namespace Catch { + +class StringData; + +/// A non-owning string class (similar to the forthcoming std::string_view) +/// Note that, because a StringRef may be a substring of another string, +/// it may not be null terminated. c_str() must return a null terminated +/// string, however, and so the StringRef will internally take ownership +/// (taking a copy), if necessary. In theory this ownership is not externally +/// visible - but it does mean (substring) StringRefs should not be shared between +/// threads. +class StringRef { +public: + using size_type = std::size_t; + +private: + friend struct StringRefTestAccess; + + char const *m_start; + size_type m_size; + + char *m_data = nullptr; + + void takeOwnership(); + + static constexpr char const *const s_empty = ""; + +public: // construction/ assignment + StringRef() noexcept : StringRef(s_empty, 0) { + } + + StringRef(StringRef const &other) noexcept : m_start(other.m_start), m_size(other.m_size) { + } + + StringRef(StringRef &&other) noexcept : m_start(other.m_start), m_size(other.m_size), m_data(other.m_data) { + other.m_data = nullptr; + } + + StringRef(char const *rawChars) noexcept; + + StringRef(char const *rawChars, size_type size) noexcept : m_start(rawChars), m_size(size) { + } + + StringRef(std::string const &stdString) noexcept : m_start(stdString.c_str()), m_size(stdString.size()) { + } + + ~StringRef() noexcept { + delete[] m_data; + } + + auto operator=(StringRef const &other) noexcept -> StringRef & { + delete[] m_data; + m_data = nullptr; + m_start = other.m_start; + m_size = other.m_size; + return *this; + } + + operator std::string() const; + + void swap(StringRef &other) noexcept; + +public: // operators + auto operator==(StringRef const &other) const noexcept -> bool; + auto operator!=(StringRef const &other) const noexcept -> bool; + + auto operator[](size_type index) const noexcept -> char; + +public: // named queries + auto empty() const noexcept -> bool { + return m_size == 0; + } + auto size() const noexcept -> size_type { + return m_size; + } + + auto numberOfCharacters() const noexcept -> size_type; + auto c_str() const -> char const *; + +public: // substrings and searches + auto substr(size_type start, size_type size) const noexcept -> StringRef; + + // Returns the current start pointer. + // Note that the pointer can change when if the StringRef is a substring + auto currentData() const noexcept -> char const *; + +private: // ownership queries - may not be consistent between calls + auto isOwned() const noexcept -> bool; + auto isSubstring() const noexcept -> bool; +}; + +auto operator+(StringRef const &lhs, StringRef const &rhs) -> std::string; +auto operator+(StringRef const &lhs, char const *rhs) -> std::string; +auto operator+(char const *lhs, StringRef const &rhs) -> std::string; + +auto operator+=(std::string &lhs, StringRef const &sr) -> std::string &; +auto operator<<(std::ostream &os, StringRef const &sr) -> std::ostream &; + +inline auto operator"" _sr(char const *rawChars, std::size_t size) noexcept -> StringRef { + return StringRef(rawChars, size); +} + +} // namespace Catch + +// end catch_stringref.h +namespace Catch { + +template class TestInvokerAsMethod : public ITestInvoker { + void (C::*m_testAsMethod)(); + +public: + TestInvokerAsMethod(void (C::*testAsMethod)()) noexcept : m_testAsMethod(testAsMethod) { + } + + void invoke() const override { + C obj; + (obj.*m_testAsMethod)(); + } +}; + +auto makeTestInvoker(void (*testAsFunction)()) noexcept -> ITestInvoker *; + +template auto makeTestInvoker(void (C::*testAsMethod)()) noexcept -> ITestInvoker * { + return new (std::nothrow) TestInvokerAsMethod(testAsMethod); +} + +struct NameAndTags { + NameAndTags(StringRef const &name_ = StringRef(), StringRef const &tags_ = StringRef()) noexcept; + StringRef name; + StringRef tags; +}; + +struct AutoReg : NonCopyable { + AutoReg(ITestInvoker *invoker, SourceLineInfo const &lineInfo, StringRef const &classOrMethod, + NameAndTags const &nameAndTags) noexcept; + ~AutoReg(); +}; + +} // end namespace Catch + +#define INTERNAL_CATCH_EXPAND1(param) INTERNAL_CATCH_EXPAND2(param) +#define INTERNAL_CATCH_EXPAND2(...) INTERNAL_CATCH_NO##__VA_ARGS__ +#define INTERNAL_CATCH_DEF(...) INTERNAL_CATCH_DEF __VA_ARGS__ +#define INTERNAL_CATCH_NOINTERNAL_CATCH_DEF + +#if defined(CATCH_CONFIG_DISABLE) +#define INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(TestName, ...) static void TestName() +#define INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(TestName, ClassName, ...) \ + namespace { \ + struct TestName : INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF ClassName) { \ + void test(); \ + }; \ + } \ + void TestName::test() + +#endif + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_TESTCASE2(TestName, ...) \ + static void TestName(); \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace { \ + Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME(autoRegistrar)(Catch::makeTestInvoker(&TestName), CATCH_INTERNAL_LINEINFO, \ + "", Catch::NameAndTags{__VA_ARGS__}); \ + } /* NOLINT */ \ + CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \ + static void TestName() +#define INTERNAL_CATCH_TESTCASE(...) \ + INTERNAL_CATCH_TESTCASE2(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____), __VA_ARGS__) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_METHOD_AS_TEST_CASE(QualifiedMethod, ...) \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace { \ + Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME(autoRegistrar)(Catch::makeTestInvoker(&QualifiedMethod), \ + CATCH_INTERNAL_LINEINFO, "&" #QualifiedMethod, \ + Catch::NameAndTags{__VA_ARGS__}); \ + } /* NOLINT */ \ + CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_TEST_CASE_METHOD2(TestName, ClassName, ...) \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace { \ + struct TestName : INTERNAL_CATCH_EXPAND1(INTERNAL_CATCH_DEF ClassName) { \ + void test(); \ + }; \ + Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME(autoRegistrar)(Catch::makeTestInvoker(&TestName::test), \ + CATCH_INTERNAL_LINEINFO, #ClassName, \ + Catch::NameAndTags{__VA_ARGS__}); /* NOLINT */ \ + } \ + CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \ + void TestName::test() +#define INTERNAL_CATCH_TEST_CASE_METHOD(ClassName, ...) \ + INTERNAL_CATCH_TEST_CASE_METHOD2(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____), ClassName, __VA_ARGS__) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_REGISTER_TESTCASE(Function, ...) \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + Catch::AutoReg INTERNAL_CATCH_UNIQUE_NAME(autoRegistrar)(Catch::makeTestInvoker(Function), CATCH_INTERNAL_LINEINFO, \ + "", Catch::NameAndTags{__VA_ARGS__}); /* NOLINT */ \ + CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS + +// end catch_test_registry.h +// start catch_capture.hpp + +// start catch_assertionhandler.h + +// start catch_assertioninfo.h + +// start catch_result_type.h + +namespace Catch { + +// ResultWas::OfType enum +struct ResultWas { + enum OfType { + Unknown = -1, + Ok = 0, + Info = 1, + Warning = 2, + + FailureBit = 0x10, + + ExpressionFailed = FailureBit | 1, + ExplicitFailure = FailureBit | 2, + + Exception = 0x100 | FailureBit, + + ThrewException = Exception | 1, + DidntThrowException = Exception | 2, + + FatalErrorCondition = 0x200 | FailureBit + + }; +}; + +bool isOk(ResultWas::OfType resultType); +bool isJustInfo(int flags); + +// ResultDisposition::Flags enum +struct ResultDisposition { + enum Flags { + Normal = 0x01, + + ContinueOnFailure = 0x02, // Failures fail test, but execution continues + FalseTest = 0x04, // Prefix expression with ! + SuppressFail = 0x08 // Failures are reported but do not fail the test + }; +}; + +ResultDisposition::Flags operator|(ResultDisposition::Flags lhs, ResultDisposition::Flags rhs); + +bool shouldContinueOnFailure(int flags); +inline bool isFalseTest(int flags) { + return (flags & ResultDisposition::FalseTest) != 0; +} +bool shouldSuppressFailure(int flags); + +} // end namespace Catch + +// end catch_result_type.h +namespace Catch { + +struct AssertionInfo { + StringRef macroName; + SourceLineInfo lineInfo; + StringRef capturedExpression; + ResultDisposition::Flags resultDisposition; + + // We want to delete this constructor but a compiler bug in 4.8 means + // the struct is then treated as non-aggregate + //AssertionInfo() = delete; +}; + +} // end namespace Catch + +// end catch_assertioninfo.h +// start catch_decomposer.h + +// start catch_tostring.h + +#include +#include +#include +#include +// start catch_stream.h + +#include +#include +#include + +namespace Catch { + +std::ostream &cout(); +std::ostream &cerr(); +std::ostream &clog(); + +class StringRef; + +struct IStream { + virtual ~IStream(); + virtual std::ostream &stream() const = 0; +}; + +auto makeStream(StringRef const &filename) -> IStream const *; + +class ReusableStringStream { + std::size_t m_index; + std::ostream *m_oss; + +public: + ReusableStringStream(); + ~ReusableStringStream(); + + auto str() const -> std::string; + + template auto operator<<(T const &value) -> ReusableStringStream & { + *m_oss << value; + return *this; + } + auto get() -> std::ostream & { + return *m_oss; + } + + static void cleanup(); +}; +} // namespace Catch + +// end catch_stream.h + +#ifdef __OBJC__ +// start catch_objc_arc.hpp + +#import + +#ifdef __has_feature +#define CATCH_ARC_ENABLED __has_feature(objc_arc) +#else +#define CATCH_ARC_ENABLED 0 +#endif + +void arcSafeRelease(NSObject *obj); +id performOptionalSelector(id obj, SEL sel); + +#if !CATCH_ARC_ENABLED +inline void arcSafeRelease(NSObject *obj) { + [obj release]; +} +inline id performOptionalSelector(id obj, SEL sel) { + if ([obj respondsToSelector:sel]) + return [obj performSelector:sel]; + return nil; +} +#define CATCH_UNSAFE_UNRETAINED +#define CATCH_ARC_STRONG +#else +inline void arcSafeRelease(NSObject *) { +} +inline id performOptionalSelector(id obj, SEL sel) { +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" +#endif + if ([obj respondsToSelector:sel]) + return [obj performSelector:sel]; +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + return nil; +} +#define CATCH_UNSAFE_UNRETAINED __unsafe_unretained +#define CATCH_ARC_STRONG __strong +#endif + +// end catch_objc_arc.hpp +#endif + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning( \ + disable : 4180) // We attempt to stream a function (address) by const&, which MSVC complains about but is harmless +#endif + +// We need a dummy global operator<< so we can bring it into Catch namespace later +struct Catch_global_namespace_dummy {}; +std::ostream &operator<<(std::ostream &, Catch_global_namespace_dummy); + +namespace Catch { +// Bring in operator<< from global namespace into Catch namespace +using ::operator<<; + +namespace Detail { + +extern const std::string unprintableString; + +std::string rawMemoryToString(const void *object, std::size_t size); + +template std::string rawMemoryToString(const T &object) { + return rawMemoryToString(&object, sizeof(object)); +} + +template class IsStreamInsertable { + template + static auto test(int) -> decltype(std::declval() << std::declval(), std::true_type()); + + template static auto test(...) -> std::false_type; + +public: + static const bool value = decltype(test(0))::value; +}; + +template std::string convertUnknownEnumToString(E e); + +template +typename std::enable_if::value && !std::is_base_of::value, std::string>::type +convertUnstreamable(T const &) { + return Detail::unprintableString; +} +template +typename std::enable_if::value && std::is_base_of::value, std::string>::type +convertUnstreamable(T const &ex) { + return ex.what(); +} + +template +typename std::enable_if::value, std::string>::type convertUnstreamable(T const &value) { + return convertUnknownEnumToString(value); +} + +#if defined(_MANAGED) +//! Convert a CLR string to a utf8 std::string +template std::string clrReferenceToString(T ^ ref) { + if (ref == nullptr) + return std::string("null"); + auto bytes = System::Text::Encoding::UTF8->GetBytes(ref->ToString()); + cli::pin_ptr p = &bytes[0]; + return std::string(reinterpret_cast(p), bytes->Length); +} +#endif + +} // namespace Detail + +// If we decide for C++14, change these to enable_if_ts +template struct StringMaker { + template + static typename std::enable_if<::Catch::Detail::IsStreamInsertable::value, std::string>::type + convert(const Fake &value) { + ReusableStringStream rss; + // NB: call using the function-like syntax to avoid ambiguity with + // user-defined templated operator<< under clang. + rss.operator<<(value); + return rss.str(); + } + + template + static typename std::enable_if::value, std::string>::type + convert(const Fake &value) { +#if !defined(CATCH_CONFIG_FALLBACK_STRINGIFIER) + return Detail::convertUnstreamable(value); +#else + return CATCH_CONFIG_FALLBACK_STRINGIFIER(value); +#endif + } +}; + +namespace Detail { + +// This function dispatches all stringification requests inside of Catch. +// Should be preferably called fully qualified, like ::Catch::Detail::stringify +template std::string stringify(const T &e) { + return ::Catch::StringMaker::type>::type>::convert(e); +} + +template std::string convertUnknownEnumToString(E e) { + return ::Catch::Detail::stringify(static_cast::type>(e)); +} + +#if defined(_MANAGED) +template std::string stringify(T ^ e) { + return ::Catch::StringMaker::convert(e); +} +#endif + +} // namespace Detail + +// Some predefined specializations + +template <> struct StringMaker { static std::string convert(const std::string &str); }; +#ifdef CATCH_CONFIG_WCHAR +template <> struct StringMaker { static std::string convert(const std::wstring &wstr); }; +#endif + +template <> struct StringMaker { static std::string convert(char const *str); }; +template <> struct StringMaker { static std::string convert(char *str); }; + +#ifdef CATCH_CONFIG_WCHAR +template <> struct StringMaker { static std::string convert(wchar_t const *str); }; +template <> struct StringMaker { static std::string convert(wchar_t *str); }; +#endif + +// TBD: Should we use `strnlen` to ensure that we don't go out of the buffer, +// while keeping string semantics? +template struct StringMaker { + static std::string convert(char const *str) { + return ::Catch::Detail::stringify(std::string{str}); + } +}; +template struct StringMaker { + static std::string convert(signed char const *str) { + return ::Catch::Detail::stringify(std::string{reinterpret_cast(str)}); + } +}; +template struct StringMaker { + static std::string convert(unsigned char const *str) { + return ::Catch::Detail::stringify(std::string{reinterpret_cast(str)}); + } +}; + +template <> struct StringMaker { static std::string convert(int value); }; +template <> struct StringMaker { static std::string convert(long value); }; +template <> struct StringMaker { static std::string convert(long long value); }; +template <> struct StringMaker { static std::string convert(unsigned int value); }; +template <> struct StringMaker { static std::string convert(unsigned long value); }; +template <> struct StringMaker { static std::string convert(unsigned long long value); }; + +template <> struct StringMaker { static std::string convert(bool b); }; + +template <> struct StringMaker { static std::string convert(char c); }; +template <> struct StringMaker { static std::string convert(signed char c); }; +template <> struct StringMaker { static std::string convert(unsigned char c); }; + +template <> struct StringMaker { static std::string convert(std::nullptr_t); }; + +template <> struct StringMaker { static std::string convert(float value); }; +template <> struct StringMaker { static std::string convert(double value); }; + +template struct StringMaker { + template static std::string convert(U *p) { + if (p) { + return ::Catch::Detail::rawMemoryToString(p); + } else { + return "nullptr"; + } + } +}; + +template struct StringMaker { + static std::string convert(R C::*p) { + if (p) { + return ::Catch::Detail::rawMemoryToString(p); + } else { + return "nullptr"; + } + } +}; + +#if defined(_MANAGED) +template struct StringMaker { + static std::string convert(T ^ ref) { + return ::Catch::Detail::clrReferenceToString(ref); + } +}; +#endif + +namespace Detail { +template std::string rangeToString(InputIterator first, InputIterator last) { + ReusableStringStream rss; + rss << "{ "; + if (first != last) { + rss << ::Catch::Detail::stringify(*first); + for (++first; first != last; ++first) + rss << ", " << ::Catch::Detail::stringify(*first); + } + rss << " }"; + return rss.str(); +} +} // namespace Detail + +#ifdef __OBJC__ +template <> struct StringMaker { + static std::string convert(NSString *nsstring) { + if (!nsstring) + return "nil"; + return std::string("@") + [nsstring UTF8String]; + } +}; +template <> struct StringMaker { + static std::string convert(NSObject *nsObject) { + return ::Catch::Detail::stringify([nsObject description]); + } +}; +namespace Detail { +inline std::string stringify(NSString *nsstring) { + return StringMaker::convert(nsstring); +} + +} // namespace Detail +#endif // __OBJC__ + +} // namespace Catch + +////////////////////////////////////////////////////// +// Separate std-lib types stringification, so it can be selectively enabled +// This means that we do not bring in + +#if defined(CATCH_CONFIG_ENABLE_ALL_STRINGMAKERS) +#define CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER +#define CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER +#define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER +#endif + +// Separate std::pair specialization +#if defined(CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER) +#include +namespace Catch { +template struct StringMaker> { + static std::string convert(const std::pair &pair) { + ReusableStringStream rss; + rss << "{ " << ::Catch::Detail::stringify(pair.first) << ", " << ::Catch::Detail::stringify(pair.second) << " }"; + return rss.str(); + } +}; +} // namespace Catch +#endif // CATCH_CONFIG_ENABLE_PAIR_STRINGMAKER + +// Separate std::tuple specialization +#if defined(CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER) +#include +namespace Catch { +namespace Detail { +template ::value)> struct TupleElementPrinter { + static void print(const Tuple &tuple, std::ostream &os) { + os << (N ? ", " : " ") << ::Catch::Detail::stringify(std::get(tuple)); + TupleElementPrinter::print(tuple, os); + } +}; + +template struct TupleElementPrinter { + static void print(const Tuple &, std::ostream &) { + } +}; + +} // namespace Detail + +template struct StringMaker> { + static std::string convert(const std::tuple &tuple) { + ReusableStringStream rss; + rss << '{'; + Detail::TupleElementPrinter>::print(tuple, rss.get()); + rss << " }"; + return rss.str(); + } +}; +} // namespace Catch +#endif // CATCH_CONFIG_ENABLE_TUPLE_STRINGMAKER + +namespace Catch { +struct not_this_one {}; // Tag type for detecting which begin/ end are being selected + +// Import begin/ end from std here so they are considered alongside the fallback (...) overloads in this namespace +using std::begin; +using std::end; + +not_this_one begin(...); +not_this_one end(...); + +template struct is_range { + static const bool value = !std::is_same())), not_this_one>::value && + !std::is_same())), not_this_one>::value; +}; + +#if defined(_MANAGED) // Managed types are never ranges +template struct is_range { static const bool value = false; }; +#endif + +template std::string rangeToString(Range const &range) { + return ::Catch::Detail::rangeToString(begin(range), end(range)); +} + +// Handle vector specially +template std::string rangeToString(std::vector const &v) { + ReusableStringStream rss; + rss << "{ "; + bool first = true; + for (bool b : v) { + if (first) + first = false; + else + rss << ", "; + rss << ::Catch::Detail::stringify(b); + } + rss << " }"; + return rss.str(); +} + +template +struct StringMaker< + R, typename std::enable_if::value && !::Catch::Detail::IsStreamInsertable::value>::type> { + static std::string convert(R const &range) { + return rangeToString(range); + } +}; + +template struct StringMaker { + static std::string convert(T const (&arr)[SZ]) { + return rangeToString(arr); + } +}; + +} // namespace Catch + +// Separate std::chrono::duration specialization +#if defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER) +#include +#include +#include + +namespace Catch { + +template struct ratio_string { static std::string symbol(); }; + +template std::string ratio_string::symbol() { + Catch::ReusableStringStream rss; + rss << '[' << Ratio::num << '/' << Ratio::den << ']'; + return rss.str(); +} +template <> struct ratio_string { static std::string symbol(); }; +template <> struct ratio_string { static std::string symbol(); }; +template <> struct ratio_string { static std::string symbol(); }; +template <> struct ratio_string { static std::string symbol(); }; +template <> struct ratio_string { static std::string symbol(); }; +template <> struct ratio_string { static std::string symbol(); }; + +//////////// +// std::chrono::duration specializations +template struct StringMaker> { + static std::string convert(std::chrono::duration const &duration) { + ReusableStringStream rss; + rss << duration.count() << ' ' << ratio_string::symbol() << 's'; + return rss.str(); + } +}; +template struct StringMaker>> { + static std::string convert(std::chrono::duration> const &duration) { + ReusableStringStream rss; + rss << duration.count() << " s"; + return rss.str(); + } +}; +template struct StringMaker>> { + static std::string convert(std::chrono::duration> const &duration) { + ReusableStringStream rss; + rss << duration.count() << " m"; + return rss.str(); + } +}; +template struct StringMaker>> { + static std::string convert(std::chrono::duration> const &duration) { + ReusableStringStream rss; + rss << duration.count() << " h"; + return rss.str(); + } +}; + +//////////// +// std::chrono::time_point specialization +// Generic time_point cannot be specialized, only std::chrono::time_point +template struct StringMaker> { + static std::string convert(std::chrono::time_point const &time_point) { + return ::Catch::Detail::stringify(time_point.time_since_epoch()) + " since epoch"; + } +}; +// std::chrono::time_point specialization +template struct StringMaker> { + static std::string convert(std::chrono::time_point const &time_point) { + auto converted = std::chrono::system_clock::to_time_t(time_point); + +#ifdef _MSC_VER + std::tm timeInfo = {}; + gmtime_s(&timeInfo, &converted); +#else + std::tm *timeInfo = std::gmtime(&converted); +#endif + + auto const timeStampSize = sizeof("2017-01-16T17:06:45Z"); + char timeStamp[timeStampSize]; + const char *const fmt = "%Y-%m-%dT%H:%M:%SZ"; + +#ifdef _MSC_VER + std::strftime(timeStamp, timeStampSize, fmt, &timeInfo); +#else + std::strftime(timeStamp, timeStampSize, fmt, timeInfo); +#endif + return std::string(timeStamp); + } +}; +} // namespace Catch +#endif // CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +// end catch_tostring.h +#include + +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable : 4389) // '==' : signed/unsigned mismatch +#pragma warning(disable : 4018) // more "signed/unsigned mismatch" +#pragma warning(disable : 4312) // Converting int to T* using reinterpret_cast (issue on x64 platform) +#pragma warning(disable : 4180) // qualifier applied to function type has no meaning +#endif + +namespace Catch { + +struct ITransientExpression { + auto isBinaryExpression() const -> bool { + return m_isBinaryExpression; + } + auto getResult() const -> bool { + return m_result; + } + virtual void streamReconstructedExpression(std::ostream &os) const = 0; + + ITransientExpression(bool isBinaryExpression, bool result) + : m_isBinaryExpression(isBinaryExpression), m_result(result) { + } + + // We don't actually need a virtual destructor, but many static analysers + // complain if it's not here :-( + virtual ~ITransientExpression(); + + bool m_isBinaryExpression; + bool m_result; +}; + +void formatReconstructedExpression(std::ostream &os, std::string const &lhs, StringRef op, std::string const &rhs); + +template class BinaryExpr : public ITransientExpression { + LhsT m_lhs; + StringRef m_op; + RhsT m_rhs; + + void streamReconstructedExpression(std::ostream &os) const override { + formatReconstructedExpression(os, Catch::Detail::stringify(m_lhs), m_op, Catch::Detail::stringify(m_rhs)); + } + +public: + BinaryExpr(bool comparisonResult, LhsT lhs, StringRef op, RhsT rhs) + : ITransientExpression{true, comparisonResult}, m_lhs(lhs), m_op(op), m_rhs(rhs) { + } +}; + +template class UnaryExpr : public ITransientExpression { + LhsT m_lhs; + + void streamReconstructedExpression(std::ostream &os) const override { + os << Catch::Detail::stringify(m_lhs); + } + +public: + explicit UnaryExpr(LhsT lhs) : ITransientExpression{false, lhs ? true : false}, m_lhs(lhs) { + } +}; + +// Specialised comparison functions to handle equality comparisons between ints and pointers (NULL deduces as an int) +template auto compareEqual(LhsT const &lhs, RhsT const &rhs) -> bool { + return static_cast(lhs == rhs); +} +template auto compareEqual(T *const &lhs, int rhs) -> bool { + return lhs == reinterpret_cast(rhs); +} +template auto compareEqual(T *const &lhs, long rhs) -> bool { + return lhs == reinterpret_cast(rhs); +} +template auto compareEqual(int lhs, T *const &rhs) -> bool { + return reinterpret_cast(lhs) == rhs; +} +template auto compareEqual(long lhs, T *const &rhs) -> bool { + return reinterpret_cast(lhs) == rhs; +} + +template auto compareNotEqual(LhsT const &lhs, RhsT &&rhs) -> bool { + return static_cast(lhs != rhs); +} +template auto compareNotEqual(T *const &lhs, int rhs) -> bool { + return lhs != reinterpret_cast(rhs); +} +template auto compareNotEqual(T *const &lhs, long rhs) -> bool { + return lhs != reinterpret_cast(rhs); +} +template auto compareNotEqual(int lhs, T *const &rhs) -> bool { + return reinterpret_cast(lhs) != rhs; +} +template auto compareNotEqual(long lhs, T *const &rhs) -> bool { + return reinterpret_cast(lhs) != rhs; +} + +template class ExprLhs { + LhsT m_lhs; + +public: + explicit ExprLhs(LhsT lhs) : m_lhs(lhs) { + } + + template auto operator==(RhsT const &rhs) -> BinaryExpr const { + return {compareEqual(m_lhs, rhs), m_lhs, "==", rhs}; + } + auto operator==(bool rhs) -> BinaryExpr const { + return {m_lhs == rhs, m_lhs, "==", rhs}; + } + + template auto operator!=(RhsT const &rhs) -> BinaryExpr const { + return {compareNotEqual(m_lhs, rhs), m_lhs, "!=", rhs}; + } + auto operator!=(bool rhs) -> BinaryExpr const { + return {m_lhs != rhs, m_lhs, "!=", rhs}; + } + + template auto operator>(RhsT const &rhs) -> BinaryExpr const { + return {static_cast(m_lhs > rhs), m_lhs, ">", rhs}; + } + template auto operator<(RhsT const &rhs) -> BinaryExpr const { + return {static_cast(m_lhs < rhs), m_lhs, "<", rhs}; + } + template auto operator>=(RhsT const &rhs) -> BinaryExpr const { + return {static_cast(m_lhs >= rhs), m_lhs, ">=", rhs}; + } + template auto operator<=(RhsT const &rhs) -> BinaryExpr const { + return {static_cast(m_lhs <= rhs), m_lhs, "<=", rhs}; + } + + auto makeUnaryExpr() const -> UnaryExpr { + return UnaryExpr{m_lhs}; + } +}; + +void handleExpression(ITransientExpression const &expr); + +template void handleExpression(ExprLhs const &expr) { + handleExpression(expr.makeUnaryExpr()); +} + +struct Decomposer { + template auto operator<=(T const &lhs) -> ExprLhs { + return ExprLhs{lhs}; + } + + auto operator<=(bool value) -> ExprLhs { + return ExprLhs{value}; + } +}; + +} // end namespace Catch + +#ifdef _MSC_VER +#pragma warning(pop) +#endif + +// end catch_decomposer.h +// start catch_interfaces_capture.h + +#include + +namespace Catch { + +class AssertionResult; +struct AssertionInfo; +struct SectionInfo; +struct SectionEndInfo; +struct MessageInfo; +struct Counts; +struct BenchmarkInfo; +struct BenchmarkStats; +struct AssertionReaction; + +struct ITransientExpression; + +struct IResultCapture { + + virtual ~IResultCapture(); + + virtual bool sectionStarted(SectionInfo const §ionInfo, Counts &assertions) = 0; + virtual void sectionEnded(SectionEndInfo const &endInfo) = 0; + virtual void sectionEndedEarly(SectionEndInfo const &endInfo) = 0; + + virtual void benchmarkStarting(BenchmarkInfo const &info) = 0; + virtual void benchmarkEnded(BenchmarkStats const &stats) = 0; + + virtual void pushScopedMessage(MessageInfo const &message) = 0; + virtual void popScopedMessage(MessageInfo const &message) = 0; + + virtual void handleFatalErrorCondition(StringRef message) = 0; + + virtual void handleExpr(AssertionInfo const &info, ITransientExpression const &expr, AssertionReaction &reaction) = 0; + virtual void handleMessage(AssertionInfo const &info, ResultWas::OfType resultType, StringRef const &message, + AssertionReaction &reaction) = 0; + virtual void handleUnexpectedExceptionNotThrown(AssertionInfo const &info, AssertionReaction &reaction) = 0; + virtual void handleUnexpectedInflightException(AssertionInfo const &info, std::string const &message, + AssertionReaction &reaction) = 0; + virtual void handleIncomplete(AssertionInfo const &info) = 0; + virtual void handleNonExpr(AssertionInfo const &info, ResultWas::OfType resultType, AssertionReaction &reaction) = 0; + + virtual bool lastAssertionPassed() = 0; + virtual void assertionPassed() = 0; + + // Deprecated, do not use: + virtual std::string getCurrentTestName() const = 0; + virtual const AssertionResult *getLastResult() const = 0; + virtual void exceptionEarlyReported() = 0; +}; + +IResultCapture &getResultCapture(); +} // namespace Catch + +// end catch_interfaces_capture.h +namespace Catch { + +struct TestFailureException {}; +struct AssertionResultData; +struct IResultCapture; +class RunContext; + +class LazyExpression { + friend class AssertionHandler; + friend struct AssertionStats; + friend class RunContext; + + ITransientExpression const *m_transientExpression = nullptr; + bool m_isNegated; + +public: + LazyExpression(bool isNegated); + LazyExpression(LazyExpression const &other); + LazyExpression &operator=(LazyExpression const &) = delete; + + explicit operator bool() const; + + friend auto operator<<(std::ostream &os, LazyExpression const &lazyExpr) -> std::ostream &; +}; + +struct AssertionReaction { + bool shouldDebugBreak = false; + bool shouldThrow = false; +}; + +class AssertionHandler { + AssertionInfo m_assertionInfo; + AssertionReaction m_reaction; + bool m_completed = false; + IResultCapture &m_resultCapture; + +public: + AssertionHandler(StringRef macroName, SourceLineInfo const &lineInfo, StringRef capturedExpression, + ResultDisposition::Flags resultDisposition); + ~AssertionHandler() { + if (!m_completed) { + m_resultCapture.handleIncomplete(m_assertionInfo); + } + } + + template void handleExpr(ExprLhs const &expr) { + handleExpr(expr.makeUnaryExpr()); + } + void handleExpr(ITransientExpression const &expr); + + void handleMessage(ResultWas::OfType resultType, StringRef const &message); + + void handleExceptionThrownAsExpected(); + void handleUnexpectedExceptionNotThrown(); + void handleExceptionNotThrownAsExpected(); + void handleThrowingCallSkipped(); + void handleUnexpectedInflightException(); + + void complete(); + void setCompleted(); + + // query + auto allowThrows() const -> bool; +}; + +void handleExceptionMatchExpr(AssertionHandler &handler, std::string const &str, StringRef matcherString); + +} // namespace Catch + +// end catch_assertionhandler.h +// start catch_message.h + +#include + +namespace Catch { + +struct MessageInfo { + MessageInfo(std::string const &_macroName, SourceLineInfo const &_lineInfo, ResultWas::OfType _type); + + std::string macroName; + std::string message; + SourceLineInfo lineInfo; + ResultWas::OfType type; + unsigned int sequence; + + bool operator==(MessageInfo const &other) const; + bool operator<(MessageInfo const &other) const; + +private: + static unsigned int globalCount; +}; + +struct MessageStream { + + template MessageStream &operator<<(T const &value) { + m_stream << value; + return *this; + } + + ReusableStringStream m_stream; +}; + +struct MessageBuilder : MessageStream { + MessageBuilder(std::string const ¯oName, SourceLineInfo const &lineInfo, ResultWas::OfType type); + + template MessageBuilder &operator<<(T const &value) { + m_stream << value; + return *this; + } + + MessageInfo m_info; +}; + +class ScopedMessage { +public: + explicit ScopedMessage(MessageBuilder const &builder); + ~ScopedMessage(); + + MessageInfo m_info; +}; + +} // end namespace Catch + +// end catch_message.h +#if !defined(CATCH_CONFIG_DISABLE) + +#if !defined(CATCH_CONFIG_DISABLE_STRINGIFICATION) +#define CATCH_INTERNAL_STRINGIFY(...) #__VA_ARGS__ +#else +#define CATCH_INTERNAL_STRINGIFY(...) "Disabled by CATCH_CONFIG_DISABLE_STRINGIFICATION" +#endif + +#if defined(CATCH_CONFIG_FAST_COMPILE) + +/////////////////////////////////////////////////////////////////////////////// +// Another way to speed-up compilation is to omit local try-catch for REQUIRE* +// macros. +#define INTERNAL_CATCH_TRY +#define INTERNAL_CATCH_CATCH(capturer) + +#else // CATCH_CONFIG_FAST_COMPILE + +#define INTERNAL_CATCH_TRY try +#define INTERNAL_CATCH_CATCH(handler) \ + catch (...) { \ + handler.handleUnexpectedInflightException(); \ + } + +#endif + +#define INTERNAL_CATCH_REACT(handler) handler.complete(); + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_TEST(macroName, resultDisposition, ...) \ + do { \ + Catch::AssertionHandler catchAssertionHandler(macroName, CATCH_INTERNAL_LINEINFO, \ + CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \ + INTERNAL_CATCH_TRY { \ + CATCH_INTERNAL_SUPPRESS_PARENTHESES_WARNINGS \ + catchAssertionHandler.handleExpr(Catch::Decomposer() <= __VA_ARGS__); \ + CATCH_INTERNAL_UNSUPPRESS_PARENTHESES_WARNINGS \ + } \ + INTERNAL_CATCH_CATCH(catchAssertionHandler) \ + INTERNAL_CATCH_REACT(catchAssertionHandler) \ + } while ( \ + (void)0, \ + false && \ + static_cast(!!( \ + __VA_ARGS__))) // the expression here is never evaluated at runtime but it forces the compiler to give it a look +// The double negation silences MSVC's C4800 warning, the static_cast forces short-circuit evaluation if the type has overloaded &&. + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_IF(macroName, resultDisposition, ...) \ + INTERNAL_CATCH_TEST(macroName, resultDisposition, __VA_ARGS__); \ + if (Catch::getResultCapture().lastAssertionPassed()) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_ELSE(macroName, resultDisposition, ...) \ + INTERNAL_CATCH_TEST(macroName, resultDisposition, __VA_ARGS__); \ + if (!Catch::getResultCapture().lastAssertionPassed()) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_NO_THROW(macroName, resultDisposition, ...) \ + do { \ + Catch::AssertionHandler catchAssertionHandler(macroName, CATCH_INTERNAL_LINEINFO, \ + CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \ + try { \ + static_cast(__VA_ARGS__); \ + catchAssertionHandler.handleExceptionNotThrownAsExpected(); \ + } catch (...) { \ + catchAssertionHandler.handleUnexpectedInflightException(); \ + } \ + INTERNAL_CATCH_REACT(catchAssertionHandler) \ + } while (false) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_THROWS(macroName, resultDisposition, ...) \ + do { \ + Catch::AssertionHandler catchAssertionHandler(macroName, CATCH_INTERNAL_LINEINFO, \ + CATCH_INTERNAL_STRINGIFY(__VA_ARGS__), resultDisposition); \ + if (catchAssertionHandler.allowThrows()) \ + try { \ + static_cast(__VA_ARGS__); \ + catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \ + } catch (...) { \ + catchAssertionHandler.handleExceptionThrownAsExpected(); \ + } \ + else \ + catchAssertionHandler.handleThrowingCallSkipped(); \ + INTERNAL_CATCH_REACT(catchAssertionHandler) \ + } while (false) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_THROWS_AS(macroName, exceptionType, resultDisposition, expr) \ + do { \ + Catch::AssertionHandler catchAssertionHandler( \ + macroName, CATCH_INTERNAL_LINEINFO, \ + CATCH_INTERNAL_STRINGIFY(expr) ", " CATCH_INTERNAL_STRINGIFY(exceptionType), resultDisposition); \ + if (catchAssertionHandler.allowThrows()) \ + try { \ + static_cast(expr); \ + catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \ + } catch (exceptionType const &) { \ + catchAssertionHandler.handleExceptionThrownAsExpected(); \ + } catch (...) { \ + catchAssertionHandler.handleUnexpectedInflightException(); \ + } \ + else \ + catchAssertionHandler.handleThrowingCallSkipped(); \ + INTERNAL_CATCH_REACT(catchAssertionHandler) \ + } while (false) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_MSG(macroName, messageType, resultDisposition, ...) \ + do { \ + Catch::AssertionHandler catchAssertionHandler(macroName, CATCH_INTERNAL_LINEINFO, "", resultDisposition); \ + catchAssertionHandler.handleMessage( \ + messageType, (Catch::MessageStream() << __VA_ARGS__ + ::Catch::StreamEndStop()).m_stream.str()); \ + INTERNAL_CATCH_REACT(catchAssertionHandler) \ + } while (false) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_INFO(macroName, log) \ + Catch::ScopedMessage INTERNAL_CATCH_UNIQUE_NAME(scopedMessage)( \ + Catch::MessageBuilder(macroName, CATCH_INTERNAL_LINEINFO, Catch::ResultWas::Info) << log); + +/////////////////////////////////////////////////////////////////////////////// +// Although this is matcher-based, it can be used with just a string +#define INTERNAL_CATCH_THROWS_STR_MATCHES(macroName, resultDisposition, matcher, ...) \ + do { \ + Catch::AssertionHandler catchAssertionHandler( \ + macroName, CATCH_INTERNAL_LINEINFO, \ + CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY(matcher), resultDisposition); \ + if (catchAssertionHandler.allowThrows()) \ + try { \ + static_cast(__VA_ARGS__); \ + catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \ + } catch (...) { \ + Catch::handleExceptionMatchExpr(catchAssertionHandler, matcher, #matcher); \ + } \ + else \ + catchAssertionHandler.handleThrowingCallSkipped(); \ + INTERNAL_CATCH_REACT(catchAssertionHandler) \ + } while (false) + +#endif // CATCH_CONFIG_DISABLE + +// end catch_capture.hpp +// start catch_section.h + +// start catch_section_info.h + +// start catch_totals.h + +#include + +namespace Catch { + +struct Counts { + Counts operator-(Counts const &other) const; + Counts &operator+=(Counts const &other); + + std::size_t total() const; + bool allPassed() const; + bool allOk() const; + + std::size_t passed = 0; + std::size_t failed = 0; + std::size_t failedButOk = 0; +}; + +struct Totals { + + Totals operator-(Totals const &other) const; + Totals &operator+=(Totals const &other); + + Totals delta(Totals const &prevTotals) const; + + int error = 0; + Counts assertions; + Counts testCases; +}; +} // namespace Catch + +// end catch_totals.h +#include + +namespace Catch { + +struct SectionInfo { + SectionInfo(SourceLineInfo const &_lineInfo, std::string const &_name, + std::string const &_description = std::string()); + + std::string name; + std::string description; + SourceLineInfo lineInfo; +}; + +struct SectionEndInfo { + SectionEndInfo(SectionInfo const &_sectionInfo, Counts const &_prevAssertions, double _durationInSeconds); + + SectionInfo sectionInfo; + Counts prevAssertions; + double durationInSeconds; +}; + +} // end namespace Catch + +// end catch_section_info.h +// start catch_timer.h + +#include + +namespace Catch { + +auto getCurrentNanosecondsSinceEpoch() -> uint64_t; +auto getEstimatedClockResolution() -> uint64_t; + +class Timer { + uint64_t m_nanoseconds = 0; + +public: + void start(); + auto getElapsedNanoseconds() const -> uint64_t; + auto getElapsedMicroseconds() const -> uint64_t; + auto getElapsedMilliseconds() const -> unsigned int; + auto getElapsedSeconds() const -> double; +}; + +} // namespace Catch + +// end catch_timer.h +#include + +namespace Catch { + +class Section : NonCopyable { +public: + Section(SectionInfo const &info); + ~Section(); + + // This indicates whether the section should be executed or not + explicit operator bool() const; + +private: + SectionInfo m_info; + + std::string m_name; + Counts m_assertions; + bool m_sectionIncluded; + Timer m_timer; +}; + +} // end namespace Catch + +#define INTERNAL_CATCH_SECTION(...) \ + if (Catch::Section const &INTERNAL_CATCH_UNIQUE_NAME(catch_internal_Section) = \ + Catch::SectionInfo(CATCH_INTERNAL_LINEINFO, __VA_ARGS__)) + +// end catch_section.h +// start catch_benchmark.h + +#include +#include + +namespace Catch { + +class BenchmarkLooper { + + std::string m_name; + std::size_t m_count = 0; + std::size_t m_iterationsToRun = 1; + uint64_t m_resolution; + Timer m_timer; + + static auto getResolution() -> uint64_t; + +public: + // Keep most of this inline as it's on the code path that is being timed + BenchmarkLooper(StringRef name) : m_name(name), m_resolution(getResolution()) { + reportStart(); + m_timer.start(); + } + + explicit operator bool() { + if (m_count < m_iterationsToRun) + return true; + return needsMoreIterations(); + } + + void increment() { + ++m_count; + } + + void reportStart(); + auto needsMoreIterations() -> bool; +}; + +} // end namespace Catch + +#define BENCHMARK(name) for (Catch::BenchmarkLooper looper(name); looper; looper.increment()) + +// end catch_benchmark.h +// start catch_interfaces_exception.h + +// start catch_interfaces_registry_hub.h + +#include +#include + +namespace Catch { + +class TestCase; +struct ITestCaseRegistry; +struct IExceptionTranslatorRegistry; +struct IExceptionTranslator; +struct IReporterRegistry; +struct IReporterFactory; +struct ITagAliasRegistry; +class StartupExceptionRegistry; + +using IReporterFactoryPtr = std::shared_ptr; + +struct IRegistryHub { + virtual ~IRegistryHub(); + + virtual IReporterRegistry const &getReporterRegistry() const = 0; + virtual ITestCaseRegistry const &getTestCaseRegistry() const = 0; + virtual ITagAliasRegistry const &getTagAliasRegistry() const = 0; + + virtual IExceptionTranslatorRegistry &getExceptionTranslatorRegistry() = 0; + + virtual StartupExceptionRegistry const &getStartupExceptionRegistry() const = 0; +}; + +struct IMutableRegistryHub { + virtual ~IMutableRegistryHub(); + virtual void registerReporter(std::string const &name, IReporterFactoryPtr const &factory) = 0; + virtual void registerListener(IReporterFactoryPtr const &factory) = 0; + virtual void registerTest(TestCase const &testInfo) = 0; + virtual void registerTranslator(const IExceptionTranslator *translator) = 0; + virtual void registerTagAlias(std::string const &alias, std::string const &tag, SourceLineInfo const &lineInfo) = 0; + virtual void registerStartupException() noexcept = 0; +}; + +IRegistryHub &getRegistryHub(); +IMutableRegistryHub &getMutableRegistryHub(); +void cleanUp(); +std::string translateActiveException(); + +} // namespace Catch + +// end catch_interfaces_registry_hub.h +#if defined(CATCH_CONFIG_DISABLE) +#define INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG(translatorName, signature) \ + static std::string translatorName(signature) +#endif + +#include +#include +#include + +namespace Catch { +using exceptionTranslateFunction = std::string (*)(); + +struct IExceptionTranslator; +using ExceptionTranslators = std::vector>; + +struct IExceptionTranslator { + virtual ~IExceptionTranslator(); + virtual std::string translate(ExceptionTranslators::const_iterator it, + ExceptionTranslators::const_iterator itEnd) const = 0; +}; + +struct IExceptionTranslatorRegistry { + virtual ~IExceptionTranslatorRegistry(); + + virtual std::string translateActiveException() const = 0; +}; + +class ExceptionTranslatorRegistrar { + template class ExceptionTranslator : public IExceptionTranslator { + public: + ExceptionTranslator(std::string (*translateFunction)(T &)) : m_translateFunction(translateFunction) { + } + + std::string translate(ExceptionTranslators::const_iterator it, + ExceptionTranslators::const_iterator itEnd) const override { + try { + if (it == itEnd) + std::rethrow_exception(std::current_exception()); + else + return (*it)->translate(it + 1, itEnd); + } catch (T &ex) { + return m_translateFunction(ex); + } + } + + protected: + std::string (*m_translateFunction)(T &); + }; + +public: + template ExceptionTranslatorRegistrar(std::string (*translateFunction)(T &)) { + getMutableRegistryHub().registerTranslator(new ExceptionTranslator(translateFunction)); + } +}; +} // namespace Catch + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_TRANSLATE_EXCEPTION2(translatorName, signature) \ + static std::string translatorName(signature); \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace { \ + Catch::ExceptionTranslatorRegistrar INTERNAL_CATCH_UNIQUE_NAME(catch_internal_ExceptionRegistrar)(&translatorName); \ + } \ + CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS \ + static std::string translatorName(signature) + +#define INTERNAL_CATCH_TRANSLATE_EXCEPTION(signature) \ + INTERNAL_CATCH_TRANSLATE_EXCEPTION2(INTERNAL_CATCH_UNIQUE_NAME(catch_internal_ExceptionTranslator), signature) + +// end catch_interfaces_exception.h +// start catch_approx.h + +#include +#include + +namespace Catch { +namespace Detail { + +class Approx { +private: + bool equalityComparisonImpl(double other) const; + +public: + explicit Approx(double value); + + static Approx custom(); + + template ::value>::type> + Approx operator()(T const &value) { + Approx approx(static_cast(value)); + approx.epsilon(m_epsilon); + approx.margin(m_margin); + approx.scale(m_scale); + return approx; + } + + template ::value>::type> + explicit Approx(T const &value) : Approx(static_cast(value)) { + } + + template ::value>::type> + friend bool operator==(const T &lhs, Approx const &rhs) { + auto lhs_v = static_cast(lhs); + return rhs.equalityComparisonImpl(lhs_v); + } + + template ::value>::type> + friend bool operator==(Approx const &lhs, const T &rhs) { + return operator==(rhs, lhs); + } + + template ::value>::type> + friend bool operator!=(T const &lhs, Approx const &rhs) { + return !operator==(lhs, rhs); + } + + template ::value>::type> + friend bool operator!=(Approx const &lhs, T const &rhs) { + return !operator==(rhs, lhs); + } + + template ::value>::type> + friend bool operator<=(T const &lhs, Approx const &rhs) { + return static_cast(lhs) < rhs.m_value || lhs == rhs; + } + + template ::value>::type> + friend bool operator<=(Approx const &lhs, T const &rhs) { + return lhs.m_value < static_cast(rhs) || lhs == rhs; + } + + template ::value>::type> + friend bool operator>=(T const &lhs, Approx const &rhs) { + return static_cast(lhs) > rhs.m_value || lhs == rhs; + } + + template ::value>::type> + friend bool operator>=(Approx const &lhs, T const &rhs) { + return lhs.m_value > static_cast(rhs) || lhs == rhs; + } + + template ::value>::type> + Approx &epsilon(T const &newEpsilon) { + double epsilonAsDouble = static_cast(newEpsilon); + if (epsilonAsDouble < 0 || epsilonAsDouble > 1.0) { + throw std::domain_error("Invalid Approx::epsilon: " + Catch::Detail::stringify(epsilonAsDouble) + + ", Approx::epsilon has to be between 0 and 1"); + } + m_epsilon = epsilonAsDouble; + return *this; + } + + template ::value>::type> + Approx &margin(T const &newMargin) { + double marginAsDouble = static_cast(newMargin); + if (marginAsDouble < 0) { + throw std::domain_error("Invalid Approx::margin: " + Catch::Detail::stringify(marginAsDouble) + + ", Approx::Margin has to be non-negative."); + } + m_margin = marginAsDouble; + return *this; + } + + template ::value>::type> + Approx &scale(T const &newScale) { + m_scale = static_cast(newScale); + return *this; + } + + std::string toString() const; + +private: + double m_epsilon; + double m_margin; + double m_scale; + double m_value; +}; +} // namespace Detail + +template <> struct StringMaker { + static std::string convert(Catch::Detail::Approx const &value); +}; + +} // end namespace Catch + +// end catch_approx.h +// start catch_string_manip.h + +#include +#include + +namespace Catch { + +bool startsWith(std::string const &s, std::string const &prefix); +bool startsWith(std::string const &s, char prefix); +bool endsWith(std::string const &s, std::string const &suffix); +bool endsWith(std::string const &s, char suffix); +bool contains(std::string const &s, std::string const &infix); +void toLowerInPlace(std::string &s); +std::string toLower(std::string const &s); +std::string trim(std::string const &str); +bool replaceInPlace(std::string &str, std::string const &replaceThis, std::string const &withThis); + +struct pluralise { + pluralise(std::size_t count, std::string const &label); + + friend std::ostream &operator<<(std::ostream &os, pluralise const &pluraliser); + + std::size_t m_count; + std::string m_label; +}; +} // namespace Catch + +// end catch_string_manip.h +#ifndef CATCH_CONFIG_DISABLE_MATCHERS +// start catch_capture_matchers.h + +// start catch_matchers.h + +#include +#include + +namespace Catch { +namespace Matchers { +namespace Impl { + +template struct MatchAllOf; +template struct MatchAnyOf; +template struct MatchNotOf; + +class MatcherUntypedBase { +public: + MatcherUntypedBase() = default; + MatcherUntypedBase(MatcherUntypedBase const &) = default; + MatcherUntypedBase &operator=(MatcherUntypedBase const &) = delete; + std::string toString() const; + +protected: + virtual ~MatcherUntypedBase(); + virtual std::string describe() const = 0; + mutable std::string m_cachedToString; +}; + +template struct MatcherMethod { virtual bool match(ObjectT const &arg) const = 0; }; +template struct MatcherMethod { virtual bool match(PtrT *arg) const = 0; }; + +template struct MatcherBase : MatcherUntypedBase, MatcherMethod { + + MatchAllOf operator&&(MatcherBase const &other) const; + MatchAnyOf operator||(MatcherBase const &other) const; + MatchNotOf operator!() const; +}; + +template struct MatchAllOf : MatcherBase { + bool match(ArgT const &arg) const override { + for (auto matcher : m_matchers) { + if (!matcher->match(arg)) + return false; + } + return true; + } + std::string describe() const override { + std::string description; + description.reserve(4 + m_matchers.size() * 32); + description += "( "; + bool first = true; + for (auto matcher : m_matchers) { + if (first) + first = false; + else + description += " and "; + description += matcher->toString(); + } + description += " )"; + return description; + } + + MatchAllOf &operator&&(MatcherBase const &other) { + m_matchers.push_back(&other); + return *this; + } + + std::vector const *> m_matchers; +}; +template struct MatchAnyOf : MatcherBase { + + bool match(ArgT const &arg) const override { + for (auto matcher : m_matchers) { + if (matcher->match(arg)) + return true; + } + return false; + } + std::string describe() const override { + std::string description; + description.reserve(4 + m_matchers.size() * 32); + description += "( "; + bool first = true; + for (auto matcher : m_matchers) { + if (first) + first = false; + else + description += " or "; + description += matcher->toString(); + } + description += " )"; + return description; + } + + MatchAnyOf &operator||(MatcherBase const &other) { + m_matchers.push_back(&other); + return *this; + } + + std::vector const *> m_matchers; +}; + +template struct MatchNotOf : MatcherBase { + + MatchNotOf(MatcherBase const &underlyingMatcher) : m_underlyingMatcher(underlyingMatcher) { + } + + bool match(ArgT const &arg) const override { + return !m_underlyingMatcher.match(arg); + } + + std::string describe() const override { + return "not " + m_underlyingMatcher.toString(); + } + MatcherBase const &m_underlyingMatcher; +}; + +template MatchAllOf MatcherBase::operator&&(MatcherBase const &other) const { + return MatchAllOf() && *this && other; +} +template MatchAnyOf MatcherBase::operator||(MatcherBase const &other) const { + return MatchAnyOf() || *this || other; +} +template MatchNotOf MatcherBase::operator!() const { + return MatchNotOf(*this); +} + +} // namespace Impl + +} // namespace Matchers + +using namespace Matchers; +using Matchers::Impl::MatcherBase; + +} // namespace Catch + +// end catch_matchers.h +// start catch_matchers_floating.h + +#include +#include + +namespace Catch { +namespace Matchers { + +namespace Floating { + +enum class FloatingPointKind : uint8_t; + +struct WithinAbsMatcher : MatcherBase { + WithinAbsMatcher(double target, double margin); + bool match(double const &matchee) const override; + std::string describe() const override; + +private: + double m_target; + double m_margin; +}; + +struct WithinUlpsMatcher : MatcherBase { + WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType); + bool match(double const &matchee) const override; + std::string describe() const override; + +private: + double m_target; + int m_ulps; + FloatingPointKind m_type; +}; + +} // namespace Floating + +// The following functions create the actual matcher objects. +// This allows the types to be inferred +Floating::WithinUlpsMatcher WithinULP(double target, int maxUlpDiff); +Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff); +Floating::WithinAbsMatcher WithinAbs(double target, double margin); + +} // namespace Matchers +} // namespace Catch + +// end catch_matchers_floating.h +// start catch_matchers_generic.hpp + +#include +#include + +namespace Catch { +namespace Matchers { +namespace Generic { + +namespace Detail { +std::string finalizeDescription(const std::string &desc); +} + +template class PredicateMatcher : public MatcherBase { + std::function m_predicate; + std::string m_description; + +public: + PredicateMatcher(std::function const &elem, std::string const &descr) + : m_predicate(std::move(elem)), m_description(Detail::finalizeDescription(descr)) { + } + + bool match(T const &item) const override { + return m_predicate(item); + } + + std::string describe() const override { + return m_description; + } +}; + +} // namespace Generic + +// The following functions create the actual matcher objects. +// The user has to explicitly specify type to the function, because +// infering std::function is hard (but possible) and +// requires a lot of TMP. +template +Generic::PredicateMatcher Predicate(std::function const &predicate, + std::string const &description = "") { + return Generic::PredicateMatcher(predicate, description); +} + +} // namespace Matchers +} // namespace Catch + +// end catch_matchers_generic.hpp +// start catch_matchers_string.h + +#include + +namespace Catch { +namespace Matchers { + +namespace StdString { + +struct CasedString { + CasedString(std::string const &str, CaseSensitive::Choice caseSensitivity); + std::string adjustString(std::string const &str) const; + std::string caseSensitivitySuffix() const; + + CaseSensitive::Choice m_caseSensitivity; + std::string m_str; +}; + +struct StringMatcherBase : MatcherBase { + StringMatcherBase(std::string const &operation, CasedString const &comparator); + std::string describe() const override; + + CasedString m_comparator; + std::string m_operation; +}; + +struct EqualsMatcher : StringMatcherBase { + EqualsMatcher(CasedString const &comparator); + bool match(std::string const &source) const override; +}; +struct ContainsMatcher : StringMatcherBase { + ContainsMatcher(CasedString const &comparator); + bool match(std::string const &source) const override; +}; +struct StartsWithMatcher : StringMatcherBase { + StartsWithMatcher(CasedString const &comparator); + bool match(std::string const &source) const override; +}; +struct EndsWithMatcher : StringMatcherBase { + EndsWithMatcher(CasedString const &comparator); + bool match(std::string const &source) const override; +}; + +struct RegexMatcher : MatcherBase { + RegexMatcher(std::string regex, CaseSensitive::Choice caseSensitivity); + bool match(std::string const &matchee) const override; + std::string describe() const override; + +private: + std::string m_regex; + CaseSensitive::Choice m_caseSensitivity; +}; + +} // namespace StdString + +// The following functions create the actual matcher objects. +// This allows the types to be inferred + +StdString::EqualsMatcher Equals(std::string const &str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes); +StdString::ContainsMatcher Contains(std::string const &str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes); +StdString::EndsWithMatcher EndsWith(std::string const &str, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes); +StdString::StartsWithMatcher StartsWith(std::string const &str, + CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes); +StdString::RegexMatcher Matches(std::string const ®ex, CaseSensitive::Choice caseSensitivity = CaseSensitive::Yes); + +} // namespace Matchers +} // namespace Catch + +// end catch_matchers_string.h +// start catch_matchers_vector.h + +#include + +namespace Catch { +namespace Matchers { + +namespace Vector { +namespace Detail { +template size_t count(InputIterator first, InputIterator last, T const &item) { + size_t cnt = 0; + for (; first != last; ++first) { + if (*first == item) { + ++cnt; + } + } + return cnt; +} +template bool contains(InputIterator first, InputIterator last, T const &item) { + for (; first != last; ++first) { + if (*first == item) { + return true; + } + } + return false; +} +} // namespace Detail + +template struct ContainsElementMatcher : MatcherBase> { + + ContainsElementMatcher(T const &comparator) : m_comparator(comparator) { + } + + bool match(std::vector const &v) const override { + for (auto const &el : v) { + if (el == m_comparator) { + return true; + } + } + return false; + } + + std::string describe() const override { + return "Contains: " + ::Catch::Detail::stringify(m_comparator); + } + + T const &m_comparator; +}; + +template struct ContainsMatcher : MatcherBase> { + + ContainsMatcher(std::vector const &comparator) : m_comparator(comparator) { + } + + bool match(std::vector const &v) const override { + // !TBD: see note in EqualsMatcher + if (m_comparator.size() > v.size()) + return false; + for (auto const &comparator : m_comparator) { + auto present = false; + for (const auto &el : v) { + if (el == comparator) { + present = true; + break; + } + } + if (!present) { + return false; + } + } + return true; + } + std::string describe() const override { + return "Contains: " + ::Catch::Detail::stringify(m_comparator); + } + + std::vector const &m_comparator; +}; + +template struct EqualsMatcher : MatcherBase> { + + EqualsMatcher(std::vector const &comparator) : m_comparator(comparator) { + } + + bool match(std::vector const &v) const override { + // !TBD: This currently works if all elements can be compared using != + // - a more general approach would be via a compare template that defaults + // to using !=. but could be specialised for, e.g. std::vector etc + // - then just call that directly + if (m_comparator.size() != v.size()) + return false; + for (std::size_t i = 0; i < v.size(); ++i) + if (m_comparator[i] != v[i]) + return false; + return true; + } + std::string describe() const override { + return "Equals: " + ::Catch::Detail::stringify(m_comparator); + } + std::vector const &m_comparator; +}; + +template struct UnorderedEqualsMatcher : MatcherBase> { + UnorderedEqualsMatcher(std::vector const &target) : m_target(target) { + } + bool match(std::vector const &vec) const override { + // Note: This is a reimplementation of std::is_permutation, + // because I don't want to include inside the common path + if (m_target.size() != vec.size()) { + return false; + } + auto lfirst = m_target.begin(), llast = m_target.end(); + auto rfirst = vec.begin(), rlast = vec.end(); + // Cut common prefix to optimize checking of permuted parts + while (lfirst != llast && *lfirst != *rfirst) { + ++lfirst; + ++rfirst; + } + if (lfirst == llast) { + return true; + } + + for (auto mid = lfirst; mid != llast; ++mid) { + // Skip already counted items + if (Detail::contains(lfirst, mid, *mid)) { + continue; + } + size_t num_vec = Detail::count(rfirst, rlast, *mid); + if (num_vec == 0 || Detail::count(lfirst, llast, *mid) != num_vec) { + return false; + } + } + + return true; + } + + std::string describe() const override { + return "UnorderedEquals: " + ::Catch::Detail::stringify(m_target); + } + +private: + std::vector const &m_target; +}; + +} // namespace Vector + +// The following functions create the actual matcher objects. +// This allows the types to be inferred + +template Vector::ContainsMatcher Contains(std::vector const &comparator) { + return Vector::ContainsMatcher(comparator); +} + +template Vector::ContainsElementMatcher VectorContains(T const &comparator) { + return Vector::ContainsElementMatcher(comparator); +} + +template Vector::EqualsMatcher Equals(std::vector const &comparator) { + return Vector::EqualsMatcher(comparator); +} + +template Vector::UnorderedEqualsMatcher UnorderedEquals(std::vector const &target) { + return Vector::UnorderedEqualsMatcher(target); +} + +} // namespace Matchers +} // namespace Catch + +// end catch_matchers_vector.h +namespace Catch { + +template class MatchExpr : public ITransientExpression { + ArgT const &m_arg; + MatcherT m_matcher; + StringRef m_matcherString; + +public: + MatchExpr(ArgT const &arg, MatcherT const &matcher, StringRef matcherString) + : ITransientExpression{true, matcher.match(arg)}, m_arg(arg), m_matcher(matcher), m_matcherString(matcherString) { + } + + void streamReconstructedExpression(std::ostream &os) const override { + auto matcherAsString = m_matcher.toString(); + os << Catch::Detail::stringify(m_arg) << ' '; + if (matcherAsString == Detail::unprintableString) + os << m_matcherString; + else + os << matcherAsString; + } +}; + +using StringMatcher = Matchers::Impl::MatcherBase; + +void handleExceptionMatchExpr(AssertionHandler &handler, StringMatcher const &matcher, StringRef matcherString); + +template +auto makeMatchExpr(ArgT const &arg, MatcherT const &matcher, StringRef matcherString) -> MatchExpr { + return MatchExpr(arg, matcher, matcherString); +} + +} // namespace Catch + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CHECK_THAT(macroName, matcher, resultDisposition, arg) \ + do { \ + Catch::AssertionHandler catchAssertionHandler( \ + macroName, CATCH_INTERNAL_LINEINFO, CATCH_INTERNAL_STRINGIFY(arg) ", " CATCH_INTERNAL_STRINGIFY(matcher), \ + resultDisposition); \ + INTERNAL_CATCH_TRY { \ + catchAssertionHandler.handleExpr(Catch::makeMatchExpr(arg, matcher, #matcher)); \ + } \ + INTERNAL_CATCH_CATCH(catchAssertionHandler) \ + INTERNAL_CATCH_REACT(catchAssertionHandler) \ + } while (false) + +/////////////////////////////////////////////////////////////////////////////// +#define INTERNAL_CATCH_THROWS_MATCHES(macroName, exceptionType, resultDisposition, matcher, ...) \ + do { \ + Catch::AssertionHandler catchAssertionHandler(macroName, CATCH_INTERNAL_LINEINFO, \ + CATCH_INTERNAL_STRINGIFY(__VA_ARGS__) ", " CATCH_INTERNAL_STRINGIFY( \ + exceptionType) ", " CATCH_INTERNAL_STRINGIFY(matcher), \ + resultDisposition); \ + if (catchAssertionHandler.allowThrows()) \ + try { \ + static_cast(__VA_ARGS__); \ + catchAssertionHandler.handleUnexpectedExceptionNotThrown(); \ + } catch (exceptionType const &ex) { \ + catchAssertionHandler.handleExpr(Catch::makeMatchExpr(ex, matcher, #matcher)); \ + } catch (...) { \ + catchAssertionHandler.handleUnexpectedInflightException(); \ + } \ + else \ + catchAssertionHandler.handleThrowingCallSkipped(); \ + INTERNAL_CATCH_REACT(catchAssertionHandler) \ + } while (false) + +// end catch_capture_matchers.h +#endif + +// These files are included here so the single_include script doesn't put them +// in the conditionally compiled sections +// start catch_test_case_info.h + +#include +#include +#include + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" +#endif + +namespace Catch { + +struct ITestInvoker; + +struct TestCaseInfo { + enum SpecialProperties { + None = 0, + IsHidden = 1 << 1, + ShouldFail = 1 << 2, + MayFail = 1 << 3, + Throws = 1 << 4, + NonPortable = 1 << 5, + Benchmark = 1 << 6 + }; + + TestCaseInfo(std::string const &_name, std::string const &_className, std::string const &_description, + std::vector const &_tags, SourceLineInfo const &_lineInfo); + + friend void setTags(TestCaseInfo &testCaseInfo, std::vector tags); + + bool isHidden() const; + bool throws() const; + bool okToFail() const; + bool expectedToFail() const; + + std::string tagsAsString() const; + + std::string name; + std::string className; + std::string description; + std::vector tags; + std::vector lcaseTags; + SourceLineInfo lineInfo; + SpecialProperties properties; +}; + +class TestCase : public TestCaseInfo { +public: + TestCase(ITestInvoker *testCase, TestCaseInfo &&info); + + TestCase withName(std::string const &_newName) const; + + void invoke() const; + + TestCaseInfo const &getTestCaseInfo() const; + + bool operator==(TestCase const &other) const; + bool operator<(TestCase const &other) const; + +private: + std::shared_ptr test; +}; + +TestCase makeTestCase(ITestInvoker *testCase, std::string const &className, NameAndTags const &nameAndTags, + SourceLineInfo const &lineInfo); +} // namespace Catch + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +// end catch_test_case_info.h +// start catch_interfaces_runner.h + +namespace Catch { + +struct IRunner { + virtual ~IRunner(); + virtual bool aborting() const = 0; +}; +} // namespace Catch + +// end catch_interfaces_runner.h + +#ifdef __OBJC__ +// start catch_objc.hpp + +#import + +#include + +// NB. Any general catch headers included here must be included +// in catch.hpp first to make sure they are included by the single +// header for non obj-usage + +/////////////////////////////////////////////////////////////////////////////// +// This protocol is really only here for (self) documenting purposes, since +// all its methods are optional. +@protocol OcFixture + +@optional + +- (void)setUp; +- (void)tearDown; + +@end + +namespace Catch { + +class OcMethod : public ITestInvoker { + +public: + OcMethod(Class cls, SEL sel) : m_cls(cls), m_sel(sel) { + } + + virtual void invoke() const { + id obj = [[m_cls alloc] init]; + + performOptionalSelector(obj, @selector(setUp)); + performOptionalSelector(obj, m_sel); + performOptionalSelector(obj, @selector(tearDown)); + + arcSafeRelease(obj); + } + +private: + virtual ~OcMethod() { + } + + Class m_cls; + SEL m_sel; +}; + +namespace Detail { + +inline std::string getAnnotation(Class cls, std::string const &annotationName, std::string const &testCaseName) { + NSString *selStr = [[NSString alloc] initWithFormat:@"Catch_%s_%s", annotationName.c_str(), testCaseName.c_str()]; + SEL sel = NSSelectorFromString(selStr); + arcSafeRelease(selStr); + id value = performOptionalSelector(cls, sel); + if (value) + return [(NSString *)value UTF8String]; + return ""; +} +} // namespace Detail + +inline std::size_t registerTestMethods() { + std::size_t noTestMethods = 0; + int noClasses = objc_getClassList(nullptr, 0); + + Class *classes = (CATCH_UNSAFE_UNRETAINED Class *)malloc(sizeof(Class) * noClasses); + objc_getClassList(classes, noClasses); + + for (int c = 0; c < noClasses; c++) { + Class cls = classes[c]; + { + u_int count; + Method *methods = class_copyMethodList(cls, &count); + for (u_int m = 0; m < count; m++) { + SEL selector = method_getName(methods[m]); + std::string methodName = sel_getName(selector); + if (startsWith(methodName, "Catch_TestCase_")) { + std::string testCaseName = methodName.substr(15); + std::string name = Detail::getAnnotation(cls, "Name", testCaseName); + std::string desc = Detail::getAnnotation(cls, "Description", testCaseName); + const char *className = class_getName(cls); + + getMutableRegistryHub().registerTest( + makeTestCase(new OcMethod(cls, selector), className, name.c_str(), desc.c_str(), SourceLineInfo("", 0))); + noTestMethods++; + } + } + free(methods); + } + } + return noTestMethods; +} + +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) + +namespace Matchers { +namespace Impl { +namespace NSStringMatchers { + +struct StringHolder : MatcherBase { + StringHolder(NSString *substr) : m_substr([substr copy]) { + } + StringHolder(StringHolder const &other) : m_substr([other.m_substr copy]) { + } + StringHolder() { + arcSafeRelease(m_substr); + } + + bool match(NSString *arg) const override { + return false; + } + + NSString *CATCH_ARC_STRONG m_substr; +}; + +struct Equals : StringHolder { + Equals(NSString *substr) : StringHolder(substr) { + } + + bool match(NSString *str) const override { + return (str != nil || m_substr == nil) && [str isEqualToString:m_substr]; + } + + std::string describe() const override { + return "equals string: " + Catch::Detail::stringify(m_substr); + } +}; + +struct Contains : StringHolder { + Contains(NSString *substr) : StringHolder(substr) { + } + + bool match(NSString *str) const { + return (str != nil || m_substr == nil) && [str rangeOfString:m_substr].location != NSNotFound; + } + + std::string describe() const override { + return "contains string: " + Catch::Detail::stringify(m_substr); + } +}; + +struct StartsWith : StringHolder { + StartsWith(NSString *substr) : StringHolder(substr) { + } + + bool match(NSString *str) const override { + return (str != nil || m_substr == nil) && [str rangeOfString:m_substr].location == 0; + } + + std::string describe() const override { + return "starts with: " + Catch::Detail::stringify(m_substr); + } +}; +struct EndsWith : StringHolder { + EndsWith(NSString *substr) : StringHolder(substr) { + } + + bool match(NSString *str) const override { + return (str != nil || m_substr == nil) && [str rangeOfString:m_substr].location == [str length] - [m_substr length]; + } + + std::string describe() const override { + return "ends with: " + Catch::Detail::stringify(m_substr); + } +}; + +} // namespace NSStringMatchers +} // namespace Impl + +inline Impl::NSStringMatchers::Equals Equals(NSString *substr) { + return Impl::NSStringMatchers::Equals(substr); +} + +inline Impl::NSStringMatchers::Contains Contains(NSString *substr) { + return Impl::NSStringMatchers::Contains(substr); +} + +inline Impl::NSStringMatchers::StartsWith StartsWith(NSString *substr) { + return Impl::NSStringMatchers::StartsWith(substr); +} + +inline Impl::NSStringMatchers::EndsWith EndsWith(NSString *substr) { + return Impl::NSStringMatchers::EndsWith(substr); +} + +} // namespace Matchers + +using namespace Matchers; + +#endif // CATCH_CONFIG_DISABLE_MATCHERS + +} // namespace Catch + +/////////////////////////////////////////////////////////////////////////////// +#define OC_MAKE_UNIQUE_NAME(root, uniqueSuffix) root##uniqueSuffix +#define OC_TEST_CASE2(name, desc, uniqueSuffix) \ + +(NSString *)OC_MAKE_UNIQUE_NAME(Catch_Name_test_, uniqueSuffix) { \ + return @name; \ + } \ + +(NSString *)OC_MAKE_UNIQUE_NAME(Catch_Description_test_, uniqueSuffix) { \ + return @desc; \ + } \ + -(void)OC_MAKE_UNIQUE_NAME(Catch_TestCase_test_, uniqueSuffix) + +#define OC_TEST_CASE(name, desc) OC_TEST_CASE2(name, desc, __LINE__) + +// end catch_objc.hpp +#endif + +#ifdef CATCH_CONFIG_EXTERNAL_INTERFACES +// start catch_external_interfaces.h + +// start catch_reporter_bases.hpp + +// start catch_interfaces_reporter.h + +// start catch_config.hpp + +// start catch_test_spec_parser.h + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" +#endif + +// start catch_test_spec.h + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpadded" +#endif + +// start catch_wildcard_pattern.h + +namespace Catch { +class WildcardPattern { + enum WildcardPosition { + NoWildcard = 0, + WildcardAtStart = 1, + WildcardAtEnd = 2, + WildcardAtBothEnds = WildcardAtStart | WildcardAtEnd + }; + +public: + WildcardPattern(std::string const &pattern, CaseSensitive::Choice caseSensitivity); + virtual ~WildcardPattern() = default; + virtual bool matches(std::string const &str) const; + +private: + std::string adjustCase(std::string const &str) const; + CaseSensitive::Choice m_caseSensitivity; + WildcardPosition m_wildcard = NoWildcard; + std::string m_pattern; +}; +} // namespace Catch + +// end catch_wildcard_pattern.h +#include +#include +#include + +namespace Catch { + +class TestSpec { + struct Pattern { + virtual ~Pattern(); + virtual bool matches(TestCaseInfo const &testCase) const = 0; + }; + using PatternPtr = std::shared_ptr; + + class NamePattern : public Pattern { + public: + NamePattern(std::string const &name); + virtual ~NamePattern(); + virtual bool matches(TestCaseInfo const &testCase) const override; + + private: + WildcardPattern m_wildcardPattern; + }; + + class TagPattern : public Pattern { + public: + TagPattern(std::string const &tag); + virtual ~TagPattern(); + virtual bool matches(TestCaseInfo const &testCase) const override; + + private: + std::string m_tag; + }; + + class ExcludedPattern : public Pattern { + public: + ExcludedPattern(PatternPtr const &underlyingPattern); + virtual ~ExcludedPattern(); + virtual bool matches(TestCaseInfo const &testCase) const override; + + private: + PatternPtr m_underlyingPattern; + }; + + struct Filter { + std::vector m_patterns; + + bool matches(TestCaseInfo const &testCase) const; + }; + +public: + bool hasFilters() const; + bool matches(TestCaseInfo const &testCase) const; + +private: + std::vector m_filters; + + friend class TestSpecParser; +}; +} // namespace Catch + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +// end catch_test_spec.h +// start catch_interfaces_tag_alias_registry.h + +#include + +namespace Catch { + +struct TagAlias; + +struct ITagAliasRegistry { + virtual ~ITagAliasRegistry(); + // Nullptr if not present + virtual TagAlias const *find(std::string const &alias) const = 0; + virtual std::string expandAliases(std::string const &unexpandedTestSpec) const = 0; + + static ITagAliasRegistry const &get(); +}; + +} // end namespace Catch + +// end catch_interfaces_tag_alias_registry.h +namespace Catch { + +class TestSpecParser { + enum Mode { None, Name, QuotedName, Tag, EscapedName }; + Mode m_mode = None; + bool m_exclusion = false; + std::size_t m_start = std::string::npos, m_pos = 0; + std::string m_arg; + std::vector m_escapeChars; + TestSpec::Filter m_currentFilter; + TestSpec m_testSpec; + ITagAliasRegistry const *m_tagAliases = nullptr; + +public: + TestSpecParser(ITagAliasRegistry const &tagAliases); + + TestSpecParser &parse(std::string const &arg); + TestSpec testSpec(); + +private: + void visitChar(char c); + void startNewMode(Mode mode, std::size_t start); + void escape(); + std::string subString() const; + + template void addPattern() { + std::string token = subString(); + for (std::size_t i = 0; i < m_escapeChars.size(); ++i) + token = token.substr(0, m_escapeChars[i] - m_start - i) + token.substr(m_escapeChars[i] - m_start - i + 1); + m_escapeChars.clear(); + if (startsWith(token, "exclude:")) { + m_exclusion = true; + token = token.substr(8); + } + if (!token.empty()) { + TestSpec::PatternPtr pattern = std::make_shared(token); + if (m_exclusion) + pattern = std::make_shared(pattern); + m_currentFilter.m_patterns.push_back(pattern); + } + m_exclusion = false; + m_mode = None; + } + + void addFilter(); +}; +TestSpec parseTestSpec(std::string const &arg); + +} // namespace Catch + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +// end catch_test_spec_parser.h +// start catch_interfaces_config.h + +#include +#include +#include +#include + +namespace Catch { + +enum class Verbosity { Quiet = 0, Normal, High }; + +struct WarnAbout { + enum What { Nothing = 0x00, NoAssertions = 0x01, NoTests = 0x02 }; +}; + +struct ShowDurations { + enum OrNot { DefaultForReporter, Always, Never }; +}; +struct RunTests { + enum InWhatOrder { InDeclarationOrder, InLexicographicalOrder, InRandomOrder }; +}; +struct UseColour { + enum YesOrNo { Auto, Yes, No }; +}; +struct WaitForKeypress { + enum When { Never, BeforeStart = 1, BeforeExit = 2, BeforeStartAndExit = BeforeStart | BeforeExit }; +}; + +class TestSpec; + +struct IConfig : NonCopyable { + + virtual ~IConfig(); + + virtual bool allowThrows() const = 0; + virtual std::ostream &stream() const = 0; + virtual std::string name() const = 0; + virtual bool includeSuccessfulResults() const = 0; + virtual bool shouldDebugBreak() const = 0; + virtual bool warnAboutMissingAssertions() const = 0; + virtual bool warnAboutNoTests() const = 0; + virtual int abortAfter() const = 0; + virtual bool showInvisibles() const = 0; + virtual ShowDurations::OrNot showDurations() const = 0; + virtual TestSpec const &testSpec() const = 0; + virtual bool hasTestFilters() const = 0; + virtual RunTests::InWhatOrder runOrder() const = 0; + virtual unsigned int rngSeed() const = 0; + virtual int benchmarkResolutionMultiple() const = 0; + virtual UseColour::YesOrNo useColour() const = 0; + virtual std::vector const &getSectionsToRun() const = 0; + virtual Verbosity verbosity() const = 0; +}; + +using IConfigPtr = std::shared_ptr; +} // namespace Catch + +// end catch_interfaces_config.h +// Libstdc++ doesn't like incomplete classes for unique_ptr + +#include +#include +#include + +#ifndef CATCH_CONFIG_CONSOLE_WIDTH +#define CATCH_CONFIG_CONSOLE_WIDTH 80 +#endif + +namespace Catch { + +struct IStream; + +struct ConfigData { + bool listTests = false; + bool listTags = false; + bool listReporters = false; + bool listTestNamesOnly = false; + + bool showSuccessfulTests = false; + bool shouldDebugBreak = false; + bool noThrow = false; + bool showHelp = false; + bool showInvisibles = false; + bool filenamesAsTags = false; + bool libIdentify = false; + + int abortAfter = -1; + unsigned int rngSeed = 0; + int benchmarkResolutionMultiple = 100; + + Verbosity verbosity = Verbosity::Normal; + WarnAbout::What warnings = WarnAbout::Nothing; + ShowDurations::OrNot showDurations = ShowDurations::DefaultForReporter; + RunTests::InWhatOrder runOrder = RunTests::InDeclarationOrder; + UseColour::YesOrNo useColour = UseColour::Auto; + WaitForKeypress::When waitForKeypress = WaitForKeypress::Never; + + std::string outputFilename; + std::string name; + std::string processName; +#ifndef CATCH_CONFIG_DEFAULT_REPORTER +#define CATCH_CONFIG_DEFAULT_REPORTER "console" +#endif + std::string reporterName = CATCH_CONFIG_DEFAULT_REPORTER; +#undef CATCH_CONFIG_DEFAULT_REPORTER + + std::vector testsOrTags; + std::vector sectionsToRun; +}; + +class Config : public IConfig { +public: + Config() = default; + Config(ConfigData const &data); + virtual ~Config() = default; + + std::string const &getFilename() const; + + bool listTests() const; + bool listTestNamesOnly() const; + bool listTags() const; + bool listReporters() const; + + std::string getProcessName() const; + std::string const &getReporterName() const; + + std::vector const &getTestsOrTags() const; + std::vector const &getSectionsToRun() const override; + + virtual TestSpec const &testSpec() const override; + bool hasTestFilters() const override; + + bool showHelp() const; + + // IConfig interface + bool allowThrows() const override; + std::ostream &stream() const override; + std::string name() const override; + bool includeSuccessfulResults() const override; + bool warnAboutMissingAssertions() const override; + bool warnAboutNoTests() const override; + ShowDurations::OrNot showDurations() const override; + RunTests::InWhatOrder runOrder() const override; + unsigned int rngSeed() const override; + int benchmarkResolutionMultiple() const override; + UseColour::YesOrNo useColour() const override; + bool shouldDebugBreak() const override; + int abortAfter() const override; + bool showInvisibles() const override; + Verbosity verbosity() const override; + +private: + IStream const *openStream(); + ConfigData m_data; + + std::unique_ptr m_stream; + TestSpec m_testSpec; + bool m_hasTestFilters = false; +}; + +} // end namespace Catch + +// end catch_config.hpp +// start catch_assertionresult.h + +#include + +namespace Catch { + +struct AssertionResultData { + AssertionResultData() = delete; + + AssertionResultData(ResultWas::OfType _resultType, LazyExpression const &_lazyExpression); + + std::string message; + mutable std::string reconstructedExpression; + LazyExpression lazyExpression; + ResultWas::OfType resultType; + + std::string reconstructExpression() const; +}; + +class AssertionResult { +public: + AssertionResult() = delete; + AssertionResult(AssertionInfo const &info, AssertionResultData const &data); + + bool isOk() const; + bool succeeded() const; + ResultWas::OfType getResultType() const; + bool hasExpression() const; + bool hasMessage() const; + std::string getExpression() const; + std::string getExpressionInMacro() const; + bool hasExpandedExpression() const; + std::string getExpandedExpression() const; + std::string getMessage() const; + SourceLineInfo getSourceInfo() const; + StringRef getTestMacroName() const; + + //protected: + AssertionInfo m_info; + AssertionResultData m_resultData; +}; + +} // end namespace Catch + +// end catch_assertionresult.h +// start catch_option.hpp + +namespace Catch { + +// An optional type +template class Option { +public: + Option() : nullableValue(nullptr) { + } + Option(T const &_value) : nullableValue(new (storage) T(_value)) { + } + Option(Option const &_other) : nullableValue(_other ? new (storage) T(*_other) : nullptr) { + } + + ~Option() { + reset(); + } + + Option &operator=(Option const &_other) { + if (&_other != this) { + reset(); + if (_other) + nullableValue = new (storage) T(*_other); + } + return *this; + } + Option &operator=(T const &_value) { + reset(); + nullableValue = new (storage) T(_value); + return *this; + } + + void reset() { + if (nullableValue) + nullableValue->~T(); + nullableValue = nullptr; + } + + T &operator*() { + return *nullableValue; + } + T const &operator*() const { + return *nullableValue; + } + T *operator->() { + return nullableValue; + } + const T *operator->() const { + return nullableValue; + } + + T valueOr(T const &defaultValue) const { + return nullableValue ? *nullableValue : defaultValue; + } + + bool some() const { + return nullableValue != nullptr; + } + bool none() const { + return nullableValue == nullptr; + } + + bool operator!() const { + return nullableValue == nullptr; + } + explicit operator bool() const { + return some(); + } + +private: + T *nullableValue; + alignas(alignof(T)) char storage[sizeof(T)]; +}; + +} // end namespace Catch + +// end catch_option.hpp +#include +#include +#include +#include +#include + +namespace Catch { + +struct ReporterConfig { + explicit ReporterConfig(IConfigPtr const &_fullConfig); + + ReporterConfig(IConfigPtr const &_fullConfig, std::ostream &_stream); + + std::ostream &stream() const; + IConfigPtr fullConfig() const; + +private: + std::ostream *m_stream; + IConfigPtr m_fullConfig; +}; + +struct ReporterPreferences { + bool shouldRedirectStdOut = false; +}; + +template struct LazyStat : Option { + LazyStat &operator=(T const &_value) { + Option::operator=(_value); + used = false; + return *this; + } + void reset() { + Option::reset(); + used = false; + } + bool used = false; +}; + +struct TestRunInfo { + TestRunInfo(std::string const &_name); + std::string name; +}; +struct GroupInfo { + GroupInfo(std::string const &_name, std::size_t _groupIndex, std::size_t _groupsCount); + + std::string name; + std::size_t groupIndex; + std::size_t groupsCounts; +}; + +struct AssertionStats { + AssertionStats(AssertionResult const &_assertionResult, std::vector const &_infoMessages, + Totals const &_totals); + + AssertionStats(AssertionStats const &) = default; + AssertionStats(AssertionStats &&) = default; + AssertionStats &operator=(AssertionStats const &) = default; + AssertionStats &operator=(AssertionStats &&) = default; + virtual ~AssertionStats(); + + AssertionResult assertionResult; + std::vector infoMessages; + Totals totals; +}; + +struct SectionStats { + SectionStats(SectionInfo const &_sectionInfo, Counts const &_assertions, double _durationInSeconds, + bool _missingAssertions); + SectionStats(SectionStats const &) = default; + SectionStats(SectionStats &&) = default; + SectionStats &operator=(SectionStats const &) = default; + SectionStats &operator=(SectionStats &&) = default; + virtual ~SectionStats(); + + SectionInfo sectionInfo; + Counts assertions; + double durationInSeconds; + bool missingAssertions; +}; + +struct TestCaseStats { + TestCaseStats(TestCaseInfo const &_testInfo, Totals const &_totals, std::string const &_stdOut, + std::string const &_stdErr, bool _aborting); + + TestCaseStats(TestCaseStats const &) = default; + TestCaseStats(TestCaseStats &&) = default; + TestCaseStats &operator=(TestCaseStats const &) = default; + TestCaseStats &operator=(TestCaseStats &&) = default; + virtual ~TestCaseStats(); + + TestCaseInfo testInfo; + Totals totals; + std::string stdOut; + std::string stdErr; + bool aborting; +}; + +struct TestGroupStats { + TestGroupStats(GroupInfo const &_groupInfo, Totals const &_totals, bool _aborting); + TestGroupStats(GroupInfo const &_groupInfo); + + TestGroupStats(TestGroupStats const &) = default; + TestGroupStats(TestGroupStats &&) = default; + TestGroupStats &operator=(TestGroupStats const &) = default; + TestGroupStats &operator=(TestGroupStats &&) = default; + virtual ~TestGroupStats(); + + GroupInfo groupInfo; + Totals totals; + bool aborting; +}; + +struct TestRunStats { + TestRunStats(TestRunInfo const &_runInfo, Totals const &_totals, bool _aborting); + + TestRunStats(TestRunStats const &) = default; + TestRunStats(TestRunStats &&) = default; + TestRunStats &operator=(TestRunStats const &) = default; + TestRunStats &operator=(TestRunStats &&) = default; + virtual ~TestRunStats(); + + TestRunInfo runInfo; + Totals totals; + bool aborting; +}; + +struct BenchmarkInfo { + std::string name; +}; +struct BenchmarkStats { + BenchmarkInfo info; + std::size_t iterations; + uint64_t elapsedTimeInNanoseconds; +}; + +struct IStreamingReporter { + virtual ~IStreamingReporter() = default; + + // Implementing class must also provide the following static methods: + // static std::string getDescription(); + // static std::set getSupportedVerbosities() + + virtual ReporterPreferences getPreferences() const = 0; + + virtual void noMatchingTestCases(std::string const &spec) = 0; + + virtual void testRunStarting(TestRunInfo const &testRunInfo) = 0; + virtual void testGroupStarting(GroupInfo const &groupInfo) = 0; + + virtual void testCaseStarting(TestCaseInfo const &testInfo) = 0; + virtual void sectionStarting(SectionInfo const §ionInfo) = 0; + + // *** experimental *** + virtual void benchmarkStarting(BenchmarkInfo const &) { + } + + virtual void assertionStarting(AssertionInfo const &assertionInfo) = 0; + + // The return value indicates if the messages buffer should be cleared: + virtual bool assertionEnded(AssertionStats const &assertionStats) = 0; + + // *** experimental *** + virtual void benchmarkEnded(BenchmarkStats const &) { + } + + virtual void sectionEnded(SectionStats const §ionStats) = 0; + virtual void testCaseEnded(TestCaseStats const &testCaseStats) = 0; + virtual void testGroupEnded(TestGroupStats const &testGroupStats) = 0; + virtual void testRunEnded(TestRunStats const &testRunStats) = 0; + + virtual void skipTest(TestCaseInfo const &testInfo) = 0; + + // Default empty implementation provided + virtual void fatalErrorEncountered(StringRef name); + + virtual bool isMulti() const; +}; +using IStreamingReporterPtr = std::unique_ptr; + +struct IReporterFactory { + virtual ~IReporterFactory(); + virtual IStreamingReporterPtr create(ReporterConfig const &config) const = 0; + virtual std::string getDescription() const = 0; +}; +using IReporterFactoryPtr = std::shared_ptr; + +struct IReporterRegistry { + using FactoryMap = std::map; + using Listeners = std::vector; + + virtual ~IReporterRegistry(); + virtual IStreamingReporterPtr create(std::string const &name, IConfigPtr const &config) const = 0; + virtual FactoryMap const &getFactories() const = 0; + virtual Listeners const &getListeners() const = 0; +}; + +} // end namespace Catch + +// end catch_interfaces_reporter.h +#include +#include +#include +#include +#include +#include +#include + +namespace Catch { +void prepareExpandedExpression(AssertionResult &result); + +// Returns double formatted as %.3f (format expected on output) +std::string getFormattedDuration(double duration); + +template struct StreamingReporterBase : IStreamingReporter { + + StreamingReporterBase(ReporterConfig const &_config) : m_config(_config.fullConfig()), stream(_config.stream()) { + m_reporterPrefs.shouldRedirectStdOut = false; + if (!DerivedT::getSupportedVerbosities().count(m_config->verbosity())) + throw std::domain_error("Verbosity level not supported by this reporter"); + } + + ReporterPreferences getPreferences() const override { + return m_reporterPrefs; + } + + static std::set getSupportedVerbosities() { + return {Verbosity::Normal}; + } + + ~StreamingReporterBase() override = default; + + void noMatchingTestCases(std::string const &) override { + } + + void testRunStarting(TestRunInfo const &_testRunInfo) override { + currentTestRunInfo = _testRunInfo; + } + void testGroupStarting(GroupInfo const &_groupInfo) override { + currentGroupInfo = _groupInfo; + } + + void testCaseStarting(TestCaseInfo const &_testInfo) override { + currentTestCaseInfo = _testInfo; + } + void sectionStarting(SectionInfo const &_sectionInfo) override { + m_sectionStack.push_back(_sectionInfo); + } + + void sectionEnded(SectionStats const & /* _sectionStats */) override { + m_sectionStack.pop_back(); + } + void testCaseEnded(TestCaseStats const & /* _testCaseStats */) override { + currentTestCaseInfo.reset(); + } + void testGroupEnded(TestGroupStats const & /* _testGroupStats */) override { + currentGroupInfo.reset(); + } + void testRunEnded(TestRunStats const & /* _testRunStats */) override { + currentTestCaseInfo.reset(); + currentGroupInfo.reset(); + currentTestRunInfo.reset(); + } + + void skipTest(TestCaseInfo const &) override { + // Don't do anything with this by default. + // It can optionally be overridden in the derived class. + } + + IConfigPtr m_config; + std::ostream &stream; + + LazyStat currentTestRunInfo; + LazyStat currentGroupInfo; + LazyStat currentTestCaseInfo; + + std::vector m_sectionStack; + ReporterPreferences m_reporterPrefs; +}; + +template struct CumulativeReporterBase : IStreamingReporter { + template struct Node { + explicit Node(T const &_value) : value(_value) { + } + virtual ~Node() { + } + + using ChildNodes = std::vector>; + T value; + ChildNodes children; + }; + struct SectionNode { + explicit SectionNode(SectionStats const &_stats) : stats(_stats) { + } + virtual ~SectionNode() = default; + + bool operator==(SectionNode const &other) const { + return stats.sectionInfo.lineInfo == other.stats.sectionInfo.lineInfo; + } + bool operator==(std::shared_ptr const &other) const { + return operator==(*other); + } + + SectionStats stats; + using ChildSections = std::vector>; + using Assertions = std::vector; + ChildSections childSections; + Assertions assertions; + std::string stdOut; + std::string stdErr; + }; + + struct BySectionInfo { + BySectionInfo(SectionInfo const &other) : m_other(other) { + } + BySectionInfo(BySectionInfo const &other) : m_other(other.m_other) { + } + bool operator()(std::shared_ptr const &node) const { + return ((node->stats.sectionInfo.name == m_other.name) && (node->stats.sectionInfo.lineInfo == m_other.lineInfo)); + } + void operator=(BySectionInfo const &) = delete; + + private: + SectionInfo const &m_other; + }; + + using TestCaseNode = Node; + using TestGroupNode = Node; + using TestRunNode = Node; + + CumulativeReporterBase(ReporterConfig const &_config) : m_config(_config.fullConfig()), stream(_config.stream()) { + m_reporterPrefs.shouldRedirectStdOut = false; + if (!DerivedT::getSupportedVerbosities().count(m_config->verbosity())) + throw std::domain_error("Verbosity level not supported by this reporter"); + } + ~CumulativeReporterBase() override = default; + + ReporterPreferences getPreferences() const override { + return m_reporterPrefs; + } + + static std::set getSupportedVerbosities() { + return {Verbosity::Normal}; + } + + void testRunStarting(TestRunInfo const &) override { + } + void testGroupStarting(GroupInfo const &) override { + } + + void testCaseStarting(TestCaseInfo const &) override { + } + + void sectionStarting(SectionInfo const §ionInfo) override { + SectionStats incompleteStats(sectionInfo, Counts(), 0, false); + std::shared_ptr node; + if (m_sectionStack.empty()) { + if (!m_rootSection) + m_rootSection = std::make_shared(incompleteStats); + node = m_rootSection; + } else { + SectionNode &parentNode = *m_sectionStack.back(); + auto it = + std::find_if(parentNode.childSections.begin(), parentNode.childSections.end(), BySectionInfo(sectionInfo)); + if (it == parentNode.childSections.end()) { + node = std::make_shared(incompleteStats); + parentNode.childSections.push_back(node); + } else + node = *it; + } + m_sectionStack.push_back(node); + m_deepestSection = std::move(node); + } + + void assertionStarting(AssertionInfo const &) override { + } + + bool assertionEnded(AssertionStats const &assertionStats) override { + assert(!m_sectionStack.empty()); + // AssertionResult holds a pointer to a temporary DecomposedExpression, + // which getExpandedExpression() calls to build the expression string. + // Our section stack copy of the assertionResult will likely outlive the + // temporary, so it must be expanded or discarded now to avoid calling + // a destroyed object later. + prepareExpandedExpression(const_cast(assertionStats.assertionResult)); + SectionNode §ionNode = *m_sectionStack.back(); + sectionNode.assertions.push_back(assertionStats); + return true; + } + void sectionEnded(SectionStats const §ionStats) override { + assert(!m_sectionStack.empty()); + SectionNode &node = *m_sectionStack.back(); + node.stats = sectionStats; + m_sectionStack.pop_back(); + } + void testCaseEnded(TestCaseStats const &testCaseStats) override { + auto node = std::make_shared(testCaseStats); + assert(m_sectionStack.size() == 0); + node->children.push_back(m_rootSection); + m_testCases.push_back(node); + m_rootSection.reset(); + + assert(m_deepestSection); + m_deepestSection->stdOut = testCaseStats.stdOut; + m_deepestSection->stdErr = testCaseStats.stdErr; + } + void testGroupEnded(TestGroupStats const &testGroupStats) override { + auto node = std::make_shared(testGroupStats); + node->children.swap(m_testCases); + m_testGroups.push_back(node); + } + void testRunEnded(TestRunStats const &testRunStats) override { + auto node = std::make_shared(testRunStats); + node->children.swap(m_testGroups); + m_testRuns.push_back(node); + testRunEndedCumulative(); + } + virtual void testRunEndedCumulative() = 0; + + void skipTest(TestCaseInfo const &) override { + } + + IConfigPtr m_config; + std::ostream &stream; + std::vector m_assertions; + std::vector>> m_sections; + std::vector> m_testCases; + std::vector> m_testGroups; + + std::vector> m_testRuns; + + std::shared_ptr m_rootSection; + std::shared_ptr m_deepestSection; + std::vector> m_sectionStack; + ReporterPreferences m_reporterPrefs; +}; + +template char const *getLineOfChars() { + static char line[CATCH_CONFIG_CONSOLE_WIDTH] = {0}; + if (!*line) { + std::memset(line, C, CATCH_CONFIG_CONSOLE_WIDTH - 1); + line[CATCH_CONFIG_CONSOLE_WIDTH - 1] = 0; + } + return line; +} + +struct TestEventListenerBase : StreamingReporterBase { + TestEventListenerBase(ReporterConfig const &_config); + + void assertionStarting(AssertionInfo const &) override; + bool assertionEnded(AssertionStats const &) override; +}; + +} // end namespace Catch + +// end catch_reporter_bases.hpp +// start catch_console_colour.h + +namespace Catch { + +struct Colour { + enum Code { + None = 0, + + White, + Red, + Green, + Blue, + Cyan, + Yellow, + Grey, + + Bright = 0x10, + + BrightRed = Bright | Red, + BrightGreen = Bright | Green, + LightGrey = Bright | Grey, + BrightWhite = Bright | White, + BrightYellow = Bright | Yellow, + + // By intention + FileName = LightGrey, + Warning = BrightYellow, + ResultError = BrightRed, + ResultSuccess = BrightGreen, + ResultExpectedFailure = Warning, + + Error = BrightRed, + Success = Green, + + OriginalExpression = Cyan, + ReconstructedExpression = BrightYellow, + + SecondaryText = LightGrey, + Headers = White + }; + + // Use constructed object for RAII guard + Colour(Code _colourCode); + Colour(Colour &&other) noexcept; + Colour &operator=(Colour &&other) noexcept; + ~Colour(); + + // Use static method for one-shot changes + static void use(Code _colourCode); + +private: + bool m_moved = false; +}; + +std::ostream &operator<<(std::ostream &os, Colour const &); + +} // end namespace Catch + +// end catch_console_colour.h +// start catch_reporter_registrars.hpp + +namespace Catch { + +template class ReporterRegistrar { + + class ReporterFactory : public IReporterFactory { + + virtual IStreamingReporterPtr create(ReporterConfig const &config) const override { + return std::unique_ptr(new T(config)); + } + + virtual std::string getDescription() const override { + return T::getDescription(); + } + }; + +public: + explicit ReporterRegistrar(std::string const &name) { + getMutableRegistryHub().registerReporter(name, std::make_shared()); + } +}; + +template class ListenerRegistrar { + + class ListenerFactory : public IReporterFactory { + + virtual IStreamingReporterPtr create(ReporterConfig const &config) const override { + return std::unique_ptr(new T(config)); + } + virtual std::string getDescription() const override { + return std::string(); + } + }; + +public: + ListenerRegistrar() { + getMutableRegistryHub().registerListener(std::make_shared()); + } +}; +} // namespace Catch + +#if !defined(CATCH_CONFIG_DISABLE) + +#define CATCH_REGISTER_REPORTER(name, reporterType) \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace { \ + Catch::ReporterRegistrar catch_internal_RegistrarFor##reporterType(name); \ + } \ + CATCH_INTERNAL_UNSUPPRESS_GLOBALS_WARNINGS + +#define CATCH_REGISTER_LISTENER(listenerType) \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS \ + namespace { \ + Catch::ListenerRegistrar catch_internal_RegistrarFor##listenerType; \ + } \ + CATCH_INTERNAL_SUPPRESS_GLOBALS_WARNINGS +#else // CATCH_CONFIG_DISABLE + +#define CATCH_REGISTER_REPORTER(name, reporterType) +#define CATCH_REGISTER_LISTENER(listenerType) + +#endif // CATCH_CONFIG_DISABLE + +// end catch_reporter_registrars.hpp +// Allow users to base their work off existing reporters +// start catch_reporter_compact.h + +namespace Catch { + +struct CompactReporter : StreamingReporterBase { + + using StreamingReporterBase::StreamingReporterBase; + + ~CompactReporter() override; + + static std::string getDescription(); + + ReporterPreferences getPreferences() const override; + + void noMatchingTestCases(std::string const &spec) override; + + void assertionStarting(AssertionInfo const &) override; + + bool assertionEnded(AssertionStats const &_assertionStats) override; + + void sectionEnded(SectionStats const &_sectionStats) override; + + void testRunEnded(TestRunStats const &_testRunStats) override; +}; + +} // end namespace Catch + +// end catch_reporter_compact.h +// start catch_reporter_console.h + +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning( \ + disable : 4061) // Not all labels are EXPLICITLY handled in switch \ + // Note that 4062 (not all labels are handled \ + // and default is missing) is enabled +#endif + +namespace Catch { +// Fwd decls +struct SummaryColumn; +class TablePrinter; + +struct ConsoleReporter : StreamingReporterBase { + std::unique_ptr m_tablePrinter; + + ConsoleReporter(ReporterConfig const &config); + ~ConsoleReporter() override; + static std::string getDescription(); + + void noMatchingTestCases(std::string const &spec) override; + + void assertionStarting(AssertionInfo const &) override; + + bool assertionEnded(AssertionStats const &_assertionStats) override; + + void sectionStarting(SectionInfo const &_sectionInfo) override; + void sectionEnded(SectionStats const &_sectionStats) override; + + void benchmarkStarting(BenchmarkInfo const &info) override; + void benchmarkEnded(BenchmarkStats const &stats) override; + + void testCaseEnded(TestCaseStats const &_testCaseStats) override; + void testGroupEnded(TestGroupStats const &_testGroupStats) override; + void testRunEnded(TestRunStats const &_testRunStats) override; + +private: + void lazyPrint(); + + void lazyPrintWithoutClosingBenchmarkTable(); + void lazyPrintRunInfo(); + void lazyPrintGroupInfo(); + void printTestCaseAndSectionHeader(); + + void printClosedHeader(std::string const &_name); + void printOpenHeader(std::string const &_name); + + // if string has a : in first line will set indent to follow it on + // subsequent lines + void printHeaderString(std::string const &_string, std::size_t indent = 0); + + void printTotals(Totals const &totals); + void printSummaryRow(std::string const &label, std::vector const &cols, std::size_t row); + + void printTotalsDivider(Totals const &totals); + void printSummaryDivider(); + +private: + bool m_headerPrinted = false; +}; + +} // end namespace Catch + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif + +// end catch_reporter_console.h +// start catch_reporter_junit.h + +// start catch_xmlwriter.h + +#include + +namespace Catch { + +class XmlEncode { +public: + enum ForWhat { ForTextNodes, ForAttributes }; + + XmlEncode(std::string const &str, ForWhat forWhat = ForTextNodes); + + void encodeTo(std::ostream &os) const; + + friend std::ostream &operator<<(std::ostream &os, XmlEncode const &xmlEncode); + +private: + std::string m_str; + ForWhat m_forWhat; +}; + +class XmlWriter { +public: + class ScopedElement { + public: + ScopedElement(XmlWriter *writer); + + ScopedElement(ScopedElement &&other) noexcept; + ScopedElement &operator=(ScopedElement &&other) noexcept; + + ~ScopedElement(); + + ScopedElement &writeText(std::string const &text, bool indent = true); + + template ScopedElement &writeAttribute(std::string const &name, T const &attribute) { + m_writer->writeAttribute(name, attribute); + return *this; + } + + private: + mutable XmlWriter *m_writer = nullptr; + }; + + XmlWriter(std::ostream &os = Catch::cout()); + ~XmlWriter(); + + XmlWriter(XmlWriter const &) = delete; + XmlWriter &operator=(XmlWriter const &) = delete; + + XmlWriter &startElement(std::string const &name); + + ScopedElement scopedElement(std::string const &name); + + XmlWriter &endElement(); + + XmlWriter &writeAttribute(std::string const &name, std::string const &attribute); + + XmlWriter &writeAttribute(std::string const &name, bool attribute); + + template XmlWriter &writeAttribute(std::string const &name, T const &attribute) { + ReusableStringStream rss; + rss << attribute; + return writeAttribute(name, rss.str()); + } + + XmlWriter &writeText(std::string const &text, bool indent = true); + + XmlWriter &writeComment(std::string const &text); + + void writeStylesheetRef(std::string const &url); + + XmlWriter &writeBlankLine(); + + void ensureTagClosed(); + +private: + void writeDeclaration(); + + void newlineIfNecessary(); + + bool m_tagIsOpen = false; + bool m_needsNewline = false; + std::vector m_tags; + std::string m_indent; + std::ostream &m_os; +}; + +} // namespace Catch + +// end catch_xmlwriter.h +namespace Catch { + +class JunitReporter : public CumulativeReporterBase { +public: + JunitReporter(ReporterConfig const &_config); + + ~JunitReporter() override; + + static std::string getDescription(); + + void noMatchingTestCases(std::string const & /*spec*/) override; + + void testRunStarting(TestRunInfo const &runInfo) override; + + void testGroupStarting(GroupInfo const &groupInfo) override; + + void testCaseStarting(TestCaseInfo const &testCaseInfo) override; + bool assertionEnded(AssertionStats const &assertionStats) override; + + void testCaseEnded(TestCaseStats const &testCaseStats) override; + + void testGroupEnded(TestGroupStats const &testGroupStats) override; + + void testRunEndedCumulative() override; + + void writeGroup(TestGroupNode const &groupNode, double suiteTime); + + void writeTestCase(TestCaseNode const &testCaseNode); + + void writeSection(std::string const &className, std::string const &rootName, SectionNode const §ionNode); + + void writeAssertions(SectionNode const §ionNode); + void writeAssertion(AssertionStats const &stats); + + XmlWriter xml; + Timer suiteTimer; + std::string stdOutForSuite; + std::string stdErrForSuite; + unsigned int unexpectedExceptions = 0; + bool m_okToFail = false; +}; + +} // end namespace Catch + +// end catch_reporter_junit.h +// start catch_reporter_xml.h + +namespace Catch { +class XmlReporter : public StreamingReporterBase { +public: + XmlReporter(ReporterConfig const &_config); + + ~XmlReporter() override; + + static std::string getDescription(); + + virtual std::string getStylesheetRef() const; + + void writeSourceInfo(SourceLineInfo const &sourceInfo); + +public: // StreamingReporterBase + void noMatchingTestCases(std::string const &s) override; + + void testRunStarting(TestRunInfo const &testInfo) override; + + void testGroupStarting(GroupInfo const &groupInfo) override; + + void testCaseStarting(TestCaseInfo const &testInfo) override; + + void sectionStarting(SectionInfo const §ionInfo) override; + + void assertionStarting(AssertionInfo const &) override; + + bool assertionEnded(AssertionStats const &assertionStats) override; + + void sectionEnded(SectionStats const §ionStats) override; + + void testCaseEnded(TestCaseStats const &testCaseStats) override; + + void testGroupEnded(TestGroupStats const &testGroupStats) override; + + void testRunEnded(TestRunStats const &testRunStats) override; + +private: + Timer m_testCaseTimer; + XmlWriter m_xml; + int m_sectionDepth = 0; +}; + +} // end namespace Catch + +// end catch_reporter_xml.h + +// end catch_external_interfaces.h +#endif + +#endif // ! CATCH_CONFIG_IMPL_ONLY + +#ifdef CATCH_IMPL +// start catch_impl.hpp + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wweak-vtables" +#endif + +// Keep these here for external reporters +// start catch_test_case_tracker.h + +#include +#include +#include + +namespace Catch { +namespace TestCaseTracking { + +struct NameAndLocation { + std::string name; + SourceLineInfo location; + + NameAndLocation(std::string const &_name, SourceLineInfo const &_location); +}; + +struct ITracker; + +using ITrackerPtr = std::shared_ptr; + +struct ITracker { + virtual ~ITracker(); + + // static queries + virtual NameAndLocation const &nameAndLocation() const = 0; + + // dynamic queries + virtual bool isComplete() const = 0; // Successfully completed or failed + virtual bool isSuccessfullyCompleted() const = 0; + virtual bool isOpen() const = 0; // Started but not complete + virtual bool hasChildren() const = 0; + + virtual ITracker &parent() = 0; + + // actions + virtual void close() = 0; // Successfully complete + virtual void fail() = 0; + virtual void markAsNeedingAnotherRun() = 0; + + virtual void addChild(ITrackerPtr const &child) = 0; + virtual ITrackerPtr findChild(NameAndLocation const &nameAndLocation) = 0; + virtual void openChild() = 0; + + // Debug/ checking + virtual bool isSectionTracker() const = 0; + virtual bool isIndexTracker() const = 0; +}; + +class TrackerContext { + + enum RunState { NotStarted, Executing, CompletedCycle }; + + ITrackerPtr m_rootTracker; + ITracker *m_currentTracker = nullptr; + RunState m_runState = NotStarted; + +public: + static TrackerContext &instance(); + + ITracker &startRun(); + void endRun(); + + void startCycle(); + void completeCycle(); + + bool completedCycle() const; + ITracker ¤tTracker(); + void setCurrentTracker(ITracker *tracker); +}; + +class TrackerBase : public ITracker { +protected: + enum CycleState { NotStarted, Executing, ExecutingChildren, NeedsAnotherRun, CompletedSuccessfully, Failed }; + + class TrackerHasName { + NameAndLocation m_nameAndLocation; + + public: + TrackerHasName(NameAndLocation const &nameAndLocation); + bool operator()(ITrackerPtr const &tracker) const; + }; + + using Children = std::vector; + NameAndLocation m_nameAndLocation; + TrackerContext &m_ctx; + ITracker *m_parent; + Children m_children; + CycleState m_runState = NotStarted; + +public: + TrackerBase(NameAndLocation const &nameAndLocation, TrackerContext &ctx, ITracker *parent); + + NameAndLocation const &nameAndLocation() const override; + bool isComplete() const override; + bool isSuccessfullyCompleted() const override; + bool isOpen() const override; + bool hasChildren() const override; + + void addChild(ITrackerPtr const &child) override; + + ITrackerPtr findChild(NameAndLocation const &nameAndLocation) override; + ITracker &parent() override; + + void openChild() override; + + bool isSectionTracker() const override; + bool isIndexTracker() const override; + + void open(); + + void close() override; + void fail() override; + void markAsNeedingAnotherRun() override; + +private: + void moveToParent(); + void moveToThis(); +}; + +class SectionTracker : public TrackerBase { + std::vector m_filters; + +public: + SectionTracker(NameAndLocation const &nameAndLocation, TrackerContext &ctx, ITracker *parent); + + bool isSectionTracker() const override; + + static SectionTracker &acquire(TrackerContext &ctx, NameAndLocation const &nameAndLocation); + + void tryOpen(); + + void addInitialFilters(std::vector const &filters); + void addNextFilters(std::vector const &filters); +}; + +class IndexTracker : public TrackerBase { + int m_size; + int m_index = -1; + +public: + IndexTracker(NameAndLocation const &nameAndLocation, TrackerContext &ctx, ITracker *parent, int size); + + bool isIndexTracker() const override; + void close() override; + + static IndexTracker &acquire(TrackerContext &ctx, NameAndLocation const &nameAndLocation, int size); + + int index() const; + + void moveNext(); +}; + +} // namespace TestCaseTracking + +using TestCaseTracking::ITracker; +using TestCaseTracking::TrackerContext; +using TestCaseTracking::SectionTracker; +using TestCaseTracking::IndexTracker; + +} // namespace Catch + +// end catch_test_case_tracker.h + +// start catch_leak_detector.h + +namespace Catch { + +struct LeakDetector { + LeakDetector(); +}; + +} // namespace Catch +// end catch_leak_detector.h +// Cpp files will be included in the single-header file here +// start catch_approx.cpp + +#include +#include + +namespace { + +// Performs equivalent check of std::fabs(lhs - rhs) <= margin +// But without the subtraction to allow for INFINITY in comparison +bool marginComparison(double lhs, double rhs, double margin) { + return (lhs + margin >= rhs) && (rhs + margin >= lhs); +} + +} // namespace + +namespace Catch { +namespace Detail { + +Approx::Approx(double value) + : m_epsilon(std::numeric_limits::epsilon() * 100), m_margin(0.0), m_scale(0.0), m_value(value) { +} + +Approx Approx::custom() { + return Approx(0); +} + +std::string Approx::toString() const { + ReusableStringStream rss; + rss << "Approx( " << ::Catch::Detail::stringify(m_value) << " )"; + return rss.str(); +} + +bool Approx::equalityComparisonImpl(const double other) const { + // First try with fixed margin, then compute margin based on epsilon, scale and Approx's value + // Thanks to Richard Harris for his help refining the scaled margin value + return marginComparison(m_value, other, m_margin) || + marginComparison(m_value, other, m_epsilon * (m_scale + std::fabs(m_value))); +} + +} // end namespace Detail + +std::string StringMaker::convert(Catch::Detail::Approx const &value) { + return value.toString(); +} + +} // end namespace Catch +// end catch_approx.cpp +// start catch_assertionhandler.cpp + +// start catch_context.h + +#include + +namespace Catch { + +struct IResultCapture; +struct IRunner; +struct IConfig; +struct IMutableContext; + +using IConfigPtr = std::shared_ptr; + +struct IContext { + virtual ~IContext(); + + virtual IResultCapture *getResultCapture() = 0; + virtual IRunner *getRunner() = 0; + virtual IConfigPtr const &getConfig() const = 0; +}; + +struct IMutableContext : IContext { + virtual ~IMutableContext(); + virtual void setResultCapture(IResultCapture *resultCapture) = 0; + virtual void setRunner(IRunner *runner) = 0; + virtual void setConfig(IConfigPtr const &config) = 0; + +private: + static IMutableContext *currentContext; + friend IMutableContext &getCurrentMutableContext(); + friend void cleanUpContext(); + static void createContext(); +}; + +inline IMutableContext &getCurrentMutableContext() { + if (!IMutableContext::currentContext) + IMutableContext::createContext(); + return *IMutableContext::currentContext; +} + +inline IContext &getCurrentContext() { + return getCurrentMutableContext(); +} + +void cleanUpContext(); +} // namespace Catch + +// end catch_context.h +// start catch_debugger.h + +namespace Catch { +bool isDebuggerActive(); +} + +#ifdef CATCH_PLATFORM_MAC + +#define CATCH_TRAP() __asm__("int $3\n" : :) /* NOLINT */ + +#elif defined(CATCH_PLATFORM_LINUX) +// If we can use inline assembler, do it because this allows us to break +// directly at the location of the failing check instead of breaking inside +// raise() called from it, i.e. one stack frame below. +#if defined(__GNUC__) && (defined(__i386) || defined(__x86_64)) +#define CATCH_TRAP() asm volatile("int $3") /* NOLINT */ +#else // Fall back to the generic way. +#include + +#define CATCH_TRAP() raise(SIGTRAP) +#endif +#elif defined(_MSC_VER) +#define CATCH_TRAP() __debugbreak() +#elif defined(__MINGW32__) +extern "C" __declspec(dllimport) void __stdcall DebugBreak(); +#define CATCH_TRAP() DebugBreak() +#endif + +#ifdef CATCH_TRAP +#define CATCH_BREAK_INTO_DEBUGGER() \ + if (Catch::isDebuggerActive()) { \ + CATCH_TRAP(); \ + } +#else +namespace Catch { +inline void doNothing() { +} +} // namespace Catch +#define CATCH_BREAK_INTO_DEBUGGER() Catch::doNothing() +#endif + +// end catch_debugger.h +// start catch_run_context.h + +// start catch_fatal_condition.h + +// start catch_windows_h_proxy.h + +#if defined(CATCH_PLATFORM_WINDOWS) + +#if !defined(NOMINMAX) && !defined(CATCH_CONFIG_NO_NOMINMAX) +#define CATCH_DEFINED_NOMINMAX +#define NOMINMAX +#endif +#if !defined(WIN32_LEAN_AND_MEAN) && !defined(CATCH_CONFIG_NO_WIN32_LEAN_AND_MEAN) +#define CATCH_DEFINED_WIN32_LEAN_AND_MEAN +#define WIN32_LEAN_AND_MEAN +#endif + +#ifdef __AFXDLL +#include +#else +#include +#endif + +#ifdef CATCH_DEFINED_NOMINMAX +#undef NOMINMAX +#endif +#ifdef CATCH_DEFINED_WIN32_LEAN_AND_MEAN +#undef WIN32_LEAN_AND_MEAN +#endif + +#endif // defined(CATCH_PLATFORM_WINDOWS) + +// end catch_windows_h_proxy.h +#if defined(CATCH_CONFIG_WINDOWS_SEH) + +namespace Catch { + +struct FatalConditionHandler { + + static LONG CALLBACK handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo); + FatalConditionHandler(); + static void reset(); + ~FatalConditionHandler(); + +private: + static bool isSet; + static ULONG guaranteeSize; + static PVOID exceptionHandlerHandle; +}; + +} // namespace Catch + +#elif defined(CATCH_CONFIG_POSIX_SIGNALS) + +#include + +namespace Catch { + +struct FatalConditionHandler { + + static bool isSet; + static struct sigaction oldSigActions[]; + static stack_t oldSigStack; + static char altStackMem[]; + + static void handleSignal(int sig); + + FatalConditionHandler(); + ~FatalConditionHandler(); + static void reset(); +}; + +} // namespace Catch + +#else + +namespace Catch { +struct FatalConditionHandler { + void reset(); +}; +} // namespace Catch + +#endif + +// end catch_fatal_condition.h +#include + +namespace Catch { + +struct IMutableContext; + +/////////////////////////////////////////////////////////////////////////// + +class RunContext : public IResultCapture, public IRunner { + +public: + RunContext(RunContext const &) = delete; + RunContext &operator=(RunContext const &) = delete; + + explicit RunContext(IConfigPtr const &_config, IStreamingReporterPtr &&reporter); + + ~RunContext() override; + + void testGroupStarting(std::string const &testSpec, std::size_t groupIndex, std::size_t groupsCount); + void testGroupEnded(std::string const &testSpec, Totals const &totals, std::size_t groupIndex, + std::size_t groupsCount); + + Totals runTest(TestCase const &testCase); + + IConfigPtr config() const; + IStreamingReporter &reporter() const; + +public: // IResultCapture + // Assertion handlers + void handleExpr(AssertionInfo const &info, ITransientExpression const &expr, AssertionReaction &reaction) override; + void handleMessage(AssertionInfo const &info, ResultWas::OfType resultType, StringRef const &message, + AssertionReaction &reaction) override; + void handleUnexpectedExceptionNotThrown(AssertionInfo const &info, AssertionReaction &reaction) override; + void handleUnexpectedInflightException(AssertionInfo const &info, std::string const &message, + AssertionReaction &reaction) override; + void handleIncomplete(AssertionInfo const &info) override; + void handleNonExpr(AssertionInfo const &info, ResultWas::OfType resultType, AssertionReaction &reaction) override; + + bool sectionStarted(SectionInfo const §ionInfo, Counts &assertions) override; + + void sectionEnded(SectionEndInfo const &endInfo) override; + void sectionEndedEarly(SectionEndInfo const &endInfo) override; + + void benchmarkStarting(BenchmarkInfo const &info) override; + void benchmarkEnded(BenchmarkStats const &stats) override; + + void pushScopedMessage(MessageInfo const &message) override; + void popScopedMessage(MessageInfo const &message) override; + + std::string getCurrentTestName() const override; + + const AssertionResult *getLastResult() const override; + + void exceptionEarlyReported() override; + + void handleFatalErrorCondition(StringRef message) override; + + bool lastAssertionPassed() override; + + void assertionPassed() override; + +public: + // !TBD We need to do this another way! + bool aborting() const final; + +private: + void runCurrentTest(std::string &redirectedCout, std::string &redirectedCerr); + void invokeActiveTestCase(); + + void resetAssertionInfo(); + bool testForMissingAssertions(Counts &assertions); + + void assertionEnded(AssertionResult const &result); + void reportExpr(AssertionInfo const &info, ResultWas::OfType resultType, ITransientExpression const *expr, + bool negated); + + void populateReaction(AssertionReaction &reaction); + +private: + void handleUnfinishedSections(); + + TestRunInfo m_runInfo; + IMutableContext &m_context; + TestCase const *m_activeTestCase = nullptr; + ITracker *m_testCaseTracker; + Option m_lastResult; + + IConfigPtr m_config; + Totals m_totals; + IStreamingReporterPtr m_reporter; + std::vector m_messages; + AssertionInfo m_lastAssertionInfo; + std::vector m_unfinishedSections; + std::vector m_activeSections; + TrackerContext m_trackerContext; + bool m_lastAssertionPassed = false; + bool m_shouldReportUnexpected = true; + bool m_includeSuccessfulResults; +}; + +} // end namespace Catch + +// end catch_run_context.h +namespace Catch { + +auto operator<<(std::ostream &os, ITransientExpression const &expr) -> std::ostream & { + expr.streamReconstructedExpression(os); + return os; +} + +LazyExpression::LazyExpression(bool isNegated) : m_isNegated(isNegated) { +} + +LazyExpression::LazyExpression(LazyExpression const &other) : m_isNegated(other.m_isNegated) { +} + +LazyExpression::operator bool() const { + return m_transientExpression != nullptr; +} + +auto operator<<(std::ostream &os, LazyExpression const &lazyExpr) -> std::ostream & { + if (lazyExpr.m_isNegated) + os << "!"; + + if (lazyExpr) { + if (lazyExpr.m_isNegated && lazyExpr.m_transientExpression->isBinaryExpression()) + os << "(" << *lazyExpr.m_transientExpression << ")"; + else + os << *lazyExpr.m_transientExpression; + } else { + os << "{** error - unchecked empty expression requested **}"; + } + return os; +} + +AssertionHandler::AssertionHandler(StringRef macroName, SourceLineInfo const &lineInfo, StringRef capturedExpression, + ResultDisposition::Flags resultDisposition) + : m_assertionInfo{macroName, lineInfo, capturedExpression, resultDisposition}, m_resultCapture(getResultCapture()) { +} + +void AssertionHandler::handleExpr(ITransientExpression const &expr) { + m_resultCapture.handleExpr(m_assertionInfo, expr, m_reaction); +} +void AssertionHandler::handleMessage(ResultWas::OfType resultType, StringRef const &message) { + m_resultCapture.handleMessage(m_assertionInfo, resultType, message, m_reaction); +} + +auto AssertionHandler::allowThrows() const -> bool { + return getCurrentContext().getConfig()->allowThrows(); +} + +void AssertionHandler::complete() { + setCompleted(); + if (m_reaction.shouldDebugBreak) { + + // If you find your debugger stopping you here then go one level up on the + // call-stack for the code that caused it (typically a failed assertion) + + // (To go back to the test and change execution, jump over the throw, next) + CATCH_BREAK_INTO_DEBUGGER(); + } + if (m_reaction.shouldThrow) + throw Catch::TestFailureException(); +} +void AssertionHandler::setCompleted() { + m_completed = true; +} + +void AssertionHandler::handleUnexpectedInflightException() { + m_resultCapture.handleUnexpectedInflightException(m_assertionInfo, Catch::translateActiveException(), m_reaction); +} + +void AssertionHandler::handleExceptionThrownAsExpected() { + m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction); +} +void AssertionHandler::handleExceptionNotThrownAsExpected() { + m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction); +} + +void AssertionHandler::handleUnexpectedExceptionNotThrown() { + m_resultCapture.handleUnexpectedExceptionNotThrown(m_assertionInfo, m_reaction); +} + +void AssertionHandler::handleThrowingCallSkipped() { + m_resultCapture.handleNonExpr(m_assertionInfo, ResultWas::Ok, m_reaction); +} + +// This is the overload that takes a string and infers the Equals matcher from it +// The more general overload, that takes any string matcher, is in catch_capture_matchers.cpp +void handleExceptionMatchExpr(AssertionHandler &handler, std::string const &str, StringRef matcherString) { + handleExceptionMatchExpr(handler, Matchers::Equals(str), matcherString); +} + +} // namespace Catch +// end catch_assertionhandler.cpp +// start catch_assertionresult.cpp + +namespace Catch { +AssertionResultData::AssertionResultData(ResultWas::OfType _resultType, LazyExpression const &_lazyExpression) + : lazyExpression(_lazyExpression), resultType(_resultType) { +} + +std::string AssertionResultData::reconstructExpression() const { + + if (reconstructedExpression.empty()) { + if (lazyExpression) { + ReusableStringStream rss; + rss << lazyExpression; + reconstructedExpression = rss.str(); + } + } + return reconstructedExpression; +} + +AssertionResult::AssertionResult(AssertionInfo const &info, AssertionResultData const &data) + : m_info(info), m_resultData(data) { +} + +// Result was a success +bool AssertionResult::succeeded() const { + return Catch::isOk(m_resultData.resultType); +} + +// Result was a success, or failure is suppressed +bool AssertionResult::isOk() const { + return Catch::isOk(m_resultData.resultType) || shouldSuppressFailure(m_info.resultDisposition); +} + +ResultWas::OfType AssertionResult::getResultType() const { + return m_resultData.resultType; +} + +bool AssertionResult::hasExpression() const { + return m_info.capturedExpression[0] != 0; +} + +bool AssertionResult::hasMessage() const { + return !m_resultData.message.empty(); +} + +std::string AssertionResult::getExpression() const { + if (isFalseTest(m_info.resultDisposition)) + return "!(" + m_info.capturedExpression + ")"; + else + return m_info.capturedExpression; +} + +std::string AssertionResult::getExpressionInMacro() const { + std::string expr; + if (m_info.macroName[0] == 0) + expr = m_info.capturedExpression; + else { + expr.reserve(m_info.macroName.size() + m_info.capturedExpression.size() + 4); + expr += m_info.macroName; + expr += "( "; + expr += m_info.capturedExpression; + expr += " )"; + } + return expr; +} + +bool AssertionResult::hasExpandedExpression() const { + return hasExpression() && getExpandedExpression() != getExpression(); +} + +std::string AssertionResult::getExpandedExpression() const { + std::string expr = m_resultData.reconstructExpression(); + return expr.empty() ? getExpression() : expr; +} + +std::string AssertionResult::getMessage() const { + return m_resultData.message; +} +SourceLineInfo AssertionResult::getSourceInfo() const { + return m_info.lineInfo; +} + +StringRef AssertionResult::getTestMacroName() const { + return m_info.macroName; +} + +} // end namespace Catch +// end catch_assertionresult.cpp +// start catch_benchmark.cpp + +namespace Catch { + +auto BenchmarkLooper::getResolution() -> uint64_t { + return getEstimatedClockResolution() * getCurrentContext().getConfig()->benchmarkResolutionMultiple(); +} + +void BenchmarkLooper::reportStart() { + getResultCapture().benchmarkStarting({m_name}); +} +auto BenchmarkLooper::needsMoreIterations() -> bool { + auto elapsed = m_timer.getElapsedNanoseconds(); + + // Exponentially increasing iterations until we're confident in our timer resolution + if (elapsed < m_resolution) { + m_iterationsToRun *= 10; + return true; + } + + getResultCapture().benchmarkEnded({{m_name}, m_count, elapsed}); + return false; +} + +} // end namespace Catch +// end catch_benchmark.cpp +// start catch_capture_matchers.cpp + +namespace Catch { + +using StringMatcher = Matchers::Impl::MatcherBase; + +// This is the general overload that takes a any string matcher +// There is another overload, in catch_assertionhandler.h/.cpp, that only takes a string and infers +// the Equals matcher (so the header does not mention matchers) +void handleExceptionMatchExpr(AssertionHandler &handler, StringMatcher const &matcher, StringRef matcherString) { + std::string exceptionMessage = Catch::translateActiveException(); + MatchExpr expr(exceptionMessage, matcher, matcherString); + handler.handleExpr(expr); +} + +} // namespace Catch +// end catch_capture_matchers.cpp +// start catch_commandline.cpp + +// start catch_commandline.h + +// start catch_clara.h + +// Use Catch's value for console width (store Clara's off to the side, if present) +#ifdef CLARA_CONFIG_CONSOLE_WIDTH +#define CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH +#undef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH +#endif +#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CONFIG_CONSOLE_WIDTH - 1 + +#ifdef __clang__ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wweak-vtables" +#pragma clang diagnostic ignored "-Wexit-time-destructors" +#pragma clang diagnostic ignored "-Wshadow" +#endif + +// start clara.hpp +// Copyright 2017 Two Blue Cubes Ltd. All rights reserved. +// +// Distributed under the Boost Software License, Version 1.0. (See accompanying +// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) +// +// See https://github.com/philsquared/Clara for more details + +// Clara v1.1.4 + +#ifndef CATCH_CLARA_CONFIG_CONSOLE_WIDTH +#define CATCH_CLARA_CONFIG_CONSOLE_WIDTH 80 +#endif + +#ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH +#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_CLARA_CONFIG_CONSOLE_WIDTH +#endif + +#ifndef CLARA_CONFIG_OPTIONAL_TYPE +#ifdef __has_include +#if __has_include() && __cplusplus >= 201703L +#include +#define CLARA_CONFIG_OPTIONAL_TYPE std::optional +#endif +#endif +#endif + +// ----------- #included from clara_textflow.hpp ----------- + +// TextFlowCpp +// +// A single-header library for wrapping and laying out basic text, by Phil Nash +// +// This work is licensed under the BSD 2-Clause license. +// See the accompanying LICENSE file, or the one at https://opensource.org/licenses/BSD-2-Clause +// +// This project is hosted at https://github.com/philsquared/textflowcpp + +#include +#include +#include +#include + +#ifndef CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH +#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH 80 +#endif + +namespace Catch { +namespace clara { +namespace TextFlow { + +inline auto isWhitespace(char c) -> bool { + static std::string chars = " \t\n\r"; + return chars.find(c) != std::string::npos; +} +inline auto isBreakableBefore(char c) -> bool { + static std::string chars = "[({<|"; + return chars.find(c) != std::string::npos; +} +inline auto isBreakableAfter(char c) -> bool { + static std::string chars = "])}>.,:;*+-=&/\\"; + return chars.find(c) != std::string::npos; +} + +class Columns; + +class Column { + std::vector m_strings; + size_t m_width = CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH; + size_t m_indent = 0; + size_t m_initialIndent = std::string::npos; + +public: + class iterator { + friend Column; + + Column const &m_column; + size_t m_stringIndex = 0; + size_t m_pos = 0; + + size_t m_len = 0; + size_t m_end = 0; + bool m_suffix = false; + + iterator(Column const &column, size_t stringIndex) : m_column(column), m_stringIndex(stringIndex) { + } + + auto line() const -> std::string const & { + return m_column.m_strings[m_stringIndex]; + } + + auto isBoundary(size_t at) const -> bool { + assert(at > 0); + assert(at <= line().size()); + + return at == line().size() || (isWhitespace(line()[at]) && !isWhitespace(line()[at - 1])) || + isBreakableBefore(line()[at]) || isBreakableAfter(line()[at - 1]); + } + + void calcLength() { + assert(m_stringIndex < m_column.m_strings.size()); + + m_suffix = false; + auto width = m_column.m_width - indent(); + m_end = m_pos; + while (m_end < line().size() && line()[m_end] != '\n') + ++m_end; + + if (m_end < m_pos + width) { + m_len = m_end - m_pos; + } else { + size_t len = width; + while (len > 0 && !isBoundary(m_pos + len)) + --len; + while (len > 0 && isWhitespace(line()[m_pos + len - 1])) + --len; + + if (len > 0) { + m_len = len; + } else { + m_suffix = true; + m_len = width - 1; + } + } + } + + auto indent() const -> size_t { + auto initial = m_pos == 0 && m_stringIndex == 0 ? m_column.m_initialIndent : std::string::npos; + return initial == std::string::npos ? m_column.m_indent : initial; + } + + auto addIndentAndSuffix(std::string const &plain) const -> std::string { + return std::string(indent(), ' ') + (m_suffix ? plain + "-" : plain); + } + + public: + explicit iterator(Column const &column) : m_column(column) { + assert(m_column.m_width > m_column.m_indent); + assert(m_column.m_initialIndent == std::string::npos || m_column.m_width > m_column.m_initialIndent); + calcLength(); + if (m_len == 0) + m_stringIndex++; // Empty string + } + + auto operator*() const -> std::string { + assert(m_stringIndex < m_column.m_strings.size()); + assert(m_pos <= m_end); + if (m_pos + m_column.m_width < m_end) + return addIndentAndSuffix(line().substr(m_pos, m_len)); + else + return addIndentAndSuffix(line().substr(m_pos, m_end - m_pos)); + } + + auto operator++() -> iterator & { + m_pos += m_len; + if (m_pos < line().size() && line()[m_pos] == '\n') + m_pos += 1; + else + while (m_pos < line().size() && isWhitespace(line()[m_pos])) + ++m_pos; + + if (m_pos == line().size()) { + m_pos = 0; + ++m_stringIndex; + } + if (m_stringIndex < m_column.m_strings.size()) + calcLength(); + return *this; + } + auto operator++(int) -> iterator { + iterator prev(*this); + operator++(); + return prev; + } + + auto operator==(iterator const &other) const -> bool { + return m_pos == other.m_pos && m_stringIndex == other.m_stringIndex && &m_column == &other.m_column; + } + auto operator!=(iterator const &other) const -> bool { + return !operator==(other); + } + }; + using const_iterator = iterator; + + explicit Column(std::string const &text) { + m_strings.push_back(text); + } + + auto width(size_t newWidth) -> Column & { + assert(newWidth > 0); + m_width = newWidth; + return *this; + } + auto indent(size_t newIndent) -> Column & { + m_indent = newIndent; + return *this; + } + auto initialIndent(size_t newIndent) -> Column & { + m_initialIndent = newIndent; + return *this; + } + + auto width() const -> size_t { + return m_width; + } + auto begin() const -> iterator { + return iterator(*this); + } + auto end() const -> iterator { + return {*this, m_strings.size()}; + } + + inline friend std::ostream &operator<<(std::ostream &os, Column const &col) { + bool first = true; + for (auto line : col) { + if (first) + first = false; + else + os << "\n"; + os << line; + } + return os; + } + + auto operator+(Column const &other) -> Columns; + + auto toString() const -> std::string { + std::ostringstream oss; + oss << *this; + return oss.str(); + } +}; + +class Spacer : public Column { + +public: + explicit Spacer(size_t spaceWidth) : Column("") { + width(spaceWidth); + } +}; + +class Columns { + std::vector m_columns; + +public: + class iterator { + friend Columns; + struct EndTag {}; + + std::vector const &m_columns; + std::vector m_iterators; + size_t m_activeIterators; + + iterator(Columns const &columns, EndTag) : m_columns(columns.m_columns), m_activeIterators(0) { + m_iterators.reserve(m_columns.size()); + + for (auto const &col : m_columns) + m_iterators.push_back(col.end()); + } + + public: + explicit iterator(Columns const &columns) : m_columns(columns.m_columns), m_activeIterators(m_columns.size()) { + m_iterators.reserve(m_columns.size()); + + for (auto const &col : m_columns) + m_iterators.push_back(col.begin()); + } + + auto operator==(iterator const &other) const -> bool { + return m_iterators == other.m_iterators; + } + auto operator!=(iterator const &other) const -> bool { + return m_iterators != other.m_iterators; + } + auto operator*() const -> std::string { + std::string row, padding; + + for (size_t i = 0; i < m_columns.size(); ++i) { + auto width = m_columns[i].width(); + if (m_iterators[i] != m_columns[i].end()) { + std::string col = *m_iterators[i]; + row += padding + col; + if (col.size() < width) + padding = std::string(width - col.size(), ' '); + else + padding = ""; + } else { + padding += std::string(width, ' '); + } + } + return row; + } + auto operator++() -> iterator & { + for (size_t i = 0; i < m_columns.size(); ++i) { + if (m_iterators[i] != m_columns[i].end()) + ++m_iterators[i]; + } + return *this; + } + auto operator++(int) -> iterator { + iterator prev(*this); + operator++(); + return prev; + } + }; + using const_iterator = iterator; + + auto begin() const -> iterator { + return iterator(*this); + } + auto end() const -> iterator { + return {*this, iterator::EndTag()}; + } + + auto operator+=(Column const &col) -> Columns & { + m_columns.push_back(col); + return *this; + } + auto operator+(Column const &col) -> Columns { + Columns combined = *this; + combined += col; + return combined; + } + + inline friend std::ostream &operator<<(std::ostream &os, Columns const &cols) { + + bool first = true; + for (auto line : cols) { + if (first) + first = false; + else + os << "\n"; + os << line; + } + return os; + } + + auto toString() const -> std::string { + std::ostringstream oss; + oss << *this; + return oss.str(); + } +}; + +inline auto Column::operator+(Column const &other) -> Columns { + Columns cols; + cols += *this; + cols += other; + return cols; +} +} // namespace TextFlow +} // namespace clara +} // namespace Catch + +// ----------- end of #include from clara_textflow.hpp ----------- +// ........... back in clara.hpp + +#include +#include +#include + +#if !defined(CATCH_PLATFORM_WINDOWS) && (defined(WIN32) || defined(__WIN32__) || defined(_WIN32) || defined(_MSC_VER)) +#define CATCH_PLATFORM_WINDOWS +#endif + +namespace Catch { +namespace clara { +namespace detail { + +// Traits for extracting arg and return type of lambdas (for single argument lambdas) +template struct UnaryLambdaTraits : UnaryLambdaTraits {}; + +template +struct UnaryLambdaTraits { + static const bool isValid = false; +}; + +template struct UnaryLambdaTraits { + static const bool isValid = true; + using ArgType = typename std::remove_const::type>::type; + using ReturnType = ReturnT; +}; + +class TokenStream; + +// Transport for raw args (copied from main args, or supplied via init list for testing) +class Args { + friend TokenStream; + std::string m_exeName; + std::vector m_args; + +public: + Args(int argc, char const *const *argv) : m_exeName(argv[0]), m_args(argv + 1, argv + argc) { + } + + Args(std::initializer_list args) : m_exeName(*args.begin()), m_args(args.begin() + 1, args.end()) { + } + + auto exeName() const -> std::string { + return m_exeName; + } +}; + +// Wraps a token coming from a token stream. These may not directly correspond to strings as a single string +// may encode an option + its argument if the : or = form is used +enum class TokenType { Option, Argument }; +struct Token { + TokenType type; + std::string token; +}; + +inline auto isOptPrefix(char c) -> bool { + return c == '-' +#ifdef CATCH_PLATFORM_WINDOWS + || c == '/' +#endif + ; +} + +// Abstracts iterators into args as a stream of tokens, with option arguments uniformly handled +class TokenStream { + using Iterator = std::vector::const_iterator; + Iterator it; + Iterator itEnd; + std::vector m_tokenBuffer; + + void loadBuffer() { + m_tokenBuffer.resize(0); + + // Skip any empty strings + while (it != itEnd && it->empty()) + ++it; + + if (it != itEnd) { + auto const &next = *it; + if (isOptPrefix(next[0])) { + auto delimiterPos = next.find_first_of(" :="); + if (delimiterPos != std::string::npos) { + m_tokenBuffer.push_back({TokenType::Option, next.substr(0, delimiterPos)}); + m_tokenBuffer.push_back({TokenType::Argument, next.substr(delimiterPos + 1)}); + } else { + if (next[1] != '-' && next.size() > 2) { + std::string opt = "- "; + for (size_t i = 1; i < next.size(); ++i) { + opt[1] = next[i]; + m_tokenBuffer.push_back({TokenType::Option, opt}); + } + } else { + m_tokenBuffer.push_back({TokenType::Option, next}); + } + } + } else { + m_tokenBuffer.push_back({TokenType::Argument, next}); + } + } + } + +public: + explicit TokenStream(Args const &args) : TokenStream(args.m_args.begin(), args.m_args.end()) { + } + + TokenStream(Iterator it, Iterator itEnd) : it(it), itEnd(itEnd) { + loadBuffer(); + } + + explicit operator bool() const { + return !m_tokenBuffer.empty() || it != itEnd; + } + + auto count() const -> size_t { + return m_tokenBuffer.size() + (itEnd - it); + } + + auto operator*() const -> Token { + assert(!m_tokenBuffer.empty()); + return m_tokenBuffer.front(); + } + + auto operator-> () const -> Token const * { + assert(!m_tokenBuffer.empty()); + return &m_tokenBuffer.front(); + } + + auto operator++() -> TokenStream & { + if (m_tokenBuffer.size() >= 2) { + m_tokenBuffer.erase(m_tokenBuffer.begin()); + } else { + if (it != itEnd) + ++it; + loadBuffer(); + } + return *this; + } +}; + +class ResultBase { +public: + enum Type { Ok, LogicError, RuntimeError }; + +protected: + ResultBase(Type type) : m_type(type) { + } + virtual ~ResultBase() = default; + + virtual void enforceOk() const = 0; + + Type m_type; +}; + +template class ResultValueBase : public ResultBase { +public: + auto value() const -> T const & { + enforceOk(); + return m_value; + } + +protected: + ResultValueBase(Type type) : ResultBase(type) { + } + + ResultValueBase(ResultValueBase const &other) : ResultBase(other) { + if (m_type == ResultBase::Ok) + new (&m_value) T(other.m_value); + } + + ResultValueBase(Type, T const &value) : ResultBase(Ok) { + new (&m_value) T(value); + } + + auto operator=(ResultValueBase const &other) -> ResultValueBase & { + if (m_type == ResultBase::Ok) + m_value.~T(); + ResultBase::operator=(other); + if (m_type == ResultBase::Ok) + new (&m_value) T(other.m_value); + return *this; + } + + ~ResultValueBase() override { + if (m_type == Ok) + m_value.~T(); + } + + union { + T m_value; + }; +}; + +template <> class ResultValueBase : public ResultBase { +protected: + using ResultBase::ResultBase; +}; + +template class BasicResult : public ResultValueBase { +public: + template + explicit BasicResult(BasicResult const &other) + : ResultValueBase(other.type()), m_errorMessage(other.errorMessage()) { + assert(type() != ResultBase::Ok); + } + + template static auto ok(U const &value) -> BasicResult { + return {ResultBase::Ok, value}; + } + static auto ok() -> BasicResult { + return {ResultBase::Ok}; + } + static auto logicError(std::string const &message) -> BasicResult { + return {ResultBase::LogicError, message}; + } + static auto runtimeError(std::string const &message) -> BasicResult { + return {ResultBase::RuntimeError, message}; + } + + explicit operator bool() const { + return m_type == ResultBase::Ok; + } + auto type() const -> ResultBase::Type { + return m_type; + } + auto errorMessage() const -> std::string { + return m_errorMessage; + } + +protected: + void enforceOk() const override { + + // Errors shouldn't reach this point, but if they do + // the actual error message will be in m_errorMessage + assert(m_type != ResultBase::LogicError); + assert(m_type != ResultBase::RuntimeError); + if (m_type != ResultBase::Ok) + std::abort(); + } + + std::string m_errorMessage; // Only populated if resultType is an error + + BasicResult(ResultBase::Type type, std::string const &message) : ResultValueBase(type), m_errorMessage(message) { + assert(m_type != ResultBase::Ok); + } + + using ResultValueBase::ResultValueBase; + using ResultBase::m_type; +}; + +enum class ParseResultType { Matched, NoMatch, ShortCircuitAll, ShortCircuitSame }; + +class ParseState { +public: + ParseState(ParseResultType type, TokenStream const &remainingTokens) + : m_type(type), m_remainingTokens(remainingTokens) { + } + + auto type() const -> ParseResultType { + return m_type; + } + auto remainingTokens() const -> TokenStream { + return m_remainingTokens; + } + +private: + ParseResultType m_type; + TokenStream m_remainingTokens; +}; + +using Result = BasicResult; +using ParserResult = BasicResult; +using InternalParseResult = BasicResult; + +struct HelpColumns { + std::string left; + std::string right; +}; + +template inline auto convertInto(std::string const &source, T &target) -> ParserResult { + std::stringstream ss; + ss << source; + ss >> target; + if (ss.fail()) + return ParserResult::runtimeError("Unable to convert '" + source + "' to destination type"); + else + return ParserResult::ok(ParseResultType::Matched); +} +inline auto convertInto(std::string const &source, std::string &target) -> ParserResult { + target = source; + return ParserResult::ok(ParseResultType::Matched); +} +inline auto convertInto(std::string const &source, bool &target) -> ParserResult { + std::string srcLC = source; + std::transform(srcLC.begin(), srcLC.end(), srcLC.begin(), [](char c) { return static_cast(::tolower(c)); }); + if (srcLC == "y" || srcLC == "1" || srcLC == "true" || srcLC == "yes" || srcLC == "on") + target = true; + else if (srcLC == "n" || srcLC == "0" || srcLC == "false" || srcLC == "no" || srcLC == "off") + target = false; + else + return ParserResult::runtimeError("Expected a boolean value but did not recognise: '" + source + "'"); + return ParserResult::ok(ParseResultType::Matched); +} +#ifdef CLARA_CONFIG_OPTIONAL_TYPE +template +inline auto convertInto(std::string const &source, CLARA_CONFIG_OPTIONAL_TYPE &target) -> ParserResult { + T temp; + auto result = convertInto(source, temp); + if (result) + target = std::move(temp); + return result; +} +#endif // CLARA_CONFIG_OPTIONAL_TYPE + +struct NonCopyable { + NonCopyable() = default; + NonCopyable(NonCopyable const &) = delete; + NonCopyable(NonCopyable &&) = delete; + NonCopyable &operator=(NonCopyable const &) = delete; + NonCopyable &operator=(NonCopyable &&) = delete; +}; + +struct BoundRef : NonCopyable { + virtual ~BoundRef() = default; + virtual auto isContainer() const -> bool { + return false; + } + virtual auto isFlag() const -> bool { + return false; + } +}; +struct BoundValueRefBase : BoundRef { + virtual auto setValue(std::string const &arg) -> ParserResult = 0; +}; +struct BoundFlagRefBase : BoundRef { + virtual auto setFlag(bool flag) -> ParserResult = 0; + virtual auto isFlag() const -> bool { + return true; + } +}; + +template struct BoundValueRef : BoundValueRefBase { + T &m_ref; + + explicit BoundValueRef(T &ref) : m_ref(ref) { + } + + auto setValue(std::string const &arg) -> ParserResult override { + return convertInto(arg, m_ref); + } +}; + +template struct BoundValueRef> : BoundValueRefBase { + std::vector &m_ref; + + explicit BoundValueRef(std::vector &ref) : m_ref(ref) { + } + + auto isContainer() const -> bool override { + return true; + } + + auto setValue(std::string const &arg) -> ParserResult override { + T temp; + auto result = convertInto(arg, temp); + if (result) + m_ref.push_back(temp); + return result; + } +}; + +struct BoundFlagRef : BoundFlagRefBase { + bool &m_ref; + + explicit BoundFlagRef(bool &ref) : m_ref(ref) { + } + + auto setFlag(bool flag) -> ParserResult override { + m_ref = flag; + return ParserResult::ok(ParseResultType::Matched); + } +}; + +template struct LambdaInvoker { + static_assert(std::is_same::value, "Lambda must return void or clara::ParserResult"); + + template static auto invoke(L const &lambda, ArgType const &arg) -> ParserResult { + return lambda(arg); + } +}; + +template <> struct LambdaInvoker { + template static auto invoke(L const &lambda, ArgType const &arg) -> ParserResult { + lambda(arg); + return ParserResult::ok(ParseResultType::Matched); + } +}; + +template +inline auto invokeLambda(L const &lambda, std::string const &arg) -> ParserResult { + ArgType temp{}; + auto result = convertInto(arg, temp); + return !result ? result : LambdaInvoker::ReturnType>::invoke(lambda, temp); +} + +template struct BoundLambda : BoundValueRefBase { + L m_lambda; + + static_assert(UnaryLambdaTraits::isValid, "Supplied lambda must take exactly one argument"); + explicit BoundLambda(L const &lambda) : m_lambda(lambda) { + } + + auto setValue(std::string const &arg) -> ParserResult override { + return invokeLambda::ArgType>(m_lambda, arg); + } +}; + +template struct BoundFlagLambda : BoundFlagRefBase { + L m_lambda; + + static_assert(UnaryLambdaTraits::isValid, "Supplied lambda must take exactly one argument"); + static_assert(std::is_same::ArgType, bool>::value, "flags must be boolean"); + + explicit BoundFlagLambda(L const &lambda) : m_lambda(lambda) { + } + + auto setFlag(bool flag) -> ParserResult override { + return LambdaInvoker::ReturnType>::invoke(m_lambda, flag); + } +}; + +enum class Optionality { Optional, Required }; + +struct Parser; + +class ParserBase { +public: + virtual ~ParserBase() = default; + virtual auto validate() const -> Result { + return Result::ok(); + } + virtual auto parse(std::string const &exeName, TokenStream const &tokens) const -> InternalParseResult = 0; + virtual auto cardinality() const -> size_t { + return 1; + } + + auto parse(Args const &args) const -> InternalParseResult { + return parse(args.exeName(), TokenStream(args)); + } +}; + +template class ComposableParserImpl : public ParserBase { +public: + template auto operator|(T const &other) const -> Parser; + + template auto operator+(T const &other) const -> Parser; +}; + +// Common code and state for Args and Opts +template class ParserRefImpl : public ComposableParserImpl { +protected: + Optionality m_optionality = Optionality::Optional; + std::shared_ptr m_ref; + std::string m_hint; + std::string m_description; + + explicit ParserRefImpl(std::shared_ptr const &ref) : m_ref(ref) { + } + +public: + template + ParserRefImpl(T &ref, std::string const &hint) : m_ref(std::make_shared>(ref)), m_hint(hint) { + } + + template + ParserRefImpl(LambdaT const &ref, std::string const &hint) + : m_ref(std::make_shared>(ref)), m_hint(hint) { + } + + auto operator()(std::string const &description) -> DerivedT & { + m_description = description; + return static_cast(*this); + } + + auto optional() -> DerivedT & { + m_optionality = Optionality::Optional; + return static_cast(*this); + }; + + auto required() -> DerivedT & { + m_optionality = Optionality::Required; + return static_cast(*this); + }; + + auto isOptional() const -> bool { + return m_optionality == Optionality::Optional; + } + + auto cardinality() const -> size_t override { + if (m_ref->isContainer()) + return 0; + else + return 1; + } + + auto hint() const -> std::string { + return m_hint; + } +}; + +class ExeName : public ComposableParserImpl { + std::shared_ptr m_name; + std::shared_ptr m_ref; + + template static auto makeRef(LambdaT const &lambda) -> std::shared_ptr { + return std::make_shared>(lambda); + } + +public: + ExeName() : m_name(std::make_shared("")) { + } + + explicit ExeName(std::string &ref) : ExeName() { + m_ref = std::make_shared>(ref); + } + + template explicit ExeName(LambdaT const &lambda) : ExeName() { + m_ref = std::make_shared>(lambda); + } + + // The exe name is not parsed out of the normal tokens, but is handled specially + auto parse(std::string const &, TokenStream const &tokens) const -> InternalParseResult override { + return InternalParseResult::ok(ParseState(ParseResultType::NoMatch, tokens)); + } + + auto name() const -> std::string { + return *m_name; + } + auto set(std::string const &newName) -> ParserResult { + + auto lastSlash = newName.find_last_of("\\/"); + auto filename = (lastSlash == std::string::npos) ? newName : newName.substr(lastSlash + 1); + + *m_name = filename; + if (m_ref) + return m_ref->setValue(filename); + else + return ParserResult::ok(ParseResultType::Matched); + } +}; + +class Arg : public ParserRefImpl { +public: + using ParserRefImpl::ParserRefImpl; + + auto parse(std::string const &, TokenStream const &tokens) const -> InternalParseResult override { + auto validationResult = validate(); + if (!validationResult) + return InternalParseResult(validationResult); + + auto remainingTokens = tokens; + auto const &token = *remainingTokens; + if (token.type != TokenType::Argument) + return InternalParseResult::ok(ParseState(ParseResultType::NoMatch, remainingTokens)); + + assert(!m_ref->isFlag()); + auto valueRef = static_cast(m_ref.get()); + + auto result = valueRef->setValue(remainingTokens->token); + if (!result) + return InternalParseResult(result); + else + return InternalParseResult::ok(ParseState(ParseResultType::Matched, ++remainingTokens)); + } +}; + +inline auto normaliseOpt(std::string const &optName) -> std::string { +#ifdef CATCH_PLATFORM_WINDOWS + if (optName[0] == '/') + return "-" + optName.substr(1); + else +#endif + return optName; +} + +class Opt : public ParserRefImpl { +protected: + std::vector m_optNames; + +public: + template + explicit Opt(LambdaT const &ref) : ParserRefImpl(std::make_shared>(ref)) { + } + + explicit Opt(bool &ref) : ParserRefImpl(std::make_shared(ref)) { + } + + template Opt(LambdaT const &ref, std::string const &hint) : ParserRefImpl(ref, hint) { + } + + template Opt(T &ref, std::string const &hint) : ParserRefImpl(ref, hint) { + } + + auto operator[](std::string const &optName) -> Opt & { + m_optNames.push_back(optName); + return *this; + } + + auto getHelpColumns() const -> std::vector { + std::ostringstream oss; + bool first = true; + for (auto const &opt : m_optNames) { + if (first) + first = false; + else + oss << ", "; + oss << opt; + } + if (!m_hint.empty()) + oss << " <" << m_hint << ">"; + return {{oss.str(), m_description}}; + } + + auto isMatch(std::string const &optToken) const -> bool { + auto normalisedToken = normaliseOpt(optToken); + for (auto const &name : m_optNames) { + if (normaliseOpt(name) == normalisedToken) + return true; + } + return false; + } + + using ParserBase::parse; + + auto parse(std::string const &, TokenStream const &tokens) const -> InternalParseResult override { + auto validationResult = validate(); + if (!validationResult) + return InternalParseResult(validationResult); + + auto remainingTokens = tokens; + if (remainingTokens && remainingTokens->type == TokenType::Option) { + auto const &token = *remainingTokens; + if (isMatch(token.token)) { + if (m_ref->isFlag()) { + auto flagRef = static_cast(m_ref.get()); + auto result = flagRef->setFlag(true); + if (!result) + return InternalParseResult(result); + if (result.value() == ParseResultType::ShortCircuitAll) + return InternalParseResult::ok(ParseState(result.value(), remainingTokens)); + } else { + auto valueRef = static_cast(m_ref.get()); + ++remainingTokens; + if (!remainingTokens) + return InternalParseResult::runtimeError("Expected argument following " + token.token); + auto const &argToken = *remainingTokens; + if (argToken.type != TokenType::Argument) + return InternalParseResult::runtimeError("Expected argument following " + token.token); + auto result = valueRef->setValue(argToken.token); + if (!result) + return InternalParseResult(result); + if (result.value() == ParseResultType::ShortCircuitAll) + return InternalParseResult::ok(ParseState(result.value(), remainingTokens)); + } + return InternalParseResult::ok(ParseState(ParseResultType::Matched, ++remainingTokens)); + } + } + return InternalParseResult::ok(ParseState(ParseResultType::NoMatch, remainingTokens)); + } + + auto validate() const -> Result override { + if (m_optNames.empty()) + return Result::logicError("No options supplied to Opt"); + for (auto const &name : m_optNames) { + if (name.empty()) + return Result::logicError("Option name cannot be empty"); +#ifdef CATCH_PLATFORM_WINDOWS + if (name[0] != '-' && name[0] != '/') + return Result::logicError("Option name must begin with '-' or '/'"); +#else + if (name[0] != '-') + return Result::logicError("Option name must begin with '-'"); +#endif + } + return ParserRefImpl::validate(); + } +}; + +struct Help : Opt { + Help(bool &showHelpFlag) + : Opt([&](bool flag) { + showHelpFlag = flag; + return ParserResult::ok(ParseResultType::ShortCircuitAll); + }) { + static_cast (*this)("display usage information")["-?"]["-h"]["--help"].optional(); + } +}; + +struct Parser : ParserBase { + + mutable ExeName m_exeName; + std::vector m_options; + std::vector m_args; + + auto operator|=(ExeName const &exeName) -> Parser & { + m_exeName = exeName; + return *this; + } + + auto operator|=(Arg const &arg) -> Parser & { + m_args.push_back(arg); + return *this; + } + + auto operator|=(Opt const &opt) -> Parser & { + m_options.push_back(opt); + return *this; + } + + auto operator|=(Parser const &other) -> Parser & { + m_options.insert(m_options.end(), other.m_options.begin(), other.m_options.end()); + m_args.insert(m_args.end(), other.m_args.begin(), other.m_args.end()); + return *this; + } + + template auto operator|(T const &other) const -> Parser { + return Parser(*this) |= other; + } + + // Forward deprecated interface with '+' instead of '|' + template auto operator+=(T const &other) -> Parser & { + return operator|=(other); + } + template auto operator+(T const &other) const -> Parser { + return operator|(other); + } + + auto getHelpColumns() const -> std::vector { + std::vector cols; + for (auto const &o : m_options) { + auto childCols = o.getHelpColumns(); + cols.insert(cols.end(), childCols.begin(), childCols.end()); + } + return cols; + } + + void writeToStream(std::ostream &os) const { + if (!m_exeName.name().empty()) { + os << "usage:\n" + << " " << m_exeName.name() << " "; + bool required = true, first = true; + for (auto const &arg : m_args) { + if (first) + first = false; + else + os << " "; + if (arg.isOptional() && required) { + os << "["; + required = false; + } + os << "<" << arg.hint() << ">"; + if (arg.cardinality() == 0) + os << " ... "; + } + if (!required) + os << "]"; + if (!m_options.empty()) + os << " options"; + os << "\n\nwhere options are:" << std::endl; + } + + auto rows = getHelpColumns(); + size_t consoleWidth = CATCH_CLARA_CONFIG_CONSOLE_WIDTH; + size_t optWidth = 0; + for (auto const &cols : rows) + optWidth = (std::max)(optWidth, cols.left.size() + 2); + + optWidth = (std::min)(optWidth, consoleWidth / 2); + + for (auto const &cols : rows) { + auto row = TextFlow::Column(cols.left).width(optWidth).indent(2) + TextFlow::Spacer(4) + + TextFlow::Column(cols.right).width(consoleWidth - 7 - optWidth); + os << row << std::endl; + } + } + + friend auto operator<<(std::ostream &os, Parser const &parser) -> std::ostream & { + parser.writeToStream(os); + return os; + } + + auto validate() const -> Result override { + for (auto const &opt : m_options) { + auto result = opt.validate(); + if (!result) + return result; + } + for (auto const &arg : m_args) { + auto result = arg.validate(); + if (!result) + return result; + } + return Result::ok(); + } + + using ParserBase::parse; + + auto parse(std::string const &exeName, TokenStream const &tokens) const -> InternalParseResult override { + + struct ParserInfo { + ParserBase const *parser = nullptr; + size_t count = 0; + }; + const size_t totalParsers = m_options.size() + m_args.size(); + assert(totalParsers < 512); + // ParserInfo parseInfos[totalParsers]; // <-- this is what we really want to do + ParserInfo parseInfos[512]; + + { + size_t i = 0; + for (auto const &opt : m_options) + parseInfos[i++].parser = &opt; + for (auto const &arg : m_args) + parseInfos[i++].parser = &arg; + } + + m_exeName.set(exeName); + + auto result = InternalParseResult::ok(ParseState(ParseResultType::NoMatch, tokens)); + while (result.value().remainingTokens()) { + bool tokenParsed = false; + + for (size_t i = 0; i < totalParsers; ++i) { + auto &parseInfo = parseInfos[i]; + if (parseInfo.parser->cardinality() == 0 || parseInfo.count < parseInfo.parser->cardinality()) { + result = parseInfo.parser->parse(exeName, result.value().remainingTokens()); + if (!result) + return result; + if (result.value().type() != ParseResultType::NoMatch) { + tokenParsed = true; + ++parseInfo.count; + break; + } + } + } + + if (result.value().type() == ParseResultType::ShortCircuitAll) + return result; + if (!tokenParsed) + return InternalParseResult::runtimeError("Unrecognised token: " + result.value().remainingTokens()->token); + } + // !TBD Check missing required options + return result; + } +}; + +template +template +auto ComposableParserImpl::operator|(T const &other) const -> Parser { + return Parser() | static_cast(*this) | other; +} +} // namespace detail + +// A Combined parser +using detail::Parser; + +// A parser for options +using detail::Opt; + +// A parser for arguments +using detail::Arg; + +// Wrapper for argc, argv from main() +using detail::Args; + +// Specifies the name of the executable +using detail::ExeName; + +// Convenience wrapper for option parser that specifies the help option +using detail::Help; + +// enum of result types from a parse +using detail::ParseResultType; + +// Result type for parser operation +using detail::ParserResult; + +} // namespace clara +} // namespace Catch + +// end clara.hpp +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +// Restore Clara's value for console width, if present +#ifdef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH +#define CATCH_CLARA_TEXTFLOW_CONFIG_CONSOLE_WIDTH CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH +#undef CATCH_TEMP_CLARA_CONFIG_CONSOLE_WIDTH +#endif + +// end catch_clara.h +namespace Catch { + +clara::Parser makeCommandLineParser(ConfigData &config); + +} // end namespace Catch + +// end catch_commandline.h +#include +#include + +namespace Catch { + +clara::Parser makeCommandLineParser(ConfigData &config) { + + using namespace clara; + + auto const setWarning = [&](std::string const &warning) { + auto warningSet = [&]() { + if (warning == "NoAssertions") + return WarnAbout::NoAssertions; + + if (warning == "NoTests") + return WarnAbout::NoTests; + + return WarnAbout::Nothing; + }(); + + if (warningSet == WarnAbout::Nothing) + return ParserResult::runtimeError("Unrecognised warning: '" + warning + "'"); + config.warnings = static_cast(config.warnings | warningSet); + return ParserResult::ok(ParseResultType::Matched); + }; + auto const loadTestNamesFromFile = [&](std::string const &filename) { + std::ifstream f(filename.c_str()); + if (!f.is_open()) + return ParserResult::runtimeError("Unable to load input file: '" + filename + "'"); + + std::string line; + while (std::getline(f, line)) { + line = trim(line); + if (!line.empty() && !startsWith(line, '#')) { + if (!startsWith(line, '"')) + line = '"' + line + '"'; + config.testsOrTags.push_back(line + ','); + } + } + return ParserResult::ok(ParseResultType::Matched); + }; + auto const setTestOrder = [&](std::string const &order) { + if (startsWith("declared", order)) + config.runOrder = RunTests::InDeclarationOrder; + else if (startsWith("lexical", order)) + config.runOrder = RunTests::InLexicographicalOrder; + else if (startsWith("random", order)) + config.runOrder = RunTests::InRandomOrder; + else + return clara::ParserResult::runtimeError("Unrecognised ordering: '" + order + "'"); + return ParserResult::ok(ParseResultType::Matched); + }; + auto const setRngSeed = [&](std::string const &seed) { + if (seed != "time") + return clara::detail::convertInto(seed, config.rngSeed); + config.rngSeed = static_cast(std::time(nullptr)); + return ParserResult::ok(ParseResultType::Matched); + }; + auto const setColourUsage = [&](std::string const &useColour) { + auto mode = toLower(useColour); + + if (mode == "yes") + config.useColour = UseColour::Yes; + else if (mode == "no") + config.useColour = UseColour::No; + else if (mode == "auto") + config.useColour = UseColour::Auto; + else + return ParserResult::runtimeError("colour mode must be one of: auto, yes or no. '" + useColour + + "' not recognised"); + return ParserResult::ok(ParseResultType::Matched); + }; + auto const setWaitForKeypress = [&](std::string const &keypress) { + auto keypressLc = toLower(keypress); + if (keypressLc == "start") + config.waitForKeypress = WaitForKeypress::BeforeStart; + else if (keypressLc == "exit") + config.waitForKeypress = WaitForKeypress::BeforeExit; + else if (keypressLc == "both") + config.waitForKeypress = WaitForKeypress::BeforeStartAndExit; + else + return ParserResult::runtimeError("keypress argument must be one of: start, exit or both. '" + keypress + + "' not recognised"); + return ParserResult::ok(ParseResultType::Matched); + }; + auto const setVerbosity = [&](std::string const &verbosity) { + auto lcVerbosity = toLower(verbosity); + if (lcVerbosity == "quiet") + config.verbosity = Verbosity::Quiet; + else if (lcVerbosity == "normal") + config.verbosity = Verbosity::Normal; + else if (lcVerbosity == "high") + config.verbosity = Verbosity::High; + else + return ParserResult::runtimeError("Unrecognised verbosity, '" + verbosity + "'"); + return ParserResult::ok(ParseResultType::Matched); + }; + + auto cli = ExeName(config.processName) | Help(config.showHelp) | + Opt(config.listTests)["-l"]["--list-tests"]("list all/matching test cases") | + Opt(config.listTags)["-t"]["--list-tags"]("list all/matching tags") | + Opt(config.showSuccessfulTests)["-s"]["--success"]("include successful tests in output") | + Opt(config.shouldDebugBreak)["-b"]["--break"]("break into debugger on failure") | + Opt(config.noThrow)["-e"]["--nothrow"]("skip exception tests") | + Opt(config.showInvisibles)["-i"]["--invisibles"]("show invisibles (tabs, newlines)") | + Opt(config.outputFilename, "filename")["-o"]["--out"]("output filename") | + Opt(config.reporterName, "name")["-r"]["--reporter"]("reporter to use (defaults to console)") | + Opt(config.name, "name")["-n"]["--name"]("suite name") | + Opt([&](bool) { config.abortAfter = 1; })["-a"]["--abort"]("abort at first failure") | + Opt([&](int x) { config.abortAfter = x; }, "no. failures")["-x"]["--abortx"]("abort after x failures") | + Opt(setWarning, "warning name")["-w"]["--warn"]("enable warnings") | + Opt([&](bool flag) { config.showDurations = flag ? ShowDurations::Always : ShowDurations::Never; }, + "yes|no")["-d"]["--durations"]("show test durations") | + Opt(loadTestNamesFromFile, "filename")["-f"]["--input-file"]("load test names to run from a file") | + Opt(config.filenamesAsTags)["-#"]["--filenames-as-tags"]("adds a tag for the filename") | + Opt(config.sectionsToRun, "section name")["-c"]["--section"]("specify section to run") | + Opt(setVerbosity, "quiet|normal|high")["-v"]["--verbosity"]("set output verbosity") | + Opt(config.listTestNamesOnly)["--list-test-names-only"]("list all/matching test cases names only") | + Opt(config.listReporters)["--list-reporters"]("list all reporters") | + Opt(setTestOrder, "decl|lex|rand")["--order"]("test case order (defaults to decl)") | + Opt(setRngSeed, "'time'|number")["--rng-seed"]("set a specific seed for random numbers") | + Opt(setColourUsage, "yes|no")["--use-colour"]("should output be colourised") | + Opt(config.libIdentify)["--libidentify"]("report name and version according to libidentify standard") | + Opt(setWaitForKeypress, "start|exit|both")["--wait-for-keypress"]("waits for a keypress before exiting") | + Opt(config.benchmarkResolutionMultiple, + "multiplier")["--benchmark-resolution-multiple"]("multiple of clock resolution to run benchmarks") + + | Arg(config.testsOrTags, "test name|pattern|tags")("which test or tests to use"); + + return cli; +} + +} // end namespace Catch +// end catch_commandline.cpp +// start catch_common.cpp + +#include +#include + +namespace Catch { + +bool SourceLineInfo::empty() const noexcept { + return file[0] == '\0'; +} +bool SourceLineInfo::operator==(SourceLineInfo const &other) const noexcept { + return line == other.line && (file == other.file || std::strcmp(file, other.file) == 0); +} +bool SourceLineInfo::operator<(SourceLineInfo const &other) const noexcept { + return line < other.line || (line == other.line && (std::strcmp(file, other.file) < 0)); +} + +std::ostream &operator<<(std::ostream &os, SourceLineInfo const &info) { +#ifndef __GNUG__ + os << info.file << '(' << info.line << ')'; +#else + os << info.file << ':' << info.line; +#endif + return os; +} + +std::string StreamEndStop::operator+() const { + return std::string(); +} + +NonCopyable::NonCopyable() = default; +NonCopyable::~NonCopyable() = default; + +} // namespace Catch +// end catch_common.cpp +// start catch_config.cpp + +// start catch_enforce.h + +#include + +#define CATCH_PREPARE_EXCEPTION(type, msg) type((Catch::ReusableStringStream() << msg).str()) +#define CATCH_INTERNAL_ERROR(msg) \ + throw CATCH_PREPARE_EXCEPTION(std::logic_error, CATCH_INTERNAL_LINEINFO << ": Internal Catch error: " << msg); +#define CATCH_ERROR(msg) throw CATCH_PREPARE_EXCEPTION(std::domain_error, msg) +#define CATCH_ENFORCE(condition, msg) \ + do { \ + if (!(condition)) \ + CATCH_ERROR(msg); \ + } while (false) + +// end catch_enforce.h +namespace Catch { + +Config::Config(ConfigData const &data) : m_data(data), m_stream(openStream()) { + TestSpecParser parser(ITagAliasRegistry::get()); + if (data.testsOrTags.empty()) { + parser.parse("~[.]"); // All not hidden tests + } else { + m_hasTestFilters = true; + for (auto const &testOrTags : data.testsOrTags) + parser.parse(testOrTags); + } + m_testSpec = parser.testSpec(); +} + +std::string const &Config::getFilename() const { + return m_data.outputFilename; +} + +bool Config::listTests() const { + return m_data.listTests; +} +bool Config::listTestNamesOnly() const { + return m_data.listTestNamesOnly; +} +bool Config::listTags() const { + return m_data.listTags; +} +bool Config::listReporters() const { + return m_data.listReporters; +} + +std::string Config::getProcessName() const { + return m_data.processName; +} +std::string const &Config::getReporterName() const { + return m_data.reporterName; +} + +std::vector const &Config::getTestsOrTags() const { + return m_data.testsOrTags; +} +std::vector const &Config::getSectionsToRun() const { + return m_data.sectionsToRun; +} + +TestSpec const &Config::testSpec() const { + return m_testSpec; +} +bool Config::hasTestFilters() const { + return m_hasTestFilters; +} + +bool Config::showHelp() const { + return m_data.showHelp; +} + +// IConfig interface +bool Config::allowThrows() const { + return !m_data.noThrow; +} +std::ostream &Config::stream() const { + return m_stream->stream(); +} +std::string Config::name() const { + return m_data.name.empty() ? m_data.processName : m_data.name; +} +bool Config::includeSuccessfulResults() const { + return m_data.showSuccessfulTests; +} +bool Config::warnAboutMissingAssertions() const { + return !!(m_data.warnings & WarnAbout::NoAssertions); +} +bool Config::warnAboutNoTests() const { + return !!(m_data.warnings & WarnAbout::NoTests); +} +ShowDurations::OrNot Config::showDurations() const { + return m_data.showDurations; +} +RunTests::InWhatOrder Config::runOrder() const { + return m_data.runOrder; +} +unsigned int Config::rngSeed() const { + return m_data.rngSeed; +} +int Config::benchmarkResolutionMultiple() const { + return m_data.benchmarkResolutionMultiple; +} +UseColour::YesOrNo Config::useColour() const { + return m_data.useColour; +} +bool Config::shouldDebugBreak() const { + return m_data.shouldDebugBreak; +} +int Config::abortAfter() const { + return m_data.abortAfter; +} +bool Config::showInvisibles() const { + return m_data.showInvisibles; +} +Verbosity Config::verbosity() const { + return m_data.verbosity; +} + +IStream const *Config::openStream() { + return Catch::makeStream(m_data.outputFilename); +} + +} // end namespace Catch +// end catch_config.cpp +// start catch_console_colour.cpp + +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wexit-time-destructors" +#endif + +// start catch_errno_guard.h + +namespace Catch { + +class ErrnoGuard { +public: + ErrnoGuard(); + ~ErrnoGuard(); + +private: + int m_oldErrno; +}; + +} // namespace Catch + +// end catch_errno_guard.h +#include + +namespace Catch { +namespace { + +struct IColourImpl { + virtual ~IColourImpl() = default; + virtual void use(Colour::Code _colourCode) = 0; +}; + +struct NoColourImpl : IColourImpl { + void use(Colour::Code) { + } + + static IColourImpl *instance() { + static NoColourImpl s_instance; + return &s_instance; + } +}; + +} // namespace +} // namespace Catch + +#if !defined(CATCH_CONFIG_COLOUR_NONE) && !defined(CATCH_CONFIG_COLOUR_WINDOWS) && !defined(CATCH_CONFIG_COLOUR_ANSI) +#ifdef CATCH_PLATFORM_WINDOWS +#define CATCH_CONFIG_COLOUR_WINDOWS +#else +#define CATCH_CONFIG_COLOUR_ANSI +#endif +#endif + +#if defined(CATCH_CONFIG_COLOUR_WINDOWS) ///////////////////////////////////////// + +namespace Catch { +namespace { + +class Win32ColourImpl : public IColourImpl { +public: + Win32ColourImpl() : stdoutHandle(GetStdHandle(STD_OUTPUT_HANDLE)) { + CONSOLE_SCREEN_BUFFER_INFO csbiInfo; + GetConsoleScreenBufferInfo(stdoutHandle, &csbiInfo); + originalForegroundAttributes = + csbiInfo.wAttributes & ~(BACKGROUND_GREEN | BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_INTENSITY); + originalBackgroundAttributes = + csbiInfo.wAttributes & ~(FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE | FOREGROUND_INTENSITY); + } + + virtual void use(Colour::Code _colourCode) override { + switch (_colourCode) { + case Colour::None: + return setTextAttribute(originalForegroundAttributes); + case Colour::White: + return setTextAttribute(FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE); + case Colour::Red: + return setTextAttribute(FOREGROUND_RED); + case Colour::Green: + return setTextAttribute(FOREGROUND_GREEN); + case Colour::Blue: + return setTextAttribute(FOREGROUND_BLUE); + case Colour::Cyan: + return setTextAttribute(FOREGROUND_BLUE | FOREGROUND_GREEN); + case Colour::Yellow: + return setTextAttribute(FOREGROUND_RED | FOREGROUND_GREEN); + case Colour::Grey: + return setTextAttribute(0); + + case Colour::LightGrey: + return setTextAttribute(FOREGROUND_INTENSITY); + case Colour::BrightRed: + return setTextAttribute(FOREGROUND_INTENSITY | FOREGROUND_RED); + case Colour::BrightGreen: + return setTextAttribute(FOREGROUND_INTENSITY | FOREGROUND_GREEN); + case Colour::BrightWhite: + return setTextAttribute(FOREGROUND_INTENSITY | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE); + case Colour::BrightYellow: + return setTextAttribute(FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_GREEN); + + case Colour::Bright: + CATCH_INTERNAL_ERROR("not a colour"); + + default: + CATCH_ERROR("Unknown colour requested"); + } + } + +private: + void setTextAttribute(WORD _textAttribute) { + SetConsoleTextAttribute(stdoutHandle, _textAttribute | originalBackgroundAttributes); + } + HANDLE stdoutHandle; + WORD originalForegroundAttributes; + WORD originalBackgroundAttributes; +}; + +IColourImpl *platformColourInstance() { + static Win32ColourImpl s_instance; + + IConfigPtr config = getCurrentContext().getConfig(); + UseColour::YesOrNo colourMode = config ? config->useColour() : UseColour::Auto; + if (colourMode == UseColour::Auto) + colourMode = UseColour::Yes; + return colourMode == UseColour::Yes ? &s_instance : NoColourImpl::instance(); +} + +} // namespace +} // end namespace Catch + +#elif defined(CATCH_CONFIG_COLOUR_ANSI) ////////////////////////////////////// + +#include + +namespace Catch { +namespace { + +// use POSIX/ ANSI console terminal codes +// Thanks to Adam Strzelecki for original contribution +// (http://github.com/nanoant) +// https://github.com/philsquared/Catch/pull/131 +class PosixColourImpl : public IColourImpl { +public: + virtual void use(Colour::Code _colourCode) override { + switch (_colourCode) { + case Colour::None: + case Colour::White: + return setColour("[0m"); + case Colour::Red: + return setColour("[0;31m"); + case Colour::Green: + return setColour("[0;32m"); + case Colour::Blue: + return setColour("[0;34m"); + case Colour::Cyan: + return setColour("[0;36m"); + case Colour::Yellow: + return setColour("[0;33m"); + case Colour::Grey: + return setColour("[1;30m"); + + case Colour::LightGrey: + return setColour("[0;37m"); + case Colour::BrightRed: + return setColour("[1;31m"); + case Colour::BrightGreen: + return setColour("[1;32m"); + case Colour::BrightWhite: + return setColour("[1;37m"); + case Colour::BrightYellow: + return setColour("[1;33m"); + + case Colour::Bright: + CATCH_INTERNAL_ERROR("not a colour"); + default: + CATCH_INTERNAL_ERROR("Unknown colour requested"); + } + } + static IColourImpl *instance() { + static PosixColourImpl s_instance; + return &s_instance; + } + +private: + void setColour(const char *_escapeCode) { + Catch::cout() << '\033' << _escapeCode; + } +}; + +bool useColourOnPlatform() { + return +#ifdef CATCH_PLATFORM_MAC + !isDebuggerActive() && +#endif +#if !(defined(__DJGPP__) && defined(__STRICT_ANSI__)) + isatty(STDOUT_FILENO) +#else + false +#endif + ; +} +IColourImpl *platformColourInstance() { + ErrnoGuard guard; + IConfigPtr config = getCurrentContext().getConfig(); + UseColour::YesOrNo colourMode = config ? config->useColour() : UseColour::Auto; + if (colourMode == UseColour::Auto) + colourMode = useColourOnPlatform() ? UseColour::Yes : UseColour::No; + return colourMode == UseColour::Yes ? PosixColourImpl::instance() : NoColourImpl::instance(); +} + +} // namespace +} // end namespace Catch + +#else // not Windows or ANSI /////////////////////////////////////////////// + +namespace Catch { + +static IColourImpl *platformColourInstance() { + return NoColourImpl::instance(); +} + +} // end namespace Catch + +#endif // Windows/ ANSI/ None + +namespace Catch { + +Colour::Colour(Code _colourCode) { + use(_colourCode); +} +Colour::Colour(Colour &&rhs) noexcept { + m_moved = rhs.m_moved; + rhs.m_moved = true; +} +Colour &Colour::operator=(Colour &&rhs) noexcept { + m_moved = rhs.m_moved; + rhs.m_moved = true; + return *this; +} + +Colour::~Colour() { + if (!m_moved) + use(None); +} + +void Colour::use(Code _colourCode) { + static IColourImpl *impl = platformColourInstance(); + impl->use(_colourCode); +} + +std::ostream &operator<<(std::ostream &os, Colour const &) { + return os; +} + +} // end namespace Catch + +#if defined(__clang__) +#pragma clang diagnostic pop +#endif + +// end catch_console_colour.cpp +// start catch_context.cpp + +namespace Catch { + +class Context : public IMutableContext, NonCopyable { + +public: // IContext + virtual IResultCapture *getResultCapture() override { + return m_resultCapture; + } + virtual IRunner *getRunner() override { + return m_runner; + } + + virtual IConfigPtr const &getConfig() const override { + return m_config; + } + + virtual ~Context() override; + +public: // IMutableContext + virtual void setResultCapture(IResultCapture *resultCapture) override { + m_resultCapture = resultCapture; + } + virtual void setRunner(IRunner *runner) override { + m_runner = runner; + } + virtual void setConfig(IConfigPtr const &config) override { + m_config = config; + } + + friend IMutableContext &getCurrentMutableContext(); + +private: + IConfigPtr m_config; + IRunner *m_runner = nullptr; + IResultCapture *m_resultCapture = nullptr; +}; + +IMutableContext *IMutableContext::currentContext = nullptr; + +void IMutableContext::createContext() { + currentContext = new Context(); +} + +void cleanUpContext() { + delete IMutableContext::currentContext; + IMutableContext::currentContext = nullptr; +} +IContext::~IContext() = default; +IMutableContext::~IMutableContext() = default; +Context::~Context() = default; +} // namespace Catch +// end catch_context.cpp +// start catch_debug_console.cpp + +// start catch_debug_console.h + +#include + +namespace Catch { +void writeToDebugConsole(std::string const &text); +} + +// end catch_debug_console.h +#ifdef CATCH_PLATFORM_WINDOWS + +namespace Catch { +void writeToDebugConsole(std::string const &text) { + ::OutputDebugStringA(text.c_str()); +} +} // namespace Catch + +#else + +namespace Catch { +void writeToDebugConsole(std::string const &text) { + // !TBD: Need a version for Mac/ XCode and other IDEs + Catch::cout() << text; +} +} // namespace Catch + +#endif // Platform +// end catch_debug_console.cpp +// start catch_debugger.cpp + +#ifdef CATCH_PLATFORM_MAC + +#include +#include +#include +#include +#include +#include +#include + +namespace Catch { + +// The following function is taken directly from the following technical note: +// http://developer.apple.com/library/mac/#qa/qa2004/qa1361.html + +// Returns true if the current process is being debugged (either +// running under the debugger or has a debugger attached post facto). +bool isDebuggerActive() { + + int mib[4]; + struct kinfo_proc info; + std::size_t size; + + // Initialize the flags so that, if sysctl fails for some bizarre + // reason, we get a predictable result. + + info.kp_proc.p_flag = 0; + + // Initialize mib, which tells sysctl the info we want, in this case + // we're looking for information about a specific process ID. + + mib[0] = CTL_KERN; + mib[1] = KERN_PROC; + mib[2] = KERN_PROC_PID; + mib[3] = getpid(); + + // Call sysctl. + + size = sizeof(info); + if (sysctl(mib, sizeof(mib) / sizeof(*mib), &info, &size, nullptr, 0) != 0) { + Catch::cerr() << "\n** Call to sysctl failed - unable to determine if debugger is active **\n" << std::endl; + return false; + } + + // We're being debugged if the P_TRACED flag is set. + + return ((info.kp_proc.p_flag & P_TRACED) != 0); +} +} // namespace Catch + +#elif defined(CATCH_PLATFORM_LINUX) +#include +#include + +namespace Catch { +// The standard POSIX way of detecting a debugger is to attempt to +// ptrace() the process, but this needs to be done from a child and not +// this process itself to still allow attaching to this process later +// if wanted, so is rather heavy. Under Linux we have the PID of the +// "debugger" (which doesn't need to be gdb, of course, it could also +// be strace, for example) in /proc/$PID/status, so just get it from +// there instead. +bool isDebuggerActive() { + // Libstdc++ has a bug, where std::ifstream sets errno to 0 + // This way our users can properly assert over errno values + ErrnoGuard guard; + std::ifstream in("/proc/self/status"); + for (std::string line; std::getline(in, line);) { + static const int PREFIX_LEN = 11; + if (line.compare(0, PREFIX_LEN, "TracerPid:\t") == 0) { + // We're traced if the PID is not 0 and no other PID starts + // with 0 digit, so it's enough to check for just a single + // character. + return line.length() > PREFIX_LEN && line[PREFIX_LEN] != '0'; + } + } + + return false; +} +} // namespace Catch +#elif defined(_MSC_VER) +extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); +namespace Catch { +bool isDebuggerActive() { + return IsDebuggerPresent() != 0; +} +} // namespace Catch +#elif defined(__MINGW32__) +extern "C" __declspec(dllimport) int __stdcall IsDebuggerPresent(); +namespace Catch { +bool isDebuggerActive() { + return IsDebuggerPresent() != 0; +} +} // namespace Catch +#else +namespace Catch { +bool isDebuggerActive() { + return false; +} +} // namespace Catch +#endif // Platform +// end catch_debugger.cpp +// start catch_decomposer.cpp + +namespace Catch { + +ITransientExpression::~ITransientExpression() = default; + +void formatReconstructedExpression(std::ostream &os, std::string const &lhs, StringRef op, std::string const &rhs) { + if (lhs.size() + rhs.size() < 40 && lhs.find('\n') == std::string::npos && rhs.find('\n') == std::string::npos) + os << lhs << " " << op << " " << rhs; + else + os << lhs << "\n" << op << "\n" << rhs; +} +} // namespace Catch +// end catch_decomposer.cpp +// start catch_errno_guard.cpp + +#include + +namespace Catch { +ErrnoGuard::ErrnoGuard() : m_oldErrno(errno) { +} +ErrnoGuard::~ErrnoGuard() { + errno = m_oldErrno; +} +} // namespace Catch +// end catch_errno_guard.cpp +// start catch_exception_translator_registry.cpp + +// start catch_exception_translator_registry.h + +#include +#include +#include + +namespace Catch { + +class ExceptionTranslatorRegistry : public IExceptionTranslatorRegistry { +public: + ~ExceptionTranslatorRegistry(); + virtual void registerTranslator(const IExceptionTranslator *translator); + virtual std::string translateActiveException() const override; + std::string tryTranslators() const; + +private: + std::vector> m_translators; +}; +} // namespace Catch + +// end catch_exception_translator_registry.h +#ifdef __OBJC__ +#import "Foundation/Foundation.h" +#endif + +namespace Catch { + +ExceptionTranslatorRegistry::~ExceptionTranslatorRegistry() { +} + +void ExceptionTranslatorRegistry::registerTranslator(const IExceptionTranslator *translator) { + m_translators.push_back(std::unique_ptr(translator)); +} + +std::string ExceptionTranslatorRegistry::translateActiveException() const { + try { +#ifdef __OBJC__ + // In Objective-C try objective-c exceptions first + @try { + return tryTranslators(); + } @catch (NSException *exception) { + return Catch::Detail::stringify([exception description]); + } +#else + // Compiling a mixed mode project with MSVC means that CLR + // exceptions will be caught in (...) as well. However, these + // do not fill-in std::current_exception and thus lead to crash + // when attempting rethrow. + // /EHa switch also causes structured exceptions to be caught + // here, but they fill-in current_exception properly, so + // at worst the output should be a little weird, instead of + // causing a crash. + if (std::current_exception() == nullptr) { + return "Non C++ exception. Possibly a CLR exception."; + } + return tryTranslators(); +#endif + } catch (TestFailureException &) { + std::rethrow_exception(std::current_exception()); + } catch (std::exception &ex) { + return ex.what(); + } catch (std::string &msg) { + return msg; + } catch (const char *msg) { + return msg; + } catch (...) { + return "Unknown exception"; + } +} + +std::string ExceptionTranslatorRegistry::tryTranslators() const { + if (m_translators.empty()) + std::rethrow_exception(std::current_exception()); + else + return m_translators[0]->translate(m_translators.begin() + 1, m_translators.end()); +} +} // namespace Catch +// end catch_exception_translator_registry.cpp +// start catch_fatal_condition.cpp + +#if defined(__GNUC__) +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wmissing-field-initializers" +#endif + +#if defined(CATCH_CONFIG_WINDOWS_SEH) || defined(CATCH_CONFIG_POSIX_SIGNALS) + +namespace { +// Report the error condition +void reportFatal(char const *const message) { + Catch::getCurrentContext().getResultCapture()->handleFatalErrorCondition(message); +} +} // namespace + +#endif // signals/SEH handling + +#if defined(CATCH_CONFIG_WINDOWS_SEH) + +namespace Catch { +struct SignalDefs { + DWORD id; + const char *name; +}; + +// There is no 1-1 mapping between signals and windows exceptions. +// Windows can easily distinguish between SO and SigSegV, +// but SigInt, SigTerm, etc are handled differently. +static SignalDefs signalDefs[] = { + {EXCEPTION_ILLEGAL_INSTRUCTION, "SIGILL - Illegal instruction signal"}, + {EXCEPTION_STACK_OVERFLOW, "SIGSEGV - Stack overflow"}, + {EXCEPTION_ACCESS_VIOLATION, "SIGSEGV - Segmentation violation signal"}, + {EXCEPTION_INT_DIVIDE_BY_ZERO, "Divide by zero error"}, +}; + +LONG CALLBACK FatalConditionHandler::handleVectoredException(PEXCEPTION_POINTERS ExceptionInfo) { + for (auto const &def : signalDefs) { + if (ExceptionInfo->ExceptionRecord->ExceptionCode == def.id) { + reportFatal(def.name); + } + } + // If its not an exception we care about, pass it along. + // This stops us from eating debugger breaks etc. + return EXCEPTION_CONTINUE_SEARCH; +} + +FatalConditionHandler::FatalConditionHandler() { + isSet = true; + // 32k seems enough for Catch to handle stack overflow, + // but the value was found experimentally, so there is no strong guarantee + guaranteeSize = 32 * 1024; + exceptionHandlerHandle = nullptr; + // Register as first handler in current chain + exceptionHandlerHandle = AddVectoredExceptionHandler(1, handleVectoredException); + // Pass in guarantee size to be filled + SetThreadStackGuarantee(&guaranteeSize); +} + +void FatalConditionHandler::reset() { + if (isSet) { + RemoveVectoredExceptionHandler(exceptionHandlerHandle); + SetThreadStackGuarantee(&guaranteeSize); + exceptionHandlerHandle = nullptr; + isSet = false; + } +} + +FatalConditionHandler::~FatalConditionHandler() { + reset(); +} + +bool FatalConditionHandler::isSet = false; +ULONG FatalConditionHandler::guaranteeSize = 0; +PVOID FatalConditionHandler::exceptionHandlerHandle = nullptr; + +} // namespace Catch + +#elif defined(CATCH_CONFIG_POSIX_SIGNALS) + +namespace Catch { + +struct SignalDefs { + int id; + const char *name; +}; + +// 32kb for the alternate stack seems to be sufficient. However, this value +// is experimentally determined, so that's not guaranteed. +constexpr static std::size_t sigStackSize = 32768 >= MINSIGSTKSZ ? 32768 : MINSIGSTKSZ; + +static SignalDefs signalDefs[] = { + {SIGINT, "SIGINT - Terminal interrupt signal"}, {SIGILL, "SIGILL - Illegal instruction signal"}, + {SIGFPE, "SIGFPE - Floating point error signal"}, {SIGSEGV, "SIGSEGV - Segmentation violation signal"}, + {SIGTERM, "SIGTERM - Termination request signal"}, {SIGABRT, "SIGABRT - Abort (abnormal termination) signal"}}; + +void FatalConditionHandler::handleSignal(int sig) { + char const *name = ""; + for (auto const &def : signalDefs) { + if (sig == def.id) { + name = def.name; + break; + } + } + reset(); + reportFatal(name); + raise(sig); +} + +FatalConditionHandler::FatalConditionHandler() { + isSet = true; + stack_t sigStack; + sigStack.ss_sp = altStackMem; + sigStack.ss_size = sigStackSize; + sigStack.ss_flags = 0; + sigaltstack(&sigStack, &oldSigStack); + struct sigaction sa = {}; + + sa.sa_handler = handleSignal; + sa.sa_flags = SA_ONSTACK; + for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) { + sigaction(signalDefs[i].id, &sa, &oldSigActions[i]); + } +} + +FatalConditionHandler::~FatalConditionHandler() { + reset(); +} + +void FatalConditionHandler::reset() { + if (isSet) { + // Set signals back to previous values -- hopefully nobody overwrote them in the meantime + for (std::size_t i = 0; i < sizeof(signalDefs) / sizeof(SignalDefs); ++i) { + sigaction(signalDefs[i].id, &oldSigActions[i], nullptr); + } + // Return the old stack + sigaltstack(&oldSigStack, nullptr); + isSet = false; + } +} + +bool FatalConditionHandler::isSet = false; +struct sigaction FatalConditionHandler::oldSigActions[sizeof(signalDefs) / sizeof(SignalDefs)] = {}; +stack_t FatalConditionHandler::oldSigStack = {}; +char FatalConditionHandler::altStackMem[sigStackSize] = {}; + +} // namespace Catch + +#else + +namespace Catch { +void FatalConditionHandler::reset() { +} +} // namespace Catch + +#endif // signals/SEH handling + +#if defined(__GNUC__) +#pragma GCC diagnostic pop +#endif +// end catch_fatal_condition.cpp +// start catch_interfaces_capture.cpp + +namespace Catch { +IResultCapture::~IResultCapture() = default; +} +// end catch_interfaces_capture.cpp +// start catch_interfaces_config.cpp + +namespace Catch { +IConfig::~IConfig() = default; +} +// end catch_interfaces_config.cpp +// start catch_interfaces_exception.cpp + +namespace Catch { +IExceptionTranslator::~IExceptionTranslator() = default; +IExceptionTranslatorRegistry::~IExceptionTranslatorRegistry() = default; +} // namespace Catch +// end catch_interfaces_exception.cpp +// start catch_interfaces_registry_hub.cpp + +namespace Catch { +IRegistryHub::~IRegistryHub() = default; +IMutableRegistryHub::~IMutableRegistryHub() = default; +} // namespace Catch +// end catch_interfaces_registry_hub.cpp +// start catch_interfaces_reporter.cpp + +// start catch_reporter_listening.h + +namespace Catch { + +class ListeningReporter : public IStreamingReporter { + using Reporters = std::vector; + Reporters m_listeners; + IStreamingReporterPtr m_reporter = nullptr; + +public: + void addListener(IStreamingReporterPtr &&listener); + void addReporter(IStreamingReporterPtr &&reporter); + +public: // IStreamingReporter + ReporterPreferences getPreferences() const override; + + void noMatchingTestCases(std::string const &spec) override; + + static std::set getSupportedVerbosities(); + + void benchmarkStarting(BenchmarkInfo const &benchmarkInfo) override; + void benchmarkEnded(BenchmarkStats const &benchmarkStats) override; + + void testRunStarting(TestRunInfo const &testRunInfo) override; + void testGroupStarting(GroupInfo const &groupInfo) override; + void testCaseStarting(TestCaseInfo const &testInfo) override; + void sectionStarting(SectionInfo const §ionInfo) override; + void assertionStarting(AssertionInfo const &assertionInfo) override; + + // The return value indicates if the messages buffer should be cleared: + bool assertionEnded(AssertionStats const &assertionStats) override; + void sectionEnded(SectionStats const §ionStats) override; + void testCaseEnded(TestCaseStats const &testCaseStats) override; + void testGroupEnded(TestGroupStats const &testGroupStats) override; + void testRunEnded(TestRunStats const &testRunStats) override; + + void skipTest(TestCaseInfo const &testInfo) override; + bool isMulti() const override; +}; + +} // end namespace Catch + +// end catch_reporter_listening.h +namespace Catch { + +ReporterConfig::ReporterConfig(IConfigPtr const &_fullConfig) + : m_stream(&_fullConfig->stream()), m_fullConfig(_fullConfig) { +} + +ReporterConfig::ReporterConfig(IConfigPtr const &_fullConfig, std::ostream &_stream) + : m_stream(&_stream), m_fullConfig(_fullConfig) { +} + +std::ostream &ReporterConfig::stream() const { + return *m_stream; +} +IConfigPtr ReporterConfig::fullConfig() const { + return m_fullConfig; +} + +TestRunInfo::TestRunInfo(std::string const &_name) : name(_name) { +} + +GroupInfo::GroupInfo(std::string const &_name, std::size_t _groupIndex, std::size_t _groupsCount) + : name(_name), groupIndex(_groupIndex), groupsCounts(_groupsCount) { +} + +AssertionStats::AssertionStats(AssertionResult const &_assertionResult, std::vector const &_infoMessages, + Totals const &_totals) + : assertionResult(_assertionResult), infoMessages(_infoMessages), totals(_totals) { + assertionResult.m_resultData.lazyExpression.m_transientExpression = + _assertionResult.m_resultData.lazyExpression.m_transientExpression; + + if (assertionResult.hasMessage()) { + // Copy message into messages list. + // !TBD This should have been done earlier, somewhere + MessageBuilder builder(assertionResult.getTestMacroName(), assertionResult.getSourceInfo(), + assertionResult.getResultType()); + builder << assertionResult.getMessage(); + builder.m_info.message = builder.m_stream.str(); + + infoMessages.push_back(builder.m_info); + } +} + +AssertionStats::~AssertionStats() = default; + +SectionStats::SectionStats(SectionInfo const &_sectionInfo, Counts const &_assertions, double _durationInSeconds, + bool _missingAssertions) + : sectionInfo(_sectionInfo), assertions(_assertions), durationInSeconds(_durationInSeconds), + missingAssertions(_missingAssertions) { +} + +SectionStats::~SectionStats() = default; + +TestCaseStats::TestCaseStats(TestCaseInfo const &_testInfo, Totals const &_totals, std::string const &_stdOut, + std::string const &_stdErr, bool _aborting) + : testInfo(_testInfo), totals(_totals), stdOut(_stdOut), stdErr(_stdErr), aborting(_aborting) { +} + +TestCaseStats::~TestCaseStats() = default; + +TestGroupStats::TestGroupStats(GroupInfo const &_groupInfo, Totals const &_totals, bool _aborting) + : groupInfo(_groupInfo), totals(_totals), aborting(_aborting) { +} + +TestGroupStats::TestGroupStats(GroupInfo const &_groupInfo) : groupInfo(_groupInfo), aborting(false) { +} + +TestGroupStats::~TestGroupStats() = default; + +TestRunStats::TestRunStats(TestRunInfo const &_runInfo, Totals const &_totals, bool _aborting) + : runInfo(_runInfo), totals(_totals), aborting(_aborting) { +} + +TestRunStats::~TestRunStats() = default; + +void IStreamingReporter::fatalErrorEncountered(StringRef) { +} +bool IStreamingReporter::isMulti() const { + return false; +} + +IReporterFactory::~IReporterFactory() = default; +IReporterRegistry::~IReporterRegistry() = default; + +} // end namespace Catch +// end catch_interfaces_reporter.cpp +// start catch_interfaces_runner.cpp + +namespace Catch { +IRunner::~IRunner() = default; +} +// end catch_interfaces_runner.cpp +// start catch_interfaces_testcase.cpp + +namespace Catch { +ITestInvoker::~ITestInvoker() = default; +ITestCaseRegistry::~ITestCaseRegistry() = default; +} // namespace Catch +// end catch_interfaces_testcase.cpp +// start catch_leak_detector.cpp + +#ifdef CATCH_CONFIG_WINDOWS_CRTDBG +#include + +namespace Catch { + +LeakDetector::LeakDetector() { + int flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); + flag |= _CRTDBG_LEAK_CHECK_DF; + flag |= _CRTDBG_ALLOC_MEM_DF; + _CrtSetDbgFlag(flag); + _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE | _CRTDBG_MODE_DEBUG); + _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); + // Change this to leaking allocation's number to break there + _CrtSetBreakAlloc(-1); +} +} // namespace Catch + +#else + +Catch::LeakDetector::LeakDetector() { +} + +#endif +// end catch_leak_detector.cpp +// start catch_list.cpp + +// start catch_list.h + +#include + +namespace Catch { + +std::size_t listTests(Config const &config); + +std::size_t listTestsNamesOnly(Config const &config); + +struct TagInfo { + void add(std::string const &spelling); + std::string all() const; + + std::set spellings; + std::size_t count = 0; +}; + +std::size_t listTags(Config const &config); + +std::size_t listReporters(Config const & /*config*/); + +Option list(Config const &config); + +} // end namespace Catch + +// end catch_list.h +// start catch_text.h + +namespace Catch { +using namespace clara::TextFlow; +} + +// end catch_text.h +#include +#include +#include + +namespace Catch { + +std::size_t listTests(Config const &config) { + TestSpec testSpec = config.testSpec(); + if (config.hasTestFilters()) + Catch::cout() << "Matching test cases:\n"; + else { + Catch::cout() << "All available test cases:\n"; + } + + auto matchedTestCases = filterTests(getAllTestCasesSorted(config), testSpec, config); + for (auto const &testCaseInfo : matchedTestCases) { + Colour::Code colour = testCaseInfo.isHidden() ? Colour::SecondaryText : Colour::None; + Colour colourGuard(colour); + + Catch::cout() << Column(testCaseInfo.name).initialIndent(2).indent(4) << "\n"; + if (config.verbosity() >= Verbosity::High) { + Catch::cout() << Column(Catch::Detail::stringify(testCaseInfo.lineInfo)).indent(4) << std::endl; + std::string description = testCaseInfo.description; + if (description.empty()) + description = "(NO DESCRIPTION)"; + Catch::cout() << Column(description).indent(4) << std::endl; + } + if (!testCaseInfo.tags.empty()) + Catch::cout() << Column(testCaseInfo.tagsAsString()).indent(6) << "\n"; + } + + if (!config.hasTestFilters()) + Catch::cout() << pluralise(matchedTestCases.size(), "test case") << '\n' << std::endl; + else + Catch::cout() << pluralise(matchedTestCases.size(), "matching test case") << '\n' << std::endl; + return matchedTestCases.size(); +} + +std::size_t listTestsNamesOnly(Config const &config) { + TestSpec testSpec = config.testSpec(); + std::size_t matchedTests = 0; + std::vector matchedTestCases = filterTests(getAllTestCasesSorted(config), testSpec, config); + for (auto const &testCaseInfo : matchedTestCases) { + matchedTests++; + if (startsWith(testCaseInfo.name, '#')) + Catch::cout() << '"' << testCaseInfo.name << '"'; + else + Catch::cout() << testCaseInfo.name; + if (config.verbosity() >= Verbosity::High) + Catch::cout() << "\t@" << testCaseInfo.lineInfo; + Catch::cout() << std::endl; + } + return matchedTests; +} + +void TagInfo::add(std::string const &spelling) { + ++count; + spellings.insert(spelling); +} + +std::string TagInfo::all() const { + std::string out; + for (auto const &spelling : spellings) + out += "[" + spelling + "]"; + return out; +} + +std::size_t listTags(Config const &config) { + TestSpec testSpec = config.testSpec(); + if (config.hasTestFilters()) + Catch::cout() << "Tags for matching test cases:\n"; + else { + Catch::cout() << "All available tags:\n"; + } + + std::map tagCounts; + + std::vector matchedTestCases = filterTests(getAllTestCasesSorted(config), testSpec, config); + for (auto const &testCase : matchedTestCases) { + for (auto const &tagName : testCase.getTestCaseInfo().tags) { + std::string lcaseTagName = toLower(tagName); + auto countIt = tagCounts.find(lcaseTagName); + if (countIt == tagCounts.end()) + countIt = tagCounts.insert(std::make_pair(lcaseTagName, TagInfo())).first; + countIt->second.add(tagName); + } + } + + for (auto const &tagCount : tagCounts) { + ReusableStringStream rss; + rss << " " << std::setw(2) << tagCount.second.count << " "; + auto str = rss.str(); + auto wrapper = + Column(tagCount.second.all()).initialIndent(0).indent(str.size()).width(CATCH_CONFIG_CONSOLE_WIDTH - 10); + Catch::cout() << str << wrapper << '\n'; + } + Catch::cout() << pluralise(tagCounts.size(), "tag") << '\n' << std::endl; + return tagCounts.size(); +} + +std::size_t listReporters(Config const & /*config*/) { + Catch::cout() << "Available reporters:\n"; + IReporterRegistry::FactoryMap const &factories = getRegistryHub().getReporterRegistry().getFactories(); + std::size_t maxNameLen = 0; + for (auto const &factoryKvp : factories) + maxNameLen = (std::max)(maxNameLen, factoryKvp.first.size()); + + for (auto const &factoryKvp : factories) { + Catch::cout() << Column(factoryKvp.first + ":").indent(2).width(5 + maxNameLen) + + Column(factoryKvp.second->getDescription()) + .initialIndent(0) + .indent(2) + .width(CATCH_CONFIG_CONSOLE_WIDTH - maxNameLen - 8) + << "\n"; + } + Catch::cout() << std::endl; + return factories.size(); +} + +Option list(Config const &config) { + Option listedCount; + if (config.listTests()) + listedCount = listedCount.valueOr(0) + listTests(config); + if (config.listTestNamesOnly()) + listedCount = listedCount.valueOr(0) + listTestsNamesOnly(config); + if (config.listTags()) + listedCount = listedCount.valueOr(0) + listTags(config); + if (config.listReporters()) + listedCount = listedCount.valueOr(0) + listReporters(config); + return listedCount; +} + +} // end namespace Catch +// end catch_list.cpp +// start catch_matchers.cpp + +namespace Catch { +namespace Matchers { +namespace Impl { + +std::string MatcherUntypedBase::toString() const { + if (m_cachedToString.empty()) + m_cachedToString = describe(); + return m_cachedToString; +} + +MatcherUntypedBase::~MatcherUntypedBase() = default; + +} // namespace Impl +} // namespace Matchers + +using namespace Matchers; +using Matchers::Impl::MatcherBase; + +} // namespace Catch +// end catch_matchers.cpp +// start catch_matchers_floating.cpp + +// start catch_to_string.hpp + +#include + +namespace Catch { +template std::string to_string(T const &t) { +#if defined(CATCH_CONFIG_CPP11_TO_STRING) + return std::to_string(t); +#else + ReusableStringStream rss; + rss << t; + return rss.str(); +#endif +} +} // end namespace Catch + +// end catch_to_string.hpp +#include +#include +#include +#include + +namespace Catch { +namespace Matchers { +namespace Floating { +enum class FloatingPointKind : uint8_t { Float, Double }; +} +} // namespace Matchers +} // namespace Catch + +namespace { + +template struct Converter; + +template <> struct Converter { + static_assert(sizeof(float) == sizeof(int32_t), "Important ULP matcher assumption violated"); + Converter(float f) { + std::memcpy(&i, &f, sizeof(f)); + } + int32_t i; +}; + +template <> struct Converter { + static_assert(sizeof(double) == sizeof(int64_t), "Important ULP matcher assumption violated"); + Converter(double d) { + std::memcpy(&i, &d, sizeof(d)); + } + int64_t i; +}; + +template auto convert(T t) -> Converter { + return Converter(t); +} + +template bool almostEqualUlps(FP lhs, FP rhs, int maxUlpDiff) { + // Comparison with NaN should always be false. + // This way we can rule it out before getting into the ugly details + if (std::isnan(lhs) || std::isnan(rhs)) { + return false; + } + + auto lc = convert(lhs); + auto rc = convert(rhs); + + if ((lc.i < 0) != (rc.i < 0)) { + // Potentially we can have +0 and -0 + return lhs == rhs; + } + + auto ulpDiff = std::abs(lc.i - rc.i); + return ulpDiff <= maxUlpDiff; +} + +} // namespace + +namespace Catch { +namespace Matchers { +namespace Floating { +WithinAbsMatcher::WithinAbsMatcher(double target, double margin) : m_target{target}, m_margin{margin} { + if (m_margin < 0) { + throw std::domain_error("Allowed margin difference has to be >= 0"); + } +} + +// Performs equivalent check of std::fabs(lhs - rhs) <= margin +// But without the subtraction to allow for INFINITY in comparison +bool WithinAbsMatcher::match(double const &matchee) const { + return (matchee + m_margin >= m_target) && (m_target + m_margin >= matchee); +} + +std::string WithinAbsMatcher::describe() const { + return "is within " + ::Catch::Detail::stringify(m_margin) + " of " + ::Catch::Detail::stringify(m_target); +} + +WithinUlpsMatcher::WithinUlpsMatcher(double target, int ulps, FloatingPointKind baseType) + : m_target{target}, m_ulps{ulps}, m_type{baseType} { + if (m_ulps < 0) { + throw std::domain_error("Allowed ulp difference has to be >= 0"); + } +} + +bool WithinUlpsMatcher::match(double const &matchee) const { + switch (m_type) { + case FloatingPointKind::Float: + return almostEqualUlps(static_cast(matchee), static_cast(m_target), m_ulps); + case FloatingPointKind::Double: + return almostEqualUlps(matchee, m_target, m_ulps); + default: + throw std::domain_error("Unknown FloatingPointKind value"); + } +} + +std::string WithinUlpsMatcher::describe() const { + return "is within " + Catch::to_string(m_ulps) + " ULPs of " + ::Catch::Detail::stringify(m_target) + + ((m_type == FloatingPointKind::Float) ? "f" : ""); +} + +} // namespace Floating + +Floating::WithinUlpsMatcher WithinULP(double target, int maxUlpDiff) { + return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Double); +} + +Floating::WithinUlpsMatcher WithinULP(float target, int maxUlpDiff) { + return Floating::WithinUlpsMatcher(target, maxUlpDiff, Floating::FloatingPointKind::Float); +} + +Floating::WithinAbsMatcher WithinAbs(double target, double margin) { + return Floating::WithinAbsMatcher(target, margin); +} + +} // namespace Matchers +} // namespace Catch + +// end catch_matchers_floating.cpp +// start catch_matchers_generic.cpp + +std::string Catch::Matchers::Generic::Detail::finalizeDescription(const std::string &desc) { + if (desc.empty()) { + return "matches undescribed predicate"; + } else { + return "matches predicate: \"" + desc + '"'; + } +} +// end catch_matchers_generic.cpp +// start catch_matchers_string.cpp + +#include + +namespace Catch { +namespace Matchers { + +namespace StdString { + +CasedString::CasedString(std::string const &str, CaseSensitive::Choice caseSensitivity) + : m_caseSensitivity(caseSensitivity), m_str(adjustString(str)) { +} +std::string CasedString::adjustString(std::string const &str) const { + return m_caseSensitivity == CaseSensitive::No ? toLower(str) : str; +} +std::string CasedString::caseSensitivitySuffix() const { + return m_caseSensitivity == CaseSensitive::No ? " (case insensitive)" : std::string(); +} + +StringMatcherBase::StringMatcherBase(std::string const &operation, CasedString const &comparator) + : m_comparator(comparator), m_operation(operation) { +} + +std::string StringMatcherBase::describe() const { + std::string description; + description.reserve(5 + m_operation.size() + m_comparator.m_str.size() + m_comparator.caseSensitivitySuffix().size()); + description += m_operation; + description += ": \""; + description += m_comparator.m_str; + description += "\""; + description += m_comparator.caseSensitivitySuffix(); + return description; +} + +EqualsMatcher::EqualsMatcher(CasedString const &comparator) : StringMatcherBase("equals", comparator) { +} + +bool EqualsMatcher::match(std::string const &source) const { + return m_comparator.adjustString(source) == m_comparator.m_str; +} + +ContainsMatcher::ContainsMatcher(CasedString const &comparator) : StringMatcherBase("contains", comparator) { +} + +bool ContainsMatcher::match(std::string const &source) const { + return contains(m_comparator.adjustString(source), m_comparator.m_str); +} + +StartsWithMatcher::StartsWithMatcher(CasedString const &comparator) : StringMatcherBase("starts with", comparator) { +} + +bool StartsWithMatcher::match(std::string const &source) const { + return startsWith(m_comparator.adjustString(source), m_comparator.m_str); +} + +EndsWithMatcher::EndsWithMatcher(CasedString const &comparator) : StringMatcherBase("ends with", comparator) { +} + +bool EndsWithMatcher::match(std::string const &source) const { + return endsWith(m_comparator.adjustString(source), m_comparator.m_str); +} + +RegexMatcher::RegexMatcher(std::string regex, CaseSensitive::Choice caseSensitivity) + : m_regex(std::move(regex)), m_caseSensitivity(caseSensitivity) { +} + +bool RegexMatcher::match(std::string const &matchee) const { + auto flags = std::regex::ECMAScript; // ECMAScript is the default syntax option anyway + if (m_caseSensitivity == CaseSensitive::Choice::No) { + flags |= std::regex::icase; + } + auto reg = std::regex(m_regex, flags); + return std::regex_match(matchee, reg); +} + +std::string RegexMatcher::describe() const { + return "matches " + ::Catch::Detail::stringify(m_regex) + + ((m_caseSensitivity == CaseSensitive::Choice::Yes) ? " case sensitively" : " case insensitively"); +} + +} // namespace StdString + +StdString::EqualsMatcher Equals(std::string const &str, CaseSensitive::Choice caseSensitivity) { + return StdString::EqualsMatcher(StdString::CasedString(str, caseSensitivity)); +} +StdString::ContainsMatcher Contains(std::string const &str, CaseSensitive::Choice caseSensitivity) { + return StdString::ContainsMatcher(StdString::CasedString(str, caseSensitivity)); +} +StdString::EndsWithMatcher EndsWith(std::string const &str, CaseSensitive::Choice caseSensitivity) { + return StdString::EndsWithMatcher(StdString::CasedString(str, caseSensitivity)); +} +StdString::StartsWithMatcher StartsWith(std::string const &str, CaseSensitive::Choice caseSensitivity) { + return StdString::StartsWithMatcher(StdString::CasedString(str, caseSensitivity)); +} + +StdString::RegexMatcher Matches(std::string const ®ex, CaseSensitive::Choice caseSensitivity) { + return StdString::RegexMatcher(regex, caseSensitivity); +} + +} // namespace Matchers +} // namespace Catch +// end catch_matchers_string.cpp +// start catch_message.cpp + +// start catch_uncaught_exceptions.h + +namespace Catch { +bool uncaught_exceptions(); +} // end namespace Catch + +// end catch_uncaught_exceptions.h +namespace Catch { + +MessageInfo::MessageInfo(std::string const &_macroName, SourceLineInfo const &_lineInfo, ResultWas::OfType _type) + : macroName(_macroName), lineInfo(_lineInfo), type(_type), sequence(++globalCount) { +} + +bool MessageInfo::operator==(MessageInfo const &other) const { + return sequence == other.sequence; +} + +bool MessageInfo::operator<(MessageInfo const &other) const { + return sequence < other.sequence; +} + +// This may need protecting if threading support is added +unsigned int MessageInfo::globalCount = 0; + +//////////////////////////////////////////////////////////////////////////// + +Catch::MessageBuilder::MessageBuilder(std::string const ¯oName, SourceLineInfo const &lineInfo, + ResultWas::OfType type) + : m_info(macroName, lineInfo, type) { +} + +//////////////////////////////////////////////////////////////////////////// + +ScopedMessage::ScopedMessage(MessageBuilder const &builder) : m_info(builder.m_info) { + m_info.message = builder.m_stream.str(); + getResultCapture().pushScopedMessage(m_info); +} + +ScopedMessage::~ScopedMessage() { + if (!uncaught_exceptions()) { + getResultCapture().popScopedMessage(m_info); + } +} +} // end namespace Catch +// end catch_message.cpp +// start catch_output_redirect.cpp + +// start catch_output_redirect.h +#ifndef TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H +#define TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H + +#include +#include +#include + +namespace Catch { + +class RedirectedStream { + std::ostream &m_originalStream; + std::ostream &m_redirectionStream; + std::streambuf *m_prevBuf; + +public: + RedirectedStream(std::ostream &originalStream, std::ostream &redirectionStream); + ~RedirectedStream(); +}; + +class RedirectedStdOut { + ReusableStringStream m_rss; + RedirectedStream m_cout; + +public: + RedirectedStdOut(); + auto str() const -> std::string; +}; + +// StdErr has two constituent streams in C++, std::cerr and std::clog +// This means that we need to redirect 2 streams into 1 to keep proper +// order of writes +class RedirectedStdErr { + ReusableStringStream m_rss; + RedirectedStream m_cerr; + RedirectedStream m_clog; + +public: + RedirectedStdErr(); + auto str() const -> std::string; +}; + +// Windows's implementation of std::tmpfile is terrible (it tries +// to create a file inside system folder, thus requiring elevated +// privileges for the binary), so we have to use tmpnam(_s) and +// create the file ourselves there. +class TempFile { +public: + TempFile(TempFile const &) = delete; + TempFile &operator=(TempFile const &) = delete; + TempFile(TempFile &&) = delete; + TempFile &operator=(TempFile &&) = delete; + + TempFile(); + ~TempFile(); + + std::FILE *getFile(); + std::string getContents(); + +private: + std::FILE *m_file = nullptr; +#if defined(_MSC_VER) + char m_buffer[L_tmpnam] = {0}; +#endif +}; + +class OutputRedirect { +public: + OutputRedirect(OutputRedirect const &) = delete; + OutputRedirect &operator=(OutputRedirect const &) = delete; + OutputRedirect(OutputRedirect &&) = delete; + OutputRedirect &operator=(OutputRedirect &&) = delete; + + OutputRedirect(std::string &stdout_dest, std::string &stderr_dest); + ~OutputRedirect(); + +private: + int m_originalStdout = -1; + int m_originalStderr = -1; + TempFile m_stdoutFile; + TempFile m_stderrFile; + std::string &m_stdoutDest; + std::string &m_stderrDest; +}; + +} // end namespace Catch + +#endif // TWOBLUECUBES_CATCH_OUTPUT_REDIRECT_H +// end catch_output_redirect.h +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) +#include //_dup and _dup2 +#define dup _dup +#define dup2 _dup2 +#define fileno _fileno +#else +#include // dup and dup2 +#endif + +namespace Catch { + +RedirectedStream::RedirectedStream(std::ostream &originalStream, std::ostream &redirectionStream) + : m_originalStream(originalStream), m_redirectionStream(redirectionStream), m_prevBuf(m_originalStream.rdbuf()) { + m_originalStream.rdbuf(m_redirectionStream.rdbuf()); +} + +RedirectedStream::~RedirectedStream() { + m_originalStream.rdbuf(m_prevBuf); +} + +RedirectedStdOut::RedirectedStdOut() : m_cout(Catch::cout(), m_rss.get()) { +} +auto RedirectedStdOut::str() const -> std::string { + return m_rss.str(); +} + +RedirectedStdErr::RedirectedStdErr() : m_cerr(Catch::cerr(), m_rss.get()), m_clog(Catch::clog(), m_rss.get()) { +} +auto RedirectedStdErr::str() const -> std::string { + return m_rss.str(); +} + +#if defined(_MSC_VER) +TempFile::TempFile() { + if (tmpnam_s(m_buffer)) { + throw std::runtime_error("Could not get a temp filename"); + } + if (fopen_s(&m_file, m_buffer, "w")) { + char buffer[100]; + if (strerror_s(buffer, errno)) { + throw std::runtime_error("Could not translate errno to string"); + } + throw std::runtime_error("Could not open the temp file: " + std::string(m_buffer) + buffer); + } +} +#else +TempFile::TempFile() { + m_file = std::tmpfile(); + if (!m_file) { + throw std::runtime_error("Could not create a temp file."); + } +} + +#endif + +TempFile::~TempFile() { + // TBD: What to do about errors here? + std::fclose(m_file); +// We manually create the file on Windows only, on Linux +// it will be autodeleted +#if defined(_MSC_VER) + std::remove(m_buffer); +#endif +} + +FILE *TempFile::getFile() { + return m_file; +} + +std::string TempFile::getContents() { + std::stringstream sstr; + char buffer[100] = {}; + std::rewind(m_file); + while (std::fgets(buffer, sizeof(buffer), m_file)) { + sstr << buffer; + } + return sstr.str(); +} + +OutputRedirect::OutputRedirect(std::string &stdout_dest, std::string &stderr_dest) + : m_originalStdout(dup(1)), m_originalStderr(dup(2)), m_stdoutDest(stdout_dest), m_stderrDest(stderr_dest) { + dup2(fileno(m_stdoutFile.getFile()), 1); + dup2(fileno(m_stderrFile.getFile()), 2); +} + +OutputRedirect::~OutputRedirect() { + Catch::cout() << std::flush; + fflush(stdout); + // Since we support overriding these streams, we flush cerr + // even though std::cerr is unbuffered + Catch::cerr() << std::flush; + Catch::clog() << std::flush; + fflush(stderr); + + dup2(m_originalStdout, 1); + dup2(m_originalStderr, 2); + + m_stdoutDest += m_stdoutFile.getContents(); + m_stderrDest += m_stderrFile.getContents(); +} + +} // namespace Catch + +#if defined(_MSC_VER) +#undef dup +#undef dup2 +#undef fileno +#endif +// end catch_output_redirect.cpp +// start catch_random_number_generator.cpp + +// start catch_random_number_generator.h + +#include + +namespace Catch { + +struct IConfig; + +void seedRng(IConfig const &config); + +unsigned int rngSeed(); + +struct RandomNumberGenerator { + using result_type = unsigned int; + + static constexpr result_type(min)() { + return 0; + } + static constexpr result_type(max)() { + return 1000000; + } + + result_type operator()(result_type n) const; + result_type operator()() const; + + template static void shuffle(V &vector) { + RandomNumberGenerator rng; + std::shuffle(vector.begin(), vector.end(), rng); + } +}; + +} // namespace Catch + +// end catch_random_number_generator.h +#include + +namespace Catch { + +void seedRng(IConfig const &config) { + if (config.rngSeed() != 0) + std::srand(config.rngSeed()); +} +unsigned int rngSeed() { + return getCurrentContext().getConfig()->rngSeed(); +} + +RandomNumberGenerator::result_type RandomNumberGenerator::operator()(result_type n) const { + return std::rand() % n; +} +RandomNumberGenerator::result_type RandomNumberGenerator::operator()() const { + return std::rand() % (max)(); +} + +} // namespace Catch +// end catch_random_number_generator.cpp +// start catch_registry_hub.cpp + +// start catch_test_case_registry_impl.h + +#include +#include +#include +#include + +namespace Catch { + +class TestCase; +struct IConfig; + +std::vector sortTests(IConfig const &config, std::vector const &unsortedTestCases); +bool matchTest(TestCase const &testCase, TestSpec const &testSpec, IConfig const &config); + +void enforceNoDuplicateTestCases(std::vector const &functions); + +std::vector filterTests(std::vector const &testCases, TestSpec const &testSpec, + IConfig const &config); +std::vector const &getAllTestCasesSorted(IConfig const &config); + +class TestRegistry : public ITestCaseRegistry { +public: + virtual ~TestRegistry() = default; + + virtual void registerTest(TestCase const &testCase); + + std::vector const &getAllTests() const override; + std::vector const &getAllTestsSorted(IConfig const &config) const override; + +private: + std::vector m_functions; + mutable RunTests::InWhatOrder m_currentSortOrder = RunTests::InDeclarationOrder; + mutable std::vector m_sortedFunctions; + std::size_t m_unnamedCount = 0; + std::ios_base::Init m_ostreamInit; // Forces cout/ cerr to be initialised +}; + +/////////////////////////////////////////////////////////////////////////// + +class TestInvokerAsFunction : public ITestInvoker { + void (*m_testAsFunction)(); + +public: + TestInvokerAsFunction(void (*testAsFunction)()) noexcept; + + void invoke() const override; +}; + +std::string extractClassName(StringRef const &classOrQualifiedMethodName); + +/////////////////////////////////////////////////////////////////////////// + +} // end namespace Catch + +// end catch_test_case_registry_impl.h +// start catch_reporter_registry.h + +#include + +namespace Catch { + +class ReporterRegistry : public IReporterRegistry { + +public: + ~ReporterRegistry() override; + + IStreamingReporterPtr create(std::string const &name, IConfigPtr const &config) const override; + + void registerReporter(std::string const &name, IReporterFactoryPtr const &factory); + void registerListener(IReporterFactoryPtr const &factory); + + FactoryMap const &getFactories() const override; + Listeners const &getListeners() const override; + +private: + FactoryMap m_factories; + Listeners m_listeners; +}; +} // namespace Catch + +// end catch_reporter_registry.h +// start catch_tag_alias_registry.h + +// start catch_tag_alias.h + +#include + +namespace Catch { + +struct TagAlias { + TagAlias(std::string const &_tag, SourceLineInfo _lineInfo); + + std::string tag; + SourceLineInfo lineInfo; +}; + +} // end namespace Catch + +// end catch_tag_alias.h +#include + +namespace Catch { + +class TagAliasRegistry : public ITagAliasRegistry { +public: + ~TagAliasRegistry() override; + TagAlias const *find(std::string const &alias) const override; + std::string expandAliases(std::string const &unexpandedTestSpec) const override; + void add(std::string const &alias, std::string const &tag, SourceLineInfo const &lineInfo); + +private: + std::map m_registry; +}; + +} // end namespace Catch + +// end catch_tag_alias_registry.h +// start catch_startup_exception_registry.h + +#include +#include + +namespace Catch { + +class StartupExceptionRegistry { +public: + void add(std::exception_ptr const &exception) noexcept; + std::vector const &getExceptions() const noexcept; + +private: + std::vector m_exceptions; +}; + +} // end namespace Catch + +// end catch_startup_exception_registry.h +namespace Catch { + +namespace { + +class RegistryHub : public IRegistryHub, public IMutableRegistryHub, private NonCopyable { + +public: // IRegistryHub + RegistryHub() = default; + IReporterRegistry const &getReporterRegistry() const override { + return m_reporterRegistry; + } + ITestCaseRegistry const &getTestCaseRegistry() const override { + return m_testCaseRegistry; + } + IExceptionTranslatorRegistry &getExceptionTranslatorRegistry() override { + return m_exceptionTranslatorRegistry; + } + ITagAliasRegistry const &getTagAliasRegistry() const override { + return m_tagAliasRegistry; + } + StartupExceptionRegistry const &getStartupExceptionRegistry() const override { + return m_exceptionRegistry; + } + +public: // IMutableRegistryHub + void registerReporter(std::string const &name, IReporterFactoryPtr const &factory) override { + m_reporterRegistry.registerReporter(name, factory); + } + void registerListener(IReporterFactoryPtr const &factory) override { + m_reporterRegistry.registerListener(factory); + } + void registerTest(TestCase const &testInfo) override { + m_testCaseRegistry.registerTest(testInfo); + } + void registerTranslator(const IExceptionTranslator *translator) override { + m_exceptionTranslatorRegistry.registerTranslator(translator); + } + void registerTagAlias(std::string const &alias, std::string const &tag, SourceLineInfo const &lineInfo) override { + m_tagAliasRegistry.add(alias, tag, lineInfo); + } + void registerStartupException() noexcept override { + m_exceptionRegistry.add(std::current_exception()); + } + +private: + TestRegistry m_testCaseRegistry; + ReporterRegistry m_reporterRegistry; + ExceptionTranslatorRegistry m_exceptionTranslatorRegistry; + TagAliasRegistry m_tagAliasRegistry; + StartupExceptionRegistry m_exceptionRegistry; +}; + +// Single, global, instance +RegistryHub *&getTheRegistryHub() { + static RegistryHub *theRegistryHub = nullptr; + if (!theRegistryHub) + theRegistryHub = new RegistryHub(); + return theRegistryHub; +} +} // namespace + +IRegistryHub &getRegistryHub() { + return *getTheRegistryHub(); +} +IMutableRegistryHub &getMutableRegistryHub() { + return *getTheRegistryHub(); +} +void cleanUp() { + delete getTheRegistryHub(); + getTheRegistryHub() = nullptr; + cleanUpContext(); + ReusableStringStream::cleanup(); +} +std::string translateActiveException() { + return getRegistryHub().getExceptionTranslatorRegistry().translateActiveException(); +} + +} // end namespace Catch +// end catch_registry_hub.cpp +// start catch_reporter_registry.cpp + +namespace Catch { + +ReporterRegistry::~ReporterRegistry() = default; + +IStreamingReporterPtr ReporterRegistry::create(std::string const &name, IConfigPtr const &config) const { + auto it = m_factories.find(name); + if (it == m_factories.end()) + return nullptr; + return it->second->create(ReporterConfig(config)); +} + +void ReporterRegistry::registerReporter(std::string const &name, IReporterFactoryPtr const &factory) { + m_factories.emplace(name, factory); +} +void ReporterRegistry::registerListener(IReporterFactoryPtr const &factory) { + m_listeners.push_back(factory); +} + +IReporterRegistry::FactoryMap const &ReporterRegistry::getFactories() const { + return m_factories; +} +IReporterRegistry::Listeners const &ReporterRegistry::getListeners() const { + return m_listeners; +} + +} // namespace Catch +// end catch_reporter_registry.cpp +// start catch_result_type.cpp + +namespace Catch { + +bool isOk(ResultWas::OfType resultType) { + return (resultType & ResultWas::FailureBit) == 0; +} +bool isJustInfo(int flags) { + return flags == ResultWas::Info; +} + +ResultDisposition::Flags operator|(ResultDisposition::Flags lhs, ResultDisposition::Flags rhs) { + return static_cast(static_cast(lhs) | static_cast(rhs)); +} + +bool shouldContinueOnFailure(int flags) { + return (flags & ResultDisposition::ContinueOnFailure) != 0; +} +bool shouldSuppressFailure(int flags) { + return (flags & ResultDisposition::SuppressFail) != 0; +} + +} // end namespace Catch +// end catch_result_type.cpp +// start catch_run_context.cpp + +#include +#include +#include + +namespace Catch { + +RunContext::RunContext(IConfigPtr const &_config, IStreamingReporterPtr &&reporter) + : m_runInfo(_config->name()), m_context(getCurrentMutableContext()), m_config(_config), + m_reporter(std::move(reporter)), m_lastAssertionInfo{StringRef(), SourceLineInfo("", 0), StringRef(), + ResultDisposition::Normal}, + m_includeSuccessfulResults(m_config->includeSuccessfulResults()) { + m_context.setRunner(this); + m_context.setConfig(m_config); + m_context.setResultCapture(this); + m_reporter->testRunStarting(m_runInfo); +} + +RunContext::~RunContext() { + m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, aborting())); +} + +void RunContext::testGroupStarting(std::string const &testSpec, std::size_t groupIndex, std::size_t groupsCount) { + m_reporter->testGroupStarting(GroupInfo(testSpec, groupIndex, groupsCount)); +} + +void RunContext::testGroupEnded(std::string const &testSpec, Totals const &totals, std::size_t groupIndex, + std::size_t groupsCount) { + m_reporter->testGroupEnded(TestGroupStats(GroupInfo(testSpec, groupIndex, groupsCount), totals, aborting())); +} + +Totals RunContext::runTest(TestCase const &testCase) { + Totals prevTotals = m_totals; + + std::string redirectedCout; + std::string redirectedCerr; + + auto const &testInfo = testCase.getTestCaseInfo(); + + m_reporter->testCaseStarting(testInfo); + + m_activeTestCase = &testCase; + + ITracker &rootTracker = m_trackerContext.startRun(); + assert(rootTracker.isSectionTracker()); + static_cast(rootTracker).addInitialFilters(m_config->getSectionsToRun()); + do { + m_trackerContext.startCycle(); + m_testCaseTracker = + &SectionTracker::acquire(m_trackerContext, TestCaseTracking::NameAndLocation(testInfo.name, testInfo.lineInfo)); + runCurrentTest(redirectedCout, redirectedCerr); + } while (!m_testCaseTracker->isSuccessfullyCompleted() && !aborting()); + + Totals deltaTotals = m_totals.delta(prevTotals); + if (testInfo.expectedToFail() && deltaTotals.testCases.passed > 0) { + deltaTotals.assertions.failed++; + deltaTotals.testCases.passed--; + deltaTotals.testCases.failed++; + } + m_totals.testCases += deltaTotals.testCases; + m_reporter->testCaseEnded(TestCaseStats(testInfo, deltaTotals, redirectedCout, redirectedCerr, aborting())); + + m_activeTestCase = nullptr; + m_testCaseTracker = nullptr; + + return deltaTotals; +} + +IConfigPtr RunContext::config() const { + return m_config; +} + +IStreamingReporter &RunContext::reporter() const { + return *m_reporter; +} + +void RunContext::assertionEnded(AssertionResult const &result) { + if (result.getResultType() == ResultWas::Ok) { + m_totals.assertions.passed++; + m_lastAssertionPassed = true; + } else if (!result.isOk()) { + m_lastAssertionPassed = false; + if (m_activeTestCase->getTestCaseInfo().okToFail()) + m_totals.assertions.failedButOk++; + else + m_totals.assertions.failed++; + } else { + m_lastAssertionPassed = true; + } + + // We have no use for the return value (whether messages should be cleared), because messages were made scoped + // and should be let to clear themselves out. + static_cast(m_reporter->assertionEnded(AssertionStats(result, m_messages, m_totals))); + + // Reset working state + resetAssertionInfo(); + m_lastResult = result; +} +void RunContext::resetAssertionInfo() { + m_lastAssertionInfo.macroName = StringRef(); + m_lastAssertionInfo.capturedExpression = "{Unknown expression after the reported line}"_sr; +} + +bool RunContext::sectionStarted(SectionInfo const §ionInfo, Counts &assertions) { + ITracker §ionTracker = SectionTracker::acquire( + m_trackerContext, TestCaseTracking::NameAndLocation(sectionInfo.name, sectionInfo.lineInfo)); + if (!sectionTracker.isOpen()) + return false; + m_activeSections.push_back(§ionTracker); + + m_lastAssertionInfo.lineInfo = sectionInfo.lineInfo; + + m_reporter->sectionStarting(sectionInfo); + + assertions = m_totals.assertions; + + return true; +} + +bool RunContext::testForMissingAssertions(Counts &assertions) { + if (assertions.total() != 0) + return false; + if (!m_config->warnAboutMissingAssertions()) + return false; + if (m_trackerContext.currentTracker().hasChildren()) + return false; + m_totals.assertions.failed++; + assertions.failed++; + return true; +} + +void RunContext::sectionEnded(SectionEndInfo const &endInfo) { + Counts assertions = m_totals.assertions - endInfo.prevAssertions; + bool missingAssertions = testForMissingAssertions(assertions); + + if (!m_activeSections.empty()) { + m_activeSections.back()->close(); + m_activeSections.pop_back(); + } + + m_reporter->sectionEnded(SectionStats(endInfo.sectionInfo, assertions, endInfo.durationInSeconds, missingAssertions)); + m_messages.clear(); +} + +void RunContext::sectionEndedEarly(SectionEndInfo const &endInfo) { + if (m_unfinishedSections.empty()) + m_activeSections.back()->fail(); + else + m_activeSections.back()->close(); + m_activeSections.pop_back(); + + m_unfinishedSections.push_back(endInfo); +} +void RunContext::benchmarkStarting(BenchmarkInfo const &info) { + m_reporter->benchmarkStarting(info); +} +void RunContext::benchmarkEnded(BenchmarkStats const &stats) { + m_reporter->benchmarkEnded(stats); +} + +void RunContext::pushScopedMessage(MessageInfo const &message) { + m_messages.push_back(message); +} + +void RunContext::popScopedMessage(MessageInfo const &message) { + m_messages.erase(std::remove(m_messages.begin(), m_messages.end(), message), m_messages.end()); +} + +std::string RunContext::getCurrentTestName() const { + return m_activeTestCase ? m_activeTestCase->getTestCaseInfo().name : std::string(); +} + +const AssertionResult *RunContext::getLastResult() const { + return &(*m_lastResult); +} + +void RunContext::exceptionEarlyReported() { + m_shouldReportUnexpected = false; +} + +void RunContext::handleFatalErrorCondition(StringRef message) { + // First notify reporter that bad things happened + m_reporter->fatalErrorEncountered(message); + + // Don't rebuild the result -- the stringification itself can cause more fatal errors + // Instead, fake a result data. + AssertionResultData tempResult(ResultWas::FatalErrorCondition, {false}); + tempResult.message = message; + AssertionResult result(m_lastAssertionInfo, tempResult); + + assertionEnded(result); + + handleUnfinishedSections(); + + // Recreate section for test case (as we will lose the one that was in scope) + auto const &testCaseInfo = m_activeTestCase->getTestCaseInfo(); + SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description); + + Counts assertions; + assertions.failed = 1; + SectionStats testCaseSectionStats(testCaseSection, assertions, 0, false); + m_reporter->sectionEnded(testCaseSectionStats); + + auto const &testInfo = m_activeTestCase->getTestCaseInfo(); + + Totals deltaTotals; + deltaTotals.testCases.failed = 1; + deltaTotals.assertions.failed = 1; + m_reporter->testCaseEnded(TestCaseStats(testInfo, deltaTotals, std::string(), std::string(), false)); + m_totals.testCases.failed++; + testGroupEnded(std::string(), m_totals, 1, 1); + m_reporter->testRunEnded(TestRunStats(m_runInfo, m_totals, false)); +} + +bool RunContext::lastAssertionPassed() { + return m_lastAssertionPassed; +} + +void RunContext::assertionPassed() { + m_lastAssertionPassed = true; + ++m_totals.assertions.passed; + resetAssertionInfo(); +} + +bool RunContext::aborting() const { + return m_totals.assertions.failed == static_cast(m_config->abortAfter()); +} + +void RunContext::runCurrentTest(std::string &redirectedCout, std::string &redirectedCerr) { + auto const &testCaseInfo = m_activeTestCase->getTestCaseInfo(); + SectionInfo testCaseSection(testCaseInfo.lineInfo, testCaseInfo.name, testCaseInfo.description); + m_reporter->sectionStarting(testCaseSection); + Counts prevAssertions = m_totals.assertions; + double duration = 0; + m_shouldReportUnexpected = true; + m_lastAssertionInfo = {"TEST_CASE"_sr, testCaseInfo.lineInfo, StringRef(), ResultDisposition::Normal}; + + seedRng(*m_config); + + Timer timer; + try { + if (m_reporter->getPreferences().shouldRedirectStdOut) { +#if !defined(CATCH_CONFIG_EXPERIMENTAL_REDIRECT) + RedirectedStdOut redirectedStdOut; + RedirectedStdErr redirectedStdErr; + + timer.start(); + invokeActiveTestCase(); + redirectedCout += redirectedStdOut.str(); + redirectedCerr += redirectedStdErr.str(); +#else + OutputRedirect r(redirectedCout, redirectedCerr); + timer.start(); + invokeActiveTestCase(); +#endif + } else { + timer.start(); + invokeActiveTestCase(); + } + duration = timer.getElapsedSeconds(); + } catch (TestFailureException &) { + // This just means the test was aborted due to failure + } catch (...) { + // Under CATCH_CONFIG_FAST_COMPILE, unexpected exceptions under REQUIRE assertions + // are reported without translation at the point of origin. + if (m_shouldReportUnexpected) { + AssertionReaction dummyReaction; + handleUnexpectedInflightException(m_lastAssertionInfo, translateActiveException(), dummyReaction); + } + } + Counts assertions = m_totals.assertions - prevAssertions; + bool missingAssertions = testForMissingAssertions(assertions); + + m_testCaseTracker->close(); + handleUnfinishedSections(); + m_messages.clear(); + + SectionStats testCaseSectionStats(testCaseSection, assertions, duration, missingAssertions); + m_reporter->sectionEnded(testCaseSectionStats); +} + +void RunContext::invokeActiveTestCase() { + FatalConditionHandler fatalConditionHandler; // Handle signals + m_activeTestCase->invoke(); + fatalConditionHandler.reset(); +} + +void RunContext::handleUnfinishedSections() { + // If sections ended prematurely due to an exception we stored their + // infos here so we can tear them down outside the unwind process. + for (auto it = m_unfinishedSections.rbegin(), itEnd = m_unfinishedSections.rend(); it != itEnd; ++it) + sectionEnded(*it); + m_unfinishedSections.clear(); +} + +void RunContext::handleExpr(AssertionInfo const &info, ITransientExpression const &expr, AssertionReaction &reaction) { + m_reporter->assertionStarting(info); + + bool negated = isFalseTest(info.resultDisposition); + bool result = expr.getResult() != negated; + + if (result) { + if (!m_includeSuccessfulResults) { + assertionPassed(); + } else { + reportExpr(info, ResultWas::Ok, &expr, negated); + } + } else { + reportExpr(info, ResultWas::ExpressionFailed, &expr, negated); + populateReaction(reaction); + } +} +void RunContext::reportExpr(AssertionInfo const &info, ResultWas::OfType resultType, ITransientExpression const *expr, + bool negated) { + + m_lastAssertionInfo = info; + AssertionResultData data(resultType, LazyExpression(negated)); + + AssertionResult assertionResult{info, data}; + assertionResult.m_resultData.lazyExpression.m_transientExpression = expr; + + assertionEnded(assertionResult); +} + +void RunContext::handleMessage(AssertionInfo const &info, ResultWas::OfType resultType, StringRef const &message, + AssertionReaction &reaction) { + m_reporter->assertionStarting(info); + + m_lastAssertionInfo = info; + + AssertionResultData data(resultType, LazyExpression(false)); + data.message = message; + AssertionResult assertionResult{m_lastAssertionInfo, data}; + assertionEnded(assertionResult); + if (!assertionResult.isOk()) + populateReaction(reaction); +} +void RunContext::handleUnexpectedExceptionNotThrown(AssertionInfo const &info, AssertionReaction &reaction) { + handleNonExpr(info, Catch::ResultWas::DidntThrowException, reaction); +} + +void RunContext::handleUnexpectedInflightException(AssertionInfo const &info, std::string const &message, + AssertionReaction &reaction) { + m_lastAssertionInfo = info; + + AssertionResultData data(ResultWas::ThrewException, LazyExpression(false)); + data.message = message; + AssertionResult assertionResult{info, data}; + assertionEnded(assertionResult); + populateReaction(reaction); +} + +void RunContext::populateReaction(AssertionReaction &reaction) { + reaction.shouldDebugBreak = m_config->shouldDebugBreak(); + reaction.shouldThrow = aborting() || (m_lastAssertionInfo.resultDisposition & ResultDisposition::Normal); +} + +void RunContext::handleIncomplete(AssertionInfo const &info) { + m_lastAssertionInfo = info; + + AssertionResultData data(ResultWas::ThrewException, LazyExpression(false)); + data.message = "Exception translation was disabled by CATCH_CONFIG_FAST_COMPILE"; + AssertionResult assertionResult{info, data}; + assertionEnded(assertionResult); +} +void RunContext::handleNonExpr(AssertionInfo const &info, ResultWas::OfType resultType, AssertionReaction &reaction) { + m_lastAssertionInfo = info; + + AssertionResultData data(resultType, LazyExpression(false)); + AssertionResult assertionResult{info, data}; + assertionEnded(assertionResult); + + if (!assertionResult.isOk()) + populateReaction(reaction); +} + +IResultCapture &getResultCapture() { + if (auto *capture = getCurrentContext().getResultCapture()) + return *capture; + else + CATCH_INTERNAL_ERROR("No result capture instance"); +} +} // namespace Catch +// end catch_run_context.cpp +// start catch_section.cpp + +namespace Catch { + +Section::Section(SectionInfo const &info) + : m_info(info), m_sectionIncluded(getResultCapture().sectionStarted(m_info, m_assertions)) { + m_timer.start(); +} + +Section::~Section() { + if (m_sectionIncluded) { + SectionEndInfo endInfo(m_info, m_assertions, m_timer.getElapsedSeconds()); + if (uncaught_exceptions()) + getResultCapture().sectionEndedEarly(endInfo); + else + getResultCapture().sectionEnded(endInfo); + } +} + +// This indicates whether the section should be executed or not +Section::operator bool() const { + return m_sectionIncluded; +} + +} // end namespace Catch +// end catch_section.cpp +// start catch_section_info.cpp + +namespace Catch { + +SectionInfo::SectionInfo(SourceLineInfo const &_lineInfo, std::string const &_name, std::string const &_description) + : name(_name), description(_description), lineInfo(_lineInfo) { +} + +SectionEndInfo::SectionEndInfo(SectionInfo const &_sectionInfo, Counts const &_prevAssertions, + double _durationInSeconds) + : sectionInfo(_sectionInfo), prevAssertions(_prevAssertions), durationInSeconds(_durationInSeconds) { +} + +} // end namespace Catch +// end catch_section_info.cpp +// start catch_session.cpp + +// start catch_session.h + +#include + +namespace Catch { + +class Session : NonCopyable { +public: + Session(); + ~Session() override; + + void showHelp() const; + void libIdentify(); + + int applyCommandLine(int argc, char const *const *argv); + + void useConfigData(ConfigData const &configData); + + int run(int argc, char *argv[]); +#if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE) + int run(int argc, wchar_t *const argv[]); +#endif + int run(); + + clara::Parser const &cli() const; + void cli(clara::Parser const &newParser); + ConfigData &configData(); + Config &config(); + +private: + int runInternal(); + + clara::Parser m_cli; + ConfigData m_configData; + std::shared_ptr m_config; + bool m_startupExceptions = false; +}; + +} // end namespace Catch + +// end catch_session.h +// start catch_version.h + +#include + +namespace Catch { + +// Versioning information +struct Version { + Version(Version const &) = delete; + Version &operator=(Version const &) = delete; + Version(unsigned int _majorVersion, unsigned int _minorVersion, unsigned int _patchNumber, + char const *const _branchName, unsigned int _buildNumber); + + unsigned int const majorVersion; + unsigned int const minorVersion; + unsigned int const patchNumber; + + // buildNumber is only used if branchName is not null + char const *const branchName; + unsigned int const buildNumber; + + friend std::ostream &operator<<(std::ostream &os, Version const &version); +}; + +Version const &libraryVersion(); +} // namespace Catch + +// end catch_version.h +#include +#include + +namespace Catch { + +namespace { +const int MaxExitCode = 255; + +IStreamingReporterPtr createReporter(std::string const &reporterName, IConfigPtr const &config) { + auto reporter = Catch::getRegistryHub().getReporterRegistry().create(reporterName, config); + CATCH_ENFORCE(reporter, "No reporter registered with name: '" << reporterName << "'"); + + return reporter; +} + +IStreamingReporterPtr makeReporter(std::shared_ptr const &config) { + if (Catch::getRegistryHub().getReporterRegistry().getListeners().empty()) { + return createReporter(config->getReporterName(), config); + } + + auto multi = std::unique_ptr(new ListeningReporter); + + auto const &listeners = Catch::getRegistryHub().getReporterRegistry().getListeners(); + for (auto const &listener : listeners) { + multi->addListener(listener->create(Catch::ReporterConfig(config))); + } + multi->addReporter(createReporter(config->getReporterName(), config)); + return std::move(multi); +} + +Catch::Totals runTests(std::shared_ptr const &config) { + // FixMe: Add listeners in order first, then add reporters. + + auto reporter = makeReporter(config); + + RunContext context(config, std::move(reporter)); + + Totals totals; + + context.testGroupStarting(config->name(), 1, 1); + + TestSpec testSpec = config->testSpec(); + + auto const &allTestCases = getAllTestCasesSorted(*config); + for (auto const &testCase : allTestCases) { + if (!context.aborting() && matchTest(testCase, testSpec, *config)) + totals += context.runTest(testCase); + else + context.reporter().skipTest(testCase); + } + + if (config->warnAboutNoTests() && totals.testCases.total() == 0) { + ReusableStringStream testConfig; + + bool first = true; + for (const auto &input : config->getTestsOrTags()) { + if (!first) { + testConfig << ' '; + } + first = false; + testConfig << input; + } + + context.reporter().noMatchingTestCases(testConfig.str()); + totals.error = -1; + } + + context.testGroupEnded(config->name(), totals, 1, 1); + return totals; +} + +void applyFilenamesAsTags(Catch::IConfig const &config) { + auto &tests = const_cast &>(getAllTestCasesSorted(config)); + for (auto &testCase : tests) { + auto tags = testCase.tags; + + std::string filename = testCase.lineInfo.file; + auto lastSlash = filename.find_last_of("\\/"); + if (lastSlash != std::string::npos) { + filename.erase(0, lastSlash); + filename[0] = '#'; + } + + auto lastDot = filename.find_last_of('.'); + if (lastDot != std::string::npos) { + filename.erase(lastDot); + } + + tags.push_back(std::move(filename)); + setTags(testCase, tags); + } +} + +} // namespace + +Session::Session() { + static bool alreadyInstantiated = false; + if (alreadyInstantiated) { + try { + CATCH_INTERNAL_ERROR("Only one instance of Catch::Session can ever be used"); + } catch (...) { + getMutableRegistryHub().registerStartupException(); + } + } + + const auto &exceptions = getRegistryHub().getStartupExceptionRegistry().getExceptions(); + if (!exceptions.empty()) { + m_startupExceptions = true; + Colour colourGuard(Colour::Red); + Catch::cerr() << "Errors occurred during startup!" << '\n'; + // iterate over all exceptions and notify user + for (const auto &ex_ptr : exceptions) { + try { + std::rethrow_exception(ex_ptr); + } catch (std::exception const &ex) { + Catch::cerr() << Column(ex.what()).indent(2) << '\n'; + } + } + } + + alreadyInstantiated = true; + m_cli = makeCommandLineParser(m_configData); +} +Session::~Session() { + Catch::cleanUp(); +} + +void Session::showHelp() const { + Catch::cout() << "\nCatch v" << libraryVersion() << "\n" + << m_cli << std::endl + << "For more detailed usage please see the project docs\n" + << std::endl; +} +void Session::libIdentify() { + Catch::cout() << std::left << std::setw(16) << "description: " + << "A Catch test executable\n" + << std::left << std::setw(16) << "category: " + << "testframework\n" + << std::left << std::setw(16) << "framework: " + << "Catch Test\n" + << std::left << std::setw(16) << "version: " << libraryVersion() << std::endl; +} + +int Session::applyCommandLine(int argc, char const *const *argv) { + if (m_startupExceptions) + return 1; + + auto result = m_cli.parse(clara::Args(argc, argv)); + if (!result) { + Catch::cerr() << Colour(Colour::Red) << "\nError(s) in input:\n" + << Column(result.errorMessage()).indent(2) << "\n\n"; + Catch::cerr() << "Run with -? for usage\n" << std::endl; + return MaxExitCode; + } + + if (m_configData.showHelp) + showHelp(); + if (m_configData.libIdentify) + libIdentify(); + m_config.reset(); + return 0; +} + +void Session::useConfigData(ConfigData const &configData) { + m_configData = configData; + m_config.reset(); +} + +int Session::run(int argc, char *argv[]) { + if (m_startupExceptions) + return 1; + int returnCode = applyCommandLine(argc, argv); + if (returnCode == 0) + returnCode = run(); + return returnCode; +} + +#if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(UNICODE) +int Session::run(int argc, wchar_t *const argv[]) { + + char **utf8Argv = new char *[argc]; + + for (int i = 0; i < argc; ++i) { + int bufSize = WideCharToMultiByte(CP_UTF8, 0, argv[i], -1, NULL, 0, NULL, NULL); + + utf8Argv[i] = new char[bufSize]; + + WideCharToMultiByte(CP_UTF8, 0, argv[i], -1, utf8Argv[i], bufSize, NULL, NULL); + } + + int returnCode = run(argc, utf8Argv); + + for (int i = 0; i < argc; ++i) + delete[] utf8Argv[i]; + + delete[] utf8Argv; + + return returnCode; +} +#endif +int Session::run() { + if ((m_configData.waitForKeypress & WaitForKeypress::BeforeStart) != 0) { + Catch::cout() << "...waiting for enter/ return before starting" << std::endl; + static_cast(std::getchar()); + } + int exitCode = runInternal(); + if ((m_configData.waitForKeypress & WaitForKeypress::BeforeExit) != 0) { + Catch::cout() << "...waiting for enter/ return before exiting, with code: " << exitCode << std::endl; + static_cast(std::getchar()); + } + return exitCode; +} + +clara::Parser const &Session::cli() const { + return m_cli; +} +void Session::cli(clara::Parser const &newParser) { + m_cli = newParser; +} +ConfigData &Session::configData() { + return m_configData; +} +Config &Session::config() { + if (!m_config) + m_config = std::make_shared(m_configData); + return *m_config; +} + +int Session::runInternal() { + if (m_startupExceptions) + return 1; + + if (m_configData.showHelp || m_configData.libIdentify) + return 0; + + try { + config(); // Force config to be constructed + + seedRng(*m_config); + + if (m_configData.filenamesAsTags) + applyFilenamesAsTags(*m_config); + + // Handle list request + if (Option listed = list(config())) + return static_cast(*listed); + + auto totals = runTests(m_config); + // Note that on unices only the lower 8 bits are usually used, clamping + // the return value to 255 prevents false negative when some multiple + // of 256 tests has failed + return (std::min)(MaxExitCode, (std::max)(totals.error, static_cast(totals.assertions.failed))); + } catch (std::exception &ex) { + Catch::cerr() << ex.what() << std::endl; + return MaxExitCode; + } +} + +} // end namespace Catch +// end catch_session.cpp +// start catch_startup_exception_registry.cpp + +namespace Catch { +void StartupExceptionRegistry::add(std::exception_ptr const &exception) noexcept { + try { + m_exceptions.push_back(exception); + } catch (...) { + // If we run out of memory during start-up there's really not a lot more we can do about it + std::terminate(); + } +} + +std::vector const &StartupExceptionRegistry::getExceptions() const noexcept { + return m_exceptions; +} + +} // end namespace Catch +// end catch_startup_exception_registry.cpp +// start catch_stream.cpp + +#include +#include +#include +#include +#include +#include + +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wexit-time-destructors" +#endif + +namespace Catch { + +Catch::IStream::~IStream() = default; + +namespace detail { +namespace { +template class StreamBufImpl : public std::streambuf { + char data[bufferSize]; + WriterF m_writer; + +public: + StreamBufImpl() { + setp(data, data + sizeof(data)); + } + + ~StreamBufImpl() noexcept { + StreamBufImpl::sync(); + } + +private: + int overflow(int c) override { + sync(); + + if (c != EOF) { + if (pbase() == epptr()) + m_writer(std::string(1, static_cast(c))); + else + sputc(static_cast(c)); + } + return 0; + } + + int sync() override { + if (pbase() != pptr()) { + m_writer(std::string(pbase(), static_cast(pptr() - pbase()))); + setp(pbase(), epptr()); + } + return 0; + } +}; + +/////////////////////////////////////////////////////////////////////////// + +struct OutputDebugWriter { + + void operator()(std::string const &str) { + writeToDebugConsole(str); + } +}; + +/////////////////////////////////////////////////////////////////////////// + +class FileStream : public IStream { + mutable std::ofstream m_ofs; + +public: + FileStream(StringRef filename) { + m_ofs.open(filename.c_str()); + CATCH_ENFORCE(!m_ofs.fail(), "Unable to open file: '" << filename << "'"); + } + ~FileStream() override = default; + +public: // IStream + std::ostream &stream() const override { + return m_ofs; + } +}; + +/////////////////////////////////////////////////////////////////////////// + +class CoutStream : public IStream { + mutable std::ostream m_os; + +public: + // Store the streambuf from cout up-front because + // cout may get redirected when running tests + CoutStream() : m_os(Catch::cout().rdbuf()) { + } + ~CoutStream() override = default; + +public: // IStream + std::ostream &stream() const override { + return m_os; + } +}; + +/////////////////////////////////////////////////////////////////////////// + +class DebugOutStream : public IStream { + std::unique_ptr> m_streamBuf; + mutable std::ostream m_os; + +public: + DebugOutStream() : m_streamBuf(new StreamBufImpl()), m_os(m_streamBuf.get()) { + } + + ~DebugOutStream() override = default; + +public: // IStream + std::ostream &stream() const override { + return m_os; + } +}; + +} // namespace +} // namespace detail + +/////////////////////////////////////////////////////////////////////////// + +auto makeStream(StringRef const &filename) -> IStream const * { + if (filename.empty()) + return new detail::CoutStream(); + else if (filename[0] == '%') { + if (filename == "%debug") + return new detail::DebugOutStream(); + else + CATCH_ERROR("Unrecognised stream: '" << filename << "'"); + } else + return new detail::FileStream(filename); +} + +// This class encapsulates the idea of a pool of ostringstreams that can be reused. +struct StringStreams { + std::vector> m_streams; + std::vector m_unused; + std::ostringstream m_referenceStream; // Used for copy state/ flags from + static StringStreams *s_instance; + + auto add() -> std::size_t { + if (m_unused.empty()) { + m_streams.push_back(std::unique_ptr(new std::ostringstream)); + return m_streams.size() - 1; + } else { + auto index = m_unused.back(); + m_unused.pop_back(); + return index; + } + } + + void release(std::size_t index) { + m_streams[index]->copyfmt(m_referenceStream); // Restore initial flags and other state + m_unused.push_back(index); + } + + // !TBD: put in TLS + static auto instance() -> StringStreams & { + if (!s_instance) + s_instance = new StringStreams(); + return *s_instance; + } + static void cleanup() { + delete s_instance; + s_instance = nullptr; + } +}; + +StringStreams *StringStreams::s_instance = nullptr; + +void ReusableStringStream::cleanup() { + StringStreams::cleanup(); +} + +ReusableStringStream::ReusableStringStream() + : m_index(StringStreams::instance().add()), m_oss(StringStreams::instance().m_streams[m_index].get()) { +} + +ReusableStringStream::~ReusableStringStream() { + static_cast(m_oss)->str(""); + m_oss->clear(); + StringStreams::instance().release(m_index); +} + +auto ReusableStringStream::str() const -> std::string { + return static_cast(m_oss)->str(); +} + +/////////////////////////////////////////////////////////////////////////// + +#ifndef CATCH_CONFIG_NOSTDOUT // If you #define this you must implement these functions +std::ostream &cout() { + return std::cout; +} +std::ostream &cerr() { + return std::cerr; +} +std::ostream &clog() { + return std::clog; +} +#endif +} // namespace Catch + +#if defined(__clang__) +#pragma clang diagnostic pop +#endif +// end catch_stream.cpp +// start catch_string_manip.cpp + +#include +#include +#include +#include + +namespace Catch { + +bool startsWith(std::string const &s, std::string const &prefix) { + return s.size() >= prefix.size() && std::equal(prefix.begin(), prefix.end(), s.begin()); +} +bool startsWith(std::string const &s, char prefix) { + return !s.empty() && s[0] == prefix; +} +bool endsWith(std::string const &s, std::string const &suffix) { + return s.size() >= suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), s.rbegin()); +} +bool endsWith(std::string const &s, char suffix) { + return !s.empty() && s[s.size() - 1] == suffix; +} +bool contains(std::string const &s, std::string const &infix) { + return s.find(infix) != std::string::npos; +} +char toLowerCh(char c) { + return static_cast(std::tolower(c)); +} +void toLowerInPlace(std::string &s) { + std::transform(s.begin(), s.end(), s.begin(), toLowerCh); +} +std::string toLower(std::string const &s) { + std::string lc = s; + toLowerInPlace(lc); + return lc; +} +std::string trim(std::string const &str) { + static char const *whitespaceChars = "\n\r\t "; + std::string::size_type start = str.find_first_not_of(whitespaceChars); + std::string::size_type end = str.find_last_not_of(whitespaceChars); + + return start != std::string::npos ? str.substr(start, 1 + end - start) : std::string(); +} + +bool replaceInPlace(std::string &str, std::string const &replaceThis, std::string const &withThis) { + bool replaced = false; + std::size_t i = str.find(replaceThis); + while (i != std::string::npos) { + replaced = true; + str = str.substr(0, i) + withThis + str.substr(i + replaceThis.size()); + if (i < str.size() - withThis.size()) + i = str.find(replaceThis, i + withThis.size()); + else + i = std::string::npos; + } + return replaced; +} + +pluralise::pluralise(std::size_t count, std::string const &label) : m_count(count), m_label(label) { +} + +std::ostream &operator<<(std::ostream &os, pluralise const &pluraliser) { + os << pluraliser.m_count << ' ' << pluraliser.m_label; + if (pluraliser.m_count != 1) + os << 's'; + return os; +} + +} // namespace Catch +// end catch_string_manip.cpp +// start catch_stringref.cpp + +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wexit-time-destructors" +#endif + +#include +#include +#include + +namespace { +const uint32_t byte_2_lead = 0xC0; +const uint32_t byte_3_lead = 0xE0; +const uint32_t byte_4_lead = 0xF0; +} // namespace + +namespace Catch { +StringRef::StringRef(char const *rawChars) noexcept + : StringRef(rawChars, static_cast(std::strlen(rawChars))) { +} + +StringRef::operator std::string() const { + return std::string(m_start, m_size); +} + +void StringRef::swap(StringRef &other) noexcept { + std::swap(m_start, other.m_start); + std::swap(m_size, other.m_size); + std::swap(m_data, other.m_data); +} + +auto StringRef::c_str() const -> char const * { + if (isSubstring()) + const_cast(this)->takeOwnership(); + return m_start; +} +auto StringRef::currentData() const noexcept -> char const * { + return m_start; +} + +auto StringRef::isOwned() const noexcept -> bool { + return m_data != nullptr; +} +auto StringRef::isSubstring() const noexcept -> bool { + return m_start[m_size] != '\0'; +} + +void StringRef::takeOwnership() { + if (!isOwned()) { + m_data = new char[m_size + 1]; + memcpy(m_data, m_start, m_size); + m_data[m_size] = '\0'; + m_start = m_data; + } +} +auto StringRef::substr(size_type start, size_type size) const noexcept -> StringRef { + if (start < m_size) + return StringRef(m_start + start, size); + else + return StringRef(); +} +auto StringRef::operator==(StringRef const &other) const noexcept -> bool { + return size() == other.size() && (std::strncmp(m_start, other.m_start, size()) == 0); +} +auto StringRef::operator!=(StringRef const &other) const noexcept -> bool { + return !operator==(other); +} + +auto StringRef::operator[](size_type index) const noexcept -> char { + return m_start[index]; +} + +auto StringRef::numberOfCharacters() const noexcept -> size_type { + size_type noChars = m_size; + // Make adjustments for uft encodings + for (size_type i = 0; i < m_size; ++i) { + char c = m_start[i]; + if ((c & byte_2_lead) == byte_2_lead) { + noChars--; + if ((c & byte_3_lead) == byte_3_lead) + noChars--; + if ((c & byte_4_lead) == byte_4_lead) + noChars--; + } + } + return noChars; +} + +auto operator+(StringRef const &lhs, StringRef const &rhs) -> std::string { + std::string str; + str.reserve(lhs.size() + rhs.size()); + str += lhs; + str += rhs; + return str; +} +auto operator+(StringRef const &lhs, const char *rhs) -> std::string { + return std::string(lhs) + std::string(rhs); +} +auto operator+(char const *lhs, StringRef const &rhs) -> std::string { + return std::string(lhs) + std::string(rhs); +} + +auto operator<<(std::ostream &os, StringRef const &str) -> std::ostream & { + return os.write(str.currentData(), str.size()); +} + +auto operator+=(std::string &lhs, StringRef const &rhs) -> std::string & { + lhs.append(rhs.currentData(), rhs.size()); + return lhs; +} + +} // namespace Catch + +#if defined(__clang__) +#pragma clang diagnostic pop +#endif +// end catch_stringref.cpp +// start catch_tag_alias.cpp + +namespace Catch { +TagAlias::TagAlias(std::string const &_tag, SourceLineInfo _lineInfo) : tag(_tag), lineInfo(_lineInfo) { +} +} // namespace Catch +// end catch_tag_alias.cpp +// start catch_tag_alias_autoregistrar.cpp + +namespace Catch { + +RegistrarForTagAliases::RegistrarForTagAliases(char const *alias, char const *tag, SourceLineInfo const &lineInfo) { + try { + getMutableRegistryHub().registerTagAlias(alias, tag, lineInfo); + } catch (...) { + // Do not throw when constructing global objects, instead register the exception to be processed later + getMutableRegistryHub().registerStartupException(); + } +} + +} // namespace Catch +// end catch_tag_alias_autoregistrar.cpp +// start catch_tag_alias_registry.cpp + +#include + +namespace Catch { + +TagAliasRegistry::~TagAliasRegistry() { +} + +TagAlias const *TagAliasRegistry::find(std::string const &alias) const { + auto it = m_registry.find(alias); + if (it != m_registry.end()) + return &(it->second); + else + return nullptr; +} + +std::string TagAliasRegistry::expandAliases(std::string const &unexpandedTestSpec) const { + std::string expandedTestSpec = unexpandedTestSpec; + for (auto const ®istryKvp : m_registry) { + std::size_t pos = expandedTestSpec.find(registryKvp.first); + if (pos != std::string::npos) { + expandedTestSpec = expandedTestSpec.substr(0, pos) + registryKvp.second.tag + + expandedTestSpec.substr(pos + registryKvp.first.size()); + } + } + return expandedTestSpec; +} + +void TagAliasRegistry::add(std::string const &alias, std::string const &tag, SourceLineInfo const &lineInfo) { + CATCH_ENFORCE(startsWith(alias, "[@") && endsWith(alias, ']'), "error: tag alias, '" + << alias << "' is not of the form [@alias name].\n" + << lineInfo); + + CATCH_ENFORCE(m_registry.insert(std::make_pair(alias, TagAlias(tag, lineInfo))).second, + "error: tag alias, '" << alias << "' already registered.\n" + << "\tFirst seen at: " << find(alias)->lineInfo << "\n" + << "\tRedefined at: " << lineInfo); +} + +ITagAliasRegistry::~ITagAliasRegistry() { +} + +ITagAliasRegistry const &ITagAliasRegistry::get() { + return getRegistryHub().getTagAliasRegistry(); +} + +} // end namespace Catch +// end catch_tag_alias_registry.cpp +// start catch_test_case_info.cpp + +#include +#include +#include +#include + +namespace Catch { + +TestCaseInfo::SpecialProperties parseSpecialTag(std::string const &tag) { + if (startsWith(tag, '.') || tag == "!hide") + return TestCaseInfo::IsHidden; + else if (tag == "!throws") + return TestCaseInfo::Throws; + else if (tag == "!shouldfail") + return TestCaseInfo::ShouldFail; + else if (tag == "!mayfail") + return TestCaseInfo::MayFail; + else if (tag == "!nonportable") + return TestCaseInfo::NonPortable; + else if (tag == "!benchmark") + return static_cast(TestCaseInfo::Benchmark | TestCaseInfo::IsHidden); + else + return TestCaseInfo::None; +} +bool isReservedTag(std::string const &tag) { + return parseSpecialTag(tag) == TestCaseInfo::None && tag.size() > 0 && + !std::isalnum(static_cast(tag[0])); +} +void enforceNotReservedTag(std::string const &tag, SourceLineInfo const &_lineInfo) { + CATCH_ENFORCE(!isReservedTag(tag), "Tag name: [" + << tag << "] is not allowed.\n" + << "Tag names starting with non alpha-numeric characters are reserved\n" + << _lineInfo); +} + +TestCase makeTestCase(ITestInvoker *_testCase, std::string const &_className, NameAndTags const &nameAndTags, + SourceLineInfo const &_lineInfo) { + bool isHidden = false; + + // Parse out tags + std::vector tags; + std::string desc, tag; + bool inTag = false; + std::string _descOrTags = nameAndTags.tags; + for (char c : _descOrTags) { + if (!inTag) { + if (c == '[') + inTag = true; + else + desc += c; + } else { + if (c == ']') { + TestCaseInfo::SpecialProperties prop = parseSpecialTag(tag); + if ((prop & TestCaseInfo::IsHidden) != 0) + isHidden = true; + else if (prop == TestCaseInfo::None) + enforceNotReservedTag(tag, _lineInfo); + + tags.push_back(tag); + tag.clear(); + inTag = false; + } else + tag += c; + } + } + if (isHidden) { + tags.push_back("."); + } + + TestCaseInfo info(nameAndTags.name, _className, desc, tags, _lineInfo); + return TestCase(_testCase, std::move(info)); +} + +void setTags(TestCaseInfo &testCaseInfo, std::vector tags) { + std::sort(begin(tags), end(tags)); + tags.erase(std::unique(begin(tags), end(tags)), end(tags)); + testCaseInfo.lcaseTags.clear(); + + for (auto const &tag : tags) { + std::string lcaseTag = toLower(tag); + testCaseInfo.properties = + static_cast(testCaseInfo.properties | parseSpecialTag(lcaseTag)); + testCaseInfo.lcaseTags.push_back(lcaseTag); + } + testCaseInfo.tags = std::move(tags); +} + +TestCaseInfo::TestCaseInfo(std::string const &_name, std::string const &_className, std::string const &_description, + std::vector const &_tags, SourceLineInfo const &_lineInfo) + : name(_name), className(_className), description(_description), lineInfo(_lineInfo), properties(None) { + setTags(*this, _tags); +} + +bool TestCaseInfo::isHidden() const { + return (properties & IsHidden) != 0; +} +bool TestCaseInfo::throws() const { + return (properties & Throws) != 0; +} +bool TestCaseInfo::okToFail() const { + return (properties & (ShouldFail | MayFail)) != 0; +} +bool TestCaseInfo::expectedToFail() const { + return (properties & (ShouldFail)) != 0; +} + +std::string TestCaseInfo::tagsAsString() const { + std::string ret; + // '[' and ']' per tag + std::size_t full_size = 2 * tags.size(); + for (const auto &tag : tags) { + full_size += tag.size(); + } + ret.reserve(full_size); + for (const auto &tag : tags) { + ret.push_back('['); + ret.append(tag); + ret.push_back(']'); + } + + return ret; +} + +TestCase::TestCase(ITestInvoker *testCase, TestCaseInfo &&info) : TestCaseInfo(std::move(info)), test(testCase) { +} + +TestCase TestCase::withName(std::string const &_newName) const { + TestCase other(*this); + other.name = _newName; + return other; +} + +void TestCase::invoke() const { + test->invoke(); +} + +bool TestCase::operator==(TestCase const &other) const { + return test.get() == other.test.get() && name == other.name && className == other.className; +} + +bool TestCase::operator<(TestCase const &other) const { + return name < other.name; +} + +TestCaseInfo const &TestCase::getTestCaseInfo() const { + return *this; +} + +} // end namespace Catch +// end catch_test_case_info.cpp +// start catch_test_case_registry_impl.cpp + +#include + +namespace Catch { + +std::vector sortTests(IConfig const &config, std::vector const &unsortedTestCases) { + + std::vector sorted = unsortedTestCases; + + switch (config.runOrder()) { + case RunTests::InLexicographicalOrder: + std::sort(sorted.begin(), sorted.end()); + break; + case RunTests::InRandomOrder: + seedRng(config); + RandomNumberGenerator::shuffle(sorted); + break; + case RunTests::InDeclarationOrder: + // already in declaration order + break; + } + return sorted; +} +bool matchTest(TestCase const &testCase, TestSpec const &testSpec, IConfig const &config) { + return testSpec.matches(testCase) && (config.allowThrows() || !testCase.throws()); +} + +void enforceNoDuplicateTestCases(std::vector const &functions) { + std::set seenFunctions; + for (auto const &function : functions) { + auto prev = seenFunctions.insert(function); + CATCH_ENFORCE(prev.second, "error: TEST_CASE( \"" << function.name << "\" ) already defined.\n" + << "\tFirst seen at " << prev.first->getTestCaseInfo().lineInfo + << "\n" + << "\tRedefined at " << function.getTestCaseInfo().lineInfo); + } +} + +std::vector filterTests(std::vector const &testCases, TestSpec const &testSpec, + IConfig const &config) { + std::vector filtered; + filtered.reserve(testCases.size()); + for (auto const &testCase : testCases) + if (matchTest(testCase, testSpec, config)) + filtered.push_back(testCase); + return filtered; +} +std::vector const &getAllTestCasesSorted(IConfig const &config) { + return getRegistryHub().getTestCaseRegistry().getAllTestsSorted(config); +} + +void TestRegistry::registerTest(TestCase const &testCase) { + std::string name = testCase.getTestCaseInfo().name; + if (name.empty()) { + ReusableStringStream rss; + rss << "Anonymous test case " << ++m_unnamedCount; + return registerTest(testCase.withName(rss.str())); + } + m_functions.push_back(testCase); +} + +std::vector const &TestRegistry::getAllTests() const { + return m_functions; +} +std::vector const &TestRegistry::getAllTestsSorted(IConfig const &config) const { + if (m_sortedFunctions.empty()) + enforceNoDuplicateTestCases(m_functions); + + if (m_currentSortOrder != config.runOrder() || m_sortedFunctions.empty()) { + m_sortedFunctions = sortTests(config, m_functions); + m_currentSortOrder = config.runOrder(); + } + return m_sortedFunctions; +} + +/////////////////////////////////////////////////////////////////////////// +TestInvokerAsFunction::TestInvokerAsFunction(void (*testAsFunction)()) noexcept : m_testAsFunction(testAsFunction) { +} + +void TestInvokerAsFunction::invoke() const { + m_testAsFunction(); +} + +std::string extractClassName(StringRef const &classOrQualifiedMethodName) { + std::string className = classOrQualifiedMethodName; + if (startsWith(className, '&')) { + std::size_t lastColons = className.rfind("::"); + std::size_t penultimateColons = className.rfind("::", lastColons - 1); + if (penultimateColons == std::string::npos) + penultimateColons = 1; + className = className.substr(penultimateColons, lastColons - penultimateColons); + } + return className; +} + +} // end namespace Catch +// end catch_test_case_registry_impl.cpp +// start catch_test_case_tracker.cpp + +#include +#include +#include +#include +#include + +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wexit-time-destructors" +#endif + +namespace Catch { +namespace TestCaseTracking { + +NameAndLocation::NameAndLocation(std::string const &_name, SourceLineInfo const &_location) + : name(_name), location(_location) { +} + +ITracker::~ITracker() = default; + +TrackerContext &TrackerContext::instance() { + static TrackerContext s_instance; + return s_instance; +} + +ITracker &TrackerContext::startRun() { + m_rootTracker = std::make_shared(NameAndLocation("{root}", CATCH_INTERNAL_LINEINFO), *this, nullptr); + m_currentTracker = nullptr; + m_runState = Executing; + return *m_rootTracker; +} + +void TrackerContext::endRun() { + m_rootTracker.reset(); + m_currentTracker = nullptr; + m_runState = NotStarted; +} + +void TrackerContext::startCycle() { + m_currentTracker = m_rootTracker.get(); + m_runState = Executing; +} +void TrackerContext::completeCycle() { + m_runState = CompletedCycle; +} + +bool TrackerContext::completedCycle() const { + return m_runState == CompletedCycle; +} +ITracker &TrackerContext::currentTracker() { + return *m_currentTracker; +} +void TrackerContext::setCurrentTracker(ITracker *tracker) { + m_currentTracker = tracker; +} + +TrackerBase::TrackerHasName::TrackerHasName(NameAndLocation const &nameAndLocation) + : m_nameAndLocation(nameAndLocation) { +} +bool TrackerBase::TrackerHasName::operator()(ITrackerPtr const &tracker) const { + return tracker->nameAndLocation().name == m_nameAndLocation.name && + tracker->nameAndLocation().location == m_nameAndLocation.location; +} + +TrackerBase::TrackerBase(NameAndLocation const &nameAndLocation, TrackerContext &ctx, ITracker *parent) + : m_nameAndLocation(nameAndLocation), m_ctx(ctx), m_parent(parent) { +} + +NameAndLocation const &TrackerBase::nameAndLocation() const { + return m_nameAndLocation; +} +bool TrackerBase::isComplete() const { + return m_runState == CompletedSuccessfully || m_runState == Failed; +} +bool TrackerBase::isSuccessfullyCompleted() const { + return m_runState == CompletedSuccessfully; +} +bool TrackerBase::isOpen() const { + return m_runState != NotStarted && !isComplete(); +} +bool TrackerBase::hasChildren() const { + return !m_children.empty(); +} + +void TrackerBase::addChild(ITrackerPtr const &child) { + m_children.push_back(child); +} + +ITrackerPtr TrackerBase::findChild(NameAndLocation const &nameAndLocation) { + auto it = std::find_if(m_children.begin(), m_children.end(), TrackerHasName(nameAndLocation)); + return (it != m_children.end()) ? *it : nullptr; +} +ITracker &TrackerBase::parent() { + assert(m_parent); // Should always be non-null except for root + return *m_parent; +} + +void TrackerBase::openChild() { + if (m_runState != ExecutingChildren) { + m_runState = ExecutingChildren; + if (m_parent) + m_parent->openChild(); + } +} + +bool TrackerBase::isSectionTracker() const { + return false; +} +bool TrackerBase::isIndexTracker() const { + return false; +} + +void TrackerBase::open() { + m_runState = Executing; + moveToThis(); + if (m_parent) + m_parent->openChild(); +} + +void TrackerBase::close() { + + // Close any still open children (e.g. generators) + while (&m_ctx.currentTracker() != this) + m_ctx.currentTracker().close(); + + switch (m_runState) { + case NeedsAnotherRun: + break; + + case Executing: + m_runState = CompletedSuccessfully; + break; + case ExecutingChildren: + if (m_children.empty() || m_children.back()->isComplete()) + m_runState = CompletedSuccessfully; + break; + + case NotStarted: + case CompletedSuccessfully: + case Failed: + CATCH_INTERNAL_ERROR("Illogical state: " << m_runState); + + default: + CATCH_INTERNAL_ERROR("Unknown state: " << m_runState); + } + moveToParent(); + m_ctx.completeCycle(); +} +void TrackerBase::fail() { + m_runState = Failed; + if (m_parent) + m_parent->markAsNeedingAnotherRun(); + moveToParent(); + m_ctx.completeCycle(); +} +void TrackerBase::markAsNeedingAnotherRun() { + m_runState = NeedsAnotherRun; +} + +void TrackerBase::moveToParent() { + assert(m_parent); + m_ctx.setCurrentTracker(m_parent); +} +void TrackerBase::moveToThis() { + m_ctx.setCurrentTracker(this); +} + +SectionTracker::SectionTracker(NameAndLocation const &nameAndLocation, TrackerContext &ctx, ITracker *parent) + : TrackerBase(nameAndLocation, ctx, parent) { + if (parent) { + while (!parent->isSectionTracker()) + parent = &parent->parent(); + + SectionTracker &parentSection = static_cast(*parent); + addNextFilters(parentSection.m_filters); + } +} + +bool SectionTracker::isSectionTracker() const { + return true; +} + +SectionTracker &SectionTracker::acquire(TrackerContext &ctx, NameAndLocation const &nameAndLocation) { + std::shared_ptr section; + + ITracker ¤tTracker = ctx.currentTracker(); + if (ITrackerPtr childTracker = currentTracker.findChild(nameAndLocation)) { + assert(childTracker); + assert(childTracker->isSectionTracker()); + section = std::static_pointer_cast(childTracker); + } else { + section = std::make_shared(nameAndLocation, ctx, ¤tTracker); + currentTracker.addChild(section); + } + if (!ctx.completedCycle()) + section->tryOpen(); + return *section; +} + +void SectionTracker::tryOpen() { + if (!isComplete() && (m_filters.empty() || m_filters[0].empty() || m_filters[0] == m_nameAndLocation.name)) + open(); +} + +void SectionTracker::addInitialFilters(std::vector const &filters) { + if (!filters.empty()) { + m_filters.push_back(""); // Root - should never be consulted + m_filters.push_back(""); // Test Case - not a section filter + m_filters.insert(m_filters.end(), filters.begin(), filters.end()); + } +} +void SectionTracker::addNextFilters(std::vector const &filters) { + if (filters.size() > 1) + m_filters.insert(m_filters.end(), ++filters.begin(), filters.end()); +} + +IndexTracker::IndexTracker(NameAndLocation const &nameAndLocation, TrackerContext &ctx, ITracker *parent, int size) + : TrackerBase(nameAndLocation, ctx, parent), m_size(size) { +} + +bool IndexTracker::isIndexTracker() const { + return true; +} + +IndexTracker &IndexTracker::acquire(TrackerContext &ctx, NameAndLocation const &nameAndLocation, int size) { + std::shared_ptr tracker; + + ITracker ¤tTracker = ctx.currentTracker(); + if (ITrackerPtr childTracker = currentTracker.findChild(nameAndLocation)) { + assert(childTracker); + assert(childTracker->isIndexTracker()); + tracker = std::static_pointer_cast(childTracker); + } else { + tracker = std::make_shared(nameAndLocation, ctx, ¤tTracker, size); + currentTracker.addChild(tracker); + } + + if (!ctx.completedCycle() && !tracker->isComplete()) { + if (tracker->m_runState != ExecutingChildren && tracker->m_runState != NeedsAnotherRun) + tracker->moveNext(); + tracker->open(); + } + + return *tracker; +} + +int IndexTracker::index() const { + return m_index; +} + +void IndexTracker::moveNext() { + m_index++; + m_children.clear(); +} + +void IndexTracker::close() { + TrackerBase::close(); + if (m_runState == CompletedSuccessfully && m_index < m_size - 1) + m_runState = Executing; +} + +} // namespace TestCaseTracking + +using TestCaseTracking::ITracker; +using TestCaseTracking::TrackerContext; +using TestCaseTracking::SectionTracker; +using TestCaseTracking::IndexTracker; + +} // namespace Catch + +#if defined(__clang__) +#pragma clang diagnostic pop +#endif +// end catch_test_case_tracker.cpp +// start catch_test_registry.cpp + +namespace Catch { + +auto makeTestInvoker(void (*testAsFunction)()) noexcept -> ITestInvoker * { + return new (std::nothrow) TestInvokerAsFunction(testAsFunction); +} + +NameAndTags::NameAndTags(StringRef const &name_, StringRef const &tags_) noexcept : name(name_), tags(tags_) { +} + +AutoReg::AutoReg(ITestInvoker *invoker, SourceLineInfo const &lineInfo, StringRef const &classOrMethod, + NameAndTags const &nameAndTags) noexcept { + try { + getMutableRegistryHub().registerTest(makeTestCase(invoker, extractClassName(classOrMethod), nameAndTags, lineInfo)); + } catch (...) { + // Do not throw when constructing global objects, instead register the exception to be processed later + getMutableRegistryHub().registerStartupException(); + } +} + +AutoReg::~AutoReg() = default; +} // namespace Catch +// end catch_test_registry.cpp +// start catch_test_spec.cpp + +#include +#include +#include +#include + +namespace Catch { + +TestSpec::Pattern::~Pattern() = default; +TestSpec::NamePattern::~NamePattern() = default; +TestSpec::TagPattern::~TagPattern() = default; +TestSpec::ExcludedPattern::~ExcludedPattern() = default; + +TestSpec::NamePattern::NamePattern(std::string const &name) : m_wildcardPattern(toLower(name), CaseSensitive::No) { +} +bool TestSpec::NamePattern::matches(TestCaseInfo const &testCase) const { + return m_wildcardPattern.matches(toLower(testCase.name)); +} + +TestSpec::TagPattern::TagPattern(std::string const &tag) : m_tag(toLower(tag)) { +} +bool TestSpec::TagPattern::matches(TestCaseInfo const &testCase) const { + return std::find(begin(testCase.lcaseTags), end(testCase.lcaseTags), m_tag) != end(testCase.lcaseTags); +} + +TestSpec::ExcludedPattern::ExcludedPattern(PatternPtr const &underlyingPattern) + : m_underlyingPattern(underlyingPattern) { +} +bool TestSpec::ExcludedPattern::matches(TestCaseInfo const &testCase) const { + return !m_underlyingPattern->matches(testCase); +} + +bool TestSpec::Filter::matches(TestCaseInfo const &testCase) const { + // All patterns in a filter must match for the filter to be a match + for (auto const &pattern : m_patterns) { + if (!pattern->matches(testCase)) + return false; + } + return true; +} + +bool TestSpec::hasFilters() const { + return !m_filters.empty(); +} +bool TestSpec::matches(TestCaseInfo const &testCase) const { + // A TestSpec matches if any filter matches + for (auto const &filter : m_filters) + if (filter.matches(testCase)) + return true; + return false; +} +} // namespace Catch +// end catch_test_spec.cpp +// start catch_test_spec_parser.cpp + +namespace Catch { + +TestSpecParser::TestSpecParser(ITagAliasRegistry const &tagAliases) : m_tagAliases(&tagAliases) { +} + +TestSpecParser &TestSpecParser::parse(std::string const &arg) { + m_mode = None; + m_exclusion = false; + m_start = std::string::npos; + m_arg = m_tagAliases->expandAliases(arg); + m_escapeChars.clear(); + for (m_pos = 0; m_pos < m_arg.size(); ++m_pos) + visitChar(m_arg[m_pos]); + if (m_mode == Name) + addPattern(); + return *this; +} +TestSpec TestSpecParser::testSpec() { + addFilter(); + return m_testSpec; +} + +void TestSpecParser::visitChar(char c) { + if (m_mode == None) { + switch (c) { + case ' ': + return; + case '~': + m_exclusion = true; + return; + case '[': + return startNewMode(Tag, ++m_pos); + case '"': + return startNewMode(QuotedName, ++m_pos); + case '\\': + return escape(); + default: + startNewMode(Name, m_pos); + break; + } + } + if (m_mode == Name) { + if (c == ',') { + addPattern(); + addFilter(); + } else if (c == '[') { + if (subString() == "exclude:") + m_exclusion = true; + else + addPattern(); + startNewMode(Tag, ++m_pos); + } else if (c == '\\') + escape(); + } else if (m_mode == EscapedName) + m_mode = Name; + else if (m_mode == QuotedName && c == '"') + addPattern(); + else if (m_mode == Tag && c == ']') + addPattern(); +} +void TestSpecParser::startNewMode(Mode mode, std::size_t start) { + m_mode = mode; + m_start = start; +} +void TestSpecParser::escape() { + if (m_mode == None) + m_start = m_pos; + m_mode = EscapedName; + m_escapeChars.push_back(m_pos); +} +std::string TestSpecParser::subString() const { + return m_arg.substr(m_start, m_pos - m_start); +} + +void TestSpecParser::addFilter() { + if (!m_currentFilter.m_patterns.empty()) { + m_testSpec.m_filters.push_back(m_currentFilter); + m_currentFilter = TestSpec::Filter(); + } +} + +TestSpec parseTestSpec(std::string const &arg) { + return TestSpecParser(ITagAliasRegistry::get()).parse(arg).testSpec(); +} + +} // namespace Catch +// end catch_test_spec_parser.cpp +// start catch_timer.cpp + +#include + +static const uint64_t nanosecondsInSecond = 1000000000; + +namespace Catch { + +auto getCurrentNanosecondsSinceEpoch() -> uint64_t { + return std::chrono::duration_cast( + std::chrono::high_resolution_clock::now().time_since_epoch()) + .count(); +} + +auto estimateClockResolution() -> uint64_t { + uint64_t sum = 0; + static const uint64_t iterations = 1000000; + + auto startTime = getCurrentNanosecondsSinceEpoch(); + + for (std::size_t i = 0; i < iterations; ++i) { + + uint64_t ticks; + uint64_t baseTicks = getCurrentNanosecondsSinceEpoch(); + do { + ticks = getCurrentNanosecondsSinceEpoch(); + } while (ticks == baseTicks); + + auto delta = ticks - baseTicks; + sum += delta; + + // If we have been calibrating for over 3 seconds -- the clock + // is terrible and we should move on. + // TBD: How to signal that the measured resolution is probably wrong? + if (ticks > startTime + 3 * nanosecondsInSecond) { + return sum / i; + } + } + + // We're just taking the mean, here. To do better we could take the std. dev and exclude outliers + // - and potentially do more iterations if there's a high variance. + return sum / iterations; +} +auto getEstimatedClockResolution() -> uint64_t { + static auto s_resolution = estimateClockResolution(); + return s_resolution; +} + +void Timer::start() { + m_nanoseconds = getCurrentNanosecondsSinceEpoch(); +} +auto Timer::getElapsedNanoseconds() const -> uint64_t { + return getCurrentNanosecondsSinceEpoch() - m_nanoseconds; +} +auto Timer::getElapsedMicroseconds() const -> uint64_t { + return getElapsedNanoseconds() / 1000; +} +auto Timer::getElapsedMilliseconds() const -> unsigned int { + return static_cast(getElapsedMicroseconds() / 1000); +} +auto Timer::getElapsedSeconds() const -> double { + return getElapsedMicroseconds() / 1000000.0; +} + +} // namespace Catch +// end catch_timer.cpp +// start catch_tostring.cpp + +#if defined(__clang__) +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wexit-time-destructors" +#pragma clang diagnostic ignored "-Wglobal-constructors" +#endif + +// Enable specific decls locally +#if !defined(CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER) +#define CATCH_CONFIG_ENABLE_CHRONO_STRINGMAKER +#endif + +#include +#include + +namespace Catch { + +namespace Detail { + +const std::string unprintableString = "{?}"; + +namespace { +const int hexThreshold = 255; + +struct Endianness { + enum Arch { Big, Little }; + + static Arch which() { + union _ { + int asInt; + char asChar[sizeof(int)]; + } u; + + u.asInt = 1; + return (u.asChar[sizeof(int) - 1] == 1) ? Big : Little; + } +}; +} // namespace + +std::string rawMemoryToString(const void *object, std::size_t size) { + // Reverse order for little endian architectures + int i = 0, end = static_cast(size), inc = 1; + if (Endianness::which() == Endianness::Little) { + i = end - 1; + end = inc = -1; + } + + unsigned char const *bytes = static_cast(object); + ReusableStringStream rss; + rss << "0x" << std::setfill('0') << std::hex; + for (; i != end; i += inc) + rss << std::setw(2) << static_cast(bytes[i]); + return rss.str(); +} +} // namespace Detail + +template std::string fpToString(T value, int precision) { + if (std::isnan(value)) { + return "nan"; + } + + ReusableStringStream rss; + rss << std::setprecision(precision) << std::fixed << value; + std::string d = rss.str(); + std::size_t i = d.find_last_not_of('0'); + if (i != std::string::npos && i != d.size() - 1) { + if (d[i] == '.') + i++; + d = d.substr(0, i + 1); + } + return d; +} + +//// ======================================================= //// +// +// Out-of-line defs for full specialization of StringMaker +// +//// ======================================================= //// + +std::string StringMaker::convert(const std::string &str) { + if (!getCurrentContext().getConfig()->showInvisibles()) { + return '"' + str + '"'; + } + + std::string s("\""); + for (char c : str) { + switch (c) { + case '\n': + s.append("\\n"); + break; + case '\t': + s.append("\\t"); + break; + default: + s.push_back(c); + break; + } + } + s.append("\""); + return s; +} + +#ifdef CATCH_CONFIG_WCHAR +std::string StringMaker::convert(const std::wstring &wstr) { + std::string s; + s.reserve(wstr.size()); + for (auto c : wstr) { + s += (c <= 0xff) ? static_cast(c) : '?'; + } + return ::Catch::Detail::stringify(s); +} +#endif + +std::string StringMaker::convert(char const *str) { + if (str) { + return ::Catch::Detail::stringify(std::string{str}); + } else { + return {"{null string}"}; + } +} +std::string StringMaker::convert(char *str) { + if (str) { + return ::Catch::Detail::stringify(std::string{str}); + } else { + return {"{null string}"}; + } +} +#ifdef CATCH_CONFIG_WCHAR +std::string StringMaker::convert(wchar_t const *str) { + if (str) { + return ::Catch::Detail::stringify(std::wstring{str}); + } else { + return {"{null string}"}; + } +} +std::string StringMaker::convert(wchar_t *str) { + if (str) { + return ::Catch::Detail::stringify(std::wstring{str}); + } else { + return {"{null string}"}; + } +} +#endif + +std::string StringMaker::convert(int value) { + return ::Catch::Detail::stringify(static_cast(value)); +} +std::string StringMaker::convert(long value) { + return ::Catch::Detail::stringify(static_cast(value)); +} +std::string StringMaker::convert(long long value) { + ReusableStringStream rss; + rss << value; + if (value > Detail::hexThreshold) { + rss << " (0x" << std::hex << value << ')'; + } + return rss.str(); +} + +std::string StringMaker::convert(unsigned int value) { + return ::Catch::Detail::stringify(static_cast(value)); +} +std::string StringMaker::convert(unsigned long value) { + return ::Catch::Detail::stringify(static_cast(value)); +} +std::string StringMaker::convert(unsigned long long value) { + ReusableStringStream rss; + rss << value; + if (value > Detail::hexThreshold) { + rss << " (0x" << std::hex << value << ')'; + } + return rss.str(); +} + +std::string StringMaker::convert(bool b) { + return b ? "true" : "false"; +} + +std::string StringMaker::convert(char value) { + if (value == '\r') { + return "'\\r'"; + } else if (value == '\f') { + return "'\\f'"; + } else if (value == '\n') { + return "'\\n'"; + } else if (value == '\t') { + return "'\\t'"; + } else if ('\0' <= value && value < ' ') { + return ::Catch::Detail::stringify(static_cast(value)); + } else { + char chstr[] = "' '"; + chstr[1] = value; + return chstr; + } +} +std::string StringMaker::convert(signed char c) { + return ::Catch::Detail::stringify(static_cast(c)); +} +std::string StringMaker::convert(unsigned char c) { + return ::Catch::Detail::stringify(static_cast(c)); +} + +std::string StringMaker::convert(std::nullptr_t) { + return "nullptr"; +} + +std::string StringMaker::convert(float value) { + return fpToString(value, 5) + 'f'; +} +std::string StringMaker::convert(double value) { + return fpToString(value, 10); +} + +std::string ratio_string::symbol() { + return "a"; +} +std::string ratio_string::symbol() { + return "f"; +} +std::string ratio_string::symbol() { + return "p"; +} +std::string ratio_string::symbol() { + return "n"; +} +std::string ratio_string::symbol() { + return "u"; +} +std::string ratio_string::symbol() { + return "m"; +} + +} // end namespace Catch + +#if defined(__clang__) +#pragma clang diagnostic pop +#endif + +// end catch_tostring.cpp +// start catch_totals.cpp + +namespace Catch { + +Counts Counts::operator-(Counts const &other) const { + Counts diff; + diff.passed = passed - other.passed; + diff.failed = failed - other.failed; + diff.failedButOk = failedButOk - other.failedButOk; + return diff; +} + +Counts &Counts::operator+=(Counts const &other) { + passed += other.passed; + failed += other.failed; + failedButOk += other.failedButOk; + return *this; +} + +std::size_t Counts::total() const { + return passed + failed + failedButOk; +} +bool Counts::allPassed() const { + return failed == 0 && failedButOk == 0; +} +bool Counts::allOk() const { + return failed == 0; +} + +Totals Totals::operator-(Totals const &other) const { + Totals diff; + diff.assertions = assertions - other.assertions; + diff.testCases = testCases - other.testCases; + return diff; +} + +Totals &Totals::operator+=(Totals const &other) { + assertions += other.assertions; + testCases += other.testCases; + return *this; +} + +Totals Totals::delta(Totals const &prevTotals) const { + Totals diff = *this - prevTotals; + if (diff.assertions.failed > 0) + ++diff.testCases.failed; + else if (diff.assertions.failedButOk > 0) + ++diff.testCases.failedButOk; + else + ++diff.testCases.passed; + return diff; +} + +} // namespace Catch +// end catch_totals.cpp +// start catch_uncaught_exceptions.cpp + +#include + +namespace Catch { +bool uncaught_exceptions() { +#if defined(CATCH_CONFIG_CPP17_UNCAUGHT_EXCEPTIONS) + return std::uncaught_exceptions() > 0; +#else + return std::uncaught_exception(); +#endif +} +} // end namespace Catch +// end catch_uncaught_exceptions.cpp +// start catch_version.cpp + +#include + +namespace Catch { + +Version::Version(unsigned int _majorVersion, unsigned int _minorVersion, unsigned int _patchNumber, + char const *const _branchName, unsigned int _buildNumber) + : majorVersion(_majorVersion), minorVersion(_minorVersion), patchNumber(_patchNumber), branchName(_branchName), + buildNumber(_buildNumber) { +} + +std::ostream &operator<<(std::ostream &os, Version const &version) { + os << version.majorVersion << '.' << version.minorVersion << '.' << version.patchNumber; + // branchName is never null -> 0th char is \0 if it is empty + if (version.branchName[0]) { + os << '-' << version.branchName << '.' << version.buildNumber; + } + return os; +} + +Version const &libraryVersion() { + static Version version(2, 2, 3, "", 0); + return version; +} + +} // namespace Catch +// end catch_version.cpp +// start catch_wildcard_pattern.cpp + +#include + +namespace Catch { + +WildcardPattern::WildcardPattern(std::string const &pattern, CaseSensitive::Choice caseSensitivity) + : m_caseSensitivity(caseSensitivity), m_pattern(adjustCase(pattern)) { + if (startsWith(m_pattern, '*')) { + m_pattern = m_pattern.substr(1); + m_wildcard = WildcardAtStart; + } + if (endsWith(m_pattern, '*')) { + m_pattern = m_pattern.substr(0, m_pattern.size() - 1); + m_wildcard = static_cast(m_wildcard | WildcardAtEnd); + } +} + +bool WildcardPattern::matches(std::string const &str) const { + switch (m_wildcard) { + case NoWildcard: + return m_pattern == adjustCase(str); + case WildcardAtStart: + return endsWith(adjustCase(str), m_pattern); + case WildcardAtEnd: + return startsWith(adjustCase(str), m_pattern); + case WildcardAtBothEnds: + return contains(adjustCase(str), m_pattern); + default: + CATCH_INTERNAL_ERROR("Unknown enum"); + } +} + +std::string WildcardPattern::adjustCase(std::string const &str) const { + return m_caseSensitivity == CaseSensitive::No ? toLower(str) : str; +} +} // namespace Catch +// end catch_wildcard_pattern.cpp +// start catch_xmlwriter.cpp + +#include + +using uchar = unsigned char; + +namespace Catch { + +namespace { + +size_t trailingBytes(unsigned char c) { + if ((c & 0xE0) == 0xC0) { + return 2; + } + if ((c & 0xF0) == 0xE0) { + return 3; + } + if ((c & 0xF8) == 0xF0) { + return 4; + } + CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered"); +} + +uint32_t headerValue(unsigned char c) { + if ((c & 0xE0) == 0xC0) { + return c & 0x1F; + } + if ((c & 0xF0) == 0xE0) { + return c & 0x0F; + } + if ((c & 0xF8) == 0xF0) { + return c & 0x07; + } + CATCH_INTERNAL_ERROR("Invalid multibyte utf-8 start byte encountered"); +} + +void hexEscapeChar(std::ostream &os, unsigned char c) { + os << "\\x" << std::uppercase << std::hex << std::setfill('0') << std::setw(2) << static_cast(c); +} + +} // anonymous namespace + +XmlEncode::XmlEncode(std::string const &str, ForWhat forWhat) : m_str(str), m_forWhat(forWhat) { +} + +void XmlEncode::encodeTo(std::ostream &os) const { + // Apostrophe escaping not necessary if we always use " to write attributes + // (see: http://www.w3.org/TR/xml/#syntax) + + for (std::size_t idx = 0; idx < m_str.size(); ++idx) { + uchar c = m_str[idx]; + switch (c) { + case '<': + os << "<"; + break; + case '&': + os << "&"; + break; + + case '>': + // See: http://www.w3.org/TR/xml/#syntax + if (idx > 2 && m_str[idx - 1] == ']' && m_str[idx - 2] == ']') + os << ">"; + else + os << c; + break; + + case '\"': + if (m_forWhat == ForAttributes) + os << """; + else + os << c; + break; + + default: + // Check for control characters and invalid utf-8 + + // Escape control characters in standard ascii + // see http://stackoverflow.com/questions/404107/why-are-control-characters-illegal-in-xml-1-0 + if (c < 0x09 || (c > 0x0D && c < 0x20) || c == 0x7F) { + hexEscapeChar(os, c); + break; + } + + // Plain ASCII: Write it to stream + if (c < 0x7F) { + os << c; + break; + } + + // UTF-8 territory + // Check if the encoding is valid and if it is not, hex escape bytes. + // Important: We do not check the exact decoded values for validity, only the encoding format + // First check that this bytes is a valid lead byte: + // This means that it is not encoded as 1111 1XXX + // Or as 10XX XXXX + if (c < 0xC0 || c >= 0xF8) { + hexEscapeChar(os, c); + break; + } + + auto encBytes = trailingBytes(c); + // Are there enough bytes left to avoid accessing out-of-bounds memory? + if (idx + encBytes - 1 >= m_str.size()) { + hexEscapeChar(os, c); + break; + } + // The header is valid, check data + // The next encBytes bytes must together be a valid utf-8 + // This means: bitpattern 10XX XXXX and the extracted value is sane (ish) + bool valid = true; + uint32_t value = headerValue(c); + for (std::size_t n = 1; n < encBytes; ++n) { + uchar nc = m_str[idx + n]; + valid &= ((nc & 0xC0) == 0x80); + value = (value << 6) | (nc & 0x3F); + } + + if ( + // Wrong bit pattern of following bytes + (!valid) || + // Overlong encodings + (value < 0x80) || (0x80 <= value && value < 0x800 && encBytes > 2) || + (0x800 < value && value < 0x10000 && encBytes > 3) || + // Encoded value out of range + (value >= 0x110000)) { + hexEscapeChar(os, c); + break; + } + + // If we got here, this is in fact a valid(ish) utf-8 sequence + for (std::size_t n = 0; n < encBytes; ++n) { + os << m_str[idx + n]; + } + idx += encBytes - 1; + break; + } + } +} + +std::ostream &operator<<(std::ostream &os, XmlEncode const &xmlEncode) { + xmlEncode.encodeTo(os); + return os; +} + +XmlWriter::ScopedElement::ScopedElement(XmlWriter *writer) : m_writer(writer) { +} + +XmlWriter::ScopedElement::ScopedElement(ScopedElement &&other) noexcept : m_writer(other.m_writer) { + other.m_writer = nullptr; +} +XmlWriter::ScopedElement &XmlWriter::ScopedElement::operator=(ScopedElement &&other) noexcept { + if (m_writer) { + m_writer->endElement(); + } + m_writer = other.m_writer; + other.m_writer = nullptr; + return *this; +} + +XmlWriter::ScopedElement::~ScopedElement() { + if (m_writer) + m_writer->endElement(); +} + +XmlWriter::ScopedElement &XmlWriter::ScopedElement::writeText(std::string const &text, bool indent) { + m_writer->writeText(text, indent); + return *this; +} + +XmlWriter::XmlWriter(std::ostream &os) : m_os(os) { + writeDeclaration(); +} + +XmlWriter::~XmlWriter() { + while (!m_tags.empty()) + endElement(); +} + +XmlWriter &XmlWriter::startElement(std::string const &name) { + ensureTagClosed(); + newlineIfNecessary(); + m_os << m_indent << '<' << name; + m_tags.push_back(name); + m_indent += " "; + m_tagIsOpen = true; + return *this; +} + +XmlWriter::ScopedElement XmlWriter::scopedElement(std::string const &name) { + ScopedElement scoped(this); + startElement(name); + return scoped; +} + +XmlWriter &XmlWriter::endElement() { + newlineIfNecessary(); + m_indent = m_indent.substr(0, m_indent.size() - 2); + if (m_tagIsOpen) { + m_os << "/>"; + m_tagIsOpen = false; + } else { + m_os << m_indent << ""; + } + m_os << std::endl; + m_tags.pop_back(); + return *this; +} + +XmlWriter &XmlWriter::writeAttribute(std::string const &name, std::string const &attribute) { + if (!name.empty() && !attribute.empty()) + m_os << ' ' << name << "=\"" << XmlEncode(attribute, XmlEncode::ForAttributes) << '"'; + return *this; +} + +XmlWriter &XmlWriter::writeAttribute(std::string const &name, bool attribute) { + m_os << ' ' << name << "=\"" << (attribute ? "true" : "false") << '"'; + return *this; +} + +XmlWriter &XmlWriter::writeText(std::string const &text, bool indent) { + if (!text.empty()) { + bool tagWasOpen = m_tagIsOpen; + ensureTagClosed(); + if (tagWasOpen && indent) + m_os << m_indent; + m_os << XmlEncode(text); + m_needsNewline = true; + } + return *this; +} + +XmlWriter &XmlWriter::writeComment(std::string const &text) { + ensureTagClosed(); + m_os << m_indent << ""; + m_needsNewline = true; + return *this; +} + +void XmlWriter::writeStylesheetRef(std::string const &url) { + m_os << "\n"; +} + +XmlWriter &XmlWriter::writeBlankLine() { + ensureTagClosed(); + m_os << '\n'; + return *this; +} + +void XmlWriter::ensureTagClosed() { + if (m_tagIsOpen) { + m_os << ">" << std::endl; + m_tagIsOpen = false; + } +} + +void XmlWriter::writeDeclaration() { + m_os << "\n"; +} + +void XmlWriter::newlineIfNecessary() { + if (m_needsNewline) { + m_os << std::endl; + m_needsNewline = false; + } +} +} // namespace Catch +// end catch_xmlwriter.cpp +// start catch_reporter_bases.cpp + +#include +#include +#include +#include +#include + +namespace Catch { +void prepareExpandedExpression(AssertionResult &result) { + result.getExpandedExpression(); +} + +// Because formatting using c++ streams is stateful, drop down to C is required +// Alternatively we could use stringstream, but its performance is... not good. +std::string getFormattedDuration(double duration) { + // Max exponent + 1 is required to represent the whole part + // + 1 for decimal point + // + 3 for the 3 decimal places + // + 1 for null terminator + const std::size_t maxDoubleSize = DBL_MAX_10_EXP + 1 + 1 + 3 + 1; + char buffer[maxDoubleSize]; + + // Save previous errno, to prevent sprintf from overwriting it + ErrnoGuard guard; +#ifdef _MSC_VER + sprintf_s(buffer, "%.3f", duration); +#else + sprintf(buffer, "%.3f", duration); +#endif + return std::string(buffer); +} + +TestEventListenerBase::TestEventListenerBase(ReporterConfig const &_config) : StreamingReporterBase(_config) { +} + +void TestEventListenerBase::assertionStarting(AssertionInfo const &) { +} + +bool TestEventListenerBase::assertionEnded(AssertionStats const &) { + return false; +} + +} // end namespace Catch +// end catch_reporter_bases.cpp +// start catch_reporter_compact.cpp + +namespace { + +#ifdef CATCH_PLATFORM_MAC +const char *failedString() { + return "FAILED"; +} +const char *passedString() { + return "PASSED"; +} +#else +const char *failedString() { + return "failed"; +} +const char *passedString() { + return "passed"; +} +#endif + +// Colour::LightGrey +Catch::Colour::Code dimColour() { + return Catch::Colour::FileName; +} + +std::string bothOrAll(std::size_t count) { + return count == 1 ? std::string() : count == 2 ? "both " : "all "; +} + +} // anon namespace + +namespace Catch { +namespace { +// Colour, message variants: +// - white: No tests ran. +// - red: Failed [both/all] N test cases, failed [both/all] M assertions. +// - white: Passed [both/all] N test cases (no assertions). +// - red: Failed N tests cases, failed M assertions. +// - green: Passed [both/all] N tests cases with M assertions. +void printTotals(std::ostream &out, const Totals &totals) { + if (totals.testCases.total() == 0) { + out << "No tests ran."; + } else if (totals.testCases.failed == totals.testCases.total()) { + Colour colour(Colour::ResultError); + const std::string qualify_assertions_failed = + totals.assertions.failed == totals.assertions.total() ? bothOrAll(totals.assertions.failed) : std::string(); + out << "Failed " << bothOrAll(totals.testCases.failed) << pluralise(totals.testCases.failed, "test case") + << ", " + "failed " + << qualify_assertions_failed << pluralise(totals.assertions.failed, "assertion") << '.'; + } else if (totals.assertions.total() == 0) { + out << "Passed " << bothOrAll(totals.testCases.total()) << pluralise(totals.testCases.total(), "test case") + << " (no assertions)."; + } else if (totals.assertions.failed) { + Colour colour(Colour::ResultError); + out << "Failed " << pluralise(totals.testCases.failed, "test case") + << ", " + "failed " + << pluralise(totals.assertions.failed, "assertion") << '.'; + } else { + Colour colour(Colour::ResultSuccess); + out << "Passed " << bothOrAll(totals.testCases.passed) << pluralise(totals.testCases.passed, "test case") + << " with " << pluralise(totals.assertions.passed, "assertion") << '.'; + } +} + +// Implementation of CompactReporter formatting +class AssertionPrinter { +public: + AssertionPrinter &operator=(AssertionPrinter const &) = delete; + AssertionPrinter(AssertionPrinter const &) = delete; + AssertionPrinter(std::ostream &_stream, AssertionStats const &_stats, bool _printInfoMessages) + : stream(_stream), result(_stats.assertionResult), messages(_stats.infoMessages), + itMessage(_stats.infoMessages.begin()), printInfoMessages(_printInfoMessages) { + } + + void print() { + printSourceInfo(); + + itMessage = messages.begin(); + + switch (result.getResultType()) { + case ResultWas::Ok: + printResultType(Colour::ResultSuccess, passedString()); + printOriginalExpression(); + printReconstructedExpression(); + if (!result.hasExpression()) + printRemainingMessages(Colour::None); + else + printRemainingMessages(); + break; + case ResultWas::ExpressionFailed: + if (result.isOk()) + printResultType(Colour::ResultSuccess, failedString() + std::string(" - but was ok")); + else + printResultType(Colour::Error, failedString()); + printOriginalExpression(); + printReconstructedExpression(); + printRemainingMessages(); + break; + case ResultWas::ThrewException: + printResultType(Colour::Error, failedString()); + printIssue("unexpected exception with message:"); + printMessage(); + printExpressionWas(); + printRemainingMessages(); + break; + case ResultWas::FatalErrorCondition: + printResultType(Colour::Error, failedString()); + printIssue("fatal error condition with message:"); + printMessage(); + printExpressionWas(); + printRemainingMessages(); + break; + case ResultWas::DidntThrowException: + printResultType(Colour::Error, failedString()); + printIssue("expected exception, got none"); + printExpressionWas(); + printRemainingMessages(); + break; + case ResultWas::Info: + printResultType(Colour::None, "info"); + printMessage(); + printRemainingMessages(); + break; + case ResultWas::Warning: + printResultType(Colour::None, "warning"); + printMessage(); + printRemainingMessages(); + break; + case ResultWas::ExplicitFailure: + printResultType(Colour::Error, failedString()); + printIssue("explicitly"); + printRemainingMessages(Colour::None); + break; + // These cases are here to prevent compiler warnings + case ResultWas::Unknown: + case ResultWas::FailureBit: + case ResultWas::Exception: + printResultType(Colour::Error, "** internal error **"); + break; + } + } + +private: + void printSourceInfo() const { + Colour colourGuard(Colour::FileName); + stream << result.getSourceInfo() << ':'; + } + + void printResultType(Colour::Code colour, std::string const &passOrFail) const { + if (!passOrFail.empty()) { + { + Colour colourGuard(colour); + stream << ' ' << passOrFail; + } + stream << ':'; + } + } + + void printIssue(std::string const &issue) const { + stream << ' ' << issue; + } + + void printExpressionWas() { + if (result.hasExpression()) { + stream << ';'; + { + Colour colour(dimColour()); + stream << " expression was:"; + } + printOriginalExpression(); + } + } + + void printOriginalExpression() const { + if (result.hasExpression()) { + stream << ' ' << result.getExpression(); + } + } + + void printReconstructedExpression() const { + if (result.hasExpandedExpression()) { + { + Colour colour(dimColour()); + stream << " for: "; + } + stream << result.getExpandedExpression(); + } + } + + void printMessage() { + if (itMessage != messages.end()) { + stream << " '" << itMessage->message << '\''; + ++itMessage; + } + } + + void printRemainingMessages(Colour::Code colour = dimColour()) { + if (itMessage == messages.end()) + return; + + // using messages.end() directly yields (or auto) compilation error: + std::vector::const_iterator itEnd = messages.end(); + const std::size_t N = static_cast(std::distance(itMessage, itEnd)); + + { + Colour colourGuard(colour); + stream << " with " << pluralise(N, "message") << ':'; + } + + for (; itMessage != itEnd;) { + // If this assertion is a warning ignore any INFO messages + if (printInfoMessages || itMessage->type != ResultWas::Info) { + stream << " '" << itMessage->message << '\''; + if (++itMessage != itEnd) { + Colour colourGuard(dimColour()); + stream << " and"; + } + } + } + } + +private: + std::ostream &stream; + AssertionResult const &result; + std::vector messages; + std::vector::const_iterator itMessage; + bool printInfoMessages; +}; + +} // namespace + +std::string CompactReporter::getDescription() { + return "Reports test results on a single line, suitable for IDEs"; +} + +ReporterPreferences CompactReporter::getPreferences() const { + ReporterPreferences prefs; + prefs.shouldRedirectStdOut = false; + return prefs; +} + +void CompactReporter::noMatchingTestCases(std::string const &spec) { + stream << "No test cases matched '" << spec << '\'' << std::endl; +} + +void CompactReporter::assertionStarting(AssertionInfo const &) { +} + +bool CompactReporter::assertionEnded(AssertionStats const &_assertionStats) { + AssertionResult const &result = _assertionStats.assertionResult; + + bool printInfoMessages = true; + + // Drop out if result was successful and we're not printing those + if (!m_config->includeSuccessfulResults() && result.isOk()) { + if (result.getResultType() != ResultWas::Warning) + return false; + printInfoMessages = false; + } + + AssertionPrinter printer(stream, _assertionStats, printInfoMessages); + printer.print(); + + stream << std::endl; + return true; +} + +void CompactReporter::sectionEnded(SectionStats const &_sectionStats) { + if (m_config->showDurations() == ShowDurations::Always) { + stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name + << std::endl; + } +} + +void CompactReporter::testRunEnded(TestRunStats const &_testRunStats) { + printTotals(stream, _testRunStats.totals); + stream << '\n' << std::endl; + StreamingReporterBase::testRunEnded(_testRunStats); +} + +CompactReporter::~CompactReporter() { +} + +CATCH_REGISTER_REPORTER("compact", CompactReporter) + +} // end namespace Catch +// end catch_reporter_compact.cpp +// start catch_reporter_console.cpp + +#include +#include + +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning( \ + disable : 4061) // Not all labels are EXPLICITLY handled in switch \ + // Note that 4062 (not all labels are handled \ + // and default is missing) is enabled +#endif + +namespace Catch { + +namespace { + +// Formatter impl for ConsoleReporter +class ConsoleAssertionPrinter { +public: + ConsoleAssertionPrinter &operator=(ConsoleAssertionPrinter const &) = delete; + ConsoleAssertionPrinter(ConsoleAssertionPrinter const &) = delete; + ConsoleAssertionPrinter(std::ostream &_stream, AssertionStats const &_stats, bool _printInfoMessages) + : stream(_stream), stats(_stats), result(_stats.assertionResult), colour(Colour::None), + message(result.getMessage()), messages(_stats.infoMessages), printInfoMessages(_printInfoMessages) { + switch (result.getResultType()) { + case ResultWas::Ok: + colour = Colour::Success; + passOrFail = "PASSED"; + //if( result.hasMessage() ) + if (_stats.infoMessages.size() == 1) + messageLabel = "with message"; + if (_stats.infoMessages.size() > 1) + messageLabel = "with messages"; + break; + case ResultWas::ExpressionFailed: + if (result.isOk()) { + colour = Colour::Success; + passOrFail = "FAILED - but was ok"; + } else { + colour = Colour::Error; + passOrFail = "FAILED"; + } + if (_stats.infoMessages.size() == 1) + messageLabel = "with message"; + if (_stats.infoMessages.size() > 1) + messageLabel = "with messages"; + break; + case ResultWas::ThrewException: + colour = Colour::Error; + passOrFail = "FAILED"; + messageLabel = "due to unexpected exception with "; + if (_stats.infoMessages.size() == 1) + messageLabel += "message"; + if (_stats.infoMessages.size() > 1) + messageLabel += "messages"; + break; + case ResultWas::FatalErrorCondition: + colour = Colour::Error; + passOrFail = "FAILED"; + messageLabel = "due to a fatal error condition"; + break; + case ResultWas::DidntThrowException: + colour = Colour::Error; + passOrFail = "FAILED"; + messageLabel = "because no exception was thrown where one was expected"; + break; + case ResultWas::Info: + messageLabel = "info"; + break; + case ResultWas::Warning: + messageLabel = "warning"; + break; + case ResultWas::ExplicitFailure: + passOrFail = "FAILED"; + colour = Colour::Error; + if (_stats.infoMessages.size() == 1) + messageLabel = "explicitly with message"; + if (_stats.infoMessages.size() > 1) + messageLabel = "explicitly with messages"; + break; + // These cases are here to prevent compiler warnings + case ResultWas::Unknown: + case ResultWas::FailureBit: + case ResultWas::Exception: + passOrFail = "** internal error **"; + colour = Colour::Error; + break; + } + } + + void print() const { + printSourceInfo(); + if (stats.totals.assertions.total() > 0) { + if (result.isOk()) + stream << '\n'; + printResultType(); + printOriginalExpression(); + printReconstructedExpression(); + } else { + stream << '\n'; + } + printMessage(); + } + +private: + void printResultType() const { + if (!passOrFail.empty()) { + Colour colourGuard(colour); + stream << passOrFail << ":\n"; + } + } + void printOriginalExpression() const { + if (result.hasExpression()) { + Colour colourGuard(Colour::OriginalExpression); + stream << " "; + stream << result.getExpressionInMacro(); + stream << '\n'; + } + } + void printReconstructedExpression() const { + if (result.hasExpandedExpression()) { + stream << "with expansion:\n"; + Colour colourGuard(Colour::ReconstructedExpression); + stream << Column(result.getExpandedExpression()).indent(2) << '\n'; + } + } + void printMessage() const { + if (!messageLabel.empty()) + stream << messageLabel << ':' << '\n'; + for (auto const &msg : messages) { + // If this assertion is a warning ignore any INFO messages + if (printInfoMessages || msg.type != ResultWas::Info) + stream << Column(msg.message).indent(2) << '\n'; + } + } + void printSourceInfo() const { + Colour colourGuard(Colour::FileName); + stream << result.getSourceInfo() << ": "; + } + + std::ostream &stream; + AssertionStats const &stats; + AssertionResult const &result; + Colour::Code colour; + std::string passOrFail; + std::string messageLabel; + std::string message; + std::vector messages; + bool printInfoMessages; +}; + +std::size_t makeRatio(std::size_t number, std::size_t total) { + std::size_t ratio = total > 0 ? CATCH_CONFIG_CONSOLE_WIDTH * number / total : 0; + return (ratio == 0 && number > 0) ? 1 : ratio; +} + +std::size_t &findMax(std::size_t &i, std::size_t &j, std::size_t &k) { + if (i > j && i > k) + return i; + else if (j > k) + return j; + else + return k; +} + +struct ColumnInfo { + enum Justification { Left, Right }; + std::string name; + int width; + Justification justification; +}; +struct ColumnBreak {}; +struct RowBreak {}; + +class Duration { + enum class Unit { Auto, Nanoseconds, Microseconds, Milliseconds, Seconds, Minutes }; + static const uint64_t s_nanosecondsInAMicrosecond = 1000; + static const uint64_t s_nanosecondsInAMillisecond = 1000 * s_nanosecondsInAMicrosecond; + static const uint64_t s_nanosecondsInASecond = 1000 * s_nanosecondsInAMillisecond; + static const uint64_t s_nanosecondsInAMinute = 60 * s_nanosecondsInASecond; + + uint64_t m_inNanoseconds; + Unit m_units; + +public: + explicit Duration(uint64_t inNanoseconds, Unit units = Unit::Auto) : m_inNanoseconds(inNanoseconds), m_units(units) { + if (m_units == Unit::Auto) { + if (m_inNanoseconds < s_nanosecondsInAMicrosecond) + m_units = Unit::Nanoseconds; + else if (m_inNanoseconds < s_nanosecondsInAMillisecond) + m_units = Unit::Microseconds; + else if (m_inNanoseconds < s_nanosecondsInASecond) + m_units = Unit::Milliseconds; + else if (m_inNanoseconds < s_nanosecondsInAMinute) + m_units = Unit::Seconds; + else + m_units = Unit::Minutes; + } + } + + auto value() const -> double { + switch (m_units) { + case Unit::Microseconds: + return m_inNanoseconds / static_cast(s_nanosecondsInAMicrosecond); + case Unit::Milliseconds: + return m_inNanoseconds / static_cast(s_nanosecondsInAMillisecond); + case Unit::Seconds: + return m_inNanoseconds / static_cast(s_nanosecondsInASecond); + case Unit::Minutes: + return m_inNanoseconds / static_cast(s_nanosecondsInAMinute); + default: + return static_cast(m_inNanoseconds); + } + } + auto unitsAsString() const -> std::string { + switch (m_units) { + case Unit::Nanoseconds: + return "ns"; + case Unit::Microseconds: + return "µs"; + case Unit::Milliseconds: + return "ms"; + case Unit::Seconds: + return "s"; + case Unit::Minutes: + return "m"; + default: + return "** internal error **"; + } + } + friend auto operator<<(std::ostream &os, Duration const &duration) -> std::ostream & { + return os << duration.value() << " " << duration.unitsAsString(); + } +}; +} // namespace + +class TablePrinter { + std::ostream &m_os; + std::vector m_columnInfos; + std::ostringstream m_oss; + int m_currentColumn = -1; + bool m_isOpen = false; + +public: + TablePrinter(std::ostream &os, std::vector columnInfos) + : m_os(os), m_columnInfos(std::move(columnInfos)) { + } + + auto columnInfos() const -> std::vector const & { + return m_columnInfos; + } + + void open() { + if (!m_isOpen) { + m_isOpen = true; + *this << RowBreak(); + for (auto const &info : m_columnInfos) + *this << info.name << ColumnBreak(); + *this << RowBreak(); + m_os << Catch::getLineOfChars<'-'>() << "\n"; + } + } + void close() { + if (m_isOpen) { + *this << RowBreak(); + m_os << std::endl; + m_isOpen = false; + } + } + + template friend TablePrinter &operator<<(TablePrinter &tp, T const &value) { + tp.m_oss << value; + return tp; + } + + friend TablePrinter &operator<<(TablePrinter &tp, ColumnBreak) { + auto colStr = tp.m_oss.str(); + // This takes account of utf8 encodings + auto strSize = Catch::StringRef(colStr).numberOfCharacters(); + tp.m_oss.str(""); + tp.open(); + if (tp.m_currentColumn == static_cast(tp.m_columnInfos.size() - 1)) { + tp.m_currentColumn = -1; + tp.m_os << "\n"; + } + tp.m_currentColumn++; + + auto colInfo = tp.m_columnInfos[tp.m_currentColumn]; + auto padding = (strSize + 2 < static_cast(colInfo.width)) + ? std::string(colInfo.width - (strSize + 2), ' ') + : std::string(); + if (colInfo.justification == ColumnInfo::Left) + tp.m_os << colStr << padding << " "; + else + tp.m_os << padding << colStr << " "; + return tp; + } + + friend TablePrinter &operator<<(TablePrinter &tp, RowBreak) { + if (tp.m_currentColumn > 0) { + tp.m_os << "\n"; + tp.m_currentColumn = -1; + } + return tp; + } +}; + +ConsoleReporter::ConsoleReporter(ReporterConfig const &config) + : StreamingReporterBase(config), + m_tablePrinter( + new TablePrinter(config.stream(), {{"benchmark name", CATCH_CONFIG_CONSOLE_WIDTH - 32, ColumnInfo::Left}, + {"iters", 8, ColumnInfo::Right}, + {"elapsed ns", 14, ColumnInfo::Right}, + {"average", 14, ColumnInfo::Right}})) { +} +ConsoleReporter::~ConsoleReporter() = default; + +std::string ConsoleReporter::getDescription() { + return "Reports test results as plain lines of text"; +} + +void ConsoleReporter::noMatchingTestCases(std::string const &spec) { + stream << "No test cases matched '" << spec << '\'' << std::endl; +} + +void ConsoleReporter::assertionStarting(AssertionInfo const &) { +} + +bool ConsoleReporter::assertionEnded(AssertionStats const &_assertionStats) { + AssertionResult const &result = _assertionStats.assertionResult; + + bool includeResults = m_config->includeSuccessfulResults() || !result.isOk(); + + // Drop out if result was successful but we're not printing them. + if (!includeResults && result.getResultType() != ResultWas::Warning) + return false; + + lazyPrint(); + + ConsoleAssertionPrinter printer(stream, _assertionStats, includeResults); + printer.print(); + stream << std::endl; + return true; +} + +void ConsoleReporter::sectionStarting(SectionInfo const &_sectionInfo) { + m_headerPrinted = false; + StreamingReporterBase::sectionStarting(_sectionInfo); +} +void ConsoleReporter::sectionEnded(SectionStats const &_sectionStats) { + m_tablePrinter->close(); + if (_sectionStats.missingAssertions) { + lazyPrint(); + Colour colour(Colour::ResultError); + if (m_sectionStack.size() > 1) + stream << "\nNo assertions in section"; + else + stream << "\nNo assertions in test case"; + stream << " '" << _sectionStats.sectionInfo.name << "'\n" << std::endl; + } + if (m_config->showDurations() == ShowDurations::Always) { + stream << getFormattedDuration(_sectionStats.durationInSeconds) << " s: " << _sectionStats.sectionInfo.name + << std::endl; + } + if (m_headerPrinted) { + m_headerPrinted = false; + } + StreamingReporterBase::sectionEnded(_sectionStats); +} + +void ConsoleReporter::benchmarkStarting(BenchmarkInfo const &info) { + lazyPrintWithoutClosingBenchmarkTable(); + + auto nameCol = Column(info.name).width(static_cast(m_tablePrinter->columnInfos()[0].width - 2)); + + bool firstLine = true; + for (auto line : nameCol) { + if (!firstLine) + (*m_tablePrinter) << ColumnBreak() << ColumnBreak() << ColumnBreak(); + else + firstLine = false; + + (*m_tablePrinter) << line << ColumnBreak(); + } +} +void ConsoleReporter::benchmarkEnded(BenchmarkStats const &stats) { + Duration average(stats.elapsedTimeInNanoseconds / stats.iterations); + (*m_tablePrinter) << stats.iterations << ColumnBreak() << stats.elapsedTimeInNanoseconds << ColumnBreak() << average + << ColumnBreak(); +} + +void ConsoleReporter::testCaseEnded(TestCaseStats const &_testCaseStats) { + m_tablePrinter->close(); + StreamingReporterBase::testCaseEnded(_testCaseStats); + m_headerPrinted = false; +} +void ConsoleReporter::testGroupEnded(TestGroupStats const &_testGroupStats) { + if (currentGroupInfo.used) { + printSummaryDivider(); + stream << "Summary for group '" << _testGroupStats.groupInfo.name << "':\n"; + printTotals(_testGroupStats.totals); + stream << '\n' << std::endl; + } + StreamingReporterBase::testGroupEnded(_testGroupStats); +} +void ConsoleReporter::testRunEnded(TestRunStats const &_testRunStats) { + printTotalsDivider(_testRunStats.totals); + printTotals(_testRunStats.totals); + stream << std::endl; + StreamingReporterBase::testRunEnded(_testRunStats); +} + +void ConsoleReporter::lazyPrint() { + + m_tablePrinter->close(); + lazyPrintWithoutClosingBenchmarkTable(); +} + +void ConsoleReporter::lazyPrintWithoutClosingBenchmarkTable() { + + if (!currentTestRunInfo.used) + lazyPrintRunInfo(); + if (!currentGroupInfo.used) + lazyPrintGroupInfo(); + + if (!m_headerPrinted) { + printTestCaseAndSectionHeader(); + m_headerPrinted = true; + } +} +void ConsoleReporter::lazyPrintRunInfo() { + stream << '\n' << getLineOfChars<'~'>() << '\n'; + Colour colour(Colour::SecondaryText); + stream << currentTestRunInfo->name << " is a Catch v" << libraryVersion() << " host application.\n" + << "Run with -? for options\n\n"; + + if (m_config->rngSeed() != 0) + stream << "Randomness seeded to: " << m_config->rngSeed() << "\n\n"; + + currentTestRunInfo.used = true; +} +void ConsoleReporter::lazyPrintGroupInfo() { + if (!currentGroupInfo->name.empty() && currentGroupInfo->groupsCounts > 1) { + printClosedHeader("Group: " + currentGroupInfo->name); + currentGroupInfo.used = true; + } +} +void ConsoleReporter::printTestCaseAndSectionHeader() { + assert(!m_sectionStack.empty()); + printOpenHeader(currentTestCaseInfo->name); + + if (m_sectionStack.size() > 1) { + Colour colourGuard(Colour::Headers); + + auto it = m_sectionStack.begin() + 1, // Skip first section (test case) + itEnd = m_sectionStack.end(); + for (; it != itEnd; ++it) + printHeaderString(it->name, 2); + } + + SourceLineInfo lineInfo = m_sectionStack.back().lineInfo; + + if (!lineInfo.empty()) { + stream << getLineOfChars<'-'>() << '\n'; + Colour colourGuard(Colour::FileName); + stream << lineInfo << '\n'; + } + stream << getLineOfChars<'.'>() << '\n' << std::endl; +} + +void ConsoleReporter::printClosedHeader(std::string const &_name) { + printOpenHeader(_name); + stream << getLineOfChars<'.'>() << '\n'; +} +void ConsoleReporter::printOpenHeader(std::string const &_name) { + stream << getLineOfChars<'-'>() << '\n'; + { + Colour colourGuard(Colour::Headers); + printHeaderString(_name); + } +} + +// if string has a : in first line will set indent to follow it on +// subsequent lines +void ConsoleReporter::printHeaderString(std::string const &_string, std::size_t indent) { + std::size_t i = _string.find(": "); + if (i != std::string::npos) + i += 2; + else + i = 0; + stream << Column(_string).indent(indent + i).initialIndent(indent) << '\n'; +} + +struct SummaryColumn { + + SummaryColumn(std::string _label, Colour::Code _colour) : label(std::move(_label)), colour(_colour) { + } + SummaryColumn addRow(std::size_t count) { + ReusableStringStream rss; + rss << count; + std::string row = rss.str(); + for (auto &oldRow : rows) { + while (oldRow.size() < row.size()) + oldRow = ' ' + oldRow; + while (oldRow.size() > row.size()) + row = ' ' + row; + } + rows.push_back(row); + return *this; + } + + std::string label; + Colour::Code colour; + std::vector rows; +}; + +void ConsoleReporter::printTotals(Totals const &totals) { + if (totals.testCases.total() == 0) { + stream << Colour(Colour::Warning) << "No tests ran\n"; + } else if (totals.assertions.total() > 0 && totals.testCases.allPassed()) { + stream << Colour(Colour::ResultSuccess) << "All tests passed"; + stream << " (" << pluralise(totals.assertions.passed, "assertion") << " in " + << pluralise(totals.testCases.passed, "test case") << ')' << '\n'; + } else { + + std::vector columns; + columns.push_back( + SummaryColumn("", Colour::None).addRow(totals.testCases.total()).addRow(totals.assertions.total())); + columns.push_back( + SummaryColumn("passed", Colour::Success).addRow(totals.testCases.passed).addRow(totals.assertions.passed)); + columns.push_back( + SummaryColumn("failed", Colour::ResultError).addRow(totals.testCases.failed).addRow(totals.assertions.failed)); + columns.push_back(SummaryColumn("failed as expected", Colour::ResultExpectedFailure) + .addRow(totals.testCases.failedButOk) + .addRow(totals.assertions.failedButOk)); + + printSummaryRow("test cases", columns, 0); + printSummaryRow("assertions", columns, 1); + } +} +void ConsoleReporter::printSummaryRow(std::string const &label, std::vector const &cols, + std::size_t row) { + for (auto col : cols) { + std::string value = col.rows[row]; + if (col.label.empty()) { + stream << label << ": "; + if (value != "0") + stream << value; + else + stream << Colour(Colour::Warning) << "- none -"; + } else if (value != "0") { + stream << Colour(Colour::LightGrey) << " | "; + stream << Colour(col.colour) << value << ' ' << col.label; + } + } + stream << '\n'; +} + +void ConsoleReporter::printTotalsDivider(Totals const &totals) { + if (totals.testCases.total() > 0) { + std::size_t failedRatio = makeRatio(totals.testCases.failed, totals.testCases.total()); + std::size_t failedButOkRatio = makeRatio(totals.testCases.failedButOk, totals.testCases.total()); + std::size_t passedRatio = makeRatio(totals.testCases.passed, totals.testCases.total()); + while (failedRatio + failedButOkRatio + passedRatio < CATCH_CONFIG_CONSOLE_WIDTH - 1) + findMax(failedRatio, failedButOkRatio, passedRatio)++; + while (failedRatio + failedButOkRatio + passedRatio > CATCH_CONFIG_CONSOLE_WIDTH - 1) + findMax(failedRatio, failedButOkRatio, passedRatio)--; + + stream << Colour(Colour::Error) << std::string(failedRatio, '='); + stream << Colour(Colour::ResultExpectedFailure) << std::string(failedButOkRatio, '='); + if (totals.testCases.allPassed()) + stream << Colour(Colour::ResultSuccess) << std::string(passedRatio, '='); + else + stream << Colour(Colour::Success) << std::string(passedRatio, '='); + } else { + stream << Colour(Colour::Warning) << std::string(CATCH_CONFIG_CONSOLE_WIDTH - 1, '='); + } + stream << '\n'; +} +void ConsoleReporter::printSummaryDivider() { + stream << getLineOfChars<'-'>() << '\n'; +} + +CATCH_REGISTER_REPORTER("console", ConsoleReporter) + +} // end namespace Catch + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif +// end catch_reporter_console.cpp +// start catch_reporter_junit.cpp + +#include +#include +#include +#include + +namespace Catch { + +namespace { +std::string getCurrentTimestamp() { + // Beware, this is not reentrant because of backward compatibility issues + // Also, UTC only, again because of backward compatibility (%z is C++11) + time_t rawtime; + std::time(&rawtime); + auto const timeStampSize = sizeof("2017-01-16T17:06:45Z"); + +#ifdef _MSC_VER + std::tm timeInfo = {}; + gmtime_s(&timeInfo, &rawtime); +#else + std::tm *timeInfo; + timeInfo = std::gmtime(&rawtime); +#endif + + char timeStamp[timeStampSize]; + const char *const fmt = "%Y-%m-%dT%H:%M:%SZ"; + +#ifdef _MSC_VER + std::strftime(timeStamp, timeStampSize, fmt, &timeInfo); +#else + std::strftime(timeStamp, timeStampSize, fmt, timeInfo); +#endif + return std::string(timeStamp); +} + +std::string fileNameTag(const std::vector &tags) { + auto it = std::find_if(begin(tags), end(tags), [](std::string const &tag) { return tag.front() == '#'; }); + if (it != tags.end()) + return it->substr(1); + return std::string(); +} +} // anonymous namespace + +JunitReporter::JunitReporter(ReporterConfig const &_config) : CumulativeReporterBase(_config), xml(_config.stream()) { + m_reporterPrefs.shouldRedirectStdOut = true; +} + +JunitReporter::~JunitReporter() { +} + +std::string JunitReporter::getDescription() { + return "Reports test results in an XML format that looks like Ant's junitreport target"; +} + +void JunitReporter::noMatchingTestCases(std::string const & /*spec*/) { +} + +void JunitReporter::testRunStarting(TestRunInfo const &runInfo) { + CumulativeReporterBase::testRunStarting(runInfo); + xml.startElement("testsuites"); +} + +void JunitReporter::testGroupStarting(GroupInfo const &groupInfo) { + suiteTimer.start(); + stdOutForSuite.clear(); + stdErrForSuite.clear(); + unexpectedExceptions = 0; + CumulativeReporterBase::testGroupStarting(groupInfo); +} + +void JunitReporter::testCaseStarting(TestCaseInfo const &testCaseInfo) { + m_okToFail = testCaseInfo.okToFail(); +} + +bool JunitReporter::assertionEnded(AssertionStats const &assertionStats) { + if (assertionStats.assertionResult.getResultType() == ResultWas::ThrewException && !m_okToFail) + unexpectedExceptions++; + return CumulativeReporterBase::assertionEnded(assertionStats); +} + +void JunitReporter::testCaseEnded(TestCaseStats const &testCaseStats) { + stdOutForSuite += testCaseStats.stdOut; + stdErrForSuite += testCaseStats.stdErr; + CumulativeReporterBase::testCaseEnded(testCaseStats); +} + +void JunitReporter::testGroupEnded(TestGroupStats const &testGroupStats) { + double suiteTime = suiteTimer.getElapsedSeconds(); + CumulativeReporterBase::testGroupEnded(testGroupStats); + writeGroup(*m_testGroups.back(), suiteTime); +} + +void JunitReporter::testRunEndedCumulative() { + xml.endElement(); +} + +void JunitReporter::writeGroup(TestGroupNode const &groupNode, double suiteTime) { + XmlWriter::ScopedElement e = xml.scopedElement("testsuite"); + TestGroupStats const &stats = groupNode.value; + xml.writeAttribute("name", stats.groupInfo.name); + xml.writeAttribute("errors", unexpectedExceptions); + xml.writeAttribute("failures", stats.totals.assertions.failed - unexpectedExceptions); + xml.writeAttribute("tests", stats.totals.assertions.total()); + xml.writeAttribute("hostname", "tbd"); // !TBD + if (m_config->showDurations() == ShowDurations::Never) + xml.writeAttribute("time", ""); + else + xml.writeAttribute("time", suiteTime); + xml.writeAttribute("timestamp", getCurrentTimestamp()); + + // Write test cases + for (auto const &child : groupNode.children) + writeTestCase(*child); + + xml.scopedElement("system-out").writeText(trim(stdOutForSuite), false); + xml.scopedElement("system-err").writeText(trim(stdErrForSuite), false); +} + +void JunitReporter::writeTestCase(TestCaseNode const &testCaseNode) { + TestCaseStats const &stats = testCaseNode.value; + + // All test cases have exactly one section - which represents the + // test case itself. That section may have 0-n nested sections + assert(testCaseNode.children.size() == 1); + SectionNode const &rootSection = *testCaseNode.children.front(); + + std::string className = stats.testInfo.className; + + if (className.empty()) { + className = fileNameTag(stats.testInfo.tags); + if (className.empty()) + className = "global"; + } + + if (!m_config->name().empty()) + className = m_config->name() + "." + className; + + writeSection(className, "", rootSection); +} + +void JunitReporter::writeSection(std::string const &className, std::string const &rootName, + SectionNode const §ionNode) { + std::string name = trim(sectionNode.stats.sectionInfo.name); + if (!rootName.empty()) + name = rootName + '/' + name; + + if (!sectionNode.assertions.empty() || !sectionNode.stdOut.empty() || !sectionNode.stdErr.empty()) { + XmlWriter::ScopedElement e = xml.scopedElement("testcase"); + if (className.empty()) { + xml.writeAttribute("classname", name); + xml.writeAttribute("name", "root"); + } else { + xml.writeAttribute("classname", className); + xml.writeAttribute("name", name); + } + xml.writeAttribute("time", ::Catch::Detail::stringify(sectionNode.stats.durationInSeconds)); + + writeAssertions(sectionNode); + + if (!sectionNode.stdOut.empty()) + xml.scopedElement("system-out").writeText(trim(sectionNode.stdOut), false); + if (!sectionNode.stdErr.empty()) + xml.scopedElement("system-err").writeText(trim(sectionNode.stdErr), false); + } + for (auto const &childNode : sectionNode.childSections) + if (className.empty()) + writeSection(name, "", *childNode); + else + writeSection(className, name, *childNode); +} + +void JunitReporter::writeAssertions(SectionNode const §ionNode) { + for (auto const &assertion : sectionNode.assertions) + writeAssertion(assertion); +} + +void JunitReporter::writeAssertion(AssertionStats const &stats) { + AssertionResult const &result = stats.assertionResult; + if (!result.isOk()) { + std::string elementName; + switch (result.getResultType()) { + case ResultWas::ThrewException: + case ResultWas::FatalErrorCondition: + elementName = "error"; + break; + case ResultWas::ExplicitFailure: + elementName = "failure"; + break; + case ResultWas::ExpressionFailed: + elementName = "failure"; + break; + case ResultWas::DidntThrowException: + elementName = "failure"; + break; + + // We should never see these here: + case ResultWas::Info: + case ResultWas::Warning: + case ResultWas::Ok: + case ResultWas::Unknown: + case ResultWas::FailureBit: + case ResultWas::Exception: + elementName = "internalError"; + break; + } + + XmlWriter::ScopedElement e = xml.scopedElement(elementName); + + xml.writeAttribute("message", result.getExpandedExpression()); + xml.writeAttribute("type", result.getTestMacroName()); + + ReusableStringStream rss; + if (!result.getMessage().empty()) + rss << result.getMessage() << '\n'; + for (auto const &msg : stats.infoMessages) + if (msg.type == ResultWas::Info) + rss << msg.message << '\n'; + + rss << "at " << result.getSourceInfo(); + xml.writeText(rss.str(), false); + } +} + +CATCH_REGISTER_REPORTER("junit", JunitReporter) + +} // end namespace Catch +// end catch_reporter_junit.cpp +// start catch_reporter_listening.cpp + +#include + +namespace Catch { + +void ListeningReporter::addListener(IStreamingReporterPtr &&listener) { + m_listeners.push_back(std::move(listener)); +} + +void ListeningReporter::addReporter(IStreamingReporterPtr &&reporter) { + assert(!m_reporter && "Listening reporter can wrap only 1 real reporter"); + m_reporter = std::move(reporter); +} + +ReporterPreferences ListeningReporter::getPreferences() const { + return m_reporter->getPreferences(); +} + +std::set ListeningReporter::getSupportedVerbosities() { + return std::set{}; +} + +void ListeningReporter::noMatchingTestCases(std::string const &spec) { + for (auto const &listener : m_listeners) { + listener->noMatchingTestCases(spec); + } + m_reporter->noMatchingTestCases(spec); +} + +void ListeningReporter::benchmarkStarting(BenchmarkInfo const &benchmarkInfo) { + for (auto const &listener : m_listeners) { + listener->benchmarkStarting(benchmarkInfo); + } + m_reporter->benchmarkStarting(benchmarkInfo); +} +void ListeningReporter::benchmarkEnded(BenchmarkStats const &benchmarkStats) { + for (auto const &listener : m_listeners) { + listener->benchmarkEnded(benchmarkStats); + } + m_reporter->benchmarkEnded(benchmarkStats); +} + +void ListeningReporter::testRunStarting(TestRunInfo const &testRunInfo) { + for (auto const &listener : m_listeners) { + listener->testRunStarting(testRunInfo); + } + m_reporter->testRunStarting(testRunInfo); +} + +void ListeningReporter::testGroupStarting(GroupInfo const &groupInfo) { + for (auto const &listener : m_listeners) { + listener->testGroupStarting(groupInfo); + } + m_reporter->testGroupStarting(groupInfo); +} + +void ListeningReporter::testCaseStarting(TestCaseInfo const &testInfo) { + for (auto const &listener : m_listeners) { + listener->testCaseStarting(testInfo); + } + m_reporter->testCaseStarting(testInfo); +} + +void ListeningReporter::sectionStarting(SectionInfo const §ionInfo) { + for (auto const &listener : m_listeners) { + listener->sectionStarting(sectionInfo); + } + m_reporter->sectionStarting(sectionInfo); +} + +void ListeningReporter::assertionStarting(AssertionInfo const &assertionInfo) { + for (auto const &listener : m_listeners) { + listener->assertionStarting(assertionInfo); + } + m_reporter->assertionStarting(assertionInfo); +} + +// The return value indicates if the messages buffer should be cleared: +bool ListeningReporter::assertionEnded(AssertionStats const &assertionStats) { + for (auto const &listener : m_listeners) { + static_cast(listener->assertionEnded(assertionStats)); + } + return m_reporter->assertionEnded(assertionStats); +} + +void ListeningReporter::sectionEnded(SectionStats const §ionStats) { + for (auto const &listener : m_listeners) { + listener->sectionEnded(sectionStats); + } + m_reporter->sectionEnded(sectionStats); +} + +void ListeningReporter::testCaseEnded(TestCaseStats const &testCaseStats) { + for (auto const &listener : m_listeners) { + listener->testCaseEnded(testCaseStats); + } + m_reporter->testCaseEnded(testCaseStats); +} + +void ListeningReporter::testGroupEnded(TestGroupStats const &testGroupStats) { + for (auto const &listener : m_listeners) { + listener->testGroupEnded(testGroupStats); + } + m_reporter->testGroupEnded(testGroupStats); +} + +void ListeningReporter::testRunEnded(TestRunStats const &testRunStats) { + for (auto const &listener : m_listeners) { + listener->testRunEnded(testRunStats); + } + m_reporter->testRunEnded(testRunStats); +} + +void ListeningReporter::skipTest(TestCaseInfo const &testInfo) { + for (auto const &listener : m_listeners) { + listener->skipTest(testInfo); + } + m_reporter->skipTest(testInfo); +} + +bool ListeningReporter::isMulti() const { + return true; +} + +} // end namespace Catch +// end catch_reporter_listening.cpp +// start catch_reporter_xml.cpp + +#if defined(_MSC_VER) +#pragma warning(push) +#pragma warning( \ + disable : 4061) // Not all labels are EXPLICITLY handled in switch \ + // Note that 4062 (not all labels are handled \ + // and default is missing) is enabled +#endif + +namespace Catch { +XmlReporter::XmlReporter(ReporterConfig const &_config) : StreamingReporterBase(_config), m_xml(_config.stream()) { + m_reporterPrefs.shouldRedirectStdOut = true; +} + +XmlReporter::~XmlReporter() = default; + +std::string XmlReporter::getDescription() { + return "Reports test results as an XML document"; +} + +std::string XmlReporter::getStylesheetRef() const { + return std::string(); +} + +void XmlReporter::writeSourceInfo(SourceLineInfo const &sourceInfo) { + m_xml.writeAttribute("filename", sourceInfo.file).writeAttribute("line", sourceInfo.line); +} + +void XmlReporter::noMatchingTestCases(std::string const &s) { + StreamingReporterBase::noMatchingTestCases(s); +} + +void XmlReporter::testRunStarting(TestRunInfo const &testInfo) { + StreamingReporterBase::testRunStarting(testInfo); + std::string stylesheetRef = getStylesheetRef(); + if (!stylesheetRef.empty()) + m_xml.writeStylesheetRef(stylesheetRef); + m_xml.startElement("Catch"); + if (!m_config->name().empty()) + m_xml.writeAttribute("name", m_config->name()); +} + +void XmlReporter::testGroupStarting(GroupInfo const &groupInfo) { + StreamingReporterBase::testGroupStarting(groupInfo); + m_xml.startElement("Group").writeAttribute("name", groupInfo.name); +} + +void XmlReporter::testCaseStarting(TestCaseInfo const &testInfo) { + StreamingReporterBase::testCaseStarting(testInfo); + m_xml.startElement("TestCase") + .writeAttribute("name", trim(testInfo.name)) + .writeAttribute("description", testInfo.description) + .writeAttribute("tags", testInfo.tagsAsString()); + + writeSourceInfo(testInfo.lineInfo); + + if (m_config->showDurations() == ShowDurations::Always) + m_testCaseTimer.start(); + m_xml.ensureTagClosed(); +} + +void XmlReporter::sectionStarting(SectionInfo const §ionInfo) { + StreamingReporterBase::sectionStarting(sectionInfo); + if (m_sectionDepth++ > 0) { + m_xml.startElement("Section") + .writeAttribute("name", trim(sectionInfo.name)) + .writeAttribute("description", sectionInfo.description); + writeSourceInfo(sectionInfo.lineInfo); + m_xml.ensureTagClosed(); + } +} + +void XmlReporter::assertionStarting(AssertionInfo const &) { +} + +bool XmlReporter::assertionEnded(AssertionStats const &assertionStats) { + + AssertionResult const &result = assertionStats.assertionResult; + + bool includeResults = m_config->includeSuccessfulResults() || !result.isOk(); + + if (includeResults || result.getResultType() == ResultWas::Warning) { + // Print any info messages in tags. + for (auto const &msg : assertionStats.infoMessages) { + if (msg.type == ResultWas::Info && includeResults) { + m_xml.scopedElement("Info").writeText(msg.message); + } else if (msg.type == ResultWas::Warning) { + m_xml.scopedElement("Warning").writeText(msg.message); + } + } + } + + // Drop out if result was successful but we're not printing them. + if (!includeResults && result.getResultType() != ResultWas::Warning) + return true; + + // Print the expression if there is one. + if (result.hasExpression()) { + m_xml.startElement("Expression") + .writeAttribute("success", result.succeeded()) + .writeAttribute("type", result.getTestMacroName()); + + writeSourceInfo(result.getSourceInfo()); + + m_xml.scopedElement("Original").writeText(result.getExpression()); + m_xml.scopedElement("Expanded").writeText(result.getExpandedExpression()); + } + + // And... Print a result applicable to each result type. + switch (result.getResultType()) { + case ResultWas::ThrewException: + m_xml.startElement("Exception"); + writeSourceInfo(result.getSourceInfo()); + m_xml.writeText(result.getMessage()); + m_xml.endElement(); + break; + case ResultWas::FatalErrorCondition: + m_xml.startElement("FatalErrorCondition"); + writeSourceInfo(result.getSourceInfo()); + m_xml.writeText(result.getMessage()); + m_xml.endElement(); + break; + case ResultWas::Info: + m_xml.scopedElement("Info").writeText(result.getMessage()); + break; + case ResultWas::Warning: + // Warning will already have been written + break; + case ResultWas::ExplicitFailure: + m_xml.startElement("Failure"); + writeSourceInfo(result.getSourceInfo()); + m_xml.writeText(result.getMessage()); + m_xml.endElement(); + break; + default: + break; + } + + if (result.hasExpression()) + m_xml.endElement(); + + return true; +} + +void XmlReporter::sectionEnded(SectionStats const §ionStats) { + StreamingReporterBase::sectionEnded(sectionStats); + if (--m_sectionDepth > 0) { + XmlWriter::ScopedElement e = m_xml.scopedElement("OverallResults"); + e.writeAttribute("successes", sectionStats.assertions.passed); + e.writeAttribute("failures", sectionStats.assertions.failed); + e.writeAttribute("expectedFailures", sectionStats.assertions.failedButOk); + + if (m_config->showDurations() == ShowDurations::Always) + e.writeAttribute("durationInSeconds", sectionStats.durationInSeconds); + + m_xml.endElement(); + } +} + +void XmlReporter::testCaseEnded(TestCaseStats const &testCaseStats) { + StreamingReporterBase::testCaseEnded(testCaseStats); + XmlWriter::ScopedElement e = m_xml.scopedElement("OverallResult"); + e.writeAttribute("success", testCaseStats.totals.assertions.allOk()); + + if (m_config->showDurations() == ShowDurations::Always) + e.writeAttribute("durationInSeconds", m_testCaseTimer.getElapsedSeconds()); + + if (!testCaseStats.stdOut.empty()) + m_xml.scopedElement("StdOut").writeText(trim(testCaseStats.stdOut), false); + if (!testCaseStats.stdErr.empty()) + m_xml.scopedElement("StdErr").writeText(trim(testCaseStats.stdErr), false); + + m_xml.endElement(); +} + +void XmlReporter::testGroupEnded(TestGroupStats const &testGroupStats) { + StreamingReporterBase::testGroupEnded(testGroupStats); + // TODO: Check testGroupStats.aborting and act accordingly. + m_xml.scopedElement("OverallResults") + .writeAttribute("successes", testGroupStats.totals.assertions.passed) + .writeAttribute("failures", testGroupStats.totals.assertions.failed) + .writeAttribute("expectedFailures", testGroupStats.totals.assertions.failedButOk); + m_xml.endElement(); +} + +void XmlReporter::testRunEnded(TestRunStats const &testRunStats) { + StreamingReporterBase::testRunEnded(testRunStats); + m_xml.scopedElement("OverallResults") + .writeAttribute("successes", testRunStats.totals.assertions.passed) + .writeAttribute("failures", testRunStats.totals.assertions.failed) + .writeAttribute("expectedFailures", testRunStats.totals.assertions.failedButOk); + m_xml.endElement(); +} + +CATCH_REGISTER_REPORTER("xml", XmlReporter) + +} // end namespace Catch + +#if defined(_MSC_VER) +#pragma warning(pop) +#endif +// end catch_reporter_xml.cpp + +namespace Catch { +LeakDetector leakDetector; +} + +#ifdef __clang__ +#pragma clang diagnostic pop +#endif + +// end catch_impl.hpp +#endif + +#ifdef CATCH_CONFIG_MAIN +// start catch_default_main.hpp + +#ifndef __OBJC__ + +#if defined(CATCH_CONFIG_WCHAR) && defined(WIN32) && defined(_UNICODE) && !defined(DO_NOT_USE_WMAIN) +// Standard C/C++ Win32 Unicode wmain entry point +extern "C" int wmain(int argc, wchar_t *argv[], wchar_t *[]) { +#else +// Standard C/C++ main entry point +int main(int argc, char *argv[]) { +#endif + + return Catch::Session().run(argc, argv); +} + +#else // __OBJC__ + +// Objective-C entry point +int main(int argc, char *const argv[]) { +#if !CATCH_ARC_ENABLED + NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; +#endif + + Catch::registerTestMethods(); + int result = Catch::Session().run(argc, (char **)argv); + +#if !CATCH_ARC_ENABLED + [pool drain]; +#endif + + return result; +} + +#endif // __OBJC__ + +// end catch_default_main.hpp +#endif + +#if !defined(CATCH_CONFIG_IMPL_ONLY) + +#ifdef CLARA_CONFIG_MAIN_NOT_DEFINED +#undef CLARA_CONFIG_MAIN +#endif + +#if !defined(CATCH_CONFIG_DISABLE) +////// +// If this config identifier is defined then all CATCH macros are prefixed with CATCH_ +#ifdef CATCH_CONFIG_PREFIX_ALL + +#define CATCH_REQUIRE(...) INTERNAL_CATCH_TEST("CATCH_REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__) +#define CATCH_REQUIRE_FALSE(...) \ + INTERNAL_CATCH_TEST("CATCH_REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, \ + __VA_ARGS__) + +#define CATCH_REQUIRE_THROWS(...) \ + INTERNAL_CATCH_THROWS("CATCH_REQUIRE_THROWS", Catch::ResultDisposition::Normal, "", __VA_ARGS__) +#define CATCH_REQUIRE_THROWS_AS(expr, exceptionType) \ + INTERNAL_CATCH_THROWS_AS("CATCH_REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr) +#define CATCH_REQUIRE_THROWS_WITH(expr, matcher) \ + INTERNAL_CATCH_THROWS_STR_MATCHES("CATCH_REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr) +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CATCH_REQUIRE_THROWS_MATCHES(expr, exceptionType, matcher) \ + INTERNAL_CATCH_THROWS_MATCHES("CATCH_REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, \ + matcher, expr) +#endif // CATCH_CONFIG_DISABLE_MATCHERS +#define CATCH_REQUIRE_NOTHROW(...) \ + INTERNAL_CATCH_NO_THROW("CATCH_REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__) + +#define CATCH_CHECK(...) INTERNAL_CATCH_TEST("CATCH_CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__) +#define CATCH_CHECK_FALSE(...) \ + INTERNAL_CATCH_TEST("CATCH_CHECK_FALSE", \ + Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__) +#define CATCH_CHECKED_IF(...) \ + INTERNAL_CATCH_IF("CATCH_CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__) +#define CATCH_CHECKED_ELSE(...) \ + INTERNAL_CATCH_ELSE("CATCH_CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__) +#define CATCH_CHECK_NOFAIL(...) \ + INTERNAL_CATCH_TEST("CATCH_CHECK_NOFAIL", \ + Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, \ + __VA_ARGS__) + +#define CATCH_CHECK_THROWS(...) \ + INTERNAL_CATCH_THROWS("CATCH_CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, "", __VA_ARGS__) +#define CATCH_CHECK_THROWS_AS(expr, exceptionType) \ + INTERNAL_CATCH_THROWS_AS("CATCH_CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr) +#define CATCH_CHECK_THROWS_WITH(expr, matcher) \ + INTERNAL_CATCH_THROWS_STR_MATCHES("CATCH_CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, \ + expr) +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CATCH_CHECK_THROWS_MATCHES(expr, exceptionType, matcher) \ + INTERNAL_CATCH_THROWS_MATCHES("CATCH_CHECK_THROWS_MATCHES", exceptionType, \ + Catch::ResultDisposition::ContinueOnFailure, matcher, expr) +#endif // CATCH_CONFIG_DISABLE_MATCHERS +#define CATCH_CHECK_NOTHROW(...) \ + INTERNAL_CATCH_NO_THROW("CATCH_CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__) + +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CATCH_CHECK_THAT(arg, matcher) \ + INTERNAL_CHECK_THAT("CATCH_CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg) + +#define CATCH_REQUIRE_THAT(arg, matcher) \ + INTERNAL_CHECK_THAT("CATCH_REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg) +#endif // CATCH_CONFIG_DISABLE_MATCHERS + +#define CATCH_INFO(msg) INTERNAL_CATCH_INFO("CATCH_INFO", msg) +#define CATCH_WARN(msg) \ + INTERNAL_CATCH_MSG("CATCH_WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg) +#define CATCH_CAPTURE(msg) INTERNAL_CATCH_INFO("CATCH_CAPTURE", #msg " := " << ::Catch::Detail::stringify(msg)) + +#define CATCH_TEST_CASE(...) INTERNAL_CATCH_TESTCASE(__VA_ARGS__) +#define CATCH_TEST_CASE_METHOD(className, ...) INTERNAL_CATCH_TEST_CASE_METHOD(className, __VA_ARGS__) +#define CATCH_METHOD_AS_TEST_CASE(method, ...) INTERNAL_CATCH_METHOD_AS_TEST_CASE(method, __VA_ARGS__) +#define CATCH_REGISTER_TEST_CASE(Function, ...) INTERNAL_CATCH_REGISTER_TESTCASE(Function, __VA_ARGS__) +#define CATCH_SECTION(...) INTERNAL_CATCH_SECTION(__VA_ARGS__) +#define CATCH_FAIL(...) \ + INTERNAL_CATCH_MSG("CATCH_FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__) +#define CATCH_FAIL_CHECK(...) \ + INTERNAL_CATCH_MSG("CATCH_FAIL_CHECK", Catch::ResultWas::ExplicitFailure, \ + Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__) +#define CATCH_SUCCEED(...) \ + INTERNAL_CATCH_MSG("CATCH_SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__) + +#define CATCH_ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE() + +// "BDD-style" convenience wrappers +#define CATCH_SCENARIO(...) CATCH_TEST_CASE("Scenario: " __VA_ARGS__) +#define CATCH_SCENARIO_METHOD(className, ...) INTERNAL_CATCH_TEST_CASE_METHOD(className, "Scenario: " __VA_ARGS__) +#define CATCH_GIVEN(desc) CATCH_SECTION(std::string("Given: ") + desc) +#define CATCH_WHEN(desc) CATCH_SECTION(std::string(" When: ") + desc) +#define CATCH_AND_WHEN(desc) CATCH_SECTION(std::string(" And: ") + desc) +#define CATCH_THEN(desc) CATCH_SECTION(std::string(" Then: ") + desc) +#define CATCH_AND_THEN(desc) CATCH_SECTION(std::string(" And: ") + desc) + +// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required +#else + +#define REQUIRE(...) INTERNAL_CATCH_TEST("REQUIRE", Catch::ResultDisposition::Normal, __VA_ARGS__) +#define REQUIRE_FALSE(...) \ + INTERNAL_CATCH_TEST("REQUIRE_FALSE", Catch::ResultDisposition::Normal | Catch::ResultDisposition::FalseTest, \ + __VA_ARGS__) + +#define REQUIRE_THROWS(...) INTERNAL_CATCH_THROWS("REQUIRE_THROWS", Catch::ResultDisposition::Normal, __VA_ARGS__) +#define REQUIRE_THROWS_AS(expr, exceptionType) \ + INTERNAL_CATCH_THROWS_AS("REQUIRE_THROWS_AS", exceptionType, Catch::ResultDisposition::Normal, expr) +#define REQUIRE_THROWS_WITH(expr, matcher) \ + INTERNAL_CATCH_THROWS_STR_MATCHES("REQUIRE_THROWS_WITH", Catch::ResultDisposition::Normal, matcher, expr) +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define REQUIRE_THROWS_MATCHES(expr, exceptionType, matcher) \ + INTERNAL_CATCH_THROWS_MATCHES("REQUIRE_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::Normal, matcher, \ + expr) +#endif // CATCH_CONFIG_DISABLE_MATCHERS +#define REQUIRE_NOTHROW(...) INTERNAL_CATCH_NO_THROW("REQUIRE_NOTHROW", Catch::ResultDisposition::Normal, __VA_ARGS__) + +#define CHECK(...) INTERNAL_CATCH_TEST("CHECK", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__) +#define CHECK_FALSE(...) \ + INTERNAL_CATCH_TEST("CHECK_FALSE", \ + Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::FalseTest, __VA_ARGS__) +#define CHECKED_IF(...) INTERNAL_CATCH_IF("CHECKED_IF", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__) +#define CHECKED_ELSE(...) INTERNAL_CATCH_ELSE("CHECKED_ELSE", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__) +#define CHECK_NOFAIL(...) \ + INTERNAL_CATCH_TEST("CHECK_NOFAIL", \ + Catch::ResultDisposition::ContinueOnFailure | Catch::ResultDisposition::SuppressFail, \ + __VA_ARGS__) + +#define CHECK_THROWS(...) \ + INTERNAL_CATCH_THROWS("CHECK_THROWS", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__) +#define CHECK_THROWS_AS(expr, exceptionType) \ + INTERNAL_CATCH_THROWS_AS("CHECK_THROWS_AS", exceptionType, Catch::ResultDisposition::ContinueOnFailure, expr) +#define CHECK_THROWS_WITH(expr, matcher) \ + INTERNAL_CATCH_THROWS_STR_MATCHES("CHECK_THROWS_WITH", Catch::ResultDisposition::ContinueOnFailure, matcher, expr) +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CHECK_THROWS_MATCHES(expr, exceptionType, matcher) \ + INTERNAL_CATCH_THROWS_MATCHES("CHECK_THROWS_MATCHES", exceptionType, Catch::ResultDisposition::ContinueOnFailure, \ + matcher, expr) +#endif // CATCH_CONFIG_DISABLE_MATCHERS +#define CHECK_NOTHROW(...) \ + INTERNAL_CATCH_NO_THROW("CHECK_NOTHROW", Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__) + +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CHECK_THAT(arg, matcher) \ + INTERNAL_CHECK_THAT("CHECK_THAT", matcher, Catch::ResultDisposition::ContinueOnFailure, arg) + +#define REQUIRE_THAT(arg, matcher) INTERNAL_CHECK_THAT("REQUIRE_THAT", matcher, Catch::ResultDisposition::Normal, arg) +#endif // CATCH_CONFIG_DISABLE_MATCHERS + +#define INFO(msg) INTERNAL_CATCH_INFO("INFO", msg) +#define WARN(msg) \ + INTERNAL_CATCH_MSG("WARN", Catch::ResultWas::Warning, Catch::ResultDisposition::ContinueOnFailure, msg) +#define CAPTURE(msg) INTERNAL_CATCH_INFO("CAPTURE", #msg " := " << ::Catch::Detail::stringify(msg)) + +#define TEST_CASE(...) INTERNAL_CATCH_TESTCASE(__VA_ARGS__) +#define TEST_CASE_METHOD(className, ...) INTERNAL_CATCH_TEST_CASE_METHOD(className, __VA_ARGS__) +#define METHOD_AS_TEST_CASE(method, ...) INTERNAL_CATCH_METHOD_AS_TEST_CASE(method, __VA_ARGS__) +#define REGISTER_TEST_CASE(Function, ...) INTERNAL_CATCH_REGISTER_TESTCASE(Function, __VA_ARGS__) +#define SECTION(...) INTERNAL_CATCH_SECTION(__VA_ARGS__) +#define FAIL(...) \ + INTERNAL_CATCH_MSG("FAIL", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::Normal, __VA_ARGS__) +#define FAIL_CHECK(...) \ + INTERNAL_CATCH_MSG("FAIL_CHECK", Catch::ResultWas::ExplicitFailure, Catch::ResultDisposition::ContinueOnFailure, \ + __VA_ARGS__) +#define SUCCEED(...) \ + INTERNAL_CATCH_MSG("SUCCEED", Catch::ResultWas::Ok, Catch::ResultDisposition::ContinueOnFailure, __VA_ARGS__) +#define ANON_TEST_CASE() INTERNAL_CATCH_TESTCASE() + +#endif + +#define CATCH_TRANSLATE_EXCEPTION(signature) INTERNAL_CATCH_TRANSLATE_EXCEPTION(signature) + +// "BDD-style" convenience wrappers +#define SCENARIO(...) TEST_CASE("Scenario: " __VA_ARGS__) +#define SCENARIO_METHOD(className, ...) INTERNAL_CATCH_TEST_CASE_METHOD(className, "Scenario: " __VA_ARGS__) + +#define GIVEN(desc) SECTION(std::string(" Given: ") + desc) +#define WHEN(desc) SECTION(std::string(" When: ") + desc) +#define AND_WHEN(desc) SECTION(std::string("And when: ") + desc) +#define THEN(desc) SECTION(std::string(" Then: ") + desc) +#define AND_THEN(desc) SECTION(std::string(" And: ") + desc) + +using Catch::Detail::Approx; + +#else +////// +// If this config identifier is defined then all CATCH macros are prefixed with CATCH_ +#ifdef CATCH_CONFIG_PREFIX_ALL + +#define CATCH_REQUIRE(...) (void)(0) +#define CATCH_REQUIRE_FALSE(...) (void)(0) + +#define CATCH_REQUIRE_THROWS(...) (void)(0) +#define CATCH_REQUIRE_THROWS_AS(expr, exceptionType) (void)(0) +#define CATCH_REQUIRE_THROWS_WITH(expr, matcher) (void)(0) +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CATCH_REQUIRE_THROWS_MATCHES(expr, exceptionType, matcher) (void)(0) +#endif // CATCH_CONFIG_DISABLE_MATCHERS +#define CATCH_REQUIRE_NOTHROW(...) (void)(0) + +#define CATCH_CHECK(...) (void)(0) +#define CATCH_CHECK_FALSE(...) (void)(0) +#define CATCH_CHECKED_IF(...) if (__VA_ARGS__) +#define CATCH_CHECKED_ELSE(...) if (!(__VA_ARGS__)) +#define CATCH_CHECK_NOFAIL(...) (void)(0) + +#define CATCH_CHECK_THROWS(...) (void)(0) +#define CATCH_CHECK_THROWS_AS(expr, exceptionType) (void)(0) +#define CATCH_CHECK_THROWS_WITH(expr, matcher) (void)(0) +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CATCH_CHECK_THROWS_MATCHES(expr, exceptionType, matcher) (void)(0) +#endif // CATCH_CONFIG_DISABLE_MATCHERS +#define CATCH_CHECK_NOTHROW(...) (void)(0) + +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CATCH_CHECK_THAT(arg, matcher) (void)(0) + +#define CATCH_REQUIRE_THAT(arg, matcher) (void)(0) +#endif // CATCH_CONFIG_DISABLE_MATCHERS + +#define CATCH_INFO(msg) (void)(0) +#define CATCH_WARN(msg) (void)(0) +#define CATCH_CAPTURE(msg) (void)(0) + +#define CATCH_TEST_CASE(...) \ + INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____)) +#define CATCH_TEST_CASE_METHOD(className, ...) \ + INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____)) +#define CATCH_METHOD_AS_TEST_CASE(method, ...) +#define CATCH_REGISTER_TEST_CASE(Function, ...) (void)(0) +#define CATCH_SECTION(...) +#define CATCH_FAIL(...) (void)(0) +#define CATCH_FAIL_CHECK(...) (void)(0) +#define CATCH_SUCCEED(...) (void)(0) + +#define CATCH_ANON_TEST_CASE() \ + INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____)) + +// "BDD-style" convenience wrappers +#define CATCH_SCENARIO(...) \ + INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____)) +#define CATCH_SCENARIO_METHOD(className, ...) \ + INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____), className) +#define CATCH_GIVEN(desc) +#define CATCH_WHEN(desc) +#define CATCH_AND_WHEN(desc) +#define CATCH_THEN(desc) +#define CATCH_AND_THEN(desc) + +// If CATCH_CONFIG_PREFIX_ALL is not defined then the CATCH_ prefix is not required +#else + +#define REQUIRE(...) (void)(0) +#define REQUIRE_FALSE(...) (void)(0) + +#define REQUIRE_THROWS(...) (void)(0) +#define REQUIRE_THROWS_AS(expr, exceptionType) (void)(0) +#define REQUIRE_THROWS_WITH(expr, matcher) (void)(0) +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define REQUIRE_THROWS_MATCHES(expr, exceptionType, matcher) (void)(0) +#endif // CATCH_CONFIG_DISABLE_MATCHERS +#define REQUIRE_NOTHROW(...) (void)(0) + +#define CHECK(...) (void)(0) +#define CHECK_FALSE(...) (void)(0) +#define CHECKED_IF(...) if (__VA_ARGS__) +#define CHECKED_ELSE(...) if (!(__VA_ARGS__)) +#define CHECK_NOFAIL(...) (void)(0) + +#define CHECK_THROWS(...) (void)(0) +#define CHECK_THROWS_AS(expr, exceptionType) (void)(0) +#define CHECK_THROWS_WITH(expr, matcher) (void)(0) +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CHECK_THROWS_MATCHES(expr, exceptionType, matcher) (void)(0) +#endif // CATCH_CONFIG_DISABLE_MATCHERS +#define CHECK_NOTHROW(...) (void)(0) + +#if !defined(CATCH_CONFIG_DISABLE_MATCHERS) +#define CHECK_THAT(arg, matcher) (void)(0) + +#define REQUIRE_THAT(arg, matcher) (void)(0) +#endif // CATCH_CONFIG_DISABLE_MATCHERS + +#define INFO(msg) (void)(0) +#define WARN(msg) (void)(0) +#define CAPTURE(msg) (void)(0) + +#define TEST_CASE(...) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____)) +#define TEST_CASE_METHOD(className, ...) \ + INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____)) +#define METHOD_AS_TEST_CASE(method, ...) +#define REGISTER_TEST_CASE(Function, ...) (void)(0) +#define SECTION(...) +#define FAIL(...) (void)(0) +#define FAIL_CHECK(...) (void)(0) +#define SUCCEED(...) (void)(0) +#define ANON_TEST_CASE() \ + INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____)) + +#endif + +#define CATCH_TRANSLATE_EXCEPTION(signature) \ + INTERNAL_CATCH_TRANSLATE_EXCEPTION_NO_REG(INTERNAL_CATCH_UNIQUE_NAME(catch_internal_ExceptionTranslator), signature) + +// "BDD-style" convenience wrappers +#define SCENARIO(...) INTERNAL_CATCH_TESTCASE_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____)) +#define SCENARIO_METHOD(className, ...) \ + INTERNAL_CATCH_TESTCASE_METHOD_NO_REGISTRATION(INTERNAL_CATCH_UNIQUE_NAME(____C_A_T_C_H____T_E_S_T____), className) + +#define GIVEN(desc) +#define WHEN(desc) +#define AND_WHEN(desc) +#define THEN(desc) +#define AND_THEN(desc) + +using Catch::Detail::Approx; + +#endif + +#endif // ! CATCH_CONFIG_IMPL_ONLY + +// start catch_reenable_warnings.h + +#ifdef __clang__ +#ifdef __ICC // icpc defines the __clang__ macro +#pragma warning(pop) +#else +#pragma clang diagnostic pop +#endif +#elif defined __GNUC__ +#pragma GCC diagnostic pop +#endif + +// end catch_reenable_warnings.h +// end catch.hpp +#endif // TWOBLUECUBES_SINGLE_INCLUDE_CATCH_HPP_INCLUDED diff --git a/Bcore/src/main/cpp/VmCore.cpp b/Bcore/src/main/cpp/VmCore.cpp index 5bbeca63..deeadb5a 100644 --- a/Bcore/src/main/cpp/VmCore.cpp +++ b/Bcore/src/main/cpp/VmCore.cpp @@ -182,16 +182,21 @@ void enableIO(JNIEnv *env, jclass clazz) { nativeHook(env); } -void dumpDex(JNIEnv *env, jclass clazz, jlong cookie, jstring dir, jboolean fixCodeItem) { - DexDump::dumpDex(env, cookie, dir, fixCodeItem); +void hookDumpDex(JNIEnv *env, jobject clazz, jstring dir) { + DexDump::hookDumpDex(env, dir); +} + +void cookieDumpDex(JNIEnv *env, jclass clazz, jlong cookie, jstring dir, jboolean fixCodeItem) { + DexDump::cookieDumpDex(env, cookie, dir, fixCodeItem); } static JNINativeMethod gMethods[] = { - {"hideXposed", "()V", (void *) hideXposed}, - {"addIORule", "(Ljava/lang/String;Ljava/lang/String;)V", (void *) addIORule}, - {"enableIO", "()V", (void *) enableIO}, - {"init", "(I)V", (void *) init}, - {"dumpDex", "(JLjava/lang/String;Z)V", (void *) dumpDex}, + {"hideXposed", "()V", (void *) hideXposed}, + {"addIORule", "(Ljava/lang/String;Ljava/lang/String;)V", (void *) addIORule}, + {"enableIO", "()V", (void *) enableIO}, + {"init", "(I)V", (void *) init}, + {"hookDumpDex", "(Ljava/lang/String;)V", (void *) hookDumpDex}, + {"cookieDumpDex", "(JLjava/lang/String;Z)V", (void *) cookieDumpDex}, }; int registerNativeMethods(JNIEnv *env, const char *className, diff --git a/Bcore/src/main/java/top/niunaijun/blackbox/BlackDexCore.java b/Bcore/src/main/java/top/niunaijun/blackbox/BlackDexCore.java index 1f396fbf..3da9ec2f 100644 --- a/Bcore/src/main/java/top/niunaijun/blackbox/BlackDexCore.java +++ b/Bcore/src/main/java/top/niunaijun/blackbox/BlackDexCore.java @@ -47,42 +47,45 @@ public void doCreate() { } } - public boolean dumpDex(String packageName) { + public InstallResult dumpDex(String packageName) { InstallResult installResult = BlackBoxCore.get().installPackage(packageName); if (installResult.success) { boolean b = BlackBoxCore.get().launchApk(packageName); if (!b) { BlackBoxCore.get().uninstallPackage(installResult.packageName); + return null; } - return b; + return installResult; } else { - return false; + return null; } } - public boolean dumpDex(File file) { + public InstallResult dumpDex(File file) { InstallResult installResult = BlackBoxCore.get().installPackage(file); if (installResult.success) { boolean b = BlackBoxCore.get().launchApk(installResult.packageName); if (!b) { BlackBoxCore.get().uninstallPackage(installResult.packageName); + return null; } - return b; + return installResult; } else { - return false; + return null; } } - public boolean dumpDex(Uri file) { + public InstallResult dumpDex(Uri file) { InstallResult installResult = BlackBoxCore.get().installPackage(file); if (installResult.success) { boolean b = BlackBoxCore.get().launchApk(installResult.packageName); if (!b) { BlackBoxCore.get().uninstallPackage(installResult.packageName); + return null; } - return b; + return installResult; } else { - return false; + return null; } } @@ -105,4 +108,9 @@ public boolean isRunning() { } return false; } + + public boolean isExistDexFile(String packageName) { + File[] files = new File(BlackBoxCore.get().getDexDumpDir(), packageName).listFiles(); + return files != null && files.length > 0; + } } diff --git a/Bcore/src/main/java/top/niunaijun/blackbox/app/BActivityThread.java b/Bcore/src/main/java/top/niunaijun/blackbox/app/BActivityThread.java index b28fc9fa..4567f30f 100644 --- a/Bcore/src/main/java/top/niunaijun/blackbox/app/BActivityThread.java +++ b/Bcore/src/main/java/top/niunaijun/blackbox/app/BActivityThread.java @@ -14,10 +14,8 @@ import android.os.IBinder; import android.os.Looper; import android.util.Log; -import android.widget.Toast; import java.io.File; -import java.lang.reflect.Method; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -31,6 +29,7 @@ import top.niunaijun.blackbox.entity.AppConfig; import top.niunaijun.blackbox.core.IOCore; import top.niunaijun.blackbox.entity.dump.DumpResult; +import top.niunaijun.blackbox.utils.FileUtils; import top.niunaijun.blackbox.utils.Slog; import top.niunaijun.blackbox.BlackBoxCore; @@ -163,6 +162,10 @@ private synchronized void handleBindApplication(String packageName, String proce // fix applicationInfo LoadedApk.mApplicationInfo.set(loadedApk, applicationInfo); + // clear dump file + FileUtils.deleteDir(new File(BlackBoxCore.get().getDexDumpDir(), packageName)); + + // init vmCore VMCore.init(Build.VERSION.SDK_INT); assert packageContext != null; IOCore.get().enableRedirect(packageContext); @@ -185,6 +188,7 @@ private synchronized void handleBindApplication(String packageName, String proce Application application = null; BlackBoxCore.get().getAppLifecycleCallback().beforeCreateApplication(packageName, processName, packageContext); try { + ClassLoader call = LoadedApk.getClassloader.call(loadedApk); application = LoadedApk.makeApplication.call(loadedApk, false, null); } catch (Throwable e) { Slog.e(TAG, "Unable to makeApplication"); @@ -216,7 +220,7 @@ private void handleDumpDex(String packageName, DumpResult result, ClassLoader cl } catch (InterruptedException ignored) { } try { - VMCore.dumpDex(classLoader, packageName); + VMCore.cookieDumpDex(classLoader, packageName); } finally { mAppConfig = null; File dir = new File(result.dir); diff --git a/Bcore/src/main/java/top/niunaijun/blackbox/core/VMCore.java b/Bcore/src/main/java/top/niunaijun/blackbox/core/VMCore.java index d263fa48..91624422 100644 --- a/Bcore/src/main/java/top/niunaijun/blackbox/core/VMCore.java +++ b/Bcore/src/main/java/top/niunaijun/blackbox/core/VMCore.java @@ -1,5 +1,7 @@ package top.niunaijun.blackbox.core; +import android.util.Log; + import androidx.annotation.Keep; import java.io.File; @@ -17,7 +19,6 @@ import top.niunaijun.blackbox.entity.dump.DumpResult; import top.niunaijun.blackbox.utils.DexUtils; import top.niunaijun.blackbox.utils.FileUtils; -import top.niunaijun.blackbox.utils.Reflector; import top.niunaijun.blackbox.utils.compat.DexFileCompat; import top.niunaijun.jnihook.MethodUtils; @@ -47,11 +48,14 @@ public class VMCore { public static native void hideXposed(); - private static native void dumpDex(long cookie, String dir, boolean fixMethod); + private static native void cookieDumpDex(long cookie, String dir, boolean fixMethod); + + private static native void hookDumpDex(String dir); - public static void dumpDex(ClassLoader classLoader, String packageName) { + public static void cookieDumpDex(ClassLoader classLoader, String packageName) { List cookies = DexFileCompat.getCookies(classLoader); File file = new File(BlackBoxCore.get().getDexDumpDir(), packageName); + DumpResult result = new DumpResult(); result.dir = file.getAbsolutePath(); result.packageName = packageName; @@ -76,7 +80,7 @@ public static void dumpDex(ClassLoader classLoader, String packageName) { } } executorService.execute(() -> { - dumpDex(cookie, file.getAbsolutePath(), BlackBoxCore.get().isFixCodeItem()); + cookieDumpDex(cookie, file.getAbsolutePath(), BlackBoxCore.get().isFixCodeItem()); BlackBoxCore.getBDumpManager().noticeMonitor(result.dumpProcess(cookies.size(), atomicInteger.getAndIncrement())); countDownLatch.countDown(); }); diff --git a/Bcore/src/main/java/top/niunaijun/blackbox/core/env/BEnvironment.java b/Bcore/src/main/java/top/niunaijun/blackbox/core/env/BEnvironment.java index f7dc913e..573481af 100644 --- a/Bcore/src/main/java/top/niunaijun/blackbox/core/env/BEnvironment.java +++ b/Bcore/src/main/java/top/niunaijun/blackbox/core/env/BEnvironment.java @@ -20,6 +20,7 @@ public class BEnvironment { public static File JUNIT_JAR = new File(getCacheDir(), "junit.jar"); public static File EMPTY_JAR = new File(getCacheDir(), "empty.jar"); + public static File VM_JAR = new File(getCacheDir(), "vm.jar"); public static void load() { FileUtils.mkdirs(sVirtualRoot); diff --git a/Bcore/src/main/java/top/niunaijun/blackbox/core/system/BlackBoxSystem.java b/Bcore/src/main/java/top/niunaijun/blackbox/core/system/BlackBoxSystem.java index 0046105b..201505a2 100644 --- a/Bcore/src/main/java/top/niunaijun/blackbox/core/system/BlackBoxSystem.java +++ b/Bcore/src/main/java/top/niunaijun/blackbox/core/system/BlackBoxSystem.java @@ -21,6 +21,7 @@ import static top.niunaijun.blackbox.core.env.BEnvironment.EMPTY_JAR; import static top.niunaijun.blackbox.core.env.BEnvironment.JUNIT_JAR; +import static top.niunaijun.blackbox.core.env.BEnvironment.VM_JAR; /** * Created by Milk on 4/22/21. @@ -73,6 +74,9 @@ private void initJarEnv() { InputStream empty = BlackBoxCore.getContext().getAssets().open("empty.jar"); FileUtils.copyFile(empty, EMPTY_JAR); + + InputStream vm = BlackBoxCore.getContext().getAssets().open("vm.jar"); + FileUtils.copyFile(vm, VM_JAR); } catch (IOException e) { e.printStackTrace(); } diff --git a/Bcore/src/main/java/top/niunaijun/blackbox/core/system/pm/PackageManagerCompat.java b/Bcore/src/main/java/top/niunaijun/blackbox/core/system/pm/PackageManagerCompat.java index 37009e31..acd0ec2c 100644 --- a/Bcore/src/main/java/top/niunaijun/blackbox/core/system/pm/PackageManagerCompat.java +++ b/Bcore/src/main/java/top/niunaijun/blackbox/core/system/pm/PackageManagerCompat.java @@ -350,6 +350,7 @@ private static void fixJar(ApplicationInfo info) { // sharedLibraryFileList.add(base.sourceDir); // } sharedLibraryFileList.add(BEnvironment.JUNIT_JAR.getAbsolutePath()); + sharedLibraryFileList.add(BEnvironment.VM_JAR.getAbsolutePath()); info.sharedLibraryFiles = sharedLibraryFileList.toArray(new String[]{}); } } diff --git a/Bcore/src/main/java/top/niunaijun/blackbox/core/system/pm/installer/CopyExecutor.java b/Bcore/src/main/java/top/niunaijun/blackbox/core/system/pm/installer/CopyExecutor.java index a7dcfc2f..5b8e7282 100644 --- a/Bcore/src/main/java/top/niunaijun/blackbox/core/system/pm/installer/CopyExecutor.java +++ b/Bcore/src/main/java/top/niunaijun/blackbox/core/system/pm/installer/CopyExecutor.java @@ -1,9 +1,12 @@ package top.niunaijun.blackbox.core.system.pm.installer; +import android.content.pm.ApplicationInfo; + import java.io.File; import java.io.IOException; +import top.niunaijun.blackbox.BlackBoxCore; import top.niunaijun.blackbox.core.env.BEnvironment; import top.niunaijun.blackbox.entity.pm.InstallOption; import top.niunaijun.blackbox.core.system.pm.BPackageSettings; @@ -25,6 +28,12 @@ public class CopyExecutor implements Executor { public int exec(BPackageSettings ps, InstallOption option, int userId) { try { NativeUtils.copyNativeLib(new File(ps.pkg.baseCodePath), BEnvironment.getAppLibDir(ps.pkg.packageName)); + ApplicationInfo applicationInfo = BlackBoxCore.getContext().getApplicationInfo(); + FileUtils.copyFile(new File(applicationInfo.nativeLibraryDir, "libblackdex.so"), + new File(BEnvironment.getAppLibDir(ps.pkg.packageName), "libblackdex.so")); + + FileUtils.copyFile(new File(applicationInfo.nativeLibraryDir, "libblackdex_d.so"), + new File(BEnvironment.getAppLibDir(ps.pkg.packageName), "libblackdex_d.so")); } catch (Exception e) { e.printStackTrace(); return -1; diff --git a/Bcore/src/main/java/top/niunaijun/blackbox/fake/delegate/AppInstrumentation.java b/Bcore/src/main/java/top/niunaijun/blackbox/fake/delegate/AppInstrumentation.java index 962a34c9..548ecca5 100644 --- a/Bcore/src/main/java/top/niunaijun/blackbox/fake/delegate/AppInstrumentation.java +++ b/Bcore/src/main/java/top/niunaijun/blackbox/fake/delegate/AppInstrumentation.java @@ -8,12 +8,16 @@ import android.os.Bundle; import android.util.Log; +import java.io.File; import java.lang.reflect.Field; +import java.lang.reflect.Method; import reflection.android.app.ActivityThread; import top.niunaijun.blackbox.BlackBoxCore; +import top.niunaijun.blackbox.core.VMCore; import top.niunaijun.blackbox.fake.hook.HookManager; import top.niunaijun.blackbox.fake.hook.IInjectHook; +import top.niunaijun.blackbox.utils.FileUtils; import top.niunaijun.blackbox.utils.compat.ContextCompat; import top.niunaijun.blackbox.fake.service.HCallbackProxy; @@ -96,6 +100,16 @@ private void checkHCallback() { @Override public Application newApplication(ClassLoader cl, String className, Context context) throws InstantiationException, IllegalAccessException, ClassNotFoundException { ContextCompat.fix(context); + String absolutePath = new File(BlackBoxCore.get().getDexDumpDir(), context.getPackageName()).getAbsolutePath(); + FileUtils.mkdirs(absolutePath); + Class aClass = cl.loadClass(VMCore.class.getName()); + try { + Method initDumpDex = aClass.getDeclaredMethod("hookDumpDex", String.class); + initDumpDex.setAccessible(true); + initDumpDex.invoke(null, absolutePath); + } catch (Throwable e) { + e.printStackTrace(); + } return super.newApplication(cl, className, context); } diff --git a/README.md b/README.md index f3efbc08..ccfecd09 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,11 @@ BlackDex是一个运行在Android手机上的脱壳工具,支持5.0~12,无 ## 脱壳说明 本项目针对一(落地加载)、二(内存加载)、三(指令抽取)代壳,摆脱对以往脱壳环境的困扰,几乎支持5.0以上的任何系统。并且拥有 **快速**、**方便**、**成功率高** 的优点。一般只需要几秒钟即可完成对已安装包括未安装应用脱壳。**未安装应用**脱壳时间主要花费在复制文件IO消耗上,由应用大小决定速度。已安装应用一般在数秒内即可完成脱壳。 +### 脱壳文件说明 +- hook_xxxx.dex **hook系统api脱壳的dex,深度脱壳不修复** +- cookie_xxxx.dex **利用dexFile cookie脱壳的dex,深度脱壳时会修复此dex** + + ## 脱壳原理 通过DexFile cookie进行脱壳,理论兼容art开始的所有版本。可能少数因设备而异,绝大部分是支持的。资源有限无法大量测试,遇到问题请提issues. @@ -49,6 +54,7 @@ BlackDex下载:https://github.com/CodingGay/BlackDex/releases - [Dreamland](https://github.com/canyie/Dreamland) - [lkchandexfile](https://github.com/lkchan724/lkchandexfile) - [xhook](https://github.com/iqiyi/xHook) +- [Dobby](https://github.com/jmpews/Dobby) ### License > ``` diff --git a/app/src/main/java/top/niunaijun/blackdex/data/DexDumpRepository.kt b/app/src/main/java/top/niunaijun/blackdex/data/DexDumpRepository.kt index 21b0d18c..9e232115 100644 --- a/app/src/main/java/top/niunaijun/blackdex/data/DexDumpRepository.kt +++ b/app/src/main/java/top/niunaijun/blackdex/data/DexDumpRepository.kt @@ -10,11 +10,11 @@ import kotlinx.coroutines.launch import top.niunaijun.blackbox.BlackBoxCore import top.niunaijun.blackbox.BlackBoxCore.getPackageManager import top.niunaijun.blackbox.BlackDexCore +import top.niunaijun.blackbox.entity.pm.InstallResult import top.niunaijun.blackbox.utils.AbiUtils -import top.niunaijun.blackbox.utils.FileUtils +import top.niunaijun.blackdex.R import top.niunaijun.blackdex.app.App import top.niunaijun.blackdex.app.AppManager -import top.niunaijun.blackdex.app.BlackDexLoader import top.niunaijun.blackdex.data.entity.AppInfo import top.niunaijun.blackdex.data.entity.DumpInfo import java.io.File @@ -55,9 +55,7 @@ class DexDumpRepository { } fun dumpDex(source: String, dexDumpLiveData: MutableLiveData) { - dexDumpLiveData.postValue(DumpInfo(DumpInfo.LOADING)) - val result = if (URLUtil.isValidUrl(source)) { BlackDexCore.get().dumpDex(Uri.parse(source)) } else if (source.contains("/")) { @@ -66,13 +64,12 @@ class DexDumpRepository { BlackDexCore.get().dumpDex(source) } - if (result) { + if (result != null) { dumpTaskId++ - startCountdown(dexDumpLiveData) + startCountdown(result, dexDumpLiveData) } else { dexDumpLiveData.postValue(DumpInfo(DumpInfo.TIMEOUT)) } - } @@ -80,11 +77,11 @@ class DexDumpRepository { dumpTaskId++ } - private fun startCountdown(dexDumpLiveData: MutableLiveData) { + private fun startCountdown(installResult: InstallResult, dexDumpLiveData: MutableLiveData) { GlobalScope.launch { val tempId = dumpTaskId while (BlackDexCore.get().isRunning) { - delay(10000) + delay(20000) //10s if (!AppManager.mBlackBoxLoader.isFixCodeItem()) { break @@ -92,7 +89,14 @@ class DexDumpRepository { //fixCodeItem 需要长时间运行,普通内存dump不需要 } if (tempId == dumpTaskId) { - dexDumpLiveData.postValue(DumpInfo(DumpInfo.TIMEOUT)) + if (BlackDexCore.get().isExistDexFile(installResult.packageName)) { + dexDumpLiveData.postValue( DumpInfo( + DumpInfo.SUCCESS, + App.getContext().getString(R.string.dex_save, File(BlackBoxCore.get().dexDumpDir, installResult.packageName).absolutePath) + )) + } else { + dexDumpLiveData.postValue(DumpInfo(DumpInfo.TIMEOUT)) + } } } } diff --git a/app/src/main/java/top/niunaijun/blackdex/view/main/MainActivity.kt b/app/src/main/java/top/niunaijun/blackdex/view/main/MainActivity.kt index 91a7f4bf..68deab8f 100644 --- a/app/src/main/java/top/niunaijun/blackdex/view/main/MainActivity.kt +++ b/app/src/main/java/top/niunaijun/blackdex/view/main/MainActivity.kt @@ -135,7 +135,6 @@ class MainActivity : PermissionActivity() { startActivity(intent) } positiveButton(res = R.string.confirm) - } } else -> {