Fix http://llvm.org/bugs/show_bug.cgi?id=10583\n - test for 1 and 2 byte fixups to...
authorJason W Kim <jason.w.kim.2009@gmail.com>
Fri, 5 Aug 2011 00:53:03 +0000 (00:53 +0000)
committerJason W Kim <jason.w.kim.2009@gmail.com>
Fri, 5 Aug 2011 00:53:03 +0000 (00:53 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@136954 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp

index e7713f34321b340b533f390b697c48e2f95267dd..05f46f6b6b18eed64800b846cb7f4f1b9be050d5 100644 (file)
@@ -94,21 +94,17 @@ public:
     assert(Fixup.getOffset() + Size <= DataSize &&
            "Invalid fixup offset!");
 
-    // Check that the upper bits are either all 0 or all 1's
-    switch (Size) {
-    case 1: 
-      assert((isInt<8>(Value) || isUInt<8>(Value)) && 
-             "Value does not fit in a 1Byte Reloc");
-      break;
-    case 2: 
-      assert((isInt<16>(Value) || isUInt<16>(Value)) && 
-             "Value does not fit in a 2Byte Reloc");
-      break;
-    case 4:
-      assert((isInt<32>(Value) || isUInt<32>(Value)) && 
-             "Value does not fit in a 4Byte Reloc");
-      break;
-    }
+    // Check that uppper bits are either all zeros or all ones.
+    // Specifically ignore overflow/underflow as long as the leakage is
+    // limited to the lower bits. This is to remain compatible with
+    // other assemblers.
+
+    const uint64_t Mask = ~0ULL;
+    const uint64_t UpperV = (Value >> (Size * 8));
+    const uint64_t MaskF = (Mask >> (Size * 8));
+    assert(((Size == 8) ||
+            ((UpperV & MaskF) == 0ULL) || ((UpperV & MaskF) == MaskF)) &&
+           "Value does not fit in the Fixup field");
 
     for (unsigned i = 0; i != Size; ++i)
       Data[Fixup.getOffset() + i] = uint8_t(Value >> (i * 8));