Coverage Report

Created: 2023-11-11 10:31

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/Core/ValueObjectRegister.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- ValueObjectRegister.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/ValueObjectRegister.h"
10
11
#include "lldb/Core/Module.h"
12
#include "lldb/Core/Value.h"
13
#include "lldb/Symbol/CompilerType.h"
14
#include "lldb/Symbol/TypeSystem.h"
15
#include "lldb/Target/ExecutionContext.h"
16
#include "lldb/Target/Process.h"
17
#include "lldb/Target/RegisterContext.h"
18
#include "lldb/Target/StackFrame.h"
19
#include "lldb/Target/Target.h"
20
#include "lldb/Utility/DataExtractor.h"
21
#include "lldb/Utility/LLDBLog.h"
22
#include "lldb/Utility/Log.h"
23
#include "lldb/Utility/Scalar.h"
24
#include "lldb/Utility/Status.h"
25
#include "lldb/Utility/Stream.h"
26
27
#include "llvm/ADT/StringRef.h"
28
29
#include <cassert>
30
#include <memory>
31
#include <optional>
32
33
namespace lldb_private {
34
class ExecutionContextScope;
35
}
36
37
using namespace lldb;
38
using namespace lldb_private;
39
40
#pragma mark ValueObjectRegisterSet
41
42
ValueObjectSP
43
ValueObjectRegisterSet::Create(ExecutionContextScope *exe_scope,
44
                               lldb::RegisterContextSP &reg_ctx_sp,
45
196
                               uint32_t set_idx) {
46
196
  auto manager_sp = ValueObjectManager::Create();
47
196
  return (new ValueObjectRegisterSet(exe_scope, *manager_sp, reg_ctx_sp,
48
196
                                     set_idx))
49
196
      ->GetSP();
50
196
}
51
52
ValueObjectRegisterSet::ValueObjectRegisterSet(ExecutionContextScope *exe_scope,
53
                                               ValueObjectManager &manager,
54
                                               lldb::RegisterContextSP &reg_ctx,
55
                                               uint32_t reg_set_idx)
56
196
    : ValueObject(exe_scope, manager), m_reg_ctx_sp(reg_ctx),
