Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/llvm-project/compiler-rt/lib/ubsan/ubsan_value.h
35233 views
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
200
201