/* * TargetValue.h -- Access to target values using OMPD callbacks */ //===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "omp-tools.h" #include "ompd-private.h" #include #ifndef SRC_TARGET_VALUE_H_ #define SRC_TARGET_VALUE_H_ #ifdef __cplusplus #include #include #include class TType; class TValue; class TBaseValue; class TTypeFactory { protected: std::map> ttypes; public: TTypeFactory() : ttypes() {} TType &getType(ompd_address_space_context_t *context, const char *typName, ompd_addr_t segment = OMPD_SEGMENT_UNSPECIFIED); }; static thread_local TTypeFactory tf = TTypeFactory(); class TType { protected: ompd_size_t typeSize; std::map fieldOffsets; std::map fieldSizes; std::map bitfieldMasks; ompd_addr_t descSegment; const char *typeName; ompd_address_space_context_t *context; bool isvoid; TType(ompd_address_space_context_t *context, const char *typeName, ompd_addr_t _segment = OMPD_SEGMENT_UNSPECIFIED); public: TType(bool, ompd_addr_t _segment = OMPD_SEGMENT_UNSPECIFIED) : descSegment(_segment), isvoid(true) {} bool isVoid() const { return isvoid; } ompd_rc_t getElementOffset(const char *fieldName, ompd_size_t *offset); ompd_rc_t getElementSize(const char *fieldName, ompd_size_t *size); ompd_rc_t getBitfieldMask(const char *fieldName, uint64_t *bitfieldmask); ompd_rc_t getSize(ompd_size_t *size); friend TValue; friend TTypeFactory; }; static TType nullType(true); /** * class TError * As TValue is designed to concatenate operations, we use TError * to catch errors that might happen on each operation and provide * the according error code and which operation raised the error. */ class TError { protected: ompd_rc_t errorCode; TError() : errorCode(ompd_rc_ok) {} TError(const ompd_rc_t &error) : errorCode(error) {} public: std::string toString() { return std::string("TError messages not implemented yet"); } friend TValue; friend TBaseValue; }; /** * class TValue * This class encapsules the access to target values by using OMPD * callback functions. The member functions are designed to concatenate * the operations that are needed to access values from structures * e.g., _a[6]->_b._c would read like : * TValue(ctx, * "_a").cast("A",2).getArrayElement(6).access("_b").cast("B").access("_c") */ class TValue { protected: TError errorState; TType *type; int pointerLevel; ompd_address_space_context_t *context; ompd_thread_context_t *tcontext; ompd_address_t symbolAddr; ompd_size_t fieldSize; public: static const ompd_callbacks_t *callbacks; static ompd_device_type_sizes_t type_sizes; TValue() : errorState(ompd_rc_error) {} /** * Create a target value object from symbol name */ TValue(ompd_address_space_context_t *_context, const char *_valueName, ompd_addr_t segment = OMPD_SEGMENT_UNSPECIFIED) : TValue(_context, NULL, _valueName, segment) {} TValue(ompd_address_space_context_t *context, ompd_thread_context_t *tcontext, const char *valueName, ompd_addr_t segment = OMPD_SEGMENT_UNSPECIFIED); /** * Create a target value object from target value address */ TValue(ompd_address_space_context_t *_context, ompd_address_t _addr) : TValue(_context, NULL, _addr) {} TValue(ompd_address_space_context_t *context, ompd_thread_context_t *tcontext, ompd_address_t addr); /** * Cast the target value object to some type of typeName * * This call modifies the object and returns a reference to the modified * object */ TValue &cast(const char *typeName); /** * Cast the target value object to some pointer of type typename * pointerlevel gives the number of * * e.g., char** would be: cast("char",2) * * This call modifies the object and returns a reference to the modified * object */ TValue &cast(const char *typeName, int pointerLevel, ompd_addr_t segment = OMPD_SEGMENT_UNSPECIFIED); /** * Get the target address of the target value */ ompd_rc_t getAddress(ompd_address_t *addr) const; /** * Get the raw memory copy of the target value */ ompd_rc_t getRawValue(void *buf, int count); /** * Fetch a string copy from the target. "this" represents the pointer * that holds the value of a null terminated character string. "buf" * points to the destination string to be allocated and copied to. * Returns 'ompd_rc_error' to signify a truncated string or a target * read error. */ ompd_rc_t getString(const char **buf); /** * Get a new target value object for the dereferenced target value * reduces the pointer level, uses the target value as new target address, * keeps the target type */ TValue dereference() const; /** * Cast to a base type * Only values of base type may be read from target */ TBaseValue castBase(ompd_target_prim_types_t baseType) const; /** * Cast to a base type * Get the size by fieldsize from runtime */ TBaseValue castBase() const; /** * Cast to a base type * Get the size by name from the rtl */ TBaseValue castBase(const char *varName); /** * Resolve field access for structs/unions * this supports both "->" and "." operator. */ TValue access(const char *fieldName) const; /** * Tests for a field bit in a bitfield */ ompd_rc_t check(const char *bitfieldName, ompd_word_t *isSet) const; /** * Get an array element */ TValue getArrayElement(int elemNumber) const; /** * Get an element of a pointer array */ TValue getPtrArrayElement(int elemNumber) const; /** * Did we raise some error yet? */ bool gotError() const { return errorState.errorCode != ompd_rc_ok; } /** * Get the error code */ ompd_rc_t getError() const { return errorState.errorCode; } /** * Did we raise some error yet? */ std::string getErrorMessage() { return errorState.toString(); } }; class TBaseValue : public TValue { protected: ompd_size_t baseTypeSize = 0; TBaseValue(const TValue &, ompd_target_prim_types_t baseType); TBaseValue(const TValue &, ompd_size_t baseTypeSize); public: ompd_rc_t getValue(void *buf, int count); template ompd_rc_t getValue(T &buf); friend TValue; }; template ompd_rc_t TBaseValue::getValue(T &buf) { assert(sizeof(T) >= baseTypeSize); ompd_rc_t ret = getValue(&buf, 1); if (sizeof(T) > baseTypeSize) { switch (baseTypeSize) { case 1: buf = (T) * ((int8_t *)&buf); break; case 2: buf = (T) * ((int16_t *)&buf); break; case 4: buf = (T) * ((int32_t *)&buf); break; case 8: buf = (T) * ((int64_t *)&buf); break; } } return ret; } #define EXTERN_C extern "C" #else #define EXTERN_C #endif #endif /*SRC_TARGET_VALUE_H_*/