1 : // Copyright 2012 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 : //
15 : // This defines the playback class. The class encapsulates the workflow
16 : // associated with parsing a trace file with respect to an original module.
17 : // It takes care of validating that all data sources match (trace files,
18 : // instrumented module, original module), decomposing the original module,
19 : // and provides functionality for mapping trace events back to
20 : // addresses/blocks in the original module.
21 : //
22 : // Playback playback(module_path, instrumented_path, trace_files);
23 : // playback.Init(pe_file, image, parser)
24 : // playback.ConsumeCallTraceEvents()
25 :
26 : #ifndef SYZYGY_PLAYBACK_PLAYBACK_H_
27 : #define SYZYGY_PLAYBACK_PLAYBACK_H_
28 :
29 : #include <windows.h>
30 :
31 : #include "base/win/event_trace_consumer.h"
32 : #include "sawbuck/log_lib/kernel_log_consumer.h"
33 : #include "syzygy/block_graph/block_graph.h"
34 : #include "syzygy/pdb/omap.h"
35 : #include "syzygy/pe/decomposer.h"
36 : #include "syzygy/pe/image_layout.h"
37 : #include "syzygy/trace/parse/parser.h"
38 :
39 : namespace playback {
40 :
41 : class Playback {
42 : public:
43 : typedef block_graph::BlockGraph BlockGraph;
44 : typedef pe::ImageLayout ImageLayout;
45 : typedef pe::PEFile PEFile;
46 : typedef std::vector<base::FilePath> TraceFileList;
47 : typedef trace::parser::ModuleInformation ModuleInformation;
48 : typedef trace::parser::Parser Parser;
49 :
50 : // Construct a new Playback instance.
51 : // @param module_path The path of the module dll.
52 : // @param instrumented_path The path of the instrumented dll.
53 : // @param trace_files A list of the trace files to analyze.
54 : Playback(const base::FilePath& module_path,
55 : const base::FilePath& instrumented_path,
56 : const TraceFileList& trace_files);
57 :
58 : ~Playback();
59 :
60 : // Initializes the playback class and decomposes the given image.
61 : // This function is virtual to aid testing of classes that may own Playback.
62 : // @param pe_file The PE file to be initialized.
63 : // @param image The image that will receive the decomposed module.
64 : // @param parser The parser to be used.
65 : // @returns true on success, false on failure.
66 : virtual bool Init(PEFile* pe_file, ImageLayout* image, Parser* parser);
67 :
68 : // @returns true if the given ModuleInformation matches the instrumented
69 : // module signature, false otherwise.
70 : bool MatchesInstrumentedModuleSignature(
71 : const ModuleInformation& module_info) const;
72 :
73 : // Gets a code block from our image from its function address and process id.
74 : // @param process_id The process id of the module where the function resides.
75 : // @param function The relative address of the function we are searching.
76 : // @param error Will be set to true if an error occurs.
77 : // @returns The code block @p function and @p process_id refer to, or NULL if
78 : // no such block can be found (this can occur if events for multiple
79 : // instrumented modules occur in the same trace file, and we are
80 : // processing an event from a module that is not our module of interest.)
81 : // If an error occurs this will also return NULL.
82 : const BlockGraph::Block* FindFunctionBlock(DWORD process_id,
83 : FuncAddr function,
84 : bool* error);
85 :
86 : // @name Accessors
87 : // @{
88 E : const PEFile* pe_file() const { return pe_file_; }
89 E : const ImageLayout* image() const { return image_; }
90 E : const TraceFileList& trace_files() const { return trace_files_; }
91 E : const std::vector<OMAP>& omap_to() const { return omap_to_; }
92 E : const std::vector<OMAP>& omap_from() const { return omap_from_; }
93 E : const PEFile::Signature& instr_signature() const { return instr_signature_; }
94 : // @}
95 :
96 : protected:
97 : typedef pe::Decomposer Decomposer;
98 : typedef TraceFileList::iterator TraceFileIter;
99 : typedef uint64 AbsoluteAddress64;
100 : typedef uint64 Size64;
101 :
102 : // Loads information from the instrumented and original modules.
103 : bool LoadModuleInformation();
104 : // Initializes the parser.
105 : bool InitializeParser();
106 : // Loads OMAP information for the instrumented module.
107 : bool LoadInstrumentedOmap();
108 : // Decomposes the original image.
109 : bool DecomposeImage();
110 :
111 : // Parses the instrumented DLL headers, validating that it was produced
112 : // by a compatible version of the toolchain, and extracting signature
113 : // information and metadata.
114 : // @returns true on success, false otherwise.
115 : bool ValidateInstrumentedModuleAndParseSignature(
116 : PEFile::Signature* orig_signature);
117 :
118 : // The paths of the test module, instrumented module, and trace files.
119 : base::FilePath module_path_;
120 : base::FilePath instrumented_path_;
121 : TraceFileList trace_files_;
122 :
123 : // This is a copy of the parser used to decompose the image, which needs
124 : // to be initialized with a ParseEventHandler before being used.
125 : Parser* parser_;
126 :
127 : // A pointer to the PE file info for the module we're analyzing. This
128 : // is actually a pointer to a part of the output structure, but several
129 : // internals make use of it during processing.
130 : PEFile* pe_file_;
131 :
132 : // The decomposed image of the module we're analyzing. This is actually
133 : // a pointer to an image in the output structure, but several internals
134 : // make use of it during processing.
135 : ImageLayout* image_;
136 :
137 : // The OMAP info from the instrumented module's PDB. Used for mapping
138 : // addresses back and forth between the instrumented DLL and the original DLL.
139 : std::vector<OMAP> omap_to_;
140 : std::vector<OMAP> omap_from_;
141 :
142 : // Signature of the instrumented DLL. Used for filtering call-trace events.
143 : PEFile::Signature instr_signature_;
144 : };
145 :
146 : } // namespace playback
147 :
148 : #endif // SYZYGY_PLAYBACK_PLAYBACK_H_
|