Implement ICorDebugILFrame3::GetReturnValueForILOffset on arm32 (dotnet/coreclr...
authorChris Sienkiewicz <chsienki@microsoft.com>
Mon, 21 May 2018 19:24:06 +0000 (12:24 -0700)
committerGitHub <noreply@github.com>
Mon, 21 May 2018 19:24:06 +0000 (12:24 -0700)
*Implements CorDebugILFrame3::GetReturnValueForILOffset for arm32 on both windows and linux
*Fixes CordbNativeCode::GetCallInstructionLength to ensure it accounts for both 32/16 bit instructions
*Adds some asm to do float conversion
*Adds some logic to the cmake files to ensure the respective asm files get assembled correctly for both platforms

Commit migrated from https://github.com/dotnet/coreclr/commit/78d858b048b460bd399d537487949f74c708e159

src/coreclr/src/debug/di/CMakeLists.txt
src/coreclr/src/debug/di/arm/floatconversion.S [new file with mode: 0644]
src/coreclr/src/debug/di/arm/floatconversion.asm [new file with mode: 0644]
src/coreclr/src/debug/di/module.cpp
src/coreclr/src/debug/di/rspriv.h
src/coreclr/src/debug/di/rsthread.cpp
src/coreclr/src/debug/di/valuehome.cpp
src/coreclr/src/debug/inc/arm/primitives.h
src/coreclr/src/debug/inc/dbgtargetcontext.h
src/coreclr/src/pal/prebuilt/inc/cordebug.h

index abede90d2e7896ff0688a0f35d5fc6402b4fa27a..f286c58d93d97b2e105984c397565704b8adf413 100644 (file)
@@ -34,7 +34,7 @@ if(WIN32)
     #use static crt
     add_definitions(-MT) 
 
-    if (CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64)
+    if (CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM64 OR CLR_CMAKE_TARGET_ARCH_ARM)
         set(CORDBDI_SOURCES_ASM_FILE ${ARCH_SOURCES_DIR}/floatconversion.asm)
     endif()
     if (CLR_CMAKE_TARGET_ARCH_AMD64)
@@ -58,11 +58,42 @@ if(WIN32)
               ${CORDBDI_SOURCES}
               ${CORDBDI_SOURCES_WKS_PREPROCESSED_ASM}
             )
+    elseif (CLR_CMAKE_TARGET_ARCH_ARM AND NOT DEFINED CLR_CROSS_COMPONENTS_BUILD)
+          convert_to_absolute_path(CORDBDI_SOURCES_ASM_FILE ${CORDBDI_SOURCES_ASM_FILE})  
+      
+          # Inserts a custom command in CMake build to preprocess each asm source file
+          get_filename_component(name ${CORDBDI_SOURCES_ASM_FILE} NAME_WE)
+          file(TO_CMAKE_PATH "${CMAKE_CURRENT_BINARY_DIR}/${name}.asm" ASM_PREPROCESSED_FILE)
+          preprocess_def_file(${CORDBDI_SOURCES_ASM_FILE} ${ASM_PREPROCESSED_FILE})
+
+          # On Arm32, compile the preprocessed binary to .obj
+          # We do not pass any defines since we have already done pre-processing above
+          set (ASM_CMDLINE "-o ${CMAKE_CURRENT_BINARY_DIR}/${name}.obj ${ASM_PREPROCESSED_FILE}")
+
+          # Generate the batch file that will invoke the assembler
+          file(TO_CMAKE_PATH "${CMAKE_CURRENT_BINARY_DIR}/runasm_${name}_${CMAKE_BUILD_TYPE}.cmd" ASM_SCRIPT_FILE)
+
+          file(GENERATE OUTPUT "${ASM_SCRIPT_FILE}"
+                    CONTENT "\"${CMAKE_ASM_MASM_COMPILER}\" -g ${ASM_INCLUDE_DIRECTORIES} ${ASM_DEFINITIONS} ${ASM_CMDLINE}")
+
+          message("Generated  - ${ASM_SCRIPT_FILE}")
+
+          # Need to compile asm file using custom command as include directories are not provided to asm compiler
+          add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${name}.obj
+                             COMMAND ${ASM_SCRIPT_FILE}
+                             DEPENDS ${ASM_PREPROCESSED_FILE}
+                             COMMENT "Assembling ${ASM_PREPROCESSED_FILE} - ${ASM_SCRIPT_FILE}")
+
+          # mark obj as source that does not require compile
+          set_source_files_properties(${CMAKE_CURRENT_BINARY_DIR}/${name}.obj PROPERTIES EXTERNAL_OBJECT TRUE)
+
+          # Add the generated OBJ in the dependency list so that it gets consumed during linkage
+          set(CORDBDI_SOURCES ${CORDBDI_SOURCES} ${CMAKE_CURRENT_BINARY_DIR}/${name}.obj)
     endif()
 elseif(CLR_CMAKE_PLATFORM_UNIX)
     add_compile_options(-fPIC)
 
