]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Bug 470132 - s390x: Fix the wrap-around case in VGM
authorAndreas Arnez <arnez@linux.ibm.com>
Mon, 22 May 2023 16:57:35 +0000 (18:57 +0200)
committerAndreas Arnez <arnez@linux.ibm.com>
Thu, 6 Jul 2023 15:15:08 +0000 (17:15 +0200)
Valgrind's implementation of VGM is incomplete:

* It doesn't support generating a wrap-around bit mask.  Such a mask
  should result when the ending bit position is smaller than the starting
  bit position.  Valgrind runs into an assertion failure instead.

* It doesn't ignore unused bits in the I2 and I3 fields of the
  instruction, as it should.

Fix this by re-implementing the main logic in s390_irgen_VGM().

NEWS
VEX/priv/guest_s390_toIR.c

diff --git a/NEWS b/NEWS
index a4e7533115f8ac7bda4e276862c03d6f8bc35a45..783612fbb90857e5a070310cea0c5fba3c4a225d 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -38,6 +38,7 @@ are not entered into bugzilla tend to get forgotten about or ignored.
 469146  massif --ignore-fn does not ignore inlined functions
 469768  Make it possible to install gdb scripts in a different location
 470121  Can't run callgrind_control with valgrind 3.21.0 because of perl errors
+470132  s390x: Assertion failure on VGM instruction
 470520  Multiple realloc zero errors crash in MC_(eq_Error)
 470713  Failure on the Yosys project: valgrind: m_libcfile.c:1802
         (Bool vgPlain_realpath(const HChar *, HChar *)):
index 11dda41ef5fca3535726f0862ef8e628911cb1df..d9d746c38ab007297d24f05416acb8e6e412405d 100644 (file)
@@ -16388,50 +16388,37 @@ s390_irgen_VGBM(UChar v1, UShort i2, UChar m3 __attribute__((unused)))
 static const HChar *
 s390_irgen_VGM(UChar v1, UShort i2, UChar m3)
 {
-   UChar from = (i2 & 0xff00) >> 8;
-   UChar to   = (i2 & 0x00ff);
-   ULong value = 0UL;
-   IRType type = s390_vr_get_type(m3);
-   vassert(from <= to);
-
-   UChar maxIndex = 0;
-   switch (type) {
-   case Ity_I8:
-      maxIndex = 7;
-      break;
-   case Ity_I16:
-      maxIndex = 15;
-      break;
-   case Ity_I32:
-      maxIndex = 31;
-      break;
-   case Ity_I64:
-      maxIndex = 63;
-      break;
-   default:
-      vpanic("s390_irgen_VGM: unknown type");
-   }
-
-   for(UChar index = from; index <= to; index++) {
-      value |= (1ULL << (maxIndex - index));
-   }
-
-   IRExpr *fillValue;
-   switch (type) {
-   case Ity_I8:
+   s390_insn_assert("vgm", m3 <= 3);
+
+   UChar  max_idx = (8 << m3) - 1;
+   UChar  from    = max_idx & (i2 >> 8);
+   UChar  to      = max_idx & i2;
+   ULong  all_one = (1ULL << max_idx << 1) - 1;
+   ULong  value   = (all_one >> from) ^ (all_one >> to >> 1);
+
+   /* In case of wrap-around we now have a value that needs inverting:
+          to         from
+          V           V
+      00000111111111110000000000000000 */
+   if (to < from)
+      value ^= all_one;
+
+   IRExpr* fillValue;
+   switch (m3) {
+   case 0:
       fillValue = mkU8(value);
       break;
-   case Ity_I16:
+   case 1:
       fillValue = mkU16(value);
       break;
-   case Ity_I32:
+   case 2:
       fillValue = mkU32(value);
       break;
-   case Ity_I64:
+   case 3:
       fillValue = mkU64(value);
       break;
    default:
-      vpanic("s390_irgen_VGM: unknown type");
+      vpanic("s390_irgen_VGM: unknown element size");
    }
 
    s390_vr_fill(v1, fillValue);