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