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