1 //===-- SBValue.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/API/SBValue.h"
10 #include "lldb/Utility/Instrumentation.h"
11
12 #include "lldb/API/SBDeclaration.h"
13 #include "lldb/API/SBStream.h"
14 #include "lldb/API/SBTypeFilter.h"
15 #include "lldb/API/SBTypeFormat.h"
16 #include "lldb/API/SBTypeSummary.h"
17 #include "lldb/API/SBTypeSynthetic.h"
18
19 #include "lldb/Breakpoint/Watchpoint.h"
20 #include "lldb/Core/Declaration.h"
21 #include "lldb/Core/Module.h"
22 #include "lldb/Core/Section.h"
23 #include "lldb/Core/Value.h"
24 #include "lldb/Core/ValueObject.h"
25 #include "lldb/Core/ValueObjectConstResult.h"
26 #include "lldb/DataFormatters/DataVisualization.h"
27 #include "lldb/DataFormatters/DumpValueObjectOptions.h"
28 #include "lldb/Symbol/Block.h"
29 #include "lldb/Symbol/ObjectFile.h"
30 #include "lldb/Symbol/Type.h"
31 #include "lldb/Symbol/Variable.h"
32 #include "lldb/Symbol/VariableList.h"
33 #include "lldb/Target/ExecutionContext.h"
34 #include "lldb/Target/Process.h"
35 #include "lldb/Target/StackFrame.h"
36 #include "lldb/Target/Target.h"
37 #include "lldb/Target/Thread.h"
38 #include "lldb/Utility/DataExtractor.h"
39 #include "lldb/Utility/Scalar.h"
40 #include "lldb/Utility/Stream.h"
41
42 #include "lldb/API/SBDebugger.h"
43 #include "lldb/API/SBExpressionOptions.h"
44 #include "lldb/API/SBFrame.h"
45 #include "lldb/API/SBProcess.h"
46 #include "lldb/API/SBTarget.h"
47 #include "lldb/API/SBThread.h"
48
49 #include <memory>
50
51 using namespace lldb;
52 using namespace lldb_private;
53
54 class ValueImpl {
55 public:
56 ValueImpl() = default;
57
ValueImpl(lldb::ValueObjectSP in_valobj_sp,lldb::DynamicValueType use_dynamic,bool use_synthetic,const char * name=nullptr)58 ValueImpl(lldb::ValueObjectSP in_valobj_sp,
59 lldb::DynamicValueType use_dynamic, bool use_synthetic,
60 const char *name = nullptr)
61 : m_use_dynamic(use_dynamic), m_use_synthetic(use_synthetic),
62 m_name(name) {
63 if (in_valobj_sp) {
64 if ((m_valobj_sp = in_valobj_sp->GetQualifiedRepresentationIfAvailable(
65 lldb::eNoDynamicValues, false))) {
66 if (!m_name.IsEmpty())
67 m_valobj_sp->SetName(m_name);
68 }
69 }
70 }
71
72 ValueImpl(const ValueImpl &rhs) = default;
73
operator =(const ValueImpl & rhs)74 ValueImpl &operator=(const ValueImpl &rhs) {
75 if (this != &rhs) {
76 m_valobj_sp = rhs.m_valobj_sp;
77 m_use_dynamic = rhs.m_use_dynamic;
78 m_use_synthetic = rhs.m_use_synthetic;
79 m_name = rhs.m_name;
80 }
81 return *this;
82 }
83
IsValid()84 bool IsValid() {
85 if (m_valobj_sp.get() == nullptr)
86 return false;
87 else {
88 // FIXME: This check is necessary but not sufficient. We for sure don't
89 // want to touch SBValues whose owning
90 // targets have gone away. This check is a little weak in that it
91 // enforces that restriction when you call IsValid, but since IsValid
92 // doesn't lock the target, you have no guarantee that the SBValue won't
93 // go invalid after you call this... Also, an SBValue could depend on
94 // data from one of the modules in the target, and those could go away
95 // independently of the target, for instance if a module is unloaded.
96 // But right now, neither SBValues nor ValueObjects know which modules
97 // they depend on. So I have no good way to make that check without
98 // tracking that in all the ValueObject subclasses.
99 TargetSP target_sp = m_valobj_sp->GetTargetSP();
100 return target_sp && target_sp->IsValid();
101 }
102 }
103
GetRootSP()104 lldb::ValueObjectSP GetRootSP() { return m_valobj_sp; }
105
GetSP(Process::StopLocker & stop_locker,std::unique_lock<std::recursive_mutex> & lock,Status & error)106 lldb::ValueObjectSP GetSP(Process::StopLocker &stop_locker,
107 std::unique_lock<std::recursive_mutex> &lock,
108 Status &error) {
109 if (!m_valobj_sp) {
110 error.SetErrorString("invalid value object");
111 return m_valobj_sp;
112 }
113
114 lldb::ValueObjectSP value_sp = m_valobj_sp;
115
116 Target *target = value_sp->GetTargetSP().get();
117 // If this ValueObject holds an error, then it is valuable for that.
118 if (value_sp->GetError().Fail())
119 return value_sp;
120
121 if (!target)
122 return ValueObjectSP();
123
124 lock = std::unique_lock<std::recursive_mutex>(target->GetAPIMutex());
125
126 ProcessSP process_sp(value_sp->GetProcessSP());
127 if (process_sp && !stop_locker.TryLock(&process_sp->GetRunLock())) {
128 // We don't allow people to play around with ValueObject if the process
129 // is running. If you want to look at values, pause the process, then
130 // look.
131 error.SetErrorString("process must be stopped.");
132 return ValueObjectSP();
133 }
134
135 if (m_use_dynamic != eNoDynamicValues) {
136 ValueObjectSP dynamic_sp = value_sp->GetDynamicValue(m_use_dynamic);
137 if (dynamic_sp)
138 value_sp = dynamic_sp;
139 }
140
141 if (m_use_synthetic) {
142 ValueObjectSP synthetic_sp = value_sp->GetSyntheticValue();
143 if (synthetic_sp)
144 value_sp = synthetic_sp;
145 }
146
147 if (!value_sp)
148 error.SetErrorString("invalid value object");
149 if (!m_name.IsEmpty())
150 value_sp->SetName(m_name);
151
152 return value_sp;
153 }
154
SetUseDynamic(lldb::DynamicValueType use_dynamic)155 void SetUseDynamic(lldb::DynamicValueType use_dynamic) {
156 m_use_dynamic = use_dynamic;
157 }
158
SetUseSynthetic(bool use_synthetic)159 void SetUseSynthetic(bool use_synthetic) { m_use_synthetic = use_synthetic; }
160
GetUseDynamic()161 lldb::DynamicValueType GetUseDynamic() { return m_use_dynamic; }
162
GetUseSynthetic()163 bool GetUseSynthetic() { return m_use_synthetic; }
164
165 // All the derived values that we would make from the m_valobj_sp will share
166 // the ExecutionContext with m_valobj_sp, so we don't need to do the
167 // calculations in GetSP to return the Target, Process, Thread or Frame. It
168 // is convenient to provide simple accessors for these, which I do here.
GetTargetSP()169 TargetSP GetTargetSP() {
170 if (m_valobj_sp)
171 return m_valobj_sp->GetTargetSP();
172 else
173 return TargetSP();
174 }
175
GetProcessSP()176 ProcessSP GetProcessSP() {
177 if (m_valobj_sp)
178 return m_valobj_sp->GetProcessSP();
179 else
180 return ProcessSP();
181 }
182
GetThreadSP()183 ThreadSP GetThreadSP() {
184 if (m_valobj_sp)
185 return m_valobj_sp->GetThreadSP();
186 else
187 return ThreadSP();
188 }
189
GetFrameSP()190 StackFrameSP GetFrameSP() {
191 if (m_valobj_sp)
192 return m_valobj_sp->GetFrameSP();
193 else
194 return StackFrameSP();
195 }
196
197 private:
198 lldb::ValueObjectSP m_valobj_sp;
199 lldb::DynamicValueType m_use_dynamic;
200 bool m_use_synthetic;
201 ConstString m_name;
202 };
203
204 class ValueLocker {
205 public:
206 ValueLocker() = default;
207
GetLockedSP(ValueImpl & in_value)208 ValueObjectSP GetLockedSP(ValueImpl &in_value) {
209 return in_value.GetSP(m_stop_locker, m_lock, m_lock_error);
210 }
211
GetError()212 Status &GetError() { return m_lock_error; }
213
214 private:
215 Process::StopLocker m_stop_locker;
216 std::unique_lock<std::recursive_mutex> m_lock;
217 Status m_lock_error;
218 };
219
SBValue()220 SBValue::SBValue() { LLDB_INSTRUMENT_VA(this); }
221
SBValue(const lldb::ValueObjectSP & value_sp)222 SBValue::SBValue(const lldb::ValueObjectSP &value_sp) {
223 LLDB_INSTRUMENT_VA(this, value_sp);
224
225 SetSP(value_sp);
226 }
227
SBValue(const SBValue & rhs)228 SBValue::SBValue(const SBValue &rhs) {
229 LLDB_INSTRUMENT_VA(this, rhs);
230
231 SetSP(rhs.m_opaque_sp);
232 }
233
operator =(const SBValue & rhs)234 SBValue &SBValue::operator=(const SBValue &rhs) {
235 LLDB_INSTRUMENT_VA(this, rhs);
236
237 if (this != &rhs) {
238 SetSP(rhs.m_opaque_sp);
239 }
240 return *this;
241 }
242
243 SBValue::~SBValue() = default;
244
IsValid()245 bool SBValue::IsValid() {
246 LLDB_INSTRUMENT_VA(this);
247 return this->operator bool();
248 }
operator bool() const249 SBValue::operator bool() const {
250 LLDB_INSTRUMENT_VA(this);
251
252 // If this function ever changes to anything that does more than just check
253 // if the opaque shared pointer is non NULL, then we need to update all "if
254 // (m_opaque_sp)" code in this file.
255 return m_opaque_sp.get() != nullptr && m_opaque_sp->IsValid() &&
256 m_opaque_sp->GetRootSP().get() != nullptr;
257 }
258
Clear()259 void SBValue::Clear() {
260 LLDB_INSTRUMENT_VA(this);
261
262 m_opaque_sp.reset();
263 }
264
GetError()265 SBError SBValue::GetError() {
266 LLDB_INSTRUMENT_VA(this);
267
268 SBError sb_error;
269
270 ValueLocker locker;
271 lldb::ValueObjectSP value_sp(GetSP(locker));
272 if (value_sp)
273 sb_error.SetError(value_sp->GetError());
274 else
275 sb_error.SetErrorStringWithFormat("error: %s",
276 locker.GetError().AsCString());
277
278 return sb_error;
279 }
280
GetID()281 user_id_t SBValue::GetID() {
282 LLDB_INSTRUMENT_VA(this);
283
284 ValueLocker locker;
285 lldb::ValueObjectSP value_sp(GetSP(locker));
286 if (value_sp)
287 return value_sp->GetID();
288 return LLDB_INVALID_UID;
289 }
290
GetName()291 const char *SBValue::GetName() {
292 LLDB_INSTRUMENT_VA(this);
293
294 ValueLocker locker;
295 lldb::ValueObjectSP value_sp(GetSP(locker));
296 if (!value_sp)
297 return nullptr;
298
299 return value_sp->GetName().GetCString();
300 }
301
GetTypeName()302 const char *SBValue::GetTypeName() {
303 LLDB_INSTRUMENT_VA(this);
304
305 ValueLocker locker;
306 lldb::ValueObjectSP value_sp(GetSP(locker));
307 if (!value_sp)
308 return nullptr;
309
310 return value_sp->GetQualifiedTypeName().GetCString();
311 }
312
GetDisplayTypeName()313 const char *SBValue::GetDisplayTypeName() {
314 LLDB_INSTRUMENT_VA(this);
315
316 ValueLocker locker;
317 lldb::ValueObjectSP value_sp(GetSP(locker));
318 if (!value_sp)
319 return nullptr;
320
321 return value_sp->GetDisplayTypeName().GetCString();
322 }
323
GetByteSize()324 size_t SBValue::GetByteSize() {
325 LLDB_INSTRUMENT_VA(this);
326
327 size_t result = 0;
328
329 ValueLocker locker;
330 lldb::ValueObjectSP value_sp(GetSP(locker));
331 if (value_sp) {
332 result = value_sp->GetByteSize().value_or(0);
333 }
334
335 return result;
336 }
337
IsInScope()338 bool SBValue::IsInScope() {
339 LLDB_INSTRUMENT_VA(this);
340
341 bool result = false;
342
343 ValueLocker locker;
344 lldb::ValueObjectSP value_sp(GetSP(locker));
345 if (value_sp) {
346 result = value_sp->IsInScope();
347 }
348
349 return result;
350 }
351
GetValue()352 const char *SBValue::GetValue() {
353 LLDB_INSTRUMENT_VA(this);
354
355 ValueLocker locker;
356 lldb::ValueObjectSP value_sp(GetSP(locker));
357 if (!value_sp)
358 return nullptr;
359 return ConstString(value_sp->GetValueAsCString()).GetCString();
360 }
361
GetValueType()362 ValueType SBValue::GetValueType() {
363 LLDB_INSTRUMENT_VA(this);
364
365 ValueType result = eValueTypeInvalid;
366 ValueLocker locker;
367 lldb::ValueObjectSP value_sp(GetSP(locker));
368 if (value_sp)
369 result = value_sp->GetValueType();
370
371 return result;
372 }
373
GetObjectDescription()374 const char *SBValue::GetObjectDescription() {
375 LLDB_INSTRUMENT_VA(this);
376
377 ValueLocker locker;
378 lldb::ValueObjectSP value_sp(GetSP(locker));
379 if (!value_sp)
380 return nullptr;
381
382 return ConstString(value_sp->GetObjectDescription()).GetCString();
383 }
384
GetType()385 SBType SBValue::GetType() {
386 LLDB_INSTRUMENT_VA(this);
387
388 SBType sb_type;
389 ValueLocker locker;
390 lldb::ValueObjectSP value_sp(GetSP(locker));
391 TypeImplSP type_sp;
392 if (value_sp) {
393 type_sp = std::make_shared<TypeImpl>(value_sp->GetTypeImpl());
394 sb_type.SetSP(type_sp);
395 }
396
397 return sb_type;
398 }
399
GetValueDidChange()400 bool SBValue::GetValueDidChange() {
401 LLDB_INSTRUMENT_VA(this);
402
403 bool result = false;
404 ValueLocker locker;
405 lldb::ValueObjectSP value_sp(GetSP(locker));
406 if (value_sp) {
407 if (value_sp->UpdateValueIfNeeded(false))
408 result = value_sp->GetValueDidChange();
409 }
410
411 return result;
412 }
413
GetSummary()414 const char *SBValue::GetSummary() {
415 LLDB_INSTRUMENT_VA(this);
416
417 ValueLocker locker;
418 lldb::ValueObjectSP value_sp(GetSP(locker));
419 if (!value_sp)
420 return nullptr;
421
422 return ConstString(value_sp->GetSummaryAsCString()).GetCString();
423 }
424
GetSummary(lldb::SBStream & stream,lldb::SBTypeSummaryOptions & options)425 const char *SBValue::GetSummary(lldb::SBStream &stream,
426 lldb::SBTypeSummaryOptions &options) {
427 LLDB_INSTRUMENT_VA(this, stream, options);
428
429 ValueLocker locker;
430 lldb::ValueObjectSP value_sp(GetSP(locker));
431 if (value_sp) {
432 std::string buffer;
433 if (value_sp->GetSummaryAsCString(buffer, options.ref()) && !buffer.empty())
434 stream.Printf("%s", buffer.c_str());
435 }
436 return ConstString(stream.GetData()).GetCString();
437 }
438
GetLocation()439 const char *SBValue::GetLocation() {
440 LLDB_INSTRUMENT_VA(this);
441
442 ValueLocker locker;
443 lldb::ValueObjectSP value_sp(GetSP(locker));
444 if (!value_sp)
445 return nullptr;
446
447 return ConstString(value_sp->GetLocationAsCString()).GetCString();
448 }
449
450 // Deprecated - use the one that takes an lldb::SBError
SetValueFromCString(const char * value_str)451 bool SBValue::SetValueFromCString(const char *value_str) {
452 LLDB_INSTRUMENT_VA(this, value_str);
453
454 lldb::SBError dummy;
455 return SetValueFromCString(value_str, dummy);
456 }
457
SetValueFromCString(const char * value_str,lldb::SBError & error)458 bool SBValue::SetValueFromCString(const char *value_str, lldb::SBError &error) {
459 LLDB_INSTRUMENT_VA(this, value_str, error);
460
461 bool success = false;
462 ValueLocker locker;
463 lldb::ValueObjectSP value_sp(GetSP(locker));
464 if (value_sp) {
465 success = value_sp->SetValueFromCString(value_str, error.ref());
466 } else
467 error.SetErrorStringWithFormat("Could not get value: %s",
468 locker.GetError().AsCString());
469
470 return success;
471 }
472
GetTypeFormat()473 lldb::SBTypeFormat SBValue::GetTypeFormat() {
474 LLDB_INSTRUMENT_VA(this);
475
476 lldb::SBTypeFormat format;
477 ValueLocker locker;
478 lldb::ValueObjectSP value_sp(GetSP(locker));
479 if (value_sp) {
480 if (value_sp->UpdateValueIfNeeded(true)) {
481 lldb::TypeFormatImplSP format_sp = value_sp->GetValueFormat();
482 if (format_sp)
483 format.SetSP(format_sp);
484 }
485 }
486 return format;
487 }
488
GetTypeSummary()489 lldb::SBTypeSummary SBValue::GetTypeSummary() {
490 LLDB_INSTRUMENT_VA(this);
491
492 lldb::SBTypeSummary summary;
493 ValueLocker locker;
494 lldb::ValueObjectSP value_sp(GetSP(locker));
495 if (value_sp) {
496 if (value_sp->UpdateValueIfNeeded(true)) {
497 lldb::TypeSummaryImplSP summary_sp = value_sp->GetSummaryFormat();
498 if (summary_sp)
499 summary.SetSP(summary_sp);
500 }
501 }
502 return summary;
503 }
504
GetTypeFilter()505 lldb::SBTypeFilter SBValue::GetTypeFilter() {
506 LLDB_INSTRUMENT_VA(this);
507
508 lldb::SBTypeFilter filter;
509 ValueLocker locker;
510 lldb::ValueObjectSP value_sp(GetSP(locker));
511 if (value_sp) {
512 if (value_sp->UpdateValueIfNeeded(true)) {
513 lldb::SyntheticChildrenSP synthetic_sp = value_sp->GetSyntheticChildren();
514
515 if (synthetic_sp && !synthetic_sp->IsScripted()) {
516 TypeFilterImplSP filter_sp =
517 std::static_pointer_cast<TypeFilterImpl>(synthetic_sp);
518 filter.SetSP(filter_sp);
519 }
520 }
521 }
522 return filter;
523 }
524
GetTypeSynthetic()525 lldb::SBTypeSynthetic SBValue::GetTypeSynthetic() {
526 LLDB_INSTRUMENT_VA(this);
527
528 lldb::SBTypeSynthetic synthetic;
529 ValueLocker locker;
530 lldb::ValueObjectSP value_sp(GetSP(locker));
531 if (value_sp) {
532 if (value_sp->UpdateValueIfNeeded(true)) {
533 lldb::SyntheticChildrenSP children_sp = value_sp->GetSyntheticChildren();
534
535 if (children_sp && children_sp->IsScripted()) {
536 ScriptedSyntheticChildrenSP synth_sp =
537 std::static_pointer_cast<ScriptedSyntheticChildren>(children_sp);
538 synthetic.SetSP(synth_sp);
539 }
540 }
541 }
542 return synthetic;
543 }
544
CreateChildAtOffset(const char * name,uint32_t offset,SBType type)545 lldb::SBValue SBValue::CreateChildAtOffset(const char *name, uint32_t offset,
546 SBType type) {
547 LLDB_INSTRUMENT_VA(this, name, offset, type);
548
549 lldb::SBValue sb_value;
550 ValueLocker locker;
551 lldb::ValueObjectSP value_sp(GetSP(locker));
552 lldb::ValueObjectSP new_value_sp;
553 if (value_sp) {
554 TypeImplSP type_sp(type.GetSP());
555 if (type.IsValid()) {
556 sb_value.SetSP(value_sp->GetSyntheticChildAtOffset(
557 offset, type_sp->GetCompilerType(false), true),
558 GetPreferDynamicValue(), GetPreferSyntheticValue(), name);
559 }
560 }
561 return sb_value;
562 }
563
Cast(SBType type)564 lldb::SBValue SBValue::Cast(SBType type) {
565 LLDB_INSTRUMENT_VA(this, type);
566
567 lldb::SBValue sb_value;
568 ValueLocker locker;
569 lldb::ValueObjectSP value_sp(GetSP(locker));
570 TypeImplSP type_sp(type.GetSP());
571 if (value_sp && type_sp)
572 sb_value.SetSP(value_sp->Cast(type_sp->GetCompilerType(false)),
573 GetPreferDynamicValue(), GetPreferSyntheticValue());
574 return sb_value;
575 }
576
CreateValueFromExpression(const char * name,const char * expression)577 lldb::SBValue SBValue::CreateValueFromExpression(const char *name,
578 const char *expression) {
579 LLDB_INSTRUMENT_VA(this, name, expression);
580
581 SBExpressionOptions options;
582 options.ref().SetKeepInMemory(true);
583 return CreateValueFromExpression(name, expression, options);
584 }
585
CreateValueFromExpression(const char * name,const char * expression,SBExpressionOptions & options)586 lldb::SBValue SBValue::CreateValueFromExpression(const char *name,
587 const char *expression,
588 SBExpressionOptions &options) {
589 LLDB_INSTRUMENT_VA(this, name, expression, options);
590
591 lldb::SBValue sb_value;
592 ValueLocker locker;
593 lldb::ValueObjectSP value_sp(GetSP(locker));
594 lldb::ValueObjectSP new_value_sp;
595 if (value_sp) {
596 ExecutionContext exe_ctx(value_sp->GetExecutionContextRef());
597 new_value_sp = ValueObject::CreateValueObjectFromExpression(
598 name, expression, exe_ctx, options.ref());
599 if (new_value_sp)
600 new_value_sp->SetName(ConstString(name));
601 }
602 sb_value.SetSP(new_value_sp);
603 return sb_value;
604 }
605
CreateValueFromAddress(const char * name,lldb::addr_t address,SBType sb_type)606 lldb::SBValue SBValue::CreateValueFromAddress(const char *name,
607 lldb::addr_t address,
608 SBType sb_type) {
609 LLDB_INSTRUMENT_VA(this, name, address, sb_type);
610
611 lldb::SBValue sb_value;
612 ValueLocker locker;
613 lldb::ValueObjectSP value_sp(GetSP(locker));
614 lldb::ValueObjectSP new_value_sp;
615 lldb::TypeImplSP type_impl_sp(sb_type.GetSP());
616 if (value_sp && type_impl_sp) {
617 CompilerType ast_type(type_impl_sp->GetCompilerType(true));
618 ExecutionContext exe_ctx(value_sp->GetExecutionContextRef());
619 new_value_sp = ValueObject::CreateValueObjectFromAddress(name, address,
620 exe_ctx, ast_type);
621 }
622 sb_value.SetSP(new_value_sp);
623 return sb_value;
624 }
625
CreateValueFromData(const char * name,SBData data,SBType sb_type)626 lldb::SBValue SBValue::CreateValueFromData(const char *name, SBData data,
627 SBType sb_type) {
628 LLDB_INSTRUMENT_VA(this, name, data, sb_type);
629
630 lldb::SBValue sb_value;
631 lldb::ValueObjectSP new_value_sp;
632 ValueLocker locker;
633 lldb::ValueObjectSP value_sp(GetSP(locker));
634 lldb::TypeImplSP type_impl_sp(sb_type.GetSP());
635 if (value_sp && type_impl_sp) {
636 ExecutionContext exe_ctx(value_sp->GetExecutionContextRef());
637 new_value_sp = ValueObject::CreateValueObjectFromData(
638 name, **data, exe_ctx, type_impl_sp->GetCompilerType(true));
639 new_value_sp->SetAddressTypeOfChildren(eAddressTypeLoad);
640 }
641 sb_value.SetSP(new_value_sp);
642 return sb_value;
643 }
644
GetChildAtIndex(uint32_t idx)645 SBValue SBValue::GetChildAtIndex(uint32_t idx) {
646 LLDB_INSTRUMENT_VA(this, idx);
647
648 const bool can_create_synthetic = false;
649 lldb::DynamicValueType use_dynamic = eNoDynamicValues;
650 TargetSP target_sp;
651 if (m_opaque_sp)
652 target_sp = m_opaque_sp->GetTargetSP();
653
654 if (target_sp)
655 use_dynamic = target_sp->GetPreferDynamicValue();
656
657 return GetChildAtIndex(idx, use_dynamic, can_create_synthetic);
658 }
659
GetChildAtIndex(uint32_t idx,lldb::DynamicValueType use_dynamic,bool can_create_synthetic)660 SBValue SBValue::GetChildAtIndex(uint32_t idx,
661 lldb::DynamicValueType use_dynamic,
662 bool can_create_synthetic) {
663 LLDB_INSTRUMENT_VA(this, idx, use_dynamic, can_create_synthetic);
664
665 lldb::ValueObjectSP child_sp;
666
667 ValueLocker locker;
668 lldb::ValueObjectSP value_sp(GetSP(locker));
669 if (value_sp) {
670 const bool can_create = true;
671 child_sp = value_sp->GetChildAtIndex(idx);
672 if (can_create_synthetic && !child_sp) {
673 child_sp = value_sp->GetSyntheticArrayMember(idx, can_create);
674 }
675 }
676
677 SBValue sb_value;
678 sb_value.SetSP(child_sp, use_dynamic, GetPreferSyntheticValue());
679
680 return sb_value;
681 }
682
GetIndexOfChildWithName(const char * name)683 uint32_t SBValue::GetIndexOfChildWithName(const char *name) {
684 LLDB_INSTRUMENT_VA(this, name);
685
686 uint32_t idx = UINT32_MAX;
687 ValueLocker locker;
688 lldb::ValueObjectSP value_sp(GetSP(locker));
689 if (value_sp) {
690 idx = value_sp->GetIndexOfChildWithName(name);
691 }
692 return idx;
693 }
694
GetChildMemberWithName(const char * name)695 SBValue SBValue::GetChildMemberWithName(const char *name) {
696 LLDB_INSTRUMENT_VA(this, name);
697
698 lldb::DynamicValueType use_dynamic_value = eNoDynamicValues;
699 TargetSP target_sp;
700 if (m_opaque_sp)
701 target_sp = m_opaque_sp->GetTargetSP();
702
703 if (target_sp)
704 use_dynamic_value = target_sp->GetPreferDynamicValue();
705 return GetChildMemberWithName(name, use_dynamic_value);
706 }
707
708 SBValue
GetChildMemberWithName(const char * name,lldb::DynamicValueType use_dynamic_value)709 SBValue::GetChildMemberWithName(const char *name,
710 lldb::DynamicValueType use_dynamic_value) {
711 LLDB_INSTRUMENT_VA(this, name, use_dynamic_value);
712
713 lldb::ValueObjectSP child_sp;
714
715 ValueLocker locker;
716 lldb::ValueObjectSP value_sp(GetSP(locker));
717 if (value_sp) {
718 child_sp = value_sp->GetChildMemberWithName(name);
719 }
720
721 SBValue sb_value;
722 sb_value.SetSP(child_sp, use_dynamic_value, GetPreferSyntheticValue());
723
724 return sb_value;
725 }
726
GetDynamicValue(lldb::DynamicValueType use_dynamic)727 lldb::SBValue SBValue::GetDynamicValue(lldb::DynamicValueType use_dynamic) {
728 LLDB_INSTRUMENT_VA(this, use_dynamic);
729
730 SBValue value_sb;
731 if (IsValid()) {
732 ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(), use_dynamic,
733 m_opaque_sp->GetUseSynthetic()));
734 value_sb.SetSP(proxy_sp);
735 }
736 return value_sb;
737 }
738
GetStaticValue()739 lldb::SBValue SBValue::GetStaticValue() {
740 LLDB_INSTRUMENT_VA(this);
741
742 SBValue value_sb;
743 if (IsValid()) {
744 ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(),
745 eNoDynamicValues,
746 m_opaque_sp->GetUseSynthetic()));
747 value_sb.SetSP(proxy_sp);
748 }
749 return value_sb;
750 }
751
GetNonSyntheticValue()752 lldb::SBValue SBValue::GetNonSyntheticValue() {
753 LLDB_INSTRUMENT_VA(this);
754
755 SBValue value_sb;
756 if (IsValid()) {
757 ValueImplSP proxy_sp(new ValueImpl(m_opaque_sp->GetRootSP(),
758 m_opaque_sp->GetUseDynamic(), false));
759 value_sb.SetSP(proxy_sp);
760 }
761 return value_sb;
762 }
763
GetPreferDynamicValue()764 lldb::DynamicValueType SBValue::GetPreferDynamicValue() {
765 LLDB_INSTRUMENT_VA(this);
766
767 if (!IsValid())
768 return eNoDynamicValues;
769 return m_opaque_sp->GetUseDynamic();
770 }
771
SetPreferDynamicValue(lldb::DynamicValueType use_dynamic)772 void SBValue::SetPreferDynamicValue(lldb::DynamicValueType use_dynamic) {
773 LLDB_INSTRUMENT_VA(this, use_dynamic);
774
775 if (IsValid())
776 return m_opaque_sp->SetUseDynamic(use_dynamic);
777 }
778
GetPreferSyntheticValue()779 bool SBValue::GetPreferSyntheticValue() {
780 LLDB_INSTRUMENT_VA(this);
781
782 if (!IsValid())
783 return false;
784 return m_opaque_sp->GetUseSynthetic();
785 }
786
SetPreferSyntheticValue(bool use_synthetic)787 void SBValue::SetPreferSyntheticValue(bool use_synthetic) {
788 LLDB_INSTRUMENT_VA(this, use_synthetic);
789
790 if (IsValid())
791 return m_opaque_sp->SetUseSynthetic(use_synthetic);
792 }
793
IsDynamic()794 bool SBValue::IsDynamic() {
795 LLDB_INSTRUMENT_VA(this);
796
797 ValueLocker locker;
798 lldb::ValueObjectSP value_sp(GetSP(locker));
799 if (value_sp)
800 return value_sp->IsDynamic();
801 return false;
802 }
803
IsSynthetic()804 bool SBValue::IsSynthetic() {
805 LLDB_INSTRUMENT_VA(this);
806
807 ValueLocker locker;
808 lldb::ValueObjectSP value_sp(GetSP(locker));
809 if (value_sp)
810 return value_sp->IsSynthetic();
811 return false;
812 }
813
IsSyntheticChildrenGenerated()814 bool SBValue::IsSyntheticChildrenGenerated() {
815 LLDB_INSTRUMENT_VA(this);
816
817 ValueLocker locker;
818 lldb::ValueObjectSP value_sp(GetSP(locker));
819 if (value_sp)
820 return value_sp->IsSyntheticChildrenGenerated();
821 return false;
822 }
823
SetSyntheticChildrenGenerated(bool is)824 void SBValue::SetSyntheticChildrenGenerated(bool is) {
825 LLDB_INSTRUMENT_VA(this, is);
826
827 ValueLocker locker;
828 lldb::ValueObjectSP value_sp(GetSP(locker));
829 if (value_sp)
830 return value_sp->SetSyntheticChildrenGenerated(is);
831 }
832
GetValueForExpressionPath(const char * expr_path)833 lldb::SBValue SBValue::GetValueForExpressionPath(const char *expr_path) {
834 LLDB_INSTRUMENT_VA(this, expr_path);
835
836 lldb::ValueObjectSP child_sp;
837 ValueLocker locker;
838 lldb::ValueObjectSP value_sp(GetSP(locker));
839 if (value_sp) {
840 // using default values for all the fancy options, just do it if you can
841 child_sp = value_sp->GetValueForExpressionPath(expr_path);
842 }
843
844 SBValue sb_value;
845 sb_value.SetSP(child_sp, GetPreferDynamicValue(), GetPreferSyntheticValue());
846
847 return sb_value;
848 }
849
GetValueAsSigned(SBError & error,int64_t fail_value)850 int64_t SBValue::GetValueAsSigned(SBError &error, int64_t fail_value) {
851 LLDB_INSTRUMENT_VA(this, error, fail_value);
852
853 error.Clear();
854 ValueLocker locker;
855 lldb::ValueObjectSP value_sp(GetSP(locker));
856 if (value_sp) {
857 bool success = true;
858 uint64_t ret_val = fail_value;
859 ret_val = value_sp->GetValueAsSigned(fail_value, &success);
860 if (!success)
861 error.SetErrorString("could not resolve value");
862 return ret_val;
863 } else
864 error.SetErrorStringWithFormat("could not get SBValue: %s",
865 locker.GetError().AsCString());
866
867 return fail_value;
868 }
869
GetValueAsUnsigned(SBError & error,uint64_t fail_value)870 uint64_t SBValue::GetValueAsUnsigned(SBError &error, uint64_t fail_value) {
871 LLDB_INSTRUMENT_VA(this, error, fail_value);
872
873 error.Clear();
874 ValueLocker locker;
875 lldb::ValueObjectSP value_sp(GetSP(locker));
876 if (value_sp) {
877 bool success = true;
878 uint64_t ret_val = fail_value;
879 ret_val = value_sp->GetValueAsUnsigned(fail_value, &success);
880 if (!success)
881 error.SetErrorString("could not resolve value");
882 return ret_val;
883 } else
884 error.SetErrorStringWithFormat("could not get SBValue: %s",
885 locker.GetError().AsCString());
886
887 return fail_value;
888 }
889
GetValueAsSigned(int64_t fail_value)890 int64_t SBValue::GetValueAsSigned(int64_t fail_value) {
891 LLDB_INSTRUMENT_VA(this, fail_value);
892
893 ValueLocker locker;
894 lldb::ValueObjectSP value_sp(GetSP(locker));
895 if (value_sp) {
896 return value_sp->GetValueAsSigned(fail_value);
897 }
898 return fail_value;
899 }
900
GetValueAsUnsigned(uint64_t fail_value)901 uint64_t SBValue::GetValueAsUnsigned(uint64_t fail_value) {
902 LLDB_INSTRUMENT_VA(this, fail_value);
903
904 ValueLocker locker;
905 lldb::ValueObjectSP value_sp(GetSP(locker));
906 if (value_sp) {
907 return value_sp->GetValueAsUnsigned(fail_value);
908 }
909 return fail_value;
910 }
911
MightHaveChildren()912 bool SBValue::MightHaveChildren() {
913 LLDB_INSTRUMENT_VA(this);
914
915 bool has_children = false;
916 ValueLocker locker;
917 lldb::ValueObjectSP value_sp(GetSP(locker));
918 if (value_sp)
919 has_children = value_sp->MightHaveChildren();
920
921 return has_children;
922 }
923
IsRuntimeSupportValue()924 bool SBValue::IsRuntimeSupportValue() {
925 LLDB_INSTRUMENT_VA(this);
926
927 bool is_support = false;
928 ValueLocker locker;
929 lldb::ValueObjectSP value_sp(GetSP(locker));
930 if (value_sp)
931 is_support = value_sp->IsRuntimeSupportValue();
932
933 return is_support;
934 }
935
GetNumChildren()936 uint32_t SBValue::GetNumChildren() {
937 LLDB_INSTRUMENT_VA(this);
938
939 return GetNumChildren(UINT32_MAX);
940 }
941
GetNumChildren(uint32_t max)942 uint32_t SBValue::GetNumChildren(uint32_t max) {
943 LLDB_INSTRUMENT_VA(this, max);
944
945 uint32_t num_children = 0;
946
947 ValueLocker locker;
948 lldb::ValueObjectSP value_sp(GetSP(locker));
949 if (value_sp)
950 num_children = value_sp->GetNumChildren(max);
951
952 return num_children;
953 }
954
Dereference()955 SBValue SBValue::Dereference() {
956 LLDB_INSTRUMENT_VA(this);
957
958 SBValue sb_value;
959 ValueLocker locker;
960 lldb::ValueObjectSP value_sp(GetSP(locker));
961 if (value_sp) {
962 Status error;
963 sb_value = value_sp->Dereference(error);
964 }
965
966 return sb_value;
967 }
968
969 // Deprecated - please use GetType().IsPointerType() instead.
TypeIsPointerType()970 bool SBValue::TypeIsPointerType() {
971 LLDB_INSTRUMENT_VA(this);
972
973 return GetType().IsPointerType();
974 }
975
GetOpaqueType()976 void *SBValue::GetOpaqueType() {
977 LLDB_INSTRUMENT_VA(this);
978
979 ValueLocker locker;
980 lldb::ValueObjectSP value_sp(GetSP(locker));
981 if (value_sp)
982 return value_sp->GetCompilerType().GetOpaqueQualType();
983 return nullptr;
984 }
985
GetTarget()986 lldb::SBTarget SBValue::GetTarget() {
987 LLDB_INSTRUMENT_VA(this);
988
989 SBTarget sb_target;
990 TargetSP target_sp;
991 if (m_opaque_sp) {
992 target_sp = m_opaque_sp->GetTargetSP();
993 sb_target.SetSP(target_sp);
994 }
995
996 return sb_target;
997 }
998
GetProcess()999 lldb::SBProcess SBValue::GetProcess() {
1000 LLDB_INSTRUMENT_VA(this);
1001
1002 SBProcess sb_process;
1003 ProcessSP process_sp;
1004 if (m_opaque_sp) {
1005 process_sp = m_opaque_sp->GetProcessSP();
1006 sb_process.SetSP(process_sp);
1007 }
1008
1009 return sb_process;
1010 }
1011
GetThread()1012 lldb::SBThread SBValue::GetThread() {
1013 LLDB_INSTRUMENT_VA(this);
1014
1015 SBThread sb_thread;
1016 ThreadSP thread_sp;
1017 if (m_opaque_sp) {
1018 thread_sp = m_opaque_sp->GetThreadSP();
1019 sb_thread.SetThread(thread_sp);
1020 }
1021
1022 return sb_thread;
1023 }
1024
GetFrame()1025 lldb::SBFrame SBValue::GetFrame() {
1026 LLDB_INSTRUMENT_VA(this);
1027
1028 SBFrame sb_frame;
1029 StackFrameSP frame_sp;
1030 if (m_opaque_sp) {
1031 frame_sp = m_opaque_sp->GetFrameSP();
1032 sb_frame.SetFrameSP(frame_sp);
1033 }
1034
1035 return sb_frame;
1036 }
1037
GetSP(ValueLocker & locker) const1038 lldb::ValueObjectSP SBValue::GetSP(ValueLocker &locker) const {
1039 // IsValid means that the SBValue has a value in it. But that's not the
1040 // only time that ValueObjects are useful. We also want to return the value
1041 // if there's an error state in it.
1042 if (!m_opaque_sp || (!m_opaque_sp->IsValid()
1043 && (m_opaque_sp->GetRootSP()
1044 && !m_opaque_sp->GetRootSP()->GetError().Fail()))) {
1045 locker.GetError().SetErrorString("No value");
1046 return ValueObjectSP();
1047 }
1048 return locker.GetLockedSP(*m_opaque_sp.get());
1049 }
1050
GetSP() const1051 lldb::ValueObjectSP SBValue::GetSP() const {
1052 LLDB_INSTRUMENT_VA(this);
1053
1054 ValueLocker locker;
1055 return GetSP(locker);
1056 }
1057
SetSP(ValueImplSP impl_sp)1058 void SBValue::SetSP(ValueImplSP impl_sp) { m_opaque_sp = impl_sp; }
1059
SetSP(const lldb::ValueObjectSP & sp)1060 void SBValue::SetSP(const lldb::ValueObjectSP &sp) {
1061 if (sp) {
1062 lldb::TargetSP target_sp(sp->GetTargetSP());
1063 if (target_sp) {
1064 lldb::DynamicValueType use_dynamic = target_sp->GetPreferDynamicValue();
1065 bool use_synthetic =
1066 target_sp->TargetProperties::GetEnableSyntheticValue();
1067 m_opaque_sp = ValueImplSP(new ValueImpl(sp, use_dynamic, use_synthetic));
1068 } else
1069 m_opaque_sp = ValueImplSP(new ValueImpl(sp, eNoDynamicValues, true));
1070 } else
1071 m_opaque_sp = ValueImplSP(new ValueImpl(sp, eNoDynamicValues, false));
1072 }
1073
SetSP(const lldb::ValueObjectSP & sp,lldb::DynamicValueType use_dynamic)1074 void SBValue::SetSP(const lldb::ValueObjectSP &sp,
1075 lldb::DynamicValueType use_dynamic) {
1076 if (sp) {
1077 lldb::TargetSP target_sp(sp->GetTargetSP());
1078 if (target_sp) {
1079 bool use_synthetic =
1080 target_sp->TargetProperties::GetEnableSyntheticValue();
1081 SetSP(sp, use_dynamic, use_synthetic);
1082 } else
1083 SetSP(sp, use_dynamic, true);
1084 } else
1085 SetSP(sp, use_dynamic, false);
1086 }
1087
SetSP(const lldb::ValueObjectSP & sp,bool use_synthetic)1088 void SBValue::SetSP(const lldb::ValueObjectSP &sp, bool use_synthetic) {
1089 if (sp) {
1090 lldb::TargetSP target_sp(sp->GetTargetSP());
1091 if (target_sp) {
1092 lldb::DynamicValueType use_dynamic = target_sp->GetPreferDynamicValue();
1093 SetSP(sp, use_dynamic, use_synthetic);
1094 } else
1095 SetSP(sp, eNoDynamicValues, use_synthetic);
1096 } else
1097 SetSP(sp, eNoDynamicValues, use_synthetic);
1098 }
1099
SetSP(const lldb::ValueObjectSP & sp,lldb::DynamicValueType use_dynamic,bool use_synthetic)1100 void SBValue::SetSP(const lldb::ValueObjectSP &sp,
1101 lldb::DynamicValueType use_dynamic, bool use_synthetic) {
1102 m_opaque_sp = ValueImplSP(new ValueImpl(sp, use_dynamic, use_synthetic));
1103 }
1104
SetSP(const lldb::ValueObjectSP & sp,lldb::DynamicValueType use_dynamic,bool use_synthetic,const char * name)1105 void SBValue::SetSP(const lldb::ValueObjectSP &sp,
1106 lldb::DynamicValueType use_dynamic, bool use_synthetic,
1107 const char *name) {
1108 m_opaque_sp =
1109 ValueImplSP(new ValueImpl(sp, use_dynamic, use_synthetic, name));
1110 }
1111
GetExpressionPath(SBStream & description)1112 bool SBValue::GetExpressionPath(SBStream &description) {
1113 LLDB_INSTRUMENT_VA(this, description);
1114
1115 ValueLocker locker;
1116 lldb::ValueObjectSP value_sp(GetSP(locker));
1117 if (value_sp) {
1118 value_sp->GetExpressionPath(description.ref());
1119 return true;
1120 }
1121 return false;
1122 }
1123
GetExpressionPath(SBStream & description,bool qualify_cxx_base_classes)1124 bool SBValue::GetExpressionPath(SBStream &description,
1125 bool qualify_cxx_base_classes) {
1126 LLDB_INSTRUMENT_VA(this, description, qualify_cxx_base_classes);
1127
1128 ValueLocker locker;
1129 lldb::ValueObjectSP value_sp(GetSP(locker));
1130 if (value_sp) {
1131 value_sp->GetExpressionPath(description.ref());
1132 return true;
1133 }
1134 return false;
1135 }
1136
EvaluateExpression(const char * expr) const1137 lldb::SBValue SBValue::EvaluateExpression(const char *expr) const {
1138 LLDB_INSTRUMENT_VA(this, expr);
1139
1140 ValueLocker locker;
1141 lldb::ValueObjectSP value_sp(GetSP(locker));
1142 if (!value_sp)
1143 return SBValue();
1144
1145 lldb::TargetSP target_sp = value_sp->GetTargetSP();
1146 if (!target_sp)
1147 return SBValue();
1148
1149 lldb::SBExpressionOptions options;
1150 options.SetFetchDynamicValue(target_sp->GetPreferDynamicValue());
1151 options.SetUnwindOnError(true);
1152 options.SetIgnoreBreakpoints(true);
1153
1154 return EvaluateExpression(expr, options, nullptr);
1155 }
1156
1157 lldb::SBValue
EvaluateExpression(const char * expr,const SBExpressionOptions & options) const1158 SBValue::EvaluateExpression(const char *expr,
1159 const SBExpressionOptions &options) const {
1160 LLDB_INSTRUMENT_VA(this, expr, options);
1161
1162 return EvaluateExpression(expr, options, nullptr);
1163 }
1164
EvaluateExpression(const char * expr,const SBExpressionOptions & options,const char * name) const1165 lldb::SBValue SBValue::EvaluateExpression(const char *expr,
1166 const SBExpressionOptions &options,
1167 const char *name) const {
1168 LLDB_INSTRUMENT_VA(this, expr, options, name);
1169
1170 if (!expr || expr[0] == '\0') {
1171 return SBValue();
1172 }
1173
1174
1175 ValueLocker locker;
1176 lldb::ValueObjectSP value_sp(GetSP(locker));
1177 if (!value_sp) {
1178 return SBValue();
1179 }
1180
1181 lldb::TargetSP target_sp = value_sp->GetTargetSP();
1182 if (!target_sp) {
1183 return SBValue();
1184 }
1185
1186 std::lock_guard<std::recursive_mutex> guard(target_sp->GetAPIMutex());
1187 ExecutionContext exe_ctx(target_sp.get());
1188
1189 StackFrame *frame = exe_ctx.GetFramePtr();
1190 if (!frame) {
1191 return SBValue();
1192 }
1193
1194 ValueObjectSP res_val_sp;
1195 target_sp->EvaluateExpression(expr, frame, res_val_sp, options.ref(), nullptr,
1196 value_sp.get());
1197
1198 if (name)
1199 res_val_sp->SetName(ConstString(name));
1200
1201 SBValue result;
1202 result.SetSP(res_val_sp, options.GetFetchDynamicValue());
1203 return result;
1204 }
1205
GetDescription(SBStream & description)1206 bool SBValue::GetDescription(SBStream &description) {
1207 LLDB_INSTRUMENT_VA(this, description);
1208
1209 Stream &strm = description.ref();
1210
1211 ValueLocker locker;
1212 lldb::ValueObjectSP value_sp(GetSP(locker));
1213 if (value_sp) {
1214 DumpValueObjectOptions options;
1215 options.SetUseDynamicType(m_opaque_sp->GetUseDynamic());
1216 options.SetUseSyntheticValue(m_opaque_sp->GetUseSynthetic());
1217 value_sp->Dump(strm, options);
1218 } else {
1219 strm.PutCString("No value");
1220 }
1221
1222 return true;
1223 }
1224
GetFormat()1225 lldb::Format SBValue::GetFormat() {
1226 LLDB_INSTRUMENT_VA(this);
1227
1228 ValueLocker locker;
1229 lldb::ValueObjectSP value_sp(GetSP(locker));
1230 if (value_sp)
1231 return value_sp->GetFormat();
1232 return eFormatDefault;
1233 }
1234
SetFormat(lldb::Format format)1235 void SBValue::SetFormat(lldb::Format format) {
1236 LLDB_INSTRUMENT_VA(this, format);
1237
1238 ValueLocker locker;
1239 lldb::ValueObjectSP value_sp(GetSP(locker));
1240 if (value_sp)
1241 value_sp->SetFormat(format);
1242 }
1243
AddressOf()1244 lldb::SBValue SBValue::AddressOf() {
1245 LLDB_INSTRUMENT_VA(this);
1246
1247 SBValue sb_value;
1248 ValueLocker locker;
1249 lldb::ValueObjectSP value_sp(GetSP(locker));
1250 if (value_sp) {
1251 Status error;
1252 sb_value.SetSP(value_sp->AddressOf(error), GetPreferDynamicValue(),
1253 GetPreferSyntheticValue());
1254 }
1255
1256 return sb_value;
1257 }
1258
GetLoadAddress()1259 lldb::addr_t SBValue::GetLoadAddress() {
1260 LLDB_INSTRUMENT_VA(this);
1261
1262 lldb::addr_t value = LLDB_INVALID_ADDRESS;
1263 ValueLocker locker;
1264 lldb::ValueObjectSP value_sp(GetSP(locker));
1265 if (value_sp) {
1266 TargetSP target_sp(value_sp->GetTargetSP());
1267 if (target_sp) {
1268 const bool scalar_is_load_address = true;
1269 AddressType addr_type;
1270 value = value_sp->GetAddressOf(scalar_is_load_address, &addr_type);
1271 if (addr_type == eAddressTypeFile) {
1272 ModuleSP module_sp(value_sp->GetModule());
1273 if (!module_sp)
1274 value = LLDB_INVALID_ADDRESS;
1275 else {
1276 Address addr;
1277 module_sp->ResolveFileAddress(value, addr);
1278 value = addr.GetLoadAddress(target_sp.get());
1279 }
1280 } else if (addr_type == eAddressTypeHost ||
1281 addr_type == eAddressTypeInvalid)
1282 value = LLDB_INVALID_ADDRESS;
1283 }
1284 }
1285
1286 return value;
1287 }
1288
GetAddress()1289 lldb::SBAddress SBValue::GetAddress() {
1290 LLDB_INSTRUMENT_VA(this);
1291
1292 Address addr;
1293 ValueLocker locker;
1294 lldb::ValueObjectSP value_sp(GetSP(locker));
1295 if (value_sp) {
1296 TargetSP target_sp(value_sp->GetTargetSP());
1297 if (target_sp) {
1298 lldb::addr_t value = LLDB_INVALID_ADDRESS;
1299 const bool scalar_is_load_address = true;
1300 AddressType addr_type;
1301 value = value_sp->GetAddressOf(scalar_is_load_address, &addr_type);
1302 if (addr_type == eAddressTypeFile) {
1303 ModuleSP module_sp(value_sp->GetModule());
1304 if (module_sp)
1305 module_sp->ResolveFileAddress(value, addr);
1306 } else if (addr_type == eAddressTypeLoad) {
1307 // no need to check the return value on this.. if it can actually do
1308 // the resolve addr will be in the form (section,offset), otherwise it
1309 // will simply be returned as (NULL, value)
1310 addr.SetLoadAddress(value, target_sp.get());
1311 }
1312 }
1313 }
1314
1315 return SBAddress(addr);
1316 }
1317
GetPointeeData(uint32_t item_idx,uint32_t item_count)1318 lldb::SBData SBValue::GetPointeeData(uint32_t item_idx, uint32_t item_count) {
1319 LLDB_INSTRUMENT_VA(this, item_idx, item_count);
1320
1321 lldb::SBData sb_data;
1322 ValueLocker locker;
1323 lldb::ValueObjectSP value_sp(GetSP(locker));
1324 if (value_sp) {
1325 TargetSP target_sp(value_sp->GetTargetSP());
1326 if (target_sp) {
1327 DataExtractorSP data_sp(new DataExtractor());
1328 value_sp->GetPointeeData(*data_sp, item_idx, item_count);
1329 if (data_sp->GetByteSize() > 0)
1330 *sb_data = data_sp;
1331 }
1332 }
1333
1334 return sb_data;
1335 }
1336
GetData()1337 lldb::SBData SBValue::GetData() {
1338 LLDB_INSTRUMENT_VA(this);
1339
1340 lldb::SBData sb_data;
1341 ValueLocker locker;
1342 lldb::ValueObjectSP value_sp(GetSP(locker));
1343 if (value_sp) {
1344 DataExtractorSP data_sp(new DataExtractor());
1345 Status error;
1346 value_sp->GetData(*data_sp, error);
1347 if (error.Success())
1348 *sb_data = data_sp;
1349 }
1350
1351 return sb_data;
1352 }
1353
SetData(lldb::SBData & data,SBError & error)1354 bool SBValue::SetData(lldb::SBData &data, SBError &error) {
1355 LLDB_INSTRUMENT_VA(this, data, error);
1356
1357 ValueLocker locker;
1358 lldb::ValueObjectSP value_sp(GetSP(locker));
1359 bool ret = true;
1360
1361 if (value_sp) {
1362 DataExtractor *data_extractor = data.get();
1363
1364 if (!data_extractor) {
1365 error.SetErrorString("No data to set");
1366 ret = false;
1367 } else {
1368 Status set_error;
1369
1370 value_sp->SetData(*data_extractor, set_error);
1371
1372 if (!set_error.Success()) {
1373 error.SetErrorStringWithFormat("Couldn't set data: %s",
1374 set_error.AsCString());
1375 ret = false;
1376 }
1377 }
1378 } else {
1379 error.SetErrorStringWithFormat(
1380 "Couldn't set data: could not get SBValue: %s",
1381 locker.GetError().AsCString());
1382 ret = false;
1383 }
1384
1385 return ret;
1386 }
1387
Clone(const char * new_name)1388 lldb::SBValue SBValue::Clone(const char *new_name) {
1389 LLDB_INSTRUMENT_VA(this, new_name);
1390
1391 ValueLocker locker;
1392 lldb::ValueObjectSP value_sp(GetSP(locker));
1393
1394 if (value_sp)
1395 return lldb::SBValue(value_sp->Clone(ConstString(new_name)));
1396 else
1397 return lldb::SBValue();
1398 }
1399
GetDeclaration()1400 lldb::SBDeclaration SBValue::GetDeclaration() {
1401 LLDB_INSTRUMENT_VA(this);
1402
1403 ValueLocker locker;
1404 lldb::ValueObjectSP value_sp(GetSP(locker));
1405 SBDeclaration decl_sb;
1406 if (value_sp) {
1407 Declaration decl;
1408 if (value_sp->GetDeclaration(decl))
1409 decl_sb.SetDeclaration(decl);
1410 }
1411 return decl_sb;
1412 }
1413
Watch(bool resolve_location,bool read,bool write,SBError & error)1414 lldb::SBWatchpoint SBValue::Watch(bool resolve_location, bool read, bool write,
1415 SBError &error) {
1416 LLDB_INSTRUMENT_VA(this, resolve_location, read, write, error);
1417
1418 SBWatchpoint sb_watchpoint;
1419
1420 // If the SBValue is not valid, there's no point in even trying to watch it.
1421 ValueLocker locker;
1422 lldb::ValueObjectSP value_sp(GetSP(locker));
1423 TargetSP target_sp(GetTarget().GetSP());
1424 if (value_sp && target_sp) {
1425 // Read and Write cannot both be false.
1426 if (!read && !write)
1427 return sb_watchpoint;
1428
1429 // If the value is not in scope, don't try and watch and invalid value
1430 if (!IsInScope())
1431 return sb_watchpoint;
1432
1433 addr_t addr = GetLoadAddress();
1434 if (addr == LLDB_INVALID_ADDRESS)
1435 return sb_watchpoint;
1436 size_t byte_size = GetByteSize();
1437 if (byte_size == 0)
1438 return sb_watchpoint;
1439
1440 uint32_t watch_type = 0;
1441 if (read) {
1442 watch_type |= LLDB_WATCH_TYPE_READ;
1443 // read + write, the most likely intention
1444 // is to catch all writes to this, not just
1445 // value modifications.
1446 if (write)
1447 watch_type |= LLDB_WATCH_TYPE_WRITE;
1448 } else {
1449 if (write)
1450 watch_type |= LLDB_WATCH_TYPE_MODIFY;
1451 }
1452
1453 Status rc;
1454 CompilerType type(value_sp->GetCompilerType());
1455 WatchpointSP watchpoint_sp =
1456 target_sp->CreateWatchpoint(addr, byte_size, &type, watch_type, rc);
1457 error.SetError(rc);
1458
1459 if (watchpoint_sp) {
1460 sb_watchpoint.SetSP(watchpoint_sp);
1461 Declaration decl;
1462 if (value_sp->GetDeclaration(decl)) {
1463 if (decl.GetFile()) {
1464 StreamString ss;
1465 // True to show fullpath for declaration file.
1466 decl.DumpStopContext(&ss, true);
1467 watchpoint_sp->SetDeclInfo(std::string(ss.GetString()));
1468 }
1469 }
1470 }
1471 } else if (target_sp) {
1472 error.SetErrorStringWithFormat("could not get SBValue: %s",
1473 locker.GetError().AsCString());
1474 } else {
1475 error.SetErrorString("could not set watchpoint, a target is required");
1476 }
1477
1478 return sb_watchpoint;
1479 }
1480
1481 // FIXME: Remove this method impl (as well as the decl in .h) once it is no
1482 // longer needed.
1483 // Backward compatibility fix in the interim.
Watch(bool resolve_location,bool read,bool write)1484 lldb::SBWatchpoint SBValue::Watch(bool resolve_location, bool read,
1485 bool write) {
1486 LLDB_INSTRUMENT_VA(this, resolve_location, read, write);
1487
1488 SBError error;
1489 return Watch(resolve_location, read, write, error);
1490 }
1491
WatchPointee(bool resolve_location,bool read,bool write,SBError & error)1492 lldb::SBWatchpoint SBValue::WatchPointee(bool resolve_location, bool read,
1493 bool write, SBError &error) {
1494 LLDB_INSTRUMENT_VA(this, resolve_location, read, write, error);
1495
1496 SBWatchpoint sb_watchpoint;
1497 if (IsInScope() && GetType().IsPointerType())
1498 sb_watchpoint = Dereference().Watch(resolve_location, read, write, error);
1499 return sb_watchpoint;
1500 }
1501
Persist()1502 lldb::SBValue SBValue::Persist() {
1503 LLDB_INSTRUMENT_VA(this);
1504
1505 ValueLocker locker;
1506 lldb::ValueObjectSP value_sp(GetSP(locker));
1507 SBValue persisted_sb;
1508 if (value_sp) {
1509 persisted_sb.SetSP(value_sp->Persist());
1510 }
1511 return persisted_sb;
1512 }
1513
GetVTable()1514 lldb::SBValue SBValue::GetVTable() {
1515 SBValue vtable_sb;
1516 ValueLocker locker;
1517 lldb::ValueObjectSP value_sp(GetSP(locker));
1518 if (!value_sp)
1519 return vtable_sb;
1520
1521 vtable_sb.SetSP(value_sp->GetVTable());
1522 return vtable_sb;
1523 }
1524