ubsan_value.h revision 4a4ef702597471bff5e249b8ec9d94d265007895
1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//===-- ubsan_value.h -------------------------------------------*- C++ -*-===//
2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//
3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//                     The LLVM Compiler Infrastructure
4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//
5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// This file is distributed under the University of Illinois Open Source
6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// License. See LICENSE.TXT for details.
7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//
8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//===----------------------------------------------------------------------===//
9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//
10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// Representation of data which is passed from the compiler-generated calls into
11b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// the ubsan runtime.
12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//
13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org//===----------------------------------------------------------------------===//
14b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#ifndef UBSAN_VALUE_H
15b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#define UBSAN_VALUE_H
16b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
17b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// For now, only support linux and darwin. Other platforms should be easy to
18b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// add, and probably work as-is.
19b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#if !defined(__linux__) && !defined(__APPLE__)
20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#error "UBSan not supported for this platform!"
21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#include "sanitizer_common/sanitizer_common.h"
24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org// FIXME: Move this out to a config header.
26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#if defined(__clang__) || __SIZEOF_INT128__
27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgtypedef __int128 s128;
28fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgtypedef unsigned __int128 u128;
29fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org#define HAVE_INT128_T 1
30fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org#else
31fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org#define HAVE_INT128_T 0
32fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org#endif
33fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org
34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace __ubsan {
36fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org
37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/// \brief Largest integer types we support.
38fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org#if HAVE_INT128_T
39fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgtypedef s128 SIntMax;
40fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgtypedef u128 UIntMax;
41fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org#else
42fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.orgtypedef s64 SIntMax;
43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgtypedef u64 UIntMax;
44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif
45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/// \brief Largest floating-point type we support.
47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgtypedef long double FloatMax;
48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/// \brief A description of a source location. This corresponds to Clang's
51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/// \c PresumedLoc type.
52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgclass SourceLocation {
53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  const char *Filename;
54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  u32 Line;
55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  u32 Column;
56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgpublic:
58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  SourceLocation() : Filename(), Line(), Column() {}
59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  SourceLocation(const char *Filename, unsigned Line, unsigned Column)
60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    : Filename(Filename), Line(Line), Column(Column) {}
61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// \brief Determine whether the source location is known.
63fbda0fcf2f9e82c82bcaac138f44d4e5144f6e0dpbos@webrtc.org  bool isInvalid() const { return !Filename; }
64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// \brief Get the presumed filename for the source location.
66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  const char *getFilename() const { return Filename; }
67b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  /// \brief Get the presumed line number.
68  unsigned getLine() const { return Line; }
69  /// \brief Get the column within the presumed line.
70  unsigned getColumn() const { return Column; }
71};
72
73
74/// \brief A description of a type.
75class TypeDescriptor {
76  /// A value from the \c Kind enumeration, specifying what flavor of type we
77  /// have.
78  u16 TypeKind;
79
80  /// A \c Type-specific value providing information which allows us to
81  /// interpret the meaning of a ValueHandle of this type.
82  u16 TypeInfo;
83
84  /// The name of the type follows, in a format suitable for including in
85  /// diagnostics.
86  char TypeName[1];
87
88public:
89  enum Kind {
90    /// An integer type. Lowest bit is 1 for a signed value, 0 for an unsigned
91    /// value. Remaining bits are log_2(bit width). The value representation is
92    /// the integer itself if it fits into a ValueHandle, and a pointer to the
93    /// integer otherwise.
94    TK_Integer = 0x0000,
95    /// A floating-point type. Low 16 bits are bit width. The value
96    /// representation is a pointer to the floating-point value.
97    TK_Float = 0x0001,
98    /// Any other type. The value representation is unspecified.
99    TK_Unknown = 0xffff
100  };
101
102  const char *getTypeName() const { return TypeName; }
103
104  Kind getKind() const {
105    return static_cast<Kind>(TypeKind);
106  }
107
108  bool isIntegerTy() const { return getKind() == TK_Integer; }
109  bool isSignedIntegerTy() const {
110    return isIntegerTy() && (TypeInfo & 1);
111  }
112  bool isUnsignedIntegerTy() const {
113    return isIntegerTy() && !(TypeInfo & 1);
114  }
115  unsigned getIntegerBitWidth() const {
116    CHECK(isIntegerTy());
117    return 1 << (TypeInfo >> 1);
118  }
119
120  bool isFloatTy() const { return getKind() == TK_Float; }
121  unsigned getFloatBitWidth() const {
122    CHECK(isFloatTy());
123    return TypeInfo;
124  }
125};
126
127/// \brief An opaque handle to a value.
128typedef uptr ValueHandle;
129
130
131/// \brief Representation of an operand value provided by the instrumented code.
132///
133/// This is a combination of a TypeDescriptor (which is emitted as constant data
134/// as an operand to a handler function) and a ValueHandle (which is passed at
135/// runtime when a check failure occurs).
136class Value {
137  /// The type of the value.
138  const TypeDescriptor &Type;
139  /// The encoded value itself.
140  ValueHandle Val;
141
142  /// Is \c Val a (zero-extended) integer?
143  bool isInlineInt() const {
144    CHECK(getType().isIntegerTy());
145    const unsigned InlineBits = sizeof(ValueHandle) * 8;
146    const unsigned Bits = getType().getIntegerBitWidth();
147    return Bits <= InlineBits;
148  }
149
150public:
151  Value(const TypeDescriptor &Type, ValueHandle Val) : Type(Type), Val(Val) {}
152
153  const TypeDescriptor &getType() const { return Type; }
154
155  /// \brief Get this value as a signed integer.
156  SIntMax getSIntValue() const;
157
158  /// \brief Get this value as an unsigned integer.
159  UIntMax getUIntValue() const;
160
161  /// \brief Decode this value, which must be a positive or unsigned integer.
162  UIntMax getPositiveIntValue() const;
163
164  /// Is this an integer with value -1?
165  bool isMinusOne() const {
166    return getType().isSignedIntegerTy() && getSIntValue() == -1;
167  }
168
169  /// Is this a negative integer?
170  bool isNegative() const {
171    return getType().isSignedIntegerTy() && getSIntValue() < 0;
172  }
173
174  /// \brief Get this value as a floating-point quantity.
175  FloatMax getFloatValue() const;
176};
177
178} // namespace __ubsan
179
180#endif // UBSAN_VALUE_H
181