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

source code of lldb/source/Core/Value.cpp