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