Fix dotnet/coreclr#9457
authorjashook <jashoo@microsoft.com>
Mon, 13 Mar 2017 23:15:10 +0000 (16:15 -0700)
committerjashook <jashoo@microsoft.com>
Tue, 14 Mar 2017 17:21:23 +0000 (10:21 -0700)
To optimize code size we only added a UWC_END code if the last code in
uecMem does not equal UWC_END. However, the uec codes are variable sized
and allow any value to follow the code. Therefore, the value has the
small possibility to equal the value of UWC_END (0x4e on arm64
and 0xFF on arm32). Which incorrectly leaves the unwind array
unterminated.

Commit migrated from https://github.com/dotnet/coreclr/commit/43a3f8ed85b210fe5b1a4d56f1b887ad835f2f24

src/coreclr/src/jit/unwind.h
src/coreclr/tests/arm64/Tests.lst

index 27d23b1..c74ee2d 100644 (file)
@@ -321,7 +321,12 @@ class UnwindEpilogCodes : public UnwindBase, public UnwindCodesBase
 
 public:
     UnwindEpilogCodes(Compiler* comp)
-        : UnwindBase(comp), uecMem(uecMemLocal), uecMemSize(UEC_LOCAL_COUNT), uecCodeSlot(-1), uecFinalized(false)
+        : UnwindBase(comp)
+        , uecMem(uecMemLocal)
+        , firstByteOfLastCode(0)
+        , uecMemSize(UEC_LOCAL_COUNT)
+        , uecCodeSlot(-1)
+        , uecFinalized(false)
     {
     }
 
@@ -332,12 +337,16 @@ public:
     virtual void AddCode(BYTE b1)
     {
         AppendByte(b1);
+
+        firstByteOfLastCode = b1;
     }
 
     virtual void AddCode(BYTE b1, BYTE b2)
     {
         AppendByte(b1);
         AppendByte(b2);
+
+        firstByteOfLastCode = b1;
     }
 
     virtual void AddCode(BYTE b1, BYTE b2, BYTE b3)
@@ -345,6 +354,8 @@ public:
         AppendByte(b1);
         AppendByte(b2);
         AppendByte(b3);
+
+        firstByteOfLastCode = b1;
     }
 
     virtual void AddCode(BYTE b1, BYTE b2, BYTE b3, BYTE b4)
@@ -353,6 +364,8 @@ public:
         AppendByte(b2);
         AppendByte(b3);
         AppendByte(b4);
+
+        firstByteOfLastCode = b1;
     }
 
     // Return a pointer to the first unwind code byte
@@ -406,11 +419,13 @@ public:
     {
         assert(!uecFinalized);
         noway_assert(0 <= uecCodeSlot && uecCodeSlot < uecMemSize); // There better be at least one code!
-        BYTE lastCode = uecMem[uecCodeSlot];
-        if (!IsEndCode(lastCode)) // If the last code is an end code, we don't need to append one.
+
+        if (!IsEndCode(firstByteOfLastCode)) // If the last code is an end code, we don't need to append one.
         {
-            AppendByte(UWC_END); // Add a default "end" code to the end of the array of unwind codes
+            AppendByte(UWC_END);           // Add a default "end" code to the end of the array of unwind codes
+            firstByteOfLastCode = UWC_END; // Update firstByteOfLastCode in case we use it later
         }
+
         uecFinalized = true; // With the "end" code in place, now we're done
 
 #ifdef DEBUG
@@ -445,6 +460,7 @@ private:
     // If there are more unwind codes, we dynamically allocate memory.
     BYTE  uecMemLocal[UEC_LOCAL_COUNT];
     BYTE* uecMem;
+    BYTE  firstByteOfLastCode;
 
     // uecMemSize is the number of bytes/slots in uecMem. This is equal to UEC_LOCAL_COUNT unless
     // we've dynamically allocated memory to store the codes.
index a3bf508..7bc486a 100644 (file)
@@ -79297,7 +79297,7 @@ RelativePath=Loader\classloader\TypeGeneratorTests\TypeGeneratorTest963\Generate
 WorkingDir=Loader\classloader\TypeGeneratorTests\TypeGeneratorTest963\Generated963
 Expected=0
 MaxAllowedDurationSeconds=600
-Categories=EXPECTED_FAIL;9457;NEW
+Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
 [Generated407.cmd_10034]
@@ -85609,7 +85609,7 @@ RelativePath=Loader\classloader\TypeGeneratorTests\TypeGeneratorTest928\Generate
 WorkingDir=Loader\classloader\TypeGeneratorTests\TypeGeneratorTest928\Generated928
 Expected=0
 MaxAllowedDurationSeconds=600
-Categories=EXPECTED_FAIL;9457;NEW
+Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
 [DevDiv_367099.cmd_10823]
@@ -86337,7 +86337,7 @@ RelativePath=Loader\classloader\TypeGeneratorTests\TypeGeneratorTest763\Generate
 WorkingDir=Loader\classloader\TypeGeneratorTests\TypeGeneratorTest763\Generated763
 Expected=0
 MaxAllowedDurationSeconds=600
-Categories=EXPECTED_FAIL;9457;NEW
+Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
 [Generated1349.cmd_10914]
@@ -87313,7 +87313,7 @@ RelativePath=Loader\classloader\TypeGeneratorTests\TypeGeneratorTest693\Generate
 WorkingDir=Loader\classloader\TypeGeneratorTests\TypeGeneratorTest693\Generated693
 Expected=0
 MaxAllowedDurationSeconds=600
-Categories=EXPECTED_FAIL;9457;NEW
+Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
 [Generated500.cmd_11036]
@@ -88401,7 +88401,7 @@ RelativePath=Loader\classloader\TypeGeneratorTests\TypeGeneratorTest688\Generate
 WorkingDir=Loader\classloader\TypeGeneratorTests\TypeGeneratorTest688\Generated688
 Expected=0
 MaxAllowedDurationSeconds=600
-Categories=EXPECTED_FAIL;9457;NEW
+Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
 [Generated169.cmd_11172]
@@ -89577,7 +89577,7 @@ RelativePath=Loader\classloader\TypeGeneratorTests\TypeGeneratorTest1411\Generat
 WorkingDir=Loader\classloader\TypeGeneratorTests\TypeGeneratorTest1411\Generated1411
 Expected=0
 MaxAllowedDurationSeconds=600
-Categories=EXPECTED_FAIL;9457;NEW
+Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
 [Generated303.cmd_11319]
@@ -90065,7 +90065,7 @@ RelativePath=Loader\classloader\TypeGeneratorTests\TypeGeneratorTest1412\Generat
 WorkingDir=Loader\classloader\TypeGeneratorTests\TypeGeneratorTest1412\Generated1412
 Expected=0
 MaxAllowedDurationSeconds=600
-Categories=EXPECTED_FAIL;9457;NEW
+Categories=EXPECTED_PASS;NEW
 HostStyle=0
 
 [Generated1272.cmd_11380]