(root)/
gcc-13.2.0/
libsanitizer/
ubsan/
ubsan_value.h
       1  //===-- ubsan_value.h -------------------------------------------*- C++ -*-===//
       2  //
       3  // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
       4  // See https://llvm.org/LICENSE.txt for license information.
       5  // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
       6  //
       7  //===----------------------------------------------------------------------===//
       8  //
       9  // Representation of data which is passed from the compiler-generated calls into
      10  // the ubsan runtime.
      11  //
      12  //===----------------------------------------------------------------------===//
      13  #ifndef UBSAN_VALUE_H
      14  #define UBSAN_VALUE_H
      15  
      16  #include "sanitizer_common/sanitizer_atomic.h"
      17  #include "sanitizer_common/sanitizer_common.h"
      18  
      19  // FIXME: Move this out to a config header.
      20  #if __SIZEOF_INT128__
      21  __extension__ typedef __int128 s128;
      22  __extension__ typedef unsigned __int128 u128;
      23  #define HAVE_INT128_T 1
      24  #else
      25  #define HAVE_INT128_T 0
      26  #endif
      27  
      28  namespace __ubsan {
      29  
      30  /// \brief Largest integer types we support.
      31  #if HAVE_INT128_T
      32  typedef s128 SIntMax;
      33  typedef u128 UIntMax;
      34  #else
      35  typedef s64 SIntMax;
      36  typedef u64 UIntMax;
      37  #endif
      38  
      39  /// \brief Largest floating-point type we support.
      40  typedef long double FloatMax;
      41  
      42  /// \brief A description of a source location. This corresponds to Clang's
      43  /// \c PresumedLoc type.
      44  class SourceLocation {
      45    const char *Filename;
      46    u32 Line;
      47    u32 Column;
      48  
      49  public:
      50    SourceLocation() : Filename(), Line(), Column() {}
      51    SourceLocation(const char *Filename, unsigned Line, unsigned Column)
      52      : Filename(Filename), Line(Line), Column(Column) {}
      53  
      54    /// \brief Determine whether the source location is known.
      55    bool isInvalid() const { return !Filename; }
      56  
      57    /// \brief Atomically acquire a copy, disabling original in-place.
      58    /// Exactly one call to acquire() returns a copy that isn't disabled.
      59    SourceLocation acquire() {
      60      u32 OldColumn = __sanitizer::atomic_exchange(
      61                          (__sanitizer::atomic_uint32_t *)&Column, ~u32(0),
      62                          __sanitizer::memory_order_relaxed);
      63      return SourceLocation(Filename, Line, OldColumn);
      64    }
      65  
      66    /// \brief Determine if this Location has been disabled.
      67    /// Disabled SourceLocations are invalid to use.
      68    bool isDisabled() {
      69      return Column == ~u32(0);
      70    }
      71  
      72    /// \brief Get the presumed filename for the source location.
      73    const char *getFilename() const { return Filename; }
      74    /// \brief Get the presumed line number.
      75    unsigned getLine() const { return Line; }
      76    /// \brief Get the column within the presumed line.
      77    unsigned getColumn() const { return Column; }
      78  };
      79  
      80  
      81  /// \brief A description of a type.
      82  class TypeDescriptor {
      83    /// A value from the \c Kind enumeration, specifying what flavor of type we
      84    /// have.
      85    u16 TypeKind;
      86  
      87    /// A \c Type-specific value providing information which allows us to
      88    /// interpret the meaning of a ValueHandle of this type.
      89    u16 TypeInfo;
      90  
      91    /// The name of the type follows, in a format suitable for including in
      92    /// diagnostics.
      93    char TypeName[1];
      94  
      95  public:
      96    enum Kind {
      97      /// An integer type. Lowest bit is 1 for a signed value, 0 for an unsigned
      98      /// value. Remaining bits are log_2(bit width). The value representation is
      99      /// the integer itself if it fits into a ValueHandle, and a pointer to the
     100      /// integer otherwise.
     101      TK_Integer = 0x0000,
     102      /// A floating-point type. Low 16 bits are bit width. The value
     103      /// representation is that of bitcasting the floating-point value to an
     104      /// integer type.
     105      TK_Float = 0x0001,
     106      /// Any other type. The value representation is unspecified.
     107      TK_Unknown = 0xffff
     108    };
     109  
     110    const char *getTypeName() const { return TypeName; }
     111  
     112    Kind getKind() const {
     113      return static_cast<Kind>(TypeKind);
     114    }
     115  
     116    bool isIntegerTy() const { return getKind() == TK_Integer; }
     117    bool isSignedIntegerTy() const {
     118      return isIntegerTy() && (TypeInfo & 1);
     119    }
     120    bool isUnsignedIntegerTy() const {
     121      return isIntegerTy() && !(TypeInfo & 1);
     122    }
     123    unsigned getIntegerBitWidth() const {
     124      CHECK(isIntegerTy());
     125      return 1 << (TypeInfo >> 1);
     126    }
     127  
     128    bool isFloatTy() const { return getKind() == TK_Float; }
     129    unsigned getFloatBitWidth() const {
     130      CHECK(isFloatTy());
     131      return TypeInfo;
     132    }
     133  };
     134  
     135  /// \brief An opaque handle to a value.
     136  typedef uptr ValueHandle;
     137  
     138  /// Returns the class name of the given ObjC object, or null if the name
     139  /// cannot be found.
     140  const char *getObjCClassName(ValueHandle Pointer);
     141  
     142  /// \brief Representation of an operand value provided by the instrumented code.
     143  ///
     144  /// This is a combination of a TypeDescriptor (which is emitted as constant data
     145  /// as an operand to a handler function) and a ValueHandle (which is passed at
     146  /// runtime when a check failure occurs).
     147  class Value {
     148    /// The type of the value.
     149    const TypeDescriptor &Type;
     150    /// The encoded value itself.
     151    ValueHandle Val;
     152  
     153    /// Is \c Val a (zero-extended) integer?
     154    bool isInlineInt() const {
     155      CHECK(getType().isIntegerTy());
     156      const unsigned InlineBits = sizeof(ValueHandle) * 8;
     157      const unsigned Bits = getType().getIntegerBitWidth();
     158      return Bits <= InlineBits;
     159    }
     160  
     161    /// Is \c Val a (zero-extended) integer representation of a float?
     162    bool isInlineFloat() const {
     163      CHECK(getType().isFloatTy());
     164      const unsigned InlineBits = sizeof(ValueHandle) * 8;
     165      const unsigned Bits = getType().getFloatBitWidth();
     166      return Bits <= InlineBits;
     167    }
     168  
     169  public:
     170    Value(const TypeDescriptor &Type, ValueHandle Val) : Type(Type), Val(Val) {}
     171  
     172    const TypeDescriptor &getType() const { return Type; }
     173  
     174    /// \brief Get this value as a signed integer.
     175    SIntMax getSIntValue() const;
     176  
     177    /// \brief Get this value as an unsigned integer.
     178    UIntMax getUIntValue() const;
     179  
     180    /// \brief Decode this value, which must be a positive or unsigned integer.
     181    UIntMax getPositiveIntValue() const;
     182  
     183    /// Is this an integer with value -1?
     184    bool isMinusOne() const {
     185      return getType().isSignedIntegerTy() && getSIntValue() == -1;
     186    }
     187  
     188    /// Is this a negative integer?
     189    bool isNegative() const {
     190      return getType().isSignedIntegerTy() && getSIntValue() < 0;
     191    }
     192  
     193    /// \brief Get this value as a floating-point quantity.
     194    FloatMax getFloatValue() const;
     195  };
     196  
     197  } // namespace __ubsan
     198  
     199  #endif // UBSAN_VALUE_H