57
196
      m_reg_set(nullptr), m_reg_set_idx(reg_set_idx) {
58
196
  assert(reg_ctx);
59
196
  m_reg_set = reg_ctx->GetRegisterSet(m_reg_set_idx);
60
196
  if (m_reg_set) {
61
196
    m_name.SetCString(m_reg_set->name);
62
196
  }
63
196
}
64
65
196
ValueObjectRegisterSet::~ValueObjectRegisterSet() = default;
66
67
11.0k
CompilerType ValueObjectRegisterSet::GetCompilerTypeImpl() {
68
11.0k
  return CompilerType();
69
11.0k
}
70
71
0
ConstString ValueObjectRegisterSet::GetTypeName() { return ConstString(); }
72
73
0
ConstString ValueObjectRegisterSet::GetQualifiedTypeName() {
74
0
  return ConstString();
75
0
}
76
77
30
size_t ValueObjectRegisterSet::CalculateNumChildren(uint32_t max) {
78
30
  const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
79
30
  if (reg_set) {
80
30
    auto reg_count = reg_set->num_registers;
81
30
    return reg_count <= max ? reg_count : 
max0
;
82
30
  }
83
0
  return 0;
84
30
}
85
86
0
std::optional<uint64_t> ValueObjectRegisterSet::GetByteSize() { return 0; }
87
88
111
bool ValueObjectRegisterSet::UpdateValue() {
89
111
  m_error.Clear();
90
111
  SetValueDidChange(false);
91
111
  ExecutionContext exe_ctx(GetExecutionContextRef());
92
111
  StackFrame *frame = exe_ctx.GetFramePtr();
93
111
  if (frame == nullptr)
94
0
    m_reg_ctx_sp.reset();
95
111
  else {
96
111
    m_reg_ctx_sp = frame->GetRegisterContext();
97
111
    if (m_reg_ctx_sp) {
98
111
      const RegisterSet *reg_set = m_reg_ctx_sp->GetRegisterSet(m_reg_set_idx);
99
111
      if (reg_set == nullptr)
100
0
        m_reg_ctx_sp.reset();
101
111
      else if (m_reg_set != reg_set) {
102
0
        SetValueDidChange(true);
103
0
        m_name.SetCString(reg_set->name);
104
0
      }
105
111
    }
106
111
  }
107
111
  if (m_reg_ctx_sp) {
108
111
    SetValueIsValid(true);
109
111
  } else {
110
0
    SetValueIsValid(false);
111
0
    m_error.SetErrorToGenericError();
112
0
    m_children.Clear();
113
0
  }
114
111
  return m_error.Success();
115
111
}
116
117
ValueObject *ValueObjectRegisterSet::CreateChildAtIndex(
118
1.06k
    size_t idx, bool synthetic_array_member, int32_t synthetic_index) {
119
1.06k
  ValueObject *valobj = nullptr;
120
1.06k
  if (m_reg_ctx_sp && m_reg_set) {
121
1.06k
    const size_t num_children = GetNumChildren();
122
1.06k
    if (idx < num_children)
123
1.06k
      valobj = new ValueObjectRegister(
124
1.06k
          *this, m_reg_ctx_sp,
125
1.06k
          m_reg_ctx_sp->GetRegisterInfoAtIndex(m_reg_set->registers[idx]));
126
1.06k
  }
127
1.06k
  return valobj;
128
1.06k
}
129
130
lldb::ValueObjectSP
131
ValueObjectRegisterSet::GetChildMemberWithName(llvm::StringRef name,
132
452
                                               bool can_create) {
133
452
  ValueObject *valobj = nullptr;
134
452
  if (m_reg_ctx_sp && m_reg_set) {
135
452
    const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoByName(name);
136
452
    if (reg_info != nullptr)
137
452
      valobj = new ValueObjectRegister(*this, m_reg_ctx_sp, reg_info);
138
452
  }
139
452
  if (valobj)
140
452
    return valobj->GetSP();
141
0
  else
142
0
    return ValueObjectSP();
143
452
}
144
145
0
size_t ValueObjectRegisterSet::GetIndexOfChildWithName(llvm::StringRef name) {
146
0
  if (m_reg_ctx_sp && m_reg_set) {
147
0
    const RegisterInfo *reg_info = m_reg_ctx_sp->GetRegisterInfoByName(name);
148
0
    if (reg_info != nullptr)
149
0
      return reg_info->kinds[eRegisterKindLLDB];
150
0
  }
151
0
  return UINT32_MAX;
152
0
}
153
154
#pragma mark -
155
#pragma mark ValueObjectRegister
156
157
1.57k
void ValueObjectRegister::ConstructObject(const RegisterInfo *reg_info) {
158
1.57k
  if (reg_info) {
159
1.57k
    m_reg_info = *reg_info;
160
1.57k
    if (reg_info->name)
161
1.57k
      m_name.SetCString(reg_info->name);
162
0
    else if (reg_info->alt_name)
163
0
      m_name.SetCString(reg_info->alt_name);
164
1.57k
  }
165
1.57k
}
166
167
ValueObjectRegister::ValueObjectRegister(ValueObject &parent,
168
                                         lldb::RegisterContextSP &reg_ctx_sp,
169
                                         const RegisterInfo *reg_info)
170
1.51k
    : ValueObject(parent), m_reg_ctx_sp(reg_ctx_sp), m_reg_info(),
171
1.51k
      m_reg_value(), m_type_name(), m_compiler_type() {
172
1.51k
  assert(reg_ctx_sp.get());
173
1.51k
  ConstructObject(reg_info);
174
1.51k
}
175
176
ValueObjectSP ValueObjectRegister::Create(ExecutionContextScope *exe_scope,
177
                                          lldb::RegisterContextSP &reg_ctx_sp,
178
61
                                          const RegisterInfo *reg_info) {
179
61
  auto manager_sp = ValueObjectManager::Create();
180
61
  return (new ValueObjectRegister(exe_scope, *manager_sp, reg_ctx_sp, reg_info))
181
61
      ->GetSP();
182
61
}
183
184
ValueObjectRegister::ValueObjectRegister(ExecutionContextScope *exe_scope,
185
                                         ValueObjectManager &manager,
186
                                         lldb::RegisterContextSP &reg_ctx,
187
                                         const RegisterInfo *reg_info)
188
61
    : ValueObject(exe_scope, manager), m_reg_ctx_sp(reg_ctx), m_reg_info(),
