blob: 0c41afafba9f8f795309bfd985c2fe21c4513262 [file] [log] [blame]
Richard Smith68b30142012-10-09 19:34:32 +00001//===-- 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
43/// \brief A description of a source location. This corresponds to Clang's
44/// \c PresumedLoc type.
45class SourceLocation {
46 const char *Filename;
47 u32 Line;
48 u32 Column;
49
50public:
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 Get the presumed filename for the source location.
58 const char *getFilename() const { return Filename; }
59 /// \brief Get the presumed line number.
60 unsigned getLine() const { return Line; }
61 /// \brief Get the column within the presumed line.
62 unsigned getColumn() const { return Column; }
63};
64
65
66/// \brief A description of a type.
67class TypeDescriptor {
Richard Smith68b30142012-10-09 19:34:32 +000068 /// A value from the \c Kind enumeration, specifying what flavor of type we
69 /// have.
70 u16 TypeKind;
71
72 /// A \c Type-specific value providing information which allows us to
73 /// interpret the meaning of a ValueHandle of this type.
74 u16 TypeInfo;
75
Richard Smithb6fb3812012-10-09 23:55:18 +000076 /// The name of the type follows, in a format suitable for including in
77 /// diagnostics.
78 char TypeName[1];
79
Richard Smith68b30142012-10-09 19:34:32 +000080public:
81 enum Kind {
82 /// An integer type. Lowest bit is 1 for a signed value, 0 for an unsigned
83 /// value. Remaining bits are log_2(bit width). The value representation is
84 /// the integer itself if it fits into a ValueHandle, and a pointer to the
85 /// integer otherwise.
86 TK_Integer = 0x0000,
87 /// A floating-point type. Low 16 bits are bit width. The value
88 /// representation is a pointer to the floating-point value.
89 TK_Float = 0x0001,
90 /// Any other type. The value representation is unspecified.
91 TK_Unknown = 0xffff
92 };
93
94 const char *getTypeName() const { return TypeName; }
95
96 Kind getKind() const {
97 return static_cast<Kind>(TypeKind);
98 }
99
100 bool isIntegerTy() const { return getKind() == TK_Integer; }
101 bool isSignedIntegerTy() const {
102 return isIntegerTy() && (TypeInfo & 1);
103 }
104 bool isUnsignedIntegerTy() const {
105 return isIntegerTy() && !(TypeInfo & 1);
106 }
107 unsigned getIntegerBitWidth() const {
108 CHECK(isIntegerTy());
109 return 1 << (TypeInfo >> 1);
110 }
111
112 bool isFloatTy() const { return getKind() == TK_Float; }
113 unsigned getFloatBitWidth() const {
114 CHECK(isFloatTy());
115 return TypeInfo;
116 }
117};
118
119/// \brief An opaque handle to a value.
120typedef uptr ValueHandle;
121
122
123/// \brief Representation of an operand value provided by the instrumented code.
124///
125/// This is a combination of a TypeDescriptor (which is emitted as constant data
126/// as an operand to a handler function) and a ValueHandle (which is passed at
127/// runtime when a check failure occurs).
128class Value {
129 /// The type of the value.
130 const TypeDescriptor &Type;
131 /// The encoded value itself.
132 ValueHandle Val;
133
134 /// Is \c Val a (zero-extended) integer?
135 bool isInlineInt() const {
136 CHECK(getType().isIntegerTy());
137 const unsigned InlineBits = sizeof(ValueHandle) * 8;
138 const unsigned Bits = getType().getIntegerBitWidth();
139 return Bits <= InlineBits;
140 }
141
142public:
143 Value(const TypeDescriptor &Type, ValueHandle Val) : Type(Type), Val(Val) {}
144
145 const TypeDescriptor &getType() const { return Type; }
146
147 /// \brief Get this value as a signed integer.
148 SIntMax getSIntValue() const;
149
150 /// \brief Get this value as an unsigned integer.
151 UIntMax getUIntValue() const;
152
153 /// \brief Decode this value, which must be a positive or unsigned integer.
154 UIntMax getPositiveIntValue() const;
155
156 /// Is this an integer with value -1?
157 bool isMinusOne() const {
158 return getType().isSignedIntegerTy() && getSIntValue() == -1;
159 }
160
161 /// Is this a negative integer?
162 bool isNegative() const {
163 return getType().isSignedIntegerTy() && getSIntValue() < 0;
164 }
165
166 /// \brief Get this value as a floating-point quantity.
167 long double getFloatValue() const;
168};
169
170} // namespace __ubsan
171
172#endif // UBSAN_VALUE_H