From fe8bc173dfc3a50dc18415b62ddd974ec2386804 Mon Sep 17 00:00:00 2001 From: Thays Grazia Date: Fri, 12 Mar 2021 14:00:59 -0300 Subject: [PATCH] [mono][debugger] Implementing mscordbi to support iCorDebug on mono runtime (#47639) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Implementing mscordbi on mono to support icordebug * Fix eval, fix step and cancel step, remove suspend status on mscordbi * Using log from coreclr as mscordbi does * Missing files * Removing eglib from implementation * Compiling on Mac * Compiling and Working on windows. Changing what @lambdageek suggested about mono_atomic_inc_i32 * Generating libmscordbi on mac * Fix socket on mac * Counting references, deleting objects, removing unecessary properties, formating with cland-format, renaming properties to follow the used pattern. * Checking error when get reply from debugger * Fix format, reuse regmeta from coreclr and try to fix compilation on windows * Dont build when target is android or ios or wasm * Fix error unused variable * Fixing error: 'CFUserNotificationDisplayAlert' is unavailable: not available on macCatalyst * Fix compilation error on Linux * Fix function not found in maccatalyst Fix warning as error of macro redefinition * Dont compile mscordbi on maccatalyst * Fix compilation on linux * Fix compilation on android, ios and browser * Fix compilation on linux * Fix cross compiling * Fix compilation x86 windows * Fix x86 compilation * Fix compilation on windows * Fix cmake error * Fix cmake * Fix arm64 mac * Fix windows compilation * Fix memory leak * Returning E_NOTIMPL where it was possible and it's not implemented as suggested by @cshung * Fix what @cshung * Use only one ref count * Adding ex_try everywhere that we could have an allocation failure. * Implementing get class * Apply suggestions from code review Co-authored-by: Noah Falk * Fix what @noahfalk suggested in his review. * Fixing what was suggested by @viniciusjarina * Fix what was suggested by @viniciusjarina * Changing what @noahfalk suggested * Accept more than 1 stepper per thread * Changing what was suggested by @noahfalk * Using CORDB_ADDRESS to return addresses from debugged process * Fix eval * Update src/mono/mono/mini/debugger-agent.c Co-authored-by: Aleksey Kliger (λgeek) * Using 1:1 with runtime for cordbtype and cordbclass * Rnaming methods as suggested by @lambdageek * Update src/mono/dbi/cordb-process.h Co-authored-by: Aleksey Kliger (λgeek) * Update CMakeLists.txt * Fix arm64 compilation * Fix arm64 compilation * Fix error cmake * fix arm64 compilation * Fix arm64 compilation * Fix arm64 compilation * Fix arm64 compilation * Revert "Fix arm64 compilation" This reverts commit 25f24bc7ac66966fe59805e54e4009c909608b2c. * Revert "Fix arm64 compilation" This reverts commit a8f0318881d7b3e6b5a69b1b56c17478a71fdb4f. * Revert "fix arm64 compilation" This reverts commit b5de06dcf00bf296f2c8f4b47aa2492afbd73acd. * Revert "Fix error cmake" This reverts commit 2aae4636499d073ca5aa6fb9319d84875be6e08e. * Revert "Fix arm64 compilation" This reverts commit ae5f701589c3bd8ca04b9d9369af2b285a5d9bd0. * Revert "Fix arm64 compilation" This reverts commit 94d957c7416a900c9e90dec53900a104572ea6a1. * Removing arm64 compilation * Remove arm64 compilation Co-authored-by: Noah Falk Co-authored-by: Aleksey Kliger (λgeek) --- eng/native/configureplatform.cmake | 4 +- src/coreclr/clrdefinitions.cmake | 2 +- src/coreclr/pal/src/configure.cmake | 2 +- src/coreclr/pal/src/libunwind/configure.cmake | 2 +- src/coreclr/pal/src/synchmgr/synchmanager.cpp | 6 +- src/coreclr/utilcode/ccomprc.cpp | 4 + src/mono/CMakeLists.txt | 8 + src/mono/dbi/CMakeLists.txt | 151 ++ src/mono/dbi/cordb-appdomain.cpp | 293 ++++ src/mono/dbi/cordb-appdomain.h | 92 ++ src/mono/dbi/cordb-assembly.cpp | 426 ++++++ src/mono/dbi/cordb-assembly.h | 107 ++ src/mono/dbi/cordb-blocking-obj.cpp | 53 + src/mono/dbi/cordb-blocking-obj.h | 36 + src/mono/dbi/cordb-breakpoint.cpp | 89 ++ src/mono/dbi/cordb-breakpoint.h | 52 + src/mono/dbi/cordb-chain.cpp | 154 +++ src/mono/dbi/cordb-chain.h | 74 + src/mono/dbi/cordb-class.cpp | 90 ++ src/mono/dbi/cordb-class.h | 43 + src/mono/dbi/cordb-code.cpp | 152 +++ src/mono/dbi/cordb-code.h | 51 + src/mono/dbi/cordb-eval.cpp | 263 ++++ src/mono/dbi/cordb-eval.h | 68 + src/mono/dbi/cordb-frame.cpp | 541 ++++++++ src/mono/dbi/cordb-frame.h | 158 +++ src/mono/dbi/cordb-function.cpp | 210 +++ src/mono/dbi/cordb-function.h | 65 + src/mono/dbi/cordb-process.cpp | 809 +++++++++++ src/mono/dbi/cordb-process.h | 143 ++ src/mono/dbi/cordb-register.cpp | 53 + src/mono/dbi/cordb-register.h | 40 + src/mono/dbi/cordb-stepper.cpp | 148 ++ src/mono/dbi/cordb-stepper.h | 48 + src/mono/dbi/cordb-symbol.h | 667 +++++++++ src/mono/dbi/cordb-thread.cpp | 299 ++++ src/mono/dbi/cordb-thread.h | 77 ++ src/mono/dbi/cordb-type.cpp | 184 +++ src/mono/dbi/cordb-type.h | 73 + src/mono/dbi/cordb-value.cpp | 1215 +++++++++++++++++ src/mono/dbi/cordb-value.h | 247 ++++ src/mono/dbi/cordb.cpp | 600 ++++++++ src/mono/dbi/cordb.h | 241 ++++ src/mono/dbi/debugger-coreclr-compat.h | 22 + src/mono/dbi/socket-dbi/CMakeLists.txt | 10 + src/mono/dbi/socket-dbi/socket.cpp | 105 ++ src/mono/dbi/socket-dbi/socket.h | 20 + src/mono/mono/mini/debugger-agent.c | 90 +- src/mono/mono/mini/debugger-mono-compat.h | 21 + src/mono/mono/mini/debugger-protocol.c | 60 +- src/mono/mono/mini/debugger-protocol.h | 25 +- src/mono/mono/mini/mini-amd64.c | 6 + src/mono/mono/mini/mini-arm.c | 6 + src/mono/mono/mini/mini-arm64.c | 6 + src/mono/mono/mini/mini-mips.c | 6 + src/mono/mono/mini/mini-ppc.c | 9 + src/mono/mono/mini/mini-riscv.c | 6 + src/mono/mono/mini/mini-s390x.c | 6 + src/mono/mono/mini/mini-sparc.c | 7 + src/mono/mono/mini/mini-wasm.c | 7 + src/mono/mono/mini/mini-x86.c | 18 + src/mono/mono/mini/mini.h | 1 + 62 files changed, 8411 insertions(+), 60 deletions(-) create mode 100644 src/mono/dbi/CMakeLists.txt create mode 100644 src/mono/dbi/cordb-appdomain.cpp create mode 100644 src/mono/dbi/cordb-appdomain.h create mode 100644 src/mono/dbi/cordb-assembly.cpp create mode 100644 src/mono/dbi/cordb-assembly.h create mode 100644 src/mono/dbi/cordb-blocking-obj.cpp create mode 100644 src/mono/dbi/cordb-blocking-obj.h create mode 100644 src/mono/dbi/cordb-breakpoint.cpp create mode 100644 src/mono/dbi/cordb-breakpoint.h create mode 100644 src/mono/dbi/cordb-chain.cpp create mode 100644 src/mono/dbi/cordb-chain.h create mode 100644 src/mono/dbi/cordb-class.cpp create mode 100644 src/mono/dbi/cordb-class.h create mode 100644 src/mono/dbi/cordb-code.cpp create mode 100644 src/mono/dbi/cordb-code.h create mode 100644 src/mono/dbi/cordb-eval.cpp create mode 100644 src/mono/dbi/cordb-eval.h create mode 100644 src/mono/dbi/cordb-frame.cpp create mode 100644 src/mono/dbi/cordb-frame.h create mode 100644 src/mono/dbi/cordb-function.cpp create mode 100644 src/mono/dbi/cordb-function.h create mode 100644 src/mono/dbi/cordb-process.cpp create mode 100644 src/mono/dbi/cordb-process.h create mode 100644 src/mono/dbi/cordb-register.cpp create mode 100644 src/mono/dbi/cordb-register.h create mode 100644 src/mono/dbi/cordb-stepper.cpp create mode 100644 src/mono/dbi/cordb-stepper.h create mode 100644 src/mono/dbi/cordb-symbol.h create mode 100644 src/mono/dbi/cordb-thread.cpp create mode 100644 src/mono/dbi/cordb-thread.h create mode 100644 src/mono/dbi/cordb-type.cpp create mode 100644 src/mono/dbi/cordb-type.h create mode 100644 src/mono/dbi/cordb-value.cpp create mode 100644 src/mono/dbi/cordb-value.h create mode 100644 src/mono/dbi/cordb.cpp create mode 100644 src/mono/dbi/cordb.h create mode 100644 src/mono/dbi/debugger-coreclr-compat.h create mode 100644 src/mono/dbi/socket-dbi/CMakeLists.txt create mode 100644 src/mono/dbi/socket-dbi/socket.cpp create mode 100644 src/mono/dbi/socket-dbi/socket.h create mode 100644 src/mono/mono/mini/debugger-mono-compat.h diff --git a/eng/native/configureplatform.cmake b/eng/native/configureplatform.cmake index 9e7e7743c0f9e..25d10118d922a 100644 --- a/eng/native/configureplatform.cmake +++ b/eng/native/configureplatform.cmake @@ -41,9 +41,9 @@ if(CLR_CMAKE_HOST_OS STREQUAL Linux) set(CLR_CMAKE_HOST_UNIX_ARMV7L 1) elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL arm OR CMAKE_SYSTEM_PROCESSOR STREQUAL armv7-a) set(CLR_CMAKE_HOST_UNIX_ARM 1) - elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64) + elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL aarch64 OR CMAKE_SYSTEM_PROCESSOR STREQUAL arm64) set(CLR_CMAKE_HOST_UNIX_ARM64 1) - elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL i686) + elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL i686 OR CMAKE_SYSTEM_PROCESSOR STREQUAL x86) set(CLR_CMAKE_HOST_UNIX_X86 1) else() clr_unknown_arch() diff --git a/src/coreclr/clrdefinitions.cmake b/src/coreclr/clrdefinitions.cmake index 9c774cd4aeb92..115031ff49b6c 100644 --- a/src/coreclr/clrdefinitions.cmake +++ b/src/coreclr/clrdefinitions.cmake @@ -1,4 +1,4 @@ -include(clrfeatures.cmake) +include(${CMAKE_CURRENT_LIST_DIR}/clrfeatures.cmake) add_compile_definitions($<$>:DACCESS_COMPILE>) add_compile_definitions($<$>:CROSSGEN_COMPILE>) diff --git a/src/coreclr/pal/src/configure.cmake b/src/coreclr/pal/src/configure.cmake index 28f8d708afdd6..ee4a3241196ea 100644 --- a/src/coreclr/pal/src/configure.cmake +++ b/src/coreclr/pal/src/configure.cmake @@ -1402,4 +1402,4 @@ check_prototype_definition( ${STATFS_INCLUDES} HAVE_NON_LEGACY_STATFS) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h) +configure_file(${CMAKE_CURRENT_LIST_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/config.h) diff --git a/src/coreclr/pal/src/libunwind/configure.cmake b/src/coreclr/pal/src/libunwind/configure.cmake index 8e9c00abfbeb9..e721db79f403b 100644 --- a/src/coreclr/pal/src/libunwind/configure.cmake +++ b/src/coreclr/pal/src/libunwind/configure.cmake @@ -69,7 +69,7 @@ int main(void) return result; }" HAVE_STDALIGN_ALIGNAS) -configure_file(${CMAKE_CURRENT_SOURCE_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/config.h) +configure_file(${CMAKE_CURRENT_LIST_DIR}/config.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/config.h) add_definitions(-DHAVE_CONFIG_H=1) configure_file(include/libunwind-common.h.in ${CMAKE_CURRENT_BINARY_DIR}/include/libunwind-common.h) diff --git a/src/coreclr/pal/src/synchmgr/synchmanager.cpp b/src/coreclr/pal/src/synchmgr/synchmanager.cpp index b1fdb82adf76a..55a343de4d669 100644 --- a/src/coreclr/pal/src/synchmgr/synchmanager.cpp +++ b/src/coreclr/pal/src/synchmgr/synchmanager.cpp @@ -4623,7 +4623,11 @@ namespace CorUnix ptsAbsTmo->tv_nsec = tv.tv_usec * tccMicroSecondsToNanoSeconds; } #else - #error "Don't know how to get hi-res current time on this platform" +#ifdef DBI_COMPONENT_MONO + return ERROR_INTERNAL_ERROR; +#else + #error "Don't know how to get hi-res current time on this platform" +#endif #endif // HAVE_WORKING_CLOCK_GETTIME, HAVE_WORKING_GETTIMEOFDAY #if HAVE_CLOCK_MONOTONIC && HAVE_PTHREAD_CONDATTR_SETCLOCK } diff --git a/src/coreclr/utilcode/ccomprc.cpp b/src/coreclr/utilcode/ccomprc.cpp index 78f7f56e0bd27..134a52836deba 100644 --- a/src/coreclr/utilcode/ccomprc.cpp +++ b/src/coreclr/utilcode/ccomprc.cpp @@ -489,6 +489,9 @@ HRESULT CCompRC::LoadString(ResourceCategory eCategory, UINT iResourceID, __out_ HRESULT CCompRC::LoadString(ResourceCategory eCategory, LocaleID langId, UINT iResourceID, __out_ecount(iMax) LPWSTR szBuffer, int iMax, int *pcwchUsed) { +#ifdef DBI_COMPONENT_MONO + return E_NOTIMPL; +#else CONTRACTL { GC_NOTRIGGER; @@ -535,6 +538,7 @@ HRESULT CCompRC::LoadString(ResourceCategory eCategory, LocaleID langId, UINT iR return LoadNativeStringResource(NATIVE_STRING_RESOURCE_TABLE(NATIVE_STRING_RESOURCE_NAME), iResourceID, szBuffer, iMax, pcwchUsed); #endif // HOST_WINDOWS +#endif } #ifndef DACCESS_COMPILE diff --git a/src/mono/CMakeLists.txt b/src/mono/CMakeLists.txt index 12dbafe50ccd6..0ba506b5c241e 100644 --- a/src/mono/CMakeLists.txt +++ b/src/mono/CMakeLists.txt @@ -6,6 +6,11 @@ endif() project(mono) +set(CMAKE_C_FLAGS_CHECKED "") +set(CMAKE_CXX_FLAGS_CHECKED "") +set(CMAKE_EXE_LINKER_FLAGS_CHECKED "") +set(CMAKE_SHARED_LINKER_FLAGS_CHECKED "") + include(GNUInstallDirs) include(CheckIncludeFile) include(CheckFunctionExists) @@ -702,6 +707,9 @@ endif() ### End of OS specific checks add_subdirectory(mono) +if (NOT TARGET_ARCH STREQUAL "arm64" AND NOT CMAKE_CROSSCOMPILING AND NOT TARGET_IOS AND NOT TARGET_ANDROID AND NOT TARGET_BROWSER AND NOT HOST_MACCATALYST) + add_subdirectory(dbi) +endif() configure_file(cmake/config.h.in config.h) configure_file(cmake/eglib-config.h.cmake.in mono/eglib/eglib-config.h) # TODO: eglib-config.h is not needed, we're using hardcoded eglib-config.hw diff --git a/src/mono/dbi/CMakeLists.txt b/src/mono/dbi/CMakeLists.txt new file mode 100644 index 0000000000000..9a0c2367e072d --- /dev/null +++ b/src/mono/dbi/CMakeLists.txt @@ -0,0 +1,151 @@ +project(mscordbi) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(CMAKE_EXPORT_COMPILE_COMMANDS ON) +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + +set(CLR_DIR ${PROJECT_SOURCE_DIR}/../../coreclr) +set(VM_DIR ${PROJECT_SOURCE_DIR}/../../coreclr/vm) +set(CMAKE_OSX_ARCHITECTURES ${CMAKE_SYSTEM_PROCESSOR}) +set(CMAKE_EXE_LINKER_FLAGS_CHECKED "") +set(CMAKE_SHARED_LINKER_FLAGS_CHECKED "") +set(CLR_CMAKE_HOST_ARCH ${CMAKE_GENERATOR_PLATFORM}) +set(FEATURE_EVENT_TRACE 0) + +if(HOST_WIN32) + if(HOST_X86) + set(CLR_CMAKE_HOST_ARCH x86) + elseif(HOST_ARM64) + set(CLR_CMAKE_HOST_ARCH arm64) + elseif(HOST_ARM) + set(CLR_CMAKE_HOST_ARCH arm) + elseif(HOST_AMD64) + set(CLR_CMAKE_HOST_ARCH x64) + endif() +endif() + +add_definitions(-DDBI_COMPONENT_MONO) + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR}/../.. + ${PROJECT_SOURCE_DIR}/../ + ${PROJECT_SOURCE_DIR}/../dbi + ${PROJECT_SOURCE_DIR}/../dbi/socket-dbi + ${PROJECT_SOURCE_DIR}/../../coreclr/md/enc + ${PROJECT_SOURCE_DIR}/../../coreclr/inc + ${PROJECT_SOURCE_DIR}/../../coreclr/md/inc + ${PROJECT_SOURCE_DIR}/../../coreclr/md/compiler) + +set(mscorbi_sources_base + cordb.cpp + cordb.h + cordb-appdomain.cpp + cordb-appdomain.h + cordb-assembly.cpp + cordb-assembly.h + cordb-blocking-obj.cpp + cordb-blocking-obj.h + cordb-breakpoint.cpp + cordb-breakpoint.h + cordb-chain.cpp + cordb-chain.h + cordb-class.cpp + cordb-class.h + cordb-code.cpp + cordb-code.h + cordb-eval.cpp + cordb-eval.h + cordb-frame.cpp + cordb-frame.h + cordb-function.cpp + cordb-function.h + cordb-process.cpp + cordb-process.h + cordb-register.cpp + cordb-register.h + cordb-stepper.cpp + cordb-stepper.h + cordb-thread.cpp + cordb-thread.h + cordb-type.cpp + cordb-type.h + cordb-value.cpp + cordb-value.h +) + + +if(HOST_DARWIN) +set(OS_LIBS "-framework CoreFoundation" "-framework Foundation") +elseif(HOST_LINUX) +set(OS_LIBS pthread m dl) +elseif(HOST_WIN32) +set(OS_LIBS bcrypt.lib Mswsock.lib ws2_32.lib psapi.lib version.lib advapi32.lib winmm.lib kernel32.lib) +endif() + +addprefix(mscorbi_sources ../dbi/ "${mscorbi_sources_base}") +add_subdirectory(${PROJECT_SOURCE_DIR}/socket-dbi) + +include(${PROJECT_SOURCE_DIR}/../../../eng/native/configuretools.cmake) +include(${PROJECT_SOURCE_DIR}/../../../eng/native/configurepaths.cmake) +include(${PROJECT_SOURCE_DIR}/../../../eng/native/configureplatform.cmake) +include(${PROJECT_SOURCE_DIR}/../../../eng/native/configurecompiler.cmake) + +if (CLR_CMAKE_HOST_UNIX) + include_directories("${PROJECT_SOURCE_DIR}/../../coreclr/pal/inc") + include_directories("${PROJECT_SOURCE_DIR}/../../coreclr/pal/inc/rt") + include_directories("${PROJECT_SOURCE_DIR}/../../coreclr/pal/src/safecrt") + + append("-Wno-missing-prototypes -Wno-pointer-arith -Wno-macro-redefined" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) + add_subdirectory(${PROJECT_SOURCE_DIR}/../../coreclr/pal pal) + + include_directories("../../coreclr/pal/inc/rt/cpp") + add_compile_options(-nostdinc) +endif (CLR_CMAKE_HOST_UNIX) + +include_directories("../../coreclr/pal/prebuilt/inc") +include_directories("../../coreclr/nativeresources") + +if (CLR_CMAKE_HOST_UNIX) + add_subdirectory(${PROJECT_SOURCE_DIR}/../../coreclr/nativeresources nativeresources) +endif() + +add_subdirectory(${PROJECT_SOURCE_DIR}/../../coreclr/md/runtime md/runtime) +add_subdirectory(${PROJECT_SOURCE_DIR}/../../coreclr/md/compiler md/compiler) + +include(${PROJECT_SOURCE_DIR}/../../coreclr/clrdefinitions.cmake) +include_directories(${CMAKE_CURRENT_BINARY_DIR}/../) +include_directories(${CMAKE_CURRENT_BINARY_DIR}/../inc/) +add_subdirectory(${PROJECT_SOURCE_DIR}/../../coreclr/md/enc md/enc) +add_subdirectory(${PROJECT_SOURCE_DIR}/../../coreclr/utilcode utilcode) +if (CLR_CMAKE_HOST_UNIX) + add_subdirectory(${PROJECT_SOURCE_DIR}/../../coreclr/palrt palrt) + append("-Wno-strict-prototypes -Wno-deprecated -Wno-pointer-arith" CMAKE_C_FLAGS CMAKE_CXX_FLAGS) +endif (CLR_CMAKE_HOST_UNIX) + +add_library(mscordbi SHARED "${mscorbi_sources};${PROJECT_SOURCE_DIR}/../mono/mini/debugger-protocol.c;${PROJECT_SOURCE_DIR}/../../coreclr/pal/prebuilt/idl/xcordebug_i.cpp;${PROJECT_SOURCE_DIR}/../../coreclr/pal/prebuilt/idl/cordebug_i.cpp") + +#SET(CMAKE_C_COMPILER ${CMAKE_CXX_COMPILER}) + +set_source_files_properties(${PROJECT_SOURCE_DIR}/../mono/mini/debugger-protocol.c PROPERTIES LANGUAGE CXX) + +set(COREDBI_LIBRARIES + utilcodestaticnohost + mdruntime-dbi + mdcompiler-dbi + mdruntimerw-dbi + socket-dbi + ${OS_LIBS} +) + +if(CLR_CMAKE_HOST_UNIX) + list(APPEND COREDBI_LIBRARIES + coreclrpal + palrt + nativeresourcestring + ) +endif() + +target_link_libraries(mscordbi ${COREDBI_LIBRARIES} ) +install(TARGETS mscordbi DESTINATION lib) diff --git a/src/mono/dbi/cordb-appdomain.cpp b/src/mono/dbi/cordb-appdomain.cpp new file mode 100644 index 0000000000000..d59b942fdcf53 --- /dev/null +++ b/src/mono/dbi/cordb-appdomain.cpp @@ -0,0 +1,293 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: CORDB-APPDOMAIN.CPP +// + +#include +#include +#include + +using namespace std; + +CordbAppDomain::CordbAppDomain(Connection* conn, CordbProcess* ppProcess) : CordbBaseMono(conn) +{ + pProcess = ppProcess; + pProcess->AddAppDomain(this); +} + +HRESULT CordbAppDomain::Stop(DWORD dwTimeoutIgnored) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbAppDomain - Stop - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbAppDomain::Continue(BOOL fIsOutOfBand) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbAppDomain - Continue - IMPLEMENTED\n")); + pProcess->Continue(fIsOutOfBand); + return S_OK; +} + +HRESULT CordbAppDomain::IsRunning(BOOL* pbRunning) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbAppDomain - IsRunning - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbAppDomain::HasQueuedCallbacks(ICorDebugThread* pThread, BOOL* pbQueued) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbAppDomain - HasQueuedCallbacks - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT +CordbAppDomain::EnumerateThreads(ICorDebugThreadEnum** ppThreads) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbAppDomain - EnumerateThreads - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT +CordbAppDomain::SetAllThreadsDebugState(CorDebugThreadState state, ICorDebugThread* pExceptThisThread) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbAppDomain - SetAllThreadsDebugState - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbAppDomain::Detach(void) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbAppDomain - Detach - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbAppDomain::Terminate(UINT exitCode) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbAppDomain - Terminate - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT +CordbAppDomain::CanCommitChanges(ULONG cSnapshots, + ICorDebugEditAndContinueSnapshot* pSnapshots[], + ICorDebugErrorInfoEnum** pError) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbAppDomain - CanCommitChanges - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT +CordbAppDomain::CommitChanges(ULONG cSnapshots, + ICorDebugEditAndContinueSnapshot* pSnapshots[], + ICorDebugErrorInfoEnum** pError) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbAppDomain - CommitChanges - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbAppDomain::QueryInterface(REFIID id, _COM_Outptr_ void __RPC_FAR* __RPC_FAR* ppInterface) +{ + if (id == IID_ICorDebugAppDomain) + { + *ppInterface = (ICorDebugAppDomain*)this; + } + else if (id == IID_ICorDebugAppDomain2) + { + *ppInterface = (ICorDebugAppDomain2*)this; + } + else if (id == IID_ICorDebugAppDomain3) + { + *ppInterface = (ICorDebugAppDomain3*)this; + } + else if (id == IID_ICorDebugAppDomain4) + { + *ppInterface = (ICorDebugAppDomain4*)this; + } + else if (id == IID_ICorDebugController) + *ppInterface = (ICorDebugController*)(ICorDebugAppDomain*)this; + else if (id == IID_IUnknown) + *ppInterface = (IUnknown*)(ICorDebugAppDomain*)this; + else + { + *ppInterface = NULL; + return E_NOINTERFACE; + } + AddRef(); + return S_OK; +} + +HRESULT CordbAppDomain::GetProcess(ICorDebugProcess** ppProcess) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbAppDomain - GetProcess - IMPLEMENTED\n")); + pProcess->QueryInterface(IID_ICorDebugProcess, (void**)ppProcess); + return S_OK; +} + +HRESULT +CordbAppDomain::EnumerateAssemblies(ICorDebugAssemblyEnum** ppAssemblies) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbAppDomain - EnumerateAssemblies - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT +CordbAppDomain::GetModuleFromMetaDataInterface(IUnknown* pIMetaData, ICorDebugModule** ppModule) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbAppDomain - GetModuleFromMetaDataInterface - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT +CordbAppDomain::EnumerateBreakpoints(ICorDebugBreakpointEnum** ppBreakpoints) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbAppDomain - EnumerateBreakpoints - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbAppDomain::EnumerateSteppers(ICorDebugStepperEnum** ppSteppers) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbAppDomain - EnumerateSteppers - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbAppDomain::IsAttached(BOOL* pbAttached) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbAppDomain - IsAttached - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT +CordbAppDomain::GetName(ULONG32 cchName, ULONG32* pcchName, WCHAR szName[]) +{ + LOG((LF_CORDB, LL_INFO1000000, "CordbAppDomain - GetName - IMPLEMENTED\n")); + if (cchName < strlen("DefaultDomain")) + { + *pcchName = (ULONG32)strlen("DefaultDomain") + 1; + return S_OK; + } + wcscpy(szName, W("DefaultDomain")); + + return S_OK; +} + +HRESULT CordbAppDomain::GetObject(ICorDebugValue** ppObject) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbAppDomain - GetObject - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbAppDomain::Attach(void) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbAppDomain - Attach - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbAppDomain::GetID(ULONG32* pId) +{ + *pId = 0; + LOG((LF_CORDB, LL_INFO1000000, "CordbAppDomain - GetID - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbAppDomain::GetArrayOrPointerType(CorElementType elementType, + ULONG32 nRank, + + ICorDebugType* pTypeArg, + ICorDebugType** ppType) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbAppDomain - GetArrayOrPointerType - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbAppDomain::GetFunctionPointerType(ULONG32 nTypeArgs, ICorDebugType* ppTypeArgs[], ICorDebugType** ppType) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbAppDomain - GetFunctionPointerType - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbAppDomain::GetCachedWinRTTypesForIIDs(ULONG32 cReqTypes, + GUID* iidsToResolve, + ICorDebugTypeEnum** ppTypesEnum) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbAppDomain - GetCachedWinRTTypesForIIDs - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbAppDomain::GetCachedWinRTTypes(ICorDebugGuidToTypeEnum** ppGuidToTypeEnum) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbAppDomain - GetCachedWinRTTypes - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT +CordbAppDomain::GetObjectForCCW(CORDB_ADDRESS ccwPointer, ICorDebugValue** ppManagedObject) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbAppDomain - GetObjectForCCW - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbAppDomainEnum::Next(ULONG celt, ICorDebugAppDomain* values[], ULONG* pceltFetched) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbAppDomainEnum - Next - NOT IMPLEMENTED\n")); + *pceltFetched = celt; + for (ULONG i = 0; i < celt; i++) + { + if (current_pos >= pProcess->m_pAddDomains->GetCount()) + { + *pceltFetched = 0; + return S_FALSE; + } + CordbAppDomain* appdomain = (CordbAppDomain*)pProcess->m_pAddDomains->Get(current_pos); + appdomain->QueryInterface(IID_ICorDebugAppDomain, (void**)values + current_pos); + current_pos++; + } + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbAppDomainEnum::Skip(ULONG celt) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbAppDomainEnum - Skip - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbAppDomainEnum::Reset(void) +{ + current_pos = 0; + LOG((LF_CORDB, LL_INFO100000, "CordbAppDomainEnum - Reset - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbAppDomainEnum::Clone(ICorDebugEnum** ppEnum) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbAppDomainEnum - Clone - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbAppDomainEnum::GetCount(ULONG* pcelt) +{ + LOG((LF_CORDB, LL_INFO1000000, "CordbAppDomainEnum - GetCount - IMPLEMENTED\n")); + *pcelt = pProcess->m_pAddDomains->GetCount(); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbAppDomainEnum::QueryInterface(REFIID id, void** pInterface) +{ + if (id == IID_IUnknown) + *pInterface = static_cast(static_cast(this)); + else if (id == IID_ICorDebugAppDomainEnum) + *pInterface = static_cast(this); + else if (id == IID_ICorDebugEnum) + *pInterface = static_cast(this); + else + { + return E_NOINTERFACE; + } + AddRef(); + return S_OK; +} + +CordbAppDomainEnum::CordbAppDomainEnum(Connection* conn, CordbProcess* ppProcess) : CordbBaseMono(conn) +{ + current_pos = 0; + this->pProcess = ppProcess; +} diff --git a/src/mono/dbi/cordb-appdomain.h b/src/mono/dbi/cordb-appdomain.h new file mode 100644 index 0000000000000..5adbe154575c6 --- /dev/null +++ b/src/mono/dbi/cordb-appdomain.h @@ -0,0 +1,92 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: CORDB-APPDOMAIN.H +// + +#ifndef __MONO_DEBUGGER_CORDB_APPDOMAIN_H__ +#define __MONO_DEBUGGER_CORDB_APPDOMAIN_H__ + +#include + +class CordbAppDomain : public CordbBaseMono, + public ICorDebugAppDomain, + public ICorDebugAppDomain2, + public ICorDebugAppDomain3, + public ICorDebugAppDomain4 +{ + CordbProcess* pProcess; + +public: + CordbAppDomain(Connection* conn, CordbProcess* ppProcess); + ULONG STDMETHODCALLTYPE AddRef(void) + { + return (BaseAddRef()); + } + ULONG STDMETHODCALLTYPE Release(void) + { + return (BaseRelease()); + } + const char* GetClassName() + { + return "CordbAppDomain"; + } + HRESULT STDMETHODCALLTYPE Stop(DWORD dwTimeoutIgnored); + HRESULT STDMETHODCALLTYPE Continue(BOOL fIsOutOfBand); + HRESULT STDMETHODCALLTYPE IsRunning(BOOL* pbRunning); + HRESULT STDMETHODCALLTYPE HasQueuedCallbacks(ICorDebugThread* pThread, BOOL* pbQueued); + HRESULT STDMETHODCALLTYPE EnumerateThreads(ICorDebugThreadEnum** ppThreads); + HRESULT STDMETHODCALLTYPE SetAllThreadsDebugState(CorDebugThreadState state, ICorDebugThread* pExceptThisThread); + HRESULT STDMETHODCALLTYPE Detach(void); + HRESULT STDMETHODCALLTYPE Terminate(UINT exitCode); + HRESULT STDMETHODCALLTYPE CanCommitChanges(ULONG cSnapshots, ICorDebugEditAndContinueSnapshot* pSnapshots[], ICorDebugErrorInfoEnum** pError); + HRESULT STDMETHODCALLTYPE CommitChanges(ULONG cSnapshots, ICorDebugEditAndContinueSnapshot* pSnapshots[], ICorDebugErrorInfoEnum** pError); + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id, _COM_Outptr_ void __RPC_FAR* __RPC_FAR* ppInterface); + HRESULT STDMETHODCALLTYPE GetProcess(ICorDebugProcess** ppProcess); + HRESULT STDMETHODCALLTYPE EnumerateAssemblies(ICorDebugAssemblyEnum** ppAssemblies); + HRESULT STDMETHODCALLTYPE GetModuleFromMetaDataInterface(IUnknown* pIMetaData, ICorDebugModule** ppModule); + HRESULT STDMETHODCALLTYPE EnumerateBreakpoints(ICorDebugBreakpointEnum** ppBreakpoints); + HRESULT STDMETHODCALLTYPE EnumerateSteppers(ICorDebugStepperEnum** ppSteppers); + HRESULT STDMETHODCALLTYPE IsAttached(BOOL* pbAttached); + HRESULT STDMETHODCALLTYPE GetName(ULONG32 cchName, ULONG32* pcchName, WCHAR szName[]); + HRESULT STDMETHODCALLTYPE GetObject(ICorDebugValue** ppObject); + HRESULT STDMETHODCALLTYPE Attach(void); + HRESULT STDMETHODCALLTYPE GetID(ULONG32* pId); + HRESULT STDMETHODCALLTYPE GetArrayOrPointerType(CorElementType elementType, + ULONG32 nRank, + ICorDebugType* pTypeArg, + ICorDebugType** ppType); + HRESULT STDMETHODCALLTYPE GetFunctionPointerType(ULONG32 nTypeArgs, ICorDebugType* ppTypeArgs[], ICorDebugType** ppType); + HRESULT STDMETHODCALLTYPE GetCachedWinRTTypesForIIDs(ULONG32 cReqTypes, GUID* iidsToResolve, ICorDebugTypeEnum** ppTypesEnum); + HRESULT STDMETHODCALLTYPE GetCachedWinRTTypes(ICorDebugGuidToTypeEnum** ppGuidToTypeEnum); + HRESULT STDMETHODCALLTYPE GetObjectForCCW(CORDB_ADDRESS ccwPointer, ICorDebugValue** ppManagedObject); +}; + +class CordbAppDomainEnum : public CordbBaseMono, public ICorDebugAppDomainEnum +{ + DWORD current_pos; + CordbProcess* pProcess; + +public: + CordbAppDomainEnum(Connection* conn, CordbProcess* ppProcess); + ULONG STDMETHODCALLTYPE AddRef(void) + { + return (BaseAddRef()); + } + ULONG STDMETHODCALLTYPE Release(void) + { + return (BaseRelease()); + } + const char* GetClassName() + { + return "CordbAppDomainEnum"; + } + HRESULT STDMETHODCALLTYPE Next(ULONG celt, ICorDebugAppDomain* values[], ULONG* pceltFetched); + HRESULT STDMETHODCALLTYPE Skip(ULONG celt); + HRESULT STDMETHODCALLTYPE Reset(void); + HRESULT STDMETHODCALLTYPE Clone(ICorDebugEnum** ppEnum); + HRESULT STDMETHODCALLTYPE GetCount(ULONG* pcelt); + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject); +}; + +#endif diff --git a/src/mono/dbi/cordb-assembly.cpp b/src/mono/dbi/cordb-assembly.cpp new file mode 100644 index 0000000000000..95add50bb3b47 --- /dev/null +++ b/src/mono/dbi/cordb-assembly.cpp @@ -0,0 +1,426 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: CORDB-ASSEMBLY.CPP +// + +#include +#include +#include +#include +#include +#include +#include "corerror.h" +#include "metamodel.h" +#include "metamodelpub.h" +#include "rwutil.h" +#include "stdafx.h" +#include "stgio.h" + +#include "importhelper.h" + +#include +#include "mdlog.h" +#include "mdperf.h" +#include "regmeta.h" +#include "ex.h" + +using namespace std; + +CordbAssembly::CordbAssembly(Connection* conn, CordbProcess* process, CordbAppDomain* appDomain, int id_assembly) + : CordbBaseMono(conn) +{ + m_pProcess = process; + m_pAppDomain = appDomain; + m_pAppDomain->InternalAddRef(); + m_debuggerId = id_assembly; +} + +CordbAssembly::~CordbAssembly() +{ + m_pAppDomain->InternalRelease(); +} + +HRESULT CordbAssembly::IsFullyTrusted(BOOL* pbFullyTrusted) +{ + *pbFullyTrusted = true; + LOG((LF_CORDB, LL_INFO100000, "CorDebugAssembly - IsFullyTrusted - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbAssembly::GetAppDomain(ICorDebugAppDomain** ppAppDomain) +{ + LOG((LF_CORDB, LL_INFO1000000, "CorDebugAssembly - GetAppDomain - IMPLEMENTED\n")); + m_pAppDomain->QueryInterface(IID_ICorDebugAppDomain, (void**)ppAppDomain); + return S_OK; +} + +HRESULT CordbAssembly::EnumerateModules(ICorDebugModuleEnum** ppModules) +{ + LOG((LF_CORDB, LL_INFO100000, "CorDebugAssembly - EnumerateModules - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbAssembly::GetCodeBase(ULONG32 cchName, ULONG32* pcchName, WCHAR szName[]) +{ + LOG((LF_CORDB, LL_INFO100000, "CorDebugAssembly - GetCodeBase - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbAssembly::GetName(ULONG32 cchName, ULONG32* pcchName, WCHAR szName[]) +{ + LOG((LF_CORDB, LL_INFO100000, "CorDebugAssembly - GetName - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbAssembly::QueryInterface(REFIID id, _COM_Outptr_ void __RPC_FAR* __RPC_FAR* ppInterface) +{ + if (id == IID_ICorDebugAssembly) + *ppInterface = static_cast(this); + else if (id == IID_ICorDebugAssembly2) + *ppInterface = static_cast(this); + else if (id == IID_IUnknown) + *ppInterface = static_cast(static_cast(this)); + else + { + *ppInterface = NULL; + return E_NOINTERFACE; + } + AddRef(); + return S_OK; +} + +HRESULT CordbAssembly::GetProcess(ICorDebugProcess** ppProcess) +{ + LOG((LF_CORDB, LL_INFO1000000, "CorDebugAssembly - GetProcess - IMPLEMENTED\n")); + conn->GetProcess()->QueryInterface(IID_ICorDebugProcess, (void**)ppProcess); + return S_OK; +} + +CordbModule::CordbModule(Connection* conn, CordbProcess* process, CordbAssembly* assembly, int id_assembly) + : CordbBaseMono(conn) +{ + m_pProcess = process; + m_pRegMeta = NULL; + m_pAssembly = assembly; + m_debuggerId = id_assembly; + m_pAssembly->InternalAddRef(); + dwFlags = 0; + conn->GetProcess()->AddModule(this); + m_pPeImage = NULL; + m_pAssemblyName = NULL; +} + +CordbModule::~CordbModule() +{ + if (m_pAssembly) + m_pAssembly->InternalRelease(); + /*if (m_pPeImage) + free(m_pPeImage);*/ + if (m_pAssemblyName) + free(m_pAssemblyName); +} + +HRESULT CordbModule::QueryInterface(REFIID id, void** pInterface) +{ + if (id == IID_ICorDebugModule) + { + *pInterface = static_cast(this); + } + else if (id == IID_ICorDebugModule2) + { + *pInterface = static_cast(this); + } + else if (id == IID_ICorDebugModule3) + { + *pInterface = static_cast(this); + } + else if (id == IID_ICorDebugModule4) + { + *pInterface = static_cast(this); + } + else if (id == IID_IUnknown) + { + *pInterface = static_cast(static_cast(this)); + } + else + { + *pInterface = NULL; + return E_NOINTERFACE; + } + AddRef(); + return S_OK; +} + +HRESULT CordbModule::IsMappedLayout(BOOL* pIsMapped) +{ + *pIsMapped = FALSE; + LOG((LF_CORDB, LL_INFO1000000, "CordbModule - IsMappedLayout - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbModule::CreateReaderForInMemorySymbols(REFIID riid, void** ppObj) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbModule - CreateReaderForInMemorySymbols - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbModule::SetJMCStatus(BOOL bIsJustMyCode, ULONG32 cOthers, mdToken pTokens[]) +{ + if (cOthers != 0) + { + _ASSERTE(!"not yet impl for cOthers != 0"); + return E_NOTIMPL; + } + LOG((LF_CORDB, LL_INFO100000, "CordbModule - SetJMCStatus - IMPLEMENTED\n")); + //on mono JMC is not by module, for now receiving this for one module, will affect all. + if (bIsJustMyCode) + conn->GetProcess()->SetJMCStatus(bIsJustMyCode); + return S_OK; +} + +HRESULT CordbModule::ApplyChanges(ULONG cbMetadata, BYTE pbMetadata[], ULONG cbIL, BYTE pbIL[]) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbModule - ApplyChanges - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbModule::SetJITCompilerFlags(DWORD dwFlags) +{ + this->dwFlags = dwFlags; + LOG((LF_CORDB, LL_INFO100000, "CordbModule - SetJITCompilerFlags - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbModule::GetJITCompilerFlags(DWORD* pdwFlags) +{ + *pdwFlags = dwFlags; + LOG((LF_CORDB, LL_INFO100000, "CordbModule - GetJITCompilerFlags - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbModule::ResolveAssembly(mdToken tkAssemblyRef, ICorDebugAssembly** ppAssembly) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbModule - ResolveAssembly - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbModule::GetProcess(ICorDebugProcess** ppProcess) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbModule - GetProcess - IMPLEMENTED\n")); + conn->GetProcess()->QueryInterface(IID_ICorDebugProcess, (void**)ppProcess); + return S_OK; +} + +HRESULT CordbModule::GetBaseAddress(CORDB_ADDRESS* pAddress) +{ + HRESULT hr = S_OK; + EX_TRY + { + if (!m_pPeImage) { + MdbgProtBuffer localbuf; + m_dbgprot_buffer_init(&localbuf, 128); + m_dbgprot_buffer_add_id(&localbuf, GetDebuggerId()); + int cmdId = conn->SendEvent(MDBGPROT_CMD_SET_ASSEMBLY, MDBGPROT_CMD_ASSEMBLY_GET_PEIMAGE_ADDRESS, &localbuf); + m_dbgprot_buffer_free(&localbuf); + + ReceivedReplyPacket* received_reply_packet = conn->GetReplyWithError(cmdId); + CHECK_ERROR_RETURN_FALSE(received_reply_packet); + MdbgProtBuffer* pReply = received_reply_packet->Buffer(); + + m_pPeImage = m_dbgprot_decode_long(pReply->p, &pReply->p, pReply->end); + m_nPeImageSize = m_dbgprot_decode_int(pReply->p, &pReply->p, pReply->end); + } + LOG((LF_CORDB, LL_INFO1000000, "CordbModule - GetBaseAddress - IMPLEMENTED\n")); + *pAddress = (CORDB_ADDRESS)m_pPeImage; + } + EX_CATCH_HRESULT(hr); + return hr; +} + +HRESULT CordbModule::GetName(ULONG32 cchName, ULONG32* pcchName, WCHAR szName[]) +{ + HRESULT hr = S_OK; + EX_TRY + { + if (!m_pAssemblyName) { + LOG((LF_CORDB, LL_INFO1000000, "CordbModule - GetName - IMPLEMENTED\n")); + MdbgProtBuffer localbuf; + m_dbgprot_buffer_init(&localbuf, 128); + m_dbgprot_buffer_add_id(&localbuf, GetDebuggerId()); + int cmdId = conn->SendEvent(MDBGPROT_CMD_SET_ASSEMBLY, MDBGPROT_CMD_ASSEMBLY_GET_LOCATION, &localbuf); + m_dbgprot_buffer_free(&localbuf); + + ReceivedReplyPacket* received_reply_packet = conn->GetReplyWithError(cmdId); + CHECK_ERROR_RETURN_FALSE(received_reply_packet); + MdbgProtBuffer* pReply = received_reply_packet->Buffer(); + + m_pAssemblyName = m_dbgprot_decode_string(pReply->p, &pReply->p, pReply->end); + } + + if (cchName < strlen(m_pAssemblyName) + 1) + { + *pcchName = (ULONG32)strlen(m_pAssemblyName) + 1; + } + else + { + MultiByteToWideChar(CP_UTF8, 0, m_pAssemblyName, -1, szName, cchName); + *pcchName = cchName; + } + } + EX_CATCH_HRESULT(hr); + return hr; +} + +HRESULT CordbModule::EnableJITDebugging(BOOL bTrackJITInfo, BOOL bAllowJitOpts) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbModule - EnableJITDebugging - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbModule::EnableClassLoadCallbacks(BOOL bClassLoadCallbacks) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbModule - EnableClassLoadCallbacks - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbModule::GetFunctionFromToken(mdMethodDef methodDef, ICorDebugFunction** ppFunction) +{ + HRESULT hr = S_OK; + EX_TRY + { + LOG((LF_CORDB, LL_INFO1000000, "CordbModule - GetFunctionFromToken - IMPLEMENTED\n")); + MdbgProtBuffer localbuf; + m_dbgprot_buffer_init(&localbuf, 128); + m_dbgprot_buffer_add_id(&localbuf, m_debuggerId); + m_dbgprot_buffer_add_int(&localbuf, methodDef); + int cmdId = conn->SendEvent(MDBGPROT_CMD_SET_ASSEMBLY, MDBGPROT_CMD_ASSEMBLY_GET_METHOD_FROM_TOKEN, &localbuf); + m_dbgprot_buffer_free(&localbuf); + + ReceivedReplyPacket* received_reply_packet = conn->GetReplyWithError(cmdId); + CHECK_ERROR_RETURN_FALSE(received_reply_packet); + MdbgProtBuffer* pReply = received_reply_packet->Buffer(); + + int id = m_dbgprot_decode_id(pReply->p, &pReply->p, pReply->end); + CordbFunction* func = NULL; + func = m_pProcess->FindFunction(id); + if (func == NULL) + { + func = new CordbFunction(conn, methodDef, id, this); + } + func->QueryInterface(IID_ICorDebugFunction, (void**)ppFunction); + } + EX_CATCH_HRESULT(hr); + return hr; +} + +HRESULT CordbModule::GetFunctionFromRVA(CORDB_ADDRESS rva, ICorDebugFunction** ppFunction) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbModule - GetFunctionFromRVA - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbModule::GetClassFromToken(mdTypeDef typeDef, ICorDebugClass** ppClass) +{ + CordbClass* pClass = conn->GetProcess()->FindOrAddClass(typeDef, GetDebuggerId()); + pClass->QueryInterface(IID_ICorDebugClass, (void**)ppClass); + return S_OK; +} + +HRESULT +CordbModule::CreateBreakpoint(ICorDebugModuleBreakpoint** ppBreakpoint) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbModule - CreateBreakpoint - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbModule::GetEditAndContinueSnapshot(ICorDebugEditAndContinueSnapshot** ppEditAndContinueSnapshot) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbModule - GetEditAndContinueSnapshot - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbModule::GetMetaDataInterface(REFIID riid, IUnknown** ppObj) +{ + if (m_pRegMeta == NULL) + { + OptionValue optionForNewScope; + memset(&optionForNewScope, 0, sizeof(OptionValue)); + optionForNewScope.m_ThreadSafetyOptions = MDThreadSafetyOn; + + m_pRegMeta = new RegMeta(); + m_pRegMeta->SetOption(&optionForNewScope); + + m_pStgdbRW = new CLiteWeightStgdbRW(); + ULONG32 pcchName = 0; + GetName(0, &pcchName, NULL); + + WCHAR* full_path; + full_path = (WCHAR*)malloc(sizeof(WCHAR) * pcchName); + GetName(pcchName, &pcchName, full_path); + + m_pStgdbRW->OpenForRead(full_path, NULL, 0, 0); + free(full_path); + + m_pRegMeta->InitWithStgdb((ICorDebugModule*)this, m_pStgdbRW); + } + m_pRegMeta->QueryInterface(riid, (void**)ppObj); + LOG((LF_CORDB, LL_INFO1000000, "CordbModule - GetMetaDataInterface - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbModule::GetToken(mdModule* pToken) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbModule - GetToken - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbModule::IsDynamic(BOOL* pDynamic) +{ + LOG((LF_CORDB, LL_INFO1000000, "CordbModule - IsDynamic - IMPLEMENTED\n")); + HRESULT hr = S_OK; + EX_TRY + { + MdbgProtBuffer localbuf; + m_dbgprot_buffer_init(&localbuf, 128); + m_dbgprot_buffer_add_id(&localbuf, GetDebuggerId()); + int cmdId = conn->SendEvent(MDBGPROT_CMD_SET_ASSEMBLY, MDBGPROT_CMD_ASSEMBLY_GET_IS_DYNAMIC, &localbuf); + m_dbgprot_buffer_free(&localbuf); + + ReceivedReplyPacket* received_reply_packet = conn->GetReplyWithError(cmdId); + CHECK_ERROR_RETURN_FALSE(received_reply_packet); + MdbgProtBuffer* pReply = received_reply_packet->Buffer(); + + int m_bIsDynamic = m_dbgprot_decode_byte(pReply->p, &pReply->p, pReply->end); + *pDynamic = m_bIsDynamic; + } + EX_CATCH_HRESULT(hr); + return hr; +} + +HRESULT CordbModule::GetGlobalVariableValue(mdFieldDef fieldDef, ICorDebugValue** ppValue) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbModule - GetGlobalVariableValue - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbModule::GetSize(ULONG32* pcBytes) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbModule - GetSize -IMPLEMENTED\n")); + *pcBytes = m_nPeImageSize; + return S_OK; +} + +HRESULT CordbModule::IsInMemory(BOOL* pInMemory) +{ + LOG((LF_CORDB, LL_INFO1000000, "CordbModule - IsInMemory - IMPLEMENTED\n")); + *pInMemory = FALSE; + return S_OK; +} + +HRESULT CordbModule::GetAssembly(ICorDebugAssembly** ppAssembly) +{ + LOG((LF_CORDB, LL_INFO1000000, "CordbModule - GetAssembly - IMPLEMENTED\n")); + m_pAssembly->QueryInterface(IID_ICorDebugAssembly, (void**)ppAssembly); + return S_OK; +} diff --git a/src/mono/dbi/cordb-assembly.h b/src/mono/dbi/cordb-assembly.h new file mode 100644 index 0000000000000..b5397bbe60e56 --- /dev/null +++ b/src/mono/dbi/cordb-assembly.h @@ -0,0 +1,107 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: CORDB-ASSEMBLY.H +// + +#ifndef __MONO_DEBUGGER_CORDB_ASSEMBLY_H__ +#define __MONO_DEBUGGER_CORDB_ASSEMBLY_H__ + +#include + +class CLiteWeightStgdbRW; + +class CordbModule : public CordbBaseMono, + public ICorDebugModule, + public ICorDebugModule2, + public ICorDebugModule3, + public ICorDebugModule4 +{ + int m_debuggerId; // id on mono side; + CordbProcess* m_pProcess; + RegMeta* m_pRegMeta; + CordbAssembly* m_pAssembly; + CLiteWeightStgdbRW* m_pStgdbRW; + CORDB_ADDRESS m_pPeImage; + int32_t m_nPeImageSize; + unsigned long dwFlags; + char * m_pAssemblyName; + +public: + CordbModule(Connection* conn, CordbProcess* process, CordbAssembly* assembly, int id_assembly); + ULONG STDMETHODCALLTYPE AddRef(void) + { + return (BaseAddRef()); + } + ULONG STDMETHODCALLTYPE Release(void) + { + return (BaseRelease()); + } + const char* GetClassName() + { + return "CordbModule"; + } + ~CordbModule(); + + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id, void** pInterface); + HRESULT STDMETHODCALLTYPE IsMappedLayout(BOOL* pIsMapped); + HRESULT STDMETHODCALLTYPE CreateReaderForInMemorySymbols(REFIID riid, void** ppObj); + HRESULT STDMETHODCALLTYPE SetJMCStatus(BOOL bIsJustMyCode, ULONG32 cTokens, mdToken pTokens[]); + HRESULT STDMETHODCALLTYPE ApplyChanges(ULONG cbMetadata, BYTE pbMetadata[], ULONG cbIL, BYTE pbIL[]); + HRESULT STDMETHODCALLTYPE SetJITCompilerFlags(DWORD dwFlags); + HRESULT STDMETHODCALLTYPE GetJITCompilerFlags(DWORD* pdwFlags); + HRESULT STDMETHODCALLTYPE ResolveAssembly(mdToken tkAssemblyRef, ICorDebugAssembly** ppAssembly); + HRESULT STDMETHODCALLTYPE GetProcess(ICorDebugProcess** ppProcess); + HRESULT STDMETHODCALLTYPE GetBaseAddress(CORDB_ADDRESS* pAddress); + HRESULT STDMETHODCALLTYPE GetAssembly(ICorDebugAssembly** ppAssembly); + HRESULT STDMETHODCALLTYPE GetName(ULONG32 cchName, ULONG32* pcchName, WCHAR szName[]); + HRESULT STDMETHODCALLTYPE EnableJITDebugging(BOOL bTrackJITInfo, BOOL bAllowJitOpts); + HRESULT STDMETHODCALLTYPE EnableClassLoadCallbacks(BOOL bClassLoadCallbacks); + HRESULT STDMETHODCALLTYPE GetFunctionFromToken(mdMethodDef methodDef, ICorDebugFunction** ppFunction); + HRESULT STDMETHODCALLTYPE GetFunctionFromRVA(CORDB_ADDRESS rva, ICorDebugFunction** ppFunction); + HRESULT STDMETHODCALLTYPE GetClassFromToken(mdTypeDef typeDef, ICorDebugClass** ppClass); + HRESULT STDMETHODCALLTYPE CreateBreakpoint(ICorDebugModuleBreakpoint** ppBreakpoint); + HRESULT STDMETHODCALLTYPE GetEditAndContinueSnapshot(ICorDebugEditAndContinueSnapshot** ppEditAndContinueSnapshot); + HRESULT STDMETHODCALLTYPE GetMetaDataInterface(REFIID riid, IUnknown** ppObj); + HRESULT STDMETHODCALLTYPE GetToken(mdModule* pToken); + HRESULT STDMETHODCALLTYPE IsDynamic(BOOL* pDynamic); + HRESULT STDMETHODCALLTYPE GetGlobalVariableValue(mdFieldDef fieldDef, ICorDebugValue** ppValue); + HRESULT STDMETHODCALLTYPE GetSize(ULONG32* pcBytes); + HRESULT STDMETHODCALLTYPE IsInMemory(BOOL* pInMemory); + int GetDebuggerId() const + { + return m_debuggerId; + } +}; + +class CordbAssembly : public CordbBaseMono, public ICorDebugAssembly, public ICorDebugAssembly2 +{ + CordbProcess* m_pProcess; + CordbAppDomain* m_pAppDomain; + int m_debuggerId; + +public: + CordbAssembly(Connection* conn, CordbProcess* process, CordbAppDomain* appDomain, int id_assembly); + ULONG STDMETHODCALLTYPE AddRef(void) + { + return (BaseAddRef()); + } + ULONG STDMETHODCALLTYPE Release(void) + { + return (BaseRelease()); + } + const char* GetClassName() + { + return "CordbAssembly"; + } + ~CordbAssembly(); + HRESULT STDMETHODCALLTYPE IsFullyTrusted(BOOL* pbFullyTrusted); + HRESULT STDMETHODCALLTYPE GetProcess(ICorDebugProcess** ppProcess); + HRESULT STDMETHODCALLTYPE GetAppDomain(ICorDebugAppDomain** ppAppDomain); + HRESULT STDMETHODCALLTYPE EnumerateModules(ICorDebugModuleEnum** ppModules); + HRESULT STDMETHODCALLTYPE GetCodeBase(ULONG32 cchName, ULONG32* pcchName, WCHAR szName[]); + HRESULT STDMETHODCALLTYPE GetName(ULONG32 cchName, ULONG32* pcchName, WCHAR szName[]); + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id, _COM_Outptr_ void __RPC_FAR* __RPC_FAR* ppInterface); +}; + +#endif diff --git a/src/mono/dbi/cordb-blocking-obj.cpp b/src/mono/dbi/cordb-blocking-obj.cpp new file mode 100644 index 0000000000000..98a2dfcc1c9dc --- /dev/null +++ b/src/mono/dbi/cordb-blocking-obj.cpp @@ -0,0 +1,53 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: CORDB-BLOCKING-OBJ.CPP +// + +#include +#include + +CordbBlockingObjectEnum::CordbBlockingObjectEnum(Connection* conn) : CordbBaseMono(conn) {} + +HRESULT STDMETHODCALLTYPE CordbBlockingObjectEnum::Next(ULONG celt, + CorDebugBlockingObject values[], + ULONG* pceltFetched) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbBlockingObjectEnum - Next - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbBlockingObjectEnum::Skip(ULONG celt) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbBlockingObjectEnum - Skip - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbBlockingObjectEnum::Reset(void) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbBlockingObjectEnum - Reset - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbBlockingObjectEnum::Clone(ICorDebugEnum** ppEnum) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbBlockingObjectEnum - Clone - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbBlockingObjectEnum::GetCount(ULONG* pcelt) +{ + pcelt = 0; + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbBlockingObjectEnum::QueryInterface(REFIID id, void** ppInterface) +{ + if (id == IID_ICorDebugBlockingObjectEnum) + *ppInterface = (ICorDebugBlockingObjectEnum*)this; + else if (id == IID_IUnknown) + *ppInterface = (IUnknown*)(ICorDebugBlockingObjectEnum*)this; + LOG((LF_CORDB, LL_INFO100000, "CordbBlockingObjectEnum - QueryInterface - IMPLEMENTED\n")); + AddRef(); + return S_OK; +} diff --git a/src/mono/dbi/cordb-blocking-obj.h b/src/mono/dbi/cordb-blocking-obj.h new file mode 100644 index 0000000000000..b7d49b002d4a0 --- /dev/null +++ b/src/mono/dbi/cordb-blocking-obj.h @@ -0,0 +1,36 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: CORDB-BLOCKING-OBJ.H +// + +#ifndef __MONO_DEBUGGER_CORDB_BLOCKING_OBJ_H__ +#define __MONO_DEBUGGER_CORDB_BLOCKING_OBJ_H__ + +#include + +class CordbBlockingObjectEnum : public CordbBaseMono, public ICorDebugBlockingObjectEnum +{ +public: + CordbBlockingObjectEnum(Connection* conn); + ULONG STDMETHODCALLTYPE AddRef(void) + { + return (BaseAddRef()); + } + ULONG STDMETHODCALLTYPE Release(void) + { + return (BaseRelease()); + } + const char* GetClassName() + { + return "CordbBlockingObjectEnum"; + } + HRESULT STDMETHODCALLTYPE Next(ULONG celt, CorDebugBlockingObject values[], ULONG* pceltFetched); + HRESULT STDMETHODCALLTYPE Skip(ULONG celt); + HRESULT STDMETHODCALLTYPE Reset(void); + HRESULT STDMETHODCALLTYPE Clone(ICorDebugEnum** ppEnum); + HRESULT STDMETHODCALLTYPE GetCount(ULONG* pcelt); + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject); +}; + +#endif diff --git a/src/mono/dbi/cordb-breakpoint.cpp b/src/mono/dbi/cordb-breakpoint.cpp new file mode 100644 index 0000000000000..1d45b6e0fb6d3 --- /dev/null +++ b/src/mono/dbi/cordb-breakpoint.cpp @@ -0,0 +1,89 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: CORDB-BREAKPOINT.CPP +// + +#include +#include +#include +#include +#include + +using namespace std; + +CordbFunctionBreakpoint::CordbFunctionBreakpoint(Connection* conn, CordbCode* code, ULONG32 offset) + : CordbBaseMono(conn) +{ + this->m_pCode = code; + this->m_offset = offset; + conn->GetProcess()->AddBreakpoint(this); + m_debuggerId = -1; +} + +CordbFunctionBreakpoint::~CordbFunctionBreakpoint() {} + +HRESULT CordbFunctionBreakpoint::GetFunction(ICorDebugFunction** ppFunction) +{ + GetCode()->GetFunction()->QueryInterface(IID_ICorDebugFunction, (void**)ppFunction); + LOG((LF_CORDB, LL_INFO1000000, "CordbFunctionBreakpoint - GetFunction - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbFunctionBreakpoint::GetOffset(ULONG32* pnOffset) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbFunctionBreakpoint - GetOffset - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbFunctionBreakpoint::Activate(BOOL bActive) +{ + if (bActive) + { + MdbgProtBuffer sendbuf; + int buflen = 128; + m_dbgprot_buffer_init(&sendbuf, buflen); + m_dbgprot_buffer_add_byte(&sendbuf, MDBGPROT_EVENT_KIND_BREAKPOINT); + m_dbgprot_buffer_add_byte(&sendbuf, MDBGPROT_SUSPEND_POLICY_ALL); + m_dbgprot_buffer_add_byte(&sendbuf, 1); // modifiers + m_dbgprot_buffer_add_byte(&sendbuf, MDBGPROT_MOD_KIND_LOCATION_ONLY); + m_dbgprot_buffer_add_id(&sendbuf, this->GetCode()->GetFunction()->GetDebuggerId()); + m_dbgprot_buffer_add_long(&sendbuf, m_offset); + int cmdId = conn->SendEvent(MDBGPROT_CMD_SET_EVENT_REQUEST, MDBGPROT_CMD_EVENT_REQUEST_SET, &sendbuf); + m_dbgprot_buffer_free(&sendbuf); + LOG((LF_CORDB, LL_INFO1000000, "CordbFunctionBreakpoint - Activate - IMPLEMENTED\n")); + + ReceivedReplyPacket* received_reply_packet = conn->GetReplyWithError(cmdId); + CHECK_ERROR_RETURN_FALSE(received_reply_packet); + MdbgProtBuffer* pReply = received_reply_packet->Buffer(); + + m_debuggerId = m_dbgprot_decode_id(pReply->p, &pReply->p, pReply->end); + } + else + { + LOG((LF_CORDB, LL_INFO100000, "CordbFunctionBreakpoint - Activate - FALSE - NOT IMPLEMENTED\n")); + } + return S_OK; +} + +HRESULT CordbFunctionBreakpoint::IsActive(BOOL* pbActive) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbFunctionBreakpoint - IsActive - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbFunctionBreakpoint::QueryInterface(REFIID id, void** pInterface) +{ + if (id == IID_ICorDebugFunctionBreakpoint) + { + *pInterface = static_cast(this); + } + else + { + // Not looking for a function breakpoint? See if the base class handles + // this interface. (issue 143976) + // return CordbBreakpoint::QueryInterface(id, pInterface); + } + AddRef(); + return S_OK; +} diff --git a/src/mono/dbi/cordb-breakpoint.h b/src/mono/dbi/cordb-breakpoint.h new file mode 100644 index 0000000000000..ad3444551d504 --- /dev/null +++ b/src/mono/dbi/cordb-breakpoint.h @@ -0,0 +1,52 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: CORDB-BREAKPOINT.H +// + +#ifndef __MONO_DEBUGGER_CORDB_BREAKPOINT_H__ +#define __MONO_DEBUGGER_CORDB_BREAKPOINT_H__ + +#include + +class CordbFunctionBreakpoint : public CordbBaseMono, public ICorDebugFunctionBreakpoint +{ + CordbCode* m_pCode; + ULONG32 m_offset; + int m_debuggerId; + +public: + CordbFunctionBreakpoint(Connection* conn, CordbCode* code, ULONG32 offset); + ULONG STDMETHODCALLTYPE AddRef(void) + { + return (BaseAddRef()); + } + ULONG STDMETHODCALLTYPE Release(void) + { + return (BaseRelease()); + } + ULONG32 GetOffset() const + { + return m_offset; + } + CordbCode* GetCode() const + { + return m_pCode; + } + const char* GetClassName() + { + return "CordbFunctionBreakpoint"; + } + ~CordbFunctionBreakpoint(); + HRESULT STDMETHODCALLTYPE GetFunction(ICorDebugFunction** ppFunction); + HRESULT STDMETHODCALLTYPE GetOffset(ULONG32* pnOffset); + HRESULT STDMETHODCALLTYPE Activate(BOOL bActive); + HRESULT STDMETHODCALLTYPE IsActive(BOOL* pbActive); + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id, _COM_Outptr_ void __RPC_FAR* __RPC_FAR* pInterface); + int GetDebuggerId() const + { + return m_debuggerId; + } +}; + +#endif diff --git a/src/mono/dbi/cordb-chain.cpp b/src/mono/dbi/cordb-chain.cpp new file mode 100644 index 0000000000000..5d6a67a348881 --- /dev/null +++ b/src/mono/dbi/cordb-chain.cpp @@ -0,0 +1,154 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: CORDB-CHAIN.CPP +// + +#include +#include +#include +#include +#include + +using namespace std; + +HRESULT CordbChainEnum::Next(ULONG celt, ICorDebugChain* chains[], ULONG* pceltFetched) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbChainEnum - Next - NOT IMPLEMENTED\n")); + + chains[0] = new CordbChain(conn, m_pThread, CHAIN_PROCESS_START, false); + chains[1] = new CordbChain(conn, m_pThread, CHAIN_ENTER_MANAGED, true); + chains[0]->AddRef(); + chains[1]->AddRef(); + *pceltFetched = celt; + return S_OK; +} + +CordbChainEnum::CordbChainEnum(Connection* conn, CordbThread* thread) : CordbBaseMono(conn) +{ + this->m_pThread = thread; +} + +HRESULT CordbChainEnum::QueryInterface(REFIID id, void** pInterface) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbChainEnum - QueryInterface - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbChainEnum::Skip(ULONG celt) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbChainEnum - Skip - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbChainEnum::Reset(void) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbChainEnum - Reset - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbChainEnum::Clone(ICorDebugEnum** ppEnum) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbChainEnum - Clone - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbChainEnum::GetCount(ULONG* pcelt) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbChainEnum - GetCount - NOT IMPLEMENTED\n")); + + *pcelt = 2; + return S_OK; +} + +CordbChain::CordbChain(Connection* conn, CordbThread* thread, CorDebugChainReason chain_reason, bool is_managed) + : CordbBaseMono(conn) +{ + this->m_pThread = thread; + this->m_chainReason = chain_reason; + this->m_isManaged = is_managed; +} + +HRESULT STDMETHODCALLTYPE CordbChain::GetThread(ICorDebugThread** ppThread) +{ + m_pThread->QueryInterface(IID_ICorDebugThread, (void**)ppThread); + LOG((LF_CORDB, LL_INFO1000000, "CordbChain - GetThread - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbChain::GetStackRange(CORDB_ADDRESS* pStart, CORDB_ADDRESS* pEnd) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbChain - GetStackRange - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbChain::GetContext(ICorDebugContext** ppContext) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbChain - GetContext - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbChain::GetCaller(ICorDebugChain** ppChain) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbChain - GetCaller - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbChain::GetCallee(ICorDebugChain** ppChain) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbChain - GetCallee - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbChain::GetPrevious(ICorDebugChain** ppChain) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbChain - GetPrevious - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbChain::GetNext(ICorDebugChain** ppChain) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbChain - GetNext - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbChain::IsManaged(BOOL* pManaged) +{ + LOG((LF_CORDB, LL_INFO1000000, "CordbChain - IsManaged - IMPLEMENTED\n")); + *pManaged = m_isManaged; + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbChain::EnumerateFrames(ICorDebugFrameEnum** ppFrames) +{ + CordbFrameEnum* pFrame = new CordbFrameEnum(conn, m_pThread); + pFrame->AddRef(); + *ppFrames = static_cast(pFrame); + LOG((LF_CORDB, LL_INFO1000000, "CordbChain - EnumerateFrames - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbChain::GetActiveFrame(ICorDebugFrame** ppFrame) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbChain - GetActiveFrame - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbChain::GetRegisterSet(ICorDebugRegisterSet** ppRegisters) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbChain - GetRegisterSet - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbChain::GetReason(CorDebugChainReason* pReason) +{ + *pReason = m_chainReason; + LOG((LF_CORDB, LL_INFO1000000, "CordbChain - GetReason - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbChain::QueryInterface(REFIID id, _COM_Outptr_ void __RPC_FAR* __RPC_FAR* pInterface) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbChain - QueryInterface - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} diff --git a/src/mono/dbi/cordb-chain.h b/src/mono/dbi/cordb-chain.h new file mode 100644 index 0000000000000..ce23f46f198d6 --- /dev/null +++ b/src/mono/dbi/cordb-chain.h @@ -0,0 +1,74 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: CORDB-CHAIN.H +// + +#ifndef __MONO_DEBUGGER_CORDB_CHAIN_H__ +#define __MONO_DEBUGGER_CORDB_CHAIN_H__ + +#include + +class CordbChainEnum : public CordbBaseMono, public ICorDebugChainEnum +{ + CordbThread* m_pThread; + +public: + CordbChainEnum(Connection* conn, CordbThread* thread); + ULONG STDMETHODCALLTYPE AddRef(void) + { + return (BaseAddRef()); + } + ULONG STDMETHODCALLTYPE Release(void) + { + return (BaseRelease()); + } + const char* GetClassName() + { + return "CordbChainEnum"; + } + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id, _COM_Outptr_ void __RPC_FAR* __RPC_FAR* pInterface); + + HRESULT STDMETHODCALLTYPE Skip(ULONG celt); + HRESULT STDMETHODCALLTYPE Reset(void); + HRESULT STDMETHODCALLTYPE Clone(ICorDebugEnum** ppEnum); + HRESULT STDMETHODCALLTYPE GetCount(ULONG* pcelt); + HRESULT STDMETHODCALLTYPE Next(ULONG celt, ICorDebugChain* chains[], ULONG* pceltFetched); +}; + +class CordbChain : public CordbBaseMono, public ICorDebugChain +{ + CordbThread* m_pThread; + CorDebugChainReason m_chainReason; + bool m_isManaged; + +public: + CordbChain(Connection* conn, CordbThread* thread, CorDebugChainReason chain_reason, bool is_managed); + ULONG STDMETHODCALLTYPE AddRef(void) + { + return (BaseAddRef()); + } + ULONG STDMETHODCALLTYPE Release(void) + { + return (BaseRelease()); + } + const char* GetClassName() + { + return "CordbChain"; + } + HRESULT STDMETHODCALLTYPE GetThread(ICorDebugThread** ppThread); + HRESULT STDMETHODCALLTYPE GetStackRange(CORDB_ADDRESS* pStart, CORDB_ADDRESS* pEnd); + HRESULT STDMETHODCALLTYPE GetContext(ICorDebugContext** ppContext); + HRESULT STDMETHODCALLTYPE GetCaller(ICorDebugChain** ppChain); + HRESULT STDMETHODCALLTYPE GetCallee(ICorDebugChain** ppChain); + HRESULT STDMETHODCALLTYPE GetPrevious(ICorDebugChain** ppChain); + HRESULT STDMETHODCALLTYPE GetNext(ICorDebugChain** ppChain); + HRESULT STDMETHODCALLTYPE IsManaged(BOOL* pManaged); + HRESULT STDMETHODCALLTYPE EnumerateFrames(ICorDebugFrameEnum** ppFrames); + HRESULT STDMETHODCALLTYPE GetActiveFrame(ICorDebugFrame** ppFrame); + HRESULT STDMETHODCALLTYPE GetRegisterSet(ICorDebugRegisterSet** ppRegisters); + HRESULT STDMETHODCALLTYPE GetReason(CorDebugChainReason* pReason); + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id, _COM_Outptr_ void __RPC_FAR* __RPC_FAR* pInterface); +}; + +#endif diff --git a/src/mono/dbi/cordb-class.cpp b/src/mono/dbi/cordb-class.cpp new file mode 100644 index 0000000000000..61574859c11b8 --- /dev/null +++ b/src/mono/dbi/cordb-class.cpp @@ -0,0 +1,90 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: CORDB-CLASS.CPP +// + +#include +#include +#include +#include +#include + +#include "cordb-assembly.h" + +using namespace std; + +CordbClass::CordbClass(Connection* conn, mdToken token, int module_id) : CordbBaseMono(conn) +{ + this->m_metadataToken = token; + this->m_debuggerModuleId = module_id; +} + +HRESULT STDMETHODCALLTYPE CordbClass::GetModule(ICorDebugModule** pModule) +{ + LOG((LF_CORDB, LL_INFO1000000, "CordbClass - GetModule - IMPLEMENTED\n")); + if (pModule) + { + CordbModule* module = conn->GetProcess()->GetModule(m_debuggerModuleId); + if (module) + { + *pModule = static_cast(module); + (*pModule)->AddRef(); + return S_OK; + } + } + return S_FALSE; +} + +HRESULT STDMETHODCALLTYPE CordbClass::GetToken(mdTypeDef* pTypeDef) +{ + LOG((LF_CORDB, LL_INFO1000000, "CordbClass - GetToken - IMPLEMENTED\n")); + *pTypeDef = m_metadataToken; + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbClass::GetStaticFieldValue(mdFieldDef fieldDef, + ICorDebugFrame* pFrame, + ICorDebugValue** ppValue) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbClass - GetStaticFieldValue - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbClass::QueryInterface(REFIID id, void** pInterface) +{ + if (id == IID_ICorDebugClass) + { + *pInterface = static_cast(this); + } + else if (id == IID_ICorDebugClass2) + { + *pInterface = static_cast(this); + } + else if (id == IID_IUnknown) + { + *pInterface = static_cast(static_cast(this)); + } + else + { + *pInterface = NULL; + return E_NOINTERFACE; + } + AddRef(); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbClass::GetParameterizedType(CorElementType elementType, + ULONG32 nTypeArgs, + ICorDebugType* ppTypeArgs[], + ICorDebugType** ppType) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbClass - GetParameterizedType - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbClass::SetJMCStatus(BOOL bIsJustMyCode) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbClass - SetJMCStatus - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} diff --git a/src/mono/dbi/cordb-class.h b/src/mono/dbi/cordb-class.h new file mode 100644 index 0000000000000..d02daf05dabd5 --- /dev/null +++ b/src/mono/dbi/cordb-class.h @@ -0,0 +1,43 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: CORDB-CLASS.H +// + +#ifndef __MONO_DEBUGGER_CORDB_CLASS_H__ +#define __MONO_DEBUGGER_CORDB_CLASS_H__ + +#include + +class CordbClass : public CordbBaseMono, public ICorDebugClass, public ICorDebugClass2 +{ + mdToken m_metadataToken; + int m_debuggerModuleId; + +public: + CordbClass(Connection* conn, mdToken token, int module_id); + ULONG STDMETHODCALLTYPE AddRef(void) + { + return (BaseAddRef()); + } + ULONG STDMETHODCALLTYPE Release(void) + { + return (BaseRelease()); + } + const char* GetClassName() + { + return "CordbClass"; + } + HRESULT STDMETHODCALLTYPE GetModule(ICorDebugModule** pModule); + HRESULT STDMETHODCALLTYPE GetToken(mdTypeDef* pTypeDef); + HRESULT STDMETHODCALLTYPE GetStaticFieldValue(mdFieldDef fieldDef, ICorDebugFrame* pFrame, ICorDebugValue** ppValue); + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject); + + HRESULT STDMETHODCALLTYPE GetParameterizedType(CorElementType elementType, + ULONG32 nTypeArgs, + ICorDebugType* ppTypeArgs[], + ICorDebugType** ppType); + HRESULT STDMETHODCALLTYPE SetJMCStatus(BOOL bIsJustMyCode); +}; + +#endif diff --git a/src/mono/dbi/cordb-code.cpp b/src/mono/dbi/cordb-code.cpp new file mode 100644 index 0000000000000..10b8301cb596e --- /dev/null +++ b/src/mono/dbi/cordb-code.cpp @@ -0,0 +1,152 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: CORDB-CODE.CPP +// + +#include +#include +#include +#include +#include +#include + +using namespace std; + +CordbCode::CordbCode(Connection* conn, CordbFunction* func) : CordbBaseMono(conn) +{ + this->m_pFunction = func; + m_nSize = 0; +} + +HRESULT CordbCode::IsIL(BOOL* pbIL) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbCode - IsIL - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbCode::GetFunction(ICorDebugFunction** ppFunction) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbCode - GetFunction - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbCode::GetAddress(CORDB_ADDRESS* pStart) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbCode - GetAddress - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +ULONG32 CordbCode::GetSize() +{ + if (m_nSize != 0) + return m_nSize; + + MdbgProtBuffer localbuf; + m_dbgprot_buffer_init(&localbuf, 128); + + m_dbgprot_buffer_add_id(&localbuf, this->GetFunction()->GetDebuggerId()); + int cmdId = conn->SendEvent(MDBGPROT_CMD_SET_METHOD, MDBGPROT_CMD_METHOD_GET_BODY, &localbuf); + m_dbgprot_buffer_free(&localbuf); + + ReceivedReplyPacket* received_reply_packet = conn->GetReplyWithError(cmdId); + if (received_reply_packet->Error() > 0 || received_reply_packet->Error2() > 0) + return 0; + MdbgProtBuffer* pReply = received_reply_packet->Buffer(); + + m_nSize = m_dbgprot_decode_int(pReply->p, &pReply->p, pReply->end); + return m_nSize; +} + +HRESULT CordbCode::GetSize(ULONG32* pcBytes) +{ + *pcBytes = GetSize(); + LOG((LF_CORDB, LL_INFO1000000, "CordbCode - GetSize - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbCode::CreateBreakpoint(ULONG32 offset, ICorDebugFunctionBreakpoint** ppBreakpoint) +{ + // add it in a list to not recreate a already created breakpoint + CordbFunctionBreakpoint* bp = new CordbFunctionBreakpoint(conn, this, offset); + bp->QueryInterface(IID_ICorDebugFunctionBreakpoint, (void**)ppBreakpoint); + LOG((LF_CORDB, LL_INFO1000000, "CordbCode - CreateBreakpoint - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbCode::GetCode( + ULONG32 startOffset, ULONG32 endOffset, ULONG32 cBufferAlloc, BYTE buffer[], ULONG32* pcBufferSize) +{ + LOG((LF_CORDB, LL_INFO1000000, "CordbCode - GetCode - IMPLEMENTED\n")); + HRESULT hr = S_OK; + EX_TRY + { + MdbgProtBuffer localbuf; + m_dbgprot_buffer_init(&localbuf, 128); + + m_dbgprot_buffer_add_id(&localbuf, this->GetFunction()->GetDebuggerId()); + int cmdId = conn->SendEvent(MDBGPROT_CMD_SET_METHOD, MDBGPROT_CMD_METHOD_GET_BODY, &localbuf); + m_dbgprot_buffer_free(&localbuf); + + ReceivedReplyPacket* received_reply_packet = conn->GetReplyWithError(cmdId); + CHECK_ERROR_RETURN_FALSE(received_reply_packet); + MdbgProtBuffer* pReply = received_reply_packet->Buffer(); + + ULONG32 totalSize = GetSize(); + + if (cBufferAlloc < endOffset - startOffset) + endOffset = startOffset + cBufferAlloc; + + if (endOffset > totalSize) + endOffset = totalSize; + + if (startOffset > totalSize) + startOffset = totalSize; + + uint8_t* m_rgbCode = m_dbgprot_decode_byte_array(pReply->p, &pReply->p, pReply->end, (int32_t*)pcBufferSize); + memcpy(buffer, + m_rgbCode+startOffset, + endOffset - startOffset); + free(m_rgbCode); + } + EX_CATCH_HRESULT(hr); + return hr; +} + +HRESULT CordbCode::GetVersionNumber(ULONG32* nVersion) +{ + *nVersion = 1; + LOG((LF_CORDB, LL_INFO100000, "CordbCode - GetVersionNumber - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbCode::GetILToNativeMapping(ULONG32 cMap, ULONG32* pcMap, COR_DEBUG_IL_TO_NATIVE_MAP map[]) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbCode - GetILToNativeMapping - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbCode::GetEnCRemapSequencePoints(ULONG32 cMap, ULONG32* pcMap, ULONG32 offsets[]) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbCode - GetEnCRemapSequencePoints - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbCode::QueryInterface(REFIID id, void** pInterface) +{ + if (id == IID_ICorDebugCode) + { + *pInterface = static_cast(this); + } + else if (id == IID_IUnknown) + { + *pInterface = static_cast(static_cast(this)); + } + else + { + *pInterface = NULL; + return E_NOINTERFACE; + } + AddRef(); + return S_OK; +} diff --git a/src/mono/dbi/cordb-code.h b/src/mono/dbi/cordb-code.h new file mode 100644 index 0000000000000..eb052fceff7ba --- /dev/null +++ b/src/mono/dbi/cordb-code.h @@ -0,0 +1,51 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: CORDB-CODE.H +// + +#ifndef __MONO_DEBUGGER_CORDB_CODE_H__ +#define __MONO_DEBUGGER_CORDB_CODE_H__ + +#include + +class CordbCode : public CordbBaseMono, public ICorDebugCode +{ + CordbFunction* m_pFunction; + ULONG32 m_nSize; +public: + CordbCode(Connection* conn, CordbFunction* func); + ULONG STDMETHODCALLTYPE AddRef(void) + { + return (BaseAddRef()); + } + ULONG STDMETHODCALLTYPE Release(void) + { + return (BaseRelease()); + } + const char* GetClassName() + { + return "CordbCode"; + } + ULONG32 GetSize(); + HRESULT STDMETHODCALLTYPE IsIL(BOOL* pbIL); + HRESULT STDMETHODCALLTYPE GetFunction(ICorDebugFunction** ppFunction); + HRESULT STDMETHODCALLTYPE GetAddress(CORDB_ADDRESS* pStart); + HRESULT STDMETHODCALLTYPE GetSize(ULONG32* pcBytes); + HRESULT STDMETHODCALLTYPE CreateBreakpoint(ULONG32 offset, ICorDebugFunctionBreakpoint** ppBreakpoint); + HRESULT STDMETHODCALLTYPE GetCode(ULONG32 startOffset, ULONG32 endOffset, ULONG32 cBufferAlloc, BYTE buffer[], ULONG32* pcBufferSize); + HRESULT STDMETHODCALLTYPE GetVersionNumber(ULONG32* nVersion); + HRESULT STDMETHODCALLTYPE GetILToNativeMapping(ULONG32 cMap, + ULONG32* pcMap, + + COR_DEBUG_IL_TO_NATIVE_MAP map[]); + HRESULT STDMETHODCALLTYPE GetEnCRemapSequencePoints(ULONG32 cMap, ULONG32* pcMap, ULONG32 offsets[]); + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id, _COM_Outptr_ void __RPC_FAR* __RPC_FAR* pInterface); + + CordbFunction* GetFunction() const + { + return m_pFunction; + } +}; + +#endif diff --git a/src/mono/dbi/cordb-eval.cpp b/src/mono/dbi/cordb-eval.cpp new file mode 100644 index 0000000000000..a09628c5e9ba4 --- /dev/null +++ b/src/mono/dbi/cordb-eval.cpp @@ -0,0 +1,263 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: CORDB-EVAL.CPP +// + +#include +#include +#include +#include +#include +#include +#include + +#include "corerror.h" +#include "metamodel.h" +#include "metamodelpub.h" +#include "rwutil.h" +#include "stdafx.h" + +CordbEval::CordbEval(Connection* conn, CordbThread* thread) : CordbBaseMono(conn) +{ + this->m_pThread = thread; + if (thread) + thread->InternalAddRef(); + m_pValue = NULL; + m_commandId = -1; +} + +CordbEval::~CordbEval() +{ + if (m_pThread) + m_pThread->InternalRelease(); +} +HRESULT STDMETHODCALLTYPE CordbEval::CallParameterizedFunction(ICorDebugFunction* pFunction, + ULONG32 nTypeArgs, + ICorDebugType* ppTypeArgs[], + ULONG32 nArgs, + ICorDebugValue* ppArgs[]) +{ + conn->GetProcess()->Stop(false); + LOG((LF_CORDB, LL_INFO1000000, "CordbEval - CallParameterizedFunction - IMPLEMENTED\n")); + + MdbgProtBuffer localbuf; + m_dbgprot_buffer_init(&localbuf, 128); + m_dbgprot_buffer_add_id(&localbuf, m_pThread->GetThreadId()); + m_dbgprot_buffer_add_int(&localbuf, 1); + m_dbgprot_buffer_add_int(&localbuf, ((CordbFunction*)pFunction)->GetDebuggerId()); + m_dbgprot_buffer_add_int(&localbuf, nArgs); + for (ULONG32 i = 0; i < nArgs; i++) + { + CorElementType ty; + ppArgs[i]->GetType(&ty); + CordbContent* cc; + cc = ((CordbValue*)ppArgs[i])->GetValue(); + m_dbgprot_buffer_add_byte(&localbuf, ty); + switch (ty) + { + case ELEMENT_TYPE_BOOLEAN: + case ELEMENT_TYPE_I1: + case ELEMENT_TYPE_U1: + m_dbgprot_buffer_add_int(&localbuf, cc->booleanValue); + break; + case ELEMENT_TYPE_CHAR: + case ELEMENT_TYPE_I2: + case ELEMENT_TYPE_U2: + m_dbgprot_buffer_add_int(&localbuf, cc->charValue); + break; + case ELEMENT_TYPE_I4: + case ELEMENT_TYPE_U4: + case ELEMENT_TYPE_R4: + m_dbgprot_buffer_add_int(&localbuf, cc->intValue); + break; + case ELEMENT_TYPE_I8: + case ELEMENT_TYPE_U8: + case ELEMENT_TYPE_R8: + m_dbgprot_buffer_add_long(&localbuf, cc->longValue); + break; + case ELEMENT_TYPE_CLASS: + case ELEMENT_TYPE_SZARRAY: + case ELEMENT_TYPE_STRING: + m_dbgprot_buffer_add_id(&localbuf, cc->intValue); + break; + default: + return E_NOTIMPL; + } + } + m_commandId = conn->SendEvent(MDBGPROT_CMD_SET_VM, MDBGPROT_CMD_VM_INVOKE_METHOD, &localbuf); + m_dbgprot_buffer_free(&localbuf); + conn->GetProcess()->AddPendingEval(this); + return S_OK; +} + +void CordbEval::EvalComplete(MdbgProtBuffer* pReply) +{ + m_dbgprot_decode_byte(pReply->p, &pReply->p, pReply->end); + CordbObjectValue::CreateCordbValue(conn, pReply, &m_pValue); + + conn->GetCordb()->GetCallback()->EvalComplete(conn->GetProcess()->GetCurrentAppDomain(), m_pThread, this); +} + +HRESULT STDMETHODCALLTYPE CordbEval::CreateValueForType(ICorDebugType* pType, ICorDebugValue** ppValue) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbEval - CreateValueForType - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbEval::NewParameterizedObject(ICorDebugFunction* pConstructor, + ULONG32 nTypeArgs, + ICorDebugType* ppTypeArgs[], + ULONG32 nArgs, + ICorDebugValue* ppArgs[]) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbEval - NewParameterizedObject - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbEval::NewParameterizedObjectNoConstructor(ICorDebugClass* pClass, + ULONG32 nTypeArgs, + ICorDebugType* ppTypeArgs[]) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbEval - NewParameterizedObjectNoConstructor - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbEval::NewParameterizedArray(ICorDebugType* pElementType, + ULONG32 rank, + ULONG32 dims[], + ULONG32 lowBounds[]) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbEval - NewParameterizedArray - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbEval::NewStringWithLength(LPCWSTR string, UINT uiLength) +{ + HRESULT hr = S_OK; + EX_TRY + { + conn->GetProcess()->Stop(false); + MdbgProtBuffer localbuf; + m_dbgprot_buffer_init(&localbuf, 128); + m_dbgprot_buffer_add_id(&localbuf, m_pThread->GetThreadId()); + int cmdId = conn->SendEvent(MDBGPROT_CMD_SET_THREAD, MDBGPROT_CMD_THREAD_GET_APPDOMAIN, &localbuf); + m_dbgprot_buffer_free(&localbuf); + + ReceivedReplyPacket* received_reply_packet = conn->GetReplyWithError(cmdId); + CHECK_ERROR_RETURN_FALSE(received_reply_packet); + MdbgProtBuffer* pReply = received_reply_packet->Buffer(); + + int domainId = m_dbgprot_decode_id(pReply->p, &pReply->p, pReply->end); + + LPSTR szString; + UTF8STR(string, szString); + + m_dbgprot_buffer_init(&localbuf, 128); + m_dbgprot_buffer_add_id(&localbuf, domainId); + m_dbgprot_buffer_add_string(&localbuf, szString); + this->m_commandId = conn->SendEvent(MDBGPROT_CMD_SET_APPDOMAIN, MDBGPROT_CMD_APPDOMAIN_CREATE_STRING, &localbuf); + m_dbgprot_buffer_free(&localbuf); + conn->GetProcess()->AddPendingEval(this); + } + EX_CATCH_HRESULT(hr); + return hr; +} + +HRESULT STDMETHODCALLTYPE CordbEval::RudeAbort(void) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbEval - RudeAbort - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT +CordbEval::QueryInterface(REFIID id, _COM_Outptr_ void __RPC_FAR* __RPC_FAR* pInterface) +{ + if (id == IID_ICorDebugEval) + { + *pInterface = static_cast(this); + } + else if (id == IID_ICorDebugEval2) + { + *pInterface = static_cast(this); + } + else if (id == IID_IUnknown) + { + *pInterface = static_cast(static_cast(this)); + } + else + { + *pInterface = NULL; + return E_NOINTERFACE; + } + AddRef(); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbEval::CallFunction(ICorDebugFunction* pFunction, ULONG32 nArgs, ICorDebugValue* ppArgs[]) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbEval - CallFunction - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbEval::NewObject(ICorDebugFunction* pConstructor, ULONG32 nArgs, ICorDebugValue* ppArgs[]) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbEval - NewObject - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbEval::NewObjectNoConstructor(ICorDebugClass* pClass) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbEval - NewObjectNoConstructor - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbEval::NewString(LPCWSTR string) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbEval - NewString - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbEval::NewArray( + CorElementType elementType, ICorDebugClass* pElementClass, ULONG32 rank, ULONG32 dims[], ULONG32 lowBounds[]) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbEval - NewArray - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbEval::IsActive(BOOL* pbActive) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbEval - IsActive - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbEval::Abort(void) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbEval - Abort - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbEval::GetResult(ICorDebugValue** ppResult) +{ + *ppResult = m_pValue; + LOG((LF_CORDB, LL_INFO1000000, "CordbEval - GetResult - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbEval::GetThread(ICorDebugThread** ppThread) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbEval - GetThread - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbEval::CreateValue(CorElementType elementType, + ICorDebugClass* pElementClass, + ICorDebugValue** ppValue) +{ + CordbContent content_value; + content_value.booleanValue = 0; + CordbValue* value = new CordbValue(conn, elementType, content_value, CordbObjectValue::GetTypeSize(elementType)); + LOG((LF_CORDB, LL_INFO1000000, "CordbEval - CreateValue - IMPLEMENTED\n")); + value->QueryInterface(IID_ICorDebugValue, (void**)ppValue); + return S_OK; +} diff --git a/src/mono/dbi/cordb-eval.h b/src/mono/dbi/cordb-eval.h new file mode 100644 index 0000000000000..87c87b6c1b257 --- /dev/null +++ b/src/mono/dbi/cordb-eval.h @@ -0,0 +1,68 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: CORDB-EVAL.H +// + +#ifndef __MONO_DEBUGGER_CORDB_EVAL_H__ +#define __MONO_DEBUGGER_CORDB_EVAL_H__ + +#include + +class CordbEval : public CordbBaseMono, public ICorDebugEval, public ICorDebugEval2 +{ + CordbThread* m_pThread; + ICorDebugValue* m_pValue; + int m_commandId; + +public: + CordbEval(Connection* conn, CordbThread* thread); + ~CordbEval(); + void EvalComplete(MdbgProtBuffer* pReply); + + HRESULT STDMETHODCALLTYPE CallParameterizedFunction(ICorDebugFunction* pFunction, + ULONG32 nTypeArgs, + ICorDebugType* ppTypeArgs[], + ULONG32 nArgs, + ICorDebugValue* ppArgs[]); + HRESULT STDMETHODCALLTYPE NewParameterizedObject(ICorDebugFunction* pConstructor, + ULONG32 nTypeArgs, + ICorDebugType* ppTypeArgs[], + ULONG32 nArgs, + ICorDebugValue* ppArgs[]); + HRESULT STDMETHODCALLTYPE NewParameterizedObjectNoConstructor(ICorDebugClass* pClass, ULONG32 nTypeArgs, ICorDebugType* ppTypeArgs[]); + HRESULT STDMETHODCALLTYPE CallFunction(ICorDebugFunction* pFunction, ULONG32 nArgs, ICorDebugValue* ppArgs[]); + HRESULT STDMETHODCALLTYPE NewObject(ICorDebugFunction* pConstructor, ULONG32 nArgs, ICorDebugValue* ppArgs[]); + HRESULT STDMETHODCALLTYPE NewObjectNoConstructor(ICorDebugClass* pClass); + HRESULT STDMETHODCALLTYPE NewString(LPCWSTR string); + HRESULT STDMETHODCALLTYPE NewArray( + CorElementType elementType, ICorDebugClass* pElementClass, ULONG32 rank, ULONG32 dims[], ULONG32 lowBounds[]); + HRESULT STDMETHODCALLTYPE IsActive(BOOL* pbActive); + HRESULT STDMETHODCALLTYPE Abort(void); + HRESULT STDMETHODCALLTYPE GetResult(ICorDebugValue** ppResult); + HRESULT STDMETHODCALLTYPE GetThread(ICorDebugThread** ppThread); + HRESULT STDMETHODCALLTYPE CreateValue(CorElementType elementType, ICorDebugClass* pElementClass, ICorDebugValue** ppValue); + HRESULT STDMETHODCALLTYPE CreateValueForType(ICorDebugType* pType, ICorDebugValue** ppValue); + HRESULT STDMETHODCALLTYPE NewParameterizedArray(ICorDebugType* pElementType, ULONG32 rank, ULONG32 dims[], ULONG32 lowBounds[]); + HRESULT STDMETHODCALLTYPE NewStringWithLength(LPCWSTR string, UINT uiLength); + HRESULT STDMETHODCALLTYPE RudeAbort(void); + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, _COM_Outptr_ void __RPC_FAR* __RPC_FAR* ppvObject); + ULONG STDMETHODCALLTYPE AddRef(void) + { + return (BaseAddRef()); + } + ULONG STDMETHODCALLTYPE Release(void) + { + return (BaseRelease()); + } + const char* GetClassName() + { + return "CordbEval"; + } + int GetCommandId() const + { + return m_commandId; + } +}; + +#endif diff --git a/src/mono/dbi/cordb-frame.cpp b/src/mono/dbi/cordb-frame.cpp new file mode 100644 index 0000000000000..32c2a53c11ed0 --- /dev/null +++ b/src/mono/dbi/cordb-frame.cpp @@ -0,0 +1,541 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: CORDB-FRAME.CPP +// + +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +CordbFrameEnum::CordbFrameEnum(Connection* conn, CordbThread* thread) : CordbBaseMono(conn) +{ + this->m_pThread = thread; + m_nFrames = 0; + m_ppFrames = NULL; +} + +CordbFrameEnum::~CordbFrameEnum() +{ + Reset(); +} + +HRESULT STDMETHODCALLTYPE CordbFrameEnum::Next(ULONG celt, ICorDebugFrame* frames[], ULONG* pceltFetched) +{ + GetCount(); + for (int i = 0; i < m_nFrames; i++) + { + this->m_ppFrames[i]->QueryInterface(IID_ICorDebugFrame, (void**)&frames[i]); + } + LOG((LF_CORDB, LL_INFO1000000, "CordbFrameEnum - Next - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbFrameEnum::Skip(ULONG celt) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbFrameEnum - Skip - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbFrameEnum::Reset(void) +{ + for (int i = 0; i < m_nFrames; i++) + { + this->m_ppFrames[i]->InternalRelease(); + } + m_nFrames = 0; + if (m_ppFrames) + free(m_ppFrames); + m_ppFrames = NULL; + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbFrameEnum::Clone(ICorDebugEnum** ppEnum) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbFrameEnum - Clone - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbFrameEnum::GetCount() { + HRESULT hr = S_OK; + if (m_nFrames != 0) + return hr; + EX_TRY + { + Reset(); + MdbgProtBuffer localbuf; + m_dbgprot_buffer_init(&localbuf, 128); + m_dbgprot_buffer_add_id(&localbuf, m_pThread->GetThreadId()); + m_dbgprot_buffer_add_int(&localbuf, 0); + m_dbgprot_buffer_add_int(&localbuf, -1); + + int cmdId = conn->SendEvent(MDBGPROT_CMD_SET_THREAD, MDBGPROT_CMD_THREAD_GET_FRAME_INFO, &localbuf); + m_dbgprot_buffer_free(&localbuf); + + ReceivedReplyPacket* received_reply_packet = conn->GetReplyWithError(cmdId); + CHECK_ERROR_RETURN_FALSE(received_reply_packet); + MdbgProtBuffer* pReply = received_reply_packet->Buffer(); + + m_nFrames = m_dbgprot_decode_int(pReply->p, &pReply->p, pReply->end); + m_ppFrames = (CordbNativeFrame**)malloc(sizeof(CordbNativeFrame*) * m_nFrames); + + for (int i = 0; i < m_nFrames; i++) + { + int frameid = m_dbgprot_decode_int(pReply->p, &pReply->p, pReply->end); + int methodId = m_dbgprot_decode_id(pReply->p, &pReply->p, pReply->end); + int il_offset = m_dbgprot_decode_int(pReply->p, &pReply->p, pReply->end); + int flags = m_dbgprot_decode_byte(pReply->p, &pReply->p, pReply->end); + + CordbNativeFrame* frame = new CordbNativeFrame(conn, frameid, methodId, il_offset, flags, m_pThread); + frame->InternalAddRef(); + m_ppFrames[i] = frame; + } + } + EX_CATCH_HRESULT(hr); + return hr; +} + +HRESULT STDMETHODCALLTYPE CordbFrameEnum::GetCount(ULONG* pcelt) +{ + LOG((LF_CORDB, LL_INFO1000000, "CordbFrameEnum - GetCount - IMPLEMENTED\n")); + HRESULT hr = S_OK; + + hr = GetCount(); + *pcelt = m_nFrames; + + return hr; +} + +HRESULT STDMETHODCALLTYPE CordbFrameEnum::QueryInterface(REFIID riid, void** ppvObject) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbFrameEnum - QueryInterface - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +CordbJITILFrame::CordbJITILFrame( + Connection* conn, int frameid, int methodId, int il_offset, int flags, CordbThread* thread) + : CordbBaseMono(conn) +{ + this->m_debuggerFrameId = frameid; + this->m_debuggerMethodId = methodId; + this->m_ilOffset = il_offset; + this->m_flags = flags; + this->m_pThread = thread; +} + +HRESULT STDMETHODCALLTYPE CordbJITILFrame::GetChain(ICorDebugChain** ppChain) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbFrame - GetChain - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbJITILFrame::GetCode(ICorDebugCode** ppCode) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbFrame - GetCode - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbJITILFrame::GetFunction(ICorDebugFunction** ppFunction) +{ + CordbFunction* func = conn->GetProcess()->FindFunction(m_debuggerMethodId); + if (!func) + { + func = new CordbFunction(conn, 0, m_debuggerMethodId, NULL); + } + func->QueryInterface(IID_ICorDebugFunction, (void**)ppFunction); + LOG((LF_CORDB, LL_INFO1000000, "CordbFrame - GetFunction - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbJITILFrame::GetFunctionToken(mdMethodDef* pToken) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbFrame - GetFunctionToken - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbJITILFrame::GetStackRange(CORDB_ADDRESS* pStart, CORDB_ADDRESS* pEnd) +{ + *pStart = 0; //forced value, only to make vs work, I'm not sure which value should returned from mono runtime + *pEnd = 1; //forced value, only to make vs work, I'm not sure which value should returned from mono runtime + LOG((LF_CORDB, LL_INFO100000, "CordbFrame - GetStackRange - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbJITILFrame::GetCaller(ICorDebugFrame** ppFrame) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbFrame - GetCaller - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbJITILFrame::GetCallee(ICorDebugFrame** ppFrame) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbFrame - GetCallee - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbJITILFrame::CreateStepper(ICorDebugStepper** ppStepper) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbFrame - CreateStepper - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbJITILFrame::QueryInterface(REFIID id, _COM_Outptr_ void __RPC_FAR* __RPC_FAR* pInterface) +{ + if (id == IID_ICorDebugILFrame) + { + *pInterface = static_cast(this); + } + else if (id == IID_ICorDebugILFrame2) + { + *pInterface = static_cast(this); + } + else if (id == IID_ICorDebugILFrame3) + { + *pInterface = static_cast(this); + } + else if (id == IID_ICorDebugILFrame4) + { + *pInterface = static_cast(this); + } + else + { + *pInterface = NULL; + return E_NOINTERFACE; + } + AddRef(); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbJITILFrame::RemapFunction(ULONG32 newILOffset) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbFrame - RemapFunction - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbJITILFrame::EnumerateTypeParameters(ICorDebugTypeEnum** ppTyParEnum) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbFrame - EnumerateTypeParameters - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbJITILFrame::GetReturnValueForILOffset(ULONG32 ILoffset, ICorDebugValue** ppReturnValue) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbFrame - GetReturnValueForILOffset - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbJITILFrame::EnumerateLocalVariablesEx(ILCodeKind flags, ICorDebugValueEnum** ppValueEnum) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbFrame - EnumerateLocalVariablesEx - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbJITILFrame::GetLocalVariableEx(ILCodeKind flags, DWORD dwIndex, ICorDebugValue** ppValue) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbFrame - GetLocalVariableEx - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbJITILFrame::GetCodeEx(ILCodeKind flags, ICorDebugCode** ppCode) +{ + if (flags == ILCODE_REJIT_IL) + *ppCode = NULL; + else + { + ICorDebugFunction* ppFunction; + GetFunction(&ppFunction); + ppFunction->GetILCode(ppCode); + ppFunction->Release(); + } + LOG((LF_CORDB, LL_INFO1000000, "CordbJITILFrame - GetCodeEx - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbJITILFrame::GetIP(ULONG32* pnOffset, CorDebugMappingResult* pMappingResult) +{ + *pnOffset = m_ilOffset; + *pMappingResult = MAPPING_EXACT; + LOG((LF_CORDB, LL_INFO1000000, "CordbFrame - GetIP - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbJITILFrame::SetIP(ULONG32 nOffset) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbFrame - SetIP - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbJITILFrame::EnumerateLocalVariables(ICorDebugValueEnum** ppValueEnum) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbFrame - EnumerateLocalVariables - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbJITILFrame::GetLocalVariable(DWORD dwIndex, ICorDebugValue** ppValue) +{ + HRESULT hr = S_OK; + EX_TRY + { + MdbgProtBuffer localbuf; + m_dbgprot_buffer_init(&localbuf, 128); + m_dbgprot_buffer_add_id(&localbuf, m_pThread->GetThreadId()); + m_dbgprot_buffer_add_id(&localbuf, m_debuggerFrameId); + m_dbgprot_buffer_add_int(&localbuf, 1); + m_dbgprot_buffer_add_int(&localbuf, dwIndex); + + int cmdId = conn->SendEvent(MDBGPROT_CMD_SET_STACK_FRAME, MDBGPROT_CMD_STACK_FRAME_GET_VALUES, &localbuf); + m_dbgprot_buffer_free(&localbuf); + + ReceivedReplyPacket* received_reply_packet = conn->GetReplyWithError(cmdId); + CHECK_ERROR_RETURN_FALSE(received_reply_packet); + MdbgProtBuffer* pReply = received_reply_packet->Buffer(); + hr = CordbObjectValue::CreateCordbValue(conn, pReply, ppValue); + } + EX_CATCH_HRESULT(hr); + return hr; +} + +HRESULT STDMETHODCALLTYPE CordbJITILFrame::EnumerateArguments(ICorDebugValueEnum** ppValueEnum) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbFrame - EnumerateArguments - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbJITILFrame::GetArgument(DWORD dwIndex, ICorDebugValue** ppValue) +{ + LOG((LF_CORDB, LL_INFO1000000, "CordbFrame - GetArgument - IMPLEMENTED\n")); + HRESULT hr = S_OK; + EX_TRY + { + MdbgProtBuffer localbuf; + m_dbgprot_buffer_init(&localbuf, 128); + m_dbgprot_buffer_add_id(&localbuf, m_pThread->GetThreadId()); + m_dbgprot_buffer_add_id(&localbuf, m_debuggerFrameId); + + m_dbgprot_buffer_add_int(&localbuf, dwIndex); + int cmdId = conn->SendEvent(MDBGPROT_CMD_SET_STACK_FRAME, MDBGPROT_CMD_STACK_FRAME_GET_ARGUMENT, &localbuf); + m_dbgprot_buffer_free(&localbuf); + + ReceivedReplyPacket* received_reply_packet = conn->GetReplyWithError(cmdId); + CHECK_ERROR_RETURN_FALSE(received_reply_packet); + MdbgProtBuffer* pReply = received_reply_packet->Buffer(); + + hr = CordbObjectValue::CreateCordbValue(conn, pReply, ppValue); + } + EX_CATCH_HRESULT(hr); + return hr; +} + +HRESULT STDMETHODCALLTYPE CordbJITILFrame::GetStackDepth(ULONG32* pDepth) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbFrame - GetStackDepth - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbJITILFrame::GetStackValue(DWORD dwIndex, ICorDebugValue** ppValue) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbFrame - GetStackValue - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbJITILFrame::CanSetIP(ULONG32 nOffset) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbFrame - CanSetIP - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +CordbNativeFrame::~CordbNativeFrame() +{ + m_JITILFrame->InternalRelease(); +} + +CordbNativeFrame::CordbNativeFrame( + Connection* conn, int frameid, int methodId, int il_offset, int flags, CordbThread* thread) + : CordbBaseMono(conn) +{ + m_JITILFrame = new CordbJITILFrame(conn, frameid, methodId, il_offset, flags, thread); + m_JITILFrame->InternalAddRef(); + this->m_pThread = thread; +} + +HRESULT STDMETHODCALLTYPE CordbNativeFrame::GetIP(ULONG32* pnOffset) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbNativeFrame - GetIP - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbNativeFrame::SetIP(ULONG32 nOffset) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbNativeFrame - SetIP - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbNativeFrame::GetRegisterSet(ICorDebugRegisterSet** ppRegisters) +{ + return m_pThread->GetRegisterSet(ppRegisters); +} + +HRESULT STDMETHODCALLTYPE CordbNativeFrame::GetLocalRegisterValue(CorDebugRegister reg, + ULONG cbSigBlob, + PCCOR_SIGNATURE pvSigBlob, + ICorDebugValue** ppValue) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbNativeFrame - GetLocalRegisterValue - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbNativeFrame::GetLocalDoubleRegisterValue(CorDebugRegister highWordReg, + CorDebugRegister lowWordReg, + ULONG cbSigBlob, + PCCOR_SIGNATURE pvSigBlob, + ICorDebugValue** ppValue) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbNativeFrame - GetLocalDoubleRegisterValue - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbNativeFrame::GetLocalMemoryValue(CORDB_ADDRESS address, + ULONG cbSigBlob, + PCCOR_SIGNATURE pvSigBlob, + ICorDebugValue** ppValue) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbNativeFrame - GetLocalMemoryValue - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbNativeFrame::GetLocalRegisterMemoryValue(CorDebugRegister highWordReg, + CORDB_ADDRESS lowWordAddress, + ULONG cbSigBlob, + PCCOR_SIGNATURE pvSigBlob, + ICorDebugValue** ppValue) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbNativeFrame - GetLocalRegisterMemoryValue - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbNativeFrame::GetLocalMemoryRegisterValue(CORDB_ADDRESS highWordAddress, + CorDebugRegister lowWordRegister, + ULONG cbSigBlob, + PCCOR_SIGNATURE pvSigBlob, + ICorDebugValue** ppValue) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbNativeFrame - GetLocalMemoryRegisterValue - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbNativeFrame::CanSetIP(ULONG32 nOffset) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbNativeFrame - CanSetIP - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbNativeFrame::GetChain(ICorDebugChain** ppChain) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbNativeFrame - GetChain - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbNativeFrame::GetCode(ICorDebugCode** ppCode) +{ + ICorDebugFunction* ppFunction; + m_JITILFrame->GetFunction(&ppFunction); + ppFunction->GetILCode(ppCode); + ppFunction->Release(); + LOG((LF_CORDB, LL_INFO100000, "CordbJITILFrame - GetCodeEx - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbNativeFrame::GetFunction(ICorDebugFunction** ppFunction) +{ + return m_JITILFrame->GetFunction(ppFunction); +} + +HRESULT STDMETHODCALLTYPE CordbNativeFrame::GetFunctionToken(mdMethodDef* pToken) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbNativeFrame - GetFunctionToken - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbNativeFrame::GetStackRange(CORDB_ADDRESS* pStart, CORDB_ADDRESS* pEnd) +{ + return m_JITILFrame->GetStackRange(pStart, pEnd); +} + +HRESULT STDMETHODCALLTYPE CordbNativeFrame::GetCaller(ICorDebugFrame** ppFrame) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbNativeFrame - GetCaller - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbNativeFrame::GetCallee(ICorDebugFrame** ppFrame) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbNativeFrame - GetCallee - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbNativeFrame::CreateStepper(ICorDebugStepper** ppStepper) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbNativeFrame - CreateStepper - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbNativeFrame::QueryInterface(REFIID id, void** pInterface) +{ + if (id == IID_ICorDebugFrame) + { + *pInterface = static_cast(static_cast(this)); + } + else if (id == IID_ICorDebugNativeFrame) + { + *pInterface = static_cast(this); + } + else if (id == IID_ICorDebugNativeFrame2) + { + *pInterface = static_cast(this); + } + else if (id == IID_IUnknown) + { + *pInterface = static_cast(static_cast(this)); + } + else + { + // might be searching for an IL Frame. delegate that search to the + // JITILFrame + if (m_JITILFrame != NULL) + { + return m_JITILFrame->QueryInterface(id, pInterface); + } + else + { + *pInterface = NULL; + return E_NOINTERFACE; + } + } + AddRef(); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbNativeFrame::IsChild(BOOL* pIsChild) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbNativeFrame - IsChild - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbNativeFrame::IsMatchingParentFrame(ICorDebugNativeFrame2* pPotentialParentFrame, + BOOL* pIsParent) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbNativeFrame - IsMatchingParentFrame - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbNativeFrame::GetStackParameterSize(ULONG32* pSize) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbNativeFrame - GetStackParameterSize - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} diff --git a/src/mono/dbi/cordb-frame.h b/src/mono/dbi/cordb-frame.h new file mode 100644 index 0000000000000..167aeda240b2c --- /dev/null +++ b/src/mono/dbi/cordb-frame.h @@ -0,0 +1,158 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: CORDB-FRAME.H +// + +#ifndef __MONO_DEBUGGER_CORDB_FRAME_H__ +#define __MONO_DEBUGGER_CORDB_FRAME_H__ + +#include + +class CordbJITILFrame : public CordbBaseMono, + public ICorDebugILFrame, + public ICorDebugILFrame2, + public ICorDebugILFrame3, + public ICorDebugILFrame4 +{ + int m_debuggerFrameId; + int m_debuggerMethodId; + int m_ilOffset; + int m_flags; + CordbThread* m_pThread; + +public: + CordbJITILFrame(Connection* conn, int frameid, int methodId, int il_offset, int flags, CordbThread* thread); + ULONG STDMETHODCALLTYPE AddRef(void) + { + return (BaseAddRef()); + } + ULONG STDMETHODCALLTYPE Release(void) + { + return (BaseRelease()); + } + const char* GetClassName() + { + return "CordbJITILFrame"; + } + HRESULT STDMETHODCALLTYPE GetChain(ICorDebugChain** ppChain); + HRESULT STDMETHODCALLTYPE GetCode(ICorDebugCode** ppCode); + HRESULT STDMETHODCALLTYPE GetFunction(ICorDebugFunction** ppFunction); + HRESULT STDMETHODCALLTYPE GetFunctionToken(mdMethodDef* pToken); + HRESULT STDMETHODCALLTYPE GetStackRange(CORDB_ADDRESS* pStart, CORDB_ADDRESS* pEnd); + HRESULT STDMETHODCALLTYPE GetCaller(ICorDebugFrame** ppFrame); + HRESULT STDMETHODCALLTYPE GetCallee(ICorDebugFrame** ppFrame); + HRESULT STDMETHODCALLTYPE CreateStepper(ICorDebugStepper** ppStepper); + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id, _COM_Outptr_ void __RPC_FAR* __RPC_FAR* pInterface); + + HRESULT STDMETHODCALLTYPE GetIP(ULONG32* pnOffset, CorDebugMappingResult* pMappingResult); + HRESULT STDMETHODCALLTYPE SetIP(ULONG32 nOffset); + HRESULT STDMETHODCALLTYPE EnumerateLocalVariables(ICorDebugValueEnum** ppValueEnum); + HRESULT STDMETHODCALLTYPE GetLocalVariable(DWORD dwIndex, ICorDebugValue** ppValue); + HRESULT STDMETHODCALLTYPE EnumerateArguments(ICorDebugValueEnum** ppValueEnum); + HRESULT STDMETHODCALLTYPE GetArgument(DWORD dwIndex, ICorDebugValue** ppValue); + HRESULT STDMETHODCALLTYPE GetStackDepth(ULONG32* pDepth); + HRESULT STDMETHODCALLTYPE GetStackValue(DWORD dwIndex, ICorDebugValue** ppValue); + HRESULT STDMETHODCALLTYPE CanSetIP(ULONG32 nOffset); + HRESULT STDMETHODCALLTYPE RemapFunction(ULONG32 newILOffset); + HRESULT STDMETHODCALLTYPE EnumerateTypeParameters(ICorDebugTypeEnum** ppTyParEnum); + HRESULT STDMETHODCALLTYPE GetReturnValueForILOffset(ULONG32 ILoffset, ICorDebugValue** ppReturnValue); + HRESULT STDMETHODCALLTYPE EnumerateLocalVariablesEx(ILCodeKind flags, ICorDebugValueEnum** ppValueEnum); + HRESULT STDMETHODCALLTYPE GetLocalVariableEx(ILCodeKind flags, DWORD dwIndex, ICorDebugValue** ppValue); + HRESULT STDMETHODCALLTYPE GetCodeEx(ILCodeKind flags, ICorDebugCode** ppCode); +}; + +class CordbNativeFrame : public CordbBaseMono, public ICorDebugNativeFrame, public ICorDebugNativeFrame2 +{ + CordbJITILFrame* m_JITILFrame; + CordbThread* m_pThread; + +public: + CordbNativeFrame(Connection* conn, int frameid, int methodId, int il_offset, int flags, CordbThread* thread); + ULONG STDMETHODCALLTYPE AddRef(void) + { + return (BaseAddRef()); + } + ULONG STDMETHODCALLTYPE Release(void) + { + return (BaseRelease()); + } + const char* GetClassName() + { + return "CordbNativeFrame"; + } + ~CordbNativeFrame(); + HRESULT STDMETHODCALLTYPE GetIP(ULONG32* pnOffset); + HRESULT STDMETHODCALLTYPE SetIP(ULONG32 nOffset); + HRESULT STDMETHODCALLTYPE GetRegisterSet(ICorDebugRegisterSet** ppRegisters); + HRESULT STDMETHODCALLTYPE GetLocalRegisterValue(CorDebugRegister reg, + ULONG cbSigBlob, + PCCOR_SIGNATURE pvSigBlob, + ICorDebugValue** ppValue); + HRESULT STDMETHODCALLTYPE GetLocalDoubleRegisterValue(CorDebugRegister highWordReg, + CorDebugRegister lowWordReg, + ULONG cbSigBlob, + PCCOR_SIGNATURE pvSigBlob, + ICorDebugValue** ppValue); + HRESULT STDMETHODCALLTYPE GetLocalMemoryValue(CORDB_ADDRESS address, + ULONG cbSigBlob, + PCCOR_SIGNATURE pvSigBlob, + ICorDebugValue** ppValue); + HRESULT STDMETHODCALLTYPE GetLocalRegisterMemoryValue(CorDebugRegister highWordReg, + CORDB_ADDRESS lowWordAddress, + ULONG cbSigBlob, + PCCOR_SIGNATURE pvSigBlob, + ICorDebugValue** ppValue); + HRESULT STDMETHODCALLTYPE GetLocalMemoryRegisterValue(CORDB_ADDRESS highWordAddress, + CorDebugRegister lowWordRegister, + ULONG cbSigBlob, + PCCOR_SIGNATURE pvSigBlob, + ICorDebugValue** ppValue); + HRESULT STDMETHODCALLTYPE CanSetIP(ULONG32 nOffset); + HRESULT STDMETHODCALLTYPE GetChain(ICorDebugChain** ppChain); + HRESULT STDMETHODCALLTYPE GetCode(ICorDebugCode** ppCode); + HRESULT STDMETHODCALLTYPE GetFunction(ICorDebugFunction** ppFunction); + HRESULT STDMETHODCALLTYPE GetFunctionToken(mdMethodDef* pToken); + HRESULT STDMETHODCALLTYPE GetStackRange(CORDB_ADDRESS* pStart, CORDB_ADDRESS* pEnd); + HRESULT STDMETHODCALLTYPE GetCaller(ICorDebugFrame** ppFrame); + HRESULT STDMETHODCALLTYPE GetCallee(ICorDebugFrame** ppFrame); + HRESULT STDMETHODCALLTYPE CreateStepper(ICorDebugStepper** ppStepper); + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject); + + HRESULT STDMETHODCALLTYPE IsChild(BOOL* pIsChild); + HRESULT STDMETHODCALLTYPE IsMatchingParentFrame(ICorDebugNativeFrame2* pPotentialParentFrame, BOOL* pIsParent); + HRESULT STDMETHODCALLTYPE GetStackParameterSize(ULONG32* pSize); +}; + +class CordbFrameEnum : public CordbBaseMono, public ICorDebugFrameEnum +{ + CordbThread* m_pThread; + int m_nFrames; + CordbNativeFrame** m_ppFrames; + +public: + CordbFrameEnum(Connection* conn, CordbThread* thread); + ULONG STDMETHODCALLTYPE AddRef(void) + { + return (BaseAddRef()); + } + ULONG STDMETHODCALLTYPE Release(void) + { + return (BaseRelease()); + } + const char* GetClassName() + { + return "CordbFrameEnum"; + } + ~CordbFrameEnum(); + HRESULT STDMETHODCALLTYPE Next(ULONG celt, ICorDebugFrame* frames[], ULONG* pceltFetched); + HRESULT STDMETHODCALLTYPE Skip(ULONG celt); + HRESULT STDMETHODCALLTYPE Reset(void); + HRESULT STDMETHODCALLTYPE Clone(ICorDebugEnum** ppEnum); + HRESULT STDMETHODCALLTYPE GetCount(ULONG* pcelt); + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject); + + HRESULT GetCount(); +}; + +#endif diff --git a/src/mono/dbi/cordb-function.cpp b/src/mono/dbi/cordb-function.cpp new file mode 100644 index 0000000000000..4757db41fa9ad --- /dev/null +++ b/src/mono/dbi/cordb-function.cpp @@ -0,0 +1,210 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: CORDB-FUNCTION.CPP +// + +#include +#include +#include +#include +#include + +using namespace std; + +CordbFunction::CordbFunction(Connection* conn, mdToken token, int id, CordbModule* module) : CordbBaseMono(conn) +{ + this->m_metadataToken = token; + this->m_debuggerId = id; + m_pCode = NULL; + this->m_pModule = module; + if (module) + module->InternalAddRef(); + conn->GetProcess()->AddFunction(this); +} + +CordbFunction::~CordbFunction() +{ + if (m_pCode) + m_pCode->InternalRelease(); + if (m_pModule) + m_pModule->InternalRelease(); +} + +HRESULT CordbFunction::QueryInterface(REFIID id, void** pInterface) +{ + if (id == IID_ICorDebugFunction) + { + *pInterface = static_cast(this); + } + else if (id == IID_ICorDebugFunction2) + { + *pInterface = static_cast(this); + } + else if (id == IID_ICorDebugFunction3) + { + *pInterface = static_cast(this); + } + else if (id == IID_ICorDebugFunction4) + { + *pInterface = static_cast(this); + } + else if (id == IID_IUnknown) + { + *pInterface = static_cast(static_cast(this)); + } + else + { + *pInterface = NULL; + return E_NOINTERFACE; + } + AddRef(); + return S_OK; +} + +HRESULT CordbFunction::GetModule(ICorDebugModule** ppModule) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbFunction - GetModule - IMPLEMENTED\n")); + HRESULT hr = S_OK; + EX_TRY + { + MdbgProtBuffer localbuf; + if (!m_pModule) + { + m_dbgprot_buffer_init(&localbuf, 128); + m_dbgprot_buffer_add_id(&localbuf, m_debuggerId); + int cmdId = conn->SendEvent(MDBGPROT_CMD_SET_METHOD, MDBGPROT_CMD_METHOD_ASSEMBLY, &localbuf); + m_dbgprot_buffer_free(&localbuf); + + ReceivedReplyPacket* received_reply_packet = conn->GetReplyWithError(cmdId); + CHECK_ERROR_RETURN_FALSE(received_reply_packet); + MdbgProtBuffer* pReply = received_reply_packet->Buffer(); + + int module_id = m_dbgprot_decode_id(pReply->p, &pReply->p, pReply->end); + m_pModule = conn->GetProcess()->GetModule(module_id); + if (m_pModule) + m_pModule->InternalAddRef(); + } + + if (!m_pModule) + hr = S_FALSE; + else { + m_pModule->AddRef(); + *ppModule = static_cast(m_pModule); + } + } + EX_CATCH_HRESULT(hr); + return hr; +} + +HRESULT CordbFunction::GetClass(ICorDebugClass** ppClass) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbFunction - GetClass - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbFunction::GetToken(mdMethodDef* pMethodDef) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbFunction - GetToken - IMPLEMENTED\n")); + HRESULT hr = S_OK; + EX_TRY + { + if (this->GetMetadataToken() == 0) + { + MdbgProtBuffer localbuf; + m_dbgprot_buffer_init(&localbuf, 128); + m_dbgprot_buffer_add_id(&localbuf, m_debuggerId); + int cmdId = conn->SendEvent(MDBGPROT_CMD_SET_METHOD, MDBGPROT_CMD_METHOD_TOKEN, &localbuf); + m_dbgprot_buffer_free(&localbuf); + + ReceivedReplyPacket* received_reply_packet = conn->GetReplyWithError(cmdId); + CHECK_ERROR_RETURN_FALSE(received_reply_packet); + MdbgProtBuffer* pReply = received_reply_packet->Buffer(); + + this->m_metadataToken = m_dbgprot_decode_int(pReply->p, &pReply->p, pReply->end); + } + *pMethodDef = this->GetMetadataToken(); + } + EX_CATCH_HRESULT(hr); + return hr; +} + +HRESULT CordbFunction::GetILCode(ICorDebugCode** ppCode) +{ + if (m_pCode == NULL) + { + m_pCode = new CordbCode(conn, this); + m_pCode->InternalAddRef(); + } + m_pCode->QueryInterface(IID_ICorDebugCode, (void**)ppCode); + LOG((LF_CORDB, LL_INFO1000000, "CordbFunction - GetILCode - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbFunction::GetNativeCode(ICorDebugCode** ppCode) +{ + if (m_pCode == NULL) + { + m_pCode = new CordbCode(conn, this); + m_pCode->InternalAddRef(); + } + m_pCode->QueryInterface(IID_ICorDebugCode, (void**)ppCode); + LOG((LF_CORDB, LL_INFO1000000, "CordbFunction - GetNativeCode - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbFunction::CreateBreakpoint(ICorDebugFunctionBreakpoint** ppBreakpoint) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbFunction - CreateBreakpoint - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbFunction::GetLocalVarSigToken(mdSignature* pmdSig) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbFunction - GetLocalVarSigToken - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbFunction::GetCurrentVersionNumber(ULONG32* pnCurrentVersion) +{ + *pnCurrentVersion = 1; + LOG((LF_CORDB, LL_INFO1000000, "CordbFunction - GetCurrentVersionNumber - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbFunction::SetJMCStatus(BOOL bIsJustMyCode) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbFunction - SetJMCStatus - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbFunction::GetJMCStatus(BOOL* pbIsJustMyCode) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbFunction - GetJMCStatus - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbFunction::EnumerateNativeCode(ICorDebugCodeEnum** ppCodeEnum) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbFunction - EnumerateNativeCode - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbFunction::GetVersionNumber(ULONG32* pnVersion) +{ + *pnVersion = 1; + LOG((LF_CORDB, LL_INFO1000000, "CordbFunction - GetVersionNumber - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbFunction::GetActiveReJitRequestILCode(ICorDebugILCode** ppReJitedILCode) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbFunction - GetActiveReJitRequestILCode - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbFunction::CreateNativeBreakpoint(ICorDebugFunctionBreakpoint** ppBreakpoint) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbFunction - CreateNativeBreakpoint - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} diff --git a/src/mono/dbi/cordb-function.h b/src/mono/dbi/cordb-function.h new file mode 100644 index 0000000000000..7b74fb0bd54a7 --- /dev/null +++ b/src/mono/dbi/cordb-function.h @@ -0,0 +1,65 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: CORDB-FUNCTION.H +// + +#ifndef __MONO_DEBUGGER_CORDB_FUNCTION_H__ +#define __MONO_DEBUGGER_CORDB_FUNCTION_H__ + +#include +#include + +class CordbFunction : public CordbBaseMono, + public ICorDebugFunction, + public ICorDebugFunction2, + public ICorDebugFunction3, + public ICorDebugFunction4 +{ + int m_debuggerId; + mdToken m_metadataToken; + CordbCode* m_pCode; + CordbModule* m_pModule; + +public: + CordbFunction(Connection* conn, mdToken token, int id, CordbModule* module); + ULONG STDMETHODCALLTYPE AddRef(void) + { + return (BaseAddRef()); + } + ULONG STDMETHODCALLTYPE Release(void) + { + return (BaseRelease()); + } + const char* GetClassName() + { + return "CordbFunction"; + } + ~CordbFunction(); + int GetDebuggerId() const + { + return m_debuggerId; + } + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id, _COM_Outptr_ void __RPC_FAR* __RPC_FAR* pInterface); + + HRESULT STDMETHODCALLTYPE GetModule(ICorDebugModule** ppModule); + HRESULT STDMETHODCALLTYPE GetClass(ICorDebugClass** ppClass); + HRESULT STDMETHODCALLTYPE GetToken(mdMethodDef* pMethodDef); + HRESULT STDMETHODCALLTYPE GetILCode(ICorDebugCode** ppCode); + HRESULT STDMETHODCALLTYPE GetNativeCode(ICorDebugCode** ppCode); + HRESULT STDMETHODCALLTYPE CreateBreakpoint(ICorDebugFunctionBreakpoint** ppBreakpoint); + HRESULT STDMETHODCALLTYPE GetLocalVarSigToken(mdSignature* pmdSig); + HRESULT STDMETHODCALLTYPE GetCurrentVersionNumber(ULONG32* pnCurrentVersion); + HRESULT STDMETHODCALLTYPE SetJMCStatus(BOOL bIsJustMyCode); + HRESULT STDMETHODCALLTYPE GetJMCStatus(BOOL* pbIsJustMyCode); + HRESULT STDMETHODCALLTYPE EnumerateNativeCode(ICorDebugCodeEnum** ppCodeEnum); + HRESULT STDMETHODCALLTYPE GetVersionNumber(ULONG32* pnVersion); + HRESULT STDMETHODCALLTYPE GetActiveReJitRequestILCode(ICorDebugILCode** ppReJitedILCode); + HRESULT STDMETHODCALLTYPE CreateNativeBreakpoint(ICorDebugFunctionBreakpoint** ppBreakpoint); + mdToken GetMetadataToken() const + { + return m_metadataToken; + } +}; + +#endif diff --git a/src/mono/dbi/cordb-process.cpp b/src/mono/dbi/cordb-process.cpp new file mode 100644 index 0000000000000..422fd02495fc0 --- /dev/null +++ b/src/mono/dbi/cordb-process.cpp @@ -0,0 +1,809 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: CORDB-PROCESS.CPP +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +CordbProcess::CordbProcess(Cordb* cordb) : CordbBaseMono(NULL) +{ + m_pAppDomainEnum = NULL; + m_pBreakpoints = new ArrayList(); + m_pThreads = new ArrayList(); + m_pFunctions = new ArrayList(); + m_pModules = new ArrayList(); + m_pAddDomains = new ArrayList(); + m_pPendingEval = new ArrayList(); + m_pSteppers = new ArrayList(); + this->m_pCordb = cordb; + m_bIsJustMyCode = false; + m_pSemReadWrite = new UTSemReadWrite(); + m_pTypeMapArray = new ArrayList(); + for (DWORD i = 0; i < CordbTypeKindTotal; i++) + { + m_pTypeMapArray->Append(new MapSHashWithRemove()); + } +} + +CordbProcess::~CordbProcess() +{ + delete m_pSemReadWrite; + if (m_pAppDomainEnum) + m_pAppDomainEnum->InternalRelease(); + + for (DWORD i = 0; i < m_pBreakpoints->GetCount(); i++) + { + CordbFunctionBreakpoint* breakpoint = (CordbFunctionBreakpoint*)m_pBreakpoints->Get(i); + if (breakpoint) + breakpoint->InternalRelease(); + } + + for (DWORD i = 0; i < m_pSteppers->GetCount(); i++) + { + CordbStepper* stepper = (CordbStepper*)m_pSteppers->Get(i); + if (stepper) + stepper->InternalRelease(); + } + + for (DWORD i = 0; i < m_pThreads->GetCount(); i++) + { + CordbThread* thread = (CordbThread*)m_pThreads->Get(i); + thread->InternalRelease(); + } + + for (DWORD i = 0; i < m_pFunctions->GetCount(); i++) + { + CordbFunction* function = (CordbFunction*)m_pFunctions->Get(i); + function->InternalRelease(); + } + + for (DWORD i = 0; i < m_pAddDomains->GetCount(); i++) + { + CordbAppDomain* appdomain = (CordbAppDomain*)m_pAddDomains->Get(i); + appdomain->InternalRelease(); + } + + for (DWORD i = 0; i < m_pModules->GetCount(); i++) + { + CordbModule* module = (CordbModule*)m_pModules->Get(i); + module->InternalRelease(); + } + + for (DWORD i = 0; i < m_pPendingEval->GetCount(); i++) + { + CordbEval* eval = (CordbEval*)m_pPendingEval->Get(i); + if (eval) + eval->InternalRelease(); + } + + for (MapSHashWithRemove::Iterator iter = m_classMap.Begin(), end = m_classMap.End(); iter != end; iter++) + { + iter->Value()->InternalRelease(); + } + + + for (DWORD i = 0; i < m_pTypeMapArray->GetCount(); i++) + { + MapSHashWithRemove* typeMap = (MapSHashWithRemove*)m_pTypeMapArray->Get(i); + for (MapSHashWithRemove::Iterator iter = typeMap->Begin(), end = typeMap->End(); iter != end; iter++) + { + if (iter->Value()) + iter->Value()->InternalRelease(); + } + } + + delete m_pBreakpoints; + delete m_pThreads; + delete m_pFunctions; + delete m_pModules; + delete m_pAddDomains; + delete m_pPendingEval; + delete m_pTypeMapArray; + delete conn; +} + +void CordbProcess::CheckPendingEval() +{ + if (!m_pPendingEval) + return; + for (DWORD i = 0; i < m_pPendingEval->GetCount(); i++) + { + CordbEval* eval = (CordbEval*)m_pPendingEval->Get(i); + if (!eval) + continue; + ReceivedReplyPacket* recvbuf = conn->GetReplyWithError(eval->GetCommandId()); + if (!recvbuf) + continue; + eval->EvalComplete(recvbuf->Buffer()); + eval->InternalRelease(); + dbg_lock(); + m_pPendingEval->Set(i, NULL); + dbg_unlock(); + } +} + +HRESULT CordbProcess::EnumerateLoaderHeapMemoryRegions(ICorDebugMemoryRangeEnum** ppRanges) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - EnumerateLoaderHeapMemoryRegions - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::EnableGCNotificationEvents(BOOL fEnable) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - EnableGCNotificationEvents - NOT IMPLEMENTED\n")); + + return S_OK; +} + +HRESULT CordbProcess::EnableExceptionCallbacksOutsideOfMyCode(BOOL enableExceptionsOutsideOfJMC) +{ + LOG((LF_CORDB, LL_INFO100000, + "CordbProcess - EnableExceptionCallbacksOutsideOfMyCode - " + "NOT IMPLEMENTED\n")); + + return S_OK; +} + +HRESULT CordbProcess::SetWriteableMetadataUpdateMode(WriteableMetadataUpdateMode flags) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - SetWriteableMetadataUpdateMode - NOT IMPLEMENTED\n")); + + return S_OK; +} + +HRESULT CordbProcess::GetGCHeapInformation(COR_HEAPINFO* pHeapInfo) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - GetGCHeapInformation - NOT IMPLEMENTED\n")); + + return S_OK; +} + +HRESULT CordbProcess::EnumerateHeap(ICorDebugHeapEnum** ppObjects) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - EnumerateHeap - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT +CordbProcess::EnumerateHeapRegions(ICorDebugHeapSegmentEnum** ppRegions) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - EnumerateHeapRegions - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::GetObject(CORDB_ADDRESS addr, ICorDebugObjectValue** pObject) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - GetObject - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::EnumerateGCReferences(BOOL enumerateWeakReferences, ICorDebugGCReferenceEnum** ppEnum) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - EnumerateGCReferences - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::EnumerateHandles(CorGCReferenceType types, ICorDebugGCReferenceEnum** ppEnum) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - EnumerateHandles - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::GetTypeID(CORDB_ADDRESS obj, COR_TYPEID* pId) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - GetTypeID - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::GetTypeForTypeID(COR_TYPEID id, ICorDebugType** ppType) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - GetTypeForTypeID - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::GetArrayLayout(COR_TYPEID id, COR_ARRAY_LAYOUT* pLayout) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - GetArrayLayout - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::GetTypeLayout(COR_TYPEID id, COR_TYPE_LAYOUT* pLayout) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - GetTypeLayout - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::GetTypeFields(COR_TYPEID id, ULONG32 celt, COR_FIELD fields[], ULONG32* pceltNeeded) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - GetTypeFields - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::EnableNGENPolicy(CorDebugNGENPolicy ePolicy) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - EnableNGENPolicy - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT +CordbProcess::Filter(const BYTE pRecord[], + DWORD countBytes, + CorDebugRecordFormat format, + DWORD dwFlags, + DWORD dwThreadId, + ICorDebugManagedCallback* pCallback, + /* [out][in] */ CORDB_CONTINUE_STATUS* pContinueStatus) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - Filter - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::ProcessStateChanged(CorDebugStateChange eChange) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - ProcessStateChanged - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::SetEnableCustomNotification(ICorDebugClass* pClass, BOOL fEnable) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - SetEnableCustomNotification - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::GetID(DWORD* pdwProcessId) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - GetID - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::GetHandle(HPROCESS* phProcessHandle) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - GetHandle - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::GetThread(DWORD dwThreadId, ICorDebugThread** ppThread) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - GetThread - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::EnumerateObjects(ICorDebugObjectEnum** ppObjects) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - EnumerateObjects - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::IsTransitionStub(CORDB_ADDRESS address, BOOL* pbTransitionStub) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - IsTransitionStub - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::IsOSSuspended(DWORD threadID, BOOL* pbSuspended) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - IsOSSuspended - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::GetThreadContext(DWORD threadID, ULONG32 contextSize, BYTE context[]) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - GetThreadContext - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::SetThreadContext(DWORD threadID, ULONG32 contextSize, BYTE context[]) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - SetThreadContext - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::ReadMemory(CORDB_ADDRESS address, DWORD size, BYTE buffer[], SIZE_T* read) +{ + LOG((LF_CORDB, LL_INFO1000000, "CordbProcess - ReadMemory - IMPLEMENTED\n")); + HRESULT hr = S_OK; + EX_TRY + { + MdbgProtBuffer localbuf; + m_dbgprot_buffer_init(&localbuf, 128); + m_dbgprot_buffer_add_long(&localbuf, address); + m_dbgprot_buffer_add_int(&localbuf, size); + int cmdId = conn->SendEvent(MDBGPROT_CMD_SET_VM, MDBGPROT_CMD_VM_READ_MEMORY, &localbuf); + m_dbgprot_buffer_free(&localbuf); + + ReceivedReplyPacket* received_reply_packet = conn->GetReplyWithError(cmdId); + CHECK_ERROR_RETURN_FALSE(received_reply_packet); + MdbgProtBuffer* pReply = received_reply_packet->Buffer(); + int memoryReadSize = 0; + uint8_t* memoryRead = m_dbgprot_decode_byte_array(pReply->p, &pReply->p, pReply->end, (int32_t*)&memoryReadSize); + memcpy(buffer, (void*)memoryRead, memoryReadSize); + if (read != NULL) + *read = memoryReadSize; + free(memoryRead); + } + EX_CATCH_HRESULT(hr); + return hr; +} + +HRESULT CordbProcess::WriteMemory(CORDB_ADDRESS address, DWORD size, BYTE buffer[], SIZE_T* written) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - WriteMemory - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::ClearCurrentException(DWORD threadID) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - ClearCurrentException - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::EnableLogMessages(BOOL fOnOff) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - EnableLogMessages - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::ModifyLogSwitch( + /* [annotation][in] */ + _In_ WCHAR* pLogSwitchName, + LONG lLevel) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - ModifyLogSwitch - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT +CordbProcess::EnumerateAppDomains(ICorDebugAppDomainEnum** ppAppDomains) +{ + if (!m_pAppDomainEnum) + { + m_pAppDomainEnum = new CordbAppDomainEnum(conn, this); + m_pAppDomainEnum->InternalAddRef(); + } + m_pAppDomainEnum->QueryInterface(IID_ICorDebugAppDomainEnum, (void**)ppAppDomains); + LOG((LF_CORDB, LL_INFO1000000, "CordbProcess - EnumerateAppDomains - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::GetObject(ICorDebugValue** ppObject) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - GetObject - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::ThreadForFiberCookie(DWORD fiberCookie, ICorDebugThread** ppThread) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - ThreadForFiberCookie - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::GetHelperThreadID(DWORD* pThreadID) +{ + LOG((LF_CORDB, LL_INFO100000, "GetHelperThreadID - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::GetThreadForTaskID(TASKID taskid, ICorDebugThread2** ppThread) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - GetHelperThreadID - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::GetVersion(COR_VERSION* version) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - GetVersion - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::SetUnmanagedBreakpoint(CORDB_ADDRESS address, ULONG32 bufsize, BYTE buffer[], ULONG32* bufLen) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - SetUnmanagedBreakpoint - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::ClearUnmanagedBreakpoint(CORDB_ADDRESS address) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - ClearUnmanagedBreakpoint - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::SetDesiredNGENCompilerFlags(DWORD pdwFlags) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - SetDesiredNGENCompilerFlags - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::GetDesiredNGENCompilerFlags(DWORD* pdwFlags) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - GetDesiredNGENCompilerFlags - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::GetReferenceValueFromGCHandle(UINT_PTR handle, ICorDebugReferenceValue** pOutValue) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - GetReferenceValueFromGCHandle - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::QueryInterface(REFIID id, _COM_Outptr_ void __RPC_FAR* __RPC_FAR* pInterface) +{ + if (id == IID_ICorDebugProcess) + { + *pInterface = static_cast(this); + } + else if (id == IID_ICorDebugController) + { + *pInterface = static_cast(static_cast(this)); + } + else if (id == IID_ICorDebugProcess2) + { + *pInterface = static_cast(this); + } + else if (id == IID_ICorDebugProcess3) + { + *pInterface = static_cast(this); + } + else if (id == IID_ICorDebugProcess4) + { + *pInterface = static_cast(this); + } + else if (id == IID_ICorDebugProcess5) + { + *pInterface = static_cast(this); + } + else if (id == IID_ICorDebugProcess7) + { + *pInterface = static_cast(this); + } + else if (id == IID_ICorDebugProcess8) + { + *pInterface = static_cast(this); + } + else if (id == IID_ICorDebugProcess10) + { + *pInterface = static_cast(this); + } + else if (id == IID_ICorDebugProcess11) + { + *pInterface = static_cast(this); + } + else if (id == IID_IUnknown) + { + *pInterface = static_cast(static_cast(this)); + } + else + { + *pInterface = NULL; + return E_NOINTERFACE; + } + AddRef(); + return S_OK; +} + +HRESULT CordbProcess::Stop(DWORD dwTimeoutIgnored) +{ + LOG((LF_CORDB, LL_INFO1000000, "CordbProcess - Stop - IMPLEMENTED\n")); + MdbgProtBuffer sendbuf; + m_dbgprot_buffer_init(&sendbuf, 128); + conn->SendEvent(MDBGPROT_CMD_SET_VM, MDBGPROT_CMD_VM_SUSPEND, &sendbuf); + m_dbgprot_buffer_free(&sendbuf); + return S_OK; +} + +HRESULT CordbProcess::Continue(BOOL fIsOutOfBand) +{ + LOG((LF_CORDB, LL_INFO1000000, "CordbProcess - Continue - IMPLEMENTED\n")); + MdbgProtBuffer sendbuf; + m_dbgprot_buffer_init(&sendbuf, 128); + conn->SendEvent(MDBGPROT_CMD_SET_VM, MDBGPROT_CMD_VM_RESUME, &sendbuf); + m_dbgprot_buffer_free(&sendbuf); + return S_OK; +} + +HRESULT CordbProcess::IsRunning(BOOL* pbRunning) +{ + *pbRunning = true; + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - IsRunning - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::HasQueuedCallbacks(ICorDebugThread* pThread, BOOL* pbQueued) +{ + // conn->process_packet_from_queue(); + *pbQueued = false; + LOG((LF_CORDB, LL_INFO1000000, "CordbProcess - HasQueuedCallbacks - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::EnumerateThreads(ICorDebugThreadEnum** ppThreads) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - EnumerateThreads - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT +CordbProcess::SetAllThreadsDebugState(CorDebugThreadState state, ICorDebugThread* pExceptThisThread) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - SetAllThreadsDebugState - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::Detach(void) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - Detach - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT CordbProcess::Terminate(UINT exitCode) +{ + MdbgProtBuffer sendbuf; + m_dbgprot_buffer_init(&sendbuf, 128); + m_dbgprot_buffer_add_int(&sendbuf, -1); + conn->SendEvent(MDBGPROT_CMD_SET_VM, MDBGPROT_CMD_VM_EXIT, &sendbuf); + m_dbgprot_buffer_free(&sendbuf); + return S_OK; +} + +HRESULT +CordbProcess::CanCommitChanges(ULONG cSnapshots, + ICorDebugEditAndContinueSnapshot* pSnapshots[], + ICorDebugErrorInfoEnum** pError) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - CanCommitChanges - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT +CordbProcess::CommitChanges(ULONG cSnapshots, + ICorDebugEditAndContinueSnapshot* pSnapshots[], + ICorDebugErrorInfoEnum** pError) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbProcess - CommitChanges - NOT IMPLEMENTED\n")); + return S_OK; +} + +void CordbProcess::AddThread(CordbThread* thread) +{ + dbg_lock(); + m_pThreads->Append(thread); + thread->InternalAddRef(); + dbg_unlock(); +} + +void CordbProcess::AddFunction(CordbFunction* function) +{ + dbg_lock(); + m_pFunctions->Append(function); + function->InternalAddRef(); + dbg_unlock(); +} + +void CordbProcess::AddModule(CordbModule* module) +{ + dbg_lock(); + m_pModules->Append(module); + module->InternalAddRef(); + dbg_unlock(); +} + +void CordbProcess::AddAppDomain(CordbAppDomain* appDomain) +{ + dbg_lock(); + m_pAddDomains->Append(appDomain); + appDomain->InternalAddRef(); + dbg_unlock(); +} + +void CordbProcess::AddPendingEval(CordbEval* eval) +{ + dbg_lock(); + m_pPendingEval->Append(eval); + eval->InternalAddRef(); + dbg_unlock(); +} + +void CordbProcess::AddBreakpoint(CordbFunctionBreakpoint* bp) +{ + dbg_lock(); + m_pBreakpoints->Append(bp); + bp->InternalAddRef(); + dbg_unlock(); +} + +void CordbProcess::AddStepper(CordbStepper* step) +{ + dbg_lock(); + m_pSteppers->Append(step); + step->InternalAddRef(); + dbg_unlock(); +} + +CordbClass* CordbProcess::FindOrAddClass(mdToken token, int module_id) +{ + CordbClass *ret = NULL; + dbg_lock(); + if (!m_classMap.Lookup(token, &ret)) { + ret = new CordbClass(conn, token, module_id); + m_classMap.Add(token, ret); + ret->InternalAddRef(); + } + dbg_unlock(); + return ret; +} + +CordbType* CordbProcess::FindOrAddPrimitiveType(CorElementType type) +{ + CordbType* ret = NULL; + MapSHashWithRemove* typeMap = (MapSHashWithRemove*) m_pTypeMapArray->Get(CordbTypeKindSimpleType); + dbg_lock(); + if (!typeMap->Lookup(type, &ret)) { + ret = new CordbType(type, conn); + typeMap->Add(type, ret); + ret->InternalAddRef(); + } + dbg_unlock(); + return ret; +} + +CordbType* CordbProcess::FindOrAddClassType(CorElementType type, CordbClass *klass) +{ + CordbType* ret = NULL; + mdToken token; + if (klass == NULL) + return FindOrAddPrimitiveType(type); + MapSHashWithRemove* typeMap = (MapSHashWithRemove*) m_pTypeMapArray->Get(CordbTypeKindClassType); + dbg_lock(); + klass->GetToken(&token); + if (!typeMap->Lookup(token, &ret)) { + ret = new CordbType(type, conn, klass); + typeMap->Add(token, ret); + ret->InternalAddRef(); + } + dbg_unlock(); + return ret; +} + +CordbType* CordbProcess::FindOrAddArrayType(CorElementType type, CordbType* arrayType) +{ + CordbType* ret = NULL; + long hash = 0; + MapSHashWithRemove* typeMap = (MapSHashWithRemove*) m_pTypeMapArray->Get(CordbTypeKindArrayType); + dbg_lock(); + CorElementType eleType; + ICorDebugClass *eleClass = 0; + mdTypeDef eleToken = 0; + arrayType->GetType(&eleType); + if (eleType == ELEMENT_TYPE_CLASS) + { + arrayType->GetClass(&eleClass); + eleClass->GetToken(&eleToken); + } + hash = (long)(pow(2, eleToken & 0xffffff) * pow(3, type) * pow(5, eleType)); //TODO: define a better hash + if (!typeMap->Lookup(hash, &ret)) { + ret = new CordbType(type, conn, NULL, arrayType); + typeMap->Add(hash, ret); + ret->InternalAddRef(); + } + dbg_unlock(); + return ret; +} + +CordbFunction* CordbProcess::FindFunction(int id) +{ + CordbFunction* ret = NULL; + dbg_lock(); + for (DWORD i = 0; i < m_pFunctions->GetCount(); i++) + { + CordbFunction* function = (CordbFunction*)m_pFunctions->Get(i); + if (function->GetDebuggerId() == id) + { + ret = function; + break; + } + } + dbg_unlock(); + return ret; +} + +CordbStepper* CordbProcess::GetStepper(int id) +{ + CordbStepper *ret = NULL; + dbg_lock(); + for (DWORD i = 0; i < m_pSteppers->GetCount(); i++) + { + CordbStepper* stepper = (CordbStepper*)m_pSteppers->Get(i); + if (stepper->GetDebuggerId() == id) + { + ret = stepper; + break; + } + } + dbg_unlock(); + return ret; +} + +CordbModule* CordbProcess::GetModule(int module_id) +{ + CordbModule* ret = NULL; + dbg_lock(); + for (DWORD i = 0; i < m_pModules->GetCount(); i++) + { + CordbModule* module = (CordbModule*)m_pModules->Get(i); + if (module->GetDebuggerId() == module_id) + { + ret = module; + break; + } + } + dbg_unlock(); + return ret; +} + +CordbAppDomain* CordbProcess::GetCurrentAppDomain() +{ + CordbAppDomain* ret = NULL; + dbg_lock(); + if (m_pAddDomains->GetCount() > 0) + ret = (CordbAppDomain*)m_pAddDomains->Get(0); + dbg_unlock(); + return ret; +} + +CordbThread* CordbProcess::FindThread(long thread_id) +{ + CordbThread* ret = NULL; + dbg_lock(); + for (DWORD i = 0; i < m_pThreads->GetCount(); i++) + { + CordbThread* thread = (CordbThread*)m_pThreads->Get(i); + if (thread->GetThreadId() == thread_id) + { + ret = thread; + break; + } + } + dbg_unlock(); + return ret; +} + +CordbFunctionBreakpoint* CordbProcess::GetBreakpoint(int id) +{ + CordbFunctionBreakpoint* ret = NULL; + dbg_lock(); + for (DWORD i = 0; i < m_pBreakpoints->GetCount(); i++) + { + CordbFunctionBreakpoint* bp = (CordbFunctionBreakpoint*)m_pBreakpoints->Get(i); + if (bp->GetDebuggerId() == id) + { + ret = bp; + break; + } + } + dbg_unlock(); + return ret; +} + +void CordbProcess::SetJMCStatus(BOOL bIsJustMyCode) +{ + m_bIsJustMyCode = bIsJustMyCode; +} + +BOOL CordbProcess::GetJMCStatus() +{ + return m_bIsJustMyCode; +} + diff --git a/src/mono/dbi/cordb-process.h b/src/mono/dbi/cordb-process.h new file mode 100644 index 0000000000000..8506c2097c92f --- /dev/null +++ b/src/mono/dbi/cordb-process.h @@ -0,0 +1,143 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: CORDB-PROCESS.H +// + +#ifndef __MONO_DEBUGGER_CORDB_PROCESS_H__ +#define __MONO_DEBUGGER_CORDB_PROCESS_H__ + +#include +#include +#include + + + +class CordbProcess : public CordbBaseMono, + public ICorDebugProcess, + public ICorDebugProcess2, + public ICorDebugProcess3, + public ICorDebugProcess4, + public ICorDebugProcess5, + public ICorDebugProcess7, + public ICorDebugProcess8, + public ICorDebugProcess10, + public ICorDebugProcess11 +{ + ArrayList* m_pBreakpoints; + ArrayList* m_pThreads; + ArrayList* m_pFunctions; + ArrayList* m_pModules; + ArrayList* m_pPendingEval; + ArrayList* m_pSteppers; + CordbAppDomainEnum* m_pAppDomainEnum; + Cordb* m_pCordb; + BOOL m_bIsJustMyCode; + ArrayList* m_pTypeMapArray; //TODO: define a better data structure to find CordbType + MapSHashWithRemove m_classMap; +public: + ArrayList* m_pAddDomains; + CordbProcess(Cordb* cordb); + ULONG STDMETHODCALLTYPE AddRef(void) + { + return (BaseAddRef()); + } + ULONG STDMETHODCALLTYPE Release(void) + { + return (BaseRelease()); + } + const char* GetClassName() + { + return "CordbProcess"; + } + Cordb* GetCordb() const + { + return m_pCordb; + } + ~CordbProcess(); + HRESULT STDMETHODCALLTYPE EnumerateLoaderHeapMemoryRegions(ICorDebugMemoryRangeEnum** ppRanges); + HRESULT STDMETHODCALLTYPE EnableGCNotificationEvents(BOOL fEnable); + HRESULT STDMETHODCALLTYPE EnableExceptionCallbacksOutsideOfMyCode(BOOL enableExceptionsOutsideOfJMC); + HRESULT STDMETHODCALLTYPE SetWriteableMetadataUpdateMode(WriteableMetadataUpdateMode flags); + HRESULT STDMETHODCALLTYPE GetGCHeapInformation(COR_HEAPINFO* pHeapInfo); + HRESULT STDMETHODCALLTYPE EnumerateHeap(ICorDebugHeapEnum** ppObjects); + HRESULT STDMETHODCALLTYPE EnumerateHeapRegions(ICorDebugHeapSegmentEnum** ppRegions); + HRESULT STDMETHODCALLTYPE GetObject(CORDB_ADDRESS addr, ICorDebugObjectValue** pObject); + HRESULT STDMETHODCALLTYPE EnumerateGCReferences(BOOL enumerateWeakReferences, ICorDebugGCReferenceEnum** ppEnum); + HRESULT STDMETHODCALLTYPE EnumerateHandles(CorGCReferenceType types, ICorDebugGCReferenceEnum** ppEnum); + HRESULT STDMETHODCALLTYPE GetTypeID(CORDB_ADDRESS obj, COR_TYPEID* pId); + HRESULT STDMETHODCALLTYPE GetTypeForTypeID(COR_TYPEID id, ICorDebugType** ppType); + HRESULT STDMETHODCALLTYPE GetArrayLayout(COR_TYPEID id, COR_ARRAY_LAYOUT* pLayout); + HRESULT STDMETHODCALLTYPE GetTypeLayout(COR_TYPEID id, COR_TYPE_LAYOUT* pLayout); + HRESULT STDMETHODCALLTYPE GetTypeFields(COR_TYPEID id, ULONG32 celt, COR_FIELD fields[], ULONG32* pceltNeeded); + HRESULT STDMETHODCALLTYPE EnableNGENPolicy(CorDebugNGENPolicy ePolicy); + HRESULT STDMETHODCALLTYPE Filter(const BYTE pRecord[], + DWORD countBytes, + CorDebugRecordFormat format, + DWORD dwFlags, + DWORD dwThreadId, + ICorDebugManagedCallback* pCallback, + CORDB_CONTINUE_STATUS* pContinueStatus); + HRESULT STDMETHODCALLTYPE ProcessStateChanged(CorDebugStateChange eChange); + HRESULT STDMETHODCALLTYPE SetEnableCustomNotification(ICorDebugClass* pClass, BOOL fEnable); + HRESULT STDMETHODCALLTYPE GetID(DWORD* pdwProcessId); + HRESULT STDMETHODCALLTYPE GetHandle(HPROCESS* phProcessHandle); + HRESULT STDMETHODCALLTYPE GetThread(DWORD dwThreadId, ICorDebugThread** ppThread); + HRESULT STDMETHODCALLTYPE EnumerateObjects(ICorDebugObjectEnum** ppObjects); + HRESULT STDMETHODCALLTYPE IsTransitionStub(CORDB_ADDRESS address, BOOL* pbTransitionStub); + HRESULT STDMETHODCALLTYPE IsOSSuspended(DWORD threadID, BOOL* pbSuspended); + HRESULT STDMETHODCALLTYPE GetThreadContext(DWORD threadID, ULONG32 contextSize, BYTE context[]); + HRESULT STDMETHODCALLTYPE SetThreadContext(DWORD threadID, ULONG32 contextSize, BYTE context[]); + HRESULT STDMETHODCALLTYPE ReadMemory(CORDB_ADDRESS address, DWORD size, BYTE buffer[], SIZE_T* read); + HRESULT STDMETHODCALLTYPE WriteMemory(CORDB_ADDRESS address, DWORD size, BYTE buffer[], SIZE_T* written); + HRESULT STDMETHODCALLTYPE ClearCurrentException(DWORD threadID); + HRESULT STDMETHODCALLTYPE EnableLogMessages(BOOL fOnOff); + HRESULT STDMETHODCALLTYPE ModifyLogSwitch(_In_ WCHAR* pLogSwitchName, LONG lLevel); + HRESULT STDMETHODCALLTYPE EnumerateAppDomains(ICorDebugAppDomainEnum** ppAppDomains); + HRESULT STDMETHODCALLTYPE GetObject(ICorDebugValue** ppObject); + HRESULT STDMETHODCALLTYPE ThreadForFiberCookie(DWORD fiberCookie, ICorDebugThread** ppThread); + HRESULT STDMETHODCALLTYPE GetHelperThreadID(DWORD* pThreadID); + HRESULT STDMETHODCALLTYPE GetThreadForTaskID(TASKID taskid, ICorDebugThread2** ppThread); + HRESULT STDMETHODCALLTYPE GetVersion(COR_VERSION* version); + HRESULT STDMETHODCALLTYPE SetUnmanagedBreakpoint(CORDB_ADDRESS address, ULONG32 bufsize, BYTE buffer[], ULONG32* bufLen); + HRESULT STDMETHODCALLTYPE ClearUnmanagedBreakpoint(CORDB_ADDRESS address); + HRESULT STDMETHODCALLTYPE SetDesiredNGENCompilerFlags(DWORD pdwFlags); + HRESULT STDMETHODCALLTYPE GetDesiredNGENCompilerFlags(DWORD* pdwFlags); + HRESULT STDMETHODCALLTYPE GetReferenceValueFromGCHandle(UINT_PTR handle, ICorDebugReferenceValue** pOutValue); + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id, _COM_Outptr_ void __RPC_FAR* __RPC_FAR* pInterface); + + HRESULT STDMETHODCALLTYPE Stop(DWORD dwTimeoutIgnored); + HRESULT STDMETHODCALLTYPE Continue(BOOL fIsOutOfBand); + HRESULT STDMETHODCALLTYPE IsRunning(BOOL* pbRunning); + HRESULT STDMETHODCALLTYPE HasQueuedCallbacks(ICorDebugThread* pThread, BOOL* pbQueued); + HRESULT STDMETHODCALLTYPE EnumerateThreads(ICorDebugThreadEnum** ppThreads); + HRESULT STDMETHODCALLTYPE SetAllThreadsDebugState(CorDebugThreadState state, ICorDebugThread* pExceptThisThread); + HRESULT STDMETHODCALLTYPE Detach(void); + HRESULT STDMETHODCALLTYPE Terminate(UINT exitCode); + HRESULT STDMETHODCALLTYPE CanCommitChanges(ULONG cSnapshots, ICorDebugEditAndContinueSnapshot* pSnapshots[], ICorDebugErrorInfoEnum** pError); + HRESULT STDMETHODCALLTYPE CommitChanges(ULONG cSnapshots, ICorDebugEditAndContinueSnapshot* pSnapshots[], ICorDebugErrorInfoEnum** pError); + + void AddThread(CordbThread* thread); + void AddFunction(CordbFunction* function); + void AddModule(CordbModule* module); + void AddAppDomain(CordbAppDomain* appDomain); + void AddBreakpoint(CordbFunctionBreakpoint* bp); + void AddPendingEval(CordbEval* eval); + void AddStepper(CordbStepper* step); + CordbClass* FindOrAddClass(mdToken token, int module_id); + CordbType* FindOrAddPrimitiveType(CorElementType type); + CordbType* FindOrAddClassType(CorElementType type, CordbClass *klass); + CordbType* FindOrAddArrayType(CorElementType type, CordbType* elementType); + //CordbType* FindOrAddGenericInstanceType(CorElementType type, std::initializer_list arrayType); //use std::initializer_list for generic instances + CordbFunction* FindFunction(int id); + CordbModule* GetModule(int module_id); + CordbStepper* GetStepper(int id); + CordbAppDomain* GetCurrentAppDomain(); + CordbThread* FindThread(long thread_id); + CordbFunctionBreakpoint* GetBreakpoint(int id); + void CheckPendingEval(); + void SetJMCStatus(BOOL bIsJustMyCode); + BOOL GetJMCStatus(); +}; + +#endif diff --git a/src/mono/dbi/cordb-register.cpp b/src/mono/dbi/cordb-register.cpp new file mode 100644 index 0000000000000..78b5d43af2c79 --- /dev/null +++ b/src/mono/dbi/cordb-register.cpp @@ -0,0 +1,53 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: CORDB-REGISTER.CPP +// + +#include +#include +#include + +using namespace std; + +HRESULT CordbRegisterSet::GetRegistersAvailable(ULONG64* pAvailable) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbRegisterSet - GetRegistersAvailable - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +CordbRegisterSet::CordbRegisterSet(Connection* conn, uint8_t* ctx, uint32_t ctx_len) : CordbBaseMono(conn) +{ + this->m_pCtx = ctx; + this->m_ctxLen = ctx_len; +} + +HRESULT CordbRegisterSet::QueryInterface(REFIID id, void** pInterface) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbRegisterSet - QueryInterface - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT CordbRegisterSet::GetRegisters(ULONG64 mask, ULONG32 regCount, CORDB_REGISTER regBuffer[]) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbRegisterSet - GetRegisters - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbRegisterSet::SetRegisters(ULONG64 mask, ULONG32 regCount, CORDB_REGISTER regBuffer[]) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbRegisterSet - SetRegisters - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbRegisterSet::GetThreadContext(ULONG32 contextSize, BYTE context[]) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbRegisterSet - GetThreadContext - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbRegisterSet::SetThreadContext(ULONG32 contextSize, BYTE context[]) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbRegisterSet - SetThreadContext - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} diff --git a/src/mono/dbi/cordb-register.h b/src/mono/dbi/cordb-register.h new file mode 100644 index 0000000000000..58f452b428a86 --- /dev/null +++ b/src/mono/dbi/cordb-register.h @@ -0,0 +1,40 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: CORDB-REGISTER.H +// + +#ifndef __MONO_DEBUGGER_CORDB_REGISTER_H__ +#define __MONO_DEBUGGER_CORDB_REGISTER_H__ + +#include + +class CordbRegisterSet : public CordbBaseMono, public ICorDebugRegisterSet +{ + uint8_t* m_pCtx; + uint32_t m_ctxLen; + +public: + CordbRegisterSet(Connection* conn, uint8_t* ctx, uint32_t ctx_len); + ULONG STDMETHODCALLTYPE AddRef(void) + { + return (BaseAddRef()); + } + ULONG STDMETHODCALLTYPE Release(void) + { + return (BaseRelease()); + } + const char* GetClassName() + { + return "CordbRegisterSet"; + } + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id, _COM_Outptr_ void __RPC_FAR* __RPC_FAR* pInterface); + + HRESULT STDMETHODCALLTYPE GetRegistersAvailable(ULONG64* pAvailable); + HRESULT STDMETHODCALLTYPE GetRegisters(ULONG64 mask, ULONG32 regCount, CORDB_REGISTER regBuffer[]); + HRESULT STDMETHODCALLTYPE SetRegisters(ULONG64 mask, ULONG32 regCount, CORDB_REGISTER regBuffer[]); + HRESULT STDMETHODCALLTYPE GetThreadContext(ULONG32 contextSize, BYTE context[]); + HRESULT STDMETHODCALLTYPE SetThreadContext(ULONG32 contextSize, BYTE context[]); +}; + +#endif diff --git a/src/mono/dbi/cordb-stepper.cpp b/src/mono/dbi/cordb-stepper.cpp new file mode 100644 index 0000000000000..fba5d4c278a75 --- /dev/null +++ b/src/mono/dbi/cordb-stepper.cpp @@ -0,0 +1,148 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: CORDB-STEPPER.CPP +// + +#include +#include +#include +#include +#include + +using namespace std; + +CordbStepper::CordbStepper(Connection* conn, CordbThread* thread) : CordbBaseMono(conn) +{ + m_pThread = thread; + m_debuggerId = -1; + conn->GetProcess()->AddStepper(this); +} + +CordbStepper::~CordbStepper() {} + +HRESULT STDMETHODCALLTYPE CordbStepper::IsActive(BOOL* pbActive) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbStepper - IsActive - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbStepper::Deactivate(void) +{ + LOG((LF_CORDB, LL_INFO1000000, "CordbStepper - Deactivate - IMPLEMENTED\n")); + MdbgProtBuffer sendbuf; + int buflen = 128; + m_dbgprot_buffer_init(&sendbuf, buflen); + m_dbgprot_buffer_add_byte(&sendbuf, MDBGPROT_EVENT_KIND_STEP); + m_dbgprot_buffer_add_int(&sendbuf, m_debuggerId); + conn->SendEvent(MDBGPROT_CMD_SET_EVENT_REQUEST, MDBGPROT_CMD_EVENT_REQUEST_CLEAR, &sendbuf); + m_dbgprot_buffer_free(&sendbuf); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbStepper::SetInterceptMask(CorDebugIntercept mask) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbStepper - SetInterceptMask - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbStepper::SetUnmappedStopMask(CorDebugUnmappedStop mask) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbStepper - SetUnmappedStopMask - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbStepper::Step(BOOL bStepIn) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbStepper - Step - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbStepper::StepRange(BOOL bStepIn, COR_DEBUG_STEP_RANGE ranges[], ULONG32 cRangeCount) +{ + LOG((LF_CORDB, LL_INFO1000000, "CordbStepper - StepRange - IMPLEMENTED\n")); + HRESULT hr = S_OK; + EX_TRY + { + MdbgProtBuffer sendbuf; + int buflen = 128; + m_dbgprot_buffer_init(&sendbuf, buflen); + m_dbgprot_buffer_add_byte(&sendbuf, MDBGPROT_EVENT_KIND_STEP); + m_dbgprot_buffer_add_byte(&sendbuf, MDBGPROT_SUSPEND_POLICY_ALL); + m_dbgprot_buffer_add_byte(&sendbuf, 1); // modifiers + m_dbgprot_buffer_add_byte(&sendbuf, MDBGPROT_MOD_KIND_STEP); + + m_dbgprot_buffer_add_id(&sendbuf, m_pThread->GetThreadId()); + m_dbgprot_buffer_add_int(&sendbuf, MDBGPROT_STEP_SIZE_MIN); + m_dbgprot_buffer_add_int(&sendbuf, bStepIn ? MDBGPROT_STEP_DEPTH_INTO : MDBGPROT_STEP_DEPTH_OVER); + m_dbgprot_buffer_add_int(&sendbuf, conn->GetProcess()->GetJMCStatus() ? MDBGPROT_STEP_FILTER_DEBUGGER_NON_USER_CODE : MDBGPROT_STEP_FILTER_NONE); + + int cmdId = conn->SendEvent(MDBGPROT_CMD_SET_EVENT_REQUEST, MDBGPROT_CMD_EVENT_REQUEST_SET, &sendbuf); + m_dbgprot_buffer_free(&sendbuf); + + ReceivedReplyPacket* received_reply_packet = conn->GetReplyWithError(cmdId); + CHECK_ERROR_RETURN_FALSE(received_reply_packet); + MdbgProtBuffer* pReply = received_reply_packet->Buffer(); + + m_debuggerId = m_dbgprot_decode_id(pReply->p, &pReply->p, pReply->end); + } + EX_CATCH_HRESULT(hr); + return hr; +} + +HRESULT STDMETHODCALLTYPE CordbStepper::StepOut(void) +{ + LOG((LF_CORDB, LL_INFO1000000, "CordbStepper - StepOut - IMPLEMENTED\n")); + HRESULT hr = S_OK; + EX_TRY + { + MdbgProtBuffer sendbuf; + int buflen = 128; + m_dbgprot_buffer_init(&sendbuf, buflen); + m_dbgprot_buffer_add_byte(&sendbuf, MDBGPROT_EVENT_KIND_STEP); + m_dbgprot_buffer_add_byte(&sendbuf, MDBGPROT_SUSPEND_POLICY_ALL); + m_dbgprot_buffer_add_byte(&sendbuf, 1); // modifiers + m_dbgprot_buffer_add_byte(&sendbuf, MDBGPROT_MOD_KIND_STEP); + + m_dbgprot_buffer_add_id(&sendbuf, m_pThread->GetThreadId()); + m_dbgprot_buffer_add_int(&sendbuf, MDBGPROT_STEP_SIZE_MIN); + m_dbgprot_buffer_add_int(&sendbuf, MDBGPROT_STEP_DEPTH_OUT); + m_dbgprot_buffer_add_int(&sendbuf, MDBGPROT_STEP_FILTER_NONE); + + int cmdId = conn->SendEvent(MDBGPROT_CMD_SET_EVENT_REQUEST, MDBGPROT_CMD_EVENT_REQUEST_SET, &sendbuf); + m_dbgprot_buffer_free(&sendbuf); + + ReceivedReplyPacket* received_reply_packet = conn->GetReplyWithError(cmdId); + CHECK_ERROR_RETURN_FALSE(received_reply_packet); + MdbgProtBuffer* pReply = received_reply_packet->Buffer(); + } + EX_CATCH_HRESULT(hr); + return hr; +} + +HRESULT STDMETHODCALLTYPE CordbStepper::SetRangeIL(BOOL bIL) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbStepper - SetRangeIL - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbStepper::QueryInterface(REFIID id, void** pInterface) +{ + if (id == IID_ICorDebugStepper) + *pInterface = static_cast(this); + else if (id == IID_ICorDebugStepper2) + *pInterface = static_cast(this); + else if (id == IID_IUnknown) + *pInterface = static_cast(static_cast(this)); + else + return E_NOINTERFACE; + + AddRef(); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbStepper::SetJMC(BOOL fIsJMCStepper) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbStepper - SetJMC - NOT IMPLEMENTED\n")); + return S_OK; +} diff --git a/src/mono/dbi/cordb-stepper.h b/src/mono/dbi/cordb-stepper.h new file mode 100644 index 0000000000000..c8d031bec52a9 --- /dev/null +++ b/src/mono/dbi/cordb-stepper.h @@ -0,0 +1,48 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: CORDB-STEPPER.H +// + +#ifndef __MONO_DEBUGGER_CORDB_STEPPER_H__ +#define __MONO_DEBUGGER_CORDB_STEPPER_H__ + +#include + +class CordbStepper : public CordbBaseMono, public ICorDebugStepper, public ICorDebugStepper2 +{ + CordbThread* m_pThread; + int m_debuggerId; + +public: + CordbStepper(Connection* conn, CordbThread* thread); + ~CordbStepper(); + ULONG STDMETHODCALLTYPE AddRef(void) + { + return (BaseAddRef()); + } + ULONG STDMETHODCALLTYPE Release(void) + { + return (BaseRelease()); + } + const char* GetClassName() + { + return "CordbStepper"; + } + HRESULT STDMETHODCALLTYPE IsActive(BOOL* pbActive); + HRESULT STDMETHODCALLTYPE Deactivate(void); + HRESULT STDMETHODCALLTYPE SetInterceptMask(CorDebugIntercept mask); + HRESULT STDMETHODCALLTYPE SetUnmappedStopMask(CorDebugUnmappedStop mask); + HRESULT STDMETHODCALLTYPE Step(BOOL bStepIn); + HRESULT STDMETHODCALLTYPE StepRange(BOOL bStepIn, COR_DEBUG_STEP_RANGE ranges[], ULONG32 cRangeCount); + HRESULT STDMETHODCALLTYPE StepOut(void); + HRESULT STDMETHODCALLTYPE SetRangeIL(BOOL bIL); + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject); + HRESULT STDMETHODCALLTYPE SetJMC(BOOL fIsJMCStepper); + int GetDebuggerId() const + { + return m_debuggerId; + } +}; + +#endif diff --git a/src/mono/dbi/cordb-symbol.h b/src/mono/dbi/cordb-symbol.h new file mode 100644 index 0000000000000..8dfde91e47cdc --- /dev/null +++ b/src/mono/dbi/cordb-symbol.h @@ -0,0 +1,667 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: CORDB-SYMBOL.H +// + +#ifndef __MONO_DEBUGGER_CORDB_SYMBOL_H__ +#define __MONO_DEBUGGER_CORDB_SYMBOL_H__ + +#include +#include + +#define COR_GLOBAL_PARENT_TOKEN TokenFromRid(1, mdtTypeDef) + +class CLiteWeightStgdbRW; + +class RegMeta : public CordbBaseMono, + public IMetaDataImport2, + public IMetaDataAssemblyImport { + CLiteWeightStgdbRW *m_pStgdb; + +public: + RegMeta(CordbAssembly *cordbAssembly, CordbModule *cordbModule); + ~RegMeta(); + ULONG STDMETHODCALLTYPE AddRef(void) { return (BaseAddRef()); } + ULONG STDMETHODCALLTYPE Release(void) { return (BaseRelease()); } + const char *GetClassName() { return "CordbRegMeta"; } + + inline int IsGlobalMethodParentTk(mdTypeDef td) { + return (td == mdTypeDefNil || td == mdTokenNil); + } + + int inline IsGlobalMethodParent(mdTypeDef *ptd) { + if (IsGlobalMethodParentTk(*ptd)) { + *ptd = COR_GLOBAL_PARENT_TOKEN; + return (true); + } + return (false); + } + + int inline IsGlobalMethodParentToken(mdTypeDef td) { + return (td == COR_GLOBAL_PARENT_TOKEN); + } + + STDMETHOD(EnumGenericParams) + (HCORENUM *phEnum, // [IN|OUT] Pointer to the enum. + mdToken + tk, // [IN] TypeDef or MethodDef whose generic parameters are requested + mdGenericParam rGenericParams[], // [OUT] Put GenericParams here. + ULONG cMax, // [IN] Max GenericParams to put. + ULONG *pcGenericParams); + + STDMETHOD(GetGenericParamProps) + ( // S_OK or error. + mdGenericParam gp, // [IN] GenericParam + ULONG *pulParamSeq, // [OUT] Index of the type parameter + DWORD *pdwParamFlags, // [OUT] Flags, for future use (e.g. variance) + mdToken *ptOwner, // [OUT] Owner (TypeDef or MethodDef) + DWORD *reserved, // [OUT] For future use (e.g. non-type parameters) + _Out_writes_to_opt_(cchName, *pchName) + LPWSTR wzname, // [OUT] Put name here + ULONG cchName, // [IN] Size of buffer + ULONG *pchName); // [OUT] Put size of name (wide chars) here. + + STDMETHOD(GetMethodSpecProps) + (mdMethodSpec mi, // [IN] The method instantiation + mdToken *tkParent, // [OUT] MethodDef or MemberRef + PCCOR_SIGNATURE *ppvSigBlob, // [OUT] point to the blob value of meta data + ULONG *pcbSigBlob); // [OUT] actual size of signature blob + + STDMETHOD(EnumGenericParamConstraints) + (HCORENUM *phEnum, // [IN|OUT] Pointer to the enum. + mdGenericParam tk, // [IN] GenericParam whose constraints are requested + mdGenericParamConstraint + rGenericParamConstraints[], // [OUT] Put GenericParamConstraints here. + ULONG cMax, // [IN] Max GenericParamConstraints to put. + ULONG *pcGenericParamConstraints); // [OUT] Put # put here. + + STDMETHOD(GetGenericParamConstraintProps) + ( // S_OK or error. + mdGenericParamConstraint gpc, // [IN] GenericParamConstraint + mdGenericParam *ptGenericParam, // [OUT] GenericParam that is constrained + mdToken *ptkConstraintType); // [OUT] TypeDef/Ref/Spec constraint + + STDMETHOD(GetPEKind) + ( // S_OK or error. + DWORD *pdwPEKind, // [OUT] The kind of PE (0 - not a PE) + DWORD *pdwMAchine); // [OUT] Machine as defined in NT header + + STDMETHOD(GetVersionString) + ( // S_OK or error. + _Out_writes_to_opt_(ccBufSize, *pccBufSize) + LPWSTR pwzBuf, // [OUT] Put version string here. + DWORD ccBufSize, // [IN] size of the buffer, in wide chars + DWORD *pccBufSize); // [OUT] Size of the version string, wide chars, + // including terminating nul. + + STDMETHOD(EnumMethodSpecs) + (HCORENUM *phEnum, // [IN|OUT] Pointer to the enum. + mdToken tk, // [IN] MethodDef or MemberRef whose MethodSpecs are requested + mdMethodSpec rMethodSpecs[], // [OUT] Put MethodSpecs here. + ULONG cMax, // [IN] Max tokens to put. + ULONG *pcMethodSpecs); // [OUT] Put actual count here. + + STDMETHOD(GetAssemblyProps) + ( // S_OK or error. + mdAssembly mda, // [IN] The Assembly for which to get the properties. + const void **ppbPublicKey, // [OUT] Pointer to the public key. + ULONG *pcbPublicKey, // [OUT] Count of bytes in the public key. + ULONG *pulHashAlgId, // [OUT] Hash Algorithm. + _Out_writes_to_opt_(cchName, *pchName) LPWSTR + szName, // [OUT] MdbgProtBuffer to fill with assembly's simply name. + ULONG cchName, // [IN] Size of buffer in wide chars. + ULONG *pchName, // [OUT] Actual # of wide chars in name. + ASSEMBLYMETADATA *pMetaData, // [OUT] Assembly MetaData. + DWORD *pdwAssemblyFlags); // [OUT] Flags. + + STDMETHOD(GetAssemblyRefProps) + ( // S_OK or error. + mdAssemblyRef + mdar, // [IN] The AssemblyRef for which to get the properties. + const void * + *ppbPublicKeyOrToken, // [OUT] Pointer to the public key or token. + ULONG *pcbPublicKeyOrToken, // [OUT] Count of bytes in the public key or + // token. + _Out_writes_to_opt_(cchName, *pchName) + LPWSTR szName, // [OUT] MdbgProtBuffer to fill with name. + ULONG cchName, // [IN] Size of buffer in wide chars. + ULONG *pchName, // [OUT] Actual # of wide chars in name. + ASSEMBLYMETADATA *pMetaData, // [OUT] Assembly MetaData. + const void **ppbHashValue, // [OUT] Hash blob. + ULONG *pcbHashValue, // [OUT] Count of bytes in the hash blob. + DWORD *pdwAssemblyRefFlags); // [OUT] Flags. + + STDMETHOD(GetFileProps) + ( // S_OK or error. + mdFile mdf, // [IN] The File for which to get the properties. + _Out_writes_to_opt_(cchName, *pchName) + LPWSTR szName, // [OUT] MdbgProtBuffer to fill with name. + ULONG cchName, // [IN] Size of buffer in wide chars. + ULONG *pchName, // [OUT] Actual # of wide chars in name. + const void **ppbHashValue, // [OUT] Pointer to the Hash Value Blob. + ULONG *pcbHashValue, // [OUT] Count of bytes in the Hash Value Blob. + DWORD *pdwFileFlags); // [OUT] Flags. + + STDMETHOD(GetExportedTypeProps) + ( // S_OK or error. + mdExportedType + mdct, // [IN] The ExportedType for which to get the properties. + _Out_writes_to_opt_(cchName, *pchName) + LPWSTR szName, // [OUT] MdbgProtBuffer to fill with name. + ULONG cchName, // [IN] Size of buffer in wide chars. + ULONG *pchName, // [OUT] Actual # of wide chars in name. + mdToken * + ptkImplementation, // [OUT] mdFile or mdAssemblyRef or mdExportedType. + mdTypeDef *ptkTypeDef, // [OUT] TypeDef token within the file. + DWORD *pdwExportedTypeFlags); // [OUT] Flags. + + STDMETHOD(GetManifestResourceProps) + ( // S_OK or error. + mdManifestResource + mdmr, // [IN] The ManifestResource for which to get the properties. + _Out_writes_to_opt_(cchName, *pchName) + LPWSTR szName, // [OUT] MdbgProtBuffer to fill with name. + ULONG cchName, // [IN] Size of buffer in wide chars. + ULONG *pchName, // [OUT] Actual # of wide chars in name. + mdToken *ptkImplementation, // [OUT] mdFile or mdAssemblyRef that provides + // the ManifestResource. + DWORD *pdwOffset, // [OUT] Offset to the beginning of the resource within + // the file. + DWORD *pdwResourceFlags); // [OUT] Flags. + + STDMETHOD(EnumAssemblyRefs) + ( // S_OK or error + HCORENUM *phEnum, // [IN|OUT] Pointer to the enum. + mdAssemblyRef rAssemblyRefs[], // [OUT] Put AssemblyRefs here. + ULONG cMax, // [IN] Max AssemblyRefs to put. + ULONG *pcTokens); // [OUT] Put # put here. + + STDMETHOD(EnumFiles) + ( // S_OK or error + HCORENUM *phEnum, // [IN|OUT] Pointer to the enum. + mdFile rFiles[], // [OUT] Put Files here. + ULONG cMax, // [IN] Max Files to put. + ULONG *pcTokens); // [OUT] Put # put here. + + STDMETHOD(EnumExportedTypes) + ( // S_OK or error + HCORENUM *phEnum, // [IN|OUT] Pointer to the enum. + mdExportedType rExportedTypes[], // [OUT] Put ExportedTypes here. + ULONG cMax, // [IN] Max ExportedTypes to put. + ULONG *pcTokens); // [OUT] Put # put here. + + STDMETHOD(EnumManifestResources) + ( // S_OK or error + HCORENUM *phEnum, // [IN|OUT] Pointer to the enum. + mdManifestResource + rManifestResources[], // [OUT] Put ManifestResources here. + ULONG cMax, // [IN] Max Resources to put. + ULONG *pcTokens); // [OUT] Put # put here. + + STDMETHOD(GetAssemblyFromScope) + ( // S_OK or error + mdAssembly *ptkAssembly); + + STDMETHOD(FindExportedTypeByName) + ( // S_OK or error + LPCWSTR szName, // [IN] Name of the ExportedType. + mdToken mdtExportedType, // [IN] ExportedType for the enclosing class. + mdExportedType + *ptkExportedType); // [OUT] Put the ExportedType token here. + + STDMETHOD(FindManifestResourceByName) + ( // S_OK or error + LPCWSTR szName, // [IN] Name of the ManifestResource. + mdManifestResource + *ptkManifestResource); // [OUT] Put the ManifestResource token here. + + STDMETHOD(FindAssembliesByName) + ( // S_OK or error + LPCWSTR szAppBase, // [IN] optional - can be NULL + LPCWSTR szPrivateBin, // [IN] optional - can be NULL + LPCWSTR szAssemblyName, // [IN] required - this is the assembly you are + // requesting + IUnknown *ppIUnk[], // [OUT] put IMetaDataAssemblyImport pointers here + ULONG cMax, // [IN] The max number to put + ULONG *pcAssemblies); // [OUT] The number of assemblies returned. + + // IUnknown methods + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, LPVOID *ppvObj); + + // IMetaDataImport functions + + void CloseEnum(HCORENUM hEnum); + HRESULT STDMETHODCALLTYPE CountEnum(HCORENUM hEnum, ULONG *pulCount); + HRESULT STDMETHODCALLTYPE ResetEnum(HCORENUM hEnum, ULONG ulPos); + HRESULT STDMETHODCALLTYPE EnumTypeDefs(HCORENUM *phEnum, mdTypeDef rTypeDefs[], ULONG cMax, + ULONG *pcTypeDefs); + HRESULT STDMETHODCALLTYPE EnumInterfaceImpls(HCORENUM *phEnum, mdTypeDef td, + mdInterfaceImpl rImpls[], ULONG cMax, + ULONG *pcImpls); + HRESULT STDMETHODCALLTYPE EnumTypeRefs(HCORENUM *phEnum, mdTypeRef rTypeRefs[], ULONG cMax, + ULONG *pcTypeRefs); + + HRESULT STDMETHODCALLTYPE FindTypeDefByName( // S_OK or error. + LPCWSTR szTypeDef, // [IN] Name of the Type. + mdToken tkEnclosingClass, // [IN] TypeDef/TypeRef for Enclosing class. + mdTypeDef *ptd); // [OUT] Put the TypeDef token here. + + HRESULT STDMETHODCALLTYPE GetScopeProps( // S_OK or error. + __out_ecount_part_opt(cchName, *pchName) + LPWSTR szName, // [OUT] Put the name here. + ULONG cchName, // [IN] Size of name buffer in wide chars. + ULONG *pchName, // [OUT] Put size of name (wide chars) here. + GUID *pmvid); // [OUT, OPTIONAL] Put MVID here. + + HRESULT STDMETHODCALLTYPE GetModuleFromScope( // S_OK. + mdModule *pmd); // [OUT] Put mdModule token here. + + HRESULT STDMETHODCALLTYPE GetTypeDefProps( // S_OK or error. + mdTypeDef td, // [IN] TypeDef token for inquiry. + __out_ecount_part_opt(cchTypeDef, *pchTypeDef) + LPWSTR szTypeDef, // [OUT] Put name here. + ULONG cchTypeDef, // [IN] size of name buffer in wide chars. + ULONG *pchTypeDef, // [OUT] put size of name (wide chars) here. + DWORD *pdwTypeDefFlags, // [OUT] Put flags here. + mdToken *ptkExtends); // [OUT] Put base class TypeDef/TypeRef here. + + HRESULT STDMETHODCALLTYPE GetInterfaceImplProps( // S_OK or error. + mdInterfaceImpl iiImpl, // [IN] InterfaceImpl token. + mdTypeDef *pClass, // [OUT] Put implementing class token here. + mdToken *ptkIface); // [OUT] Put implemented interface token here. + + HRESULT STDMETHODCALLTYPE GetTypeRefProps( // S_OK or error. + mdTypeRef tr, // [IN] TypeRef token. + mdToken *ptkResolutionScope, // [OUT] Resolution scope, ModuleRef or + // AssemblyRef. + __out_ecount_part_opt(cchName, *pchName) + LPWSTR szName, // [OUT] Name of the TypeRef. + ULONG cchName, // [IN] Size of buffer. + ULONG *pchName); // [OUT] Size of Name. + + HRESULT STDMETHODCALLTYPE ResolveTypeRef(mdTypeRef tr, REFIID riid, IUnknown **ppIScope, + mdTypeDef *ptd); + + HRESULT STDMETHODCALLTYPE EnumMembers( // S_OK, S_FALSE, or error. + HCORENUM *phEnum, // [IN|OUT] Pointer to the enum. + mdTypeDef cl, // [IN] TypeDef to scope the enumeration. + mdToken rMembers[], // [OUT] Put MemberDefs here. + ULONG cMax, // [IN] Max MemberDefs to put. + ULONG *pcTokens); // [OUT] Put # put here. + + HRESULT STDMETHODCALLTYPE EnumMembersWithName( // S_OK, S_FALSE, or error. + HCORENUM *phEnum, // [IN|OUT] Pointer to the enum. + mdTypeDef cl, // [IN] TypeDef to scope the enumeration. + LPCWSTR szName, // [IN] Limit results to those with this name. + mdToken rMembers[], // [OUT] Put MemberDefs here. + ULONG cMax, // [IN] Max MemberDefs to put. + ULONG *pcTokens); // [OUT] Put # put here. + + HRESULT STDMETHODCALLTYPE EnumMethods( // S_OK, S_FALSE, or error. + HCORENUM *phEnum, // [IN|OUT] Pointer to the enum. + mdTypeDef cl, // [IN] TypeDef to scope the enumeration. + mdMethodDef rMethods[], // [OUT] Put MethodDefs here. + ULONG cMax, // [IN] Max MethodDefs to put. + ULONG *pcTokens); // [OUT] Put # put here. + + HRESULT STDMETHODCALLTYPE EnumMethodsWithName( // S_OK, S_FALSE, or error. + HCORENUM *phEnum, // [IN|OUT] Pointer to the enum. + mdTypeDef cl, // [IN] TypeDef to scope the enumeration. + LPCWSTR szName, // [IN] Limit results to those with this name. + mdMethodDef rMethods[], // [OU] Put MethodDefs here. + ULONG cMax, // [IN] Max MethodDefs to put. + ULONG *pcTokens); // [OUT] Put # put here. + + HRESULT STDMETHODCALLTYPE EnumFields( // S_OK, S_FALSE, or error. + HCORENUM *phEnum, // [IN|OUT] Pointer to the enum. + mdTypeDef cl, // [IN] TypeDef to scope the enumeration. + mdFieldDef rFields[], // [OUT] Put FieldDefs here. + ULONG cMax, // [IN] Max FieldDefs to put. + ULONG *pcTokens); // [OUT] Put # put here. + + HRESULT STDMETHODCALLTYPE EnumFieldsWithName( // S_OK, S_FALSE, or error. + HCORENUM *phEnum, // [IN|OUT] Pointer to the enum. + mdTypeDef cl, // [IN] TypeDef to scope the enumeration. + LPCWSTR szName, // [IN] Limit results to those with this name. + mdFieldDef rFields[], // [OUT] Put MemberDefs here. + ULONG cMax, // [IN] Max MemberDefs to put. + ULONG *pcTokens); // [OUT] Put # put here. + + HRESULT STDMETHODCALLTYPE EnumParams( // S_OK, S_FALSE, or error. + HCORENUM *phEnum, // [IN|OUT] Pointer to the enum. + mdMethodDef mb, // [IN] MethodDef to scope the enumeration. + mdParamDef rParams[], // [OUT] Put ParamDefs here. + ULONG cMax, // [IN] Max ParamDefs to put. + ULONG *pcTokens); // [OUT] Put # put here. + + HRESULT STDMETHODCALLTYPE EnumMemberRefs( // S_OK, S_FALSE, or error. + HCORENUM *phEnum, // [IN|OUT] Pointer to the enum. + mdToken tkParent, // [IN] Parent token to scope the enumeration. + mdMemberRef rMemberRefs[], // [OUT] Put MemberRefs here. + ULONG cMax, // [IN] Max MemberRefs to put. + ULONG *pcTokens); // [OUT] Put # put here. + + HRESULT STDMETHODCALLTYPE EnumMethodImpls( // S_OK, S_FALSE, or error + HCORENUM *phEnum, // [IN|OUT] Pointer to the enum. + mdTypeDef td, // [IN] TypeDef to scope the enumeration. + mdToken rMethodBody[], // [OUT] Put Method Body tokens here. + mdToken rMethodDecl[], // [OUT] Put Method Declaration tokens here. + ULONG cMax, // [IN] Max tokens to put. + ULONG *pcTokens); // [OUT] Put # put here. + + HRESULT STDMETHODCALLTYPE EnumPermissionSets( // S_OK, S_FALSE, or error. + HCORENUM *phEnum, // [IN|OUT] Pointer to the enum. + mdToken tk, // [IN] if !NIL, token to scope the enumeration. + DWORD dwActions, // [IN] if !0, return only these actions. + mdPermission rPermission[], // [OUT] Put Permissions here. + ULONG cMax, // [IN] Max Permissions to put. + ULONG *pcTokens); // [OUT] Put # put here. + + HRESULT STDMETHODCALLTYPE FindMember( + mdTypeDef td, // [IN] given typedef + LPCWSTR szName, // [IN] member name + PCCOR_SIGNATURE pvSigBlob, // [IN] point to a blob value of CLR signature + ULONG cbSigBlob, // [IN] count of bytes in the signature blob + mdToken *pmb); // [OUT] matching memberdef + + HRESULT STDMETHODCALLTYPE FindMethod( + mdTypeDef td, // [IN] given typedef + LPCWSTR szName, // [IN] member name + PCCOR_SIGNATURE pvSigBlob, // [IN] point to a blob value of CLR signature + ULONG cbSigBlob, // [IN] count of bytes in the signature blob + mdMethodDef *pmb); // [OUT] matching memberdef + + HRESULT STDMETHODCALLTYPE FindField( + mdTypeDef td, // [IN] given typedef + LPCWSTR szName, // [IN] member name + PCCOR_SIGNATURE pvSigBlob, // [IN] point to a blob value of CLR signature + ULONG cbSigBlob, // [IN] count of bytes in the signature blob + mdFieldDef *pmb); // [OUT] matching memberdef + + HRESULT STDMETHODCALLTYPE FindMemberRef( + mdTypeRef td, // [IN] given typeRef + LPCWSTR szName, // [IN] member name + PCCOR_SIGNATURE pvSigBlob, // [IN] point to a blob value of CLR signature + ULONG cbSigBlob, // [IN] count of bytes in the signature blob + mdMemberRef *pmr); // [OUT] matching memberref + + HRESULT STDMETHODCALLTYPE GetMethodProps( + mdMethodDef mb, // The method for which to get props. + mdTypeDef *pClass, // Put method's class here. + __out_ecount_part_opt(cchMethod, *pchMethod) + LPWSTR szMethod, // Put method's name here. + ULONG cchMethod, // Size of szMethod buffer in wide chars. + ULONG *pchMethod, // Put actual size here + DWORD *pdwAttr, // Put flags here. + PCCOR_SIGNATURE *ppvSigBlob, // [OUT] point to the blob value of meta data + ULONG *pcbSigBlob, // [OUT] actual size of signature blob + ULONG *pulCodeRVA, // [OUT] codeRVA + DWORD *pdwImplFlags); // [OUT] Impl. Flags + + HRESULT STDMETHODCALLTYPE GetMemberRefProps( // S_OK or error. + mdMemberRef mr, // [IN] given memberref + mdToken *ptk, // [OUT] Put classref or classdef here. + __out_ecount_part_opt(cchMember, *pchMember) + LPWSTR szMember, // [OUT] buffer to fill for member's name + ULONG cchMember, // [IN] the count of char of szMember + ULONG *pchMember, // [OUT] actual count of char in member name + PCCOR_SIGNATURE *ppvSigBlob, // [OUT] point to meta data blob value + ULONG *pbSig); // [OUT] actual size of signature blob + + HRESULT STDMETHODCALLTYPE EnumProperties( // S_OK, S_FALSE, or error. + HCORENUM *phEnum, // [IN|OUT] Pointer to the enum. + mdTypeDef td, // [IN] TypeDef to scope the enumeration. + mdProperty rProperties[], // [OUT] Put Properties here. + ULONG cMax, // [IN] Max properties to put. + ULONG *pcProperties); // [OUT] Put # put here. + + HRESULT STDMETHODCALLTYPE EnumEvents( // S_OK, S_FALSE, or error. + HCORENUM *phEnum, // [IN|OUT] Pointer to the enum. + mdTypeDef td, // [IN] TypeDef to scope the enumeration. + mdEvent rEvents[], // [OUT] Put events here. + ULONG cMax, // [IN] Max events to put. + ULONG *pcEvents); // [OUT] Put # put here. + + HRESULT STDMETHODCALLTYPE GetEventProps( // S_OK, S_FALSE, or error. + mdEvent ev, // [IN] event token + mdTypeDef *pClass, // [OUT] typedef containing the event declarion. + LPCWSTR szEvent, // [OUT] Event name + ULONG cchEvent, // [IN] the count of wchar of szEvent + ULONG *pchEvent, // [OUT] actual count of wchar for event's name + DWORD *pdwEventFlags, // [OUT] Event flags. + mdToken *ptkEventType, // [OUT] EventType class + mdMethodDef *pmdAddOn, // [OUT] AddOn method of the event + mdMethodDef *pmdRemoveOn, // [OUT] RemoveOn method of the event + mdMethodDef *pmdFire, // [OUT] Fire method of the event + mdMethodDef rmdOtherMethod[], // [OUT] other method of the event + ULONG cMax, // [IN] size of rmdOtherMethod + ULONG *pcOtherMethod); // [OUT] total number of other method of this event + + HRESULT STDMETHODCALLTYPE EnumMethodSemantics( // S_OK, S_FALSE, or error. + HCORENUM *phEnum, // [IN|OUT] Pointer to the enum. + mdMethodDef mb, // [IN] MethodDef to scope the enumeration. + mdToken rEventProp[], // [OUT] Put Event/Property here. + ULONG cMax, // [IN] Max properties to put. + ULONG *pcEventProp); // [OUT] Put # put here. + + HRESULT STDMETHODCALLTYPE GetMethodSemantics( // S_OK, S_FALSE, or error. + mdMethodDef mb, // [IN] method token + mdToken tkEventProp, // [IN] event/property token. + DWORD *pdwSemanticsFlags); // [OUT] the role flags for the + // method/propevent pair + + HRESULT + GetClassLayout(mdTypeDef td, // [IN] give typedef + DWORD *pdwPackSize, // [OUT] 1, 2, 4, 8, or 16 + COR_FIELD_OFFSET rFieldOffset[], // [OUT] field offset array + ULONG cMax, // [IN] size of the array + ULONG *pcFieldOffset, // [OUT] needed array size + ULONG *pulClassSize); // [OUT] the size of the class + + HRESULT STDMETHODCALLTYPE GetFieldMarshal( + mdToken tk, // [IN] given a field's memberdef + PCCOR_SIGNATURE *ppvNativeType, // [OUT] native type of this field + ULONG *pcbNativeType); // [OUT] the count of bytes of *ppvNativeType + + HRESULT STDMETHODCALLTYPE GetRVA( // S_OK or error. + mdToken tk, // Member for which to set offset + ULONG *pulCodeRVA, // The offset + DWORD *pdwImplFlags); // the implementation flags + + HRESULT STDMETHODCALLTYPE GetPermissionSetProps( + mdPermission pm, // [IN] the permission token. + DWORD *pdwAction, // [OUT] CorDeclSecurity. + void const **ppvPermission, // [OUT] permission blob. + ULONG *pcbPermission); // [OUT] count of bytes of pvPermission. + + HRESULT STDMETHODCALLTYPE GetSigFromToken( // S_OK or error. + mdSignature mdSig, // [IN] Signature token. + PCCOR_SIGNATURE *ppvSig, // [OUT] return pointer to token. + ULONG *pcbSig); // [OUT] return size of signature. + + HRESULT STDMETHODCALLTYPE GetModuleRefProps( // S_OK or error. + mdModuleRef mur, // [IN] moduleref token. + __out_ecount_part_opt(cchName, *pchName) + LPWSTR szName, // [OUT] buffer to fill with the moduleref name. + ULONG cchName, // [IN] size of szName in wide characters. + ULONG *pchName); // [OUT] actual count of characters in the name. + + HRESULT STDMETHODCALLTYPE EnumModuleRefs( // S_OK or error. + HCORENUM *phEnum, // [IN|OUT] pointer to the enum. + mdModuleRef rModuleRefs[], // [OUT] put modulerefs here. + ULONG cmax, // [IN] max memberrefs to put. + ULONG *pcModuleRefs); // [OUT] put # put here. + + HRESULT STDMETHODCALLTYPE GetTypeSpecFromToken( // S_OK or error. + mdTypeSpec typespec, // [IN] TypeSpec token. + PCCOR_SIGNATURE *ppvSig, // [OUT] return pointer to TypeSpec signature + ULONG *pcbSig); // [OUT] return size of signature. + + HRESULT + GetNameFromToken( // Not Recommended! May be removed! + mdToken tk, // [IN] Token to get name from. Must have a name. + MDUTF8CSTR *pszUtf8NamePtr); // [OUT] Return pointer to UTF8 name in heap. + + HRESULT STDMETHODCALLTYPE EnumUnresolvedMethods( // S_OK, S_FALSE, or error. + HCORENUM *phEnum, // [IN|OUT] Pointer to the enum. + mdToken rMethods[], // [OUT] Put MemberDefs here. + ULONG cMax, // [IN] Max MemberDefs to put. + ULONG *pcTokens); // [OUT] Put # put here. + + HRESULT STDMETHODCALLTYPE GetUserString( // S_OK or error. + mdString stk, // [IN] String token. + __out_ecount_part_opt(cchString, *pchString) + LPWSTR szString, // [OUT] Copy of string. + ULONG cchString, // [IN] Max chars of room in szString. + ULONG *pchString); // [OUT] How many chars in actual string. + + HRESULT STDMETHODCALLTYPE GetPinvokeMap( // S_OK or error. + mdToken tk, // [IN] FieldDef or MethodDef. + DWORD *pdwMappingFlags, // [OUT] Flags used for mapping. + __out_ecount_part_opt(cchImportName, *pchImportName) + LPWSTR szImportName, // [OUT] Import name. + ULONG cchImportName, // [IN] Size of the name buffer. + ULONG *pchImportName, // [OUT] Actual number of characters stored. + mdModuleRef *pmrImportDLL); // [OUT] ModuleRef token for the target DLL. + + HRESULT STDMETHODCALLTYPE EnumSignatures( // S_OK or error. + HCORENUM *phEnum, // [IN|OUT] pointer to the enum. + mdSignature rSignatures[], // [OUT] put signatures here. + ULONG cmax, // [IN] max signatures to put. + ULONG *pcSignatures); // [OUT] put # put here. + + HRESULT STDMETHODCALLTYPE EnumTypeSpecs( // S_OK or error. + HCORENUM *phEnum, // [IN|OUT] pointer to the enum. + mdTypeSpec rTypeSpecs[], // [OUT] put TypeSpecs here. + ULONG cmax, // [IN] max TypeSpecs to put. + ULONG *pcTypeSpecs); // [OUT] put # put here. + + HRESULT STDMETHODCALLTYPE EnumUserStrings( // S_OK or error. + HCORENUM *phEnum, // [IN/OUT] pointer to the enum. + mdString rStrings[], // [OUT] put Strings here. + ULONG cmax, // [IN] max Strings to put. + ULONG *pcStrings); // [OUT] put # put here. + + HRESULT STDMETHODCALLTYPE GetParamForMethodIndex( // S_OK or error. + mdMethodDef md, // [IN] Method token. + ULONG ulParamSeq, // [IN] Parameter sequence. + mdParamDef *ppd); // [IN] Put Param token here. + + HRESULT STDMETHODCALLTYPE EnumCustomAttributes( // S_OK or error. + HCORENUM *phEnum, // [IN, OUT] COR enumerator. + mdToken tk, // [IN] Token to scope the enumeration, 0 for all. + mdToken tkType, // [IN] Type of interest, 0 for all. + mdCustomAttribute + rCustomAttributes[], // [OUT] Put custom attribute tokens here. + ULONG cMax, // [IN] Size of rCustomAttributes. + ULONG *pcCustomAttributes); // [OUT, OPTIONAL] Put count of token values + // here. + + HRESULT STDMETHODCALLTYPE GetCustomAttributeProps( // S_OK or error. + mdCustomAttribute cv, // [IN] CustomAttribute token. + mdToken *ptkObj, // [OUT, OPTIONAL] Put object token here. + mdToken *ptkType, // [OUT, OPTIONAL] Put AttrType token here. + void const **ppBlob, // [OUT, OPTIONAL] Put pointer to data here. + ULONG *pcbSize); // [OUT, OPTIONAL] Put size of date here. + + HRESULT STDMETHODCALLTYPE FindTypeRef( + mdToken tkResolutionScope, // [IN] ModuleRef, AssemblyRef or TypeRef. + LPCWSTR szName, // [IN] TypeRef Name. + mdTypeRef *ptr); // [OUT] matching TypeRef. + + HRESULT STDMETHODCALLTYPE GetMemberProps( + mdToken mb, // The member for which to get props. + mdTypeDef *pClass, // Put member's class here. + __out_ecount_part_opt(cchMember, *pchMember) + LPWSTR szMember, // Put member's name here. + ULONG cchMember, // Size of szMember buffer in wide chars. + ULONG *pchMember, // Put actual size here + DWORD *pdwAttr, // Put flags here. + PCCOR_SIGNATURE *ppvSigBlob, // [OUT] point to the blob value of meta data + ULONG *pcbSigBlob, // [OUT] actual size of signature blob + ULONG *pulCodeRVA, // [OUT] codeRVA + DWORD *pdwImplFlags, // [OUT] Impl. Flags + DWORD *pdwCPlusTypeFlag, // [OUT] flag for value type. selected + // ELEMENT_TYPE_* + UVCP_CONSTANT *ppValue, // [OUT] constant value + ULONG *pcchValue); // [OUT] size of constant string in chars, 0 for + // non-strings. + + HRESULT STDMETHODCALLTYPE GetFieldProps( + mdFieldDef mb, // The field for which to get props. + mdTypeDef *pClass, // Put field's class here. + __out_ecount_part_opt(cchField, *pchField) + LPWSTR szField, // Put field's name here. + ULONG cchField, // Size of szField buffer in wide chars. + ULONG *pchField, // Put actual size here + DWORD *pdwAttr, // Put flags here. + PCCOR_SIGNATURE *ppvSigBlob, // [OUT] point to the blob value of meta data + ULONG *pcbSigBlob, // [OUT] actual size of signature blob + DWORD *pdwCPlusTypeFlag, // [OUT] flag for value type. selected + // ELEMENT_TYPE_* + UVCP_CONSTANT *ppValue, // [OUT] constant value + ULONG *pcchValue); // [OUT] size of constant string in chars, 0 for + // non-strings. + + HRESULT STDMETHODCALLTYPE GetPropertyProps( // S_OK, S_FALSE, or error. + mdProperty prop, // [IN] property token + mdTypeDef *pClass, // [OUT] typedef containing the property declarion. + LPCWSTR szProperty, // [OUT] Property name + ULONG cchProperty, // [IN] the count of wchar of szProperty + ULONG *pchProperty, // [OUT] actual count of wchar for property name + DWORD *pdwPropFlags, // [OUT] property flags. + PCCOR_SIGNATURE + *ppvSig, // [OUT] property type. pointing to meta data internal blob + ULONG *pbSig, // [OUT] count of bytes in *ppvSig + DWORD *pdwCPlusTypeFlag, // [OUT] flag for value type. selected + // ELEMENT_TYPE_* + UVCP_CONSTANT *ppDefaultValue, // [OUT] constant value + ULONG *pcchDefaultValue, // [OUT] size of constant string in chars, 0 for + // non-strings. + mdMethodDef *pmdSetter, // [OUT] setter method of the property + mdMethodDef *pmdGetter, // [OUT] getter method of the property + mdMethodDef rmdOtherMethod[], // [OUT] other method of the property + ULONG cMax, // [IN] size of rmdOtherMethod + ULONG * + pcOtherMethod); // [OUT] total number of other method of this property + + HRESULT STDMETHODCALLTYPE GetParamProps( // S_OK or error. + mdParamDef tk, // [IN]The Parameter. + mdMethodDef *pmd, // [OUT] Parent Method token. + ULONG *pulSequence, // [OUT] Parameter sequence. + __out_ecount_part_opt(cchName, *pchName) + LPWSTR szName, // [OUT] Put name here. + ULONG cchName, // [OUT] Size of name buffer. + ULONG *pchName, // [OUT] Put actual size of name here. + DWORD *pdwAttr, // [OUT] Put flags here. + DWORD *pdwCPlusTypeFlag, // [OUT] Flag for value type. selected + // ELEMENT_TYPE_*. + UVCP_CONSTANT *ppValue, // [OUT] Constant value. + ULONG *pcchValue); // [OUT] size of constant string in chars, 0 for + // non-strings. + + HRESULT STDMETHODCALLTYPE GetCustomAttributeByName( // S_OK or error. + mdToken tkObj, // [IN] Object with Custom Attribute. + LPCWSTR szName, // [IN] Name of desired Custom Attribute. + const void **ppData, // [OUT] Put pointer to data here. + ULONG *pcbData); // [OUT] Put size of data here. + + BOOL IsValidToken( // True or False. + mdToken tk); // [IN] Given token. + + HRESULT STDMETHODCALLTYPE GetNestedClassProps( // S_OK or error. + mdTypeDef tdNestedClass, // [IN] NestedClass token. + mdTypeDef *ptdEnclosingClass); // [OUT] EnclosingClass token. + + HRESULT STDMETHODCALLTYPE GetNativeCallConvFromSig( // S_OK or error. + void const *pvSig, // [IN] Pointer to signature. + ULONG cbSig, // [IN] Count of signature bytes. + ULONG *pCallConv); // [OUT] Put calling conv here (see CorPinvokemap). + + HRESULT STDMETHODCALLTYPE IsGlobal( // S_OK or error. + mdToken pd, // [IN] Type, Field, or Method token. + int *pbGlobal); // [OUT] Put 1 if global, 0 otherwise. +}; + +#endif diff --git a/src/mono/dbi/cordb-thread.cpp b/src/mono/dbi/cordb-thread.cpp new file mode 100644 index 0000000000000..d7eccbbc3978f --- /dev/null +++ b/src/mono/dbi/cordb-thread.cpp @@ -0,0 +1,299 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: CORDB-THREAD.CPP +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +CordbThread::CordbThread(Connection* conn, CordbProcess* ppProcess, long thread_id) : CordbBaseMono(conn) +{ + this->m_pProcess = ppProcess; + this->m_threadId = thread_id; + m_pRegisterSet = NULL; + m_pCurrentFrame = NULL; + m_pBlockingObject = NULL; + ppProcess->AddThread(this); +} + +CordbThread::~CordbThread() +{ + if (m_pCurrentFrame) + m_pCurrentFrame->InternalRelease(); + if (m_pBlockingObject) + m_pBlockingObject->InternalRelease(); + if (m_pRegisterSet) + m_pRegisterSet->InternalRelease(); +} + +void CordbThread::SetRegisterSet(CordbRegisterSet* rs) +{ + if (m_pRegisterSet != NULL) + m_pRegisterSet->InternalRelease(); + m_pRegisterSet = rs; + m_pRegisterSet->InternalAddRef(); +} + +HRESULT STDMETHODCALLTYPE CordbThread::HasUnhandledException(void) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbThread - HasUnhandledException - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbThread::GetBlockingObjects(ICorDebugBlockingObjectEnum** ppBlockingObjectEnum) +{ + LOG((LF_CORDB, LL_INFO1000000, "CordbThread - GetBlockingObjects - IMPLEMENTED\n")); + if (m_pBlockingObject == NULL) + { + m_pBlockingObject = new CordbBlockingObjectEnum(conn); + m_pBlockingObject->InternalAddRef(); + } + m_pBlockingObject->QueryInterface(IID_ICorDebugBlockingObjectEnum, (void**)ppBlockingObjectEnum); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbThread::GetCurrentCustomDebuggerNotification(ICorDebugValue** ppNotificationObject) +{ + LOG((LF_CORDB, LL_INFO100000, + "CordbThread - GetCurrentCustomDebuggerNotification - NOT " + "IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbThread::CreateStackWalk(ICorDebugStackWalk** ppStackWalk) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbThread - CreateStackWalk - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbThread::GetActiveInternalFrames(ULONG32 cInternalFrames, + ULONG32* pcInternalFrames, + ICorDebugInternalFrame2* ppInternalFrames[]) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbThread - GetActiveInternalFrames - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbThread::GetActiveFunctions(ULONG32 cFunctions, + ULONG32* pcFunctions, + COR_ACTIVE_FUNCTION pFunctions[]) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbThread - GetActiveFunctions - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbThread::GetConnectionID(CONNID* pdwConnectionId) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbThread - GetConnectionID - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbThread::GetTaskID(TASKID* pTaskId) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbThread - GetTaskID - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbThread::GetVolatileOSThreadID(DWORD* pdwTid) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbThread - GetVolatileOSThreadID - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbThread::InterceptCurrentException( + + ICorDebugFrame* pFrame) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbThread - InterceptCurrentException - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbThread::GetProcess(ICorDebugProcess** ppProcess) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbThread - GetProcess - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbThread::GetID(DWORD* pdwThreadId) +{ + *pdwThreadId = GetThreadId(); + LOG((LF_CORDB, LL_INFO1000000, "CordbThread - GetID - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbThread::GetHandle(HTHREAD* phThreadHandle) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbThread - GetHandle - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbThread::GetAppDomain(ICorDebugAppDomain** ppAppDomain) +{ + conn->GetCurrentAppDomain()->QueryInterface(IID_ICorDebugAppDomain, (void**)ppAppDomain); + LOG((LF_CORDB, LL_INFO1000000, "CordbThread - GetAppDomain - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbThread::SetDebugState(CorDebugThreadState state) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbThread - SetDebugState - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbThread::GetDebugState(CorDebugThreadState* pState) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbThread - GetDebugState - NOT IMPLEMENTED\n")); + *pState = THREAD_RUN; + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbThread::GetUserState(CorDebugUserState* pState) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbThread - GetUserState - NOT IMPLEMENTED\n")); + + *pState = (CorDebugUserState)0; + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbThread::GetCurrentException(ICorDebugValue** ppExceptionObject) +{ + LOG((LF_CORDB, LL_INFO1000000, "CordbThread - GetCurrentException - IMPLEMENTED\n")); + + return S_FALSE; +} + +HRESULT STDMETHODCALLTYPE CordbThread::ClearCurrentException(void) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbThread - ClearCurrentException - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbThread::CreateStepper(ICorDebugStepper** ppStepper) +{ + m_pStepper = new CordbStepper(conn, this); + m_pStepper->InternalAddRef(); + m_pStepper->QueryInterface(IID_ICorDebugStepper, (void**)ppStepper); + + LOG((LF_CORDB, LL_INFO1000000, "CordbThread - CreateStepper - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbThread::EnumerateChains(ICorDebugChainEnum** ppChains) +{ + CordbChainEnum* pChains = new CordbChainEnum(conn, this); + pChains->AddRef(); + *ppChains = static_cast(pChains); + LOG((LF_CORDB, LL_INFO1000000, "CordbThread - EnumerateChains - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbThread::GetActiveChain(ICorDebugChain** ppChain) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbThread - GetActiveChain - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbThread::GetActiveFrame(ICorDebugFrame** ppFrame) +{ + LOG((LF_CORDB, LL_INFO1000000, "CordbThread - GetActiveFrame - IMPLEMENTED\n")); + HRESULT hr = S_OK; + EX_TRY + { + MdbgProtBuffer localbuf; + m_dbgprot_buffer_init(&localbuf, 128); + m_dbgprot_buffer_add_id(&localbuf, GetThreadId()); + m_dbgprot_buffer_add_int(&localbuf, 0); + m_dbgprot_buffer_add_int(&localbuf, -1); + + int cmdId = this->conn->SendEvent(MDBGPROT_CMD_SET_THREAD, MDBGPROT_CMD_THREAD_GET_FRAME_INFO, &localbuf); + m_dbgprot_buffer_free(&localbuf); + + ReceivedReplyPacket* received_reply_packet = conn->GetReplyWithError(cmdId); + CHECK_ERROR_RETURN_FALSE(received_reply_packet); + MdbgProtBuffer* pReply = received_reply_packet->Buffer(); + + int nframes = m_dbgprot_decode_int(pReply->p, &pReply->p, pReply->end); + if (nframes > 0) + { + int frameid = m_dbgprot_decode_int(pReply->p, &pReply->p, pReply->end); + int methodId = m_dbgprot_decode_id(pReply->p, &pReply->p, pReply->end); + int il_offset = m_dbgprot_decode_int(pReply->p, &pReply->p, pReply->end); + int flags = m_dbgprot_decode_byte(pReply->p, &pReply->p, pReply->end); + if (m_pCurrentFrame) + m_pCurrentFrame->InternalRelease(); + m_pCurrentFrame = new CordbNativeFrame(conn, frameid, methodId, il_offset, flags, this); + m_pCurrentFrame->InternalAddRef(); + m_pCurrentFrame->QueryInterface(IID_ICorDebugFrame, (void**)ppFrame); + } + SetRegisterSet(new CordbRegisterSet(conn, 0, 0)); + } + EX_CATCH_HRESULT(hr); + return hr; +} + +HRESULT STDMETHODCALLTYPE CordbThread::GetRegisterSet(ICorDebugRegisterSet** ppRegisters) +{ + LOG((LF_CORDB, LL_INFO1000000, "CordbThread - GetRegisterSet - IMPLEMENTED\n")); + + if (!m_pRegisterSet) + SetRegisterSet(new CordbRegisterSet(conn, 0, 0)); + m_pRegisterSet->AddRef(); + *ppRegisters = static_cast(m_pRegisterSet); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbThread::CreateEval(ICorDebugEval** ppEval) +{ + LOG((LF_CORDB, LL_INFO1000000, "CordbThread - CreateEval - IMPLEMENTED\n")); + CordbEval* eval = new CordbEval(this->conn, this); + eval->QueryInterface(IID_ICorDebugEval, (void**)ppEval); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbThread::GetObject(ICorDebugValue** ppObject) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbThread - GetObject - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbThread::QueryInterface(REFIID id, _COM_Outptr_ void __RPC_FAR* __RPC_FAR* ppInterface) +{ + if (id == IID_ICorDebugThread) + { + *ppInterface = static_cast(this); + } + else if (id == IID_ICorDebugThread2) + { + *ppInterface = static_cast(this); + } + else if (id == IID_ICorDebugThread3) + { + *ppInterface = static_cast(this); + } + else if (id == IID_ICorDebugThread4) + { + *ppInterface = static_cast(this); + } + else if (id == IID_IUnknown) + { + *ppInterface = static_cast(static_cast(this)); + } + else + { + *ppInterface = NULL; + return E_NOINTERFACE; + } + AddRef(); + return S_OK; +} diff --git a/src/mono/dbi/cordb-thread.h b/src/mono/dbi/cordb-thread.h new file mode 100644 index 0000000000000..cb133ddc29b95 --- /dev/null +++ b/src/mono/dbi/cordb-thread.h @@ -0,0 +1,77 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: CORDB-THREAD.H +// + +#ifndef __MONO_DEBUGGER_CORDB_THREAD_H__ +#define __MONO_DEBUGGER_CORDB_THREAD_H__ + +#include + +class CordbThread : public CordbBaseMono, + public ICorDebugThread, + public ICorDebugThread2, + public ICorDebugThread3, + public ICorDebugThread4 +{ + long m_threadId; + CordbProcess* m_pProcess; + CordbStepper* m_pStepper; + CordbRegisterSet* m_pRegisterSet; + CordbNativeFrame* m_pCurrentFrame; + CordbBlockingObjectEnum* m_pBlockingObject; + +public: + CordbThread(Connection* conn, CordbProcess* ppProcess, long thread_id); + ULONG STDMETHODCALLTYPE AddRef(void) + { + return (BaseAddRef()); + } + ULONG STDMETHODCALLTYPE Release(void) + { + return (BaseRelease()); + } + const char* GetClassName() + { + return "CordbThread"; + } + ~CordbThread(); + void SetRegisterSet(CordbRegisterSet* rs); + HRESULT STDMETHODCALLTYPE HasUnhandledException(void); + HRESULT STDMETHODCALLTYPE GetBlockingObjects(ICorDebugBlockingObjectEnum** ppBlockingObjectEnum); + HRESULT STDMETHODCALLTYPE GetCurrentCustomDebuggerNotification(ICorDebugValue** ppNotificationObject); + HRESULT STDMETHODCALLTYPE CreateStackWalk(ICorDebugStackWalk** ppStackWalk); + HRESULT STDMETHODCALLTYPE GetActiveInternalFrames(ULONG32 cInternalFrames, + ULONG32* pcInternalFrames, + ICorDebugInternalFrame2* ppInternalFrames[]); + HRESULT STDMETHODCALLTYPE GetActiveFunctions(ULONG32 cFunctions, ULONG32* pcFunctions, COR_ACTIVE_FUNCTION pFunctions[]); + HRESULT STDMETHODCALLTYPE GetConnectionID(CONNID* pdwConnectionId); + HRESULT STDMETHODCALLTYPE GetTaskID(TASKID* pTaskId); + HRESULT STDMETHODCALLTYPE GetVolatileOSThreadID(DWORD* pdwTid); + HRESULT STDMETHODCALLTYPE InterceptCurrentException(ICorDebugFrame* pFrame); + HRESULT STDMETHODCALLTYPE GetProcess(ICorDebugProcess** ppProcess); + HRESULT STDMETHODCALLTYPE GetID(DWORD* pdwThreadId); + HRESULT STDMETHODCALLTYPE GetHandle(HTHREAD* phThreadHandle); + HRESULT STDMETHODCALLTYPE GetAppDomain(ICorDebugAppDomain** ppAppDomain); + HRESULT STDMETHODCALLTYPE SetDebugState(CorDebugThreadState state); + HRESULT STDMETHODCALLTYPE GetDebugState(CorDebugThreadState* pState); + HRESULT STDMETHODCALLTYPE GetUserState(CorDebugUserState* pState); + HRESULT STDMETHODCALLTYPE GetCurrentException(ICorDebugValue** ppExceptionObject); + HRESULT STDMETHODCALLTYPE ClearCurrentException(void); + HRESULT STDMETHODCALLTYPE CreateStepper(ICorDebugStepper** ppStepper); + HRESULT STDMETHODCALLTYPE EnumerateChains(ICorDebugChainEnum** ppChains); + HRESULT STDMETHODCALLTYPE GetActiveChain(ICorDebugChain** ppChain); + HRESULT STDMETHODCALLTYPE GetActiveFrame(ICorDebugFrame** ppFrame); + HRESULT STDMETHODCALLTYPE GetRegisterSet(ICorDebugRegisterSet** ppRegisters); + HRESULT STDMETHODCALLTYPE CreateEval(ICorDebugEval** ppEval); + HRESULT STDMETHODCALLTYPE GetObject(ICorDebugValue** ppObject); + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID id, _COM_Outptr_ void __RPC_FAR* __RPC_FAR* pInterface); + + long GetThreadId() const + { + return m_threadId; + } +}; + +#endif diff --git a/src/mono/dbi/cordb-type.cpp b/src/mono/dbi/cordb-type.cpp new file mode 100644 index 0000000000000..c0f1744494a80 --- /dev/null +++ b/src/mono/dbi/cordb-type.cpp @@ -0,0 +1,184 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: CORDB-TYPE.CPP +// + +#include +#include +#include +#include + +using namespace std; + +CordbType::CordbType(CorElementType type, Connection* conn, CordbClass* klass, CordbType* typeParameter) + : CordbBaseMono(conn) +{ + this->m_pClass = klass; + this->m_type = type; + this->m_pTypeParameter = typeParameter; + m_pTypeEnum = NULL; + if (typeParameter) + typeParameter->InternalAddRef(); + if (klass) + klass->InternalAddRef(); +} + +CordbType::~CordbType() +{ + if (m_pClass) + m_pClass->InternalRelease(); + if (m_pTypeParameter) + m_pTypeParameter->InternalRelease(); + if (m_pTypeEnum) + m_pTypeEnum->InternalRelease(); +} + +HRESULT STDMETHODCALLTYPE CordbType::GetType(CorElementType* ty) +{ + *ty = m_type; + LOG((LF_CORDB, LL_INFO1000000, "CordbType - GetType - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbType::GetClass(ICorDebugClass** ppClass) +{ + LOG((LF_CORDB, LL_INFO1000000, "CordbType - GetClass - IMPLEMENTED\n")); + if (!m_pClass) + { + LOG((LF_CORDB, LL_INFO100000, "CordbType - GetClass - NO CLASS\n")); + return S_OK; + } + m_pClass->QueryInterface(IID_ICorDebugClass, (void**)ppClass); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbType::EnumerateTypeParameters(ICorDebugTypeEnum** ppTyParEnum) +{ + if (m_pTypeEnum == NULL) + { + m_pTypeEnum = new CordbTypeEnum(conn, m_pTypeParameter); + m_pTypeEnum->InternalAddRef(); + } + m_pTypeEnum->QueryInterface(IID_ICorDebugTypeEnum, (void**)ppTyParEnum); + + LOG((LF_CORDB, LL_INFO1000000, "CordbType - EnumerateTypeParameters - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbType::GetFirstTypeParameter(ICorDebugType** value) +{ + LOG((LF_CORDB, LL_INFO1000000, "CordbType - GetFirstTypeParameter - IMPLEMENTED\n")); + m_pTypeParameter->QueryInterface(IID_ICorDebugType, (void**)value); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbType::GetBase(ICorDebugType** pBase) +{ + LOG((LF_CORDB, LL_INFO1000000, "CordbType - GetBase - IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbType::GetStaticFieldValue(mdFieldDef fieldDef, + ICorDebugFrame* pFrame, + ICorDebugValue** ppValue) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbType - GetStaticFieldValue - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbType::GetRank(ULONG32* pnRank) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbType - GetRank - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbType::QueryInterface(REFIID id, void** pInterface) +{ + if (id == IID_ICorDebugType) + *pInterface = static_cast(this); + else if (id == IID_ICorDebugType2) + *pInterface = static_cast(this); + else if (id == IID_IUnknown) + *pInterface = static_cast(static_cast(this)); + else + { + *pInterface = NULL; + return E_NOINTERFACE; + } + AddRef(); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbType::GetTypeID(COR_TYPEID* id) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbType - GetTypeID - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +CordbTypeEnum::CordbTypeEnum(Connection* conn, CordbType* type) : CordbBaseMono(conn) +{ + this->m_pType = type; + if (type) + type->InternalAddRef(); +} + +CordbTypeEnum::~CordbTypeEnum() +{ + if (m_pType) + m_pType->InternalRelease(); +} + +HRESULT STDMETHODCALLTYPE CordbTypeEnum::Next(ULONG celt, ICorDebugType* values[], ULONG* pceltFetched) +{ + *pceltFetched = celt; + if (m_pType != NULL) + m_pType->QueryInterface(IID_ICorDebugType, (void**)&values[0]); + LOG((LF_CORDB, LL_INFO1000000, "CordbTypeEnum - Next - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbTypeEnum::Skip(ULONG celt) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbTypeEnum - Skip - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbTypeEnum::Reset(void) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbTypeEnum - Reset - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbTypeEnum::Clone(ICorDebugEnum** ppEnum) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbTypeEnum - Clone - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbTypeEnum::GetCount(ULONG* pcelt) +{ + if (m_pType != NULL) + *pcelt = 1; + else + *pcelt = 0; + LOG((LF_CORDB, LL_INFO1000000, "CordbTypeEnum - GetCount - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbTypeEnum::QueryInterface(REFIID id, void** pInterface) +{ + if (id == IID_ICorDebugEnum) + *pInterface = static_cast(this); + else if (id == IID_ICorDebugTypeEnum) + *pInterface = static_cast(this); + else if (id == IID_IUnknown) + *pInterface = static_cast(static_cast(this)); + else + { + *pInterface = NULL; + return E_NOINTERFACE; + } + AddRef(); + return S_OK; +} diff --git a/src/mono/dbi/cordb-type.h b/src/mono/dbi/cordb-type.h new file mode 100644 index 0000000000000..a2601b237c93e --- /dev/null +++ b/src/mono/dbi/cordb-type.h @@ -0,0 +1,73 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: CORDB-TYPE.H +// + +#ifndef __MONO_DEBUGGER_CORDB_TYPE_H__ +#define __MONO_DEBUGGER_CORDB_TYPE_H__ + +#include + +class CordbType : public CordbBaseMono, public ICorDebugType, public ICorDebugType2 +{ + CorElementType m_type; + CordbClass* m_pClass; + CordbType* m_pTypeParameter; + CordbTypeEnum* m_pTypeEnum; + +public: + CordbType(CorElementType type, Connection* conn, CordbClass* klass = NULL, CordbType* typeParameter = NULL); + ULONG STDMETHODCALLTYPE AddRef(void) + { + return (BaseAddRef()); + } + ULONG STDMETHODCALLTYPE Release(void) + { + return (BaseRelease()); + } + const char* GetClassName() + { + return "CordbType"; + } + ~CordbType(); + HRESULT STDMETHODCALLTYPE GetType(CorElementType* ty); + HRESULT STDMETHODCALLTYPE GetClass(ICorDebugClass** ppClass); + HRESULT STDMETHODCALLTYPE EnumerateTypeParameters(ICorDebugTypeEnum** ppTyParEnum); + HRESULT STDMETHODCALLTYPE GetFirstTypeParameter(ICorDebugType** value); + HRESULT STDMETHODCALLTYPE GetBase(ICorDebugType** pBase); + HRESULT STDMETHODCALLTYPE GetStaticFieldValue(mdFieldDef fieldDef, ICorDebugFrame* pFrame, ICorDebugValue** ppValue); + HRESULT STDMETHODCALLTYPE GetRank(ULONG32* pnRank); + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject); + + HRESULT STDMETHODCALLTYPE GetTypeID(COR_TYPEID* id); +}; + +class CordbTypeEnum : public CordbBaseMono, public ICorDebugTypeEnum +{ + CordbType* m_pType; + +public: + CordbTypeEnum(Connection* conn, CordbType* type); + ULONG STDMETHODCALLTYPE AddRef(void) + { + return (BaseAddRef()); + } + ULONG STDMETHODCALLTYPE Release(void) + { + return (BaseRelease()); + } + const char* GetClassName() + { + return "CordbTypeEnum"; + } + ~CordbTypeEnum(); + virtual HRESULT STDMETHODCALLTYPE Next(ULONG celt, ICorDebugType* values[], ULONG* pceltFetched); + HRESULT STDMETHODCALLTYPE Skip(ULONG celt); + HRESULT STDMETHODCALLTYPE Reset(void); + HRESULT STDMETHODCALLTYPE Clone(ICorDebugEnum** ppEnum); + HRESULT STDMETHODCALLTYPE GetCount(ULONG* pcelt); + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject); +}; + +#endif diff --git a/src/mono/dbi/cordb-value.cpp b/src/mono/dbi/cordb-value.cpp new file mode 100644 index 0000000000000..55943e53d1c71 --- /dev/null +++ b/src/mono/dbi/cordb-value.cpp @@ -0,0 +1,1215 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: CORDB-VALUE.CPP +// + +#include +#include +#include +#include +#include +#include + +using namespace std; + +CordbValue::CordbValue(Connection* conn, CorElementType type, CordbContent value, int size) : CordbBaseMono(conn) +{ + this->m_type = type; + this->m_value = value; + this->m_size = size; + this->conn = conn; + m_pType = NULL; +} + +CordbValue::~CordbValue() +{ + if (m_pType) + m_pType->InternalRelease(); +} + +HRESULT STDMETHODCALLTYPE CordbValue::GetType(CorElementType* pType) +{ + *pType = m_type; + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbValue::GetSize(ULONG32* pSize) +{ + *pSize = m_size; + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbValue::GetAddress(CORDB_ADDRESS* pAddress) +{ + *pAddress = (CORDB_ADDRESS)m_value.pointerValue; + LOG((LF_CORDB, LL_INFO1000000, "CordbValue - GetAddress - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbValue::CreateBreakpoint(ICorDebugValueBreakpoint** ppBreakpoint) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbValue - CreateBreakpoint - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbValue::QueryInterface(REFIID id, void** pInterface) +{ + if (id == IID_ICorDebugValue) + { + *pInterface = static_cast(static_cast(this)); + } + else if (id == IID_ICorDebugValue2) + { + *pInterface = static_cast(this); + } + else if (id == IID_ICorDebugValue3) + { + *pInterface = static_cast(this); + } + else if (id == IID_ICorDebugGenericValue) + { + *pInterface = static_cast(this); + } + else if (id == IID_IUnknown) + { + *pInterface = static_cast(static_cast(this)); + } + else + { + *pInterface = NULL; + return E_NOINTERFACE; + } + AddRef(); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbValue::GetExactType(ICorDebugType** ppType) +{ + LOG((LF_CORDB, LL_INFO1000000, "CordbValue - GetExactType - IMPLEMENTED\n")); + if (m_pType == NULL) + { + m_pType = conn->GetProcess()->FindOrAddPrimitiveType(m_type); + m_pType->InternalAddRef(); + } + m_pType->QueryInterface(IID_ICorDebugType, (void**)ppType); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbValue::GetSize64(ULONG64* pSize) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbValue - GetSize64 - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbValue::GetValue(void* pTo) +{ + LOG((LF_CORDB, LL_INFO1000000, "CordbValue - GetValue - IMPLEMENTED\n")); + memcpy(pTo, &m_value, m_size); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbValue::SetValue(void* pFrom) +{ + memcpy(&m_value, pFrom, m_size); + LOG((LF_CORDB, LL_INFO1000000, "CordbValue - SetValue - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbReferenceValue::GetType(CorElementType* pType) +{ + LOG((LF_CORDB, LL_INFO1000000, "CordbReferenceValue - GetType - IMPLEMENTED\n")); + *pType = m_type; + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbReferenceValue::GetSize(ULONG32* pSize) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbReferenceValue - GetSize - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbReferenceValue::GetAddress(CORDB_ADDRESS* pAddress) +{ + *pAddress = (CORDB_ADDRESS)m_pAddress; + LOG((LF_CORDB, LL_INFO1000000, "CordbReferenceValue - GetAddress - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbReferenceValue::CreateBreakpoint(ICorDebugValueBreakpoint** ppBreakpoint) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbReferenceValue - CreateBreakpoint - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbReferenceValue::QueryInterface(REFIID id, void** pInterface) +{ + if (id == IID_ICorDebugValue) + { + *pInterface = static_cast(static_cast(this)); + } + else if (id == IID_ICorDebugValue2) + { + *pInterface = static_cast(this); + } + else if (id == IID_ICorDebugValue3) + { + *pInterface = static_cast(this); + } + else if (id == IID_ICorDebugReferenceValue) + { + *pInterface = static_cast(this); + } + else if (id == IID_IUnknown) + { + *pInterface = static_cast(static_cast(this)); + } + else + { + *pInterface = NULL; + return E_NOINTERFACE; + } + AddRef(); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbReferenceValue::GetExactType(ICorDebugType** ppType) +{ + LOG((LF_CORDB, LL_INFO1000000, "CordbReferenceValue - GetExactType - IMPLEMENTED\n")); + HRESULT hr = S_OK; + EX_TRY + { + if (m_pCordbType) + { + m_pCordbType->QueryInterface(IID_ICorDebugType, (void**)ppType); + goto __Exit; + } + if (m_pClass != NULL) + { + m_pCordbType = conn->GetProcess()->FindOrAddClassType(m_type, m_pClass); + m_pCordbType->InternalAddRef(); + m_pCordbType->QueryInterface(IID_ICorDebugType, (void**)ppType); + goto __Exit; + } + if (m_type == ELEMENT_TYPE_CLASS && m_debuggerId != -1) + { + MdbgProtBuffer localbuf; + m_dbgprot_buffer_init(&localbuf, 128); + m_dbgprot_buffer_add_id(&localbuf, m_debuggerId); + + int cmdId = conn->SendEvent(MDBGPROT_CMD_SET_OBJECT_REF, MDBGPROT_CMD_OBJECT_REF_GET_TYPE, &localbuf); + m_dbgprot_buffer_free(&localbuf); + + ReceivedReplyPacket* received_reply_packet = conn->GetReplyWithError(cmdId); + CHECK_ERROR_RETURN_FALSE(received_reply_packet); + MdbgProtBuffer* pReply = received_reply_packet->Buffer(); + + int type_id = m_dbgprot_decode_int(pReply->p, &pReply->p, pReply->end); + + m_dbgprot_buffer_init(&localbuf, 128); + m_dbgprot_buffer_add_id(&localbuf, type_id); + + cmdId = conn->SendEvent(MDBGPROT_CMD_SET_TYPE, MDBGPROT_CMD_TYPE_GET_INFO, &localbuf); + m_dbgprot_buffer_free(&localbuf); + + received_reply_packet = conn->GetReplyWithError(cmdId); + CHECK_ERROR_RETURN_FALSE(received_reply_packet); + pReply = received_reply_packet->Buffer(); + + char* namespace_str = m_dbgprot_decode_string(pReply->p, &pReply->p, pReply->end); + char* class_name_str = m_dbgprot_decode_string(pReply->p, &pReply->p, pReply->end); + char* class_fullname_str = m_dbgprot_decode_string(pReply->p, &pReply->p, pReply->end); + int assembly_id = m_dbgprot_decode_id(pReply->p, &pReply->p, pReply->end); + int module_id = m_dbgprot_decode_id(pReply->p, &pReply->p, pReply->end); + type_id = m_dbgprot_decode_id(pReply->p, &pReply->p, pReply->end); + int type_id2 = m_dbgprot_decode_id(pReply->p, &pReply->p, pReply->end); + int token = m_dbgprot_decode_int(pReply->p, &pReply->p, pReply->end); + m_pClass = conn->GetProcess()->FindOrAddClass(token, module_id); + m_pClass->InternalAddRef(); + m_pCordbType = conn->GetProcess()->FindOrAddClassType(m_type, m_pClass); + m_pCordbType->InternalAddRef(); + m_pCordbType->QueryInterface(IID_ICorDebugType, (void**)ppType); + free(namespace_str); + free(class_name_str); + free(class_fullname_str); + goto __Exit; + } + if (m_type == ELEMENT_TYPE_SZARRAY && m_debuggerId != -1) + { + m_pClass = NULL; + MdbgProtBuffer localbuf; + m_dbgprot_buffer_init(&localbuf, 128); + m_dbgprot_buffer_add_id(&localbuf, m_debuggerId); + + int cmdId = conn->SendEvent(MDBGPROT_CMD_SET_ARRAY_REF, MDBGPROT_CMD_ARRAY_REF_GET_TYPE, &localbuf); + m_dbgprot_buffer_free(&localbuf); + + ReceivedReplyPacket* received_reply_packet = conn->GetReplyWithError(cmdId); + CHECK_ERROR_RETURN_FALSE(received_reply_packet); + MdbgProtBuffer* pReply = received_reply_packet->Buffer(); + + int type_id = m_dbgprot_decode_byte(pReply->p, &pReply->p, pReply->end); + int rank = m_dbgprot_decode_int(pReply->p, &pReply->p, pReply->end); + if (type_id == ELEMENT_TYPE_CLASS) + { + int klass_id = m_dbgprot_decode_int(pReply->p, &pReply->p, pReply->end); + + m_dbgprot_buffer_init(&localbuf, 128); + m_dbgprot_buffer_add_id(&localbuf, klass_id); + + cmdId = conn->SendEvent(MDBGPROT_CMD_SET_TYPE, MDBGPROT_CMD_TYPE_GET_INFO, &localbuf); + m_dbgprot_buffer_free(&localbuf); + + received_reply_packet = conn->GetReplyWithError(cmdId); + CHECK_ERROR_RETURN_FALSE(received_reply_packet); + pReply = received_reply_packet->Buffer(); + + char* namespace_str = m_dbgprot_decode_string(pReply->p, &pReply->p, pReply->end); + char* class_name_str = m_dbgprot_decode_string(pReply->p, &pReply->p, pReply->end); + char* class_fullname_str = m_dbgprot_decode_string(pReply->p, &pReply->p, pReply->end); + int assembly_id = m_dbgprot_decode_id(pReply->p, &pReply->p, pReply->end); + int module_id = m_dbgprot_decode_id(pReply->p, &pReply->p, pReply->end); + int type_id3 = m_dbgprot_decode_id(pReply->p, &pReply->p, pReply->end); + int type_id2 = m_dbgprot_decode_id(pReply->p, &pReply->p, pReply->end); + int token = m_dbgprot_decode_int(pReply->p, &pReply->p, pReply->end); + m_pClass = conn->GetProcess()->FindOrAddClass(token, module_id); + m_pClass->InternalAddRef(); + free(namespace_str); + free(class_name_str); + free(class_fullname_str); + } + + m_pCordbType = conn->GetProcess()->FindOrAddArrayType(m_type, conn->GetProcess()->FindOrAddClassType((CorElementType)type_id, m_pClass)); + m_pCordbType->InternalAddRef(); + m_pCordbType->QueryInterface(IID_ICorDebugType, (void**)ppType); + goto __Exit; + } + m_pCordbType = conn->GetProcess()->FindOrAddPrimitiveType(m_type); + m_pCordbType->InternalAddRef(); + m_pCordbType->QueryInterface(IID_ICorDebugType, (void**)ppType); + } + EX_CATCH_HRESULT(hr); +__Exit: + return hr; +} + +HRESULT STDMETHODCALLTYPE CordbReferenceValue::GetSize64(ULONG64* pSize) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbReferenceValue - GetSize64 - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbReferenceValue::GetValue(void* pTo) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbReferenceValue - GetValue - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbReferenceValue::SetValue(void* pFrom) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbReferenceValue - SetValue - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbReferenceValue::IsNull(BOOL* pbNull) +{ + if (m_debuggerId == -1) + *pbNull = true; + LOG((LF_CORDB, LL_INFO1000000, "CordbReferenceValue - IsNull - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbReferenceValue::GetValue(CORDB_ADDRESS* pValue) +{ + if (m_debuggerId == -1) + *pValue = NULL; + else + *pValue = (CORDB_ADDRESS)&m_debuggerId; + LOG((LF_CORDB, LL_INFO1000000, "CordbReferenceValue - GetValue - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbReferenceValue::SetValue(CORDB_ADDRESS value) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbReferenceValue - SetValue CORDB_ADDRESS - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbReferenceValue::Dereference(ICorDebugValue** ppValue) +{ + if (m_debuggerId == -1) + return CORDBG_E_BAD_REFERENCE_VALUE; + if (m_type == ELEMENT_TYPE_SZARRAY || m_type == ELEMENT_TYPE_ARRAY) + { + CordbArrayValue* objectValue = new CordbArrayValue(conn, m_pCordbType, m_debuggerId, m_pClass); + objectValue->QueryInterface(IID_ICorDebugValue, (void**)ppValue); + } + else + { + CordbObjectValue* objectValue = new CordbObjectValue(conn, m_type, m_debuggerId, m_pClass); + objectValue->QueryInterface(IID_ICorDebugValue, (void**)ppValue); + } + LOG((LF_CORDB, LL_INFO1000000, "CordbReferenceValue - Dereference - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbReferenceValue::DereferenceStrong(ICorDebugValue** ppValue) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbReferenceValue - DereferenceStrong - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +CordbReferenceValue::CordbReferenceValue(Connection* conn, CorElementType type, int object_id, CordbClass* klass, CordbType* cordbType, CORDB_ADDRESS cordbAddress) + : CordbBaseMono(conn) +{ + this->m_type = type; + this->m_debuggerId = object_id; + this->conn = conn; + this->m_pClass = klass; + this->m_pCordbType = cordbType; + this->m_pAddress = cordbAddress; + if (cordbType) + cordbType->InternalAddRef(); + if (klass) + klass->InternalAddRef(); +} + +CordbReferenceValue::~CordbReferenceValue() +{ + if (m_pCordbType) + m_pCordbType->InternalRelease(); + if (m_pClass) + m_pClass->InternalRelease(); +} + +CordbObjectValue::CordbObjectValue(Connection* conn, CorElementType type, int object_id, CordbClass* klass) + : CordbBaseMono(conn) +{ + this->m_type = type; + this->m_debuggerId = object_id; + this->m_pClass = klass; + if (klass) + klass->InternalAddRef(); + m_pCordbType = NULL; +} + +CordbObjectValue::~CordbObjectValue() +{ + if (m_pClass) + m_pClass->InternalRelease(); + if (m_pCordbType) + m_pCordbType->InternalRelease(); +} + +HRESULT STDMETHODCALLTYPE CordbObjectValue::GetType(CorElementType* pType) +{ + LOG((LF_CORDB, LL_INFO1000000, "CordbObjectValue - GetType - IMPLEMENTED\n")); + *pType = m_type; + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbObjectValue::GetSize(ULONG32* pSize) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbObjectValue - GetSize - NOT IMPLEMENTED\n")); + *pSize = 10; + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbObjectValue::GetAddress(CORDB_ADDRESS* pAddress) +{ + *pAddress = (CORDB_ADDRESS)&m_debuggerId; + LOG((LF_CORDB, LL_INFO1000000, "CordbObjectValue - GetAddress - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbObjectValue::CreateBreakpoint(ICorDebugValueBreakpoint** ppBreakpoint) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbObjectValue - CreateBreakpoint - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbObjectValue::GetExactType(ICorDebugType** ppType) +{ + LOG((LF_CORDB, LL_INFO1000000, "CordbObjectValue - GetExactType - IMPLEMENTED\n")); + if (m_pCordbType == NULL) + { + m_pCordbType = conn->GetProcess()->FindOrAddClassType(m_type, m_pClass); + m_pCordbType->InternalAddRef(); + } + m_pCordbType->QueryInterface(IID_ICorDebugType, (void**)ppType); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbObjectValue::GetSize64(ULONG64* pSize) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbObjectValue - GetSize64 - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbObjectValue::GetValue(void* pTo) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbObjectValue - GetValue - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbObjectValue::SetValue(void* pFrom) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbObjectValue - SetValue - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbObjectValue::GetVirtualMethodAndType(mdMemberRef memberRef, + ICorDebugFunction** ppFunction, + ICorDebugType** ppType) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbObjectValue - GetVirtualMethodAndType - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbObjectValue::GetLength(ULONG32* pcchString) +{ + HRESULT hr = S_OK; + EX_TRY + { + if (m_debuggerId == -1) + hr = S_FALSE; + else if (m_type == ELEMENT_TYPE_STRING) + { + MdbgProtBuffer localbuf; + m_dbgprot_buffer_init(&localbuf, 128); + m_dbgprot_buffer_add_id(&localbuf, m_debuggerId); + + int cmdId = conn->SendEvent(MDBGPROT_CMD_SET_STRING_REF, MDBGPROT_CMD_STRING_REF_GET_LENGTH, &localbuf); + m_dbgprot_buffer_free(&localbuf); + + ReceivedReplyPacket* received_reply_packet = conn->GetReplyWithError(cmdId); + CHECK_ERROR_RETURN_FALSE(received_reply_packet); + MdbgProtBuffer* pReply = received_reply_packet->Buffer(); + + *pcchString = (ULONG32)m_dbgprot_decode_long(pReply->p, &pReply->p, pReply->end); + } + else + hr = E_NOTIMPL; + } + EX_CATCH_HRESULT(hr); + return hr; +} + +HRESULT STDMETHODCALLTYPE CordbObjectValue::GetString(ULONG32 cchString, ULONG32* pcchString, WCHAR szString[]) +{ + HRESULT hr = S_OK; + EX_TRY + { + if (m_debuggerId == -1) + hr = S_FALSE; + else if (m_type == ELEMENT_TYPE_STRING) + { + MdbgProtBuffer localbuf; + m_dbgprot_buffer_init(&localbuf, 128); + m_dbgprot_buffer_add_id(&localbuf, m_debuggerId); + + int cmdId = conn->SendEvent(MDBGPROT_CMD_SET_STRING_REF, MDBGPROT_CMD_STRING_REF_GET_VALUE, &localbuf); + m_dbgprot_buffer_free(&localbuf); + + ReceivedReplyPacket* received_reply_packet = conn->GetReplyWithError(cmdId); + CHECK_ERROR_RETURN_FALSE(received_reply_packet); + MdbgProtBuffer* pReply = received_reply_packet->Buffer(); + + *pcchString = cchString; + int use_utf16 = m_dbgprot_decode_byte(pReply->p, &pReply->p, pReply->end); + if (use_utf16) + { + LOG((LF_CORDB, LL_INFO100000, "CordbObjectValue - GetString - NOT IMPLEMENTED - use_utf16\n")); + } + else + { + char* value = m_dbgprot_decode_string(pReply->p, &pReply->p, pReply->end); + LOG((LF_CORDB, LL_INFO1000000, "CordbObjectValue - GetString - IMPLEMENTED\n")); + if (cchString >= strlen(value)) + { + MultiByteToWideChar(CP_UTF8, 0, value, -1, szString, cchString); + *pcchString = cchString; + } + free(value); + } + hr = S_OK; + } + else + hr = E_NOTIMPL; + } + EX_CATCH_HRESULT(hr); + return hr; +} + +HRESULT STDMETHODCALLTYPE CordbObjectValue::CreateHandle(CorDebugHandleType type, ICorDebugHandleValue** ppHandle) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbObjectValue - CreateHandle - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbObjectValue::GetThreadOwningMonitorLock(ICorDebugThread** ppThread, + DWORD* pAcquisitionCount) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbObjectValue - GetThreadOwningMonitorLock - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbObjectValue::GetMonitorEventWaitList(ICorDebugThreadEnum** ppThreadEnum) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbObjectValue - GetMonitorEventWaitList - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE +CordbObjectValue::EnumerateExceptionCallStack(ICorDebugExceptionObjectCallStackEnum** ppCallStackEnum) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbObjectValue - EnumerateExceptionCallStack - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbObjectValue::GetCachedInterfaceTypes(BOOL bIInspectableOnly, + ICorDebugTypeEnum** ppInterfacesEnum) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbObjectValue - GetCachedInterfaceTypes - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbObjectValue::GetCachedInterfacePointers(BOOL bIInspectableOnly, + ULONG32 celt, + ULONG32* pcEltFetched, + CORDB_ADDRESS* ptrs) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbObjectValue - GetCachedInterfacePointers - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbObjectValue::GetTarget(ICorDebugReferenceValue** ppObject) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbObjectValue - GetTarget - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbObjectValue::GetFunction(ICorDebugFunction** ppFunction) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbObjectValue - GetFunction - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbObjectValue::GetClass(ICorDebugClass** ppClass) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbObjectValue - GetClass - IMPLEMENTED\n")); + if (m_pClass) { + m_pClass->QueryInterface(IID_ICorDebugClass, (void**)ppClass); + return S_OK; + } + return S_FALSE; +} + +HRESULT STDMETHODCALLTYPE CordbObjectValue::GetFieldValue(ICorDebugClass* pClass, + mdFieldDef fieldDef, + ICorDebugValue** ppValue) +{ + LOG((LF_CORDB, LL_INFO1000000, "CordbObjectValue - GetFieldValue - IMPLEMENTED\n")); + HRESULT hr = S_OK; + EX_TRY + { + if (m_debuggerId == -1) + hr = S_FALSE; + else { + MdbgProtBuffer localbuf; + m_dbgprot_buffer_init(&localbuf, 128); + m_dbgprot_buffer_add_id(&localbuf, m_debuggerId); + m_dbgprot_buffer_add_int(&localbuf, fieldDef); + + int cmdId = conn->SendEvent(MDBGPROT_CMD_SET_OBJECT_REF, MDBGPROT_CMD_OBJECT_REF_GET_VALUES_ICORDBG, &localbuf); + m_dbgprot_buffer_free(&localbuf); + + ReceivedReplyPacket* received_reply_packet = conn->GetReplyWithError(cmdId); + CHECK_ERROR_RETURN_FALSE(received_reply_packet); + MdbgProtBuffer* pReply = received_reply_packet->Buffer(); + + hr = CreateCordbValue(conn, pReply, ppValue); + } + } + EX_CATCH_HRESULT(hr); + return hr; +} + +int CordbObjectValue::GetTypeSize(int type) +{ + switch (type) + { + case ELEMENT_TYPE_VOID: + return 0; + case ELEMENT_TYPE_BOOLEAN: + case ELEMENT_TYPE_I1: + case ELEMENT_TYPE_U1: + return 1; + break; + case ELEMENT_TYPE_CHAR: + case ELEMENT_TYPE_I2: + case ELEMENT_TYPE_U2: + return 2; + case ELEMENT_TYPE_I4: + case ELEMENT_TYPE_U4: + case ELEMENT_TYPE_R4: + return 4; + case ELEMENT_TYPE_I8: + case ELEMENT_TYPE_U8: + case ELEMENT_TYPE_R8: + return 8; + } + return 0; +} + +HRESULT CordbObjectValue::CreateCordbValue(Connection* conn, MdbgProtBuffer* pReply, ICorDebugValue** ppValue) +{ + HRESULT hr = S_OK; + EX_TRY + { + CorElementType type = (CorElementType)m_dbgprot_decode_byte(pReply->p, &pReply->p, pReply->end); + CordbContent value; + + if ((MdbgProtValueTypeId)type == MDBGPROT_VALUE_TYPE_ID_NULL) + { + CorElementType type = (CorElementType)m_dbgprot_decode_byte(pReply->p, &pReply->p, pReply->end); + if (type == ELEMENT_TYPE_CLASS || type == ELEMENT_TYPE_STRING) + { + int klass_id = (CorElementType)m_dbgprot_decode_id(pReply->p, &pReply->p, pReply->end); + + MdbgProtBuffer localbuf; + m_dbgprot_buffer_init(&localbuf, 128); + m_dbgprot_buffer_add_id(&localbuf, klass_id); + int cmdId = conn->SendEvent(MDBGPROT_CMD_SET_TYPE, MDBGPROT_CMD_TYPE_GET_INFO, &localbuf); + m_dbgprot_buffer_free(&localbuf); + ReceivedReplyPacket* received_reply_packet = conn->GetReplyWithError(cmdId); + CHECK_ERROR_RETURN_FALSE(received_reply_packet); + MdbgProtBuffer* pReply = received_reply_packet->Buffer(); + char* namespace_str = m_dbgprot_decode_string(pReply->p, &pReply->p, pReply->end); + char* class_name_str = m_dbgprot_decode_string(pReply->p, &pReply->p, pReply->end); + char* class_fullname_str = m_dbgprot_decode_string(pReply->p, &pReply->p, pReply->end); + int assembly_id = m_dbgprot_decode_id(pReply->p, &pReply->p, pReply->end); + int module_id = m_dbgprot_decode_id(pReply->p, &pReply->p, pReply->end); + int type_id = m_dbgprot_decode_id(pReply->p, &pReply->p, pReply->end); + int type_id2 = m_dbgprot_decode_id(pReply->p, &pReply->p, pReply->end); + int token = m_dbgprot_decode_int(pReply->p, &pReply->p, pReply->end); + + CordbClass* klass = conn->GetProcess()->FindOrAddClass(token, module_id); + CordbReferenceValue* refValue = new CordbReferenceValue(conn, type, -1, klass); + refValue->QueryInterface(IID_ICorDebugValue, (void**)ppValue); + free(namespace_str); + free(class_name_str); + free(class_fullname_str); + } + if (type == ELEMENT_TYPE_SZARRAY) + { + CordbClass* klass = NULL; + int type_id = m_dbgprot_decode_byte(pReply->p, &pReply->p, pReply->end); + if (type_id == ELEMENT_TYPE_CLASS) + { + int klass_id = m_dbgprot_decode_int(pReply->p, &pReply->p, pReply->end); + + MdbgProtBuffer localbuf; + m_dbgprot_buffer_init(&localbuf, 128); + m_dbgprot_buffer_add_id(&localbuf, klass_id); + int cmdId = conn->SendEvent(MDBGPROT_CMD_SET_TYPE, MDBGPROT_CMD_TYPE_GET_INFO, &localbuf); + m_dbgprot_buffer_free(&localbuf); + ReceivedReplyPacket* received_reply_packet = conn->GetReplyWithError(cmdId); + CHECK_ERROR_RETURN_FALSE(received_reply_packet); + MdbgProtBuffer* pReply = received_reply_packet->Buffer(); + char* namespace_str = m_dbgprot_decode_string(pReply->p, &pReply->p, pReply->end); + char* class_name_str = m_dbgprot_decode_string(pReply->p, &pReply->p, pReply->end); + char* class_fullname_str = m_dbgprot_decode_string(pReply->p, &pReply->p, pReply->end); + int assembly_id = m_dbgprot_decode_id(pReply->p, &pReply->p, pReply->end); + int module_id = m_dbgprot_decode_id(pReply->p, &pReply->p, pReply->end); + int type_id3 = m_dbgprot_decode_id(pReply->p, &pReply->p, pReply->end); + int type_id2 = m_dbgprot_decode_id(pReply->p, &pReply->p, pReply->end); + int token = m_dbgprot_decode_int(pReply->p, &pReply->p, pReply->end); + klass = conn->GetProcess()->FindOrAddClass(token, module_id); + free(namespace_str); + free(class_name_str); + free(class_fullname_str); + } + CordbType* cordbtype = conn->GetProcess()->FindOrAddArrayType(type, conn->GetProcess()->FindOrAddClassType((CorElementType)type_id, klass)); + CordbReferenceValue* refValue = new CordbReferenceValue(conn, type, -1, klass, cordbtype); + refValue->QueryInterface(IID_ICorDebugValue, (void**)ppValue); + } + goto __Exit; + } + + switch (type) + { + case ELEMENT_TYPE_BOOLEAN: + case ELEMENT_TYPE_I1: + case ELEMENT_TYPE_U1: + case ELEMENT_TYPE_CHAR: + case ELEMENT_TYPE_I2: + case ELEMENT_TYPE_U2: + case ELEMENT_TYPE_I4: + case ELEMENT_TYPE_U4: + case ELEMENT_TYPE_R4: + case ELEMENT_TYPE_I8: + case ELEMENT_TYPE_U8: + case ELEMENT_TYPE_R8: + value.pointerValue = m_dbgprot_decode_long(pReply->p, &pReply->p, pReply->end); + break; + case ELEMENT_TYPE_CLASS: + case ELEMENT_TYPE_SZARRAY: + case ELEMENT_TYPE_STRING: + { + int object_id = m_dbgprot_decode_id(pReply->p, &pReply->p, pReply->end); + CORDB_ADDRESS address = m_dbgprot_decode_long(pReply->p, &pReply->p, pReply->end); + CordbReferenceValue* refValue = new CordbReferenceValue(conn, type, object_id, NULL, NULL, address); + refValue->QueryInterface(IID_ICorDebugValue, (void**)ppValue); + goto __Exit; + } + default: + LOG((LF_CORDB, LL_INFO100000, "default value - %d", type)); + hr = E_FAIL; + goto __Exit; + } + *ppValue = new CordbValue(conn, type, value, GetTypeSize(type)); + (*ppValue)->AddRef(); + } + EX_CATCH_HRESULT(hr); +__Exit: + return hr; +} + +HRESULT STDMETHODCALLTYPE CordbObjectValue::GetVirtualMethod(mdMemberRef memberRef, ICorDebugFunction** ppFunction) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbObjectValue - GetVirtualMethod - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbObjectValue::GetContext(ICorDebugContext** ppContext) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbObjectValue - GetContext - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbObjectValue::IsValueClass(BOOL* pbIsValueClass) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbObjectValue - IsValueClass - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbObjectValue::GetManagedCopy(IUnknown** ppObject) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbObjectValue - GetManagedCopy - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbObjectValue::SetFromManagedCopy(IUnknown* pObject) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbObjectValue - SetFromManagedCopy - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbObjectValue::IsValid(BOOL* pbValid) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbObjectValue - IsValid - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbObjectValue::CreateRelocBreakpoint(ICorDebugValueBreakpoint** ppBreakpoint) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbObjectValue - CreateRelocBreakpoint - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbObjectValue::QueryInterface(REFIID id, void** pInterface) +{ + if (id == IID_ICorDebugValue) + { + *pInterface = static_cast(static_cast(this)); + } + else if (id == IID_ICorDebugValue2) + { + *pInterface = static_cast(this); + } + else if (id == IID_ICorDebugValue3) + { + *pInterface = static_cast(this); + } + else if (id == IID_ICorDebugObjectValue) + { + *pInterface = static_cast(this); + } + else if (id == IID_ICorDebugObjectValue2) + { + *pInterface = static_cast(this); + } + else if (id == IID_ICorDebugGenericValue) + { + *pInterface = static_cast(this); + } + else if (id == IID_ICorDebugHeapValue) + { + *pInterface = static_cast(this); + } + else if (id == IID_ICorDebugHeapValue2) + { + *pInterface = static_cast(this); + } + else if (id == IID_ICorDebugHeapValue3) + { + *pInterface = static_cast(this); + } + else if ((id == IID_ICorDebugStringValue) && (m_type == ELEMENT_TYPE_STRING)) + { + *pInterface = static_cast(this); + } + else if (id == IID_IUnknown) + { + *pInterface = static_cast(static_cast(this)); + } + else + { + *pInterface = NULL; + return E_NOINTERFACE; + } + AddRef(); + return S_OK; +} + +CordbArrayValue::CordbArrayValue(Connection* conn, CordbType* type, int object_id, CordbClass* klass) + : CordbBaseMono(conn) +{ + this->m_pCordbType = type; + this->m_debuggerId = object_id; + this->m_pClass = klass; + if (klass) + klass->InternalAddRef(); + if (m_pCordbType) + m_pCordbType->InternalAddRef(); +} + +CordbArrayValue::~CordbArrayValue() +{ + if (m_pClass) + m_pClass->InternalRelease(); + if (m_pCordbType) + m_pCordbType->InternalRelease(); +} +HRESULT STDMETHODCALLTYPE CordbArrayValue::GetClass(ICorDebugClass** ppClass) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbArrayValue - GetClass - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbArrayValue::GetFieldValue(ICorDebugClass* pClass, + mdFieldDef fieldDef, + ICorDebugValue** ppValue) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbArrayValue - GetFieldValue - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbArrayValue::GetVirtualMethod(mdMemberRef memberRef, ICorDebugFunction** ppFunction) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbArrayValue - GetVirtualMethod - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbArrayValue::GetContext(ICorDebugContext** ppContext) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbArrayValue - GetContext - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbArrayValue::IsValueClass(BOOL* pbIsValueClass) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbArrayValue - IsValueClass - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbArrayValue::GetManagedCopy(IUnknown** ppObject) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbArrayValue - GetManagedCopy - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbArrayValue::SetFromManagedCopy(IUnknown* pObject) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbArrayValue - SetFromManagedCopy - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbArrayValue::GetType(CorElementType* pType) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbArrayValue - GetType - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbArrayValue::GetSize(ULONG32* pSize) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbArrayValue - GetSize - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbArrayValue::GetAddress(CORDB_ADDRESS* pAddress) +{ + *pAddress = (CORDB_ADDRESS)&m_debuggerId; + LOG((LF_CORDB, LL_INFO100000, "CordbArrayValue - GetAddress - IMPLEMENTED\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbArrayValue::CreateBreakpoint(ICorDebugValueBreakpoint** ppBreakpoint) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbArrayValue - CreateBreakpoint - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbArrayValue::QueryInterface(REFIID id, void** pInterface) +{ + if (id == IID_ICorDebugValue) + { + *pInterface = static_cast(static_cast(this)); + } + else if (id == IID_ICorDebugValue2) + { + *pInterface = static_cast(this); + } + else if (id == IID_ICorDebugValue3) + { + *pInterface = static_cast(this); + } + else if (id == IID_ICorDebugArrayValue) + { + *pInterface = static_cast(this); + } + else if (id == IID_ICorDebugGenericValue) + { + *pInterface = static_cast(this); + } + else if (id == IID_ICorDebugHeapValue2) + { + *pInterface = static_cast(this); + } + else if (id == IID_ICorDebugHeapValue3) + { + *pInterface = static_cast(this); + } + else if (id == IID_IUnknown) + { + *pInterface = static_cast(static_cast(this)); + } + else + { + *pInterface = NULL; + return E_NOINTERFACE; + } + AddRef(); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbArrayValue::GetVirtualMethodAndType(mdMemberRef memberRef, + ICorDebugFunction** ppFunction, + ICorDebugType** ppType) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbArrayValue - GetVirtualMethodAndType - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbArrayValue::GetValue(void* pTo) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbArrayValue - GetValue - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbArrayValue::SetValue(void* pFrom) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbArrayValue - SetValue - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbArrayValue::GetLength(ULONG32* pcchString) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbArrayValue - GetLength - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbArrayValue::GetString(ULONG32 cchString, ULONG32* pcchString, WCHAR szString[]) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbArrayValue - GetString - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbArrayValue::IsValid(BOOL* pbValid) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbArrayValue - IsValid - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbArrayValue::CreateRelocBreakpoint(ICorDebugValueBreakpoint** ppBreakpoint) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbArrayValue - CreateRelocBreakpoint - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbArrayValue::GetExactType(ICorDebugType** ppType) +{ + m_pCordbType->QueryInterface(IID_ICorDebugType, (void**)ppType); + LOG((LF_CORDB, LL_INFO100000, "CordbArrayValue - GetExactType - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbArrayValue::GetSize64(ULONG64* pSize) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbArrayValue - GetSize64 - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbArrayValue::CreateHandle(CorDebugHandleType type, ICorDebugHandleValue** ppHandle) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbArrayValue - CreateHandle - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbArrayValue::GetThreadOwningMonitorLock(ICorDebugThread** ppThread, + DWORD* pAcquisitionCount) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbArrayValue - GetThreadOwningMonitorLock - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbArrayValue::GetMonitorEventWaitList(ICorDebugThreadEnum** ppThreadEnum) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbArrayValue - GetMonitorEventWaitList - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE +CordbArrayValue::EnumerateExceptionCallStack(ICorDebugExceptionObjectCallStackEnum** ppCallStackEnum) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbArrayValue - EnumerateExceptionCallStack - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbArrayValue::GetCachedInterfaceTypes(BOOL bIInspectableOnly, + ICorDebugTypeEnum** ppInterfacesEnum) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbArrayValue - GetCachedInterfaceTypes - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbArrayValue::GetCachedInterfacePointers(BOOL bIInspectableOnly, + ULONG32 celt, + ULONG32* pcEltFetched, + CORDB_ADDRESS* ptrs) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbArrayValue - GetCachedInterfacePointers - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbArrayValue::GetTarget(ICorDebugReferenceValue** ppObject) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbArrayValue - GetTarget - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbArrayValue::GetFunction(ICorDebugFunction** ppFunction) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbArrayValue - GetFunction - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbArrayValue::GetElementType(CorElementType* pType) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbArrayValue - GetElementType - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbArrayValue::GetRank(ULONG32* pnRank) +{ + LOG((LF_CORDB, LL_INFO1000000, "CordbArrayValue - GetRank - IMPLEMENTED\n")); + HRESULT hr = S_OK; + EX_TRY + { + MdbgProtBuffer localbuf; + m_dbgprot_buffer_init(&localbuf, 128); + m_dbgprot_buffer_add_id(&localbuf, m_debuggerId); + + int cmdId = conn->SendEvent(MDBGPROT_CMD_SET_ARRAY_REF, MDBGPROT_CMD_ARRAY_REF_GET_LENGTH, &localbuf); + m_dbgprot_buffer_free(&localbuf); + ReceivedReplyPacket* received_reply_packet = conn->GetReplyWithError(cmdId); + CHECK_ERROR_RETURN_FALSE(received_reply_packet); + MdbgProtBuffer* pReply = received_reply_packet->Buffer(); + int rank = m_dbgprot_decode_int(pReply->p, &pReply->p, pReply->end); + *pnRank = rank; + } + EX_CATCH_HRESULT(hr); + return hr; +} + +HRESULT STDMETHODCALLTYPE CordbArrayValue::GetCount(ULONG32* pnCount) +{ + HRESULT hr = S_OK; + EX_TRY + { + MdbgProtBuffer localbuf; + m_dbgprot_buffer_init(&localbuf, 128); + m_dbgprot_buffer_add_id(&localbuf, m_debuggerId); + + int cmdId = conn->SendEvent(MDBGPROT_CMD_SET_ARRAY_REF, MDBGPROT_CMD_ARRAY_REF_GET_LENGTH, &localbuf); + m_dbgprot_buffer_free(&localbuf); + ReceivedReplyPacket* received_reply_packet = conn->GetReplyWithError(cmdId); + CHECK_ERROR_RETURN_FALSE(received_reply_packet); + MdbgProtBuffer* pReply = received_reply_packet->Buffer(); + int rank = m_dbgprot_decode_int(pReply->p, &pReply->p, pReply->end); + m_nCount = m_dbgprot_decode_int(pReply->p, &pReply->p, pReply->end); + LOG((LF_CORDB, LL_INFO1000000, "CordbArrayValue - GetCount - IMPLEMENTED\n")); + *pnCount = m_nCount; + } + EX_CATCH_HRESULT(hr); + return hr; +} + +HRESULT STDMETHODCALLTYPE CordbArrayValue::GetDimensions(ULONG32 cdim, ULONG32 dims[]) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbArrayValue - GetDimensions - IMPLEMENTED\n")); + dims[0] = m_nCount; + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbArrayValue::HasBaseIndicies(BOOL* pbHasBaseIndicies) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbArrayValue - HasBaseIndicies - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT STDMETHODCALLTYPE CordbArrayValue::GetBaseIndicies(ULONG32 cdim, ULONG32 indicies[]) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbArrayValue - GetBaseIndicies - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} + +HRESULT STDMETHODCALLTYPE CordbArrayValue::GetElement(ULONG32 cdim, ULONG32 indices[], ICorDebugValue** ppValue) +{ + LOG((LF_CORDB, LL_INFO1000000, "CordbArrayValue - GetElement - IMPLEMENTED\n")); + HRESULT hr = S_OK; + EX_TRY + { + MdbgProtBuffer localbuf; + m_dbgprot_buffer_init(&localbuf, 128); + m_dbgprot_buffer_add_id(&localbuf, m_debuggerId); + m_dbgprot_buffer_add_int(&localbuf, indices[cdim - 1]); + m_dbgprot_buffer_add_int(&localbuf, 1); + + int cmdId = conn->SendEvent(MDBGPROT_CMD_SET_ARRAY_REF, MDBGPROT_CMD_ARRAY_REF_GET_VALUES, &localbuf); + m_dbgprot_buffer_free(&localbuf); + ReceivedReplyPacket* received_reply_packet = conn->GetReplyWithError(cmdId); + CHECK_ERROR_RETURN_FALSE(received_reply_packet); + MdbgProtBuffer* pReply = received_reply_packet->Buffer(); + hr = CordbObjectValue::CreateCordbValue(conn, pReply, ppValue); + } + EX_CATCH_HRESULT(hr); + return hr; +} + +HRESULT STDMETHODCALLTYPE CordbArrayValue::GetElementAtPosition(ULONG32 nPosition, ICorDebugValue** ppValue) +{ + LOG((LF_CORDB, LL_INFO100000, "CordbArrayValue - GetElementAtPosition - NOT IMPLEMENTED\n")); + return E_NOTIMPL; +} diff --git a/src/mono/dbi/cordb-value.h b/src/mono/dbi/cordb-value.h new file mode 100644 index 0000000000000..e31573c8d6e2a --- /dev/null +++ b/src/mono/dbi/cordb-value.h @@ -0,0 +1,247 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: CORDB-VALUE.H +// + +#ifndef __MONO_DEBUGGER_CORDB_VALUE_H__ +#define __MONO_DEBUGGER_CORDB_VALUE_H__ + +#include +#include + +union CordbContent +{ + int16_t charValue; + int8_t booleanValue; + int32_t intValue; + int64_t longValue; + CORDB_ADDRESS pointerValue; +}; + +class CordbValue : public CordbBaseMono, public ICorDebugValue2, public ICorDebugValue3, public ICorDebugGenericValue +{ + CorElementType m_type; + CordbContent m_value; + int m_size; + CordbType* m_pType; + +public: + CordbValue(Connection* conn, CorElementType type, CordbContent value, int size); + ULONG STDMETHODCALLTYPE AddRef(void) + { + return (BaseAddRef()); + } + ULONG STDMETHODCALLTYPE Release(void) + { + return (BaseRelease()); + } + const char* GetClassName() + { + return "CordbValue"; + } + ~CordbValue(); + HRESULT STDMETHODCALLTYPE GetType(CorElementType* pType); + HRESULT STDMETHODCALLTYPE GetSize(ULONG32* pSize); + HRESULT STDMETHODCALLTYPE GetAddress(CORDB_ADDRESS* pAddress); + HRESULT STDMETHODCALLTYPE CreateBreakpoint(ICorDebugValueBreakpoint** ppBreakpoint); + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject); + + HRESULT STDMETHODCALLTYPE GetExactType(ICorDebugType** ppType); + HRESULT STDMETHODCALLTYPE GetSize64(ULONG64* pSize); + HRESULT STDMETHODCALLTYPE GetValue(void* pTo); + HRESULT STDMETHODCALLTYPE SetValue(void* pFrom); + CordbContent* GetValue() {return &m_value;} +}; + +class CordbReferenceValue : public CordbBaseMono, + public ICorDebugReferenceValue, + public ICorDebugValue2, + public ICorDebugValue3, + public ICorDebugGenericValue +{ + CorElementType m_type; + int m_debuggerId; + CordbClass* m_pClass; + CordbType* m_pCordbType; + CORDB_ADDRESS m_pAddress; +public: + CordbReferenceValue(Connection* conn, CorElementType type, int object_id, CordbClass* klass = NULL, CordbType* cordbType = NULL, CORDB_ADDRESS cordbAddress = NULL); + ULONG STDMETHODCALLTYPE AddRef(void) + { + return (BaseAddRef()); + } + ULONG STDMETHODCALLTYPE Release(void) + { + return (BaseRelease()); + } + const char* GetClassName() + { + return "CordbReferenceValue"; + } + ~CordbReferenceValue(); + HRESULT STDMETHODCALLTYPE GetType(CorElementType* pType); + HRESULT STDMETHODCALLTYPE GetSize(ULONG32* pSize); + HRESULT STDMETHODCALLTYPE GetAddress(CORDB_ADDRESS* pAddress); + HRESULT STDMETHODCALLTYPE CreateBreakpoint(ICorDebugValueBreakpoint** ppBreakpoint); + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject); + + HRESULT STDMETHODCALLTYPE GetExactType(ICorDebugType** ppType); + HRESULT STDMETHODCALLTYPE GetSize64(ULONG64* pSize); + HRESULT STDMETHODCALLTYPE GetValue(void* pTo); + HRESULT STDMETHODCALLTYPE SetValue(void* pFrom); + HRESULT STDMETHODCALLTYPE IsNull(BOOL* pbNull); + HRESULT STDMETHODCALLTYPE GetValue(CORDB_ADDRESS* pValue); + HRESULT STDMETHODCALLTYPE SetValue(CORDB_ADDRESS value); + HRESULT STDMETHODCALLTYPE Dereference(ICorDebugValue** ppValue); + HRESULT STDMETHODCALLTYPE DereferenceStrong(ICorDebugValue** ppValue); +}; + +class CordbObjectValue : public CordbBaseMono, + public ICorDebugObjectValue, + public ICorDebugObjectValue2, + public ICorDebugGenericValue, + public ICorDebugStringValue, + public ICorDebugValue2, + public ICorDebugValue3, + public ICorDebugHeapValue2, + public ICorDebugHeapValue3, + public ICorDebugExceptionObjectValue, + public ICorDebugComObjectValue, + public ICorDebugDelegateObjectValue +{ + CorElementType m_type; + int m_debuggerId; + CordbClass* m_pClass; + CordbType* m_pCordbType; + +public: + CordbObjectValue(Connection* conn, CorElementType type, int object_id, CordbClass* klass); + ULONG STDMETHODCALLTYPE AddRef(void) + { + return (BaseAddRef()); + } + ULONG STDMETHODCALLTYPE Release(void) + { + return (BaseRelease()); + } + const char* GetClassName() + { + return "CordbObjectValue"; + } + ~CordbObjectValue(); + HRESULT STDMETHODCALLTYPE GetClass(ICorDebugClass** ppClass); + HRESULT STDMETHODCALLTYPE GetFieldValue(ICorDebugClass* pClass, mdFieldDef fieldDef, ICorDebugValue** ppValue); + static HRESULT CreateCordbValue(Connection* conn, MdbgProtBuffer* pReply, ICorDebugValue** ppValue); + static int GetTypeSize(int type); + HRESULT STDMETHODCALLTYPE GetVirtualMethod(mdMemberRef memberRef, ICorDebugFunction** ppFunction); + HRESULT STDMETHODCALLTYPE GetContext(ICorDebugContext** ppContext); + HRESULT STDMETHODCALLTYPE IsValueClass(BOOL* pbIsValueClass); + HRESULT STDMETHODCALLTYPE GetManagedCopy(IUnknown** ppObject); + HRESULT STDMETHODCALLTYPE SetFromManagedCopy(IUnknown* pObject); + HRESULT STDMETHODCALLTYPE IsValid(BOOL* pbValid); + HRESULT STDMETHODCALLTYPE CreateRelocBreakpoint(ICorDebugValueBreakpoint** ppBreakpoint); + HRESULT STDMETHODCALLTYPE GetType(CorElementType* pType); + HRESULT STDMETHODCALLTYPE GetSize(ULONG32* pSize); + HRESULT STDMETHODCALLTYPE GetAddress(CORDB_ADDRESS* pAddress); + HRESULT STDMETHODCALLTYPE CreateBreakpoint(ICorDebugValueBreakpoint** ppBreakpoint); + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject); + + HRESULT STDMETHODCALLTYPE GetExactType(ICorDebugType** ppType); + HRESULT STDMETHODCALLTYPE GetSize64(ULONG64* pSize); + HRESULT STDMETHODCALLTYPE GetValue(void* pTo); + HRESULT STDMETHODCALLTYPE SetValue(void* pFrom); + HRESULT STDMETHODCALLTYPE GetVirtualMethodAndType(mdMemberRef memberRef, ICorDebugFunction** ppFunction, ICorDebugType** ppType); + HRESULT STDMETHODCALLTYPE GetLength(ULONG32* pcchString); + HRESULT STDMETHODCALLTYPE GetString(ULONG32 cchString, ULONG32* pcchString, WCHAR szString[]); + HRESULT STDMETHODCALLTYPE CreateHandle(CorDebugHandleType type, ICorDebugHandleValue** ppHandle); + HRESULT STDMETHODCALLTYPE GetThreadOwningMonitorLock(ICorDebugThread** ppThread, DWORD* pAcquisitionCount); + HRESULT STDMETHODCALLTYPE GetMonitorEventWaitList(ICorDebugThreadEnum** ppThreadEnum); + HRESULT STDMETHODCALLTYPE EnumerateExceptionCallStack(ICorDebugExceptionObjectCallStackEnum** ppCallStackEnum); + HRESULT STDMETHODCALLTYPE GetCachedInterfaceTypes(BOOL bIInspectableOnly, ICorDebugTypeEnum** ppInterfacesEnum); + HRESULT STDMETHODCALLTYPE GetCachedInterfacePointers(BOOL bIInspectableOnly, + ULONG32 celt, + ULONG32* pcEltFetched, + CORDB_ADDRESS* ptrs); + HRESULT STDMETHODCALLTYPE GetTarget(ICorDebugReferenceValue** ppObject); + HRESULT STDMETHODCALLTYPE GetFunction(ICorDebugFunction** ppFunction); +}; + +class CordbArrayValue : public CordbBaseMono, + public ICorDebugObjectValue, + public ICorDebugObjectValue2, + public ICorDebugGenericValue, + public ICorDebugStringValue, + public ICorDebugValue2, + public ICorDebugValue3, + public ICorDebugHeapValue2, + public ICorDebugHeapValue3, + public ICorDebugExceptionObjectValue, + public ICorDebugComObjectValue, + public ICorDebugDelegateObjectValue, + public ICorDebugArrayValue +{ + CordbType* m_pCordbType; + int m_debuggerId; + CordbClass* m_pClass; + int m_nCount; + +public: + CordbArrayValue(Connection* conn, CordbType* type, int object_id, CordbClass* klass); + ULONG STDMETHODCALLTYPE AddRef(void) + { + return (BaseAddRef()); + } + ULONG STDMETHODCALLTYPE Release(void) + { + return (BaseRelease()); + } + const char* GetClassName() + { + return "CordbArrayValue"; + } + ~CordbArrayValue(); + HRESULT STDMETHODCALLTYPE GetClass(ICorDebugClass** ppClass); + HRESULT STDMETHODCALLTYPE GetFieldValue(ICorDebugClass* pClass, mdFieldDef fieldDef, ICorDebugValue** ppValue); + HRESULT STDMETHODCALLTYPE GetVirtualMethod(mdMemberRef memberRef, ICorDebugFunction** ppFunction); + HRESULT STDMETHODCALLTYPE GetContext(ICorDebugContext** ppContext); + HRESULT STDMETHODCALLTYPE IsValueClass(BOOL* pbIsValueClass); + HRESULT STDMETHODCALLTYPE GetManagedCopy(IUnknown** ppObject); + HRESULT STDMETHODCALLTYPE SetFromManagedCopy(IUnknown* pObject); + HRESULT STDMETHODCALLTYPE GetType(CorElementType* pType); + HRESULT STDMETHODCALLTYPE GetSize(ULONG32* pSize); + HRESULT STDMETHODCALLTYPE GetAddress(CORDB_ADDRESS* pAddress); + HRESULT STDMETHODCALLTYPE CreateBreakpoint(ICorDebugValueBreakpoint** ppBreakpoint); + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void** ppvObject); + + HRESULT STDMETHODCALLTYPE GetVirtualMethodAndType(mdMemberRef memberRef, ICorDebugFunction** ppFunction, ICorDebugType** ppType); + HRESULT STDMETHODCALLTYPE GetValue(void* pTo); + HRESULT STDMETHODCALLTYPE SetValue(void* pFrom); + HRESULT STDMETHODCALLTYPE GetLength(ULONG32* pcchString); + HRESULT STDMETHODCALLTYPE GetString(ULONG32 cchString, ULONG32* pcchString, WCHAR szString[]); + HRESULT STDMETHODCALLTYPE IsValid(BOOL* pbValid); + HRESULT STDMETHODCALLTYPE CreateRelocBreakpoint(ICorDebugValueBreakpoint** ppBreakpoint); + HRESULT STDMETHODCALLTYPE GetExactType(ICorDebugType** ppType); + HRESULT STDMETHODCALLTYPE GetSize64(ULONG64* pSize); + HRESULT STDMETHODCALLTYPE CreateHandle(CorDebugHandleType type, ICorDebugHandleValue** ppHandle); + HRESULT STDMETHODCALLTYPE GetThreadOwningMonitorLock(ICorDebugThread** ppThread, DWORD* pAcquisitionCount); + HRESULT STDMETHODCALLTYPE GetMonitorEventWaitList(ICorDebugThreadEnum** ppThreadEnum); + HRESULT STDMETHODCALLTYPE EnumerateExceptionCallStack(ICorDebugExceptionObjectCallStackEnum** ppCallStackEnum); + HRESULT STDMETHODCALLTYPE GetCachedInterfaceTypes(BOOL bIInspectableOnly, ICorDebugTypeEnum** ppInterfacesEnum); + HRESULT STDMETHODCALLTYPE GetCachedInterfacePointers(BOOL bIInspectableOnly, + ULONG32 celt, + ULONG32* pcEltFetched, + CORDB_ADDRESS* ptrs); + HRESULT STDMETHODCALLTYPE GetTarget(ICorDebugReferenceValue** ppObject); + HRESULT STDMETHODCALLTYPE GetFunction(ICorDebugFunction** ppFunction); + + HRESULT STDMETHODCALLTYPE GetElementType(CorElementType* pType); + HRESULT STDMETHODCALLTYPE GetRank(ULONG32* pnRank); + HRESULT STDMETHODCALLTYPE GetCount(ULONG32* pnCount); + HRESULT STDMETHODCALLTYPE GetDimensions(ULONG32 cdim, ULONG32 dims[]); + HRESULT STDMETHODCALLTYPE HasBaseIndicies(BOOL* pbHasBaseIndicies); + HRESULT STDMETHODCALLTYPE GetBaseIndicies(ULONG32 cdim, ULONG32 indicies[]); + HRESULT STDMETHODCALLTYPE GetElement(ULONG32 cdim, ULONG32 indices[], ICorDebugValue** ppValue); + HRESULT STDMETHODCALLTYPE GetElementAtPosition(ULONG32 nPosition, ICorDebugValue** ppValue); +}; +#endif diff --git a/src/mono/dbi/cordb.cpp b/src/mono/dbi/cordb.cpp new file mode 100644 index 0000000000000..0c1517900fabd --- /dev/null +++ b/src/mono/dbi/cordb.cpp @@ -0,0 +1,600 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: CORDB.CPP +// + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DEBUG_ADDRESS "127.0.0.1" +#define DEBUG_PORT "4713" + +MONO_API HRESULT CoreCLRCreateCordbObjectEx( + int iDebuggerVersion, DWORD pid, LPCWSTR lpApplicationGroupId, HMODULE hmodTargetCLR, void** ppCordb) +{ + LOG((LF_CORDB, LL_INFO100000, "CoreCLRCreateCordbObjectEx\n")); + *ppCordb = new Cordb(); + return S_OK; +} + +static void receive_thread(Connection* c) +{ + c->Receive(); +} + +static void debugger_thread(void* m_pProcess) +{ + Connection* connection = new Connection((CordbProcess*)m_pProcess, ((CordbProcess*)m_pProcess)->GetCordb()); + ((CordbProcess*)m_pProcess)->SetConnection(connection); + connection->StartConnection(); + connection->TransportHandshake(); + connection->LoopSendReceive(); + connection->CloseConnection(); +} + +HRESULT Cordb::Initialize(void) +{ + LOG((LF_CORDB, LL_INFO100000, "Cordb - Initialize - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT Cordb::Terminate(void) +{ + LOG((LF_CORDB, LL_INFO100000, "Cordb - Terminate - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT Cordb::SetManagedHandler(ICorDebugManagedCallback* pCallback) +{ + LOG((LF_CORDB, LL_INFO1000000, "Cordb - SetManagedHandler - IMPLEMENTED\n")); + this->m_pCallback = pCallback; + this->GetCallback()->AddRef(); + return S_OK; +} + +HRESULT Cordb::SetUnmanagedHandler(ICorDebugUnmanagedCallback* pCallback) +{ + LOG((LF_CORDB, LL_INFO100000, "Cordb - SetUnmanagedHandler - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT Cordb::CreateProcess(LPCWSTR lpApplicationName, + LPWSTR lpCommandLine, + LPSECURITY_ATTRIBUTES lpProcessAttributes, + LPSECURITY_ATTRIBUTES lpThreadAttributes, + BOOL bInheritHandles, + DWORD dwCreationFlags, + PVOID lpEnvironment, + LPCWSTR lpCurrentDirectory, + LPSTARTUPINFOW lpStartupInfo, + LPPROCESS_INFORMATION lpProcessInformation, + CorDebugCreateProcessFlags debuggingFlags, + ICorDebugProcess** ppProcess) +{ + LOG((LF_CORDB, LL_INFO100000, "Cordb - CreateProcess - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT Cordb::DebugActiveProcess(DWORD id, BOOL win32Attach, ICorDebugProcess** ppProcess) +{ + LOG((LF_CORDB, LL_INFO1000000, "Cordb - DebugActiveProcess - IMPLEMENTED\n")); + m_pProcess = new CordbProcess(this); + m_pProcess->InternalAddRef(); + m_pProcess->QueryInterface(IID_ICorDebugProcess, (void**)ppProcess); + + DWORD thread_id; + CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)debugger_thread, m_pProcess, 0, &thread_id); + return S_OK; +} + +HRESULT Cordb::EnumerateProcesses(ICorDebugProcessEnum** ppProcess) +{ + LOG((LF_CORDB, LL_INFO100000, "Cordb - EnumerateProcesses - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT Cordb::GetProcess(DWORD dwProcessId, ICorDebugProcess** ppProcess) +{ + m_pProcess->QueryInterface(IID_ICorDebugProcess, (void**)ppProcess); + return S_OK; +} + +HRESULT Cordb::CanLaunchOrAttach(DWORD dwProcessId, BOOL win32DebuggingEnabled) +{ + LOG((LF_CORDB, LL_INFO100000, "Cordb - CanLaunchOrAttach - NOT IMPLEMENTED\n")); + return S_OK; +} + +Cordb::Cordb() : CordbBaseMono(NULL) +{ + m_pCallback = NULL; + m_pSemReadWrite = new UTSemReadWrite(); +#ifdef LOGGING + InitializeLogging(); +#endif +} + +Cordb::~Cordb() +{ + this->GetCallback()->Release(); + m_pProcess->InternalRelease(); + delete m_pSemReadWrite; +#ifdef LOGGING + ShutdownLogging(); +#endif +} + +HRESULT +Cordb::QueryInterface(REFIID riid, _COM_Outptr_ void __RPC_FAR* __RPC_FAR* ppvObject) +{ + LOG((LF_CORDB, LL_INFO100000, "Cordb - QueryInterface - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT Cordb::CreateProcessEx(ICorDebugRemoteTarget* pRemoteTarget, + LPCWSTR lpApplicationName, + _In_ LPWSTR lpCommandLine, + LPSECURITY_ATTRIBUTES lpProcessAttributes, + LPSECURITY_ATTRIBUTES lpThreadAttributes, + BOOL bInheritHandles, + DWORD dwCreationFlags, + PVOID lpEnvironment, + LPCWSTR lpCurrentDirectory, + LPSTARTUPINFOW lpStartupInfo, + LPPROCESS_INFORMATION lpProcessInformation, + CorDebugCreateProcessFlags debuggingFlags, + ICorDebugProcess** ppProcess) +{ + LOG((LF_CORDB, LL_INFO100000, "Cordb - CreateProcessEx - NOT IMPLEMENTED\n")); + return S_OK; +} + +HRESULT Cordb::DebugActiveProcessEx(ICorDebugRemoteTarget* pRemoteTarget, + DWORD dwProcessId, + BOOL fWin32Attach, + ICorDebugProcess** ppProcess) +{ + LOG((LF_CORDB, LL_INFO100000, "Cordb - DebugActiveProcessEx - NOT IMPLEMENTED\n")); + return S_OK; +} + +ReceivedReplyPacket::ReceivedReplyPacket(int error, int error_2, int id, MdbgProtBuffer* buf) +{ + this->error = error; + this->error_2 = error_2; + this->id = id; + this->buf = buf; +} + +ReceivedReplyPacket::~ReceivedReplyPacket() +{ + if (buf) + { + m_dbgprot_buffer_free(buf); + delete buf; + } +} + +Connection::Connection(CordbProcess* proc, Cordb* cordb) +{ + m_pProcess = proc; + m_pCordb = cordb; + m_pReceiveReplies = new ArrayList(); + m_pReceivedPacketsToProcess = new ArrayList(); +} + +Connection::~Connection() +{ + DWORD i = 0; + while (i < m_pReceiveReplies->GetCount()) + { + ReceivedReplyPacket* rrp = (ReceivedReplyPacket*)m_pReceiveReplies->Get(i); + if (rrp) + { + delete rrp; + } + i++; + } + i = 0; + while (i < m_pReceivedPacketsToProcess->GetCount()) + { + MdbgProtBuffer* buf = (MdbgProtBuffer*)m_pReceivedPacketsToProcess->Get(i); + if (buf) + { + m_dbgprot_buffer_free(buf); + delete buf; + } + i++; + } + delete m_socket; + delete m_pReceiveReplies; + delete m_pReceivedPacketsToProcess; +} + +void Connection::Receive() +{ + while (true) + { + MdbgProtBuffer recvbuf_header; + m_dbgprot_buffer_init(&recvbuf_header, HEADER_LENGTH); + + int iResult = m_socket->Receive((char*)recvbuf_header.buf, HEADER_LENGTH); + + if (iResult == -1) + { + m_dbgprot_buffer_free(&recvbuf_header); + m_pCordb->GetCallback()->ExitProcess(static_cast(GetProcess())); + break; + } + while (iResult == 0) + { + LOG((LF_CORDB, LL_INFO100000, "transport_recv () sleep returned %d, expected %d.\n", iResult, + HEADER_LENGTH)); + iResult = m_socket->Receive((char*)recvbuf_header.buf, HEADER_LENGTH); + Sleep(1000); + } + + MdbgProtHeader header; + m_dbgprot_decode_command_header(&recvbuf_header, &header); + m_dbgprot_buffer_free(&recvbuf_header); + if (header.len < HEADER_LENGTH) + { + return; + } + + MdbgProtBuffer* recvbuf = new MdbgProtBuffer(); + m_dbgprot_buffer_init(recvbuf, header.len - HEADER_LENGTH); + if (header.len - HEADER_LENGTH != 0) + { + iResult = m_socket->Receive((char*)recvbuf->p, header.len - HEADER_LENGTH); + int totalRead = iResult; + while (totalRead < header.len - HEADER_LENGTH) + { + iResult = m_socket->Receive((char*)recvbuf->p + totalRead, (header.len - HEADER_LENGTH) - totalRead); + totalRead += iResult; + } + } + + dbg_lock(); + if (header.flags == REPLY_PACKET) + { + ReceivedReplyPacket* rp = new ReceivedReplyPacket(header.error, header.error_2, header.id, recvbuf); + m_pReceiveReplies->Append(rp); + } + else + { + m_pReceivedPacketsToProcess->Append(recvbuf); + } + dbg_unlock(); + } +} + +ReceivedReplyPacket* Connection::GetReplyWithError(int cmdId) +{ + ReceivedReplyPacket* rrp = NULL; + while (rrp == NULL || rrp->Id() != cmdId) + { + dbg_lock(); + for (int i = m_pReceiveReplies->GetCount() - 1; i >= 0; i--) + { + rrp = (ReceivedReplyPacket*)m_pReceiveReplies->Get(i); + if (rrp->Id() == cmdId) + break; + } + dbg_unlock(); + } + return rrp; +} + +CordbAppDomain* Connection::GetCurrentAppDomain() +{ + return GetProcess()->GetCurrentAppDomain(); +} + +void Connection::ProcessPacketInternal(MdbgProtBuffer* recvbuf) +{ + int spolicy = m_dbgprot_decode_byte(recvbuf->p, &recvbuf->p, recvbuf->end); + int nevents = m_dbgprot_decode_int(recvbuf->p, &recvbuf->p, recvbuf->end); + CordbAppDomain* pCorDebugAppDomain = GetCurrentAppDomain(); + for (int i = 0; i < nevents; ++i) + { + + int kind = m_dbgprot_decode_byte(recvbuf->p, &recvbuf->p, recvbuf->end); + int req_id = m_dbgprot_decode_int(recvbuf->p, &recvbuf->p, recvbuf->end); + + MdbgProtEventKind etype = (MdbgProtEventKind)kind; + + long thread_id = m_dbgprot_decode_id(recvbuf->p, &recvbuf->p, recvbuf->end); + + LOG((LF_CORDB, LL_INFO100000, "Received %d %d events %s, suspend=%d\n", i, nevents, + m_dbgprot_event_to_string(etype), spolicy)); + + switch (etype) + { + case MDBGPROT_EVENT_KIND_VM_START: + { + m_pCordb->GetCallback()->CreateProcess(static_cast(GetProcess())); + } + break; + case MDBGPROT_EVENT_KIND_VM_DEATH: + { + m_pCordb->GetCallback()->ExitProcess(static_cast(GetProcess())); + } + break; + case MDBGPROT_EVENT_KIND_THREAD_START: + { + CordbThread* thread = new CordbThread(this, GetProcess(), thread_id); + m_pCordb->GetCallback()->CreateThread(pCorDebugAppDomain, thread); + } + break; + case MDBGPROT_EVENT_KIND_APPDOMAIN_CREATE: + { + } + break; + case MDBGPROT_EVENT_KIND_ASSEMBLY_LOAD: + { + // all the callbacks call a resume, in this case that we are faking 2 + // callbacks without receive command, we should not send the continue + int assembly_id = m_dbgprot_decode_id(recvbuf->p, &recvbuf->p, recvbuf->end); + if (pCorDebugAppDomain == NULL) + { + pCorDebugAppDomain = new CordbAppDomain(this, GetProcess()); + GetProcess()->Stop(false); + m_pCordb->GetCallback()->CreateAppDomain(static_cast(GetProcess()), + pCorDebugAppDomain); + } + CordbAssembly* pAssembly = new CordbAssembly(this, GetProcess(), pCorDebugAppDomain, assembly_id); + CordbModule* pModule = new CordbModule(this, GetProcess(), (CordbAssembly*)pAssembly, assembly_id); + + GetProcess()->Stop(false); + m_pCordb->GetCallback()->LoadAssembly(pCorDebugAppDomain, pAssembly); + + m_pCordb->GetCallback()->LoadModule(pCorDebugAppDomain, pModule); + } + break; + case MDBGPROT_EVENT_KIND_BREAKPOINT: + { + int method_id = m_dbgprot_decode_id(recvbuf->p, &recvbuf->p, recvbuf->end); + int64_t offset = m_dbgprot_decode_long(recvbuf->p, &recvbuf->p, recvbuf->end); + CordbThread* thread = GetProcess()->FindThread(thread_id); + if (thread == NULL) + { + thread = new CordbThread(this, GetProcess(), thread_id); + GetProcess()->Stop(false); + m_pCordb->GetCallback()->CreateThread(pCorDebugAppDomain, thread); + } + DWORD i = 0; + CordbFunctionBreakpoint* breakpoint = GetProcess()->GetBreakpoint(req_id); + m_pCordb->GetCallback()->Breakpoint(pCorDebugAppDomain, thread, + static_cast(breakpoint)); + } + break; + case MDBGPROT_EVENT_KIND_STEP: + { + int method_id = m_dbgprot_decode_id(recvbuf->p, &recvbuf->p, recvbuf->end); + int64_t offset = m_dbgprot_decode_long(recvbuf->p, &recvbuf->p, recvbuf->end); + CordbThread* thread = GetProcess()->FindThread(thread_id); + if (thread == NULL) + { + thread = new CordbThread(this, GetProcess(), thread_id); + GetProcess()->Stop(false); + m_pCordb->GetCallback()->CreateThread(pCorDebugAppDomain, thread); + } + CordbStepper* stepper = GetProcess()->GetStepper(req_id); + m_pCordb->GetCallback()->StepComplete(pCorDebugAppDomain, thread, stepper, STEP_NORMAL); + } + break; + default: + { + LOG((LF_CORDB, LL_INFO100000, "Not implemented - %s\n", m_dbgprot_event_to_string(etype))); + } + } + } + // m_dbgprot_buffer_free(&recvbuf); +} + +int Connection::ProcessPacket(bool is_answer) +{ + if (!is_answer) + ProcessPacketFromQueue(); + return 1; +} + +void Connection::ProcessPacketFromQueue() +{ + DWORD i = 0; + while (i < m_pReceivedPacketsToProcess->GetCount()) + { + MdbgProtBuffer* req = (MdbgProtBuffer*)m_pReceivedPacketsToProcess->Get(i); + if (req) + { + ProcessPacketInternal(req); + dbg_lock(); + m_pReceivedPacketsToProcess->Set(i, NULL); + dbg_unlock(); + m_dbgprot_buffer_free(req); + delete req; + } + i++; + } + GetProcess()->CheckPendingEval(); +} + +void Connection::LoopSendReceive() +{ + DWORD thread_id; + CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)receive_thread, this, 0, &thread_id); + + EnableEvent(MDBGPROT_EVENT_KIND_ASSEMBLY_LOAD); + EnableEvent(MDBGPROT_EVENT_KIND_APPDOMAIN_CREATE); + EnableEvent(MDBGPROT_EVENT_KIND_THREAD_START); + EnableEvent(MDBGPROT_EVENT_KIND_THREAD_DEATH); + EnableEvent(MDBGPROT_EVENT_KIND_APPDOMAIN_UNLOAD); + EnableEvent(MDBGPROT_EVENT_KIND_USER_BREAK); + EnableEvent(MDBGPROT_EVENT_KIND_USER_LOG); + EnableEvent(MDBGPROT_EVENT_KIND_VM_DEATH); + + MdbgProtBuffer localbuf; + m_dbgprot_buffer_init(&localbuf, 128); + m_dbgprot_buffer_add_int(&localbuf, MAJOR_VERSION); + m_dbgprot_buffer_add_int(&localbuf, MINOR_VERSION); + int cmdId = SendEvent(MDBGPROT_CMD_SET_VM, MDBGPROT_CMD_VM_SET_PROTOCOL_VERSION, &localbuf); + m_dbgprot_buffer_free(&localbuf); + + m_dbgprot_buffer_init(&localbuf, 128); + cmdId = SendEvent(MDBGPROT_CMD_SET_VM, MDBGPROT_CMD_VM_VERSION, &localbuf); + m_dbgprot_buffer_free(&localbuf); + + ReceivedReplyPacket* received_reply_packet = GetReplyWithError(cmdId); + MdbgProtBuffer* pReply = received_reply_packet->Buffer(); + + char* vm_version = m_dbgprot_decode_string(pReply->p, &pReply->p, pReply->end); + int major_version = m_dbgprot_decode_int(pReply->p, &pReply->p, pReply->end); + int minor_version = m_dbgprot_decode_int(pReply->p, &pReply->p, pReply->end); + + LOG((LF_CORDB, LL_INFO100000, "Protocol version %d.%d, server protocol version %d.%d.\n", MAJOR_VERSION, + MINOR_VERSION, major_version, minor_version)); + free(vm_version); + + m_dbgprot_buffer_init(&localbuf, 128); + SendEvent(MDBGPROT_CMD_SET_VM, MDBGPROT_CMD_VM_SET_USING_ICORDBG, &localbuf); + m_dbgprot_buffer_free(&localbuf); + + int iResult = 0; + // Receive until the peer closes the connection + do + { + iResult = ProcessPacket(); + Sleep(100); + } while (iResult >= 0); +} + +void Connection::EnableEvent(MdbgProtEventKind eventKind) +{ + MdbgProtBuffer sendbuf; + int buflen = 128; + m_dbgprot_buffer_init(&sendbuf, buflen); + m_dbgprot_buffer_add_byte(&sendbuf, eventKind); + m_dbgprot_buffer_add_byte(&sendbuf, MDBGPROT_SUSPEND_POLICY_ALL); + m_dbgprot_buffer_add_byte(&sendbuf, 0); // modifiers + SendEvent(MDBGPROT_CMD_SET_EVENT_REQUEST, MDBGPROT_CMD_EVENT_REQUEST_SET, &sendbuf); + m_dbgprot_buffer_free(&sendbuf); +} + +void Connection::CloseConnection() +{ + m_socket->Close(); +} + +void Connection::StartConnection() +{ + LOG((LF_CORDB, LL_INFO100000, "Start Connection\n")); + + m_socket = new Socket(); + + LOG((LF_CORDB, LL_INFO100000, "Listening to %s:%s\n", DEBUG_ADDRESS, DEBUG_PORT)); + + int ret = m_socket->OpenSocketAcceptConnection(DEBUG_ADDRESS, DEBUG_PORT); + if (ret == -1) + exit(1); + + LOG((LF_CORDB, LL_INFO100000, "Accepted connection from client.\n")); +} + +void Connection::TransportHandshake() +{ + int buflen = 128; + + MdbgProtBuffer sendbuf; + m_dbgprot_buffer_init(&sendbuf, buflen); + + MdbgProtBuffer recvbuf; + m_dbgprot_buffer_init(&recvbuf, buflen); + + int iResult; + iResult = m_socket->Receive((char*)recvbuf.buf, buflen); + + // Send an initial buffer + m_dbgprot_buffer_add_data(&sendbuf, (uint8_t*)"DWP-Handshake", 13); + SendPacket(sendbuf); + m_dbgprot_buffer_free(&sendbuf); + m_dbgprot_buffer_free(&recvbuf); +} + +void Connection::SendPacket(MdbgProtBuffer& sendbuf) +{ + int iResult = m_socket->Send((const char*)sendbuf.buf, m_dbgprot_buffer_len(&sendbuf)); + if (iResult == -1) + { + return; + } +} + +int Connection::SendEvent(int cmd_set, int cmd, MdbgProtBuffer* sendbuf) +{ + MdbgProtBuffer outbuf; + int ret = m_dbgprot_buffer_add_command_header(sendbuf, cmd_set, cmd, &outbuf); + SendPacket(outbuf); + m_dbgprot_buffer_free(&outbuf); + return ret; +} + +MONO_API HRESULT CoreCLRCreateCordbObject(int iDebuggerVersion, DWORD pid, HMODULE hmodTargetCLR, void** ppCordb) +{ + *ppCordb = new Cordb(); + return S_OK; +} + +MONO_API HRESULT CreateCordbObject(int iDebuggerVersion, void** ppCordb) +{ + *ppCordb = new Cordb(); + return S_OK; +} + +CordbBaseMono::CordbBaseMono(Connection* conn) +{ + this->conn = conn; + m_cRef = 0; +} + +CordbBaseMono::~CordbBaseMono() {} + +ULONG CordbBaseMono::InternalAddRef() +{ + return BaseAddRef(); +} + +ULONG CordbBaseMono::InternalRelease() +{ + return BaseRelease(); +} + +ULONG CordbBaseMono::BaseAddRef() +{ + return InterlockedIncrement((volatile LONG*)&m_cRef); +} + +ULONG CordbBaseMono::BaseRelease() +{ + ULONG cRef = InterlockedDecrement((volatile LONG*)&m_cRef); + if (cRef == 0) + { + delete this; + } + return cRef; +} + +void CordbBaseMono::SetConnection(Connection* conn) +{ + this->conn = conn; +} diff --git a/src/mono/dbi/cordb.h b/src/mono/dbi/cordb.h new file mode 100644 index 0000000000000..2bb47cbe7c312 --- /dev/null +++ b/src/mono/dbi/cordb.h @@ -0,0 +1,241 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: CORDB.H +// + +#ifndef __MONO_DEBUGGER_CORDB_H__ +#define __MONO_DEBUGGER_CORDB_H__ + +#include "cor.h" +#include "cordebug.h" +#include "corhdr.h" +#include "xcordebug.h" + +#include +#include + +#include "arraylist.h" +#include "utsem.h" +#include "ex.h" +#include "log.h" + +#ifdef HOST_WIN32 +#include +#include +#endif + +#define return_if_nok(error) \ + do \ + { \ + if (!is_ok((error))) \ + return S_FALSE; \ + } while (0) + +static UTSemReadWrite* m_pSemReadWrite; + +#define dbg_lock() m_pSemReadWrite->LockRead(); +#define dbg_unlock() m_pSemReadWrite->UnlockRead(); + +#ifdef _DEBUG +#define LOGGING +#endif + +#define CreateProcess CreateProcessW + +class Socket; +class Cordb; +class CordbProcess; +class CordbAppDomain; +class CordbAssembly; +class CordbModule; +class CordbCode; +class CordbThread; +class CordbFunction; +class CordbStepper; +class RegMeta; +class CordbRegisterSet; +class CordbClass; +class CordbNativeFrame; +class CordbAppDomainEnum; +class CordbTypeEnum; +class CordbBlockingObjectEnum; +class CordbFunctionBreakpoint; +class CordbEval; +class CordbType; + +enum CordbTypeKind { + CordbTypeKindSimpleType, + CordbTypeKindClassType, + CordbTypeKindArrayType, + CordbTypeKindTotal +}; + +class ReceivedReplyPacket +{ + int error; + int error_2; + int id; + MdbgProtBuffer* buf; + +public: + ReceivedReplyPacket(int error, int error_2, int id, MdbgProtBuffer* buf); + ~ReceivedReplyPacket(); + MdbgProtBuffer* Buffer() + { + return buf; + } + int Error() + { + return error; + } + int Error2() + { + return error_2; + } + int Id() + { + return id; + } +}; + +class Connection +{ + Socket* m_socket; + CordbProcess* m_pProcess; + Cordb* m_pCordb; + ArrayList* m_pReceiveReplies; // TODO use hashmap + ArrayList* m_pReceivedPacketsToProcess; + + void ProcessPacketInternal(MdbgProtBuffer* recvbuf); + void ProcessPacketFromQueue(); + void EnableEvent(MdbgProtEventKind eventKind); + void SendPacket(MdbgProtBuffer& sendbuf); + int ProcessPacket(bool is_answer = false); + +public: + CordbProcess* GetProcess() const + { + return m_pProcess; + } + Cordb* GetCordb() const + { + return m_pCordb; + } + Connection(CordbProcess* proc, Cordb* cordb); + ~Connection(); + + void LoopSendReceive(); + void CloseConnection(); + void StartConnection(); + void TransportHandshake(); + void Receive(); + + int SendEvent(int cmd_set, int cmd, MdbgProtBuffer* sendbuf); + ReceivedReplyPacket* GetReplyWithError(int cmdId); + CordbAppDomain* GetCurrentAppDomain(); +}; + +class CordbBaseMono +{ +protected: + Connection* conn; + ULONG m_cRef; // Ref count. +public: + CordbBaseMono(Connection* conn); + virtual ~CordbBaseMono(); + void SetConnection(Connection* conn); + ULONG BaseAddRef(void); + ULONG BaseRelease(void); + ULONG InternalAddRef(void); + ULONG InternalRelease(void); + virtual const char* GetClassName() + { + return "CordbBaseMono"; + } +}; + +class Cordb : public ICorDebug, public ICorDebugRemote, public CordbBaseMono +{ + ICorDebugManagedCallback* m_pCallback; + CordbProcess* m_pProcess; + +public: + ICorDebugManagedCallback* GetCallback() const + { + return m_pCallback; + } + Cordb(); + ULONG STDMETHODCALLTYPE AddRef(void) + { + return (BaseAddRef()); + } + ULONG STDMETHODCALLTYPE Release(void) + { + return (BaseRelease()); + } + const char* GetClassName() + { + return "Cordb"; + } + ~Cordb(); + + HRESULT STDMETHODCALLTYPE Initialize(void); + + HRESULT STDMETHODCALLTYPE Terminate(void); + + HRESULT STDMETHODCALLTYPE SetManagedHandler(ICorDebugManagedCallback* pCallback); + + HRESULT STDMETHODCALLTYPE SetUnmanagedHandler(ICorDebugUnmanagedCallback* pCallback); + + HRESULT STDMETHODCALLTYPE CreateProcess(LPCWSTR lpApplicationName, + LPWSTR lpCommandLine, + LPSECURITY_ATTRIBUTES lpProcessAttributes, + LPSECURITY_ATTRIBUTES lpThreadAttributes, + BOOL bInheritHandles, + DWORD dwCreationFlags, + PVOID lpEnvironment, + LPCWSTR lpCurrentDirectory, + LPSTARTUPINFOW lpStartupInfo, + LPPROCESS_INFORMATION lpProcessInformation, + CorDebugCreateProcessFlags debuggingFlags, + ICorDebugProcess** ppProcess); + + HRESULT STDMETHODCALLTYPE DebugActiveProcess(DWORD id, BOOL win32Attach, ICorDebugProcess** ppProcess); + HRESULT STDMETHODCALLTYPE EnumerateProcesses(ICorDebugProcessEnum** ppProcess); + + HRESULT STDMETHODCALLTYPE GetProcess(DWORD dwProcessId, ICorDebugProcess** ppProcess); + + HRESULT STDMETHODCALLTYPE CanLaunchOrAttach(DWORD dwProcessId, BOOL win32DebuggingEnabled); + HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, _COM_Outptr_ void __RPC_FAR* __RPC_FAR* ppvObject); + HRESULT STDMETHODCALLTYPE CreateProcessEx(ICorDebugRemoteTarget* pRemoteTarget, + LPCWSTR lpApplicationName, + _In_ LPWSTR lpCommandLine, + LPSECURITY_ATTRIBUTES lpProcessAttributes, + LPSECURITY_ATTRIBUTES lpThreadAttributes, + BOOL bInheritHandles, + DWORD dwCreationFlags, + PVOID lpEnvironment, + LPCWSTR lpCurrentDirectory, + LPSTARTUPINFOW lpStartupInfo, + LPPROCESS_INFORMATION lpProcessInformation, + CorDebugCreateProcessFlags debuggingFlags, + ICorDebugProcess** ppProcess); + + HRESULT STDMETHODCALLTYPE DebugActiveProcessEx(ICorDebugRemoteTarget* pRemoteTarget, + DWORD dwProcessId, + BOOL fWin32Attach, + ICorDebugProcess** ppProcess); +}; + +#define CHECK_ERROR_RETURN_FALSE(localbuf) \ + do \ + { \ + if (localbuf->Error() > 0 || localbuf->Error2() > 0) \ + { \ + LOG((LF_CORDB, LL_INFO100000, "ERROR RECEIVED\n")); \ + EX_THROW(HRException, (E_FAIL)); \ + } \ + } while (0) + +#endif diff --git a/src/mono/dbi/debugger-coreclr-compat.h b/src/mono/dbi/debugger-coreclr-compat.h new file mode 100644 index 0000000000000..536cc83961114 --- /dev/null +++ b/src/mono/dbi/debugger-coreclr-compat.h @@ -0,0 +1,22 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: DEBUGGER-CORECLR-COMPAT.H +// + +#ifndef __DBG_CORECLR_MONO_COMPAT_H__ +#define __DBG_CORECLR_MONO_COMPAT_H__ + +#define g_malloc malloc +#define g_free free +#define g_assert assert +#define g_realloc realloc +#include "stdafx.h" + +static inline int32_t dbg_rt_atomic_inc_int32_t(volatile int32_t* value) +{ + STATIC_CONTRACT_NOTHROW; + return static_cast(InterlockedIncrement((volatile LONG*)(value))); +} + +#endif \ No newline at end of file diff --git a/src/mono/dbi/socket-dbi/CMakeLists.txt b/src/mono/dbi/socket-dbi/CMakeLists.txt new file mode 100644 index 0000000000000..5e2a352ee67cd --- /dev/null +++ b/src/mono/dbi/socket-dbi/CMakeLists.txt @@ -0,0 +1,10 @@ +project(socket-dbi) + +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +set(socket_sources + socket.cpp + socket.h +) + +add_library(socket-dbi STATIC ${socket_sources}) diff --git a/src/mono/dbi/socket-dbi/socket.cpp b/src/mono/dbi/socket-dbi/socket.cpp new file mode 100644 index 0000000000000..104a280ddf152 --- /dev/null +++ b/src/mono/dbi/socket-dbi/socket.cpp @@ -0,0 +1,105 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: SOCKET.CPP +// + +#include "socket.h" + +#ifdef WIN32 +#include +#include +#else +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef HAVE_SYS_SOCKIO_H +#include +#endif +#include +#if defined(__APPLE__) +#include +#endif +#include +#include +#endif + + +Socket::~Socket() +{ + Close(); +} + +int Socket::OpenSocketAcceptConnection(const char *address, const char *port) { + socketId = -1; + + struct addrinfo *result = NULL, *ptr = NULL, hints; + int iResult; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + + // Resolve the server address and port + iResult = getaddrinfo(address, port, &hints, &result); + if (iResult != 0) { + return -1; + } + + // Attempt to connect to an address until one succeeds + for (ptr = result; ptr != NULL; ptr = ptr->ai_next) { + + // Create a SOCKET for connecting to server + socketId = socket(ptr->ai_family, ptr->ai_socktype, ptr->ai_protocol); + + if (socketId == -1) { + return -1; + } + + int flag = 1; + if (setsockopt(socketId, SOL_SOCKET, SO_REUSEADDR, (char *)&flag, sizeof(int))) + continue; + + iResult = bind(socketId, ptr->ai_addr, (int)ptr->ai_addrlen); + if (iResult == -1) + continue; + + iResult = listen(socketId, 16); + if (iResult == -1) + continue; + + break; + } + + if (iResult != -1) + socketId = accept(socketId, NULL, NULL); + + freeaddrinfo(result); + + return 1; +} + +int Socket::Receive(char *buff, int buflen) { + return recv(socketId, buff, buflen, 0); +} + +void Socket::Close() { +#ifdef WIN32 + closesocket (socketId); +#else + close (socketId); +#endif +} + +int Socket::Send(const char *buff, int buflen) { + return send(socketId, buff, buflen, 0); +} diff --git a/src/mono/dbi/socket-dbi/socket.h b/src/mono/dbi/socket-dbi/socket.h new file mode 100644 index 0000000000000..62e321fe249f8 --- /dev/null +++ b/src/mono/dbi/socket-dbi/socket.h @@ -0,0 +1,20 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: SOCKET.H +// + +#ifndef __SOCKET_DBI_H__ +#define __SOCKET_DBI_H__ + +class Socket { + long long socketId; +public: + ~Socket(); + int OpenSocketAcceptConnection(const char *address, const char *port); + void Close(); + int Receive(char *buff, int buflen); + int Send(const char *buff, int buflen); +}; + +#endif diff --git a/src/mono/mono/mini/debugger-agent.c b/src/mono/mono/mini/debugger-agent.c index b3b4b609df9c7..5180ae408b647 100644 --- a/src/mono/mono/mini/debugger-agent.c +++ b/src/mono/mono/mini/debugger-agent.c @@ -135,6 +135,7 @@ typedef struct { gboolean defer; int keepalive; gboolean setpgid; + gboolean using_icordbg; } AgentConfig; typedef struct _InvokeData InvokeData; @@ -4964,6 +4965,28 @@ buffer_add_value_full (Buffer *buf, MonoType *t, void *addr, MonoDomain *domain, buffer_add_fixed_array(buf, t, addr, domain, as_vtype, parent_vtypes, len_fixed_array); return; } + + if (agent_config.using_icordbg) { + switch (t->type) { + case MONO_TYPE_BOOLEAN: + case MONO_TYPE_I1: + case MONO_TYPE_U1: + case MONO_TYPE_CHAR: + case MONO_TYPE_I2: + case MONO_TYPE_U2: + case MONO_TYPE_I4: + case MONO_TYPE_U4: + case MONO_TYPE_R4: + case MONO_TYPE_I8: + case MONO_TYPE_U8: + case MONO_TYPE_R8: + case MONO_TYPE_PTR: + buffer_add_byte (buf, t->type); + buffer_add_long (buf, (gssize) addr); + return; + } + } + switch (t->type) { case MONO_TYPE_VOID: buffer_add_byte (buf, t->type); @@ -5033,6 +5056,8 @@ buffer_add_value_full (Buffer *buf, MonoType *t, void *addr, MonoDomain *domain, buffer_add_byte (buf, m_class_get_byval_arg (obj->vtable->klass)->type); } buffer_add_objid (buf, obj); + if (agent_config.using_icordbg) + buffer_add_long (buf, (gssize) addr); } break; handle_vtype: @@ -5306,7 +5331,7 @@ decode_value_internal (MonoType *t, int type, MonoDomain *domain, guint8 *addr, /* Fall through */ handle_vtype: case MONO_TYPE_VALUETYPE: - if (type == MONO_TYPE_OBJECT) { + if (type == MONO_TYPE_OBJECT || type == MONO_TYPE_STRING) { /* Boxed vtype */ int objid = decode_objid (buf, &buf, limit); ErrorCode err; @@ -5331,7 +5356,7 @@ decode_value_internal (MonoType *t, int type, MonoDomain *domain, guint8 *addr, handle_ref: default: if (MONO_TYPE_IS_REFERENCE (t)) { - if (type == MONO_TYPE_OBJECT) { + if (type == MONO_TYPE_OBJECT || type == MONO_TYPE_STRING) { int objid = decode_objid (buf, &buf, limit); ErrorCode err; MonoObject *obj; @@ -5470,16 +5495,14 @@ add_var (Buffer *buf, MonoDebugMethodJitInfo *jit, MonoType *t, MonoDebugVarInfo guint32 flags; int reg; guint8 *addr, *gaddr; - host_mgreg_t reg_val; flags = var->index & MONO_DEBUG_VAR_ADDRESS_MODE_FLAGS; reg = var->index & ~MONO_DEBUG_VAR_ADDRESS_MODE_FLAGS; switch (flags) { case MONO_DEBUG_VAR_ADDRESS_MODE_REGISTER: - reg_val = mono_arch_context_get_int_reg (ctx, reg); - - buffer_add_value_full (buf, t, ®_val, domain, as_vtype, NULL, 1); + addr = (guint8 *)mono_arch_context_get_int_reg_address (ctx, reg); + buffer_add_value_full (buf, t, addr, domain, as_vtype, NULL, 1); break; case MONO_DEBUG_VAR_ADDRESS_MODE_REGOFFSET: addr = (guint8 *)mono_arch_context_get_int_reg (ctx, reg); @@ -6715,15 +6738,13 @@ vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf) tls->pending_invoke->endp = tls->pending_invoke->p + (end - p); tls->pending_invoke->suspend_count = suspend_count; tls->pending_invoke->nmethods = nmethods; - if (!CHECK_PROTOCOL_VERSION (2, 59)) { //on icordbg they send a resume after calling an invoke method - if (flags & INVOKE_FLAG_SINGLE_THREADED) { - resume_thread(THREAD_TO_INTERNAL(thread)); - } - else { - count = suspend_count; - for (i = 0; i < count; ++i) - resume_vm(); - } + if (flags & INVOKE_FLAG_SINGLE_THREADED) { + resume_thread(THREAD_TO_INTERNAL(thread)); + } + else { + count = suspend_count; + for (i = 0; i < count; ++i) + resume_vm(); } break; } @@ -6866,6 +6887,16 @@ vm_commands (int command, int id, guint8 *p, guint8 *end, Buffer *buf) case CMD_VM_STOP_BUFFERING: /* Handled in the main loop */ break; + case MDBGPROT_CMD_VM_READ_MEMORY: { + guint8* memory = (guint8*) decode_long (p, &p, end); + int size = decode_int (p, &p, end); + buffer_add_byte_array (buf, memory, size); + break; + } + case MDBGPROT_CMD_VM_SET_USING_ICORDBG: { + agent_config.using_icordbg = TRUE; + break; + } default: return ERR_NOT_IMPLEMENTED; } @@ -7197,6 +7228,12 @@ domain_commands (int command, guint8 *p, guint8 *end, Buffer *buf) mono_error_cleanup (error); return ERR_INVALID_OBJECT; } + + if (CHECK_PROTOCOL_VERSION(3, 0)) { + buffer_add_byte(buf, 1); + buffer_add_byte(buf, MONO_TYPE_STRING); + } + buffer_add_objid (buf, (MonoObject*)o); break; } @@ -7468,6 +7505,15 @@ assembly_commands (int command, guint8 *p, guint8 *end, Buffer *buf) return err; break; } + case MDBGPROT_CMD_ASSEMBLY_GET_PEIMAGE_ADDRESS: { + MonoImage* image = ass->image; + if (ass->dynamic) { + return ERR_NOT_IMPLEMENTED; + } + buffer_add_long (buf, (guint64)(gsize)image->raw_data); + buffer_add_int (buf, image->raw_data_len); + break; + } default: return ERR_NOT_IMPLEMENTED; } @@ -8727,6 +8773,18 @@ thread_commands (int command, guint8 *p, guint8 *end, Buffer *buf) buffer_add_long (buf, (long)mono_stopwatch_elapsed_ms (&tls->step_time)); break; } + case MDBGPROT_CMD_THREAD_GET_APPDOMAIN: { + DebuggerTlsData* tls; + mono_loader_lock (); + tls = (DebuggerTlsData*)mono_g_hash_table_lookup (thread_to_tls, thread); + mono_loader_unlock (); + if (tls == NULL) + return ERR_UNLOADED; + if (tls->frame_count <= 0) + return ERR_UNLOADED; + buffer_add_domainid (buf, tls->frames[0]->de.domain); + break; + } default: return ERR_NOT_IMPLEMENTED; } @@ -9436,7 +9494,6 @@ command_set_to_string (CommandSet command_set) } static const char* vm_cmds_str [] = { - "", "VERSION", "ALL_THREADS", "SUSPEND", @@ -9496,6 +9553,7 @@ static const char* assembly_cmds_str[] = { "GET_METHOD_FROM_TOKEN", "HAS_DEBUG_INFO", "GET_CUSTOM_ATTRIBUTES", + "GET_PEIMAGE_ADDRESS" }; static const char* module_cmds_str[] = { diff --git a/src/mono/mono/mini/debugger-mono-compat.h b/src/mono/mono/mini/debugger-mono-compat.h new file mode 100644 index 0000000000000..0492a71f3468c --- /dev/null +++ b/src/mono/mono/mini/debugger-mono-compat.h @@ -0,0 +1,21 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. +// +// File: DEBUGGER-MONO-COMPAT.H +// + +#ifndef __DBG_MONO_MONO_COMPAT_H__ +#define __DBG_MONO_MONO_COMPAT_H__ + +#include +#include + +static +inline +int32_t +dbg_rt_atomic_inc_int32_t (volatile int32_t *value) +{ + return (int32_t)mono_atomic_inc_i32 ((volatile gint32 *)value); +} + +#endif \ No newline at end of file diff --git a/src/mono/mono/mini/debugger-protocol.c b/src/mono/mono/mini/debugger-protocol.c index 07094990d27f1..4495d756cf896 100644 --- a/src/mono/mono/mini/debugger-protocol.c +++ b/src/mono/mono/mini/debugger-protocol.c @@ -1,8 +1,12 @@ #include "debugger-protocol.h" -#include -#include "glib.h" -static int packet_id = 0; +#ifdef DBI_COMPONENT_MONO +#include "debugger-coreclr-compat.h" +#else +#include "debugger-mono-compat.h" +#endif + +static int32_t packet_id = 0; /* * Functions to decode protocol data @@ -10,32 +14,32 @@ static int packet_id = 0; int m_dbgprot_buffer_add_command_header (MdbgProtBuffer *data, int command_set, int command, MdbgProtBuffer *out) { - int id = mono_atomic_inc_i32 (&packet_id); + int id = dbg_rt_atomic_inc_int32_t ((volatile int32_t *)&packet_id); - int len = data->p - data->buf + HEADER_LENGTH; + uint32_t len = (uint32_t)(data->p - data->buf + HEADER_LENGTH); m_dbgprot_buffer_init (out, len); m_dbgprot_buffer_add_int (out, len); m_dbgprot_buffer_add_int (out, id); m_dbgprot_buffer_add_byte (out, 0); /* flags */ m_dbgprot_buffer_add_byte (out, command_set); m_dbgprot_buffer_add_byte (out, command); - m_dbgprot_buffer_add_data (out, data->buf, data->p - data->buf); + m_dbgprot_buffer_add_data (out, data->buf, (uint32_t) (data->p - data->buf)); return id; } void m_dbgprot_decode_command_header (MdbgProtBuffer *recvbuf, MdbgProtHeader *header) { - header->len = m_dbgprot_decode_int (recvbuf->buf, &recvbuf->buf, recvbuf->end); - header->id = m_dbgprot_decode_int (recvbuf->buf, &recvbuf->buf, recvbuf->end); - header->flags = m_dbgprot_decode_byte (recvbuf->buf, &recvbuf->buf, recvbuf->end); + header->len = m_dbgprot_decode_int (recvbuf->p, &recvbuf->p, recvbuf->end); + header->id = m_dbgprot_decode_int (recvbuf->p, &recvbuf->p, recvbuf->end); + header->flags = m_dbgprot_decode_byte (recvbuf->p, &recvbuf->p, recvbuf->end); if (header->flags == REPLY_PACKET) { - header->error = m_dbgprot_decode_byte (recvbuf->buf, &recvbuf->buf, recvbuf->end); - header->error_2 = m_dbgprot_decode_byte (recvbuf->buf, &recvbuf->buf, recvbuf->end); + header->error = m_dbgprot_decode_byte (recvbuf->p, &recvbuf->p, recvbuf->end); + header->error_2 = m_dbgprot_decode_byte (recvbuf->p, &recvbuf->p, recvbuf->end); } else { - header->command_set = m_dbgprot_decode_byte (recvbuf->buf, &recvbuf->buf, recvbuf->end); - header->command = m_dbgprot_decode_byte (recvbuf->buf, &recvbuf->buf, recvbuf->end); + header->command_set = m_dbgprot_decode_byte (recvbuf->p, &recvbuf->p, recvbuf->end); + header->command = m_dbgprot_decode_byte (recvbuf->p, &recvbuf->p, recvbuf->end); } } @@ -96,7 +100,7 @@ m_dbgprot_decode_string (uint8_t *buf, uint8_t **endbuf, uint8_t *limit) } uint8_t* -m_dbgprot_decode_byte_array (uint8_t *buf, uint8_t **endbuf, uint8_t *limit, int *len) +m_dbgprot_decode_byte_array (uint8_t *buf, uint8_t **endbuf, uint8_t *limit, int32_t *len) { *len = m_dbgprot_decode_int (buf, &buf, limit); uint8_t* s; @@ -121,26 +125,26 @@ m_dbgprot_decode_byte_array (uint8_t *buf, uint8_t **endbuf, uint8_t *limit, int */ void -m_dbgprot_buffer_init (MdbgProtBuffer *buf, int size) +m_dbgprot_buffer_init (MdbgProtBuffer *buf, uint32_t size) { buf->buf = (uint8_t *)g_malloc (size); buf->p = buf->buf; buf->end = buf->buf + size; } -int +uint32_t m_dbgprot_buffer_len (MdbgProtBuffer *buf) { - return buf->p - buf->buf; + return (uint32_t)(buf->p - buf->buf); } void -m_dbgprot_buffer_make_room (MdbgProtBuffer *buf, int size) +m_dbgprot_buffer_make_room (MdbgProtBuffer *buf, uint32_t size) { - if (buf->end - buf->p < size) { - int new_size = buf->end - buf->buf + size + 32; + if (((uint32_t)(buf->end - buf->p)) < size) { + size_t new_size = buf->end - buf->buf + size + 32; uint8_t *p = (uint8_t *)g_realloc (buf->buf, new_size); - size = buf->p - buf->buf; + size = (uint32_t) (buf->p - buf->buf); buf->buf = p; buf->p = p + size; buf->end = buf->buf + new_size; @@ -183,13 +187,13 @@ m_dbgprot_buffer_add_long (MdbgProtBuffer *buf, uint64_t l) } void -m_dbgprot_buffer_add_id (MdbgProtBuffer *buf, int id) +m_dbgprot_buffer_add_id (MdbgProtBuffer *buf, uint32_t id) { - m_dbgprot_buffer_add_int (buf, (uint64_t)id); + m_dbgprot_buffer_add_int (buf, id); } void -m_dbgprot_buffer_add_data (MdbgProtBuffer *buf, uint8_t *data, int len) +m_dbgprot_buffer_add_data (MdbgProtBuffer *buf, uint8_t *data, uint32_t len) { m_dbgprot_buffer_make_room (buf, len); memcpy (buf->p, data, len); @@ -197,7 +201,7 @@ m_dbgprot_buffer_add_data (MdbgProtBuffer *buf, uint8_t *data, int len) } void -m_dbgprot_buffer_add_utf16 (MdbgProtBuffer *buf, uint8_t *data, int len) +m_dbgprot_buffer_add_utf16 (MdbgProtBuffer *buf, uint8_t *data, uint32_t len) { #if G_BYTE_ORDER == G_LITTLE_ENDIAN m_dbgprot_buffer_make_room (buf, len); @@ -214,12 +218,12 @@ m_dbgprot_buffer_add_utf16 (MdbgProtBuffer *buf, uint8_t *data, int len) void m_dbgprot_buffer_add_string (MdbgProtBuffer *buf, const char *str) { - int len; + uint32_t len; if (str == NULL) { m_dbgprot_buffer_add_int (buf, 0); } else { - len = strlen (str); + len = (uint32_t) strlen (str); m_dbgprot_buffer_add_int (buf, len); m_dbgprot_buffer_add_data (buf, (uint8_t*)str, len); } @@ -267,7 +271,7 @@ m_dbgprot_event_to_string (MdbgProtEventKind event) case MDBGPROT_EVENT_KIND_USER_LOG: return "USER_LOG"; case MDBGPROT_EVENT_KIND_CRASH: return "CRASH"; default: - g_assert_not_reached (); + g_assert ( 1 ); return ""; } } diff --git a/src/mono/mono/mini/debugger-protocol.h b/src/mono/mono/mini/debugger-protocol.h index 07dafdf1824c3..2067874d105dc 100644 --- a/src/mono/mono/mini/debugger-protocol.h +++ b/src/mono/mono/mini/debugger-protocol.h @@ -32,7 +32,10 @@ typedef enum { MDBGPROT_CMD_VM_GET_TYPES = 12, MDBGPROT_CMD_VM_INVOKE_METHODS = 13, MDBGPROT_CMD_VM_START_BUFFERING = 14, - MDBGPROT_CMD_VM_STOP_BUFFERING = 15 + MDBGPROT_CMD_VM_STOP_BUFFERING = 15, + MDBGPROT_CMD_VM_READ_MEMORY = 16, + MDBGPROT_CMD_VM_WRITE_MEMORY = 17, + MDBGPROT_CMD_VM_SET_USING_ICORDBG = 18 } MdbgProtCmdVM; typedef enum { @@ -109,7 +112,8 @@ typedef enum { MDBGPROT_CMD_THREAD_GET_ID = 5, MDBGPROT_CMD_THREAD_GET_TID = 6, MDBGPROT_CMD_THREAD_SET_IP = 7, - MDBGPROT_CMD_THREAD_ELAPSED_TIME = 8 + MDBGPROT_CMD_THREAD_ELAPSED_TIME = 8, + MDBGPROT_CMD_THREAD_GET_APPDOMAIN = 9 } MdbgProtCmdThread; typedef enum { @@ -138,7 +142,8 @@ typedef enum { MDBGPROT_CMD_ASSEMBLY_GET_METHOD_FROM_TOKEN = 12, MDBGPROT_CMD_ASSEMBLY_HAS_DEBUG_INFO = 13, MDBGPROT_CMD_ASSEMBLY_GET_CATTRS = 14, - MDBGPROT_CMD_ASSEMBLY_GET_CUSTOM_ATTRIBUTES = 15 + MDBGPROT_CMD_ASSEMBLY_GET_CUSTOM_ATTRIBUTES = 15, + MDBGPROT_CMD_ASSEMBLY_GET_PEIMAGE_ADDRESS = 16, } MdbgProtCmdAssembly; typedef enum { @@ -341,22 +346,22 @@ int m_dbgprot_decode_int (uint8_t *buf, uint8_t **endbuf, uint8_t *limit); int64_t m_dbgprot_decode_long (uint8_t *buf, uint8_t **endbuf, uint8_t *limit); int m_dbgprot_decode_id (uint8_t *buf, uint8_t **endbuf, uint8_t *limit); char* m_dbgprot_decode_string (uint8_t *buf, uint8_t **endbuf, uint8_t *limit); -uint8_t* m_dbgprot_decode_byte_array(uint8_t *buf, uint8_t **endbuf, uint8_t *limit, int *len); +uint8_t* m_dbgprot_decode_byte_array(uint8_t *buf, uint8_t **endbuf, uint8_t *limit, int32_t *len); /* * Functions to encode protocol data */ -void m_dbgprot_buffer_init (MdbgProtBuffer *buf, int size); -int m_dbgprot_buffer_len (MdbgProtBuffer *buf); -void m_dbgprot_buffer_make_room (MdbgProtBuffer *buf, int size); +void m_dbgprot_buffer_init (MdbgProtBuffer *buf, uint32_t size); +uint32_t m_dbgprot_buffer_len (MdbgProtBuffer *buf); +void m_dbgprot_buffer_make_room (MdbgProtBuffer *buf, uint32_t size); void m_dbgprot_buffer_add_byte (MdbgProtBuffer *buf, uint8_t val); void m_dbgprot_buffer_add_short (MdbgProtBuffer *buf, uint32_t val); void m_dbgprot_buffer_add_int (MdbgProtBuffer *buf, uint32_t val); void m_dbgprot_buffer_add_long (MdbgProtBuffer *buf, uint64_t l); -void m_dbgprot_buffer_add_id (MdbgProtBuffer *buf, int id); -void m_dbgprot_buffer_add_data (MdbgProtBuffer *buf, uint8_t *data, int len); -void m_dbgprot_buffer_add_utf16 (MdbgProtBuffer *buf, uint8_t *data, int len); +void m_dbgprot_buffer_add_id (MdbgProtBuffer *buf, uint32_t id); +void m_dbgprot_buffer_add_data (MdbgProtBuffer *buf, uint8_t *data, uint32_t len); +void m_dbgprot_buffer_add_utf16 (MdbgProtBuffer *buf, uint8_t *data, uint32_t len); void m_dbgprot_buffer_add_string (MdbgProtBuffer *buf, const char *str); void m_dbgprot_buffer_add_byte_array (MdbgProtBuffer *buf, uint8_t *bytes, uint32_t arr_len); void m_dbgprot_buffer_add_buffer (MdbgProtBuffer *buf, MdbgProtBuffer *data); diff --git a/src/mono/mono/mini/mini-amd64.c b/src/mono/mono/mini/mini-amd64.c index fb59cfccf536e..95814172ee6f8 100644 --- a/src/mono/mono/mini/mini-amd64.c +++ b/src/mono/mono/mini/mini-amd64.c @@ -8886,6 +8886,12 @@ mono_arch_context_get_int_reg (MonoContext *ctx, int reg) return ctx->gregs [reg]; } +host_mgreg_t * +mono_arch_context_get_int_reg_address (MonoContext *ctx, int reg) +{ + return &ctx->gregs [reg]; +} + void mono_arch_context_set_int_reg (MonoContext *ctx, int reg, host_mgreg_t val) { diff --git a/src/mono/mono/mini/mini-arm.c b/src/mono/mono/mini/mini-arm.c index 1657f76c96972..e0e183467e029 100644 --- a/src/mono/mono/mini/mini-arm.c +++ b/src/mono/mono/mini/mini-arm.c @@ -7169,6 +7169,12 @@ mono_arch_context_get_int_reg (MonoContext *ctx, int reg) return ctx->regs [reg]; } +host_mgreg_t* +mono_arch_context_get_int_reg_address (MonoContext *ctx, int reg) +{ + return &ctx->regs [reg]; +} + void mono_arch_context_set_int_reg (MonoContext *ctx, int reg, host_mgreg_t val) { diff --git a/src/mono/mono/mini/mini-arm64.c b/src/mono/mono/mini/mini-arm64.c index 34efcadd83dc1..4037c28778af3 100644 --- a/src/mono/mono/mini/mini-arm64.c +++ b/src/mono/mono/mini/mini-arm64.c @@ -1058,6 +1058,12 @@ mono_arch_context_get_int_reg (MonoContext *ctx, int reg) return ctx->regs [reg]; } +host_mgreg_t* +mono_arch_context_get_int_reg_address (MonoContext *ctx, int reg) +{ + return &ctx->regs [reg]; +} + void mono_arch_context_set_int_reg (MonoContext *ctx, int reg, host_mgreg_t val) { diff --git a/src/mono/mono/mini/mini-mips.c b/src/mono/mono/mini/mini-mips.c index 073ae1bc56b63..9a353ce85fa1e 100644 --- a/src/mono/mono/mini/mini-mips.c +++ b/src/mono/mono/mini/mini-mips.c @@ -5276,6 +5276,12 @@ mono_arch_context_get_int_reg (MonoContext *ctx, int reg) return ctx->sc_regs [reg]; } +host_mgreg_t* +mono_arch_context_get_int_reg_address (MonoContext *ctx, int reg) +{ + return &ctx->sc_regs [reg]; +} + #define ENABLE_WRONG_METHOD_CHECK 0 #define MIPS_LOAD_SEQUENCE_LENGTH 8 diff --git a/src/mono/mono/mini/mini-ppc.c b/src/mono/mono/mini/mini-ppc.c index 0294d166993bc..c7f4c04a241fb 100644 --- a/src/mono/mono/mini/mini-ppc.c +++ b/src/mono/mono/mini/mini-ppc.c @@ -5755,6 +5755,15 @@ mono_arch_context_get_int_reg (MonoContext *ctx, int reg) return ctx->regs [reg]; } +host_mgreg_t* +mono_arch_context_get_int_reg_address (MonoContext *ctx, int reg) +{ + if (reg == ppc_r1) + return (host_mgreg_t)(gsize)&MONO_CONTEXT_GET_SP (ctx); + + return &ctx->regs [reg]; +} + guint32 mono_arch_get_patch_offset (guint8 *code) { diff --git a/src/mono/mono/mini/mini-riscv.c b/src/mono/mono/mini/mini-riscv.c index bb5a82af1aef4..bbe02621eb94b 100644 --- a/src/mono/mono/mini/mini-riscv.c +++ b/src/mono/mono/mini/mini-riscv.c @@ -248,6 +248,12 @@ mono_arch_context_get_int_reg (MonoContext *ctx, int reg) return ctx->gregs [reg]; } +host_mgreg_t* +mono_arch_context_get_int_reg_address (MonoContext *ctx, int reg) +{ + return &ctx->gregs [reg]; +} + void mono_arch_context_set_int_reg (MonoContext *ctx, int reg, host_mgreg_t val) { diff --git a/src/mono/mono/mini/mini-s390x.c b/src/mono/mono/mini/mini-s390x.c index 02ebf6d72baf7..835e9486ae220 100644 --- a/src/mono/mono/mini/mini-s390x.c +++ b/src/mono/mono/mini/mini-s390x.c @@ -6182,6 +6182,12 @@ mono_arch_context_get_int_reg (MonoContext *ctx, int reg) return ctx->uc_mcontext.gregs[reg]; } +host_mgreg_t* +mono_arch_context_get_int_reg_address (MonoContext *ctx, int reg) +{ + return &ctx->uc_mcontext.gregs[reg]; +} + /*========================= End of Function ========================*/ /** diff --git a/src/mono/mono/mini/mini-sparc.c b/src/mono/mono/mini/mini-sparc.c index decdcbc09cf65..448f150c5505b 100644 --- a/src/mono/mono/mini/mini-sparc.c +++ b/src/mono/mono/mini/mini-sparc.c @@ -4386,6 +4386,13 @@ mono_arch_context_get_int_reg (MonoContext *ctx, int reg) g_assert_not_reached (); } +host_mgreg_t* +mono_arch_context_get_int_reg_address (MonoContext *ctx, int reg) +{ + /* FIXME: implement */ + g_assert_not_reached (); +} + gboolean mono_arch_opcode_supported (int opcode) { diff --git a/src/mono/mono/mini/mini-wasm.c b/src/mono/mono/mini/mini-wasm.c index b87b6caf99069..35c75008a4441 100644 --- a/src/mono/mono/mini/mini-wasm.c +++ b/src/mono/mono/mini/mini-wasm.c @@ -487,6 +487,13 @@ mono_arch_context_get_int_reg (MonoContext *ctx, int reg) return 0; } +host_mgreg_t* +mono_arch_context_get_int_reg_address (MonoContext *ctx, int reg) +{ + g_error ("mono_arch_context_get_int_reg_address"); + return 0; +} + #ifdef HOST_WASM void diff --git a/src/mono/mono/mini/mini-x86.c b/src/mono/mono/mini/mini-x86.c index 13089cca75d61..cbe316bf683d6 100644 --- a/src/mono/mono/mini/mini-x86.c +++ b/src/mono/mono/mini/mini-x86.c @@ -6075,6 +6075,24 @@ mono_arch_context_get_int_reg (MonoContext *ctx, int reg) } } +host_mgreg_t* +mono_arch_context_get_int_reg_address (MonoContext *ctx, int reg) +{ + switch (reg) { + case X86_EAX: return &ctx->eax; + case X86_EBX: return &ctx->ebx; + case X86_ECX: return &ctx->ecx; + case X86_EDX: return &ctx->edx; + case X86_ESP: return &ctx->esp; + case X86_EBP: return &ctx->ebp; + case X86_ESI: return &ctx->esi; + case X86_EDI: return &ctx->edi; + default: + g_assert_not_reached (); + return 0; + } +} + void mono_arch_context_set_int_reg (MonoContext *ctx, int reg, host_mgreg_t val) { diff --git a/src/mono/mono/mini/mini.h b/src/mono/mono/mini/mini.h index 6d2f0fcf819ae..a0d723545783c 100644 --- a/src/mono/mono/mini/mini.h +++ b/src/mono/mono/mini/mini.h @@ -2445,6 +2445,7 @@ void mono_arch_undo_ip_adjustment (MonoContext *ctx); void mono_arch_do_ip_adjustment (MonoContext *ctx); gpointer mono_arch_ip_from_context (void *sigctx); host_mgreg_t mono_arch_context_get_int_reg (MonoContext *ctx, int reg); +host_mgreg_t*mono_arch_context_get_int_reg_address (MonoContext *ctx, int reg); void mono_arch_context_set_int_reg (MonoContext *ctx, int reg, host_mgreg_t val); void mono_arch_flush_register_windows (void); gboolean mono_arch_is_inst_imm (int opcode, int imm_opcode, gint64 imm);