Skip to content
This repository was archived by the owner on Jan 23, 2023. It is now read-only.

[ARM64/Unix] #9500

Merged
merged 24 commits into from
Feb 17, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
0e778d7
[Arm64/Unix] Update arm64 *.S files to match *.asm
sdmaclea Nov 22, 2016
6caae84
[Arm64/Unix] Fix CONTEXTToNativeContext()
sdmaclea Dec 1, 2016
2e7f2d1
[Arm64/Unix] ThrowExceptionFromContextInternal
sdmaclea Dec 1, 2016
86cfff3
[Arm64/Unix] Preserve x8 argument register
sdmaclea Dec 7, 2016
2fad44a
[ARM64/Unix] Add CFI directives
sdmaclea Dec 22, 2016
011e693
[Arm64/Unix] Fix RtlRestoreContext
sdmaclea Dec 22, 2016
efb5663
[Arm64/Unix] Restore FP from CurrentContextPointers
sdmaclea Dec 30, 2016
745ae83
[Arm64/Unix] fix pointer math
sdmaclea Jan 4, 2017
da3093a
[Arm64/Unix] Fix CallDescrWorkerInternal personality
sdmaclea Jan 7, 2017
d05be2c
[Arm64/Unix] More Fp fixups
sdmaclea Jan 10, 2017
6e4d219
[Arm64/Unix] CallEHFunclet machine state
sdmaclea Jan 13, 2017
775fd5a
[Arm64/Unix] CallDescrWorkerInternal
sdmaclea Jan 18, 2017
da460d6
[Arm64/Unix] RtlVirtualUnwind update pointers
sdmaclea Jan 20, 2017
dfca815
[Arm64] LazyMachState fixes
sdmaclea Jan 20, 2017
dccb0d3
[Arm64/Unix] disable USE_REDIRECT_FOR_GCSTRESS
sdmaclea Feb 1, 2017
1bf23c0
[Arm64] ClearRegDisplayArgumentAndScratchRegisters()
sdmaclea Feb 1, 2017
72a3896
[Arm64] Remove unnecesary copy in TransitionFrame
sdmaclea Feb 1, 2017
3e9676c
[Arm64/Unix] Fix comment per review
sdmaclea Feb 13, 2017
b8be0a5
[Arm64/Unix] move constants per review
sdmaclea Feb 13, 2017
fb41fca
[Arm64/Unix] Use ldp per review
sdmaclea Feb 13, 2017
1f5e9a7
[Arm64/Unix] Fix indentation per review
sdmaclea Feb 13, 2017
ce64cbb
[Arm64/Unix] Remove m_Unwound per review comments
sdmaclea Feb 13, 2017
87b96cb
[Arm64/Unix] Use PREPARE_EXTERNAL_VAR to access globals
sdmaclea Feb 17, 2017
d18c6d3
[Arm64/Unix] Fix more whitespace per earlier review comments
sdmaclea Feb 17, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 40 additions & 15 deletions src/debug/ee/arm64/dbghelpers.S
Original file line number Diff line number Diff line change
@@ -1,25 +1,50 @@
//Licensed to the .NET Foundation under one or more agreements.
// 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 "asmconstants.h"
#include "unixasmmacros.inc"

NESTED_ENTRY FuncEvalHijack, _TEXT, FuncEvalHijackPersonalityRoutine
//
// hijacking stub used to perform a func-eval, see Debugger::FuncEvalSetup() for use.
//
// on entry:
// x0 : pointer to DebuggerEval object
//

// NOTE: FuncEvalHijackPersonalityRoutine is dependent on the stack layout so if
// you change the prolog you will also need to update the personality routine.
// @dbgtodo- once we port Funceval, use the ExceptionHijack stub instead of this func-eval stub.
NESTED_ENTRY FuncEvalHijack, _TEXT, UnhandledExceptionHandlerUnix

// push arg to the stack so our personality routine can find it
// push lr to get good stacktrace in debugger
// NOTE: FuncEvalHijackPersonalityRoutine is dependent on the stack layout so if
// you change the prolog you will also need to update the personality routine.

