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