-    if(CLR_CMAKE_TARGET_ARCH_AMD64)
+    if(CLR_CMAKE_TARGET_ARCH_AMD64 OR CLR_CMAKE_TARGET_ARCH_ARM)
       set(CORDBDI_SOURCES
         ${CORDBDI_SOURCES}
         ${ARCH_SOURCES_DIR}/floatconversion.S
diff --git a/src/coreclr/src/debug/di/arm/floatconversion.S b/src/coreclr/src/debug/di/arm/floatconversion.S
new file mode 100644 (file)
index 0000000..f963593
--- /dev/null
@@ -0,0 +1,15 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+// See the LICENSE file in the project root for more information.
+
+#include <unixasmmacros.inc>
+
+// Arguments
+//     input: (in R0) the adress of the ULONGLONG to be converted to a double
+//     output: the double corresponding to the ULONGLONG input value
+
+LEAF_ENTRY FPFillR8, .TEXT
+        .thumb
+        vldr  D0, [R0]
+        bx   lr  
+LEAF_END FPFillR8, .TEXT
\ No newline at end of file
diff --git a/src/coreclr/src/debug/di/arm/floatconversion.asm b/src/coreclr/src/debug/di/arm/floatconversion.asm
new file mode 100644 (file)
index 0000000..6ed2402
--- /dev/null
@@ -0,0 +1,23 @@
+; Licensed to the .NET Foundation under one or more agreements.
+; The .NET Foundation licenses this file to you under the MIT license.
+; See the LICENSE file in the project root for more information.
+
+;; ==++==
+;;
+
+;;
+;; ==--==
+#include "ksarm.h"
+
+;; Arguments
+;;     input: (in R0) the adress of the ULONGLONG to be converted to a double
+;;     output: the double corresponding to the ULONGLONG input value
+
+    LEAF_ENTRY FPFillR8
+        vldr  D0, [R0]
+        bx   lr  
+    LEAF_END
+
+
+;; Must be at very end of file
+    END
index b0ba054a87f30af1a0dcfdf5922242a8708b9db0..814f0019ced878b2b8d3bc21ad2bd5d126915b12 100644 (file)
@@ -4522,7 +4522,10 @@ HRESULT CordbNativeCode::EnumerateVariableHomes(ICorDebugVariableHomeEnum **ppEn
 int CordbNativeCode::GetCallInstructionLength(BYTE *ip, ULONG32 count)
 {
 #if defined(DBG_TARGET_ARM)
-    return MAX_INSTRUCTION_LENGTH;
+    if (Is32BitInstruction(*(WORD*)ip))
+        return 4;
+    else
+        return 2;
 #elif defined(DBG_TARGET_ARM64)
     return MAX_INSTRUCTION_LENGTH;
 #elif defined(DBG_TARGET_X86)
index 5d5432f5586863f756aa6b311b732a0533cfe60a..a9e525fa89646cea929f622d6c05ba5f7508abb2 100644 (file)
@@ -6135,22 +6135,21 @@ public:
     void CleanupStack();
     void MarkStackFramesDirty();
 
-#if !defined(DBG_TARGET_ARM) // @ARMTODO
 
 #if defined(DBG_TARGET_X86)
     // Converts the values in the floating point register area of the context to real number values.
     void Get32bitFPRegisters(CONTEXT * pContext);
 
-#elif defined(DBG_TARGET_AMD64) ||  defined(DBG_TARGET_ARM64)
+#elif defined(DBG_TARGET_AMD64) ||  defined(DBG_TARGET_ARM64) || defined(DBG_TARGET_ARM)
     // Converts the values in the floating point register area of the context to real number values.
     void Get64bitFPRegisters(FPRegister64 * rgContextFPRegisters, int start, int nRegisters);
+
 #endif // DBG_TARGET_X86
 
    // Initializes the float state members of this instance of CordbThread. This function gets the context and
    // converts the floating point values from their context representation to real number values.    
    void LoadFloatState();
 
-#endif //!DBG_TARGET_ARM @ARMTODO
 
     HRESULT SetIP(  bool fCanSetIPOnly,
                     CordbNativeCode * pNativeCode,
@@ -6298,11 +6297,9 @@ public:
     //  Instead, we mark m_fFramesFresh in CleanupStack() and clear the cache only when it is used next time.
     CDynArray<CordbFrame *> m_stackFrames;
 
-#if !defined(DBG_TARGET_ARM) // @ARMTODO
     bool                  m_fFloatStateValid;
     unsigned int          m_floatStackTop;
     double                m_floatValues[DebuggerIPCE_FloatCount];
-#endif // !DBG_TARGET_ARM @ARMTODO
 
 private:
     // True for the window after an Exception callback, but before it's been continued.
@@ -7106,11 +7103,9 @@ public:
                                            ICorDebugValue **ppValue);
     UINT_PTR * GetAddressOfRegister(CorDebugRegister regNum) const;
     CORDB_ADDRESS GetLeftSideAddressOfRegister(CorDebugRegister regNum) const;
-#if !defined(DBG_TARGET_ARM) // @ARMTODO
     HRESULT GetLocalFloatingPointValue(DWORD index,
                                             CordbType * pType,
                                             ICorDebugValue **ppValue);
-#endif // !DBG_TARGET_ARM @ARMTODO
 
 
     CORDB_ADDRESS GetLSStackAddress(ICorDebugInfo::RegNum regNum, signed offset);
index 07850faaffeaec64436af259dae4a35388f53945..81f632bf5979e8b233146882a4ef78495f25691a 100644 (file)
@@ -79,10 +79,8 @@ CordbThread::CordbThread(CordbProcess * pProcess, VMPTR_Thread vmThread) :
     m_pAppDomain(NULL),
     m_debugState(THREAD_RUN),
     m_fFramesFresh(false),
-#if !defined(DBG_TARGET_ARM) // @ARMTODO
     m_fFloatStateValid(false), 
     m_floatStackTop(0),
-#endif // !DBG_TARGET_ARM @ARMTODO
     m_fException(false),
     m_fCreationEventQueued(false),
     m_EnCRemapFunctionIP(NULL),
@@ -109,7 +107,7 @@ CordbThread::CordbThread(CordbProcess * pProcess, VMPTR_Thread vmThread) :
     m_vmLeftSideContext = VMPTR_CONTEXT::NullPtr();
     m_vmExcepObjHandle = VMPTR_OBJECTHANDLE::NullPtr();
 
-#if defined(_DEBUG) && !defined(DBG_TARGET_ARM) // @ARMTODO
+#if defined(_DEBUG)
     for (unsigned int i = 0;
          i < (sizeof(m_floatValues) / sizeof(m_floatValues[0]));
          i++)
@@ -1328,10 +1326,8 @@ void CordbThread::MarkStackFramesDirty()
 
     _ASSERTE(GetProcess()->ThreadHoldsProcessLock());
 
-#if !defined(DBG_TARGET_ARM) // @ARMTODO
     // invalidate the cached floating point state
     m_fFloatStateValid = false;
-#endif // !defined(DBG_TARGET_ARM) @ARMTODO
 
     // This flag is only true between the window when we get an exception callback and 
     // when we call continue.  Since this function is only called when we continue, we 
@@ -1433,15 +1429,14 @@ HRESULT CordbThread::FindFrame(ICorDebugFrame ** ppFrame, FramePointer fp)
 }
 
 
-#if !defined(DBG_TARGET_ARM) // @ARMTODO
 
-#if defined(CROSS_COMPILE) && defined(_TARGET_ARM64_)
+#if defined(CROSS_COMPILE) && (defined(_TARGET_ARM64_) || defined(_TARGET_ARM_))
 extern "C" double FPFillR8(void* pFillSlot)
 {
     _ASSERTE(!"nyi for platform");
     return 0;
 }
-#elif defined(_TARGET_AMD64_) || defined(_TARGET_ARM64_) 
+#elif defined(_TARGET_AMD64_) || defined(_TARGET_ARM64_) || defined(_TARGET_ARM_)
 extern "C" double FPFillR8(void* pFillSlot);
 #endif
 
@@ -1536,7 +1531,7 @@ void CordbThread::Get32bitFPRegisters(CONTEXT * pContext)
     m_floatStackTop = floatStackTop;
 } // CordbThread::Get32bitFPRegisters
 
-#elif defined(_TARGET_AMD64_) || defined(_TARGET_ARM64_)
+#elif defined(_TARGET_AMD64_) || defined(_TARGET_ARM64_) || defined(_TARGET_ARM_)
 
 // CordbThread::Get64bitFPRegisters
 // Converts the values in the floating point register area of the context to real number values. See
@@ -1596,6 +1591,8 @@ void CordbThread::LoadFloatState()
     Get64bitFPRegisters((FPRegister64*) &(tempContext.Xmm0), 0, 16);
 #elif defined(_TARGET_ARM64_)
     Get64bitFPRegisters((FPRegister64*) &(tempContext.V), 0, 32);
+#elif defined (_TARGET_ARM_)
+    Get64bitFPRegisters((FPRegister64*) &(tempContext.D), 0, 32);
 #else 
     _ASSERTE(!"nyi for platform");
 #endif // !_TARGET_X86_
@@ -1603,7 +1600,6 @@ void CordbThread::LoadFloatState()
     m_fFloatStateValid = true;
 } // CordbThread::LoadFloatState
 
