summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packaging/0001-Fixed-ARM-single-stepper-added-ADD-Rn-PC-command-emu.patch449
-rwxr-xr-xpackaging/coreclr.spec4
2 files changed, 452 insertions, 1 deletions
diff --git a/packaging/0001-Fixed-ARM-single-stepper-added-ADD-Rn-PC-command-emu.patch b/packaging/0001-Fixed-ARM-single-stepper-added-ADD-Rn-PC-command-emu.patch
new file mode 100644
index 0000000000..b3408486cf
--- /dev/null
+++ b/packaging/0001-Fixed-ARM-single-stepper-added-ADD-Rn-PC-command-emu.patch
@@ -0,0 +1,449 @@
+From 4ff1199914c652c52740a7f414c20e7eaedf5389 Mon Sep 17 00:00:00 2001
+From: Kirill Frolov <k.frolov@samsung.com>
+Date: Wed, 22 May 2019 17:05:06 +0300
+Subject: [PATCH] Fixed ARM single stepper: added "ADD Rn, PC" command
+ emulation (#24271)
+
+This change fixes bug #24164: pull request #11366 adds generation of
+commands which use PC-relative addressing. But ArmSingleStepper doesn't
+implements support for "ADD Rn, PC" command, so when we try to debug
+managed code, generated JIT can't be single stepped correctly.
+
+Detailed changes description:
+
+1) added "ADD Rn, PC" command emulation to ArmSingleStepper;
+2) asserts added to JIT code generator, which prevents using of CPU
+instructions, which address PC (R15) register with except of only "ADD
+Rn, PC" instruction (asserts generated only in Debug builds).
+
+Normally PC register shouldn't be used in arithmetic commands almost in
+all cases.
+
+Change-Id: I76b8f973aa7a8231835c9983dff879e8592eda98
+---
+ src/jit/emitarm.cpp | 95 ++++++++++++++++++++++++++++++++++++++++-
+ src/vm/arm/armsinglestepper.cpp | 15 +++++++
+ 2 files changed, 109 insertions(+), 1 deletion(-)
+
+diff --git a/src/jit/emitarm.cpp b/src/jit/emitarm.cpp
+index 2b8eb25..3e73599 100644
+--- a/src/jit/emitarm.cpp
++++ b/src/jit/emitarm.cpp
+@@ -1671,6 +1671,7 @@ void emitter::emitIns_R_I(
+ {
+ case INS_add:
+ case INS_sub:
++ assert(reg != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
+ if ((reg == REG_SP) && insDoesNotSetFlags(flags) && ((imm & 0x01fc) == imm))
+ {
+ fmt = IF_T1_F;
+@@ -1699,6 +1700,7 @@ void emitter::emitIns_R_I(
+ break;
+
+ case INS_adc:
++ assert(reg != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
+ emitIns_R_R_I(ins, attr, reg, reg, imm, flags);
+ return;
+
+@@ -1808,6 +1810,7 @@ void emitter::emitIns_R_I(
+ case INS_lsl:
+ case INS_lsr:
+ // use the Reg, Reg, Imm encoding
++ assert(reg != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
+ emitIns_R_R_I(ins, attr, reg, reg, imm, flags);
+ return;
+
+@@ -1871,6 +1874,7 @@ void emitter::emitIns_R_I(
+ break;
+
+ case INS_cmp:
++ assert(reg != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
+ assert(!EA_IS_CNS_RELOC(attr));
+ assert(insSetsFlags(flags));
+ sf = INS_FLAGS_SET;
+@@ -1905,6 +1909,7 @@ void emitter::emitIns_R_I(
+ case INS_cmn:
+ case INS_tst:
+ case INS_teq:
++ assert(reg != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
+ assert(insSetsFlags(flags));
+ sf = INS_FLAGS_SET;
+ if (isModImmConst(imm))
+@@ -1986,6 +1991,9 @@ void emitter::emitIns_R_R(
+ switch (ins)
+ {
+ case INS_add:
++ // VM debugging single stepper doesn't support PC register with this instruction.
++ // (but reg2 might be PC for ADD Rn, PC instruction)
++ assert(reg1 != REG_PC);
+ if (insDoesNotSetFlags(flags))
+ {
+ fmt = IF_T1_D0;
+@@ -1995,6 +2003,8 @@ void emitter::emitIns_R_R(
+ __fallthrough;
+
+ case INS_sub:
++ assert(reg1 != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
++ assert(reg2 != REG_PC);
+ // Use the Thumb-1 reg,reg,reg encoding
+ emitIns_R_R_R(ins, attr, reg1, reg1, reg2, flags);
+ return;
+@@ -2021,6 +2031,8 @@ void emitter::emitIns_R_R(
+ break;
+
+ case INS_cmp:
++ assert(reg1 != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
++ assert(reg2 != REG_PC);
+ assert(insSetsFlags(flags));
+ sf = INS_FLAGS_SET;
+ if (isLowRegister(reg1) && isLowRegister(reg2))
+@@ -2034,6 +2046,7 @@ void emitter::emitIns_R_R(
+ break;
+
+ case INS_vmov_f2i:
++ assert(reg1 != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
+ assert(isGeneralRegister(reg1));
+ assert(isFloatReg(reg2));
+ fmt = IF_T2_VMOVS;
+@@ -2041,6 +2054,7 @@ void emitter::emitIns_R_R(
+ break;
+
+ case INS_vmov_i2f:
++ assert(reg2 != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
+ assert(isFloatReg(reg1));
+ assert(isGeneralRegister(reg2));
+ fmt = IF_T2_VMOVS;
+@@ -2071,6 +2085,8 @@ void emitter::emitIns_R_R(
+ goto VCVT_COMMON;
+
+ case INS_vmov:
++ assert(reg1 != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
++ assert(reg2 != REG_PC);
+ assert(reg1 != reg2);
+ __fallthrough;
+
+@@ -2099,6 +2115,8 @@ void emitter::emitIns_R_R(
+ case INS_vmul:
+ case INS_vsub:
+ case INS_vdiv:
++ assert(reg1 != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
++ assert(reg2 != REG_PC);
+ emitIns_R_R_R(ins, attr, reg1, reg1, reg2);
+ return;
+
+@@ -2122,6 +2140,8 @@ void emitter::emitIns_R_R(
+ case INS_eor:
+ case INS_orr:
+ case INS_sbc:
++ assert(reg1 != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
++ assert(reg2 != REG_PC);
+ if (insSetsFlags(flags) && isLowRegister(reg1) && isLowRegister(reg2))
+ {
+ fmt = IF_T1_E;
+@@ -2135,6 +2155,8 @@ void emitter::emitIns_R_R(
+ // the same static field load which got cse'd.
+ // there's no reason why this assert would be true in general
+ // assert(reg1 != reg2);
++ assert(reg1 != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
++ assert(reg2 != REG_PC);
+ // Use the Thumb-2 three register encoding
+ emitIns_R_R_R_I(ins, attr, reg1, reg1, reg2, 0, flags);
+ return;
+@@ -2147,6 +2169,8 @@ void emitter::emitIns_R_R(
+ // arithmetic right shift were the same local variable
+ // there's no reason why this assert would be true in general
+ // assert(reg1 != reg2);
++ assert(reg1 != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
++ assert(reg2 != REG_PC);
+ if (insSetsFlags(flags) && isLowRegister(reg1) && isLowRegister(reg2))
+ {
+ fmt = IF_T1_E;
+@@ -2163,7 +2187,8 @@ void emitter::emitIns_R_R(
+ case INS_mul:
+ // We will prefer the T2 encoding, unless (flags == INS_FLAGS_SET)
+ // The thumb-1 instruction executes much slower as it must always set the flags
+- //
++ assert(reg1 != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
++ assert(reg2 != REG_PC);
+ if (insMustSetFlags(flags) && isLowRegister(reg1) && isLowRegister(reg2))
+ {
+ fmt = IF_T1_E;
+@@ -2180,6 +2205,8 @@ void emitter::emitIns_R_R(
+ case INS_mvn:
+ case INS_cmn:
+ case INS_tst:
++ assert(reg1 != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
++ assert(reg2 != REG_PC);
+ if (insSetsFlags(flags) && isLowRegister(reg1) && isLowRegister(reg2))
+ {
+ fmt = IF_T1_E;
+@@ -2202,6 +2229,8 @@ void emitter::emitIns_R_R(
+ case INS_uxth:
+ assert(size == EA_2BYTE);
+ EXTEND_COMMON:
++ assert(reg1 != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
++ assert(reg2 != REG_PC);
+ assert(insDoesNotSetFlags(flags));
+ if (isLowRegister(reg1) && isLowRegister(reg2))
+ {
+@@ -2231,6 +2260,8 @@ void emitter::emitIns_R_R(
+ break;
+
+ case INS_clz:
++ assert(reg1 != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
++ assert(reg2 != REG_PC);
+ assert(insDoesNotSetFlags(flags));
+ fmt = IF_T2_C10;
+ sf = INS_FLAGS_NOT_SET;
+@@ -2295,6 +2326,8 @@ void emitter::emitIns_R_I_I(
+ {
+ case INS_bfc:
+ {
++ assert(reg != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
++
+ int lsb = imm1;
+ int msb = lsb + imm2 - 1;
+
+@@ -2355,6 +2388,8 @@ void emitter::emitIns_R_R_I(instruction ins,
+ switch (ins)
+ {
+ case INS_add:
++ assert(reg1 != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
++ assert(reg2 != REG_PC);
+ assert(insOptsNone(opt));
+
+ // Can we possibly encode the immediate 'imm' using a Thumb-1 encoding?
+@@ -2376,6 +2411,8 @@ void emitter::emitIns_R_R_I(instruction ins,
+ __fallthrough;
+
+ case INS_sub:
++ assert(reg1 != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
++ assert(reg2 != REG_PC);
+ assert(insOptsNone(opt));
+
+ // Is it just a mov?
+@@ -2456,6 +2493,8 @@ void emitter::emitIns_R_R_I(instruction ins,
+ case INS_bic:
+ case INS_orr:
+ case INS_orn:
++ assert(reg1 != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
++ assert(reg2 != REG_PC);
+ assert(insOptsNone(opt));
+ if (isModImmConst(imm))
+ {
+@@ -2486,6 +2525,8 @@ void emitter::emitIns_R_R_I(instruction ins,
+ break;
+
+ case INS_rsb:
++ assert(reg1 != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
++ assert(reg2 != REG_PC);
+ assert(insOptsNone(opt));
+ if (imm == 0 && isLowRegister(reg1) && isLowRegister(reg2) && insSetsFlags(flags))
+ {
+@@ -2498,6 +2539,8 @@ void emitter::emitIns_R_R_I(instruction ins,
+ case INS_adc:
+ case INS_eor:
+ case INS_sbc:
++ assert(reg1 != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
++ assert(reg2 != REG_PC);
+ assert(insOptsNone(opt));
+ if (isModImmConst(imm))
+ {
+@@ -2531,6 +2574,8 @@ void emitter::emitIns_R_R_I(instruction ins,
+ break;
+
+ case INS_mvn:
++ assert(reg1 != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
++ assert(reg2 != REG_PC);
+ assert((imm >= 0) && (imm <= 31)); // required for encoding
+ assert(!insOptAnyInc(opt));
+ if (imm == 0)
+@@ -2555,6 +2600,8 @@ void emitter::emitIns_R_R_I(instruction ins,
+ case INS_cmn:
+ case INS_teq:
+ case INS_tst:
++ assert(reg1 != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
++ assert(reg2 != REG_PC);
+ assert(insSetsFlags(flags));
+ assert((imm >= 0) && (imm <= 31)); // required for encoding
+ assert(!insOptAnyInc(opt));
+@@ -2589,6 +2636,8 @@ void emitter::emitIns_R_R_I(instruction ins,
+ case INS_asr:
+ case INS_lsl:
+ case INS_lsr:
++ assert(reg1 != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
++ assert(reg2 != REG_PC);
+ assert(insOptsNone(opt));
+
+ // On ARM, the immediate shift count of LSL and ROR must be between 1 and 31. For LSR and ASR, it is between
+@@ -2631,6 +2680,8 @@ void emitter::emitIns_R_R_I(instruction ins,
+ case INS_uxth:
+ assert(size == EA_2BYTE);
+ EXTEND_COMMON:
++ assert(reg1 != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
++ assert(reg2 != REG_PC);
+ assert(insOptsNone(opt));
+ assert(insDoesNotSetFlags(flags));
+ assert((imm & 0x018) == imm); // required for encoding
+@@ -2877,6 +2928,9 @@ void emitter::emitIns_R_R_R(instruction ins,
+
+ case INS_sub:
+ assert(reg3 != REG_SP);
++ assert(reg1 != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
++ assert(reg2 != REG_PC);
++ assert(reg3 != REG_PC || ins == INS_add); // allow ADD Rn, PC instruction in T2 encoding
+
+ if (isLowRegister(reg1) && isLowRegister(reg2) && isLowRegister(reg3) && insSetsFlags(flags))
+ {
+@@ -2911,6 +2965,9 @@ void emitter::emitIns_R_R_R(instruction ins,
+ case INS_eor:
+ case INS_orr:
+ case INS_sbc:
++ assert(reg1 != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
++ assert(reg2 != REG_PC);
++ assert(reg3 != REG_PC);
+ if (reg1 == reg2)
+ {
+ // Try to encode as a Thumb-1 instruction
+@@ -2920,6 +2977,9 @@ void emitter::emitIns_R_R_R(instruction ins,
+ __fallthrough;
+
+ case INS_orn:
++ assert(reg1 != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
++ assert(reg2 != REG_PC);
++ assert(reg3 != REG_PC);
+ // Use the Thumb-2 three register encoding, with imm=0
+ emitIns_R_R_R_I(ins, attr, reg1, reg2, reg3, 0, flags);
+ return;
+@@ -2927,6 +2987,9 @@ void emitter::emitIns_R_R_R(instruction ins,
+ case INS_asr:
+ case INS_lsl:
+ case INS_lsr:
++ assert(reg1 != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
++ assert(reg2 != REG_PC);
++ assert(reg3 != REG_PC);
+ if (reg1 == reg2 && insSetsFlags(flags) && isLowRegister(reg1) && isLowRegister(reg3))
+ {
+ // Use the Thumb-1 regdest,reg encoding
+@@ -2936,6 +2999,9 @@ void emitter::emitIns_R_R_R(instruction ins,
+ __fallthrough;
+
+ case INS_ror:
++ assert(reg1 != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
++ assert(reg2 != REG_PC);
++ assert(reg3 != REG_PC);
+ fmt = IF_T2_C4;
+ sf = insMustSetFlags(flags);
+ break;
+@@ -2943,6 +3009,11 @@ void emitter::emitIns_R_R_R(instruction ins,
+ case INS_mul:
+ if (insMustSetFlags(flags))
+ {
++ assert(reg1 !=
++ REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
++ assert(reg2 != REG_PC);
++ assert(reg3 != REG_PC);
++
+ if ((reg1 == reg2) && isLowRegister(reg1))
+ {
+ // Use the Thumb-1 regdest,reg encoding
+@@ -2964,6 +3035,10 @@ void emitter::emitIns_R_R_R(instruction ins,
+
+ case INS_sdiv:
+ case INS_udiv:
++ assert(reg1 != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
++ assert(reg2 != REG_PC);
++ assert(reg3 != REG_PC);
++
+ assert(insDoesNotSetFlags(flags));
+ fmt = IF_T2_C5;
+ sf = INS_FLAGS_NOT_SET;
+@@ -3022,6 +3097,8 @@ void emitter::emitIns_R_R_R(instruction ins,
+ break;
+
+ case INS_vmov_i2d:
++ assert(reg2 != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
++ assert(reg3 != REG_PC);
+ assert(isDoubleReg(reg1));
+ assert(isGeneralRegister(reg2));
+ assert(isGeneralRegister(reg3));
+@@ -3030,6 +3107,8 @@ void emitter::emitIns_R_R_R(instruction ins,
+ break;
+
+ case INS_vmov_d2i:
++ assert(reg1 != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
++ assert(reg2 != REG_PC);
+ assert(isGeneralRegister(reg1));
+ assert(isGeneralRegister(reg2));
+ assert(isDoubleReg(reg3));
+@@ -3096,6 +3175,9 @@ void emitter::emitIns_R_R_I_I(instruction ins,
+ switch (ins)
+ {
+ case INS_bfi:
++ assert(reg1 != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
++ assert(reg2 != REG_PC);
++
+ assert(insDoesNotSetFlags(flags));
+ imm = (lsb << 5) | msb;
+
+@@ -3105,6 +3187,9 @@ void emitter::emitIns_R_R_I_I(instruction ins,
+
+ case INS_sbfx:
+ case INS_ubfx:
++ assert(reg1 != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
++ assert(reg2 != REG_PC);
++
+ assert(insDoesNotSetFlags(flags));
+ imm = (lsb << 5) | (width - 1);
+
+@@ -3189,6 +3274,9 @@ void emitter::emitIns_R_R_R_I(instruction ins,
+ case INS_orn:
+ case INS_orr:
+ case INS_sbc:
++ assert(reg1 != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
++ assert(reg2 != REG_PC);
++ assert(reg3 != REG_PC);
+ assert((imm >= 0) && (imm <= 31)); // required for encoding
+ assert(!insOptAnyInc(opt));
+ if (imm == 0)
+@@ -3339,6 +3427,11 @@ void emitter::emitIns_R_R_R_R(
+ }
+ assert((fmt == IF_T2_F1) || (fmt == IF_T2_F2));
+
++ assert(reg1 != REG_PC); // VM debugging single stepper doesn't support PC register with this instruction.
++ assert(reg2 != REG_PC);
++ assert(reg3 != REG_PC);
++ assert(reg4 != REG_PC);
++
+ instrDesc* id = emitNewInstr(attr);
+ insSize isz = emitInsSize(fmt);
+
+diff --git a/src/vm/arm/armsinglestepper.cpp b/src/vm/arm/armsinglestepper.cpp
+index e000959..72b0925 100644
+--- a/src/vm/arm/armsinglestepper.cpp
++++ b/src/vm/arm/armsinglestepper.cpp
+@@ -1043,6 +1043,21 @@ bool ArmSingleStepper::TryEmulate(T_CONTEXT *pCtx, WORD opcode1, WORD opcode2, b
+
+ fEmulated = true;
+ }
++ else if ((opcode1 & 0xff00) == 0x4400)
++ {
++ // A8.8.6 ADD (register, Thumb) : T2
++ DWORD Rm = BitExtract(opcode1, 6, 3);
++
++ // We should only emulate this instruction if Pc is used
++ if (Rm == 15)
++ fEmulated = true;
++
++ if (execute)
++ {
++ DWORD Rd = BitExtract(opcode1, 2, 0) | BitExtract(opcode1, 7, 7) << 3;
++ SetReg(pCtx, Rd, GetReg(pCtx, Rm) + GetReg(pCtx, Rd));
++ }
++ }
+ else if (((opcode1 & 0xf000) == 0xd000) && ((opcode1 & 0x0f00) != 0x0e00))
+ {
+ // B : T1
+--
+2.7.4
+
diff --git a/packaging/coreclr.spec b/packaging/coreclr.spec
index bbe3fbccb6..7a329f60e1 100755
--- a/packaging/coreclr.spec
+++ b/packaging/coreclr.spec
@@ -23,7 +23,7 @@ Source1000: downloaded_files.tar.gz
Source1001: %{name}.manifest
Source1002: libicu.tar.gz
Source1003: dep_libs.tar.gz
-# Gbp-Ignore-Patches: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
+# Gbp-Ignore-Patches: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129
Patch0: 0001-Add-project.assets.json-files.patch
Patch1: 0001-ARM-Linux-Support-unaligned-struct-read-write-11290.patch
Patch2: 0002-x86-Linux-Thread-safe-UMThunkMarshInfo-RunTimeInit-1.patch
@@ -153,6 +153,7 @@ Patch125: 0001-Fixed-Bug-with-xmm-registry-on-x86-emulator-183.patch
Patch126: 0002-Fix-unset-ZapRelocationType-for-fixup-18589.patch
Patch127: 0001-Tizen-Remove-tizen-release-package-dependency-for-GB.patch
Patch128: 0001-Fix-alternate-stack-for-Alpine-docker-on-SELinux-179.patch
+Patch129: 0001-Fixed-ARM-single-stepper-added-ADD-Rn-PC-command-emu.patch
ExcludeArch: aarch64
@@ -383,6 +384,7 @@ cp %{SOURCE1001} .
%patch126 -p1
%patch127 -p1
%patch128 -p1
+%patch129 -p1
cat > os-release <<EOF
NAME=Tizen