1 //===-- Value.h -------------------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLDB_CORE_VALUE_H 10 #define LLDB_CORE_VALUE_H 11 12 #include "lldb/Symbol/CompilerType.h" 13 #include "lldb/Utility/DataBufferHeap.h" 14 #include "lldb/Utility/Scalar.h" 15 #include "lldb/Utility/Status.h" 16 #include "lldb/lldb-enumerations.h" 17 #include "lldb/lldb-private-enumerations.h" 18 #include "lldb/lldb-private-types.h" 19 20 #include "llvm/ADT/APInt.h" 21 22 #include <vector> 23 24 #include <stdint.h> 25 #include <string.h> 26 27 namespace lldb_private { 28 class DataExtractor; 29 class ExecutionContext; 30 class Module; 31 class Stream; 32 class Type; 33 class Variable; 34 } 35 36 namespace lldb_private { 37 38 class Value { 39 public: 40 // Values Less than zero are an error, greater than or equal to zero returns 41 // what the Scalar result is. 42 enum ValueType { 43 // m_value contains... 44 // ============================ 45 eValueTypeScalar, // raw scalar value 46 eValueTypeVector, // byte array of m_vector.length with endianness of 47 // m_vector.byte_order 48 eValueTypeFileAddress, // file address value 49 eValueTypeLoadAddress, // load address value 50 eValueTypeHostAddress // host address value (for memory in the process that 51 // is using liblldb) 52 }; 53 54 enum ContextType // Type that describes Value::m_context 55 { 56 // m_context contains... 57 // ==================== 58 eContextTypeInvalid, // undefined 59 eContextTypeRegisterInfo, // RegisterInfo * (can be a scalar or a vector 60 // register) 61 eContextTypeLLDBType, // lldb_private::Type * 62 eContextTypeVariable // lldb_private::Variable * 63 }; 64 65 const static size_t kMaxByteSize = 32u; 66 67 struct Vector { 68 // The byte array must be big enough to hold vector registers for any 69 // supported target. 70 uint8_t bytes[kMaxByteSize]; 71 size_t length; 72 lldb::ByteOrder byte_order; 73 74 Vector() : length(0), byte_order(lldb::eByteOrderInvalid) {} 75 76 Vector(const Vector &vector) { *this = vector; } 77 const Vector &operator=(const Vector &vector) { 78 SetBytes(vector.bytes, vector.length, vector.byte_order); 79 return *this; 80 } 81 82 void Clear() { length = 0; } 83 84 bool SetBytes(const void *bytes, size_t length, 85 lldb::ByteOrder byte_order) { 86 this->length = length; 87 this->byte_order = byte_order; 88 if (length) 89 ::memcpy(this->bytes, bytes, 90 length < kMaxByteSize ? length : kMaxByteSize); 91 return IsValid(); 92 } 93 94 bool IsValid() const { 95 return (length > 0 && length < kMaxByteSize && 96 byte_order != lldb::eByteOrderInvalid); 97 } 98 // Casts a vector, if valid, to an unsigned int of matching or largest 99 // supported size. Truncates to the beginning of the vector if required. 100 // Returns a default constructed Scalar if the Vector data is internally 101 // inconsistent. 102 llvm::APInt rhs = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, 103 ((type128 *)bytes)->x); 104 Scalar GetAsScalar() const { 105 Scalar scalar; 106 if (IsValid()) { 107 if (length == 1) 108 scalar = *(const uint8_t *)bytes; 109 else if (length == 2) 110 scalar = *(const uint16_t *)bytes; 111 else if (length == 4) 112 scalar = *(const uint32_t *)bytes; 113 else if (length == 8) 114 scalar = *(const uint64_t *)bytes; 115 else if (length >= 16) 116 scalar = rhs; 117 } 118 return scalar; 119 } 120 }; 121 122 Value(); 123 Value(const Scalar &scalar); 124 Value(const Vector &vector); 125 Value(const void *bytes, int len); 126 Value(const Value &rhs); 127 128 void SetBytes(const void *bytes, int len); 129 130 void AppendBytes(const void *bytes, int len); 131 132 Value &operator=(const Value &rhs); 133 134 const CompilerType &GetCompilerType(); 135 136 void SetCompilerType(const CompilerType &compiler_type); 137 138 ValueType GetValueType() const; 139 140 AddressType GetValueAddressType() const; 141 142 ContextType GetContextType() const { return m_context_type; } 143 144 void SetValueType(ValueType value_type) { m_value_type = value_type; } 145 146 void ClearContext() { 147 m_context = nullptr; 148 m_context_type = eContextTypeInvalid; 149 } 150 151 void SetContext(ContextType context_type, void *p) { 152 m_context_type = context_type; 153 m_context = p; 154 if (m_context_type == eContextTypeRegisterInfo) { 155 RegisterInfo *reg_info = GetRegisterInfo(); 156 if (reg_info->encoding == lldb::eEncodingVector && 157 m_vector.byte_order != lldb::eByteOrderInvalid) 158 SetValueType(eValueTypeScalar); 159 } 160 } 161 162 RegisterInfo *GetRegisterInfo() const; 163 164 Type *GetType(); 165 166 Scalar &ResolveValue(ExecutionContext *exe_ctx); 167 168 const Scalar &GetScalar() const { return m_value; } 169 170 const Vector &GetVector() const { return m_vector; } 171 172 Scalar &GetScalar() { return m_value; } 173 174 Vector &GetVector() { return m_vector; } 175 176 bool SetVectorBytes(const Vector &vector) { 177 m_vector = vector; 178 return m_vector.IsValid(); 179 } 180 181 bool SetVectorBytes(uint8_t *bytes, size_t length, 182 lldb::ByteOrder byte_order) { 183 return m_vector.SetBytes(bytes, length, byte_order); 184 } 185 186 bool SetScalarFromVector() { 187 if (m_vector.IsValid()) { 188 m_value = m_vector.GetAsScalar(); 189 return true; 190 } 191 return false; 192 } 193 194 size_t ResizeData(size_t len); 195 196 size_t AppendDataToHostBuffer(const Value &rhs); 197 198 DataBufferHeap &GetBuffer() { return m_data_buffer; } 199 200 const DataBufferHeap &GetBuffer() const { return m_data_buffer; } 201 202 bool ValueOf(ExecutionContext *exe_ctx); 203 204 Variable *GetVariable(); 205 206 void Dump(Stream *strm); 207 208 lldb::Format GetValueDefaultFormat(); 209 210 uint64_t GetValueByteSize(Status *error_ptr, ExecutionContext *exe_ctx); 211 212 Status GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data, 213 Module *module); // Can be nullptr 214 215 static const char *GetValueTypeAsCString(ValueType context_type); 216 217 static const char *GetContextTypeAsCString(ContextType context_type); 218 219 /// Convert this value's file address to a load address, if possible. 220 void ConvertToLoadAddress(Module *module, Target *target); 221 222 bool GetData(DataExtractor &data); 223 224 void Clear(); 225 226 protected: 227 Scalar m_value; 228 Vector m_vector; 229 CompilerType m_compiler_type; 230 void *m_context; 231 ValueType m_value_type; 232 ContextType m_context_type; 233 DataBufferHeap m_data_buffer; 234 }; 235 236 class ValueList { 237 public: 238 ValueList() : m_values() {} 239 240 ValueList(const ValueList &rhs); 241 242 ~ValueList() = default; 243 244 const ValueList &operator=(const ValueList &rhs); 245 246 // void InsertValue (Value *value, size_t idx); 247 void PushValue(const Value &value); 248 249 size_t GetSize(); 250 Value *GetValueAtIndex(size_t idx); 251 void Clear(); 252 253 private: 254 typedef std::vector<Value> collection; 255 256 collection m_values; 257 }; 258 259 } // namespace lldb_private 260 261 #endif // LLDB_CORE_VALUE_H 262