PROLOG_SAVE_REG_PAIR fp, lr, #-32
// push arg to the stack so our personality routine can find it
// push lr to get good stacktrace in debugger
PROLOG_SAVE_REG_PAIR_INDEXED 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

// This is the general purpose hijacking stub. The DacDbi Hijack primitive will
// set up the stack and then set the IP here, and so this just makes the call.
NESTED_ENTRY ExceptionHijack, _TEXT, UnhandledExceptionHandlerUnix

// make the call
bl ExceptionHijackWorker

// effective NOP to terminate unwind
mov x3, x3

// *** should never get here ***
EMIT_BREAKPOINT

// exported label so the debugger knows where the end of this function is
PATCH_LABEL ExceptionHijackEnd

NESTED_END ExceptionHijack, _TEXT

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
2 changes: 1 addition & 1 deletion src/debug/ee/wks/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ add_compile_options(-fPIC)
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})
add_library_clr(cordbee_wks ${CORDBEE_SOURCES_WKS} ../${ARCH_SOURCES_DIR}/dbghelpers.S)
else()
message(FATAL_ERROR "Only ARM and AMD64 is supported")
endif()
Expand Down
151 changes: 104 additions & 47 deletions src/pal/inc/unixasmmacrosarm64.inc
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ C_FUNC(\Name):
.endm

.macro LEAF_END_MARKED Name, Section
.global C_FUNC(\Name\()_End)
C_FUNC(\Name\()_End):
.global C_FUNC(\Name\()_End)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was this change necessary? We have the .global before the label on amd64, so if it was just a cosmetic change, I would prefer reverting it to keep the look consistent with amd64.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At the time I was trying to remove cosmetic difference between amd64 and arm64. I'll take a look.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just confirmed that this currently matches amd64.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am sorry, you're right. I don't know at what I was looking before.

LEAF_END \Name, \Section
.endm

Expand All @@ -48,40 +48,54 @@ C_FUNC(\Name\()_End):

.macro EPILOG_STACK_FREE Size
add sp, sp, \Size
.cfi_adjust_cfa_offset -\Size
.endm

.macro EPILOG_STACK_RESTORE
mov sp, fp
.cfi_restore sp
.endm

.macro PROLOG_SAVE_REG reg, ofs
str \reg, [sp, \ofs]
.cfi_rel_offset \reg, \ofs
.endm

.macro PROLOG_SAVE_REG_PAIR reg1, reg2, ofs
stp \reg1, \reg2, [sp, \ofs]
.cfi_rel_offset \reg1, \ofs
.cfi_rel_offset \reg2, \ofs + 8
.ifc \reg1, fp
mov fp, sp
.endif
.endm

.macro PROLOG_SAVE_REG_PAIR_INDEXED reg1, reg2, ofs
stp \reg1, \reg2, [sp, \ofs]!
.cfi_adjust_cfa_offset -\ofs
.cfi_rel_offset \reg1, 0
.cfi_rel_offset \reg2, 8
.ifc \reg1, fp
mov fp, sp
.endif
.endm

.macro EPILOG_RESTORE_REG reg, ofs
ldr \reg, [sp, \ofs]
.cfi_restore \reg1
.endm

.macro EPILOG_RESTORE_REG_PAIR reg1, reg2, ofs
ldp \reg1, \reg2, [sp, \ofs]
.cfi_restore \reg1
.cfi_restore \reg2
.endm

.macro EPILOG_RESTORE_REG_PAIR_INDEXED reg1, reg2, ofs
ldp \reg1, \reg2, [sp], \ofs
.cfi_restore \reg1
.cfi_restore \reg2
.cfi_adjust_cfa_offset -\ofs
.endm

.macro EPILOG_RETURN
Expand All @@ -94,14 +108,14 @@ C_FUNC(\Name\()_End):

//-----------------------------------------------------------------------------
// Define the prolog for a TransitionFrame-based method. This macro should be called first in the method and
// comprises the entire prolog (i.e. don't modify SP after calling this).The locals must be 8 byte aligned
// comprises the entire prolog (i.e. don't modify SP after calling this).The locals must be 8 byte aligned
//
// Stack layout:
//
// (stack parameters)
// ...
// fp
// lr
// lr
// CalleeSavedRegisters::x28
// CalleeSavedRegisters::x27
// CalleeSavedRegisters::x26
Expand Down Expand Up @@ -133,81 +147,122 @@ C_FUNC(\Name\()_End):
.macro PROLOG_WITH_TRANSITION_BLOCK extraLocals = 0, SaveFPArgs = 1

