16ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith//===-- ubsan_value.h -------------------------------------------*- C++ -*-===// 26ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith// 36ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith// The LLVM Compiler Infrastructure 46ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith// 56ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith// This file is distributed under the University of Illinois Open Source 66ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith// License. See LICENSE.TXT for details. 76ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith// 86ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith//===----------------------------------------------------------------------===// 96ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith// 106ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith// Representation of data which is passed from the compiler-generated calls into 116ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith// the ubsan runtime. 126ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith// 136ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith//===----------------------------------------------------------------------===// 146ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith#ifndef UBSAN_VALUE_H 156ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith#define UBSAN_VALUE_H 166ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 172173dc70641466e166b5f9485bdb3a26eaa2ba1fWill Dietz#include "sanitizer_common/sanitizer_atomic.h" 186ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith#include "sanitizer_common/sanitizer_common.h" 196ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 206ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith// FIXME: Move this out to a config header. 21e656184a2e20c0293cf838885204216cdf1db168Richard Smith#if __SIZEOF_INT128__ 222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines__extension__ typedef __int128 s128; 232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines__extension__ typedef unsigned __int128 u128; 246ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith#define HAVE_INT128_T 1 25ba3fde65b900ce9d0ecdf034dfe3825eea810434Chandler Carruth#else 26ba3fde65b900ce9d0ecdf034dfe3825eea810434Chandler Carruth#define HAVE_INT128_T 0 27ba3fde65b900ce9d0ecdf034dfe3825eea810434Chandler Carruth#endif 286ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 296ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smithnamespace __ubsan { 306ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 316ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith/// \brief Largest integer types we support. 32ba3fde65b900ce9d0ecdf034dfe3825eea810434Chandler Carruth#if HAVE_INT128_T 336ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smithtypedef s128 SIntMax; 346ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smithtypedef u128 UIntMax; 356ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith#else 366ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smithtypedef s64 SIntMax; 376ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smithtypedef u64 UIntMax; 386ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith#endif 396ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 4058561700a4abad310911a24a867da49a14fae91eRichard Smith/// \brief Largest floating-point type we support. 4158561700a4abad310911a24a867da49a14fae91eRichard Smithtypedef long double FloatMax; 4258561700a4abad310911a24a867da49a14fae91eRichard Smith 436ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith/// \brief A description of a source location. This corresponds to Clang's 446ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith/// \c PresumedLoc type. 456ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smithclass SourceLocation { 466ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith const char *Filename; 476ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith u32 Line; 486ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith u32 Column; 496ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 506ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smithpublic: 5158561700a4abad310911a24a867da49a14fae91eRichard Smith SourceLocation() : Filename(), Line(), Column() {} 526ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith SourceLocation(const char *Filename, unsigned Line, unsigned Column) 536ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith : Filename(Filename), Line(Line), Column(Column) {} 546ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 556ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// \brief Determine whether the source location is known. 566ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith bool isInvalid() const { return !Filename; } 576ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 582af552f98f980178db37eed28a609b6bf55f6df8Will Dietz /// \brief Atomically acquire a copy, disabling original in-place. 592af552f98f980178db37eed28a609b6bf55f6df8Will Dietz /// Exactly one call to acquire() returns a copy that isn't disabled. 602af552f98f980178db37eed28a609b6bf55f6df8Will Dietz SourceLocation acquire() { 612173dc70641466e166b5f9485bdb3a26eaa2ba1fWill Dietz u32 OldColumn = __sanitizer::atomic_exchange( 622173dc70641466e166b5f9485bdb3a26eaa2ba1fWill Dietz (__sanitizer::atomic_uint32_t *)&Column, ~u32(0), 632173dc70641466e166b5f9485bdb3a26eaa2ba1fWill Dietz __sanitizer::memory_order_relaxed); 642af552f98f980178db37eed28a609b6bf55f6df8Will Dietz return SourceLocation(Filename, Line, OldColumn); 652af552f98f980178db37eed28a609b6bf55f6df8Will Dietz } 662af552f98f980178db37eed28a609b6bf55f6df8Will Dietz 672af552f98f980178db37eed28a609b6bf55f6df8Will Dietz /// \brief Determine if this Location has been disabled. 682af552f98f980178db37eed28a609b6bf55f6df8Will Dietz /// Disabled SourceLocations are invalid to use. 692af552f98f980178db37eed28a609b6bf55f6df8Will Dietz bool isDisabled() { 702af552f98f980178db37eed28a609b6bf55f6df8Will Dietz return Column == ~u32(0); 712af552f98f980178db37eed28a609b6bf55f6df8Will Dietz } 722af552f98f980178db37eed28a609b6bf55f6df8Will Dietz 736ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// \brief Get the presumed filename for the source location. 746ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith const char *getFilename() const { return Filename; } 756ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// \brief Get the presumed line number. 766ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith unsigned getLine() const { return Line; } 776ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// \brief Get the column within the presumed line. 786ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith unsigned getColumn() const { return Column; } 796ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith}; 806ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 816ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 826ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith/// \brief A description of a type. 836ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smithclass TypeDescriptor { 846ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// A value from the \c Kind enumeration, specifying what flavor of type we 856ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// have. 866ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith u16 TypeKind; 876ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 886ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// A \c Type-specific value providing information which allows us to 896ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// interpret the meaning of a ValueHandle of this type. 906ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith u16 TypeInfo; 916ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 92ed81c21984efb8c1f96c82de1dd5dbcea5d7aa65Richard Smith /// The name of the type follows, in a format suitable for including in 93ed81c21984efb8c1f96c82de1dd5dbcea5d7aa65Richard Smith /// diagnostics. 94ed81c21984efb8c1f96c82de1dd5dbcea5d7aa65Richard Smith char TypeName[1]; 95ed81c21984efb8c1f96c82de1dd5dbcea5d7aa65Richard Smith 966ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smithpublic: 976ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith enum Kind { 986ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// An integer type. Lowest bit is 1 for a signed value, 0 for an unsigned 996ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// value. Remaining bits are log_2(bit width). The value representation is 1006ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// the integer itself if it fits into a ValueHandle, and a pointer to the 1016ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// integer otherwise. 1026ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith TK_Integer = 0x0000, 1036ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// A floating-point type. Low 16 bits are bit width. The value 104ec7962d874159f02ad9b1657b627ceb53fea55abRichard Smith /// representation is that of bitcasting the floating-point value to an 105ec7962d874159f02ad9b1657b627ceb53fea55abRichard Smith /// integer type. 1066ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith TK_Float = 0x0001, 1076ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// Any other type. The value representation is unspecified. 1086ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith TK_Unknown = 0xffff 1096ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith }; 1106ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 1116ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith const char *getTypeName() const { return TypeName; } 1126ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 1136ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith Kind getKind() const { 1146ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith return static_cast<Kind>(TypeKind); 1156ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith } 1166ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 1176ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith bool isIntegerTy() const { return getKind() == TK_Integer; } 1186ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith bool isSignedIntegerTy() const { 1196ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith return isIntegerTy() && (TypeInfo & 1); 1206ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith } 1216ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith bool isUnsignedIntegerTy() const { 1226ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith return isIntegerTy() && !(TypeInfo & 1); 1236ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith } 1246ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith unsigned getIntegerBitWidth() const { 1256ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith CHECK(isIntegerTy()); 1266ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith return 1 << (TypeInfo >> 1); 1276ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith } 1286ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 1296ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith bool isFloatTy() const { return getKind() == TK_Float; } 1306ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith unsigned getFloatBitWidth() const { 1316ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith CHECK(isFloatTy()); 1326ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith return TypeInfo; 1336ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith } 1346ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith}; 1356ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 1366ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith/// \brief An opaque handle to a value. 1376ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smithtypedef uptr ValueHandle; 1386ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 1396ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 1406ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith/// \brief Representation of an operand value provided by the instrumented code. 1416ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith/// 1426ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith/// This is a combination of a TypeDescriptor (which is emitted as constant data 1436ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith/// as an operand to a handler function) and a ValueHandle (which is passed at 1446ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith/// runtime when a check failure occurs). 1456ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smithclass Value { 1466ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// The type of the value. 1476ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith const TypeDescriptor &Type; 1486ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// The encoded value itself. 1496ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith ValueHandle Val; 1506ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 1516ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// Is \c Val a (zero-extended) integer? 1526ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith bool isInlineInt() const { 1536ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith CHECK(getType().isIntegerTy()); 1546ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith const unsigned InlineBits = sizeof(ValueHandle) * 8; 1556ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith const unsigned Bits = getType().getIntegerBitWidth(); 1566ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith return Bits <= InlineBits; 1576ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith } 1586ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 159ec7962d874159f02ad9b1657b627ceb53fea55abRichard Smith /// Is \c Val a (zero-extended) integer representation of a float? 160ec7962d874159f02ad9b1657b627ceb53fea55abRichard Smith bool isInlineFloat() const { 161ec7962d874159f02ad9b1657b627ceb53fea55abRichard Smith CHECK(getType().isFloatTy()); 162ec7962d874159f02ad9b1657b627ceb53fea55abRichard Smith const unsigned InlineBits = sizeof(ValueHandle) * 8; 163ec7962d874159f02ad9b1657b627ceb53fea55abRichard Smith const unsigned Bits = getType().getFloatBitWidth(); 164ec7962d874159f02ad9b1657b627ceb53fea55abRichard Smith return Bits <= InlineBits; 165ec7962d874159f02ad9b1657b627ceb53fea55abRichard Smith } 166ec7962d874159f02ad9b1657b627ceb53fea55abRichard Smith 1676ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smithpublic: 1686ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith Value(const TypeDescriptor &Type, ValueHandle Val) : Type(Type), Val(Val) {} 1696ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 1706ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith const TypeDescriptor &getType() const { return Type; } 1716ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 1726ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// \brief Get this value as a signed integer. 1736ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith SIntMax getSIntValue() const; 1746ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 1756ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// \brief Get this value as an unsigned integer. 1766ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith UIntMax getUIntValue() const; 1776ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 1786ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// \brief Decode this value, which must be a positive or unsigned integer. 1796ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith UIntMax getPositiveIntValue() const; 1806ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 1816ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// Is this an integer with value -1? 1826ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith bool isMinusOne() const { 1836ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith return getType().isSignedIntegerTy() && getSIntValue() == -1; 1846ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith } 1856ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 1866ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// Is this a negative integer? 1876ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith bool isNegative() const { 1886ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith return getType().isSignedIntegerTy() && getSIntValue() < 0; 1896ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith } 1906ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 1916ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// \brief Get this value as a floating-point quantity. 19258561700a4abad310911a24a867da49a14fae91eRichard Smith FloatMax getFloatValue() const; 1936ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith}; 1946ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 1956ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith} // namespace __ubsan 1966ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 1976ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith#endif // UBSAN_VALUE_H 198