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