-#endif // !DBG_TARGET_ARM @ARMTODO
 
 const bool SetIP_fCanSetIPOnly = TRUE;
 const bool SetIP_fSetIP = FALSE;
@@ -7058,7 +7054,6 @@ CordbNativeFrame::GetLocalMemoryRegisterValue(CORDB_ADDRESS highWordAddress,
     return hr;
 }
 
-#if !defined(DBG_TARGET_ARM) // @ARMTODO
 HRESULT CordbNativeFrame::GetLocalFloatingPointValue(DWORD index,
                                                      CordbType * pType,
                                                      ICorDebugValue **ppValue)
@@ -7083,6 +7078,11 @@ HRESULT CordbNativeFrame::GetLocalFloatingPointValue(DWORD index,
         (index <= REGISTER_ARM64_V31)))
         return E_INVALIDARG;
     index -= REGISTER_ARM64_V0;
+#elif defined(DBG_TARGET_ARM)
+    if (!((index >= REGISTER_ARM_D0) &&
+        (index <= REGISTER_ARM_D31)))
+        return E_INVALIDARG;
+    index -= REGISTER_ARM_D0;
 #else
     if (!((index >= REGISTER_X86_FPSTACK_0) &&
           (index <= REGISTER_X86_FPSTACK_7)))
