xref: /freebsd-src/contrib/llvm-project/lldb/source/Commands/CommandObjectMemory.cpp (revision 81ad626541db97eb356e2c1d4a20eb2a26a766ab)
1 //===-- CommandObjectMemory.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 "CommandObjectMemory.h"
10 #include "CommandObjectMemoryTag.h"
11 #include "lldb/Core/DumpDataExtractor.h"
12 #include "lldb/Core/Section.h"
13 #include "lldb/Core/ValueObjectMemory.h"
14 #include "lldb/Expression/ExpressionVariable.h"
15 #include "lldb/Host/OptionParser.h"
16 #include "lldb/Interpreter/CommandReturnObject.h"
17 #include "lldb/Interpreter/OptionArgParser.h"
18 #include "lldb/Interpreter/OptionGroupFormat.h"
19 #include "lldb/Interpreter/OptionGroupMemoryTag.h"
20 #include "lldb/Interpreter/OptionGroupOutputFile.h"
21 #include "lldb/Interpreter/OptionGroupValueObjectDisplay.h"
22 #include "lldb/Interpreter/OptionValueLanguage.h"
23 #include "lldb/Interpreter/OptionValueString.h"
24 #include "lldb/Interpreter/Options.h"
25 #include "lldb/Symbol/SymbolFile.h"
26 #include "lldb/Symbol/TypeList.h"
27 #include "lldb/Target/ABI.h"
28 #include "lldb/Target/Language.h"
29 #include "lldb/Target/MemoryHistory.h"
30 #include "lldb/Target/MemoryRegionInfo.h"
31 #include "lldb/Target/Process.h"
32 #include "lldb/Target/StackFrame.h"
33 #include "lldb/Target/Target.h"
34 #include "lldb/Target/Thread.h"
35 #include "lldb/Utility/Args.h"
36 #include "lldb/Utility/DataBufferHeap.h"
37 #include "lldb/Utility/StreamString.h"
38 #include "llvm/Support/MathExtras.h"
39 #include <cinttypes>
40 #include <memory>
41 
42 using namespace lldb;
43 using namespace lldb_private;
44 
45 #define LLDB_OPTIONS_memory_read
46 #include "CommandOptions.inc"
47 
48 class OptionGroupReadMemory : public OptionGroup {
49 public:
50   OptionGroupReadMemory()
51       : m_num_per_line(1, 1), m_offset(0, 0),
52         m_language_for_type(eLanguageTypeUnknown) {}
53 
54   ~OptionGroupReadMemory() override = default;
55 
56   llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
57     return llvm::makeArrayRef(g_memory_read_options);
58   }
59 
60   Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
61                         ExecutionContext *execution_context) override {
62     Status error;
63     const int short_option = g_memory_read_options[option_idx].short_option;
64 
65     switch (short_option) {
66     case 'l':
67       error = m_num_per_line.SetValueFromString(option_value);
68       if (m_num_per_line.GetCurrentValue() == 0)
69         error.SetErrorStringWithFormat(
70             "invalid value for --num-per-line option '%s'",
71             option_value.str().c_str());
72       break;
73 
74     case 'b':
75       m_output_as_binary = true;
76       break;
77 
78     case 't':
79       error = m_view_as_type.SetValueFromString(option_value);
80       break;
81 
82     case 'r':
83       m_force = true;
84       break;
85 
86     case 'x':
87       error = m_language_for_type.SetValueFromString(option_value);
88       break;
89 
90     case 'E':
91       error = m_offset.SetValueFromString(option_value);
92       break;
93 
94     default:
95       llvm_unreachable("Unimplemented option");
96     }
97     return error;
98   }
99 
100   void OptionParsingStarting(ExecutionContext *execution_context) override {
101     m_num_per_line.Clear();
102     m_output_as_binary = false;
103     m_view_as_type.Clear();
104     m_force = false;
105     m_offset.Clear();
106     m_language_for_type.Clear();
107   }
108 
109   Status FinalizeSettings(Target *target, OptionGroupFormat &format_options) {
110     Status error;
111     OptionValueUInt64 &byte_size_value = format_options.GetByteSizeValue();
112     OptionValueUInt64 &count_value = format_options.GetCountValue();
113     const bool byte_size_option_set = byte_size_value.OptionWasSet();
114     const bool num_per_line_option_set = m_num_per_line.OptionWasSet();
115     const bool count_option_set = format_options.GetCountValue().OptionWasSet();
116 
117     switch (format_options.GetFormat()) {
118     default:
119       break;
120 
121     case eFormatBoolean:
122       if (!byte_size_option_set)
123         byte_size_value = 1;
124       if (!num_per_line_option_set)
125         m_num_per_line = 1;
126       if (!count_option_set)
127         format_options.GetCountValue() = 8;
128       break;
129 
130     case eFormatCString:
131       break;
132 
133     case eFormatInstruction:
134       if (count_option_set)
135         byte_size_value = target->GetArchitecture().GetMaximumOpcodeByteSize();
136       m_num_per_line = 1;
137       break;
138 
139     case eFormatAddressInfo:
140       if (!byte_size_option_set)
141         byte_size_value = target->GetArchitecture().GetAddressByteSize();
142       m_num_per_line = 1;
143       if (!count_option_set)
144         format_options.GetCountValue() = 8;
145       break;
146 
147     case eFormatPointer:
148       byte_size_value = target->GetArchitecture().GetAddressByteSize();
149       if (!num_per_line_option_set)
150         m_num_per_line = 4;
151       if (!count_option_set)
152         format_options.GetCountValue() = 8;
153       break;
154 
155     case eFormatBinary:
156     case eFormatFloat:
157     case eFormatOctal:
158     case eFormatDecimal:
159     case eFormatEnum:
160     case eFormatUnicode8:
161     case eFormatUnicode16:
162     case eFormatUnicode32:
163     case eFormatUnsigned:
164     case eFormatHexFloat:
165       if (!byte_size_option_set)
166         byte_size_value = 4;
167       if (!num_per_line_option_set)
168         m_num_per_line = 1;
169       if (!count_option_set)
170         format_options.GetCountValue() = 8;
171       break;
172 
173     case eFormatBytes:
174     case eFormatBytesWithASCII:
175       if (byte_size_option_set) {
176         if (byte_size_value > 1)
177           error.SetErrorStringWithFormat(
178               "display format (bytes/bytes with ASCII) conflicts with the "
179               "specified byte size %" PRIu64 "\n"
180               "\tconsider using a different display format or don't specify "
181               "the byte size.",
182               byte_size_value.GetCurrentValue());
183       } else
184         byte_size_value = 1;
185       if (!num_per_line_option_set)
186         m_num_per_line = 16;
187       if (!count_option_set)
188         format_options.GetCountValue() = 32;
189       break;
190 
191     case eFormatCharArray:
192     case eFormatChar:
193     case eFormatCharPrintable:
194       if (!byte_size_option_set)
195         byte_size_value = 1;
196       if (!num_per_line_option_set)
197         m_num_per_line = 32;
198       if (!count_option_set)
199         format_options.GetCountValue() = 64;
200       break;
201 
202     case eFormatComplex:
203       if (!byte_size_option_set)
204         byte_size_value = 8;
205       if (!num_per_line_option_set)
206         m_num_per_line = 1;
207       if (!count_option_set)
208         format_options.GetCountValue() = 8;
209       break;
210 
211     case eFormatComplexInteger:
212       if (!byte_size_option_set)
213         byte_size_value = 8;
214       if (!num_per_line_option_set)
215         m_num_per_line = 1;
216       if (!count_option_set)
217         format_options.GetCountValue() = 8;
218       break;
219 
220     case eFormatHex:
221       if (!byte_size_option_set)
222         byte_size_value = 4;
223       if (!num_per_line_option_set) {
224         switch (byte_size_value) {
225         case 1:
226         case 2:
227           m_num_per_line = 8;
228           break;
229         case 4:
230           m_num_per_line = 4;
231           break;
232         case 8:
233           m_num_per_line = 2;
234           break;
235         default:
236           m_num_per_line = 1;
237           break;
238         }
239       }
240       if (!count_option_set)
241         count_value = 8;
242       break;
243 
244     case eFormatVectorOfChar:
245     case eFormatVectorOfSInt8:
246     case eFormatVectorOfUInt8:
247     case eFormatVectorOfSInt16:
248     case eFormatVectorOfUInt16:
249     case eFormatVectorOfSInt32:
250     case eFormatVectorOfUInt32:
251     case eFormatVectorOfSInt64:
252     case eFormatVectorOfUInt64:
253     case eFormatVectorOfFloat16:
254     case eFormatVectorOfFloat32:
255     case eFormatVectorOfFloat64:
256     case eFormatVectorOfUInt128:
257       if (!byte_size_option_set)
258         byte_size_value = 128;
259       if (!num_per_line_option_set)
260         m_num_per_line = 1;
261       if (!count_option_set)
262         count_value = 4;
263       break;
264     }
265     return error;
266   }
267 
268   bool AnyOptionWasSet() const {
269     return m_num_per_line.OptionWasSet() || m_output_as_binary ||
270            m_view_as_type.OptionWasSet() || m_offset.OptionWasSet() ||
271            m_language_for_type.OptionWasSet();
272   }
273 
274   OptionValueUInt64 m_num_per_line;
275   bool m_output_as_binary = false;
276   OptionValueString m_view_as_type;
277   bool m_force;
278   OptionValueUInt64 m_offset;
279   OptionValueLanguage m_language_for_type;
280 };
281 
282 // Read memory from the inferior process
283 class CommandObjectMemoryRead : public CommandObjectParsed {
284 public:
285   CommandObjectMemoryRead(CommandInterpreter &interpreter)
286       : CommandObjectParsed(
287             interpreter, "memory read",
288             "Read from the memory of the current target process.", nullptr,
289             eCommandRequiresTarget | eCommandProcessMustBePaused),
290         m_format_options(eFormatBytesWithASCII, 1, 8),
291         m_memory_tag_options(/*note_binary=*/true),
292         m_prev_format_options(eFormatBytesWithASCII, 1, 8) {
293     CommandArgumentEntry arg1;
294     CommandArgumentEntry arg2;
295     CommandArgumentData start_addr_arg;
296     CommandArgumentData end_addr_arg;
297 
298     // Define the first (and only) variant of this arg.
299     start_addr_arg.arg_type = eArgTypeAddressOrExpression;
300     start_addr_arg.arg_repetition = eArgRepeatPlain;
301 
302     // There is only one variant this argument could be; put it into the
303     // argument entry.
304     arg1.push_back(start_addr_arg);
305 
306     // Define the first (and only) variant of this arg.
307     end_addr_arg.arg_type = eArgTypeAddressOrExpression;
308     end_addr_arg.arg_repetition = eArgRepeatOptional;
309 
310     // There is only one variant this argument could be; put it into the
311     // argument entry.
312     arg2.push_back(end_addr_arg);
313 
314     // Push the data for the first argument into the m_arguments vector.
315     m_arguments.push_back(arg1);
316     m_arguments.push_back(arg2);
317 
318     // Add the "--format" and "--count" options to group 1 and 3
319     m_option_group.Append(&m_format_options,
320                           OptionGroupFormat::OPTION_GROUP_FORMAT |
321                               OptionGroupFormat::OPTION_GROUP_COUNT,
322                           LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3);
323     m_option_group.Append(&m_format_options,
324                           OptionGroupFormat::OPTION_GROUP_GDB_FMT,
325                           LLDB_OPT_SET_1 | LLDB_OPT_SET_3);
326     // Add the "--size" option to group 1 and 2
327     m_option_group.Append(&m_format_options,
328                           OptionGroupFormat::OPTION_GROUP_SIZE,
329                           LLDB_OPT_SET_1 | LLDB_OPT_SET_2);
330     m_option_group.Append(&m_memory_options);
331     m_option_group.Append(&m_outfile_options, LLDB_OPT_SET_ALL,
332                           LLDB_OPT_SET_1 | LLDB_OPT_SET_2 | LLDB_OPT_SET_3);
333     m_option_group.Append(&m_varobj_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_3);
334     m_option_group.Append(&m_memory_tag_options, LLDB_OPT_SET_ALL,
335                           LLDB_OPT_SET_ALL);
336     m_option_group.Finalize();
337   }
338 
339   ~CommandObjectMemoryRead() override = default;
340 
341   Options *GetOptions() override { return &m_option_group; }
342 
343   llvm::Optional<std::string> GetRepeatCommand(Args &current_command_args,
344                                                uint32_t index) override {
345     return m_cmd_name;
346   }
347 
348 protected:
349   bool DoExecute(Args &command, CommandReturnObject &result) override {
350     // No need to check "target" for validity as eCommandRequiresTarget ensures
351     // it is valid
352     Target *target = m_exe_ctx.GetTargetPtr();
353 
354     const size_t argc = command.GetArgumentCount();
355 
356     if ((argc == 0 && m_next_addr == LLDB_INVALID_ADDRESS) || argc > 2) {
357       result.AppendErrorWithFormat("%s takes a start address expression with "
358                                    "an optional end address expression.\n",
359                                    m_cmd_name.c_str());
360       result.AppendWarning("Expressions should be quoted if they contain "
361                            "spaces or other special characters.");
362       return false;
363     }
364 
365     CompilerType compiler_type;
366     Status error;
367 
368     const char *view_as_type_cstr =
369         m_memory_options.m_view_as_type.GetCurrentValue();
370     if (view_as_type_cstr && view_as_type_cstr[0]) {
371       // We are viewing memory as a type
372 
373       const bool exact_match = false;
374       TypeList type_list;
375       uint32_t reference_count = 0;
376       uint32_t pointer_count = 0;
377       size_t idx;
378 
379 #define ALL_KEYWORDS                                                           \
380   KEYWORD("const")                                                             \
381   KEYWORD("volatile")                                                          \
382   KEYWORD("restrict")                                                          \
383   KEYWORD("struct")                                                            \
384   KEYWORD("class")                                                             \
385   KEYWORD("union")
386 
387 #define KEYWORD(s) s,
388       static const char *g_keywords[] = {ALL_KEYWORDS};
389 #undef KEYWORD
390 
391 #define KEYWORD(s) (sizeof(s) - 1),
392       static const int g_keyword_lengths[] = {ALL_KEYWORDS};
393 #undef KEYWORD
394 
395 #undef ALL_KEYWORDS
396 
397       static size_t g_num_keywords = sizeof(g_keywords) / sizeof(const char *);
398       std::string type_str(view_as_type_cstr);
399 
400       // Remove all instances of g_keywords that are followed by spaces
401       for (size_t i = 0; i < g_num_keywords; ++i) {
402         const char *keyword = g_keywords[i];
403         int keyword_len = g_keyword_lengths[i];
404 
405         idx = 0;
406         while ((idx = type_str.find(keyword, idx)) != std::string::npos) {
407           if (type_str[idx + keyword_len] == ' ' ||
408               type_str[idx + keyword_len] == '\t') {
409             type_str.erase(idx, keyword_len + 1);
410             idx = 0;
411           } else {
412             idx += keyword_len;
413           }
414         }
415       }
416       bool done = type_str.empty();
417       //
418       idx = type_str.find_first_not_of(" \t");
419       if (idx > 0 && idx != std::string::npos)
420         type_str.erase(0, idx);
421       while (!done) {
422         // Strip trailing spaces
423         if (type_str.empty())
424           done = true;
425         else {
426           switch (type_str[type_str.size() - 1]) {
427           case '*':
428             ++pointer_count;
429             LLVM_FALLTHROUGH;
430           case ' ':
431           case '\t':
432             type_str.erase(type_str.size() - 1);
433             break;
434 
435           case '&':
436             if (reference_count == 0) {
437               reference_count = 1;
438               type_str.erase(type_str.size() - 1);
439             } else {
440               result.AppendErrorWithFormat("invalid type string: '%s'\n",
441                                            view_as_type_cstr);
442               return false;
443             }
444             break;
445 
446           default:
447             done = true;
448             break;
449           }
450         }
451       }
452 
453       llvm::DenseSet<lldb_private::SymbolFile *> searched_symbol_files;
454       ConstString lookup_type_name(type_str.c_str());
455       StackFrame *frame = m_exe_ctx.GetFramePtr();
456       ModuleSP search_first;
457       if (frame) {
458         search_first = frame->GetSymbolContext(eSymbolContextModule).module_sp;
459       }
460       target->GetImages().FindTypes(search_first.get(), lookup_type_name,
461                                     exact_match, 1, searched_symbol_files,
462                                     type_list);
463 
464       if (type_list.GetSize() == 0 && lookup_type_name.GetCString()) {
465         LanguageType language_for_type =
466             m_memory_options.m_language_for_type.GetCurrentValue();
467         std::set<LanguageType> languages_to_check;
468         if (language_for_type != eLanguageTypeUnknown) {
469           languages_to_check.insert(language_for_type);
470         } else {
471           languages_to_check = Language::GetSupportedLanguages();
472         }
473 
474         std::set<CompilerType> user_defined_types;
475         for (auto lang : languages_to_check) {
476           if (auto *persistent_vars =
477                   target->GetPersistentExpressionStateForLanguage(lang)) {
478             if (llvm::Optional<CompilerType> type =
479                     persistent_vars->GetCompilerTypeFromPersistentDecl(
480                         lookup_type_name)) {
481               user_defined_types.emplace(*type);
482             }
483           }
484         }
485 
486         if (user_defined_types.size() > 1) {
487           result.AppendErrorWithFormat(
488               "Mutiple types found matching raw type '%s', please disambiguate "
489               "by specifying the language with -x",
490               lookup_type_name.GetCString());
491           return false;
492         }
493 
494         if (user_defined_types.size() == 1) {
495           compiler_type = *user_defined_types.begin();
496         }
497       }
498 
499       if (!compiler_type.IsValid()) {
500         if (type_list.GetSize() == 0) {
501           result.AppendErrorWithFormat("unable to find any types that match "
502                                        "the raw type '%s' for full type '%s'\n",
503                                        lookup_type_name.GetCString(),
504                                        view_as_type_cstr);
505           return false;
506         } else {
507           TypeSP type_sp(type_list.GetTypeAtIndex(0));
508           compiler_type = type_sp->GetFullCompilerType();
509         }
510       }
511 
512       while (pointer_count > 0) {
513         CompilerType pointer_type = compiler_type.GetPointerType();
514         if (pointer_type.IsValid())
515           compiler_type = pointer_type;
516         else {
517           result.AppendError("unable make a pointer type\n");
518           return false;
519         }
520         --pointer_count;
521       }
522 
523       llvm::Optional<uint64_t> size = compiler_type.GetByteSize(nullptr);
524       if (!size) {
525         result.AppendErrorWithFormat(
526             "unable to get the byte size of the type '%s'\n",
527             view_as_type_cstr);
528         return false;
529       }
530       m_format_options.GetByteSizeValue() = *size;
531 
532       if (!m_format_options.GetCountValue().OptionWasSet())
533         m_format_options.GetCountValue() = 1;
534     } else {
535       error = m_memory_options.FinalizeSettings(target, m_format_options);
536     }
537 
538     // Look for invalid combinations of settings
539     if (error.Fail()) {
540       result.AppendError(error.AsCString());
541       return false;
542     }
543 
544     lldb::addr_t addr;
545     size_t total_byte_size = 0;
546     if (argc == 0) {
547       // Use the last address and byte size and all options as they were if no
548       // options have been set
549       addr = m_next_addr;
550       total_byte_size = m_prev_byte_size;
551       compiler_type = m_prev_compiler_type;
552       if (!m_format_options.AnyOptionWasSet() &&
553           !m_memory_options.AnyOptionWasSet() &&
554           !m_outfile_options.AnyOptionWasSet() &&
555           !m_varobj_options.AnyOptionWasSet() &&
556           !m_memory_tag_options.AnyOptionWasSet()) {
557         m_format_options = m_prev_format_options;
558         m_memory_options = m_prev_memory_options;
559         m_outfile_options = m_prev_outfile_options;
560         m_varobj_options = m_prev_varobj_options;
561         m_memory_tag_options = m_prev_memory_tag_options;
562       }
563     }
564 
565     size_t item_count = m_format_options.GetCountValue().GetCurrentValue();
566 
567     // TODO For non-8-bit byte addressable architectures this needs to be
568     // revisited to fully support all lldb's range of formatting options.
569     // Furthermore code memory reads (for those architectures) will not be
570     // correctly formatted even w/o formatting options.
571     size_t item_byte_size =
572         target->GetArchitecture().GetDataByteSize() > 1
573             ? target->GetArchitecture().GetDataByteSize()
574             : m_format_options.GetByteSizeValue().GetCurrentValue();
575 
576     const size_t num_per_line =
577         m_memory_options.m_num_per_line.GetCurrentValue();
578 
579     if (total_byte_size == 0) {
580       total_byte_size = item_count * item_byte_size;
581       if (total_byte_size == 0)
582         total_byte_size = 32;
583     }
584 
585     if (argc > 0)
586       addr = OptionArgParser::ToAddress(&m_exe_ctx, command[0].ref(),
587                                         LLDB_INVALID_ADDRESS, &error);
588 
589     if (addr == LLDB_INVALID_ADDRESS) {
590       result.AppendError("invalid start address expression.");
591       result.AppendError(error.AsCString());
592       return false;
593     }
594 
595     ABISP abi;
596     if (Process *proc = m_exe_ctx.GetProcessPtr())
597       abi = proc->GetABI();
598 
599     if (abi)
600       addr = abi->FixDataAddress(addr);
601 
602     if (argc == 2) {
603       lldb::addr_t end_addr = OptionArgParser::ToAddress(
604           &m_exe_ctx, command[1].ref(), LLDB_INVALID_ADDRESS, nullptr);
605       if (end_addr != LLDB_INVALID_ADDRESS && abi)
606         end_addr = abi->FixDataAddress(end_addr);
607 
608       if (end_addr == LLDB_INVALID_ADDRESS) {
609         result.AppendError("invalid end address expression.");
610         result.AppendError(error.AsCString());
611         return false;
612       } else if (end_addr <= addr) {
613         result.AppendErrorWithFormat(
614             "end address (0x%" PRIx64
615             ") must be greater than the start address (0x%" PRIx64 ").\n",
616             end_addr, addr);
617         return false;
618       } else if (m_format_options.GetCountValue().OptionWasSet()) {
619         result.AppendErrorWithFormat(
620             "specify either the end address (0x%" PRIx64
621             ") or the count (--count %" PRIu64 "), not both.\n",
622             end_addr, (uint64_t)item_count);
623         return false;
624       }
625 
626       total_byte_size = end_addr - addr;
627       item_count = total_byte_size / item_byte_size;
628     }
629 
630     uint32_t max_unforced_size = target->GetMaximumMemReadSize();
631 
632     if (total_byte_size > max_unforced_size && !m_memory_options.m_force) {
633       result.AppendErrorWithFormat(
634           "Normally, \'memory read\' will not read over %" PRIu32
635           " bytes of data.\n",
636           max_unforced_size);
637       result.AppendErrorWithFormat(
638           "Please use --force to override this restriction just once.\n");
639       result.AppendErrorWithFormat("or set target.max-memory-read-size if you "
640                                    "will often need a larger limit.\n");
641       return false;
642     }
643 
644     WritableDataBufferSP data_sp;
645     size_t bytes_read = 0;
646     if (compiler_type.GetOpaqueQualType()) {
647       // Make sure we don't display our type as ASCII bytes like the default
648       // memory read
649       if (!m_format_options.GetFormatValue().OptionWasSet())
650         m_format_options.GetFormatValue().SetCurrentValue(eFormatDefault);
651 
652       llvm::Optional<uint64_t> size = compiler_type.GetByteSize(nullptr);
653       if (!size) {
654         result.AppendError("can't get size of type");
655         return false;
656       }
657       bytes_read = *size * m_format_options.GetCountValue().GetCurrentValue();
658 
659       if (argc > 0)
660         addr = addr + (*size * m_memory_options.m_offset.GetCurrentValue());
661     } else if (m_format_options.GetFormatValue().GetCurrentValue() !=
662                eFormatCString) {
663       data_sp = std::make_shared<DataBufferHeap>(total_byte_size, '\0');
664       if (data_sp->GetBytes() == nullptr) {
665         result.AppendErrorWithFormat(
666             "can't allocate 0x%" PRIx32
667             " bytes for the memory read buffer, specify a smaller size to read",
668             (uint32_t)total_byte_size);
669         return false;
670       }
671 
672       Address address(addr, nullptr);
673       bytes_read = target->ReadMemory(address, data_sp->GetBytes(),
674                                       data_sp->GetByteSize(), error, true);
675       if (bytes_read == 0) {
676         const char *error_cstr = error.AsCString();
677         if (error_cstr && error_cstr[0]) {
678           result.AppendError(error_cstr);
679         } else {
680           result.AppendErrorWithFormat(
681               "failed to read memory from 0x%" PRIx64 ".\n", addr);
682         }
683         return false;
684       }
685 
686       if (bytes_read < total_byte_size)
687         result.AppendWarningWithFormat(
688             "Not all bytes (%" PRIu64 "/%" PRIu64
689             ") were able to be read from 0x%" PRIx64 ".\n",
690             (uint64_t)bytes_read, (uint64_t)total_byte_size, addr);
691     } else {
692       // we treat c-strings as a special case because they do not have a fixed
693       // size
694       if (m_format_options.GetByteSizeValue().OptionWasSet() &&
695           !m_format_options.HasGDBFormat())
696         item_byte_size = m_format_options.GetByteSizeValue().GetCurrentValue();
697       else
698         item_byte_size = target->GetMaximumSizeOfStringSummary();
699       if (!m_format_options.GetCountValue().OptionWasSet())
700         item_count = 1;
701       data_sp = std::make_shared<DataBufferHeap>(
702           (item_byte_size + 1) * item_count,
703           '\0'); // account for NULLs as necessary
704       if (data_sp->GetBytes() == nullptr) {
705         result.AppendErrorWithFormat(
706             "can't allocate 0x%" PRIx64
707             " bytes for the memory read buffer, specify a smaller size to read",
708             (uint64_t)((item_byte_size + 1) * item_count));
709         return false;
710       }
711       uint8_t *data_ptr = data_sp->GetBytes();
712       auto data_addr = addr;
713       auto count = item_count;
714       item_count = 0;
715       bool break_on_no_NULL = false;
716       while (item_count < count) {
717         std::string buffer;
718         buffer.resize(item_byte_size + 1, 0);
719         Status error;
720         size_t read = target->ReadCStringFromMemory(data_addr, &buffer[0],
721                                                     item_byte_size + 1, error);
722         if (error.Fail()) {
723           result.AppendErrorWithFormat(
724               "failed to read memory from 0x%" PRIx64 ".\n", addr);
725           return false;
726         }
727 
728         if (item_byte_size == read) {
729           result.AppendWarningWithFormat(
730               "unable to find a NULL terminated string at 0x%" PRIx64
731               ". Consider increasing the maximum read length.\n",
732               data_addr);
733           --read;
734           break_on_no_NULL = true;
735         } else
736           ++read; // account for final NULL byte
737 
738         memcpy(data_ptr, &buffer[0], read);
739         data_ptr += read;
740         data_addr += read;
741         bytes_read += read;
742         item_count++; // if we break early we know we only read item_count
743                       // strings
744 
745         if (break_on_no_NULL)
746           break;
747       }
748       data_sp =
749           std::make_shared<DataBufferHeap>(data_sp->GetBytes(), bytes_read + 1);
750     }
751 
752     m_next_addr = addr + bytes_read;
753     m_prev_byte_size = bytes_read;
754     m_prev_format_options = m_format_options;
755     m_prev_memory_options = m_memory_options;
756     m_prev_outfile_options = m_outfile_options;
757     m_prev_varobj_options = m_varobj_options;
758     m_prev_memory_tag_options = m_memory_tag_options;
759     m_prev_compiler_type = compiler_type;
760 
761     std::unique_ptr<Stream> output_stream_storage;
762     Stream *output_stream_p = nullptr;
763     const FileSpec &outfile_spec =
764         m_outfile_options.GetFile().GetCurrentValue();
765 
766     std::string path = outfile_spec.GetPath();
767     if (outfile_spec) {
768 
769       File::OpenOptions open_options =
770           File::eOpenOptionWriteOnly | File::eOpenOptionCanCreate;
771       const bool append = m_outfile_options.GetAppend().GetCurrentValue();
772       open_options |=
773           append ? File::eOpenOptionAppend : File::eOpenOptionTruncate;
774 
775       auto outfile = FileSystem::Instance().Open(outfile_spec, open_options);
776 
777       if (outfile) {
778         auto outfile_stream_up =
779             std::make_unique<StreamFile>(std::move(outfile.get()));
780         if (m_memory_options.m_output_as_binary) {
781           const size_t bytes_written =
782               outfile_stream_up->Write(data_sp->GetBytes(), bytes_read);
783           if (bytes_written > 0) {
784             result.GetOutputStream().Printf(
785                 "%zi bytes %s to '%s'\n", bytes_written,
786                 append ? "appended" : "written", path.c_str());
787             return true;
788           } else {
789             result.AppendErrorWithFormat("Failed to write %" PRIu64
790                                          " bytes to '%s'.\n",
791                                          (uint64_t)bytes_read, path.c_str());
792             return false;
793           }
794         } else {
795           // We are going to write ASCII to the file just point the
796           // output_stream to our outfile_stream...
797           output_stream_storage = std::move(outfile_stream_up);
798           output_stream_p = output_stream_storage.get();
799         }
800       } else {
801         result.AppendErrorWithFormat("Failed to open file '%s' for %s:\n",
802                                      path.c_str(), append ? "append" : "write");
803 
804         result.AppendError(llvm::toString(outfile.takeError()));
805         return false;
806       }
807     } else {
808       output_stream_p = &result.GetOutputStream();
809     }
810 
811     ExecutionContextScope *exe_scope = m_exe_ctx.GetBestExecutionContextScope();
812     if (compiler_type.GetOpaqueQualType()) {
813       for (uint32_t i = 0; i < item_count; ++i) {
814         addr_t item_addr = addr + (i * item_byte_size);
815         Address address(item_addr);
816         StreamString name_strm;
817         name_strm.Printf("0x%" PRIx64, item_addr);
818         ValueObjectSP valobj_sp(ValueObjectMemory::Create(
819             exe_scope, name_strm.GetString(), address, compiler_type));
820         if (valobj_sp) {
821           Format format = m_format_options.GetFormat();
822           if (format != eFormatDefault)
823             valobj_sp->SetFormat(format);
824 
825           DumpValueObjectOptions options(m_varobj_options.GetAsDumpOptions(
826               eLanguageRuntimeDescriptionDisplayVerbosityFull, format));
827 
828           valobj_sp->Dump(*output_stream_p, options);
829         } else {
830           result.AppendErrorWithFormat(
831               "failed to create a value object for: (%s) %s\n",
832               view_as_type_cstr, name_strm.GetData());
833           return false;
834         }
835       }
836       return true;
837     }
838 
839     result.SetStatus(eReturnStatusSuccessFinishResult);
840     DataExtractor data(data_sp, target->GetArchitecture().GetByteOrder(),
841                        target->GetArchitecture().GetAddressByteSize(),
842                        target->GetArchitecture().GetDataByteSize());
843 
844     Format format = m_format_options.GetFormat();
845     if (((format == eFormatChar) || (format == eFormatCharPrintable)) &&
846         (item_byte_size != 1)) {
847       // if a count was not passed, or it is 1
848       if (!m_format_options.GetCountValue().OptionWasSet() || item_count == 1) {
849         // this turns requests such as
850         // memory read -fc -s10 -c1 *charPtrPtr
851         // which make no sense (what is a char of size 10?) into a request for
852         // fetching 10 chars of size 1 from the same memory location
853         format = eFormatCharArray;
854         item_count = item_byte_size;
855         item_byte_size = 1;
856       } else {
857         // here we passed a count, and it was not 1 so we have a byte_size and
858         // a count we could well multiply those, but instead let's just fail
859         result.AppendErrorWithFormat(
860             "reading memory as characters of size %" PRIu64 " is not supported",
861             (uint64_t)item_byte_size);
862         return false;
863       }
864     }
865 
866     assert(output_stream_p);
867     size_t bytes_dumped = DumpDataExtractor(
868         data, output_stream_p, 0, format, item_byte_size, item_count,
869         num_per_line / target->GetArchitecture().GetDataByteSize(), addr, 0, 0,
870         exe_scope, m_memory_tag_options.GetShowTags().GetCurrentValue());
871     m_next_addr = addr + bytes_dumped;
872     output_stream_p->EOL();
873     return true;
874   }
875 
876   OptionGroupOptions m_option_group;
877   OptionGroupFormat m_format_options;
878   OptionGroupReadMemory m_memory_options;
879   OptionGroupOutputFile m_outfile_options;
880   OptionGroupValueObjectDisplay m_varobj_options;
881   OptionGroupMemoryTag m_memory_tag_options;
882   lldb::addr_t m_next_addr = LLDB_INVALID_ADDRESS;
883   lldb::addr_t m_prev_byte_size = 0;
884   OptionGroupFormat m_prev_format_options;
885   OptionGroupReadMemory m_prev_memory_options;
886   OptionGroupOutputFile m_prev_outfile_options;
887   OptionGroupValueObjectDisplay m_prev_varobj_options;
888   OptionGroupMemoryTag m_prev_memory_tag_options;
889   CompilerType m_prev_compiler_type;
890 };
891 
892 #define LLDB_OPTIONS_memory_find
893 #include "CommandOptions.inc"
894 
895 // Find the specified data in memory
896 class CommandObjectMemoryFind : public CommandObjectParsed {
897 public:
898   class OptionGroupFindMemory : public OptionGroup {
899   public:
900     OptionGroupFindMemory() : m_count(1), m_offset(0) {}
901 
902     ~OptionGroupFindMemory() override = default;
903 
904     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
905       return llvm::makeArrayRef(g_memory_find_options);
906     }
907 
908     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
909                           ExecutionContext *execution_context) override {
910       Status error;
911       const int short_option = g_memory_find_options[option_idx].short_option;
912 
913       switch (short_option) {
914       case 'e':
915         m_expr.SetValueFromString(option_value);
916         break;
917 
918       case 's':
919         m_string.SetValueFromString(option_value);
920         break;
921 
922       case 'c':
923         if (m_count.SetValueFromString(option_value).Fail())
924           error.SetErrorString("unrecognized value for count");
925         break;
926 
927       case 'o':
928         if (m_offset.SetValueFromString(option_value).Fail())
929           error.SetErrorString("unrecognized value for dump-offset");
930         break;
931 
932       default:
933         llvm_unreachable("Unimplemented option");
934       }
935       return error;
936     }
937 
938     void OptionParsingStarting(ExecutionContext *execution_context) override {
939       m_expr.Clear();
940       m_string.Clear();
941       m_count.Clear();
942     }
943 
944     OptionValueString m_expr;
945     OptionValueString m_string;
946     OptionValueUInt64 m_count;
947     OptionValueUInt64 m_offset;
948   };
949 
950   CommandObjectMemoryFind(CommandInterpreter &interpreter)
951       : CommandObjectParsed(
952             interpreter, "memory find",
953             "Find a value in the memory of the current target process.",
954             nullptr, eCommandRequiresProcess | eCommandProcessMustBeLaunched) {
955     CommandArgumentEntry arg1;
956     CommandArgumentEntry arg2;
957     CommandArgumentData addr_arg;
958     CommandArgumentData value_arg;
959 
960     // Define the first (and only) variant of this arg.
961     addr_arg.arg_type = eArgTypeAddressOrExpression;
962     addr_arg.arg_repetition = eArgRepeatPlain;
963 
964     // There is only one variant this argument could be; put it into the
965     // argument entry.
966     arg1.push_back(addr_arg);
967 
968     // Define the first (and only) variant of this arg.
969     value_arg.arg_type = eArgTypeAddressOrExpression;
970     value_arg.arg_repetition = eArgRepeatPlain;
971 
972     // There is only one variant this argument could be; put it into the
973     // argument entry.
974     arg2.push_back(value_arg);
975 
976     // Push the data for the first argument into the m_arguments vector.
977     m_arguments.push_back(arg1);
978     m_arguments.push_back(arg2);
979 
980     m_option_group.Append(&m_memory_options);
981     m_option_group.Append(&m_memory_tag_options, LLDB_OPT_SET_ALL,
982                           LLDB_OPT_SET_ALL);
983     m_option_group.Finalize();
984   }
985 
986   ~CommandObjectMemoryFind() override = default;
987 
988   Options *GetOptions() override { return &m_option_group; }
989 
990 protected:
991   class ProcessMemoryIterator {
992   public:
993     ProcessMemoryIterator(ProcessSP process_sp, lldb::addr_t base)
994         : m_process_sp(process_sp), m_base_addr(base) {
995       lldbassert(process_sp.get() != nullptr);
996     }
997 
998     bool IsValid() { return m_is_valid; }
999 
1000     uint8_t operator[](lldb::addr_t offset) {
1001       if (!IsValid())
1002         return 0;
1003 
1004       uint8_t retval = 0;
1005       Status error;
1006       if (0 ==
1007           m_process_sp->ReadMemory(m_base_addr + offset, &retval, 1, error)) {
1008         m_is_valid = false;
1009         return 0;
1010       }
1011 
1012       return retval;
1013     }
1014 
1015   private:
1016     ProcessSP m_process_sp;
1017     lldb::addr_t m_base_addr;
1018     bool m_is_valid = true;
1019   };
1020   bool DoExecute(Args &command, CommandReturnObject &result) override {
1021     // No need to check "process" for validity as eCommandRequiresProcess
1022     // ensures it is valid
1023     Process *process = m_exe_ctx.GetProcessPtr();
1024 
1025     const size_t argc = command.GetArgumentCount();
1026 
1027     if (argc != 2) {
1028       result.AppendError("two addresses needed for memory find");
1029       return false;
1030     }
1031 
1032     Status error;
1033     lldb::addr_t low_addr = OptionArgParser::ToAddress(
1034         &m_exe_ctx, command[0].ref(), LLDB_INVALID_ADDRESS, &error);
1035     if (low_addr == LLDB_INVALID_ADDRESS || error.Fail()) {
1036       result.AppendError("invalid low address");
1037       return false;
1038     }
1039     lldb::addr_t high_addr = OptionArgParser::ToAddress(
1040         &m_exe_ctx, command[1].ref(), LLDB_INVALID_ADDRESS, &error);
1041     if (high_addr == LLDB_INVALID_ADDRESS || error.Fail()) {
1042       result.AppendError("invalid high address");
1043       return false;
1044     }
1045 
1046     ABISP abi = m_exe_ctx.GetProcessPtr()->GetABI();
1047     if (abi) {
1048       low_addr = abi->FixDataAddress(low_addr);
1049       high_addr = abi->FixDataAddress(high_addr);
1050     }
1051 
1052     if (high_addr <= low_addr) {
1053       result.AppendError(
1054           "starting address must be smaller than ending address");
1055       return false;
1056     }
1057 
1058     lldb::addr_t found_location = LLDB_INVALID_ADDRESS;
1059 
1060     DataBufferHeap buffer;
1061 
1062     if (m_memory_options.m_string.OptionWasSet()) {
1063       llvm::StringRef str = m_memory_options.m_string.GetStringValue();
1064       if (str.empty()) {
1065         result.AppendError("search string must have non-zero length.");
1066         return false;
1067       }
1068       buffer.CopyData(str);
1069     } else if (m_memory_options.m_expr.OptionWasSet()) {
1070       StackFrame *frame = m_exe_ctx.GetFramePtr();
1071       ValueObjectSP result_sp;
1072       if ((eExpressionCompleted ==
1073            process->GetTarget().EvaluateExpression(
1074                m_memory_options.m_expr.GetStringValue(), frame, result_sp)) &&
1075           result_sp) {
1076         uint64_t value = result_sp->GetValueAsUnsigned(0);
1077         llvm::Optional<uint64_t> size =
1078             result_sp->GetCompilerType().GetByteSize(nullptr);
1079         if (!size)
1080           return false;
1081         switch (*size) {
1082         case 1: {
1083           uint8_t byte = (uint8_t)value;
1084           buffer.CopyData(&byte, 1);
1085         } break;
1086         case 2: {
1087           uint16_t word = (uint16_t)value;
1088           buffer.CopyData(&word, 2);
1089         } break;
1090         case 4: {
1091           uint32_t lword = (uint32_t)value;
1092           buffer.CopyData(&lword, 4);
1093         } break;
1094         case 8: {
1095           buffer.CopyData(&value, 8);
1096         } break;
1097         case 3:
1098         case 5:
1099         case 6:
1100         case 7:
1101           result.AppendError("unknown type. pass a string instead");
1102           return false;
1103         default:
1104           result.AppendError(
1105               "result size larger than 8 bytes. pass a string instead");
1106           return false;
1107         }
1108       } else {
1109         result.AppendError(
1110             "expression evaluation failed. pass a string instead");
1111         return false;
1112       }
1113     } else {
1114       result.AppendError(
1115           "please pass either a block of text, or an expression to evaluate.");
1116       return false;
1117     }
1118 
1119     size_t count = m_memory_options.m_count.GetCurrentValue();
1120     found_location = low_addr;
1121     bool ever_found = false;
1122     while (count) {
1123       found_location = FastSearch(found_location, high_addr, buffer.GetBytes(),
1124                                   buffer.GetByteSize());
1125       if (found_location == LLDB_INVALID_ADDRESS) {
1126         if (!ever_found) {
1127           result.AppendMessage("data not found within the range.\n");
1128           result.SetStatus(lldb::eReturnStatusSuccessFinishNoResult);
1129         } else
1130           result.AppendMessage("no more matches within the range.\n");
1131         break;
1132       }
1133       result.AppendMessageWithFormat("data found at location: 0x%" PRIx64 "\n",
1134                                      found_location);
1135 
1136       DataBufferHeap dumpbuffer(32, 0);
1137       process->ReadMemory(
1138           found_location + m_memory_options.m_offset.GetCurrentValue(),
1139           dumpbuffer.GetBytes(), dumpbuffer.GetByteSize(), error);
1140       if (!error.Fail()) {
1141         DataExtractor data(dumpbuffer.GetBytes(), dumpbuffer.GetByteSize(),
1142                            process->GetByteOrder(),
1143                            process->GetAddressByteSize());
1144         DumpDataExtractor(
1145             data, &result.GetOutputStream(), 0, lldb::eFormatBytesWithASCII, 1,
1146             dumpbuffer.GetByteSize(), 16,
1147             found_location + m_memory_options.m_offset.GetCurrentValue(), 0, 0,
1148             m_exe_ctx.GetBestExecutionContextScope(),
1149             m_memory_tag_options.GetShowTags().GetCurrentValue());
1150         result.GetOutputStream().EOL();
1151       }
1152 
1153       --count;
1154       found_location++;
1155       ever_found = true;
1156     }
1157 
1158     result.SetStatus(lldb::eReturnStatusSuccessFinishResult);
1159     return true;
1160   }
1161 
1162   lldb::addr_t FastSearch(lldb::addr_t low, lldb::addr_t high, uint8_t *buffer,
1163                           size_t buffer_size) {
1164     const size_t region_size = high - low;
1165 
1166     if (region_size < buffer_size)
1167       return LLDB_INVALID_ADDRESS;
1168 
1169     std::vector<size_t> bad_char_heuristic(256, buffer_size);
1170     ProcessSP process_sp = m_exe_ctx.GetProcessSP();
1171     ProcessMemoryIterator iterator(process_sp, low);
1172 
1173     for (size_t idx = 0; idx < buffer_size - 1; idx++) {
1174       decltype(bad_char_heuristic)::size_type bcu_idx = buffer[idx];
1175       bad_char_heuristic[bcu_idx] = buffer_size - idx - 1;
1176     }
1177     for (size_t s = 0; s <= (region_size - buffer_size);) {
1178       int64_t j = buffer_size - 1;
1179       while (j >= 0 && buffer[j] == iterator[s + j])
1180         j--;
1181       if (j < 0)
1182         return low + s;
1183       else
1184         s += bad_char_heuristic[iterator[s + buffer_size - 1]];
1185     }
1186 
1187     return LLDB_INVALID_ADDRESS;
1188   }
1189 
1190   OptionGroupOptions m_option_group;
1191   OptionGroupFindMemory m_memory_options;
1192   OptionGroupMemoryTag m_memory_tag_options;
1193 };
1194 
1195 #define LLDB_OPTIONS_memory_write
1196 #include "CommandOptions.inc"
1197 
1198 // Write memory to the inferior process
1199 class CommandObjectMemoryWrite : public CommandObjectParsed {
1200 public:
1201   class OptionGroupWriteMemory : public OptionGroup {
1202   public:
1203     OptionGroupWriteMemory() = default;
1204 
1205     ~OptionGroupWriteMemory() override = default;
1206 
1207     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1208       return llvm::makeArrayRef(g_memory_write_options);
1209     }
1210 
1211     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
1212                           ExecutionContext *execution_context) override {
1213       Status error;
1214       const int short_option = g_memory_write_options[option_idx].short_option;
1215 
1216       switch (short_option) {
1217       case 'i':
1218         m_infile.SetFile(option_value, FileSpec::Style::native);
1219         FileSystem::Instance().Resolve(m_infile);
1220         if (!FileSystem::Instance().Exists(m_infile)) {
1221           m_infile.Clear();
1222           error.SetErrorStringWithFormat("input file does not exist: '%s'",
1223                                          option_value.str().c_str());
1224         }
1225         break;
1226 
1227       case 'o': {
1228         if (option_value.getAsInteger(0, m_infile_offset)) {
1229           m_infile_offset = 0;
1230           error.SetErrorStringWithFormat("invalid offset string '%s'",
1231                                          option_value.str().c_str());
1232         }
1233       } break;
1234 
1235       default:
1236         llvm_unreachable("Unimplemented option");
1237       }
1238       return error;
1239     }
1240 
1241     void OptionParsingStarting(ExecutionContext *execution_context) override {
1242       m_infile.Clear();
1243       m_infile_offset = 0;
1244     }
1245 
1246     FileSpec m_infile;
1247     off_t m_infile_offset;
1248   };
1249 
1250   CommandObjectMemoryWrite(CommandInterpreter &interpreter)
1251       : CommandObjectParsed(
1252             interpreter, "memory write",
1253             "Write to the memory of the current target process.", nullptr,
1254             eCommandRequiresProcess | eCommandProcessMustBeLaunched),
1255         m_format_options(
1256             eFormatBytes, 1, UINT64_MAX,
1257             {std::make_tuple(
1258                  eArgTypeFormat,
1259                  "The format to use for each of the value to be written."),
1260              std::make_tuple(eArgTypeByteSize,
1261                              "The size in bytes to write from input file or "
1262                              "each value.")}) {
1263     CommandArgumentEntry arg1;
1264     CommandArgumentEntry arg2;
1265     CommandArgumentData addr_arg;
1266     CommandArgumentData value_arg;
1267 
1268     // Define the first (and only) variant of this arg.
1269     addr_arg.arg_type = eArgTypeAddress;
1270     addr_arg.arg_repetition = eArgRepeatPlain;
1271 
1272     // There is only one variant this argument could be; put it into the
1273     // argument entry.
1274     arg1.push_back(addr_arg);
1275 
1276     // Define the first (and only) variant of this arg.
1277     value_arg.arg_type = eArgTypeValue;
1278     value_arg.arg_repetition = eArgRepeatPlus;
1279     value_arg.arg_opt_set_association = LLDB_OPT_SET_1;
1280 
1281     // There is only one variant this argument could be; put it into the
1282     // argument entry.
1283     arg2.push_back(value_arg);
1284 
1285     // Push the data for the first argument into the m_arguments vector.
1286     m_arguments.push_back(arg1);
1287     m_arguments.push_back(arg2);
1288 
1289     m_option_group.Append(&m_format_options,
1290                           OptionGroupFormat::OPTION_GROUP_FORMAT,
1291                           LLDB_OPT_SET_1);
1292     m_option_group.Append(&m_format_options,
1293                           OptionGroupFormat::OPTION_GROUP_SIZE,
1294                           LLDB_OPT_SET_1 | LLDB_OPT_SET_2);
1295     m_option_group.Append(&m_memory_options, LLDB_OPT_SET_ALL, LLDB_OPT_SET_2);
1296     m_option_group.Finalize();
1297   }
1298 
1299   ~CommandObjectMemoryWrite() override = default;
1300 
1301   Options *GetOptions() override { return &m_option_group; }
1302 
1303 protected:
1304   bool DoExecute(Args &command, CommandReturnObject &result) override {
1305     // No need to check "process" for validity as eCommandRequiresProcess
1306     // ensures it is valid
1307     Process *process = m_exe_ctx.GetProcessPtr();
1308 
1309     const size_t argc = command.GetArgumentCount();
1310 
1311     if (m_memory_options.m_infile) {
1312       if (argc < 1) {
1313         result.AppendErrorWithFormat(
1314             "%s takes a destination address when writing file contents.\n",
1315             m_cmd_name.c_str());
1316         return false;
1317       }
1318       if (argc > 1) {
1319         result.AppendErrorWithFormat(
1320             "%s takes only a destination address when writing file contents.\n",
1321             m_cmd_name.c_str());
1322         return false;
1323       }
1324     } else if (argc < 2) {
1325       result.AppendErrorWithFormat(
1326           "%s takes a destination address and at least one value.\n",
1327           m_cmd_name.c_str());
1328       return false;
1329     }
1330 
1331     StreamString buffer(
1332         Stream::eBinary,
1333         process->GetTarget().GetArchitecture().GetAddressByteSize(),
1334         process->GetTarget().GetArchitecture().GetByteOrder());
1335 
1336     OptionValueUInt64 &byte_size_value = m_format_options.GetByteSizeValue();
1337     size_t item_byte_size = byte_size_value.GetCurrentValue();
1338 
1339     Status error;
1340     lldb::addr_t addr = OptionArgParser::ToAddress(
1341         &m_exe_ctx, command[0].ref(), LLDB_INVALID_ADDRESS, &error);
1342 
1343     if (addr == LLDB_INVALID_ADDRESS) {
1344       result.AppendError("invalid address expression\n");
1345       result.AppendError(error.AsCString());
1346       return false;
1347     }
1348 
1349     if (m_memory_options.m_infile) {
1350       size_t length = SIZE_MAX;
1351       if (item_byte_size > 1)
1352         length = item_byte_size;
1353       auto data_sp = FileSystem::Instance().CreateDataBuffer(
1354           m_memory_options.m_infile.GetPath(), length,
1355           m_memory_options.m_infile_offset);
1356       if (data_sp) {
1357         length = data_sp->GetByteSize();
1358         if (length > 0) {
1359           Status error;
1360           size_t bytes_written =
1361               process->WriteMemory(addr, data_sp->GetBytes(), length, error);
1362 
1363           if (bytes_written == length) {
1364             // All bytes written
1365             result.GetOutputStream().Printf(
1366                 "%" PRIu64 " bytes were written to 0x%" PRIx64 "\n",
1367                 (uint64_t)bytes_written, addr);
1368             result.SetStatus(eReturnStatusSuccessFinishResult);
1369           } else if (bytes_written > 0) {
1370             // Some byte written
1371             result.GetOutputStream().Printf(
1372                 "%" PRIu64 " bytes of %" PRIu64
1373                 " requested were written to 0x%" PRIx64 "\n",
1374                 (uint64_t)bytes_written, (uint64_t)length, addr);
1375             result.SetStatus(eReturnStatusSuccessFinishResult);
1376           } else {
1377             result.AppendErrorWithFormat("Memory write to 0x%" PRIx64
1378                                          " failed: %s.\n",
1379                                          addr, error.AsCString());
1380           }
1381         }
1382       } else {
1383         result.AppendErrorWithFormat("Unable to read contents of file.\n");
1384       }
1385       return result.Succeeded();
1386     } else if (item_byte_size == 0) {
1387       if (m_format_options.GetFormat() == eFormatPointer)
1388         item_byte_size = buffer.GetAddressByteSize();
1389       else
1390         item_byte_size = 1;
1391     }
1392 
1393     command.Shift(); // shift off the address argument
1394     uint64_t uval64;
1395     int64_t sval64;
1396     bool success = false;
1397     for (auto &entry : command) {
1398       switch (m_format_options.GetFormat()) {
1399       case kNumFormats:
1400       case eFormatFloat: // TODO: add support for floats soon
1401       case eFormatCharPrintable:
1402       case eFormatBytesWithASCII:
1403       case eFormatComplex:
1404       case eFormatEnum:
1405       case eFormatUnicode8:
1406       case eFormatUnicode16:
1407       case eFormatUnicode32:
1408       case eFormatVectorOfChar:
1409       case eFormatVectorOfSInt8:
1410       case eFormatVectorOfUInt8:
1411       case eFormatVectorOfSInt16:
1412       case eFormatVectorOfUInt16:
1413       case eFormatVectorOfSInt32:
1414       case eFormatVectorOfUInt32:
1415       case eFormatVectorOfSInt64:
1416       case eFormatVectorOfUInt64:
1417       case eFormatVectorOfFloat16:
1418       case eFormatVectorOfFloat32:
1419       case eFormatVectorOfFloat64:
1420       case eFormatVectorOfUInt128:
1421       case eFormatOSType:
1422       case eFormatComplexInteger:
1423       case eFormatAddressInfo:
1424       case eFormatHexFloat:
1425       case eFormatInstruction:
1426       case eFormatVoid:
1427         result.AppendError("unsupported format for writing memory");
1428         return false;
1429 
1430       case eFormatDefault:
1431       case eFormatBytes:
1432       case eFormatHex:
1433       case eFormatHexUppercase:
1434       case eFormatPointer: {
1435         // Decode hex bytes
1436         // Be careful, getAsInteger with a radix of 16 rejects "0xab" so we
1437         // have to special case that:
1438         bool success = false;
1439         if (entry.ref().startswith("0x"))
1440           success = !entry.ref().getAsInteger(0, uval64);
1441         if (!success)
1442           success = !entry.ref().getAsInteger(16, uval64);
1443         if (!success) {
1444           result.AppendErrorWithFormat(
1445               "'%s' is not a valid hex string value.\n", entry.c_str());
1446           return false;
1447         } else if (!llvm::isUIntN(item_byte_size * 8, uval64)) {
1448           result.AppendErrorWithFormat("Value 0x%" PRIx64
1449                                        " is too large to fit in a %" PRIu64
1450                                        " byte unsigned integer value.\n",
1451                                        uval64, (uint64_t)item_byte_size);
1452           return false;
1453         }
1454         buffer.PutMaxHex64(uval64, item_byte_size);
1455         break;
1456       }
1457       case eFormatBoolean:
1458         uval64 = OptionArgParser::ToBoolean(entry.ref(), false, &success);
1459         if (!success) {
1460           result.AppendErrorWithFormat(
1461               "'%s' is not a valid boolean string value.\n", entry.c_str());
1462           return false;
1463         }
1464         buffer.PutMaxHex64(uval64, item_byte_size);
1465         break;
1466 
1467       case eFormatBinary:
1468         if (entry.ref().getAsInteger(2, uval64)) {
1469           result.AppendErrorWithFormat(
1470               "'%s' is not a valid binary string value.\n", entry.c_str());
1471           return false;
1472         } else if (!llvm::isUIntN(item_byte_size * 8, uval64)) {
1473           result.AppendErrorWithFormat("Value 0x%" PRIx64
1474                                        " is too large to fit in a %" PRIu64
1475                                        " byte unsigned integer value.\n",
1476                                        uval64, (uint64_t)item_byte_size);
1477           return false;
1478         }
1479         buffer.PutMaxHex64(uval64, item_byte_size);
1480         break;
1481 
1482       case eFormatCharArray:
1483       case eFormatChar:
1484       case eFormatCString: {
1485         if (entry.ref().empty())
1486           break;
1487 
1488         size_t len = entry.ref().size();
1489         // Include the NULL for C strings...
1490         if (m_format_options.GetFormat() == eFormatCString)
1491           ++len;
1492         Status error;
1493         if (process->WriteMemory(addr, entry.c_str(), len, error) == len) {
1494           addr += len;
1495         } else {
1496           result.AppendErrorWithFormat("Memory write to 0x%" PRIx64
1497                                        " failed: %s.\n",
1498                                        addr, error.AsCString());
1499           return false;
1500         }
1501         break;
1502       }
1503       case eFormatDecimal:
1504         if (entry.ref().getAsInteger(0, sval64)) {
1505           result.AppendErrorWithFormat(
1506               "'%s' is not a valid signed decimal value.\n", entry.c_str());
1507           return false;
1508         } else if (!llvm::isIntN(item_byte_size * 8, sval64)) {
1509           result.AppendErrorWithFormat(
1510               "Value %" PRIi64 " is too large or small to fit in a %" PRIu64
1511               " byte signed integer value.\n",
1512               sval64, (uint64_t)item_byte_size);
1513           return false;
1514         }
1515         buffer.PutMaxHex64(sval64, item_byte_size);
1516         break;
1517 
1518       case eFormatUnsigned:
1519 
1520         if (entry.ref().getAsInteger(0, uval64)) {
1521           result.AppendErrorWithFormat(
1522               "'%s' is not a valid unsigned decimal string value.\n",
1523               entry.c_str());
1524           return false;
1525         } else if (!llvm::isUIntN(item_byte_size * 8, uval64)) {
1526           result.AppendErrorWithFormat("Value %" PRIu64
1527                                        " is too large to fit in a %" PRIu64
1528                                        " byte unsigned integer value.\n",
1529                                        uval64, (uint64_t)item_byte_size);
1530           return false;
1531         }
1532         buffer.PutMaxHex64(uval64, item_byte_size);
1533         break;
1534 
1535       case eFormatOctal:
1536         if (entry.ref().getAsInteger(8, uval64)) {
1537           result.AppendErrorWithFormat(
1538               "'%s' is not a valid octal string value.\n", entry.c_str());
1539           return false;
1540         } else if (!llvm::isUIntN(item_byte_size * 8, uval64)) {
1541           result.AppendErrorWithFormat("Value %" PRIo64
1542                                        " is too large to fit in a %" PRIu64
1543                                        " byte unsigned integer value.\n",
1544                                        uval64, (uint64_t)item_byte_size);
1545           return false;
1546         }
1547         buffer.PutMaxHex64(uval64, item_byte_size);
1548         break;
1549       }
1550     }
1551 
1552     if (!buffer.GetString().empty()) {
1553       Status error;
1554       if (process->WriteMemory(addr, buffer.GetString().data(),
1555                                buffer.GetString().size(),
1556                                error) == buffer.GetString().size())
1557         return true;
1558       else {
1559         result.AppendErrorWithFormat("Memory write to 0x%" PRIx64
1560                                      " failed: %s.\n",
1561                                      addr, error.AsCString());
1562         return false;
1563       }
1564     }
1565     return true;
1566   }
1567 
1568   OptionGroupOptions m_option_group;
1569   OptionGroupFormat m_format_options;
1570   OptionGroupWriteMemory m_memory_options;
1571 };
1572 
1573 // Get malloc/free history of a memory address.
1574 class CommandObjectMemoryHistory : public CommandObjectParsed {
1575 public:
1576   CommandObjectMemoryHistory(CommandInterpreter &interpreter)
1577       : CommandObjectParsed(interpreter, "memory history",
1578                             "Print recorded stack traces for "
1579                             "allocation/deallocation events "
1580                             "associated with an address.",
1581                             nullptr,
1582                             eCommandRequiresTarget | eCommandRequiresProcess |
1583                                 eCommandProcessMustBePaused |
1584                                 eCommandProcessMustBeLaunched) {
1585     CommandArgumentEntry arg1;
1586     CommandArgumentData addr_arg;
1587 
1588     // Define the first (and only) variant of this arg.
1589     addr_arg.arg_type = eArgTypeAddress;
1590     addr_arg.arg_repetition = eArgRepeatPlain;
1591 
1592     // There is only one variant this argument could be; put it into the
1593     // argument entry.
1594     arg1.push_back(addr_arg);
1595 
1596     // Push the data for the first argument into the m_arguments vector.
1597     m_arguments.push_back(arg1);
1598   }
1599 
1600   ~CommandObjectMemoryHistory() override = default;
1601 
1602   llvm::Optional<std::string> GetRepeatCommand(Args &current_command_args,
1603                                                uint32_t index) override {
1604     return m_cmd_name;
1605   }
1606 
1607 protected:
1608   bool DoExecute(Args &command, CommandReturnObject &result) override {
1609     const size_t argc = command.GetArgumentCount();
1610 
1611     if (argc == 0 || argc > 1) {
1612       result.AppendErrorWithFormat("%s takes an address expression",
1613                                    m_cmd_name.c_str());
1614       return false;
1615     }
1616 
1617     Status error;
1618     lldb::addr_t addr = OptionArgParser::ToAddress(
1619         &m_exe_ctx, command[0].ref(), LLDB_INVALID_ADDRESS, &error);
1620 
1621     if (addr == LLDB_INVALID_ADDRESS) {
1622       result.AppendError("invalid address expression");
1623       result.AppendError(error.AsCString());
1624       return false;
1625     }
1626 
1627     Stream *output_stream = &result.GetOutputStream();
1628 
1629     const ProcessSP &process_sp = m_exe_ctx.GetProcessSP();
1630     const MemoryHistorySP &memory_history =
1631         MemoryHistory::FindPlugin(process_sp);
1632 
1633     if (!memory_history) {
1634       result.AppendError("no available memory history provider");
1635       return false;
1636     }
1637 
1638     HistoryThreads thread_list = memory_history->GetHistoryThreads(addr);
1639 
1640     const bool stop_format = false;
1641     for (auto thread : thread_list) {
1642       thread->GetStatus(*output_stream, 0, UINT32_MAX, 0, stop_format);
1643     }
1644 
1645     result.SetStatus(eReturnStatusSuccessFinishResult);
1646 
1647     return true;
1648   }
1649 };
1650 
1651 // CommandObjectMemoryRegion
1652 #pragma mark CommandObjectMemoryRegion
1653 
1654 #define LLDB_OPTIONS_memory_region
1655 #include "CommandOptions.inc"
1656 
1657 class CommandObjectMemoryRegion : public CommandObjectParsed {
1658 public:
1659   class OptionGroupMemoryRegion : public OptionGroup {
1660   public:
1661     OptionGroupMemoryRegion() : OptionGroup(), m_all(false, false) {}
1662 
1663     ~OptionGroupMemoryRegion() override = default;
1664 
1665     llvm::ArrayRef<OptionDefinition> GetDefinitions() override {
1666       return llvm::makeArrayRef(g_memory_region_options);
1667     }
1668 
1669     Status SetOptionValue(uint32_t option_idx, llvm::StringRef option_value,
1670                           ExecutionContext *execution_context) override {
1671       Status status;
1672       const int short_option = g_memory_region_options[option_idx].short_option;
1673 
1674       switch (short_option) {
1675       case 'a':
1676         m_all.SetCurrentValue(true);
1677         m_all.SetOptionWasSet();
1678         break;
1679       default:
1680         llvm_unreachable("Unimplemented option");
1681       }
1682 
1683       return status;
1684     }
1685 
1686     void OptionParsingStarting(ExecutionContext *execution_context) override {
1687       m_all.Clear();
1688     }
1689 
1690     OptionValueBoolean m_all;
1691   };
1692 
1693   CommandObjectMemoryRegion(CommandInterpreter &interpreter)
1694       : CommandObjectParsed(interpreter, "memory region",
1695                             "Get information on the memory region containing "
1696                             "an address in the current target process.",
1697                             "memory region <address-expression> (or --all)",
1698                             eCommandRequiresProcess | eCommandTryTargetAPILock |
1699                                 eCommandProcessMustBeLaunched) {
1700     // Address in option set 1.
1701     m_arguments.push_back(CommandArgumentEntry{CommandArgumentData(
1702         eArgTypeAddressOrExpression, eArgRepeatPlain, LLDB_OPT_SET_1)});
1703     // "--all" will go in option set 2.
1704     m_option_group.Append(&m_memory_region_options);
1705     m_option_group.Finalize();
1706   }
1707 
1708   ~CommandObjectMemoryRegion() override = default;
1709 
1710   Options *GetOptions() override { return &m_option_group; }
1711 
1712 protected:
1713   void DumpRegion(CommandReturnObject &result, Target &target,
1714                   const MemoryRegionInfo &range_info, lldb::addr_t load_addr) {
1715     lldb_private::Address addr;
1716     ConstString section_name;
1717     if (target.ResolveLoadAddress(load_addr, addr)) {
1718       SectionSP section_sp(addr.GetSection());
1719       if (section_sp) {
1720         // Got the top most section, not the deepest section
1721         while (section_sp->GetParent())
1722           section_sp = section_sp->GetParent();
1723         section_name = section_sp->GetName();
1724       }
1725     }
1726 
1727     ConstString name = range_info.GetName();
1728     result.AppendMessageWithFormatv(
1729         "[{0:x16}-{1:x16}) {2:r}{3:w}{4:x}{5}{6}{7}{8}",
1730         range_info.GetRange().GetRangeBase(),
1731         range_info.GetRange().GetRangeEnd(), range_info.GetReadable(),
1732         range_info.GetWritable(), range_info.GetExecutable(), name ? " " : "",
1733         name, section_name ? " " : "", section_name);
1734     MemoryRegionInfo::OptionalBool memory_tagged = range_info.GetMemoryTagged();
1735     if (memory_tagged == MemoryRegionInfo::OptionalBool::eYes)
1736       result.AppendMessage("memory tagging: enabled");
1737 
1738     const llvm::Optional<std::vector<addr_t>> &dirty_page_list =
1739         range_info.GetDirtyPageList();
1740     if (dirty_page_list) {
1741       const size_t page_count = dirty_page_list.getValue().size();
1742       result.AppendMessageWithFormat(
1743           "Modified memory (dirty) page list provided, %zu entries.\n",
1744           page_count);
1745       if (page_count > 0) {
1746         bool print_comma = false;
1747         result.AppendMessageWithFormat("Dirty pages: ");
1748         for (size_t i = 0; i < page_count; i++) {
1749           if (print_comma)
1750             result.AppendMessageWithFormat(", ");
1751           else
1752             print_comma = true;
1753           result.AppendMessageWithFormat("0x%" PRIx64, (*dirty_page_list)[i]);
1754         }
1755         result.AppendMessageWithFormat(".\n");
1756       }
1757     }
1758   }
1759 
1760   bool DoExecute(Args &command, CommandReturnObject &result) override {
1761     ProcessSP process_sp = m_exe_ctx.GetProcessSP();
1762     if (!process_sp) {
1763       m_prev_end_addr = LLDB_INVALID_ADDRESS;
1764       result.AppendError("invalid process");
1765       return false;
1766     }
1767 
1768     Status error;
1769     lldb::addr_t load_addr = m_prev_end_addr;
1770     m_prev_end_addr = LLDB_INVALID_ADDRESS;
1771 
1772     const size_t argc = command.GetArgumentCount();
1773     const lldb::ABISP &abi = process_sp->GetABI();
1774 
1775     if (argc == 1) {
1776       if (m_memory_region_options.m_all) {
1777         result.AppendError(
1778             "The \"--all\" option cannot be used when an address "
1779             "argument is given");
1780         return false;
1781       }
1782 
1783       auto load_addr_str = command[0].ref();
1784       // Non-address bits in this will be handled later by GetMemoryRegion
1785       load_addr = OptionArgParser::ToAddress(&m_exe_ctx, load_addr_str,
1786                                              LLDB_INVALID_ADDRESS, &error);
1787       if (error.Fail() || load_addr == LLDB_INVALID_ADDRESS) {
1788         result.AppendErrorWithFormat("invalid address argument \"%s\": %s\n",
1789                                      command[0].c_str(), error.AsCString());
1790         return false;
1791       }
1792     } else if (argc > 1 ||
1793                // When we're repeating the command, the previous end address is
1794                // used for load_addr. If that was 0xF...F then we must have
1795                // reached the end of memory.
1796                (argc == 0 && !m_memory_region_options.m_all &&
1797                 load_addr == LLDB_INVALID_ADDRESS) ||
1798                // If the target has non-address bits (tags, limited virtual
1799                // address size, etc.), the end of mappable memory will be lower
1800                // than that. So if we find any non-address bit set, we must be
1801                // at the end of the mappable range.
1802                (abi && (abi->FixAnyAddress(load_addr) != load_addr))) {
1803       result.AppendErrorWithFormat(
1804           "'%s' takes one argument or \"--all\" option:\nUsage: %s\n",
1805           m_cmd_name.c_str(), m_cmd_syntax.c_str());
1806       return false;
1807     }
1808 
1809     // Is is important that we track the address used to request the region as
1810     // this will give the correct section name in the case that regions overlap.
1811     // On Windows we get mutliple regions that start at the same place but are
1812     // different sizes and refer to different sections.
1813     std::vector<std::pair<lldb_private::MemoryRegionInfo, lldb::addr_t>>
1814         region_list;
1815     if (m_memory_region_options.m_all) {
1816       // We don't use GetMemoryRegions here because it doesn't include unmapped
1817       // areas like repeating the command would. So instead, emulate doing that.
1818       lldb::addr_t addr = 0;
1819       while (error.Success() && addr != LLDB_INVALID_ADDRESS &&
1820              // When there are non-address bits the last range will not extend
1821              // to LLDB_INVALID_ADDRESS but to the max virtual address.
1822              // This prevents us looping forever if that is the case.
1823              (abi && (abi->FixAnyAddress(addr) == addr))) {
1824         lldb_private::MemoryRegionInfo region_info;
1825         error = process_sp->GetMemoryRegionInfo(addr, region_info);
1826 
1827         if (error.Success()) {
1828           region_list.push_back({region_info, addr});
1829           addr = region_info.GetRange().GetRangeEnd();
1830         }
1831       }
1832 
1833       // Even if we read nothing, don't error for --all
1834       error.Clear();
1835     } else {
1836       lldb_private::MemoryRegionInfo region_info;
1837       error = process_sp->GetMemoryRegionInfo(load_addr, region_info);
1838       if (error.Success())
1839         region_list.push_back({region_info, load_addr});
1840     }
1841 
1842     if (error.Success()) {
1843       for (std::pair<MemoryRegionInfo, addr_t> &range : region_list) {
1844         DumpRegion(result, process_sp->GetTarget(), range.first, range.second);
1845         m_prev_end_addr = range.first.GetRange().GetRangeEnd();
1846       }
1847 
1848       result.SetStatus(eReturnStatusSuccessFinishResult);
1849       return true;
1850     }
1851 
1852     result.AppendErrorWithFormat("%s\n", error.AsCString());
1853     return false;
1854   }
1855 
1856   llvm::Optional<std::string> GetRepeatCommand(Args &current_command_args,
1857                                                uint32_t index) override {
1858     // If we repeat this command, repeat it without any arguments so we can
1859     // show the next memory range
1860     return m_cmd_name;
1861   }
1862 
1863   lldb::addr_t m_prev_end_addr = LLDB_INVALID_ADDRESS;
1864 
1865   OptionGroupOptions m_option_group;
1866   OptionGroupMemoryRegion m_memory_region_options;
1867 };
1868 
1869 // CommandObjectMemory
1870 
1871 CommandObjectMemory::CommandObjectMemory(CommandInterpreter &interpreter)
1872     : CommandObjectMultiword(
1873           interpreter, "memory",
1874           "Commands for operating on memory in the current target process.",
1875           "memory <subcommand> [<subcommand-options>]") {
1876   LoadSubCommand("find",
1877                  CommandObjectSP(new CommandObjectMemoryFind(interpreter)));
1878   LoadSubCommand("read",
1879                  CommandObjectSP(new CommandObjectMemoryRead(interpreter)));
1880   LoadSubCommand("write",
1881                  CommandObjectSP(new CommandObjectMemoryWrite(interpreter)));
1882   LoadSubCommand("history",
1883                  CommandObjectSP(new CommandObjectMemoryHistory(interpreter)));
1884   LoadSubCommand("region",
1885                  CommandObjectSP(new CommandObjectMemoryRegion(interpreter)));
1886   LoadSubCommand("tag",
1887                  CommandObjectSP(new CommandObjectMemoryTag(interpreter)));
1888 }
1889 
1890 CommandObjectMemory::~CommandObjectMemory() = default;
1891