1//===-- Value.cpp ---------------------------------------------------------===//
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#include "lldb/Core/Value.h"
10
11#include "lldb/Core/Address.h"
12#include "lldb/Core/Module.h"
13#include "lldb/Symbol/CompilerType.h"
14#include "lldb/Symbol/ObjectFile.h"
15#include "lldb/Symbol/SymbolContext.h"
16#include "lldb/Symbol/Type.h"
17#include "lldb/Symbol/Variable.h"
18#include "lldb/Target/ExecutionContext.h"
19#include "lldb/Target/Process.h"
20#include "lldb/Target/SectionLoadList.h"
21#include "lldb/Target/Target.h"
22#include "lldb/Utility/ConstString.h"
23#include "lldb/Utility/DataBufferHeap.h"
24#include "lldb/Utility/DataExtractor.h"
25#include "lldb/Utility/Endian.h"
26#include "lldb/Utility/FileSpec.h"
27#include "lldb/Utility/State.h"
28#include "lldb/Utility/Stream.h"
29#include "lldb/lldb-defines.h"
30#include "lldb/lldb-forward.h"
31#include "lldb/lldb-types.h"
32
33#include <memory>
34#include <optional>
35#include <string>
36
37#include <cinttypes>
38
39using namespace lldb;
40using namespace lldb_private;
41
42Value::Value() : m_value(), m_compiler_type(), m_data_buffer() {}
43
44Value::Value(const Scalar &scalar)
45    : m_value(scalar), m_compiler_type(), m_data_buffer() {}
46
47Value::Value(const void *bytes, int len)
48    : m_value(), m_compiler_type(), m_value_type(ValueType::HostAddress),
49      m_data_buffer() {
50  SetBytes(bytes, len);
51}
52
53Value::Value(const Value &v)
54    : m_value(v.m_value), m_compiler_type(v.m_compiler_type),
55      m_context(v.m_context), m_value_type(v.m_value_type),
56      m_context_type(v.m_context_type), m_data_buffer() {
57  const uintptr_t rhs_value =
58      (uintptr_t)v.m_value.ULongLong(LLDB_INVALID_ADDRESS);
59  if ((rhs_value != 0) &&
60      (rhs_value == (uintptr_t)v.m_data_buffer.GetBytes())) {
61    m_data_buffer.CopyData(v.m_data_buffer.GetBytes(),
62                           v.m_data_buffer.GetByteSize());
63
64    m_value = (uintptr_t)m_data_buffer.GetBytes();
65  }
66}
67
68Value &Value::operator=(const Value &rhs) {
69  if (this != &rhs) {
70    m_value = rhs.m_value;
71    m_compiler_type = rhs.m_compiler_type;
72    m_context = rhs.m_context;
73    m_value_type = rhs.m_value_type;
74    m_context_type = rhs.m_context_type;
75    const uintptr_t rhs_value =
76        (uintptr_t)rhs.m_value.ULongLong(LLDB_INVALID_ADDRESS);
77    if ((rhs_value != 0) &&
78        (rhs_value == (uintptr_t)rhs.m_data_buffer.GetBytes())) {
79      m_data_buffer.CopyData(rhs.m_data_buffer.GetBytes(),
80                             rhs.m_data_buffer.GetByteSize());
81
82      m_value = (uintptr_t)m_data_buffer.GetBytes();
83    }
84  }
85  return *this;
86}
87
88void Value::SetBytes(const void *bytes, int len) {
89  m_value_type = ValueType::HostAddress;
90  m_data_buffer.CopyData(bytes, len);
91  m_value = (uintptr_t)m_data_buffer.GetBytes();
92}
93
94void Value::AppendBytes(const void *bytes, int len) {
95  m_value_type = ValueType::HostAddress;
96  m_data_buffer.AppendData(bytes, len);
97  m_value = (uintptr_t)m_data_buffer.GetBytes();
98}
99
100void Value::Dump(Stream *strm) {
101  if (!strm)
102    return;
103  m_value.GetValue(*strm, true);
104  strm->Printf(", value_type = %s, context = %p, context_type = %s",
105               Value::GetValueTypeAsCString(m_value_type), m_context,
106               Value::GetContextTypeAsCString(m_context_type));
107}
108
109Value::ValueType Value::GetValueType() const { return m_value_type; }
110
111AddressType Value::GetValueAddressType() const {
112  switch (m_value_type) {
113  case ValueType::Invalid:
114  case ValueType::Scalar:
115    break;
116  case ValueType::LoadAddress:
117    return eAddressTypeLoad;
118  case ValueType::FileAddress:
119    return eAddressTypeFile;
120  case ValueType::HostAddress:
121    return eAddressTypeHost;
122  }
123  return eAddressTypeInvalid;
124}
125
126Value::ValueType Value::GetValueTypeFromAddressType(AddressType address_type) {
127  switch (address_type) {
128    case eAddressTypeFile:
129      return Value::ValueType::FileAddress;
130    case eAddressTypeLoad:
131      return Value::ValueType::LoadAddress;
132    case eAddressTypeHost:
133      return Value::ValueType::HostAddress;
134    case eAddressTypeInvalid:
135      return Value::ValueType::Invalid;
136  }
137  llvm_unreachable("Unexpected address type!");
138}
139
140RegisterInfo *Value::GetRegisterInfo() const {
141  if (m_context_type == ContextType::RegisterInfo)
142    return static_cast<RegisterInfo *>(m_context);
143  return nullptr;
144}
145
146Type *Value::GetType() {
147  if (m_context_type == ContextType::LLDBType)
148    return static_cast<Type *>(m_context);
149  return nullptr;
150}
151
152size_t Value::AppendDataToHostBuffer(const Value &rhs) {
153  if (this == &rhs)
154    return 0;
155
156  size_t curr_size = m_data_buffer.GetByteSize();
157  Status error;
158  switch (rhs.GetValueType()) {
159  case ValueType::Invalid:
160    return 0;
161  case ValueType::Scalar: {
162    const size_t scalar_size = rhs.m_value.GetByteSize();
163    if (scalar_size > 0) {
164      const size_t new_size = curr_size + scalar_size;
165      if (ResizeData(new_size) == new_size) {
166        rhs.m_value.GetAsMemoryData(m_data_buffer.GetBytes() + curr_size,
167                                    scalar_size, endian::InlHostByteOrder(),
168                                    error);
169        return scalar_size;
170      }
171    }
172  } break;
173  case ValueType::FileAddress:
174  case ValueType::LoadAddress:
175  case ValueType::HostAddress: {
176    const uint8_t *src = rhs.GetBuffer().GetBytes();
177    const size_t src_len = rhs.GetBuffer().GetByteSize();
178    if (src && src_len > 0) {
179      const size_t new_size = curr_size + src_len;
180      if (ResizeData(new_size) == new_size) {
181        ::memcpy(m_data_buffer.GetBytes() + curr_size, src, src_len);
182        return src_len;
183      }
184    }
185  } break;
186  }
187  return 0;
188}
189
190size_t Value::ResizeData(size_t len) {
191  m_value_type = ValueType::HostAddress;
192  m_data_buffer.SetByteSize(len);
193  m_value = (uintptr_t)m_data_buffer.GetBytes();
194  return m_data_buffer.GetByteSize();
195}
196
197bool Value::ValueOf(ExecutionContext *exe_ctx) {
198  switch (m_context_type) {
199  case ContextType::Invalid:
200  case ContextType::RegisterInfo: // RegisterInfo *
201  case ContextType::LLDBType:     // Type *
202    break;
203
204  case ContextType::Variable: // Variable *
205    ResolveValue(exe_ctx);
206    return true;
207  }
208  return false;
209}
210
211uint64_t Value::GetValueByteSize(Status *error_ptr, ExecutionContext *exe_ctx) {
212  switch (m_context_type) {
213  case ContextType::RegisterInfo: // RegisterInfo *
214    if (GetRegisterInfo()) {
215      if (error_ptr)
216        error_ptr->Clear();
217      return GetRegisterInfo()->byte_size;
218    }
219    break;
220
221  case ContextType::Invalid:
222  case ContextType::LLDBType: // Type *
223  case ContextType::Variable: // Variable *
224  {
225    auto *scope = exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr;
226    if (std::optional<uint64_t> size = GetCompilerType().GetByteSize(scope)) {
227      if (error_ptr)
228        error_ptr->Clear();
229      return *size;
230    }
231    break;
232  }
233  }
234  if (error_ptr && error_ptr->Success())
235    error_ptr->SetErrorString("Unable to determine byte size.");
236  return 0;
237}
238
239const CompilerType &Value::GetCompilerType() {
240  if (!m_compiler_type.IsValid()) {
241    switch (m_context_type) {
242    case ContextType::Invalid:
243      break;
244
245    case ContextType::RegisterInfo:
246      break; // TODO: Eventually convert into a compiler type?
247
248    case ContextType::LLDBType: {
249      Type *lldb_type = GetType();
250      if (lldb_type)
251        m_compiler_type = lldb_type->GetForwardCompilerType();
252    } break;
253
254    case ContextType::Variable: {
255      Variable *variable = GetVariable();
256      if (variable) {
257        Type *variable_type = variable->GetType();
258        if (variable_type)
259          m_compiler_type = variable_type->GetForwardCompilerType();
260      }
261    } break;
262    }
263  }
264
265  return m_compiler_type;
266}
267
268void Value::SetCompilerType(const CompilerType &compiler_type) {
269  m_compiler_type = compiler_type;
270}
271
272lldb::Format Value::GetValueDefaultFormat() {
273  switch (m_context_type) {
274  case ContextType::RegisterInfo:
275    if (GetRegisterInfo())
276      return GetRegisterInfo()->format;
277    break;
278
279  case ContextType::Invalid:
280  case ContextType::LLDBType:
281  case ContextType::Variable: {
282    const CompilerType &ast_type = GetCompilerType();
283    if (ast_type.IsValid())
284      return ast_type.GetFormat();
285  } break;
286  }
287
288  // Return a good default in case we can't figure anything out
289  return eFormatHex;
290}
291
292bool Value::GetData(DataExtractor &data) {
293  switch (m_value_type) {
294  case ValueType::Invalid:
295    return false;
296  case ValueType::Scalar:
297    if (m_value.GetData(data))
298      return true;
299    break;
300
301  case ValueType::LoadAddress:
302  case ValueType::FileAddress:
303  case ValueType::HostAddress:
304    if (m_data_buffer.GetByteSize()) {
305      data.SetData(m_data_buffer.GetBytes(), m_data_buffer.GetByteSize(),
306                   data.GetByteOrder());
307      return true;
308    }
309    break;
310  }
311
312  return false;
313}
314
315Status Value::GetValueAsData(ExecutionContext *exe_ctx, DataExtractor &data,
316                             Module *module) {
317  data.Clear();
318
319  Status error;
320  lldb::addr_t address = LLDB_INVALID_ADDRESS;
321  AddressType address_type = eAddressTypeFile;
322  Address file_so_addr;
323  const CompilerType &ast_type = GetCompilerType();
324  std::optional<uint64_t> type_size = ast_type.GetByteSize(
325      exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr);
326  // Nothing to be done for a zero-sized type.
327  if (type_size && *type_size == 0)
328    return error;
329
330  switch (m_value_type) {
331  case ValueType::Invalid:
332    error.SetErrorString("invalid value");
333    break;
334  case ValueType::Scalar: {
335    data.SetByteOrder(endian::InlHostByteOrder());
336    if (ast_type.IsValid())
337      data.SetAddressByteSize(ast_type.GetPointerByteSize());
338    else
339      data.SetAddressByteSize(sizeof(void *));
340
341    uint32_t limit_byte_size = UINT32_MAX;
342
343    if (type_size)
344      limit_byte_size = *type_size;
345
346    if (limit_byte_size <= m_value.GetByteSize()) {
347      if (m_value.GetData(data, limit_byte_size))
348        return error; // Success;
349    }
350
351    error.SetErrorString("extracting data from value failed");
352    break;
353  }
354  case ValueType::LoadAddress:
355    if (exe_ctx == nullptr) {
356      error.SetErrorString("can't read load address (no execution context)");
357    } else {
358      Process *process = exe_ctx->GetProcessPtr();
359      if (process == nullptr || !process->IsAlive()) {
360        Target *target = exe_ctx->GetTargetPtr();
361        if (target) {
362          // Allow expressions to run and evaluate things when the target has
363          // memory sections loaded. This allows you to use "target modules
364          // load" to load your executable and any shared libraries, then
365          // execute commands where you can look at types in data sections.
366          const SectionLoadList &target_sections = target->GetSectionLoadList();
367          if (!target_sections.IsEmpty()) {
368            address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
369            if (target_sections.ResolveLoadAddress(address, file_so_addr)) {
370              address_type = eAddressTypeLoad;
371              data.SetByteOrder(target->GetArchitecture().GetByteOrder());
372              data.SetAddressByteSize(
373                  target->GetArchitecture().GetAddressByteSize());
374            } else
375              address = LLDB_INVALID_ADDRESS;
376          }
377        } else {
378          error.SetErrorString("can't read load address (invalid process)");
379        }
380      } else {
381        address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
382        address_type = eAddressTypeLoad;
383        data.SetByteOrder(
384            process->GetTarget().GetArchitecture().GetByteOrder());
385        data.SetAddressByteSize(
386            process->GetTarget().GetArchitecture().GetAddressByteSize());
387      }
388    }
389    break;
390
391  case ValueType::FileAddress:
392    if (exe_ctx == nullptr) {
393      error.SetErrorString("can't read file address (no execution context)");
394    } else if (exe_ctx->GetTargetPtr() == nullptr) {
395      error.SetErrorString("can't read file address (invalid target)");
396    } else {
397      address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
398      if (address == LLDB_INVALID_ADDRESS) {
399        error.SetErrorString("invalid file address");
400      } else {
401        if (module == nullptr) {
402          // The only thing we can currently lock down to a module so that we
403          // can resolve a file address, is a variable.
404          Variable *variable = GetVariable();
405          if (variable) {
406            SymbolContext var_sc;
407            variable->CalculateSymbolContext(&var_sc);
408            module = var_sc.module_sp.get();
409          }
410        }
411
412        if (module) {
413          bool resolved = false;
414          ObjectFile *objfile = module->GetObjectFile();
415          if (objfile) {
416            Address so_addr(address, objfile->GetSectionList());
417            addr_t load_address =
418                so_addr.GetLoadAddress(exe_ctx->GetTargetPtr());
419            bool process_launched_and_stopped =
420                exe_ctx->GetProcessPtr()
421                    ? StateIsStoppedState(exe_ctx->GetProcessPtr()->GetState(),
422                                          true /* must_exist */)
423                    : false;
424            // Don't use the load address if the process has exited.
425            if (load_address != LLDB_INVALID_ADDRESS &&
426                process_launched_and_stopped) {
427              resolved = true;
428              address = load_address;
429              address_type = eAddressTypeLoad;
430              data.SetByteOrder(
431                  exe_ctx->GetTargetRef().GetArchitecture().GetByteOrder());
432              data.SetAddressByteSize(exe_ctx->GetTargetRef()
433                                          .GetArchitecture()
434                                          .GetAddressByteSize());
435            } else {
436              if (so_addr.IsSectionOffset()) {
437                resolved = true;
438                file_so_addr = so_addr;
439                data.SetByteOrder(objfile->GetByteOrder());
440                data.SetAddressByteSize(objfile->GetAddressByteSize());
441              }
442            }
443          }
444          if (!resolved) {
445            Variable *variable = GetVariable();
446
447            if (module) {
448              if (variable)
449                error.SetErrorStringWithFormat(
450                    "unable to resolve the module for file address 0x%" PRIx64
451                    " for variable '%s' in %s",
452                    address, variable->GetName().AsCString(""),
453                    module->GetFileSpec().GetPath().c_str());
454              else
455                error.SetErrorStringWithFormat(
456                    "unable to resolve the module for file address 0x%" PRIx64
457                    " in %s",
458                    address, module->GetFileSpec().GetPath().c_str());
459            } else {
460              if (variable)
461                error.SetErrorStringWithFormat(
462                    "unable to resolve the module for file address 0x%" PRIx64
463                    " for variable '%s'",
464                    address, variable->GetName().AsCString(""));
465              else
466                error.SetErrorStringWithFormat(
467                    "unable to resolve the module for file address 0x%" PRIx64,
468                    address);
469            }
470          }
471        } else {
472          // Can't convert a file address to anything valid without more
473          // context (which Module it came from)
474          error.SetErrorString(
475              "can't read memory from file address without more context");
476        }
477      }
478    }
479    break;
480
481  case ValueType::HostAddress:
482    address = m_value.ULongLong(LLDB_INVALID_ADDRESS);
483    address_type = eAddressTypeHost;
484    if (exe_ctx) {
485      Target *target = exe_ctx->GetTargetPtr();
486      if (target) {
487        data.SetByteOrder(target->GetArchitecture().GetByteOrder());
488        data.SetAddressByteSize(target->GetArchitecture().GetAddressByteSize());
489        break;
490      }
491    }
492    // fallback to host settings
493    data.SetByteOrder(endian::InlHostByteOrder());
494    data.SetAddressByteSize(sizeof(void *));
495    break;
496  }
497
498  // Bail if we encountered any errors
499  if (error.Fail())
500    return error;
501
502  if (address == LLDB_INVALID_ADDRESS) {
503    error.SetErrorStringWithFormat("invalid %s address",
504                                   address_type == eAddressTypeHost ? "host"
505                                                                    : "load");
506    return error;
507  }
508
509  // If we got here, we need to read the value from memory.
510  size_t byte_size = GetValueByteSize(&error, exe_ctx);
511
512  // Bail if we encountered any errors getting the byte size.
513  if (error.Fail())
514    return error;
515
516  // No memory to read for zero-sized types.
517  if (byte_size == 0)
518    return error;
519
520  // Make sure we have enough room within "data", and if we don't make
521  // something large enough that does
522  if (!data.ValidOffsetForDataOfSize(0, byte_size)) {
523    auto data_sp = std::make_shared<DataBufferHeap>(byte_size, '\0');
524    data.SetData(data_sp);
525  }
526
527  uint8_t *dst = const_cast<uint8_t *>(data.PeekData(0, byte_size));
528  if (dst != nullptr) {
529    if (address_type == eAddressTypeHost) {
530      // The address is an address in this process, so just copy it.
531      if (address == 0) {
532        error.SetErrorString("trying to read from host address of 0.");
533        return error;
534      }
535      memcpy(dst, reinterpret_cast<uint8_t *>(address), byte_size);
536    } else if ((address_type == eAddressTypeLoad) ||
537               (address_type == eAddressTypeFile)) {
538      if (file_so_addr.IsValid()) {
539        const bool force_live_memory = true;
540        if (exe_ctx->GetTargetRef().ReadMemory(file_so_addr, dst, byte_size,
541                                               error, force_live_memory) !=
542            byte_size) {
543          error.SetErrorStringWithFormat(
544              "read memory from 0x%" PRIx64 " failed", (uint64_t)address);
545        }
546      } else {
547        // The execution context might have a NULL process, but it might have a
548        // valid process in the exe_ctx->target, so use the
549        // ExecutionContext::GetProcess accessor to ensure we get the process
550        // if there is one.
551        Process *process = exe_ctx->GetProcessPtr();
552
553        if (process) {
554          const size_t bytes_read =
555              process->ReadMemory(address, dst, byte_size, error);
556          if (bytes_read != byte_size)
557            error.SetErrorStringWithFormat(
558                "read memory from 0x%" PRIx64 " failed (%u of %u bytes read)",
559                (uint64_t)address, (uint32_t)bytes_read, (uint32_t)byte_size);
560        } else {
561          error.SetErrorStringWithFormat("read memory from 0x%" PRIx64
562                                         " failed (invalid process)",
563                                         (uint64_t)address);
564        }
565      }
566    } else {
567      error.SetErrorStringWithFormat("unsupported AddressType value (%i)",
568                                     address_type);
569    }
570  } else {
571    error.SetErrorString("out of memory");
572  }
573
574  return error;
575}
576
577Scalar &Value::ResolveValue(ExecutionContext *exe_ctx, Module *module) {
578  const CompilerType &compiler_type = GetCompilerType();
579  if (compiler_type.IsValid()) {
580    switch (m_value_type) {
581    case ValueType::Invalid:
582    case ValueType::Scalar: // raw scalar value
583      break;
584
585    case ValueType::FileAddress:
586    case ValueType::LoadAddress: // load address value
587    case ValueType::HostAddress: // host address value (for memory in the process
588                                // that is using liblldb)
589    {
590      DataExtractor data;
591      lldb::addr_t addr = m_value.ULongLong(LLDB_INVALID_ADDRESS);
592      Status error(GetValueAsData(exe_ctx, data, module));
593      if (error.Success()) {
594        Scalar scalar;
595        if (compiler_type.GetValueAsScalar(
596                data, 0, data.GetByteSize(), scalar,
597                exe_ctx ? exe_ctx->GetBestExecutionContextScope() : nullptr)) {
598          m_value = scalar;
599          m_value_type = ValueType::Scalar;
600        } else {
601          if ((uintptr_t)addr != (uintptr_t)m_data_buffer.GetBytes()) {
602            m_value.Clear();
603            m_value_type = ValueType::Scalar;
604          }
605        }
606      } else {
607        if ((uintptr_t)addr != (uintptr_t)m_data_buffer.GetBytes()) {
608          m_value.Clear();
609          m_value_type = ValueType::Scalar;
610        }
611      }
612    } break;
613    }
614  }
615  return m_value;
616}
617
618Variable *Value::GetVariable() {
619  if (m_context_type == ContextType::Variable)
620    return static_cast<Variable *>(m_context);
621  return nullptr;
622}
623
624void Value::Clear() {
625  m_value.Clear();
626  m_compiler_type.Clear();
627  m_value_type = ValueType::Scalar;
628  m_context = nullptr;
629  m_context_type = ContextType::Invalid;
630  m_data_buffer.Clear();
631}
632
633const char *Value::GetValueTypeAsCString(ValueType value_type) {
634  switch (value_type) {
635  case ValueType::Invalid:
636    return "invalid";
637  case ValueType::Scalar:
638    return "scalar";
639  case ValueType::FileAddress:
640    return "file address";
641  case ValueType::LoadAddress:
642    return "load address";
643  case ValueType::HostAddress:
644    return "host address";
645  };
646  llvm_unreachable("enum cases exhausted.");
647}
648
649const char *Value::GetContextTypeAsCString(ContextType context_type) {
650  switch (context_type) {
651  case ContextType::Invalid:
652    return "invalid";
653  case ContextType::RegisterInfo:
654    return "RegisterInfo *";
655  case ContextType::LLDBType:
656    return "Type *";
657  case ContextType::Variable:
658    return "Variable *";
659  };
660  llvm_unreachable("enum cases exhausted.");
661}
662
663void Value::ConvertToLoadAddress(Module *module, Target *target) {
664  if (!module || !target || (GetValueType() != ValueType::FileAddress))
665    return;
666
667  lldb::addr_t file_addr = GetScalar().ULongLong(LLDB_INVALID_ADDRESS);
668  if (file_addr == LLDB_INVALID_ADDRESS)
669    return;
670
671  Address so_addr;
672  if (!module->ResolveFileAddress(file_addr, so_addr))
673    return;
674  lldb::addr_t load_addr = so_addr.GetLoadAddress(target);
675  if (load_addr == LLDB_INVALID_ADDRESS)
676    return;
677
678  SetValueType(Value::ValueType::LoadAddress);
679  GetScalar() = load_addr;
680}
681
682void ValueList::PushValue(const Value &value) { m_values.push_back(value); }
683
684size_t ValueList::GetSize() { return m_values.size(); }
685
686Value *ValueList::GetValueAtIndex(size_t idx) {
687  if (idx < GetSize()) {
688    return &(m_values[idx]);
689  } else
690    return nullptr;
691}
692
693void ValueList::Clear() { m_values.clear(); }
694