1254721Semaste//===-- Value.h -------------------------------------------------*- C++ -*-===// 2254721Semaste// 3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4353358Sdim// See https://llvm.org/LICENSE.txt for license information. 5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6254721Semaste// 7254721Semaste//===----------------------------------------------------------------------===// 8254721Semaste 9254721Semaste#ifndef liblldb_Value_h_ 10254721Semaste#define liblldb_Value_h_ 11254721Semaste 12296417Sdim#include "lldb/Symbol/CompilerType.h" 13321369Sdim#include "lldb/Utility/DataBufferHeap.h" 14344779Sdim#include "lldb/Utility/Scalar.h" 15321369Sdim#include "lldb/Utility/Status.h" 16344779Sdim#include "lldb/lldb-enumerations.h" 17344779Sdim#include "lldb/lldb-private-enumerations.h" 18344779Sdim#include "lldb/lldb-private-types.h" 19254721Semaste 20344779Sdim#include "llvm/ADT/APInt.h" 21321369Sdim 22321369Sdim#include <vector> 23321369Sdim 24344779Sdim#include <stdint.h> 25344779Sdim#include <string.h> 26321369Sdim 27254721Semastenamespace lldb_private { 28321369Sdimclass DataExtractor; 29321369Sdimclass ExecutionContext; 30321369Sdimclass Module; 31321369Sdimclass Stream; 32321369Sdimclass Type; 33321369Sdimclass Variable; 34321369Sdim} 35254721Semaste 36321369Sdimnamespace lldb_private { 37321369Sdim 38314564Sdimclass Value { 39254721Semastepublic: 40341825Sdim // Values Less than zero are an error, greater than or equal to zero returns 41341825Sdim // what the Scalar result is. 42314564Sdim enum ValueType { 43314564Sdim // m_value contains... 44314564Sdim // ============================ 45314564Sdim eValueTypeScalar, // raw scalar value 46314564Sdim eValueTypeVector, // byte array of m_vector.length with endianness of 47314564Sdim // m_vector.byte_order 48314564Sdim eValueTypeFileAddress, // file address value 49314564Sdim eValueTypeLoadAddress, // load address value 50314564Sdim eValueTypeHostAddress // host address value (for memory in the process that 51314564Sdim // is using liblldb) 52314564Sdim }; 53254721Semaste 54314564Sdim enum ContextType // Type that describes Value::m_context 55314564Sdim { 56314564Sdim // m_context contains... 57314564Sdim // ==================== 58314564Sdim eContextTypeInvalid, // undefined 59314564Sdim eContextTypeRegisterInfo, // RegisterInfo * (can be a scalar or a vector 60314564Sdim // register) 61314564Sdim eContextTypeLLDBType, // lldb_private::Type * 62314564Sdim eContextTypeVariable // lldb_private::Variable * 63314564Sdim }; 64254721Semaste 65314564Sdim const static size_t kMaxByteSize = 32u; 66254721Semaste 67314564Sdim struct Vector { 68314564Sdim // The byte array must be big enough to hold vector registers for any 69314564Sdim // supported target. 70314564Sdim uint8_t bytes[kMaxByteSize]; 71314564Sdim size_t length; 72314564Sdim lldb::ByteOrder byte_order; 73254721Semaste 74314564Sdim Vector() : length(0), byte_order(lldb::eByteOrderInvalid) {} 75254721Semaste 76314564Sdim Vector(const Vector &vector) { *this = vector; } 77314564Sdim const Vector &operator=(const Vector &vector) { 78314564Sdim SetBytes(vector.bytes, vector.length, vector.byte_order); 79314564Sdim return *this; 80314564Sdim } 81254721Semaste 82314564Sdim void Clear() { length = 0; } 83254721Semaste 84314564Sdim bool SetBytes(const void *bytes, size_t length, 85314564Sdim lldb::ByteOrder byte_order) { 86314564Sdim this->length = length; 87314564Sdim this->byte_order = byte_order; 88314564Sdim if (length) 89314564Sdim ::memcpy(this->bytes, bytes, 90314564Sdim length < kMaxByteSize ? length : kMaxByteSize); 91314564Sdim return IsValid(); 92314564Sdim } 93254721Semaste 94314564Sdim bool IsValid() const { 95314564Sdim return (length > 0 && length < kMaxByteSize && 96314564Sdim byte_order != lldb::eByteOrderInvalid); 97314564Sdim } 98314564Sdim // Casts a vector, if valid, to an unsigned int of matching or largest 99341825Sdim // supported size. Truncates to the beginning of the vector if required. 100314564Sdim // Returns a default constructed Scalar if the Vector data is internally 101314564Sdim // inconsistent. 102314564Sdim llvm::APInt rhs = llvm::APInt(BITWIDTH_INT128, NUM_OF_WORDS_INT128, 103314564Sdim ((type128 *)bytes)->x); 104314564Sdim Scalar GetAsScalar() const { 105314564Sdim Scalar scalar; 106314564Sdim if (IsValid()) { 107314564Sdim if (length == 1) 108314564Sdim scalar = *(const uint8_t *)bytes; 109314564Sdim else if (length == 2) 110314564Sdim scalar = *(const uint16_t *)bytes; 111314564Sdim else if (length == 4) 112314564Sdim scalar = *(const uint32_t *)bytes; 113314564Sdim else if (length == 8) 114314564Sdim scalar = *(const uint64_t *)bytes; 115314564Sdim else if (length >= 16) 116314564Sdim scalar = rhs; 117314564Sdim } 118314564Sdim return scalar; 119314564Sdim } 120314564Sdim }; 121254721Semaste 122314564Sdim Value(); 123314564Sdim Value(const Scalar &scalar); 124314564Sdim Value(const Vector &vector); 125314564Sdim Value(const void *bytes, int len); 126314564Sdim Value(const Value &rhs); 127276479Sdim 128314564Sdim void SetBytes(const void *bytes, int len); 129254721Semaste 130314564Sdim void AppendBytes(const void *bytes, int len); 131254721Semaste 132314564Sdim Value &operator=(const Value &rhs); 133254721Semaste 134314564Sdim const CompilerType &GetCompilerType(); 135254721Semaste 136314564Sdim void SetCompilerType(const CompilerType &compiler_type); 137254721Semaste 138314564Sdim ValueType GetValueType() const; 139254721Semaste 140314564Sdim AddressType GetValueAddressType() const; 141254721Semaste 142314564Sdim ContextType GetContextType() const { return m_context_type; } 143314564Sdim 144314564Sdim void SetValueType(ValueType value_type) { m_value_type = value_type; } 145314564Sdim 146314564Sdim void ClearContext() { 147314564Sdim m_context = nullptr; 148314564Sdim m_context_type = eContextTypeInvalid; 149314564Sdim } 150314564Sdim 151314564Sdim void SetContext(ContextType context_type, void *p) { 152314564Sdim m_context_type = context_type; 153314564Sdim m_context = p; 154314564Sdim if (m_context_type == eContextTypeRegisterInfo) { 155314564Sdim RegisterInfo *reg_info = GetRegisterInfo(); 156314564Sdim if (reg_info->encoding == lldb::eEncodingVector && 157314564Sdim m_vector.byte_order != lldb::eByteOrderInvalid) 158314564Sdim SetValueType(eValueTypeScalar); 159254721Semaste } 160314564Sdim } 161254721Semaste 162314564Sdim RegisterInfo *GetRegisterInfo() const; 163254721Semaste 164314564Sdim Type *GetType(); 165254721Semaste 166314564Sdim Scalar &ResolveValue(ExecutionContext *exe_ctx); 167254721Semaste 168314564Sdim const Scalar &GetScalar() const { return m_value; } 169254721Semaste 170314564Sdim const Vector &GetVector() const { return m_vector; } 171254721Semaste 172314564Sdim Scalar &GetScalar() { return m_value; } 173254721Semaste 174314564Sdim Vector &GetVector() { return m_vector; } 175254721Semaste 176314564Sdim bool SetVectorBytes(const Vector &vector) { 177314564Sdim m_vector = vector; 178314564Sdim return m_vector.IsValid(); 179314564Sdim } 180276479Sdim 181314564Sdim bool SetVectorBytes(uint8_t *bytes, size_t length, 182314564Sdim lldb::ByteOrder byte_order) { 183314564Sdim return m_vector.SetBytes(bytes, length, byte_order); 184314564Sdim } 185314564Sdim 186314564Sdim bool SetScalarFromVector() { 187314564Sdim if (m_vector.IsValid()) { 188314564Sdim m_value = m_vector.GetAsScalar(); 189314564Sdim return true; 190276479Sdim } 191314564Sdim return false; 192314564Sdim } 193276479Sdim 194314564Sdim size_t ResizeData(size_t len); 195254721Semaste 196314564Sdim size_t AppendDataToHostBuffer(const Value &rhs); 197254721Semaste 198314564Sdim DataBufferHeap &GetBuffer() { return m_data_buffer; } 199254721Semaste 200314564Sdim const DataBufferHeap &GetBuffer() const { return m_data_buffer; } 201254721Semaste 202314564Sdim bool ValueOf(ExecutionContext *exe_ctx); 203254721Semaste 204314564Sdim Variable *GetVariable(); 205254721Semaste 206314564Sdim void Dump(Stream *strm); 207254721Semaste 208314564Sdim lldb::Format GetValueDefaultFormat(); 209254721Semaste 210321369Sdim uint64_t GetValueByteSize(Status *error_ptr, ExecutionContext *exe_ctx); 211254721Semaste 212321369Sdim Status GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data, 213321369Sdim Module *module); // Can be nullptr 214254721Semaste 215314564Sdim static const char *GetValueTypeAsCString(ValueType context_type); 216314564Sdim 217314564Sdim static const char *GetContextTypeAsCString(ContextType context_type); 218314564Sdim 219341825Sdim /// Convert this value's file address to a load address, if possible. 220341825Sdim void ConvertToLoadAddress(Module *module, Target *target); 221341825Sdim 222314564Sdim bool GetData(DataExtractor &data); 223314564Sdim 224314564Sdim void Clear(); 225314564Sdim 226254721Semasteprotected: 227314564Sdim Scalar m_value; 228314564Sdim Vector m_vector; 229314564Sdim CompilerType m_compiler_type; 230314564Sdim void *m_context; 231314564Sdim ValueType m_value_type; 232314564Sdim ContextType m_context_type; 233314564Sdim DataBufferHeap m_data_buffer; 234254721Semaste}; 235254721Semaste 236314564Sdimclass ValueList { 237254721Semastepublic: 238314564Sdim ValueList() : m_values() {} 239254721Semaste 240314564Sdim ValueList(const ValueList &rhs); 241254721Semaste 242314564Sdim ~ValueList() = default; 243254721Semaste 244314564Sdim const ValueList &operator=(const ValueList &rhs); 245254721Semaste 246314564Sdim // void InsertValue (Value *value, size_t idx); 247314564Sdim void PushValue(const Value &value); 248254721Semaste 249314564Sdim size_t GetSize(); 250314564Sdim Value *GetValueAtIndex(size_t idx); 251314564Sdim void Clear(); 252254721Semaste 253254721Semasteprivate: 254314564Sdim typedef std::vector<Value> collection; 255254721Semaste 256314564Sdim collection m_values; 257254721Semaste}; 258254721Semaste 259254721Semaste} // namespace lldb_private 260254721Semaste 261296417Sdim#endif // liblldb_Value_h_ 262