1 //===-- Disassembler.cpp --------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include "lldb/Core/Disassembler.h"
10 
11 #include "lldb/Core/AddressRange.h"
12 #include "lldb/Core/Debugger.h"
13 #include "lldb/Core/EmulateInstruction.h"
14 #include "lldb/Core/Mangled.h"
15 #include "lldb/Core/Module.h"
16 #include "lldb/Core/ModuleList.h"
17 #include "lldb/Core/PluginManager.h"
18 #include "lldb/Core/SourceManager.h"
19 #include "lldb/Host/FileSystem.h"
20 #include "lldb/Interpreter/OptionValue.h"
21 #include "lldb/Interpreter/OptionValueArray.h"
22 #include "lldb/Interpreter/OptionValueDictionary.h"
23 #include "lldb/Interpreter/OptionValueRegex.h"
24 #include "lldb/Interpreter/OptionValueString.h"
25 #include "lldb/Interpreter/OptionValueUInt64.h"
26 #include "lldb/Symbol/Function.h"
27 #include "lldb/Symbol/Symbol.h"
28 #include "lldb/Symbol/SymbolContext.h"
29 #include "lldb/Target/ExecutionContext.h"
30 #include "lldb/Target/SectionLoadList.h"
31 #include "lldb/Target/StackFrame.h"
32 #include "lldb/Target/Target.h"
33 #include "lldb/Target/Thread.h"
34 #include "lldb/Utility/DataBufferHeap.h"
35 #include "lldb/Utility/DataExtractor.h"
36 #include "lldb/Utility/RegularExpression.h"
37 #include "lldb/Utility/Status.h"
38 #include "lldb/Utility/Stream.h"
39 #include "lldb/Utility/StreamString.h"
40 #include "lldb/Utility/Timer.h"
41 #include "lldb/lldb-private-enumerations.h"
42 #include "lldb/lldb-private-interfaces.h"
43 #include "lldb/lldb-private-types.h"
44 #include "llvm/ADT/Triple.h"
45 #include "llvm/Support/Compiler.h"
46 
47 #include <cstdint>
48 #include <cstring>
49 #include <utility>
50 
51 #include <assert.h>
52 
53 #define DEFAULT_DISASM_BYTE_SIZE 32
54 
55 using namespace lldb;
56 using namespace lldb_private;
57 
58 DisassemblerSP Disassembler::FindPlugin(const ArchSpec &arch,
59                                         const char *flavor,
60                                         const char *plugin_name) {
61   static Timer::Category func_cat(LLVM_PRETTY_FUNCTION);
62   Timer scoped_timer(func_cat,
63                      "Disassembler::FindPlugin (arch = %s, plugin_name = %s)",
64                      arch.GetArchitectureName(), plugin_name);
65 
66   DisassemblerCreateInstance create_callback = nullptr;
67 
68   if (plugin_name) {
69     ConstString const_plugin_name(plugin_name);
70     create_callback = PluginManager::GetDisassemblerCreateCallbackForPluginName(
71         const_plugin_name);
72     if (create_callback) {
73       DisassemblerSP disassembler_sp(create_callback(arch, flavor));
74 
75       if (disassembler_sp)
76         return disassembler_sp;
77     }
78   } else {
79     for (uint32_t idx = 0;
80          (create_callback = PluginManager::GetDisassemblerCreateCallbackAtIndex(
81               idx)) != nullptr;
82          ++idx) {
83       DisassemblerSP disassembler_sp(create_callback(arch, flavor));
84 
85       if (disassembler_sp)
86         return disassembler_sp;
87     }
88   }
89   return DisassemblerSP();
90 }
91 
92 DisassemblerSP Disassembler::FindPluginForTarget(const TargetSP target_sp,
93                                                  const ArchSpec &arch,
94                                                  const char *flavor,
95                                                  const char *plugin_name) {
96   if (target_sp && flavor == nullptr) {
97     // FIXME - we don't have the mechanism in place to do per-architecture
98     // settings.  But since we know that for now we only support flavors on x86
99     // & x86_64,
100     if (arch.GetTriple().getArch() == llvm::Triple::x86 ||
101         arch.GetTriple().getArch() == llvm::Triple::x86_64)
102       flavor = target_sp->GetDisassemblyFlavor();
103   }
104   return FindPlugin(arch, flavor, plugin_name);
105 }
106 
107 static void ResolveAddress(const ExecutionContext &exe_ctx, const Address &addr,
108                            Address &resolved_addr) {
109   if (!addr.IsSectionOffset()) {
110     // If we weren't passed in a section offset address range, try and resolve
111     // it to something
112     Target *target = exe_ctx.GetTargetPtr();
113     if (target) {
114       bool is_resolved =
115           target->GetSectionLoadList().IsEmpty() ?
116               target->GetImages().ResolveFileAddress(addr.GetOffset(),
117                                                      resolved_addr) :
118               target->GetSectionLoadList().ResolveLoadAddress(addr.GetOffset(),
119                                                               resolved_addr);
120 
121       // We weren't able to resolve the address, just treat it as a raw address
122       if (is_resolved && resolved_addr.IsValid())
123         return;
124     }
125   }
126   resolved_addr = addr;
127 }
128 
129 lldb::DisassemblerSP Disassembler::DisassembleRange(
130     const ArchSpec &arch, const char *plugin_name, const char *flavor,
131     const ExecutionContext &exe_ctx, const AddressRange &range,
132     bool prefer_file_cache) {
133   if (range.GetByteSize() <= 0 || !exe_ctx.GetTargetPtr())
134     return {};
135 
136   if (!range.GetBaseAddress().IsValid())
137     return {};
138 
139   lldb::DisassemblerSP disasm_sp = Disassembler::FindPluginForTarget(
140       exe_ctx.GetTargetSP(), arch, flavor, plugin_name);
141 
142   if (!disasm_sp)
143     return {};
144 
145   const size_t bytes_disassembled = disasm_sp->ParseInstructions(
146       exe_ctx.GetTargetRef(), range, nullptr, prefer_file_cache);
147   if (bytes_disassembled == 0)
148     return {};
149 
150   return disasm_sp;
151 }
152 
153 lldb::DisassemblerSP
154 Disassembler::DisassembleBytes(const ArchSpec &arch, const char *plugin_name,
155                                const char *flavor, const Address &start,
156                                const void *src, size_t src_len,
157                                uint32_t num_instructions, bool data_from_file) {
158   if (!src)
159     return {};
160 
161   lldb::DisassemblerSP disasm_sp =
162       Disassembler::FindPlugin(arch, flavor, plugin_name);
163 
164   if (!disasm_sp)
165     return {};
166 
167   DataExtractor data(src, src_len, arch.GetByteOrder(),
168                      arch.GetAddressByteSize());
169 
170   (void)disasm_sp->DecodeInstructions(start, data, 0, num_instructions, false,
171                                       data_from_file);
172   return disasm_sp;
173 }
174 
175 bool Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch,
176                                const char *plugin_name, const char *flavor,
177                                const ExecutionContext &exe_ctx,
178                                const AddressRange &disasm_range,
179                                uint32_t num_instructions,
180                                bool mixed_source_and_assembly,
181                                uint32_t num_mixed_context_lines,
182                                uint32_t options, Stream &strm) {
183   if (!disasm_range.GetByteSize() || !exe_ctx.GetTargetPtr())
184     return false;
185 
186   lldb::DisassemblerSP disasm_sp(Disassembler::FindPluginForTarget(
187       exe_ctx.GetTargetSP(), arch, flavor, plugin_name));
188 
189   if (!disasm_sp)
190     return false;
191 
192   AddressRange range;
193   ResolveAddress(exe_ctx, disasm_range.GetBaseAddress(),
194                  range.GetBaseAddress());
195   range.SetByteSize(disasm_range.GetByteSize());
196   const bool prefer_file_cache = false;
197   size_t bytes_disassembled = disasm_sp->ParseInstructions(
198       exe_ctx.GetTargetRef(), range, &strm, prefer_file_cache);
199   if (bytes_disassembled == 0)
200     return false;
201 
202   return PrintInstructions(disasm_sp.get(), debugger, arch, exe_ctx,
203                            num_instructions, mixed_source_and_assembly,
204                            num_mixed_context_lines, options, strm);
205 }
206 
207 bool Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch,
208                                const char *plugin_name, const char *flavor,
209                                const ExecutionContext &exe_ctx,
210                                const Address &start_address,
211                                uint32_t num_instructions,
212                                bool mixed_source_and_assembly,
213                                uint32_t num_mixed_context_lines,
214                                uint32_t options, Stream &strm) {
215   if (num_instructions == 0 || !exe_ctx.GetTargetPtr())
216     return false;
217 
218   lldb::DisassemblerSP disasm_sp(Disassembler::FindPluginForTarget(
219       exe_ctx.GetTargetSP(), arch, flavor, plugin_name));
220   if (!disasm_sp)
221     return false;
222 
223   Address addr;
224   ResolveAddress(exe_ctx, start_address, addr);
225 
226   const bool prefer_file_cache = false;
227   size_t bytes_disassembled = disasm_sp->ParseInstructions(
228       exe_ctx.GetTargetRef(), addr, num_instructions, prefer_file_cache);
229   if (bytes_disassembled == 0)
230     return false;
231 
232   return PrintInstructions(disasm_sp.get(), debugger, arch, exe_ctx,
233                            num_instructions, mixed_source_and_assembly,
234                            num_mixed_context_lines, options, strm);
235 }
236 
237 Disassembler::SourceLine
238 Disassembler::GetFunctionDeclLineEntry(const SymbolContext &sc) {
239   if (!sc.function)
240     return {};
241 
242   if (!sc.line_entry.IsValid())
243     return {};
244 
245   LineEntry prologue_end_line = sc.line_entry;
246   FileSpec func_decl_file;
247   uint32_t func_decl_line;
248   sc.function->GetStartLineSourceInfo(func_decl_file, func_decl_line);
249 
250   if (func_decl_file != prologue_end_line.file &&
251       func_decl_file != prologue_end_line.original_file)
252     return {};
253 
254   SourceLine decl_line;
255   decl_line.file = func_decl_file;
256   decl_line.line = func_decl_line;
257   // TODO: Do we care about column on these entries?  If so, we need to plumb
258   // that through GetStartLineSourceInfo.
259   decl_line.column = 0;
260   return decl_line;
261 }
262 
263 void Disassembler::AddLineToSourceLineTables(
264     SourceLine &line,
265     std::map<FileSpec, std::set<uint32_t>> &source_lines_seen) {
266   if (line.IsValid()) {
267     auto source_lines_seen_pos = source_lines_seen.find(line.file);
268     if (source_lines_seen_pos == source_lines_seen.end()) {
269       std::set<uint32_t> lines;
270       lines.insert(line.line);
271       source_lines_seen.emplace(line.file, lines);
272     } else {
273       source_lines_seen_pos->second.insert(line.line);
274     }
275   }
276 }
277 
278 bool Disassembler::ElideMixedSourceAndDisassemblyLine(
279     const ExecutionContext &exe_ctx, const SymbolContext &sc,
280     SourceLine &line) {
281 
282   // TODO: should we also check target.process.thread.step-avoid-libraries ?
283 
284   const RegularExpression *avoid_regex = nullptr;
285 
286   // Skip any line #0 entries - they are implementation details
287   if (line.line == 0)
288     return false;
289 
290   ThreadSP thread_sp = exe_ctx.GetThreadSP();
291   if (thread_sp) {
292     avoid_regex = thread_sp->GetSymbolsToAvoidRegexp();
293   } else {
294     TargetSP target_sp = exe_ctx.GetTargetSP();
295     if (target_sp) {
296       Status error;
297       OptionValueSP value_sp = target_sp->GetDebugger().GetPropertyValue(
298           &exe_ctx, "target.process.thread.step-avoid-regexp", false, error);
299       if (value_sp && value_sp->GetType() == OptionValue::eTypeRegex) {
300         OptionValueRegex *re = value_sp->GetAsRegex();
301         if (re) {
302           avoid_regex = re->GetCurrentValue();
303         }
304       }
305     }
306   }
307   if (avoid_regex && sc.symbol != nullptr) {
308     const char *function_name =
309         sc.GetFunctionName(Mangled::ePreferDemangledWithoutArguments)
310             .GetCString();
311     if (function_name && avoid_regex->Execute(function_name)) {
312       // skip this source line
313       return true;
314     }
315   }
316   // don't skip this source line
317   return false;
318 }
319 
320 bool Disassembler::PrintInstructions(Disassembler *disasm_ptr,
321                                      Debugger &debugger, const ArchSpec &arch,
322                                      const ExecutionContext &exe_ctx,
323                                      uint32_t num_instructions,
324                                      bool mixed_source_and_assembly,
325                                      uint32_t num_mixed_context_lines,
326                                      uint32_t options, Stream &strm) {
327   // We got some things disassembled...
328   size_t num_instructions_found = disasm_ptr->GetInstructionList().GetSize();
329 
330   if (num_instructions > 0 && num_instructions < num_instructions_found)
331     num_instructions_found = num_instructions;
332 
333   const uint32_t max_opcode_byte_size =
334       disasm_ptr->GetInstructionList().GetMaxOpcocdeByteSize();
335   SymbolContext sc;
336   SymbolContext prev_sc;
337   AddressRange current_source_line_range;
338   const Address *pc_addr_ptr = nullptr;
339   StackFrame *frame = exe_ctx.GetFramePtr();
340 
341   TargetSP target_sp(exe_ctx.GetTargetSP());
342   SourceManager &source_manager =
343       target_sp ? target_sp->GetSourceManager() : debugger.GetSourceManager();
344 
345   if (frame) {
346     pc_addr_ptr = &frame->GetFrameCodeAddress();
347   }
348   const uint32_t scope =
349       eSymbolContextLineEntry | eSymbolContextFunction | eSymbolContextSymbol;
350   const bool use_inline_block_range = false;
351 
352   const FormatEntity::Entry *disassembly_format = nullptr;
353   FormatEntity::Entry format;
354   if (exe_ctx.HasTargetScope()) {
355     disassembly_format =
356         exe_ctx.GetTargetRef().GetDebugger().GetDisassemblyFormat();
357   } else {
358     FormatEntity::Parse("${addr}: ", format);
359     disassembly_format = &format;
360   }
361 
362   // First pass: step through the list of instructions, find how long the
363   // initial addresses strings are, insert padding in the second pass so the
364   // opcodes all line up nicely.
365 
366   // Also build up the source line mapping if this is mixed source & assembly
367   // mode. Calculate the source line for each assembly instruction (eliding
368   // inlined functions which the user wants to skip).
369 
370   std::map<FileSpec, std::set<uint32_t>> source_lines_seen;
371   Symbol *previous_symbol = nullptr;
372 
373   size_t address_text_size = 0;
374   for (size_t i = 0; i < num_instructions_found; ++i) {
375     Instruction *inst =
376         disasm_ptr->GetInstructionList().GetInstructionAtIndex(i).get();
377     if (inst) {
378       const Address &addr = inst->GetAddress();
379       ModuleSP module_sp(addr.GetModule());
380       if (module_sp) {
381         const SymbolContextItem resolve_mask = eSymbolContextFunction |
382                                                eSymbolContextSymbol |
383                                                eSymbolContextLineEntry;
384         uint32_t resolved_mask =
385             module_sp->ResolveSymbolContextForAddress(addr, resolve_mask, sc);
386         if (resolved_mask) {
387           StreamString strmstr;
388           Debugger::FormatDisassemblerAddress(disassembly_format, &sc, nullptr,
389                                               &exe_ctx, &addr, strmstr);
390           size_t cur_line = strmstr.GetSizeOfLastLine();
391           if (cur_line > address_text_size)
392             address_text_size = cur_line;
393 
394           // Add entries to our "source_lines_seen" map+set which list which
395           // sources lines occur in this disassembly session.  We will print
396           // lines of context around a source line, but we don't want to print
397           // a source line that has a line table entry of its own - we'll leave
398           // that source line to be printed when it actually occurs in the
399           // disassembly.
400 
401           if (mixed_source_and_assembly && sc.line_entry.IsValid()) {
402             if (sc.symbol != previous_symbol) {
403               SourceLine decl_line = GetFunctionDeclLineEntry(sc);
404               if (!ElideMixedSourceAndDisassemblyLine(exe_ctx, sc, decl_line))
405                 AddLineToSourceLineTables(decl_line, source_lines_seen);
406             }
407             if (sc.line_entry.IsValid()) {
408               SourceLine this_line;
409               this_line.file = sc.line_entry.file;
410               this_line.line = sc.line_entry.line;
411               this_line.column = sc.line_entry.column;
412               if (!ElideMixedSourceAndDisassemblyLine(exe_ctx, sc, this_line))
413                 AddLineToSourceLineTables(this_line, source_lines_seen);
414             }
415           }
416         }
417         sc.Clear(false);
418       }
419     }
420   }
421 
422   previous_symbol = nullptr;
423   SourceLine previous_line;
424   for (size_t i = 0; i < num_instructions_found; ++i) {
425     Instruction *inst =
426         disasm_ptr->GetInstructionList().GetInstructionAtIndex(i).get();
427 
428     if (inst) {
429       const Address &addr = inst->GetAddress();
430       const bool inst_is_at_pc = pc_addr_ptr && addr == *pc_addr_ptr;
431       SourceLinesToDisplay source_lines_to_display;
432 
433       prev_sc = sc;
434 
435       ModuleSP module_sp(addr.GetModule());
436       if (module_sp) {
437         uint32_t resolved_mask = module_sp->ResolveSymbolContextForAddress(
438             addr, eSymbolContextEverything, sc);
439         if (resolved_mask) {
440           if (mixed_source_and_assembly) {
441 
442             // If we've started a new function (non-inlined), print all of the
443             // source lines from the function declaration until the first line
444             // table entry - typically the opening curly brace of the function.
445             if (previous_symbol != sc.symbol) {
446               // The default disassembly format puts an extra blank line
447               // between functions - so when we're displaying the source
448               // context for a function, we don't want to add a blank line
449               // after the source context or we'll end up with two of them.
450               if (previous_symbol != nullptr)
451                 source_lines_to_display.print_source_context_end_eol = false;
452 
453               previous_symbol = sc.symbol;
454               if (sc.function && sc.line_entry.IsValid()) {
455                 LineEntry prologue_end_line = sc.line_entry;
456                 if (!ElideMixedSourceAndDisassemblyLine(exe_ctx, sc,
457                                                         prologue_end_line)) {
458                   FileSpec func_decl_file;
459                   uint32_t func_decl_line;
460                   sc.function->GetStartLineSourceInfo(func_decl_file,
461                                                       func_decl_line);
462                   if (func_decl_file == prologue_end_line.file ||
463                       func_decl_file == prologue_end_line.original_file) {
464                     // Add all the lines between the function declaration and
465                     // the first non-prologue source line to the list of lines
466                     // to print.
467                     for (uint32_t lineno = func_decl_line;
468                          lineno <= prologue_end_line.line; lineno++) {
469                       SourceLine this_line;
470                       this_line.file = func_decl_file;
471                       this_line.line = lineno;
472                       source_lines_to_display.lines.push_back(this_line);
473                     }
474                     // Mark the last line as the "current" one.  Usually this
475                     // is the open curly brace.
476                     if (source_lines_to_display.lines.size() > 0)
477                       source_lines_to_display.current_source_line =
478                           source_lines_to_display.lines.size() - 1;
479                   }
480                 }
481               }
482               sc.GetAddressRange(scope, 0, use_inline_block_range,
483                                  current_source_line_range);
484             }
485 
486             // If we've left a previous source line's address range, print a
487             // new source line
488             if (!current_source_line_range.ContainsFileAddress(addr)) {
489               sc.GetAddressRange(scope, 0, use_inline_block_range,
490                                  current_source_line_range);
491 
492               if (sc != prev_sc && sc.comp_unit && sc.line_entry.IsValid()) {
493                 SourceLine this_line;
494                 this_line.file = sc.line_entry.file;
495                 this_line.line = sc.line_entry.line;
496 
497                 if (!ElideMixedSourceAndDisassemblyLine(exe_ctx, sc,
498                                                         this_line)) {
499                   // Only print this source line if it is different from the
500                   // last source line we printed.  There may have been inlined
501                   // functions between these lines that we elided, resulting in
502                   // the same line being printed twice in a row for a
503                   // contiguous block of assembly instructions.
504                   if (this_line != previous_line) {
505 
506                     std::vector<uint32_t> previous_lines;
507                     for (uint32_t i = 0;
508                          i < num_mixed_context_lines &&
509                          (this_line.line - num_mixed_context_lines) > 0;
510                          i++) {
511                       uint32_t line =
512                           this_line.line - num_mixed_context_lines + i;
513                       auto pos = source_lines_seen.find(this_line.file);
514                       if (pos != source_lines_seen.end()) {
515                         if (pos->second.count(line) == 1) {
516                           previous_lines.clear();
517                         } else {
518                           previous_lines.push_back(line);
519                         }
520                       }
521                     }
522                     for (size_t i = 0; i < previous_lines.size(); i++) {
523                       SourceLine previous_line;
524                       previous_line.file = this_line.file;
525                       previous_line.line = previous_lines[i];
526                       auto pos = source_lines_seen.find(previous_line.file);
527                       if (pos != source_lines_seen.end()) {
528                         pos->second.insert(previous_line.line);
529                       }
530                       source_lines_to_display.lines.push_back(previous_line);
531                     }
532 
533                     source_lines_to_display.lines.push_back(this_line);
534                     source_lines_to_display.current_source_line =
535                         source_lines_to_display.lines.size() - 1;
536 
537                     for (uint32_t i = 0; i < num_mixed_context_lines; i++) {
538                       SourceLine next_line;
539                       next_line.file = this_line.file;
540                       next_line.line = this_line.line + i + 1;
541                       auto pos = source_lines_seen.find(next_line.file);
542                       if (pos != source_lines_seen.end()) {
543                         if (pos->second.count(next_line.line) == 1)
544                           break;
545                         pos->second.insert(next_line.line);
546                       }
547                       source_lines_to_display.lines.push_back(next_line);
548                     }
549                   }
550                   previous_line = this_line;
551                 }
552               }
553             }
554           }
555         } else {
556           sc.Clear(true);
557         }
558       }
559 
560       if (source_lines_to_display.lines.size() > 0) {
561         strm.EOL();
562         for (size_t idx = 0; idx < source_lines_to_display.lines.size();
563              idx++) {
564           SourceLine ln = source_lines_to_display.lines[idx];
565           const char *line_highlight = "";
566           if (inst_is_at_pc && (options & eOptionMarkPCSourceLine)) {
567             line_highlight = "->";
568           } else if (idx == source_lines_to_display.current_source_line) {
569             line_highlight = "**";
570           }
571           source_manager.DisplaySourceLinesWithLineNumbers(
572               ln.file, ln.line, ln.column, 0, 0, line_highlight, &strm);
573         }
574         if (source_lines_to_display.print_source_context_end_eol)
575           strm.EOL();
576       }
577 
578       const bool show_bytes = (options & eOptionShowBytes) != 0;
579       inst->Dump(&strm, max_opcode_byte_size, true, show_bytes, &exe_ctx, &sc,
580                  &prev_sc, nullptr, address_text_size);
581       strm.EOL();
582     } else {
583       break;
584     }
585   }
586 
587   return true;
588 }
589 
590 bool Disassembler::Disassemble(Debugger &debugger, const ArchSpec &arch,
591                                const char *plugin_name, const char *flavor,
592                                const ExecutionContext &exe_ctx,
593                                uint32_t num_instructions,
594                                bool mixed_source_and_assembly,
595                                uint32_t num_mixed_context_lines,
596                                uint32_t options, Stream &strm) {
597   AddressRange range;
598   StackFrame *frame = exe_ctx.GetFramePtr();
599   if (frame) {
600     SymbolContext sc(
601         frame->GetSymbolContext(eSymbolContextFunction | eSymbolContextSymbol));
602     if (sc.function) {
603       range = sc.function->GetAddressRange();
604     } else if (sc.symbol && sc.symbol->ValueIsAddress()) {
605       range.GetBaseAddress() = sc.symbol->GetAddressRef();
606       range.SetByteSize(sc.symbol->GetByteSize());
607     } else {
608       range.GetBaseAddress() = frame->GetFrameCodeAddress();
609     }
610 
611     if (range.GetBaseAddress().IsValid() && range.GetByteSize() == 0)
612       range.SetByteSize(DEFAULT_DISASM_BYTE_SIZE);
613   }
614 
615   return Disassemble(debugger, arch, plugin_name, flavor, exe_ctx, range,
616                      num_instructions, mixed_source_and_assembly,
617                      num_mixed_context_lines, options, strm);
618 }
619 
620 Instruction::Instruction(const Address &address, AddressClass addr_class)
621     : m_address(address), m_address_class(addr_class), m_opcode(),
622       m_calculated_strings(false) {}
623 
624 Instruction::~Instruction() = default;
625 
626 AddressClass Instruction::GetAddressClass() {
627   if (m_address_class == AddressClass::eInvalid)
628     m_address_class = m_address.GetAddressClass();
629   return m_address_class;
630 }
631 
632 void Instruction::Dump(lldb_private::Stream *s, uint32_t max_opcode_byte_size,
633                        bool show_address, bool show_bytes,
634                        const ExecutionContext *exe_ctx,
635                        const SymbolContext *sym_ctx,
636                        const SymbolContext *prev_sym_ctx,
637                        const FormatEntity::Entry *disassembly_addr_format,
638                        size_t max_address_text_size) {
639   size_t opcode_column_width = 7;
640   const size_t operand_column_width = 25;
641 
642   CalculateMnemonicOperandsAndCommentIfNeeded(exe_ctx);
643 
644   StreamString ss;
645 
646   if (show_address) {
647     Debugger::FormatDisassemblerAddress(disassembly_addr_format, sym_ctx,
648                                         prev_sym_ctx, exe_ctx, &m_address, ss);
649     ss.FillLastLineToColumn(max_address_text_size, ' ');
650   }
651 
652   if (show_bytes) {
653     if (m_opcode.GetType() == Opcode::eTypeBytes) {
654       // x86_64 and i386 are the only ones that use bytes right now so pad out
655       // the byte dump to be able to always show 15 bytes (3 chars each) plus a
656       // space
657       if (max_opcode_byte_size > 0)
658         m_opcode.Dump(&ss, max_opcode_byte_size * 3 + 1);
659       else
660         m_opcode.Dump(&ss, 15 * 3 + 1);
661     } else {
662       // Else, we have ARM or MIPS which can show up to a uint32_t 0x00000000
663       // (10 spaces) plus two for padding...
664       if (max_opcode_byte_size > 0)
665         m_opcode.Dump(&ss, max_opcode_byte_size * 3 + 1);
666       else
667         m_opcode.Dump(&ss, 12);
668     }
669   }
670 
671   const size_t opcode_pos = ss.GetSizeOfLastLine();
672 
673   // The default opcode size of 7 characters is plenty for most architectures
674   // but some like arm can pull out the occasional vqrshrun.s16.  We won't get
675   // consistent column spacing in these cases, unfortunately.
676   if (m_opcode_name.length() >= opcode_column_width) {
677     opcode_column_width = m_opcode_name.length() + 1;
678   }
679 
680   ss.PutCString(m_opcode_name);
681   ss.FillLastLineToColumn(opcode_pos + opcode_column_width, ' ');
682   ss.PutCString(m_mnemonics);
683 
684   if (!m_comment.empty()) {
685     ss.FillLastLineToColumn(
686         opcode_pos + opcode_column_width + operand_column_width, ' ');
687     ss.PutCString(" ; ");
688     ss.PutCString(m_comment);
689   }
690   s->PutCString(ss.GetString());
691 }
692 
693 bool Instruction::DumpEmulation(const ArchSpec &arch) {
694   std::unique_ptr<EmulateInstruction> insn_emulator_up(
695       EmulateInstruction::FindPlugin(arch, eInstructionTypeAny, nullptr));
696   if (insn_emulator_up) {
697     insn_emulator_up->SetInstruction(GetOpcode(), GetAddress(), nullptr);
698     return insn_emulator_up->EvaluateInstruction(0);
699   }
700 
701   return false;
702 }
703 
704 bool Instruction::CanSetBreakpoint () {
705   return !HasDelaySlot();
706 }
707 
708 bool Instruction::HasDelaySlot() {
709   // Default is false.
710   return false;
711 }
712 
713 OptionValueSP Instruction::ReadArray(FILE *in_file, Stream *out_stream,
714                                      OptionValue::Type data_type) {
715   bool done = false;
716   char buffer[1024];
717 
718   auto option_value_sp = std::make_shared<OptionValueArray>(1u << data_type);
719 
720   int idx = 0;
721   while (!done) {
722     if (!fgets(buffer, 1023, in_file)) {
723       out_stream->Printf(
724           "Instruction::ReadArray:  Error reading file (fgets).\n");
725       option_value_sp.reset();
726       return option_value_sp;
727     }
728 
729     std::string line(buffer);
730 
731     size_t len = line.size();
732     if (line[len - 1] == '\n') {
733       line[len - 1] = '\0';
734       line.resize(len - 1);
735     }
736 
737     if ((line.size() == 1) && line[0] == ']') {
738       done = true;
739       line.clear();
740     }
741 
742     if (!line.empty()) {
743       std::string value;
744       static RegularExpression g_reg_exp(
745           llvm::StringRef("^[ \t]*([^ \t]+)[ \t]*$"));
746       llvm::SmallVector<llvm::StringRef, 2> matches;
747       if (g_reg_exp.Execute(line, &matches))
748         value = matches[1].str();
749       else
750         value = line;
751 
752       OptionValueSP data_value_sp;
753       switch (data_type) {
754       case OptionValue::eTypeUInt64:
755         data_value_sp = std::make_shared<OptionValueUInt64>(0, 0);
756         data_value_sp->SetValueFromString(value);
757         break;
758       // Other types can be added later as needed.
759       default:
760         data_value_sp = std::make_shared<OptionValueString>(value.c_str(), "");
761         break;
762       }
763 
764       option_value_sp->GetAsArray()->InsertValue(idx, data_value_sp);
765       ++idx;
766     }
767   }
768 
769   return option_value_sp;
770 }
771 
772 OptionValueSP Instruction::ReadDictionary(FILE *in_file, Stream *out_stream) {
773   bool done = false;
774   char buffer[1024];
775 
776   auto option_value_sp = std::make_shared<OptionValueDictionary>();
777   static ConstString encoding_key("data_encoding");
778   OptionValue::Type data_type = OptionValue::eTypeInvalid;
779 
780   while (!done) {
781     // Read the next line in the file
782     if (!fgets(buffer, 1023, in_file)) {
783       out_stream->Printf(
784           "Instruction::ReadDictionary: Error reading file (fgets).\n");
785       option_value_sp.reset();
786       return option_value_sp;
787     }
788 
789     // Check to see if the line contains the end-of-dictionary marker ("}")
790     std::string line(buffer);
791 
792     size_t len = line.size();
793     if (line[len - 1] == '\n') {
794       line[len - 1] = '\0';
795       line.resize(len - 1);
796     }
797 
798     if ((line.size() == 1) && (line[0] == '}')) {
799       done = true;
800       line.clear();
801     }
802 
803     // Try to find a key-value pair in the current line and add it to the
804     // dictionary.
805     if (!line.empty()) {
806       static RegularExpression g_reg_exp(llvm::StringRef(
807           "^[ \t]*([a-zA-Z_][a-zA-Z0-9_]*)[ \t]*=[ \t]*(.*)[ \t]*$"));
808 
809       llvm::SmallVector<llvm::StringRef, 3> matches;
810 
811       bool reg_exp_success = g_reg_exp.Execute(line, &matches);
812       std::string key;
813       std::string value;
814       if (reg_exp_success) {
815         key = matches[1].str();
816         value = matches[2].str();
817       } else {
818         out_stream->Printf("Instruction::ReadDictionary: Failure executing "
819                            "regular expression.\n");
820         option_value_sp.reset();
821         return option_value_sp;
822       }
823 
824       ConstString const_key(key.c_str());
825       // Check value to see if it's the start of an array or dictionary.
826 
827       lldb::OptionValueSP value_sp;
828       assert(value.empty() == false);
829       assert(key.empty() == false);
830 
831       if (value[0] == '{') {
832         assert(value.size() == 1);
833         // value is a dictionary
834         value_sp = ReadDictionary(in_file, out_stream);
835         if (!value_sp) {
836           option_value_sp.reset();
837           return option_value_sp;
838         }
839       } else if (value[0] == '[') {
840         assert(value.size() == 1);
841         // value is an array
842         value_sp = ReadArray(in_file, out_stream, data_type);
843         if (!value_sp) {
844           option_value_sp.reset();
845           return option_value_sp;
846         }
847         // We've used the data_type to read an array; re-set the type to
848         // Invalid
849         data_type = OptionValue::eTypeInvalid;
850       } else if ((value[0] == '0') && (value[1] == 'x')) {
851         value_sp = std::make_shared<OptionValueUInt64>(0, 0);
852         value_sp->SetValueFromString(value);
853       } else {
854         size_t len = value.size();
855         if ((value[0] == '"') && (value[len - 1] == '"'))
856           value = value.substr(1, len - 2);
857         value_sp = std::make_shared<OptionValueString>(value.c_str(), "");
858       }
859 
860       if (const_key == encoding_key) {
861         // A 'data_encoding=..." is NOT a normal key-value pair; it is meta-data
862         // indicating the
863         // data type of an upcoming array (usually the next bit of data to be
864         // read in).
865         if (strcmp(value.c_str(), "uint32_t") == 0)
866           data_type = OptionValue::eTypeUInt64;
867       } else
868         option_value_sp->GetAsDictionary()->SetValueForKey(const_key, value_sp,
869                                                            false);
870     }
871   }
872 
873   return option_value_sp;
874 }
875 
876 bool Instruction::TestEmulation(Stream *out_stream, const char *file_name) {
877   if (!out_stream)
878     return false;
879 
880   if (!file_name) {
881     out_stream->Printf("Instruction::TestEmulation:  Missing file_name.");
882     return false;
883   }
884   FILE *test_file = FileSystem::Instance().Fopen(file_name, "r");
885   if (!test_file) {
886     out_stream->Printf(
887         "Instruction::TestEmulation: Attempt to open test file failed.");
888     return false;
889   }
890 
891   char buffer[256];
892   if (!fgets(buffer, 255, test_file)) {
893     out_stream->Printf(
894         "Instruction::TestEmulation: Error reading first line of test file.\n");
895     fclose(test_file);
896     return false;
897   }
898 
899   if (strncmp(buffer, "InstructionEmulationState={", 27) != 0) {
900     out_stream->Printf("Instructin::TestEmulation: Test file does not contain "
901                        "emulation state dictionary\n");
902     fclose(test_file);
903     return false;
904   }
905 
906   // Read all the test information from the test file into an
907   // OptionValueDictionary.
908 
909   OptionValueSP data_dictionary_sp(ReadDictionary(test_file, out_stream));
910   if (!data_dictionary_sp) {
911     out_stream->Printf(
912         "Instruction::TestEmulation:  Error reading Dictionary Object.\n");
913     fclose(test_file);
914     return false;
915   }
916 
917   fclose(test_file);
918 
919   OptionValueDictionary *data_dictionary =
920       data_dictionary_sp->GetAsDictionary();
921   static ConstString description_key("assembly_string");
922   static ConstString triple_key("triple");
923 
924   OptionValueSP value_sp = data_dictionary->GetValueForKey(description_key);
925 
926   if (!value_sp) {
927     out_stream->Printf("Instruction::TestEmulation:  Test file does not "
928                        "contain description string.\n");
929     return false;
930   }
931 
932   SetDescription(value_sp->GetStringValue());
933 
934   value_sp = data_dictionary->GetValueForKey(triple_key);
935   if (!value_sp) {
936     out_stream->Printf(
937         "Instruction::TestEmulation: Test file does not contain triple.\n");
938     return false;
939   }
940 
941   ArchSpec arch;
942   arch.SetTriple(llvm::Triple(value_sp->GetStringValue()));
943 
944   bool success = false;
945   std::unique_ptr<EmulateInstruction> insn_emulator_up(
946       EmulateInstruction::FindPlugin(arch, eInstructionTypeAny, nullptr));
947   if (insn_emulator_up)
948     success =
949         insn_emulator_up->TestEmulation(out_stream, arch, data_dictionary);
950 
951   if (success)
952     out_stream->Printf("Emulation test succeeded.");
953   else
954     out_stream->Printf("Emulation test failed.");
955 
956   return success;
957 }
958 
959 bool Instruction::Emulate(
960     const ArchSpec &arch, uint32_t evaluate_options, void *baton,
961     EmulateInstruction::ReadMemoryCallback read_mem_callback,
962     EmulateInstruction::WriteMemoryCallback write_mem_callback,
963     EmulateInstruction::ReadRegisterCallback read_reg_callback,
964     EmulateInstruction::WriteRegisterCallback write_reg_callback) {
965   std::unique_ptr<EmulateInstruction> insn_emulator_up(
966       EmulateInstruction::FindPlugin(arch, eInstructionTypeAny, nullptr));
967   if (insn_emulator_up) {
968     insn_emulator_up->SetBaton(baton);
969     insn_emulator_up->SetCallbacks(read_mem_callback, write_mem_callback,
970                                    read_reg_callback, write_reg_callback);
971     insn_emulator_up->SetInstruction(GetOpcode(), GetAddress(), nullptr);
972     return insn_emulator_up->EvaluateInstruction(evaluate_options);
973   }
974 
975   return false;
976 }
977 
978 uint32_t Instruction::GetData(DataExtractor &data) {
979   return m_opcode.GetData(data);
980 }
981 
982 InstructionList::InstructionList() : m_instructions() {}
983 
984 InstructionList::~InstructionList() = default;
985 
986 size_t InstructionList::GetSize() const { return m_instructions.size(); }
987 
988 uint32_t InstructionList::GetMaxOpcocdeByteSize() const {
989   uint32_t max_inst_size = 0;
990   collection::const_iterator pos, end;
991   for (pos = m_instructions.begin(), end = m_instructions.end(); pos != end;
992        ++pos) {
993     uint32_t inst_size = (*pos)->GetOpcode().GetByteSize();
994     if (max_inst_size < inst_size)
995       max_inst_size = inst_size;
996   }
997   return max_inst_size;
998 }
999 
1000 InstructionSP InstructionList::GetInstructionAtIndex(size_t idx) const {
1001   InstructionSP inst_sp;
1002   if (idx < m_instructions.size())
1003     inst_sp = m_instructions[idx];
1004   return inst_sp;
1005 }
1006 
1007 void InstructionList::Dump(Stream *s, bool show_address, bool show_bytes,
1008                            const ExecutionContext *exe_ctx) {
1009   const uint32_t max_opcode_byte_size = GetMaxOpcocdeByteSize();
1010   collection::const_iterator pos, begin, end;
1011 
1012   const FormatEntity::Entry *disassembly_format = nullptr;
1013   FormatEntity::Entry format;
1014   if (exe_ctx && exe_ctx->HasTargetScope()) {
1015     disassembly_format =
1016         exe_ctx->GetTargetRef().GetDebugger().GetDisassemblyFormat();
1017   } else {
1018     FormatEntity::Parse("${addr}: ", format);
1019     disassembly_format = &format;
1020   }
1021 
1022   for (begin = m_instructions.begin(), end = m_instructions.end(), pos = begin;
1023        pos != end; ++pos) {
1024     if (pos != begin)
1025       s->EOL();
1026     (*pos)->Dump(s, max_opcode_byte_size, show_address, show_bytes, exe_ctx,
1027                  nullptr, nullptr, disassembly_format, 0);
1028   }
1029 }
1030 
1031 void InstructionList::Clear() { m_instructions.clear(); }
1032 
1033 void InstructionList::Append(lldb::InstructionSP &inst_sp) {
1034   if (inst_sp)
1035     m_instructions.push_back(inst_sp);
1036 }
1037 
1038 uint32_t
1039 InstructionList::GetIndexOfNextBranchInstruction(uint32_t start,
1040                                                  Target &target,
1041                                                  bool ignore_calls,
1042                                                  bool *found_calls) const {
1043   size_t num_instructions = m_instructions.size();
1044 
1045   uint32_t next_branch = UINT32_MAX;
1046   size_t i;
1047 
1048   if (found_calls)
1049     *found_calls = false;
1050   for (i = start; i < num_instructions; i++) {
1051     if (m_instructions[i]->DoesBranch()) {
1052       if (ignore_calls && m_instructions[i]->IsCall()) {
1053         if (found_calls)
1054           *found_calls = true;
1055         continue;
1056       }
1057       next_branch = i;
1058       break;
1059     }
1060   }
1061 
1062   // Hexagon needs the first instruction of the packet with the branch. Go
1063   // backwards until we find an instruction marked end-of-packet, or until we
1064   // hit start.
1065   if (target.GetArchitecture().GetTriple().getArch() == llvm::Triple::hexagon) {
1066     // If we didn't find a branch, find the last packet start.
1067     if (next_branch == UINT32_MAX) {
1068       i = num_instructions - 1;
1069     }
1070 
1071     while (i > start) {
1072       --i;
1073 
1074       Status error;
1075       uint32_t inst_bytes;
1076       bool prefer_file_cache = false; // Read from process if process is running
1077       lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
1078       target.ReadMemory(m_instructions[i]->GetAddress(), prefer_file_cache,
1079                         &inst_bytes, sizeof(inst_bytes), error, &load_addr);
1080       // If we have an error reading memory, return start
1081       if (!error.Success())
1082         return start;
1083       // check if this is the last instruction in a packet bits 15:14 will be
1084       // 11b or 00b for a duplex
1085       if (((inst_bytes & 0xC000) == 0xC000) ||
1086           ((inst_bytes & 0xC000) == 0x0000)) {
1087         // instruction after this should be the start of next packet
1088         next_branch = i + 1;
1089         break;
1090       }
1091     }
1092 
1093     if (next_branch == UINT32_MAX) {
1094       // We couldn't find the previous packet, so return start
1095       next_branch = start;
1096     }
1097   }
1098   return next_branch;
1099 }
1100 
1101 uint32_t
1102 InstructionList::GetIndexOfInstructionAtAddress(const Address &address) {
1103   size_t num_instructions = m_instructions.size();
1104   uint32_t index = UINT32_MAX;
1105   for (size_t i = 0; i < num_instructions; i++) {
1106     if (m_instructions[i]->GetAddress() == address) {
1107       index = i;
1108       break;
1109     }
1110   }
1111   return index;
1112 }
1113 
1114 uint32_t
1115 InstructionList::GetIndexOfInstructionAtLoadAddress(lldb::addr_t load_addr,
1116                                                     Target &target) {
1117   Address address;
1118   address.SetLoadAddress(load_addr, &target);
1119   return GetIndexOfInstructionAtAddress(address);
1120 }
1121 
1122 size_t Disassembler::ParseInstructions(Target &target,
1123                                        const AddressRange &range,
1124                                        Stream *error_strm_ptr,
1125                                        bool prefer_file_cache) {
1126   const addr_t byte_size = range.GetByteSize();
1127   if (byte_size == 0 || !range.GetBaseAddress().IsValid())
1128     return 0;
1129 
1130   auto data_sp = std::make_shared<DataBufferHeap>(byte_size, '\0');
1131 
1132   Status error;
1133   lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
1134   const size_t bytes_read = target.ReadMemory(
1135       range.GetBaseAddress(), prefer_file_cache, data_sp->GetBytes(),
1136       data_sp->GetByteSize(), error, &load_addr);
1137 
1138   if (bytes_read > 0) {
1139     if (bytes_read != data_sp->GetByteSize())
1140       data_sp->SetByteSize(bytes_read);
1141     DataExtractor data(data_sp, m_arch.GetByteOrder(),
1142                        m_arch.GetAddressByteSize());
1143     const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS;
1144     return DecodeInstructions(range.GetBaseAddress(), data, 0, UINT32_MAX,
1145                               false, data_from_file);
1146   } else if (error_strm_ptr) {
1147     const char *error_cstr = error.AsCString();
1148     if (error_cstr) {
1149       error_strm_ptr->Printf("error: %s\n", error_cstr);
1150     }
1151   }
1152   return 0;
1153 }
1154 
1155 size_t Disassembler::ParseInstructions(Target &target, const Address &start,
1156                                        uint32_t num_instructions,
1157                                        bool prefer_file_cache) {
1158   m_instruction_list.Clear();
1159 
1160   if (num_instructions == 0 || !start.IsValid())
1161     return 0;
1162 
1163   // Calculate the max buffer size we will need in order to disassemble
1164   const addr_t byte_size = num_instructions * m_arch.GetMaximumOpcodeByteSize();
1165 
1166   if (byte_size == 0)
1167     return 0;
1168 
1169   DataBufferHeap *heap_buffer = new DataBufferHeap(byte_size, '\0');
1170   DataBufferSP data_sp(heap_buffer);
1171 
1172   Status error;
1173   lldb::addr_t load_addr = LLDB_INVALID_ADDRESS;
1174   const size_t bytes_read =
1175       target.ReadMemory(start, prefer_file_cache, heap_buffer->GetBytes(),
1176                         byte_size, error, &load_addr);
1177 
1178   const bool data_from_file = load_addr == LLDB_INVALID_ADDRESS;
1179 
1180   if (bytes_read == 0)
1181     return 0;
1182   DataExtractor data(data_sp, m_arch.GetByteOrder(),
1183                      m_arch.GetAddressByteSize());
1184 
1185   const bool append_instructions = true;
1186   DecodeInstructions(start, data, 0, num_instructions, append_instructions,
1187                      data_from_file);
1188 
1189   return m_instruction_list.GetSize();
1190 }
1191 
1192 // Disassembler copy constructor
1193 Disassembler::Disassembler(const ArchSpec &arch, const char *flavor)
1194     : m_arch(arch), m_instruction_list(), m_base_addr(LLDB_INVALID_ADDRESS),
1195       m_flavor() {
1196   if (flavor == nullptr)
1197     m_flavor.assign("default");
1198   else
1199     m_flavor.assign(flavor);
1200 
1201   // If this is an arm variant that can only include thumb (T16, T32)
1202   // instructions, force the arch triple to be "thumbv.." instead of "armv..."
1203   if (arch.IsAlwaysThumbInstructions()) {
1204     std::string thumb_arch_name(arch.GetTriple().getArchName().str());
1205     // Replace "arm" with "thumb" so we get all thumb variants correct
1206     if (thumb_arch_name.size() > 3) {
1207       thumb_arch_name.erase(0, 3);
1208       thumb_arch_name.insert(0, "thumb");
1209     }
1210     m_arch.SetTriple(thumb_arch_name.c_str());
1211   }
1212 }
1213 
1214 Disassembler::~Disassembler() = default;
1215 
1216 InstructionList &Disassembler::GetInstructionList() {
1217   return m_instruction_list;
1218 }
1219 
1220 const InstructionList &Disassembler::GetInstructionList() const {
1221   return m_instruction_list;
1222 }
1223 
1224 // Class PseudoInstruction
1225 
1226 PseudoInstruction::PseudoInstruction()
1227     : Instruction(Address(), AddressClass::eUnknown), m_description() {}
1228 
1229 PseudoInstruction::~PseudoInstruction() = default;
1230 
1231 bool PseudoInstruction::DoesBranch() {
1232   // This is NOT a valid question for a pseudo instruction.
1233   return false;
1234 }
1235 
1236 bool PseudoInstruction::HasDelaySlot() {
1237   // This is NOT a valid question for a pseudo instruction.
1238   return false;
1239 }
1240 
1241 size_t PseudoInstruction::Decode(const lldb_private::Disassembler &disassembler,
1242                                  const lldb_private::DataExtractor &data,
1243                                  lldb::offset_t data_offset) {
1244   return m_opcode.GetByteSize();
1245 }
1246 
1247 void PseudoInstruction::SetOpcode(size_t opcode_size, void *opcode_data) {
1248   if (!opcode_data)
1249     return;
1250 
1251   switch (opcode_size) {
1252   case 8: {
1253     uint8_t value8 = *((uint8_t *)opcode_data);
1254     m_opcode.SetOpcode8(value8, eByteOrderInvalid);
1255     break;
1256   }
1257   case 16: {
1258     uint16_t value16 = *((uint16_t *)opcode_data);
1259     m_opcode.SetOpcode16(value16, eByteOrderInvalid);
1260     break;
1261   }
1262   case 32: {
1263     uint32_t value32 = *((uint32_t *)opcode_data);
1264     m_opcode.SetOpcode32(value32, eByteOrderInvalid);
1265     break;
1266   }
1267   case 64: {
1268     uint64_t value64 = *((uint64_t *)opcode_data);
1269     m_opcode.SetOpcode64(value64, eByteOrderInvalid);
1270     break;
1271   }
1272   default:
1273     break;
1274   }
1275 }
1276 
1277 void PseudoInstruction::SetDescription(llvm::StringRef description) {
1278   m_description = std::string(description);
1279 }
1280 
1281 Instruction::Operand Instruction::Operand::BuildRegister(ConstString &r) {
1282   Operand ret;
1283   ret.m_type = Type::Register;
1284   ret.m_register = r;
1285   return ret;
1286 }
1287 
1288 Instruction::Operand Instruction::Operand::BuildImmediate(lldb::addr_t imm,
1289                                                           bool neg) {
1290   Operand ret;
1291   ret.m_type = Type::Immediate;
1292   ret.m_immediate = imm;
1293   ret.m_negative = neg;
1294   return ret;
1295 }
1296 
1297 Instruction::Operand Instruction::Operand::BuildImmediate(int64_t imm) {
1298   Operand ret;
1299   ret.m_type = Type::Immediate;
1300   if (imm < 0) {
1301     ret.m_immediate = -imm;
1302     ret.m_negative = true;
1303   } else {
1304     ret.m_immediate = imm;
1305     ret.m_negative = false;
1306   }
1307   return ret;
1308 }
1309 
1310 Instruction::Operand
1311 Instruction::Operand::BuildDereference(const Operand &ref) {
1312   Operand ret;
1313   ret.m_type = Type::Dereference;
1314   ret.m_children = {ref};
1315   return ret;
1316 }
1317 
1318 Instruction::Operand Instruction::Operand::BuildSum(const Operand &lhs,
1319                                                     const Operand &rhs) {
1320   Operand ret;
1321   ret.m_type = Type::Sum;
1322   ret.m_children = {lhs, rhs};
1323   return ret;
1324 }
1325 
1326 Instruction::Operand Instruction::Operand::BuildProduct(const Operand &lhs,
1327                                                         const Operand &rhs) {
1328   Operand ret;
1329   ret.m_type = Type::Product;
1330   ret.m_children = {lhs, rhs};
1331   return ret;
1332 }
1333 
1334 std::function<bool(const Instruction::Operand &)>
1335 lldb_private::OperandMatchers::MatchBinaryOp(
1336     std::function<bool(const Instruction::Operand &)> base,
1337     std::function<bool(const Instruction::Operand &)> left,
1338     std::function<bool(const Instruction::Operand &)> right) {
1339   return [base, left, right](const Instruction::Operand &op) -> bool {
1340     return (base(op) && op.m_children.size() == 2 &&
1341             ((left(op.m_children[0]) && right(op.m_children[1])) ||
1342              (left(op.m_children[1]) && right(op.m_children[0]))));
1343   };
1344 }
1345 
1346 std::function<bool(const Instruction::Operand &)>
1347 lldb_private::OperandMatchers::MatchUnaryOp(
1348     std::function<bool(const Instruction::Operand &)> base,
1349     std::function<bool(const Instruction::Operand &)> child) {
1350   return [base, child](const Instruction::Operand &op) -> bool {
1351     return (base(op) && op.m_children.size() == 1 && child(op.m_children[0]));
1352   };
1353 }
1354 
1355 std::function<bool(const Instruction::Operand &)>
1356 lldb_private::OperandMatchers::MatchRegOp(const RegisterInfo &info) {
1357   return [&info](const Instruction::Operand &op) {
1358     return (op.m_type == Instruction::Operand::Type::Register &&
1359             (op.m_register == ConstString(info.name) ||
1360              op.m_register == ConstString(info.alt_name)));
1361   };
1362 }
1363 
1364 std::function<bool(const Instruction::Operand &)>
1365 lldb_private::OperandMatchers::FetchRegOp(ConstString &reg) {
1366   return [&reg](const Instruction::Operand &op) {
1367     if (op.m_type != Instruction::Operand::Type::Register) {
1368       return false;
1369     }
1370     reg = op.m_register;
1371     return true;
1372   };
1373 }
1374 
1375 std::function<bool(const Instruction::Operand &)>
1376 lldb_private::OperandMatchers::MatchImmOp(int64_t imm) {
1377   return [imm](const Instruction::Operand &op) {
1378     return (op.m_type == Instruction::Operand::Type::Immediate &&
1379             ((op.m_negative && op.m_immediate == (uint64_t)-imm) ||
1380              (!op.m_negative && op.m_immediate == (uint64_t)imm)));
1381   };
1382 }
1383 
1384 std::function<bool(const Instruction::Operand &)>
1385 lldb_private::OperandMatchers::FetchImmOp(int64_t &imm) {
1386   return [&imm](const Instruction::Operand &op) {
1387     if (op.m_type != Instruction::Operand::Type::Immediate) {
1388       return false;
1389     }
1390     if (op.m_negative) {
1391       imm = -((int64_t)op.m_immediate);
1392     } else {
1393       imm = ((int64_t)op.m_immediate);
1394     }
1395     return true;
1396   };
1397 }
1398 
1399 std::function<bool(const Instruction::Operand &)>
1400 lldb_private::OperandMatchers::MatchOpType(Instruction::Operand::Type type) {
1401   return [type](const Instruction::Operand &op) { return op.m_type == type; };
1402 }
1403