@@ -7150,7 +7150,6 @@ HRESULT CordbNativeFrame::GetLocalFloatingPointValue(DWORD index,
 
     return hr;
 }
-#endif // !DBG_TARGET_ARM @ARMTODO
 
 //---------------------------------------------------------------------------------------
 //
@@ -8790,9 +8789,6 @@ HRESULT CordbJITILFrame::GetReturnValueForILOffsetImpl(ULONG32 ILoffset, ICorDeb
 
 HRESULT CordbJITILFrame::GetReturnValueForType(CordbType *pType, ICorDebugValue **ppReturnValue)
 {
-#if defined(DBG_TARGET_ARM) 
-    return E_NOTIMPL;
-#else
 
 
 #if defined(DBG_TARGET_X86)
@@ -8801,14 +8797,21 @@ HRESULT CordbJITILFrame::GetReturnValueForType(CordbType *pType, ICorDebugValue
     const CorDebugRegister floatRegister = REGISTER_AMD64_XMM0;
 #elif  defined(DBG_TARGET_ARM64)
     const CorDebugRegister floatRegister = REGISTER_ARM64_V0;
+#elif  defined(DBG_TARGET_ARM)
+    const CorDebugRegister floatRegister = REGISTER_ARM_D0;
 #endif
     
 #if defined(DBG_TARGET_X86)
     const CorDebugRegister ptrRegister = REGISTER_X86_EAX;
+    const CorDebugRegister ptrHighWordRegister = REGISTER_X86_EDX;
 #elif defined(DBG_TARGET_AMD64)
     const CorDebugRegister ptrRegister = REGISTER_AMD64_RAX;
 #elif  defined(DBG_TARGET_ARM64)
     const CorDebugRegister ptrRegister = REGISTER_ARM64_X0;
+#elif  defined(DBG_TARGET_ARM)
+    const CorDebugRegister ptrRegister = REGISTER_ARM_R0;
+    const CorDebugRegister ptrHighWordRegister = REGISTER_ARM_R1;
+
 #endif
 
     CorElementType corReturnType = pType->GetElementType();
@@ -8820,14 +8823,13 @@ HRESULT CordbJITILFrame::GetReturnValueForType(CordbType *pType, ICorDebugValue
     case ELEMENT_TYPE_R4:
     case ELEMENT_TYPE_R8:
         return m_nativeFrame->GetLocalFloatingPointValue(floatRegister, pType, ppReturnValue);
-  
-#ifdef DBG_TARGET_X86
+
+#if defined(DBG_TARGET_X86) || defined(DBG_TARGET_ARM)
     case ELEMENT_TYPE_I8:
     case ELEMENT_TYPE_U8:
-        return m_nativeFrame->GetLocalDoubleRegisterValue(REGISTER_X86_EDX, REGISTER_X86_EAX, pType, ppReturnValue);
+        return m_nativeFrame->GetLocalDoubleRegisterValue(ptrHighWordRegister, ptrRegister, pType, ppReturnValue);
 #endif
     }
-#endif
 }
 
 HRESULT CordbJITILFrame::EnumerateLocalVariablesEx(ILCodeKind flags, ICorDebugValueEnum **ppValueEnum)
index 6cae8c1f3a8457f503dd03f26312bdf1a988e2bb..24af04fcc86abd9257dfafb7b6ef7a2921ca0ff5 100644 (file)
@@ -430,7 +430,6 @@ void MemRegValueHome::GetEnregisteredValue(MemoryRange valueOutBuffer)
 
 } // MemRegValueHome::GetEnregisteredValue
 
-#if !defined(DBG_TARGET_ARM) // @ARMTODO
 
 // ----------------------------------------------------------------------------
 // FloatRegValueHome member function implementations
@@ -581,7 +580,6 @@ void FloatRegValueHome::GetEnregisteredValue(MemoryRange valueOutBuffer)
     ThrowHR(E_NOTIMPL);
 } // FloatRegValueHome::GetEnregisteredValue
 
