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