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