Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
37 changes: 26 additions & 11 deletions src/coreclr/nativeaot/Runtime/arm/GcProbe.S
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
// incoming register values into it.
PROLOG_VPUSH "{d0-d3}" // Save d0-d3 which can have the floating point return value
PROLOG_PUSH "{r0,r1}" // Save return registers
PROLOG_PUSH "{r2}" // Save r2, it might contain an objectref (async continuation)
PROLOG_STACK_ALLOC 4 // Space for caller's SP
PROLOG_PUSH "{r4-r10}" // Save non-volatile registers
PROLOG_STACK_ALLOC 8 // Space for flags and Thread*
Expand All @@ -32,7 +33,7 @@
str \trashReg, [sp, #OFFSETOF__PInvokeTransitionFrame__m_Flags]

// Compute SP value at entry to this method and save it in slot of the frame.
add \trashReg, sp, #(14 * 4 + 4 * 8)
add \trashReg, sp, #(15 * 4 + 4 * 8)
str \trashReg, [sp, #(11 * 4)]

// Link the frame into the Thread
Expand All @@ -49,6 +50,7 @@
EPILOG_STACK_FREE 8 // Discard flags and Thread*
EPILOG_POP "{r4-r10}" // Restore non-volatile registers
EPILOG_STACK_FREE 4 // Discard caller's SP
EPILOG_POP "{r2}" // Restore r2
EPILOG_POP "{r0,r1}" // Restore return registers
EPILOG_VPOP "{d0-d3}" // Restore d0-d3 which can have the floating point return value
.endm
Expand All @@ -61,25 +63,34 @@
// All registers correct for return to the original return address.
//
// Register state on exit:
// r2: thread pointer
// r3: trashed
// r3: thread pointer
// r0, r1, r2: preserved, other volatile regs trashed
//
.macro FixupHijackedCallstack
push {r0, r1}
push {r0, r1, r2}

// align stack to 8 bytes
sub sp, sp, #4

// r0 <- GetThread()
INLINE_GETTHREAD

mov r2, r0
pop {r0, r1}
mov r3, r0

// restore alignment
add sp, sp, #4

pop {r0, r1, r2}

// Fix the stack by restoring the original return address
ldr lr, [r2, #OFFSETOF__Thread__m_pvHijackedReturnAddress]
ldr lr, [r3, #OFFSETOF__Thread__m_pvHijackedReturnAddress]

// Clear hijack state
mov r3, #0
str r3, [r2, #OFFSETOF__Thread__m_ppvHijackedReturnAddressLocation]
str r3, [r2, #OFFSETOF__Thread__m_pvHijackedReturnAddress]
push {r0}
mov r0, #0
str r0, [r3, #OFFSETOF__Thread__m_ppvHijackedReturnAddressLocation]
str r0, [r3, #OFFSETOF__Thread__m_pvHijackedReturnAddress]
pop {r0}
.endm

NESTED_ENTRY RhpWaitForGC, _TEXT, NoHandler
Expand Down Expand Up @@ -110,12 +121,16 @@ NESTED_END RhpGcPollRare
NESTED_ENTRY RhpGcProbeHijack, _TEXT, NoHandler
FixupHijackedCallstack

// r3 has the thread pointer
push {r3}
PREPARE_EXTERNAL_VAR_INDIRECT RhpTrapThreads, r3
tst r3, #TrapThreadsFlags_TrapThreads
pop {r3}
bne LOCAL_LABEL(WaitForGC)
bx lr
LOCAL_LABEL(WaitForGC):
mov r12, #(DEFAULT_FRAME_SAVE_FLAGS + PTFF_SAVE_R0)
mov r2, r3 // Move thread pointer to r2 for RhpWaitForGC
mov r12, #(DEFAULT_FRAME_SAVE_FLAGS + PTFF_SAVE_R0 + PTFF_SAVE_R2)
orr r12, r12, #PTFF_THREAD_HIJACK
b RhpWaitForGC
NESTED_END RhpGcProbeHijack
Expand Down
2 changes: 2 additions & 0 deletions src/coreclr/nativeaot/Runtime/unix/unixasmmacrosarm.inc
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,12 @@
#define TSF_SuppressGcStress 0x08
#define TSF_DoNotTriggerGc 0x10

// These must match the PInvokeTransitionFrameFlags enum
#define PTFF_SAVE_ALL_PRESERVED 0x0000007F // NOTE: R11 is not included in this set!
#define PTFF_SAVE_R9 0x00000020
#define PTFF_SAVE_SP 0x00000100
#define PTFF_SAVE_R0 0x00000200
#define PTFF_SAVE_R2 0x00000800
#define PTFF_THREAD_HIJACK 0x00004000 // indicates that this is a frame for a hijacked call

#define DEFAULT_FRAME_SAVE_FLAGS (PTFF_SAVE_ALL_PRESERVED + PTFF_SAVE_SP)
Expand Down