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