From d2d4a792e306097a7c7e8afd954eeb50f2d2f23e Mon Sep 17 00:00:00 2001 From: Jan Vorlicek Date: Fri, 13 Jan 2017 23:11:54 +0100 Subject: [PATCH] Fixes to make runtime work on ARM64 Linux (#8947) This is a result of attempt to bring up CoreCLR on ARM64 Android. The bring up is on hold now, but I want to check in the changes that added ARM64 asm helpers and fixed general Linux ARM64 issues. --- .../hosts/unixcoreruncommon/coreruncommon.cpp | 2 +- src/debug/ee/arm64/dbghelpers.S | 25 ++++++ src/debug/ee/wks/CMakeLists.txt | 2 +- src/pal/inc/unixasmmacrosarm64.inc | 3 +- src/vm/appdomain.cpp | 2 + src/vm/arm64/asmhelpers.S | 89 +++++++++++++++++++--- src/vm/arm64/crthelpers.S | 4 +- 7 files changed, 110 insertions(+), 17 deletions(-) create mode 100644 src/debug/ee/arm64/dbghelpers.S diff --git a/src/coreclr/hosts/unixcoreruncommon/coreruncommon.cpp b/src/coreclr/hosts/unixcoreruncommon/coreruncommon.cpp index 723711e..5ac7654 100644 --- a/src/coreclr/hosts/unixcoreruncommon/coreruncommon.cpp +++ b/src/coreclr/hosts/unixcoreruncommon/coreruncommon.cpp @@ -447,7 +447,7 @@ int ExecuteManagedAssembly( } else { - char* error = dlerror(); + const char* error = dlerror(); fprintf(stderr, "dlopen failed to open the libcoreclr.so with error %s\n", error); } diff --git a/src/debug/ee/arm64/dbghelpers.S b/src/debug/ee/arm64/dbghelpers.S new file mode 100644 index 0000000..07ed04a --- /dev/null +++ b/src/debug/ee/arm64/dbghelpers.S @@ -0,0 +1,25 @@ +//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" + +NESTED_ENTRY FuncEvalHijack, _TEXT, FuncEvalHijackPersonalityRoutine + +// NOTE: FuncEvalHijackPersonalityRoutine is dependent on the stack layout so if +// you change the prolog you will also need to update the personality routine. + +// push arg to the stack so our personality routine can find it +// push lr to get good stacktrace in debugger + +PROLOG_SAVE_REG_PAIR fp, lr, #-32 + + str x0, [sp, #16] + // FuncEvalHijackWorker returns the address we should jump to. + bl FuncEvalHijackWorker + + EPILOG_STACK_FREE 32 + EPILOG_BRANCH_REG x0 +NESTED_END FuncEvalHijack, _TEXT + +//NESTED_ENTRY ExceptionHijack,,ExceptionHijackPersonalityRoutine \ No newline at end of file diff --git a/src/debug/ee/wks/CMakeLists.txt b/src/debug/ee/wks/CMakeLists.txt index 2b1aff5..1088355 100644 --- a/src/debug/ee/wks/CMakeLists.txt +++ b/src/debug/ee/wks/CMakeLists.txt @@ -55,7 +55,7 @@ else () add_compile_options(-fPIC) -if(CLR_CMAKE_PLATFORM_ARCH_AMD64 OR CLR_CMAKE_PLATFORM_ARCH_ARM OR CLR_CMAKE_PLATFORM_ARCH_I386) +if(CLR_CMAKE_PLATFORM_ARCH_AMD64 OR CLR_CMAKE_PLATFORM_ARCH_ARM OR CLR_CMAKE_PLATFORM_ARCH_ARM64 OR CLR_CMAKE_PLATFORM_ARCH_I386) add_library_clr(cordbee_wks ${CORDBEE_SOURCES_WKS} ../${ARCH_SOURCES_DIR}/dbghelpers.S) elseif(CLR_CMAKE_PLATFORM_ARCH_ARM64) add_library_clr(cordbee_wks ${CORDBEE_SOURCES_WKS}) diff --git a/src/pal/inc/unixasmmacrosarm64.inc b/src/pal/inc/unixasmmacrosarm64.inc index 6014205..359f27f 100644 --- a/src/pal/inc/unixasmmacrosarm64.inc +++ b/src/pal/inc/unixasmmacrosarm64.inc @@ -37,7 +37,8 @@ C_FUNC(\Name\()_End): .endm .macro PREPARE_EXTERNAL_VAR Name, HelperReg - ldr \HelperReg, [pc, #C_FUNC(\Name)@GOTPCREL] + adrp \HelperReg, \Name + add \HelperReg, \HelperReg, :lo12:\Name .endm .macro PROLOG_STACK_ALLOC Size diff --git a/src/vm/appdomain.cpp b/src/vm/appdomain.cpp index 34da344..ab51eb5 100644 --- a/src/vm/appdomain.cpp +++ b/src/vm/appdomain.cpp @@ -165,11 +165,13 @@ CrstStatic BaseDomain::m_SpecialStaticsCrst; int BaseDomain::m_iNumberOfProcessors = 0; // Shared Domain Statics +DECLSPEC_ALIGN(16) static BYTE g_pSharedDomainMemory[sizeof(SharedDomain)]; // System Domain Statics GlobalStringLiteralMap* SystemDomain::m_pGlobalStringLiteralMap = NULL; +DECLSPEC_ALIGN(16) static BYTE g_pSystemDomainMemory[sizeof(SystemDomain)]; #ifdef FEATURE_APPDOMAIN_RESOURCE_MONITORING diff --git a/src/vm/arm64/asmhelpers.S b/src/vm/arm64/asmhelpers.S index e3011ce..32eeb4e 100644 --- a/src/vm/arm64/asmhelpers.S +++ b/src/vm/arm64/asmhelpers.S @@ -142,7 +142,15 @@ NESTED_END NDirectImportThunk, _TEXT // ------------------------------------------------------------------ // ARM64TODO: Implement PrecodeFixupThunk when PreCode is Enabled NESTED_ENTRY PrecodeFixupThunk, _TEXT, NoHandler - brk #0 + ldrb w13, [x12, #Offset_PrecodeChunkIndex] //m_PrecodeChunkIndex + ldrb w14, [x12, #Offset_MethodDescChunkIndex] // m_MethodDescChunkIndex + + add x12, x12, w13, uxtw #FixupPrecode_ALIGNMENT_SHIFT_1 + add x13, x12, w13, uxtw #FixupPrecode_ALIGNMENT_SHIFT_2 + ldr x13, [x13, #SIZEOF__FixupPrecode] + add x12, x13, w14, uxtw #MethodDesc_ALIGNMENT_SHIFT + + b ThePreStub NESTED_END PrecodeFixupThunk, _TEXT // ------------------------------------------------------------------ @@ -251,14 +259,12 @@ WRITE_BARRIER_END JIT_ByRefWriteBarrier // x15 : trashed // WRITE_BARRIER_ENTRY JIT_CheckedWriteBarrier - // ARM64TODO: Temporary indirect access till support for :lo12:symbol is added - ldr x12, =g_lowest_address + PREPARE_EXTERNAL_VAR g_lowest_address, x12 ldr x12, [x12] cmp x14, x12 blt LOCAL_LABEL(NotInHeap) - // ARM64TODO: Temporary indirect access till support for :lo12:symbol is added - ldr x12, =g_highest_address + PREPARE_EXTERNAL_VAR g_highest_address, x12 ldr x12, [x12] cmp x14, x12 blt C_FUNC(JIT_WriteBarrier) @@ -284,21 +290,18 @@ WRITE_BARRIER_ENTRY JIT_WriteBarrier // Branch to Exit if the reference is not in the Gen0 heap // - // ARM64TODO: Temporary indirect access till support for :lo12:symbol is added - ldr x12, =g_ephemeral_low + PREPARE_EXTERNAL_VAR g_ephemeral_low, x12 ldr x12, [x12] cmp x15, x12 blt LOCAL_LABEL(Exit) - // ARM64TODO: Temporary indirect access till support for :lo12:symbol is added - ldr x12, =g_ephemeral_high + PREPARE_EXTERNAL_VAR g_ephemeral_high, x12 ldr x12, [x12] cmp x15, x12 bgt LOCAL_LABEL(Exit) // Check if we need to update the card table - // ARM64TODO: Temporary indirect access till support for :lo12:symbol is added - ldr x12, =g_card_table + PREPARE_EXTERNAL_VAR g_card_table, x12 ldr x12, [x12] add x15, x12, x14, lsr #11 ldrb w12, [x15] @@ -476,7 +479,7 @@ LOCAL_LABEL(UMThunkStub_HaveThread): // m_fPreemptiveGCDisabled is 4 byte field so using 32-bit variant str w9, [x19, #Thread__m_fPreemptiveGCDisabled] - ldr x2, =g_TrapReturningThreads + PREPARE_EXTERNAL_VAR g_TrapReturningThreads, x2 ldr x3, [x2] // assuming x0 contains Thread* before jumping to UMThunkStub_DoTrapReturningThreads cbnz x3, LOCAL_LABEL(UMThunkStub_DoTrapReturningThreads) @@ -667,6 +670,45 @@ LOCAL_LABEL(UM2MThunk_WrapperHelper_RegArgumentsSetup): NESTED_END UM2MThunk_WrapperHelper, _TEXT +#ifdef FEATURE_HIJACK +// ------------------------------------------------------------------ +// Hijack function for functions which return a scalar type or a struct (value type) +NESTED_ENTRY OnHijackTripThread, _TEXT, NoHandler + PROLOG_SAVE_REG_PAIR fp, lr, #-144 + // Spill callee saved registers + PROLOG_SAVE_REG_PAIR x19, x20, #16 + PROLOG_SAVE_REG_PAIR x21, x22, #32 + PROLOG_SAVE_REG_PAIR x23, x24, #48 + PROLOG_SAVE_REG_PAIR x25, x26, #64 + PROLOG_SAVE_REG_PAIR x27, x28, #80 + + // save any integral return value(s) + stp x0, x1, [sp, #96] + + // save any FP/HFA return value(s) + stp d0, d1, [sp, #112] + stp d2, d3, [sp, #128] + + mov x0, sp + bl OnHijackWorker + + // restore any integral return value(s) + ldp x0, x1, [sp, #96] + + // restore any FP/HFA return value(s) + ldp d0, d1, [sp, #112] + ldp d2, d3, [sp, #128] + + EPILOG_RESTORE_REG_PAIR x19, x20, #16 + EPILOG_RESTORE_REG_PAIR x21, x22, #32 + EPILOG_RESTORE_REG_PAIR x23, x24, #48 + EPILOG_RESTORE_REG_PAIR x25, x26, #64 + EPILOG_RESTORE_REG_PAIR x27, x28, #80 + EPILOG_RESTORE_REG_PAIR fp, lr, #144 + EPILOG_RETURN +NESTED_END OnHijackTripThread, _TEXT + +#endif // FEATURE_HIJACK // ------------------------------------------------------------------ // Redirection Stub for GC in fully interruptible method @@ -834,3 +876,26 @@ DynamicHelper DynamicHelperFrameFlags_ObjectArg, _Obj DynamicHelper DynamicHelperFrameFlags_ObjectArg | DynamicHelperFrameFlags_ObjectArg2, _ObjObj #endif + +#ifdef FEATURE_PREJIT +// ------------------------------------------------------------------ +// void StubDispatchFixupStub(args in regs x0-x7 & stack and possibly retbuff arg in x8, x11:IndirectionCellAndFlags, x12:DispatchToken) +// +// The stub dispatch thunk which transfers control to StubDispatchFixupWorker. +NESTED_ENTRY StubDispatchFixupStub, _TEXT, NoHandler + + PROLOG_WITH_TRANSITION_BLOCK + + add x0, sp, #__PWTB_TransitionBlock // pTransitionBlock + and x1, x11, #-4 // Indirection cell + mov x2, #0 // sectionIndex + mov x3, #0 // pModule + bl StubDispatchFixupWorker + mov x9, x0 + + EPILOG_WITH_TRANSITION_BLOCK_TAILCALL + PATCH_LABEL StubDispatchFixupPatchLabel + EPILOG_BRANCH_REG x9 + +NESTED_END StubDispatchFixupStub, _TEXT +#endif diff --git a/src/vm/arm64/crthelpers.S b/src/vm/arm64/crthelpers.S index 2c677e0..ff0df5b 100644 --- a/src/vm/arm64/crthelpers.S +++ b/src/vm/arm64/crthelpers.S @@ -150,7 +150,7 @@ LOCAL_LABEL(JIT_MemSet_0xd0): strb w9,[x0] LOCAL_LABEL(JIT_MemSet_0xd8): ret lr -LEAF_END JIT_MemSet, _TEXT +LEAF_END_MARKED JIT_MemSet, _TEXT // See comments above for JIT_MemSet @@ -288,4 +288,4 @@ LOCAL_LABEL(JIT_MemCpy_0xdc): strb w8,[x0] LOCAL_LABEL(JIT_MemCpy_0xe8): ret lr -LEAF_END JIT_MemCpy, _TEXT +LEAF_END_MARKED JIT_MemCpy, _TEXT -- 2.7.4