189
61
      m_reg_value(), m_type_name(), m_compiler_type() {
190
61
  assert(reg_ctx);
191
61
  ConstructObject(reg_info);
192
61
}
193
194
1.57k
ValueObjectRegister::~ValueObjectRegister() = default;
195
196
48.2k
CompilerType ValueObjectRegister::GetCompilerTypeImpl() {
197
48.2k
  if (!m_compiler_type.IsValid()) {
198
18.2k
    ExecutionContext exe_ctx(GetExecutionContextRef());
199
18.2k
    if (auto *target = exe_ctx.GetTargetPtr()) {
200
18.2k
      if (auto *exe_module = target->GetExecutableModulePointer()) {
201
1.10k
        auto type_system_or_err =
202
1.10k
            exe_module->GetTypeSystemForLanguage(eLanguageTypeC);
203
1.10k
        if (auto err = type_system_or_err.takeError()) {
204
0
          LLDB_LOG_ERROR(GetLog(LLDBLog::Types), std::move(err),
205
0
                         "Unable to get CompilerType from TypeSystem: {0}");
206
1.10k
        } else {
207
1.10k
          if (auto ts = *type_system_or_err)
208
1.10k
            m_compiler_type = ts->GetBuiltinTypeForEncodingAndBitSize(
209
1.10k
                m_reg_info.encoding, m_reg_info.byte_size * 8);
210
1.10k
        }
211
1.10k
      }
212
18.2k
    }
213
18.2k
  }
214
48.2k
  return m_compiler_type;
215
48.2k
}
216
217
520
ConstString ValueObjectRegister::GetTypeName() {
218
520
  if (m_type_name.IsEmpty())
219
280
    m_type_name = GetCompilerType().GetTypeName();
220
520
  return m_type_name;
221
520
}
222
223
0
size_t ValueObjectRegister::CalculateNumChildren(uint32_t max) {
224
0
  ExecutionContext exe_ctx(GetExecutionContextRef());
225
0
  auto children_count = GetCompilerType().GetNumChildren(true, &exe_ctx);
226
0
  return children_count <= max ? children_count : max;
227
0
}
228
229
0
std::optional<uint64_t> ValueObjectRegister::GetByteSize() {
230
0
  return m_reg_info.byte_size;
231
0
}
232
233
1.56k
bool ValueObjectRegister::UpdateValue() {
234
1.56k
  m_error.Clear();
235
1.56k
  ExecutionContext exe_ctx(GetExecutionContextRef());
236
1.56k
  StackFrame *frame = exe_ctx.GetFramePtr();
237
1.56k
  if (frame == nullptr) {
238
0
    m_reg_ctx_sp.reset();
239
0
    m_reg_value.Clear();
240
0
  }
241
242
1.56k
  if (m_reg_ctx_sp) {
243
1.56k
    RegisterValue m_old_reg_value(m_reg_value);
244
1.56k
    if (m_reg_ctx_sp->ReadRegister(&m_reg_info, m_reg_value)) {
245
1.56k
      if (m_reg_value.GetData(m_data)) {
246
1.56k
        Process *process = exe_ctx.GetProcessPtr();
247
1.56k
        if (process)
248
1.56k
          m_data.SetAddressByteSize(process->GetAddressByteSize());
249
1.56k
        m_value.SetContext(Value::ContextType::RegisterInfo,
250
1.56k
                           (void *)&m_reg_info);
251
1.56k
        m_value.SetValueType(Value::ValueType::HostAddress);
252
1.56k
        m_value.GetScalar() = (uintptr_t)m_data.GetDataStart();
253
1.56k
        SetValueIsValid(true);
254
1.56k
        SetValueDidChange(!(m_old_reg_value == m_reg_value));
255
1.56k
        return true;
256
1.56k
      }
257
1.56k
    }
258
1.56k
  }
259
260
1
  SetValueIsValid(false);
261
1
  m_error.SetErrorToGenericError();
262
1
  return false;
263
1.56k
}
264
265
bool ValueObjectRegister::SetValueFromCString(const char *value_str,
266
21
                                              Status &error) {
267
  // The new value will be in the m_data.  Copy that into our register value.
268
21
  error =
269
21
      m_reg_value.SetValueFromString(&m_reg_info, llvm::StringRef(value_str));
270
21
  if (!error.Success())
271
0
    return false;
272
273
21
  if (!m_reg_ctx_sp->WriteRegister(&m_reg_info, m_reg_value)) {
274
1
    error.SetErrorString("unable to write back to register");
275
1
    return false;
276
1
  }
277
278
20
  SetNeedsUpdate();
279
20
  return true;
280
21
}
281
282
1
bool ValueObjectRegister::SetData(DataExtractor &data, Status &error) {
283
1
  error = m_reg_value.SetValueFromData(m_reg_info, data, 0, false);
284
1
  if (!error.Success())
285
0
    return false;
286
287
1
  if (!m_reg_ctx_sp->WriteRegister(&m_reg_info, m_reg_value)) {
288
0
    error.SetErrorString("unable to write back to register");
289
0
    return false;
290
0
  }
291
292
1
  SetNeedsUpdate();
293
1
  return true;
294
1
}
295
296
374
bool ValueObjectRegister::ResolveValue(Scalar &scalar) {
297
374
  if (UpdateValueIfNeeded(
298
374
          false)) // make sure that you are up to date before returning anything
299
374
    return m_reg_value.GetScalarValue(scalar);
300
0
  return false;
301
374
}
302
303
void ValueObjectRegister::GetExpressionPath(Stream &s,
304
0
                                            GetExpressionPathFormat epformat) {
305
0
  s.Printf("$%s", m_reg_info.name);
306
0
}