xref: /llvm-project/openmp/libompd/src/TargetValue.h (revision 8101cbff77aca47ee3c7de8e43d0546057ff2ee6)
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 
26 class TType;
27 class TValue;
28 class TBaseValue;
29 
30 class TTypeFactory {
31 protected:
32   std::map<ompd_address_space_context_t *, std::map<const char *, TType>>
33       ttypes;
34 
35 public:
TTypeFactory()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 
41 static thread_local TTypeFactory tf = TTypeFactory();
42 
43 class TType {
44 protected:
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 
56 public:
57   TType(bool, ompd_addr_t _segment = OMPD_SEGMENT_UNSPECIFIED)
descSegment(_segment)58       : descSegment(_segment), isvoid(true) {}
isVoid()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 
68 static 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 
77 class TError {
78 protected:
79   ompd_rc_t errorCode;
TError()80   TError() : errorCode(ompd_rc_ok) {}
TError(const ompd_rc_t & error)81   TError(const ompd_rc_t &error) : errorCode(error) {}
82 
83 public:
toString()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 
101 class TValue {
102 protected:
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 
111 public:
112   static const ompd_callbacks_t *callbacks;
113   static ompd_device_type_sizes_t type_sizes;
114 
TValue()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)
TValue(_context,NULL,_valueName,segment)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    */
TValue(ompd_address_space_context_t * _context,ompd_address_t _addr)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    */
gotError()208   bool gotError() const { return errorState.errorCode != ompd_rc_ok; }
209   /**
210    * Get the error code
211    */
getError()212   ompd_rc_t getError() const { return errorState.errorCode; }
213   /**
214    * Did we raise some error yet?
215    */
getErrorMessage()216   std::string getErrorMessage() { return errorState.toString(); }
217 };
218 
219 class TBaseValue : public TValue {
220 protected:
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 
225 public:
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 
getValue(T & buf)232 template <typename T> ompd_rc_t TBaseValue::getValue(T &buf) {
233   assert(sizeof(T) >= baseTypeSize);
234   if (sizeof(T) == baseTypeSize)
235     return getValue(&buf, 1);
236 
237   char tmp[sizeof(T)];
238   ompd_rc_t ret = getValue(tmp, 1);
239   switch (baseTypeSize) {
240   case 1:
241     buf = (T) * ((int8_t *)tmp);
242     break;
243   case 2:
244     buf = (T) * ((int16_t *)tmp);
245     break;
246   case 4:
247     buf = (T) * ((int32_t *)tmp);
248     break;
249   case 8:
250     buf = (T) * ((int64_t *)tmp);
251     break;
252   default:
253     assert(0 && "Invalid baseTypeSize");
254     break;
255   }
256   return ret;
257 }
258 
259 #define EXTERN_C extern "C"
260 #else
261 #define EXTERN_C
262 #endif
263 
264 #endif /*SRC_TARGET_VALUE_H_*/
265