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