1/*
2 * TargetValue.h -- Access to target values using OMPD callbacks
3 */
4
5//===----------------------------------------------------------------------===//
6//
7// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
8// See https://llvm.org/LICENSE.txt for license information.
9// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
10//
11//===----------------------------------------------------------------------===//
12
13#include "omp-tools.h"
14#include "ompd-private.h"
15#include <stdlib.h>
16
17#ifndef SRC_TARGET_VALUE_H_
18#define SRC_TARGET_VALUE_H_
19
20#ifdef __cplusplus
21
22#include <cassert>
23#include <map>
24#include <string>
25
26class TType;
27class TValue;
28class TBaseValue;
29
30class TTypeFactory {
31protected:
32 std::map<ompd_address_space_context_t *, std::map<const char *, TType>>
33 ttypes;
34
35public:
36 TTypeFactory() : ttypes() {}
37 TType &getType(ompd_address_space_context_t *context, const char *typName,
38 ompd_addr_t segment = OMPD_SEGMENT_UNSPECIFIED);
39};
40
41static thread_local TTypeFactory tf = TTypeFactory();
42
43class TType {
44protected:
45 ompd_size_t typeSize;
46 std::map<const char *, ompd_size_t> fieldOffsets;
47 std::map<const char *, ompd_size_t> fieldSizes;
48 std::map<const char *, uint64_t> bitfieldMasks;
49 ompd_addr_t descSegment;
50 const char *typeName;
51 ompd_address_space_context_t *context;
52 bool isvoid;
53 TType(ompd_address_space_context_t *context, const char *typeName,
54 ompd_addr_t _segment = OMPD_SEGMENT_UNSPECIFIED);
55
56public:
57 TType(bool, ompd_addr_t _segment = OMPD_SEGMENT_UNSPECIFIED)
58 : descSegment(_segment), isvoid(true) {}
59 bool isVoid() const { return isvoid; }
60 ompd_rc_t getElementOffset(const char *fieldName, ompd_size_t *offset);
61 ompd_rc_t getElementSize(const char *fieldName, ompd_size_t *size);
62 ompd_rc_t getBitfieldMask(const char *fieldName, uint64_t *bitfieldmask);
63 ompd_rc_t getSize(ompd_size_t *size);
64 friend TValue;
65 friend TTypeFactory;
66};
67
68static TType nullType(true);
69
70/**
71 * class TError
72 * As TValue is designed to concatenate operations, we use TError
73 * to catch errors that might happen on each operation and provide
74 * the according error code and which operation raised the error.
75 */
76
77class TError {
78protected:
79 ompd_rc_t errorCode;
80 TError() : errorCode(ompd_rc_ok) {}
81 TError(const ompd_rc_t &error) : errorCode(error) {}
82
83public:
84 std::string toString() {
85 return std::string("TError messages not implemented yet");
86 }
87 friend TValue;
88 friend TBaseValue;
89};
90
91/**
92 * class TValue
93 * This class encapsules the access to target values by using OMPD
94 * callback functions. The member functions are designed to concatenate
95 * the operations that are needed to access values from structures
96 * e.g., _a[6]->_b._c would read like :
97 * TValue(ctx,
98 * "_a").cast("A",2).getArrayElement(6).access("_b").cast("B").access("_c")
99 */
100
101class TValue {
102protected:
103 TError errorState;
104 TType *type;
105 int pointerLevel;
106 ompd_address_space_context_t *context;
107 ompd_thread_context_t *tcontext;
108 ompd_address_t symbolAddr;
109 ompd_size_t fieldSize;
110
111public:
112 static const ompd_callbacks_t *callbacks;
113 static ompd_device_type_sizes_t type_sizes;
114
115 TValue() : errorState(ompd_rc_error) {}
116 /**
117 * Create a target value object from symbol name
118 */
119 TValue(ompd_address_space_context_t *_context, const char *_valueName,
120 ompd_addr_t segment = OMPD_SEGMENT_UNSPECIFIED)
121 : TValue(_context, NULL, _valueName, segment) {}
122
123 TValue(ompd_address_space_context_t *context, ompd_thread_context_t *tcontext,
124 const char *valueName, ompd_addr_t segment = OMPD_SEGMENT_UNSPECIFIED);
125 /**
126 * Create a target value object from target value address
127 */
128 TValue(ompd_address_space_context_t *_context, ompd_address_t _addr)
129 : TValue(_context, NULL, _addr) {}
130 TValue(ompd_address_space_context_t *context, ompd_thread_context_t *tcontext,
131 ompd_address_t addr);
132 /**
133 * Cast the target value object to some type of typeName
134 *
135 * This call modifies the object and returns a reference to the modified
136 * object
137 */
138 TValue &cast(const char *typeName);
139
140 /**
141 * Cast the target value object to some pointer of type typename
142 * pointerlevel gives the number of *
143 * e.g., char** would be: cast("char",2)
144 *
145 * This call modifies the object and returns a reference to the modified
146 * object
147 */
148 TValue &cast(const char *typeName, int pointerLevel,
149 ompd_addr_t segment = OMPD_SEGMENT_UNSPECIFIED);
150
151 /**
152 * Get the target address of the target value
153 */
154 ompd_rc_t getAddress(ompd_address_t *addr) const;
155 /**
156 * Get the raw memory copy of the target value
157 */
158 ompd_rc_t getRawValue(void *buf, int count);
159 /**
160 * Fetch a string copy from the target. "this" represents the pointer
161 * that holds the value of a null terminated character string. "buf"
162 * points to the destination string to be allocated and copied to.
163 * Returns 'ompd_rc_error' to signify a truncated string or a target
164 * read error.
165 */
166 ompd_rc_t getString(const char **buf);
167 /**
168 * Get a new target value object for the dereferenced target value
169 * reduces the pointer level, uses the target value as new target address,
170 * keeps the target type
171 */
172 TValue dereference() const;
173 /**
174 * Cast to a base type
175 * Only values of base type may be read from target
176 */
177 TBaseValue castBase(ompd_target_prim_types_t baseType) const;
178 /**
179 * Cast to a base type
180 * Get the size by fieldsize from runtime
181 */
182 TBaseValue castBase() const;
183 /**
184 * Cast to a base type
185 * Get the size by name from the rtl
186 */
187 TBaseValue castBase(const char *varName);
188 /**
189 * Resolve field access for structs/unions
190 * this supports both "->" and "." operator.
191 */
192 TValue access(const char *fieldName) const;
193 /**
194 * Tests for a field bit in a bitfield
195 */
196 ompd_rc_t check(const char *bitfieldName, ompd_word_t *isSet) const;
197 /**
198 * Get an array element
199 */
200 TValue getArrayElement(int elemNumber) const;
201 /**
202 * Get an element of a pointer array
203 */
204 TValue getPtrArrayElement(int elemNumber) const;
205 /**
206 * Did we raise some error yet?
207 */
208 bool gotError() const { return errorState.errorCode != ompd_rc_ok; }
209 /**
210 * Get the error code
211 */
212 ompd_rc_t getError() const { return errorState.errorCode; }
213 /**
214 * Did we raise some error yet?
215 */
216 std::string getErrorMessage() { return errorState.toString(); }
217};
218
219class TBaseValue : public TValue {
220protected:
221 ompd_size_t baseTypeSize = 0;
222 TBaseValue(const TValue &, ompd_target_prim_types_t baseType);
223 TBaseValue(const TValue &, ompd_size_t baseTypeSize);
224
225public:
226 ompd_rc_t getValue(void *buf, int count);
227 template <typename T> ompd_rc_t getValue(T &buf);
228
229 friend TValue;
230};
231
232template <typename T> ompd_rc_t TBaseValue::getValue(T &buf) {
233 assert(sizeof(T) >= baseTypeSize);
234 ompd_rc_t ret = getValue(&buf, 1);
235 if (sizeof(T) > baseTypeSize) {
236 switch (baseTypeSize) {
237 case 1:
238 buf = (T) * ((int8_t *)&buf);
239 break;
240 case 2:
241 buf = (T) * ((int16_t *)&buf);
242 break;
243 case 4:
244 buf = (T) * ((int32_t *)&buf);
245 break;
246 case 8:
247 buf = (T) * ((int64_t *)&buf);
248 break;
249 }
250 }
251 return ret;
252}
253
254#define EXTERN_C extern "C"
255#else
256#define EXTERN_C
257#endif
258
259#endif /*SRC_TARGET_VALUE_H_*/
260

source code of openmp/libompd/src/TargetValue.h