summaryrefslogtreecommitdiff
path: root/src/pal/src/arch
diff options
context:
space:
mode:
authorManu <manu-silicon@users.noreply.github.com>2016-03-30 10:56:40 +0900
committerManu <manu-silicon@users.noreply.github.com>2016-03-31 14:33:54 +0900
commit8b37a203524b88c9b003e9779822fb8fdf77e119 (patch)
tree4a8b130489a68bab226d724178e1613995181e67 /src/pal/src/arch
parentf0638c5b6aecec87b3a8aac8c808152c86febe9d (diff)
downloadcoreclr-8b37a203524b88c9b003e9779822fb8fdf77e119.tar.gz
coreclr-8b37a203524b88c9b003e9779822fb8fdf77e119.tar.bz2
coreclr-8b37a203524b88c9b003e9779822fb8fdf77e119.zip
Fix RtlRestoreContext
Due to macro expansion, the previous computed offsets to restore Lr and Pc were incorrect, causing a memory corruption (see Issue #3856 for C# code reproducing that problem). Made assembly more obvious when just restoring Sp, Lr and Pc.
Diffstat (limited to 'src/pal/src/arch')
-rw-r--r--src/pal/src/arch/arm/context2.S24
1 files changed, 13 insertions, 11 deletions
diff --git a/src/pal/src/arch/arm/context2.S b/src/pal/src/arch/arm/context2.S
index 006d0d8b43..3eafbb7bb9 100644
--- a/src/pal/src/arch/arm/context2.S
+++ b/src/pal/src/arch/arm/context2.S
@@ -192,23 +192,25 @@ LEAF_ENTRY RtlRestoreContext, _TEXT
ldr R2, [r0, #(CONTEXT_Cpsr)]
msr APSR, r2
- mov r12, r0 // ideally we would ldmia r0, {r0-r12, sp, lr, pc} here, but that isn't supported on new clang
- add r12, CONTEXT_R0 // so we'll burn r12 as the IPC reg for now -- TODO: is this ok?
+ // Ideally, we would like to use `ldmia r0, {r0-r12, sp, lr, pc}` here,
+ // but clang 3.6 and later, as per ARM recommendation, disallows using
+ // Sp in the register list, and Pc and Lr simultaneously.
+ // So we are going to use the IPC register r12 to copy Sp, Lr and Pc
+ // which should be ok -- TODO: Is this really ok?
+ add r12, r0, CONTEXT_R0
ldm r12, {r0-r11}
- add r12, (CONTEXT_Sp - CONTEXT_R0)
- ldr sp, [r12]
- ldr lr, [r12, #(CONTEXT_Lr - CONTEXT_Sp)]
- ldr pc, [r12, #(CONTEXT_Pc - CONTEXT_Sp)]
-
+ ldr sp, [r12, #(CONTEXT_Sp - (CONTEXT_R0))]
+ ldr lr, [r12, #(CONTEXT_Lr - (CONTEXT_R0))]
+ ldr pc, [r12, #(CONTEXT_Pc - (CONTEXT_R0))]
+
LOCAL_LABEL(No_Restore_CONTEXT_INTEGER):
ldr r2, [r0, #(CONTEXT_Cpsr)]
msr APSR, r2
- add r0, CONTEXT_Sp
- ldr sp, [r0]
- ldr lr, [r0, #(CONTEXT_Lr - CONTEXT_Sp)]
- ldr pc, [r0, #(CONTEXT_Pc - CONTEXT_Sp)]
+ ldr sp, [r0, #(CONTEXT_Sp)]
+ ldr lr, [r0, #(CONTEXT_Lr)]
+ ldr pc, [r0, #(CONTEXT_Pc)]
LOCAL_LABEL(No_Restore_CONTEXT_CONTROL):
ldr r2, [r0, #(CONTEXT_ContextFlags)]