__PWTB_FloatArgumentRegisters = \extraLocals
__PWTB_SaveFPArgs = \SaveFPArgs

.if ((__PWTB_FloatArgumentRegisters % 16) != 0)
__PWTB_FloatArgumentRegisters = __PWTB_FloatArgumentRegisters + 8
.endif

__PWTB_TransitionBlock = __PWTB_FloatArgumentRegisters

.if \SaveFPArgs > 0
.if (__PWTB_SaveFPArgs == 1)
__PWTB_TransitionBlock = __PWTB_TransitionBlock + SIZEOF__FloatArgumentRegisters
.endif

__PWTB_StackAlloc = __PWTB_TransitionBlock
__PWTB_ArgumentRegisters = __PWTB_StackAlloc + 96

PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, #-160
// 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
__PWTB_ArgumentRegisters = __PWTB_StackAlloc + 96

PROLOG_SAVE_REG_PAIR_INDEXED fp, lr, -176
// 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

// Allocate space for the rest of the frame
PROLOG_STACK_ALLOC __PWTB_StackAlloc

// Spill argument registers.
SAVE_ARGUMENT_REGISTERS sp, __PWTB_ArgumentRegisters

.if \SaveFPArgs > 0
.if (__PWTB_SaveFPArgs == 1)
SAVE_FLOAT_ARGUMENT_REGISTERS sp, \extraLocals
.endif

.endm

//-----------------------------------------------------------------------------
// The Following sets of SAVE_*_REGISTERS expect the memory to be reserved and
// The Following sets of SAVE_*_REGISTERS expect the memory to be reserved and
// base address to be passed in $reg
//

// Reserve 64 bytes of memory before calling SAVE_ARGUMENT_REGISTERS
.macro SAVE_ARGUMENT_REGISTERS reg, ofs
.macro SAVE_ARGUMENT_REGISTERS reg, ofs

