Coverage Report

Created: 2022-01-25 06:29

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