1 1.1 kamil //===-- ubsan_value.cc ----------------------------------------------------===// 2 1.1 kamil // 3 1.1 kamil // The LLVM Compiler Infrastructure 4 1.1 kamil // 5 1.1 kamil // This file is distributed under the University of Illinois Open Source 6 1.1 kamil // License. See LICENSE.TXT for details. 7 1.1 kamil // 8 1.1 kamil //===----------------------------------------------------------------------===// 9 1.1 kamil // 10 1.1 kamil // Representation of a runtime value, as marshaled from the generated code to 11 1.1 kamil // the ubsan runtime. 12 1.1 kamil // 13 1.1 kamil //===----------------------------------------------------------------------===// 14 1.1 kamil 15 1.1 kamil #include "ubsan_platform.h" 16 1.1 kamil #if CAN_SANITIZE_UB 17 1.1 kamil #include "ubsan_value.h" 18 1.1 kamil #include "sanitizer_common/sanitizer_common.h" 19 1.1 kamil #include "sanitizer_common/sanitizer_libc.h" 20 1.1 kamil 21 1.1 kamil using namespace __ubsan; 22 1.1 kamil 23 1.1 kamil SIntMax Value::getSIntValue() const { 24 1.1 kamil CHECK(getType().isSignedIntegerTy()); 25 1.1 kamil if (isInlineInt()) { 26 1.1 kamil // Val was zero-extended to ValueHandle. Sign-extend from original width 27 1.1 kamil // to SIntMax. 28 1.1 kamil const unsigned ExtraBits = 29 1.1 kamil sizeof(SIntMax) * 8 - getType().getIntegerBitWidth(); 30 1.1 kamil return SIntMax(Val) << ExtraBits >> ExtraBits; 31 1.1 kamil } 32 1.1 kamil if (getType().getIntegerBitWidth() == 64) 33 1.1 kamil return *reinterpret_cast<s64*>(Val); 34 1.1 kamil #if HAVE_INT128_T 35 1.1 kamil if (getType().getIntegerBitWidth() == 128) 36 1.1 kamil return *reinterpret_cast<s128*>(Val); 37 1.1 kamil #else 38 1.1 kamil if (getType().getIntegerBitWidth() == 128) 39 1.1 kamil UNREACHABLE("libclang_rt.ubsan was built without __int128 support"); 40 1.1 kamil #endif 41 1.1 kamil UNREACHABLE("unexpected bit width"); 42 1.1 kamil } 43 1.1 kamil 44 1.1 kamil UIntMax Value::getUIntValue() const { 45 1.1 kamil CHECK(getType().isUnsignedIntegerTy()); 46 1.1 kamil if (isInlineInt()) 47 1.1 kamil return Val; 48 1.1 kamil if (getType().getIntegerBitWidth() == 64) 49 1.1 kamil return *reinterpret_cast<u64*>(Val); 50 1.1 kamil #if HAVE_INT128_T 51 1.1 kamil if (getType().getIntegerBitWidth() == 128) 52 1.1 kamil return *reinterpret_cast<u128*>(Val); 53 1.1 kamil #else 54 1.1 kamil if (getType().getIntegerBitWidth() == 128) 55 1.1 kamil UNREACHABLE("libclang_rt.ubsan was built without __int128 support"); 56 1.1 kamil #endif 57 1.1 kamil UNREACHABLE("unexpected bit width"); 58 1.1 kamil } 59 1.1 kamil 60 1.1 kamil UIntMax Value::getPositiveIntValue() const { 61 1.1 kamil if (getType().isUnsignedIntegerTy()) 62 1.1 kamil return getUIntValue(); 63 1.1 kamil SIntMax Val = getSIntValue(); 64 1.1 kamil CHECK(Val >= 0); 65 1.1 kamil return Val; 66 1.1 kamil } 67 1.1 kamil 68 1.1 kamil /// Get the floating-point value of this object, extended to a long double. 69 1.1 kamil /// These are always passed by address (our calling convention doesn't allow 70 1.1 kamil /// them to be passed in floating-point registers, so this has little cost). 71 1.1 kamil FloatMax Value::getFloatValue() const { 72 1.1 kamil CHECK(getType().isFloatTy()); 73 1.1 kamil if (isInlineFloat()) { 74 1.1 kamil switch (getType().getFloatBitWidth()) { 75 1.1 kamil #if 0 76 1.1 kamil // FIXME: OpenCL / NEON 'half' type. LLVM can't lower the conversion 77 1.1 kamil // from '__fp16' to 'long double'. 78 1.1 kamil case 16: { 79 1.1 kamil __fp16 Value; 80 1.1 kamil internal_memcpy(&Value, &Val, 4); 81 1.1 kamil return Value; 82 1.1 kamil } 83 1.1 kamil #endif 84 1.1 kamil case 32: { 85 1.1 kamil float Value; 86 1.1 kamil #if defined(__BYTE_ORDER__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 87 1.1 kamil // For big endian the float value is in the last 4 bytes. 88 1.1 kamil // On some targets we may only have 4 bytes so we count backwards from 89 1.1 kamil // the end of Val to account for both the 32-bit and 64-bit cases. 90 1.1 kamil internal_memcpy(&Value, ((const char*)(&Val + 1)) - 4, 4); 91 1.1 kamil #else 92 1.1 kamil internal_memcpy(&Value, &Val, 4); 93 1.1 kamil #endif 94 1.1 kamil return Value; 95 1.1 kamil } 96 1.1 kamil case 64: { 97 1.1 kamil double Value; 98 1.1 kamil internal_memcpy(&Value, &Val, 8); 99 1.1 kamil return Value; 100 1.1 kamil } 101 1.1 kamil } 102 1.1 kamil } else { 103 1.1 kamil switch (getType().getFloatBitWidth()) { 104 1.1 kamil case 64: return *reinterpret_cast<double*>(Val); 105 1.1 kamil case 80: return *reinterpret_cast<long double*>(Val); 106 1.1 kamil case 96: return *reinterpret_cast<long double*>(Val); 107 1.1 kamil case 128: return *reinterpret_cast<long double*>(Val); 108 1.1 kamil } 109 1.1 kamil } 110 1.1 kamil UNREACHABLE("unexpected floating point bit width"); 111 1.1 kamil } 112 1.1 kamil 113 1.1 kamil #endif // CAN_SANITIZE_UB 114