1 //===-- TraceDumper.h -------------------------------------------*- C++ -*-===//
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/Target/TraceCursor.h"
10 
11 #include "lldb/Symbol/SymbolContext.h"
12 
13 #ifndef LLDB_TARGET_TRACE_INSTRUCTION_DUMPER_H
14 #define LLDB_TARGET_TRACE_INSTRUCTION_DUMPER_H
15 
16 namespace lldb_private {
17 
18 /// Class that holds the configuration used by \a TraceDumper for
19 /// traversing and dumping instructions.
20 struct TraceDumperOptions {
21   /// If \b true, the cursor will be iterated forwards starting from the
22   /// oldest instruction. Otherwise, the iteration starts from the most
23   /// recent instruction.
24   bool forwards = false;
25   /// Dump only instruction addresses without disassembly nor symbol
26   /// information.
27   bool raw = false;
28   /// Dump in json format.
29   bool json = false;
30   /// When dumping in JSON format, pretty print the output.
31   bool pretty_print_json = false;
32   /// For each trace item, print the corresponding timestamp in nanoseconds if
33   /// available.
34   bool show_timestamps = false;
35   /// Dump the events that happened between instructions.
36   bool show_events = false;
37   /// For each instruction, print the instruction kind.
38   bool show_control_flow_kind = false;
39   /// Optional custom id to start traversing from.
40   llvm::Optional<uint64_t> id = llvm::None;
41   /// Optional number of instructions to skip from the starting position
42   /// of the cursor.
43   llvm::Optional<size_t> skip = llvm::None;
44 };
45 
46 /// Class used to dump the instructions of a \a TraceCursor using its current
47 /// state and granularity.
48 class TraceDumper {
49 public:
50   /// Helper struct that holds symbol, disassembly and address information of an
51   /// instruction.
52   struct SymbolInfo {
53     SymbolContext sc;
54     Address address;
55     lldb::DisassemblerSP disassembler;
56     lldb::InstructionSP instruction;
57     lldb_private::ExecutionContext exe_ctx;
58   };
59 
60   /// Helper struct that holds all the information we know about a trace item
61   struct TraceItem {
62     lldb::user_id_t id;
63     lldb::addr_t load_address;
64     llvm::Optional<double> timestamp;
65     llvm::Optional<uint64_t> hw_clock;
66     llvm::Optional<llvm::StringRef> error;
67     llvm::Optional<lldb::TraceEvent> event;
68     llvm::Optional<SymbolInfo> symbol_info;
69     llvm::Optional<SymbolInfo> prev_symbol_info;
70     llvm::Optional<lldb::cpu_id_t> cpu_id;
71   };
72 
73   /// Interface used to abstract away the format in which the instruction
74   /// information will be dumped.
75   class OutputWriter {
76   public:
77     virtual ~OutputWriter() = default;
78 
79     /// Notify this writer that the cursor ran out of data.
80     virtual void NoMoreData() {}
81 
82     /// Dump a trace item (instruction, error or event).
83     virtual void TraceItem(const TraceItem &item) = 0;
84   };
85 
86   /// Create a instruction dumper for the cursor.
87   ///
88   /// \param[in] cursor
89   ///     The cursor whose instructions will be dumped.
90   ///
91   /// \param[in] s
92   ///     The stream where to dump the instructions to.
93   ///
94   /// \param[in] options
95   ///     Additional options for configuring the dumping.
96   TraceDumper(lldb::TraceCursorUP &&cursor_up, Stream &s,
97               const TraceDumperOptions &options);
98 
99   /// Dump \a count instructions of the thread trace starting at the current
100   /// cursor position.
101   ///
102   /// This effectively moves the cursor to the next unvisited position, so that
103   /// a subsequent call to this method continues where it left off.
104   ///
105   /// \param[in] count
106   ///     The number of instructions to print.
107   ///
108   /// \return
109   ///     The instruction id of the last traversed instruction, or \b llvm::None
110   ///     if no instructions were visited.
111   llvm::Optional<lldb::user_id_t> DumpInstructions(size_t count);
112 
113 private:
114   /// Create a trace item for the current position without symbol information.
115   TraceItem CreatRawTraceItem();
116 
117   lldb::TraceCursorUP m_cursor_up;
118   TraceDumperOptions m_options;
119   std::unique_ptr<OutputWriter> m_writer_up;
120 };
121 
122 } // namespace lldb_private
123 
124 #endif // LLDB_TARGET_TRACE_INSTRUCTION_DUMPER_H
125