ubsan_value.h revision 4a4ef702597471bff5e249b8ec9d94d265007895
1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//===-- ubsan_value.h -------------------------------------------*- C++ -*-===// 2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// 3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// The LLVM Compiler Infrastructure 4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// 5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// This file is distributed under the University of Illinois Open Source 6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// License. See LICENSE.TXT for details. 7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// 8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//===----------------------------------------------------------------------===// 9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// 10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Representation of data which is passed from the compiler-generated calls into 11b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// the ubsan runtime. 12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// 13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//===----------------------------------------------------------------------===// 14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifndef UBSAN_VALUE_H 15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#define UBSAN_VALUE_H 16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 17b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// For now, only support linux and darwin. Other platforms should be easy to 18b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// add, and probably work as-is. 19b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#if !defined(__linux__) && !defined(__APPLE__) 20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#error "UBSan not supported for this platform!" 21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif 22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "sanitizer_common/sanitizer_common.h" 24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// FIXME: Move this out to a config header. 26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#if defined(__clang__) || __SIZEOF_INT128__ 27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgtypedef __int128 s128; 28fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgtypedef unsigned __int128 u128; 29fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org#define HAVE_INT128_T 1 30fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org#else 31fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org#define HAVE_INT128_T 0 32fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org#endif 33fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org 34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace __ubsan { 36fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org 37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/// \brief Largest integer types we support. 38fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org#if HAVE_INT128_T 39fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgtypedef s128 SIntMax; 40fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgtypedef u128 UIntMax; 41fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org#else 42fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgtypedef s64 SIntMax; 43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgtypedef u64 UIntMax; 44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif 45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/// \brief Largest floating-point type we support. 47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgtypedef long double FloatMax; 48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/// \brief A description of a source location. This corresponds to Clang's 51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/// \c PresumedLoc type. 52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass SourceLocation { 53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const char *Filename; 54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org u32 Line; 55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org u32 Column; 56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgpublic: 58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org SourceLocation() : Filename(), Line(), Column() {} 59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org SourceLocation(const char *Filename, unsigned Line, unsigned Column) 60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org : Filename(Filename), Line(Line), Column(Column) {} 61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// \brief Determine whether the source location is known. 63fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org bool isInvalid() const { return !Filename; } 64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org 65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// \brief Get the presumed filename for the source location. 66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org const char *getFilename() const { return Filename; } 67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org /// \brief Get the presumed line number. 68 unsigned getLine() const { return Line; } 69 /// \brief Get the column within the presumed line. 70 unsigned getColumn() const { return Column; } 71}; 72 73 74/// \brief A description of a type. 75class TypeDescriptor { 76 /// A value from the \c Kind enumeration, specifying what flavor of type we 77 /// have. 78 u16 TypeKind; 79 80 /// A \c Type-specific value providing information which allows us to 81 /// interpret the meaning of a ValueHandle of this type. 82 u16 TypeInfo; 83 84 /// The name of the type follows, in a format suitable for including in 85 /// diagnostics. 86 char TypeName[1]; 87 88public: 89 enum Kind { 90 /// An integer type. Lowest bit is 1 for a signed value, 0 for an unsigned 91 /// value. Remaining bits are log_2(bit width). The value representation is 92 /// the integer itself if it fits into a ValueHandle, and a pointer to the 93 /// integer otherwise. 94 TK_Integer = 0x0000, 95 /// A floating-point type. Low 16 bits are bit width. The value 96 /// representation is a pointer to the floating-point value. 97 TK_Float = 0x0001, 98 /// Any other type. The value representation is unspecified. 99 TK_Unknown = 0xffff 100 }; 101 102 const char *getTypeName() const { return TypeName; } 103 104 Kind getKind() const { 105 return static_cast<Kind>(TypeKind); 106 } 107 108 bool isIntegerTy() const { return getKind() == TK_Integer; } 109 bool isSignedIntegerTy() const { 110 return isIntegerTy() && (TypeInfo & 1); 111 } 112 bool isUnsignedIntegerTy() const { 113 return isIntegerTy() && !(TypeInfo & 1); 114 } 115 unsigned getIntegerBitWidth() const { 116 CHECK(isIntegerTy()); 117 return 1 << (TypeInfo >> 1); 118 } 119 120 bool isFloatTy() const { return getKind() == TK_Float; } 121 unsigned getFloatBitWidth() const { 122 CHECK(isFloatTy()); 123 return TypeInfo; 124 } 125}; 126 127/// \brief An opaque handle to a value. 128typedef uptr ValueHandle; 129 130 131/// \brief Representation of an operand value provided by the instrumented code. 132/// 133/// This is a combination of a TypeDescriptor (which is emitted as constant data 134/// as an operand to a handler function) and a ValueHandle (which is passed at 135/// runtime when a check failure occurs). 136class Value { 137 /// The type of the value. 138 const TypeDescriptor &Type; 139 /// The encoded value itself. 140 ValueHandle Val; 141 142 /// Is \c Val a (zero-extended) integer? 143 bool isInlineInt() const { 144 CHECK(getType().isIntegerTy()); 145 const unsigned InlineBits = sizeof(ValueHandle) * 8; 146 const unsigned Bits = getType().getIntegerBitWidth(); 147 return Bits <= InlineBits; 148 } 149 150public: 151 Value(const TypeDescriptor &Type, ValueHandle Val) : Type(Type), Val(Val) {} 152 153 const TypeDescriptor &getType() const { return Type; } 154 155 /// \brief Get this value as a signed integer. 156 SIntMax getSIntValue() const; 157 158 /// \brief Get this value as an unsigned integer. 159 UIntMax getUIntValue() const; 160 161 /// \brief Decode this value, which must be a positive or unsigned integer. 162 UIntMax getPositiveIntValue() const; 163 164 /// Is this an integer with value -1? 165 bool isMinusOne() const { 166 return getType().isSignedIntegerTy() && getSIntValue() == -1; 167 } 168 169 /// Is this a negative integer? 170 bool isNegative() const { 171 return getType().isSignedIntegerTy() && getSIntValue() < 0; 172 } 173 174 /// \brief Get this value as a floating-point quantity. 175 FloatMax getFloatValue() const; 176}; 177 178} // namespace __ubsan 179 180#endif // UBSAN_VALUE_H 181