-#endif // !DBG_TARGET_ARM @ARMTODO
 
 // ============================================================================
 // RemoteValueHome implementation
index 1cceeffeab424963e4477f3a6383e69bbe4cb4cd..512baf788461eb27ae555e8a1797e52dffb5dc18 100644 (file)
@@ -17,6 +17,7 @@
 #define THUMB_CODE 1
 #endif
 
+typedef ULONGLONG                   FPRegister64;
 typedef const BYTE                  CORDB_ADDRESS_TYPE;
 typedef DPTR(CORDB_ADDRESS_TYPE)    PTR_CORDB_ADDRESS_TYPE;
 
index c2b45ee059227a30dca06282027a8dfd1f9c910d..884a583c466ca3dc086e35f220e39873fd443740 100644 (file)
@@ -344,7 +344,7 @@ typedef DECLSPEC_ALIGN(8) struct {
         DT_NEON128 Q[16];
         ULONGLONG D[32];
         DWORD S[32];
-    } DUMMYUNIONNAME;
+    };
 
     //
     // Debug registers
index e45964ae9d2c54cac1ff1e5c24d5d1cad6ef8889..b3ebe7e05fc6d6ee827e154ac42d5139a6f1915d 100644 (file)
@@ -8643,6 +8643,38 @@ enum CorDebugRegister
         REGISTER_ARM_R11       = ( REGISTER_ARM_R10 + 1 ) ,
         REGISTER_ARM_R12       = ( REGISTER_ARM_R11 + 1 ) ,
         REGISTER_ARM_LR        = ( REGISTER_ARM_R12 + 1 ) ,
