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: 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) 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 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; 80 TError() : errorCode(ompd_rc_ok) {} 81 TError(const ompd_rc_t &error) : errorCode(error) {} 82 83 public: 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 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 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 232 template <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