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 174a4ef702597471bff5e249b8ec9d94d265007895Richard Smith// For now, only support linux and darwin. Other platforms should be easy to 184a4ef702597471bff5e249b8ec9d94d265007895Richard Smith// add, and probably work as-is. 194a4ef702597471bff5e249b8ec9d94d265007895Richard Smith#if !defined(__linux__) && !defined(__APPLE__) 206ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith#error "UBSan not supported for this platform!" 216ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith#endif 226ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 232173dc70641466e166b5f9485bdb3a26eaa2ba1fWill Dietz#include "sanitizer_common/sanitizer_atomic.h" 246ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith#include "sanitizer_common/sanitizer_common.h" 256ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 266ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith// FIXME: Move this out to a config header. 27e656184a2e20c0293cf838885204216cdf1db168Richard Smith#if __SIZEOF_INT128__ 286ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smithtypedef __int128 s128; 296ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smithtypedef unsigned __int128 u128; 306ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith#define HAVE_INT128_T 1 31ba3fde65b900ce9d0ecdf034dfe3825eea810434Chandler Carruth#else 32ba3fde65b900ce9d0ecdf034dfe3825eea810434Chandler Carruth#define HAVE_INT128_T 0 33ba3fde65b900ce9d0ecdf034dfe3825eea810434Chandler Carruth#endif 346ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 356ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 366ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smithnamespace __ubsan { 376ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 386ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith/// \brief Largest integer types we support. 39ba3fde65b900ce9d0ecdf034dfe3825eea810434Chandler Carruth#if HAVE_INT128_T 406ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smithtypedef s128 SIntMax; 416ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smithtypedef u128 UIntMax; 426ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith#else 436ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smithtypedef s64 SIntMax; 446ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smithtypedef u64 UIntMax; 456ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith#endif 466ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 4758561700a4abad310911a24a867da49a14fae91eRichard Smith/// \brief Largest floating-point type we support. 4858561700a4abad310911a24a867da49a14fae91eRichard Smithtypedef long double FloatMax; 4958561700a4abad310911a24a867da49a14fae91eRichard Smith 506ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith/// \brief A description of a source location. This corresponds to Clang's 516ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith/// \c PresumedLoc type. 526ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smithclass SourceLocation { 536ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith const char *Filename; 546ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith u32 Line; 556ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith u32 Column; 566ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 576ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smithpublic: 5858561700a4abad310911a24a867da49a14fae91eRichard Smith SourceLocation() : Filename(), Line(), Column() {} 596ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith SourceLocation(const char *Filename, unsigned Line, unsigned Column) 606ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith : Filename(Filename), Line(Line), Column(Column) {} 616ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 626ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// \brief Determine whether the source location is known. 636ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith bool isInvalid() const { return !Filename; } 646ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 652af552f98f980178db37eed28a609b6bf55f6df8Will Dietz /// \brief Atomically acquire a copy, disabling original in-place. 662af552f98f980178db37eed28a609b6bf55f6df8Will Dietz /// Exactly one call to acquire() returns a copy that isn't disabled. 672af552f98f980178db37eed28a609b6bf55f6df8Will Dietz SourceLocation acquire() { 682173dc70641466e166b5f9485bdb3a26eaa2ba1fWill Dietz u32 OldColumn = __sanitizer::atomic_exchange( 692173dc70641466e166b5f9485bdb3a26eaa2ba1fWill Dietz (__sanitizer::atomic_uint32_t *)&Column, ~u32(0), 702173dc70641466e166b5f9485bdb3a26eaa2ba1fWill Dietz __sanitizer::memory_order_relaxed); 712af552f98f980178db37eed28a609b6bf55f6df8Will Dietz return SourceLocation(Filename, Line, OldColumn); 722af552f98f980178db37eed28a609b6bf55f6df8Will Dietz } 732af552f98f980178db37eed28a609b6bf55f6df8Will Dietz 742af552f98f980178db37eed28a609b6bf55f6df8Will Dietz /// \brief Determine if this Location has been disabled. 752af552f98f980178db37eed28a609b6bf55f6df8Will Dietz /// Disabled SourceLocations are invalid to use. 762af552f98f980178db37eed28a609b6bf55f6df8Will Dietz bool isDisabled() { 772af552f98f980178db37eed28a609b6bf55f6df8Will Dietz return Column == ~u32(0); 782af552f98f980178db37eed28a609b6bf55f6df8Will Dietz } 792af552f98f980178db37eed28a609b6bf55f6df8Will Dietz 806ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// \brief Get the presumed filename for the source location. 816ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith const char *getFilename() const { return Filename; } 826ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// \brief Get the presumed line number. 836ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith unsigned getLine() const { return Line; } 846ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// \brief Get the column within the presumed line. 856ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith unsigned getColumn() const { return Column; } 866ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith}; 876ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 886ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 896ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith/// \brief A description of a type. 906ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smithclass TypeDescriptor { 916ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// A value from the \c Kind enumeration, specifying what flavor of type we 926ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// have. 936ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith u16 TypeKind; 946ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 956ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// A \c Type-specific value providing information which allows us to 966ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// interpret the meaning of a ValueHandle of this type. 976ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith u16 TypeInfo; 986ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 99ed81c21984efb8c1f96c82de1dd5dbcea5d7aa65Richard Smith /// The name of the type follows, in a format suitable for including in 100ed81c21984efb8c1f96c82de1dd5dbcea5d7aa65Richard Smith /// diagnostics. 101ed81c21984efb8c1f96c82de1dd5dbcea5d7aa65Richard Smith char TypeName[1]; 102ed81c21984efb8c1f96c82de1dd5dbcea5d7aa65Richard Smith 1036ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smithpublic: 1046ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith enum Kind { 1056ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// An integer type. Lowest bit is 1 for a signed value, 0 for an unsigned 1066ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// value. Remaining bits are log_2(bit width). The value representation is 1076ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// the integer itself if it fits into a ValueHandle, and a pointer to the 1086ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// integer otherwise. 1096ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith TK_Integer = 0x0000, 1106ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// A floating-point type. Low 16 bits are bit width. The value 111ec7962d874159f02ad9b1657b627ceb53fea55abRichard Smith /// representation is that of bitcasting the floating-point value to an 112ec7962d874159f02ad9b1657b627ceb53fea55abRichard Smith /// integer type. 1136ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith TK_Float = 0x0001, 1146ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// Any other type. The value representation is unspecified. 1156ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith TK_Unknown = 0xffff 1166ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith }; 1176ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 1186ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith const char *getTypeName() const { return TypeName; } 1196ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 1206ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith Kind getKind() const { 1216ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith return static_cast<Kind>(TypeKind); 1226ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith } 1236ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 1246ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith bool isIntegerTy() const { return getKind() == TK_Integer; } 1256ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith bool isSignedIntegerTy() const { 1266ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith return isIntegerTy() && (TypeInfo & 1); 1276ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith } 1286ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith bool isUnsignedIntegerTy() const { 1296ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith return isIntegerTy() && !(TypeInfo & 1); 1306ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith } 1316ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith unsigned getIntegerBitWidth() const { 1326ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith CHECK(isIntegerTy()); 1336ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith return 1 << (TypeInfo >> 1); 1346ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith } 1356ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 1366ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith bool isFloatTy() const { return getKind() == TK_Float; } 1376ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith unsigned getFloatBitWidth() const { 1386ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith CHECK(isFloatTy()); 1396ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith return TypeInfo; 1406ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith } 1416ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith}; 1426ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 1436ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith/// \brief An opaque handle to a value. 1446ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smithtypedef uptr ValueHandle; 1456ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 1466ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 1476ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith/// \brief Representation of an operand value provided by the instrumented code. 1486ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith/// 1496ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith/// This is a combination of a TypeDescriptor (which is emitted as constant data 1506ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith/// as an operand to a handler function) and a ValueHandle (which is passed at 1516ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith/// runtime when a check failure occurs). 1526ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smithclass Value { 1536ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// The type of the value. 1546ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith const TypeDescriptor &Type; 1556ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// The encoded value itself. 1566ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith ValueHandle Val; 1576ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 1586ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// Is \c Val a (zero-extended) integer? 1596ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith bool isInlineInt() const { 1606ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith CHECK(getType().isIntegerTy()); 1616ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith const unsigned InlineBits = sizeof(ValueHandle) * 8; 1626ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith const unsigned Bits = getType().getIntegerBitWidth(); 1636ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith return Bits <= InlineBits; 1646ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith } 1656ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 166ec7962d874159f02ad9b1657b627ceb53fea55abRichard Smith /// Is \c Val a (zero-extended) integer representation of a float? 167ec7962d874159f02ad9b1657b627ceb53fea55abRichard Smith bool isInlineFloat() const { 168ec7962d874159f02ad9b1657b627ceb53fea55abRichard Smith CHECK(getType().isFloatTy()); 169ec7962d874159f02ad9b1657b627ceb53fea55abRichard Smith const unsigned InlineBits = sizeof(ValueHandle) * 8; 170ec7962d874159f02ad9b1657b627ceb53fea55abRichard Smith const unsigned Bits = getType().getFloatBitWidth(); 171ec7962d874159f02ad9b1657b627ceb53fea55abRichard Smith return Bits <= InlineBits; 172ec7962d874159f02ad9b1657b627ceb53fea55abRichard Smith } 173ec7962d874159f02ad9b1657b627ceb53fea55abRichard Smith 1746ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smithpublic: 1756ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith Value(const TypeDescriptor &Type, ValueHandle Val) : Type(Type), Val(Val) {} 1766ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 1776ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith const TypeDescriptor &getType() const { return Type; } 1786ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 1796ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// \brief Get this value as a signed integer. 1806ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith SIntMax getSIntValue() const; 1816ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 1826ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// \brief Get this value as an unsigned integer. 1836ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith UIntMax getUIntValue() const; 1846ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 1856ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// \brief Decode this value, which must be a positive or unsigned integer. 1866ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith UIntMax getPositiveIntValue() const; 1876ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 1886ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// Is this an integer with value -1? 1896ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith bool isMinusOne() const { 1906ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith return getType().isSignedIntegerTy() && getSIntValue() == -1; 1916ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith } 1926ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 1936ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// Is this a negative integer? 1946ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith bool isNegative() const { 1956ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith return getType().isSignedIntegerTy() && getSIntValue() < 0; 1966ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith } 1976ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 1986ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith /// \brief Get this value as a floating-point quantity. 19958561700a4abad310911a24a867da49a14fae91eRichard Smith FloatMax getFloatValue() const; 2006ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith}; 2016ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 2026ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith} // namespace __ubsan 2036ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith 2046ebe45146a2d93eb010b9bb5ea34cb94c6900f83Richard Smith#endif // UBSAN_VALUE_H 205