+        REGISTER_ARM_D0        = ( REGISTER_ARM_LR + 1 ) ,
+        REGISTER_ARM_D1        = ( REGISTER_ARM_D0 + 1 ) ,
+        REGISTER_ARM_D2        = ( REGISTER_ARM_D1 + 1 ) ,
+        REGISTER_ARM_D3        = ( REGISTER_ARM_D2 + 1 ) ,
+        REGISTER_ARM_D4        = ( REGISTER_ARM_D3 + 1 ) ,
+        REGISTER_ARM_D5        = ( REGISTER_ARM_D4 + 1 ) ,
+        REGISTER_ARM_D6        = ( REGISTER_ARM_D5 + 1 ) ,
+        REGISTER_ARM_D7        = ( REGISTER_ARM_D6 + 1 ) ,
+        REGISTER_ARM_D8        = ( REGISTER_ARM_D7 + 1 ) ,
+        REGISTER_ARM_D9        = ( REGISTER_ARM_D8 + 1 ) ,
+        REGISTER_ARM_D10       = ( REGISTER_ARM_D9 + 1 ) ,
+        REGISTER_ARM_D11       = ( REGISTER_ARM_D10 + 1 ) ,
+        REGISTER_ARM_D12       = ( REGISTER_ARM_D11 + 1 ) ,
+        REGISTER_ARM_D13       = ( REGISTER_ARM_D12 + 1 ) ,
+        REGISTER_ARM_D14       = ( REGISTER_ARM_D13 + 1 ) ,
+        REGISTER_ARM_D15       = ( REGISTER_ARM_D14 + 1 ) ,
+        REGISTER_ARM_D16       = ( REGISTER_ARM_D15 + 1 ) ,
+        REGISTER_ARM_D17       = ( REGISTER_ARM_D16 + 1 ) ,
+        REGISTER_ARM_D18       = ( REGISTER_ARM_D17 + 1 ) ,
+        REGISTER_ARM_D19       = ( REGISTER_ARM_D18 + 1 ) ,
+        REGISTER_ARM_D20       = ( REGISTER_ARM_D19 + 1 ) ,
+        REGISTER_ARM_D21       = ( REGISTER_ARM_D20 + 1 ) ,
+        REGISTER_ARM_D22       = ( REGISTER_ARM_D21 + 1 ) ,
+        REGISTER_ARM_D23       = ( REGISTER_ARM_D22 + 1 ) ,
+        REGISTER_ARM_D24       = ( REGISTER_ARM_D23 + 1 ) ,
+        REGISTER_ARM_D25       = ( REGISTER_ARM_D24 + 1 ) ,
+        REGISTER_ARM_D26       = ( REGISTER_ARM_D25 + 1 ) ,
+        REGISTER_ARM_D27       = ( REGISTER_ARM_D26 + 1 ) ,
+        REGISTER_ARM_D28       = ( REGISTER_ARM_D27 + 1 ) ,
+        REGISTER_ARM_D29       = ( REGISTER_ARM_D28 + 1 ) ,
+        REGISTER_ARM_D30       = ( REGISTER_ARM_D29 + 1 ) ,
+        REGISTER_ARM_D31       = ( REGISTER_ARM_D30 + 1 ) ,
         REGISTER_ARM64_PC      = 0,
         REGISTER_ARM64_SP      = ( REGISTER_ARM64_PC + 1 ) ,
         REGISTER_ARM64_FP      = ( REGISTER_ARM64_SP + 1 ) ,