265 lines · c
1/*2 * TargetValue.h -- Access to target values using OMPD callbacks3 */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-exception10//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 __cplusplus21 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 TError72 * As TValue is designed to concatenate operations, we use TError73 * to catch errors that might happen on each operation and provide74 * 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 TValue93 * This class encapsules the access to target values by using OMPD94 * callback functions. The member functions are designed to concatenate95 * the operations that are needed to access values from structures96 * 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 name118 */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 address127 */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 typeName134 *135 * This call modifies the object and returns a reference to the modified136 * object137 */138 TValue &cast(const char *typeName);139 140 /**141 * Cast the target value object to some pointer of type typename142 * 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 modified146 * object147 */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 value153 */154 ompd_rc_t getAddress(ompd_address_t *addr) const;155 /**156 * Get the raw memory copy of the target value157 */158 ompd_rc_t getRawValue(void *buf, int count);159 /**160 * Fetch a string copy from the target. "this" represents the pointer161 * 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 target164 * read error.165 */166 ompd_rc_t getString(const char **buf);167 /**168 * Get a new target value object for the dereferenced target value169 * reduces the pointer level, uses the target value as new target address,170 * keeps the target type171 */172 TValue dereference() const;173 /**174 * Cast to a base type175 * Only values of base type may be read from target176 */177 TBaseValue castBase(ompd_target_prim_types_t baseType) const;178 /**179 * Cast to a base type180 * Get the size by fieldsize from runtime181 */182 TBaseValue castBase() const;183 /**184 * Cast to a base type185 * Get the size by name from the rtl186 */187 TBaseValue castBase(const char *varName);188 /**189 * Resolve field access for structs/unions190 * this supports both "->" and "." operator.191 */192 TValue access(const char *fieldName) const;193 /**194 * Tests for a field bit in a bitfield195 */196 ompd_rc_t check(const char *bitfieldName, ompd_word_t *isSet) const;197 /**198 * Get an array element199 */200 TValue getArrayElement(int elemNumber) const;201 /**202 * Get an element of a pointer array203 */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 code211 */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 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#else261#define EXTERN_C262#endif263 264#endif /*SRC_TARGET_VALUE_H_*/265