stp x0, x1, [\reg, #(\ofs)]
.cfi_rel_offset x0, \ofs
.cfi_rel_offset x1, \ofs + 8
stp x2, x3, [\reg, #(\ofs + 16)]
.cfi_rel_offset x2, \ofs + 16
.cfi_rel_offset x3, \ofs + 24
stp x4, x5, [\reg, #(\ofs + 32)]
.cfi_rel_offset x4, \ofs + 32
.cfi_rel_offset x5, \ofs + 40
stp x6, x7, [\reg, #(\ofs + 48)]
.cfi_rel_offset x6, \ofs + 48
.cfi_rel_offset x7, \ofs + 56
str x8, [\reg, #(\ofs + 64)]
.cfi_rel_offset x8, \ofs + 64

.endm

// Reserve 64 bytes of memory before calling SAVE_FLOAT_ARGUMENT_REGISTERS
.macro SAVE_FLOAT_ARGUMENT_REGISTERS reg, ofs
.macro SAVE_FLOAT_ARGUMENT_REGISTERS reg, ofs

stp d0, d1, [\reg, #(\ofs)]
.cfi_rel_offset d0, \ofs + 0
.cfi_rel_offset d1, \ofs + 8
stp d2, d3, [\reg, #(\ofs + 16)]
.cfi_rel_offset d2, \ofs + 16
.cfi_rel_offset d3, \ofs + 24
stp d4, d5, [\reg, #(\ofs + 32)]
.cfi_rel_offset d4, \ofs + 32
.cfi_rel_offset d5, \ofs + 40
stp d6, d7, [\reg, #(\ofs + 48)]
.cfi_rel_offset d6, \ofs + 48
.cfi_rel_offset d7, \ofs + 56

.endm

.macro RESTORE_ARGUMENT_REGISTERS reg, ofs
.macro RESTORE_ARGUMENT_REGISTERS reg, ofs

ldp x0, x1, [\reg, #(\ofs)]
.cfi_restore x0
.cfi_restore x1
ldp x2, x3, [\reg, #(\ofs + 16)]
.cfi_restore x2
.cfi_restore x3
ldp x4, x5, [\reg, #(\ofs + 32)]
.cfi_restore x4
.cfi_restore x5
ldp x6, x7, [\reg, #(\ofs + 48)]
.cfi_restore x6
.cfi_restore x7
ldr x8, [\reg, #(\ofs + 64)]
.cfi_restore x8

.endm

.macro RESTORE_FLOAT_ARGUMENT_REGISTERS reg, ofs
.macro RESTORE_FLOAT_ARGUMENT_REGISTERS reg, ofs

ldp d0, d1, [\reg, #(\ofs)]
.cfi_restore d0
.cfi_restore d1
ldp d2, d3, [\reg, #(\ofs + 16)]
.cfi_restore d2
.cfi_restore d3
ldp d4, d5, [\reg, #(\ofs + 32)]
.cfi_restore d4
.cfi_restore d5
ldp d6, d7, [\reg, #(\ofs + 48)]
.cfi_restore d6
.cfi_restore d7

.endm

.macro EPILOG_BRANCH Target
b \Target
.endm

.macro EPILOG_BRANCH_REG reg
Expand All @@ -216,40 +271,42 @@ C_FUNC(\Name\()_End):

.endm

//-----------------------------------------------------------------------------
// Provides a matching epilog to PROLOG_WITH_TRANSITION_BLOCK and ends by preparing for tail-calling.
// Since this is a tail call argument registers are restored.
//
.macro EPILOG_WITH_TRANSITION_BLOCK_TAILCALL extraLocals = 0, SaveFPArgs =1

__PWTB_FloatArgumentRegisters = \extraLocals
.macro EPILOG_WITH_TRANSITION_BLOCK_RETURN

.if ((__PWTB_FloatArgumentRegisters % 16) != 0)
__PWTB_FloatArgumentRegisters = __PWTB_FloatArgumentRegisters + 8
.endif
EPILOG_STACK_FREE __PWTB_StackAlloc

__PWTB_TransitionBlock = __PWTB_FloatArgumentRegisters
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_INDEXED fp, lr, 176
ret

.if \SaveFPArgs > 0
__PWTB_TransitionBlock = __PWTB_TransitionBlock + SIZEOF__FloatArgumentRegisters
.endif
.endm

__PWTB_StackAlloc = __PWTB_TransitionBlock
__PWTB_ArgumentRegisters = __PWTB_StackAlloc + 96

.if \SaveFPArgs > 0
RESTORE_FLOAT_ARGUMENT_REGISTERS sp, __PWTB_FloatArgumentRegisters
//-----------------------------------------------------------------------------
// Provides a matching epilog to PROLOG_WITH_TRANSITION_BLOCK and ends by preparing for tail-calling.
// Since this is a tail call argument registers are restored.
//
.macro EPILOG_WITH_TRANSITION_BLOCK_TAILCALL

.if (__PWTB_SaveFPArgs == 1)
RESTORE_FLOAT_ARGUMENT_REGISTERS sp, __PWTB_FloatArgumentRegisters
.endif

RESTORE_ARGUMENT_REGISTERS sp, __PWTB_ArgumentRegisters

EPILOG_STACK_FREE __PWTB_StackAlloc
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_INDEXED fp, lr, #160

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_INDEXED fp, lr, 176

.endm

Expand All @@ -273,8 +330,8 @@ __RedirectionFuncName SETS "|?RedirectedHandledJITCaseFor":CC:"$reason":CC:"@Thr
IMPORT $__RedirectionFuncName

NESTED_ENTRY $__RedirectionStubFuncName
PROLOG_SAVE_REG_PAIR fp, lr, #-16
sub sp, sp, #16 // stack slot for CONTEXT * and padding
PROLOG_SAVE_REG_PAIR fp, lr, -16
sub sp, sp, #16 // stack slot for CONTEXT * and padding

//REDIRECTSTUB_SP_OFFSET_CONTEXT is defined in asmconstants.h and is used in GetCONTEXTFromRedirectedStubStackFrame
//If CONTEXT is not saved at 0 offset from SP it must be changed as well.
Expand Down
Loading