1 : // Copyright 2015 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 : #include "syzygy/refinery/analyzers/analyzer_factory.h"
16 :
17 : #include "syzygy/refinery/analyzers/exception_analyzer.h"
18 : #include "syzygy/refinery/analyzers/heap_analyzer.h"
19 : #include "syzygy/refinery/analyzers/memory_analyzer.h"
20 : #include "syzygy/refinery/analyzers/module_analyzer.h"
21 : #include "syzygy/refinery/analyzers/stack_analyzer.h"
22 : #include "syzygy/refinery/analyzers/stack_frame_analyzer.h"
23 : #include "syzygy/refinery/analyzers/teb_analyzer.h"
24 : #include "syzygy/refinery/analyzers/thread_analyzer.h"
25 : #include "syzygy/refinery/analyzers/type_propagator_analyzer.h"
26 : #include "syzygy/refinery/analyzers/unloaded_module_analyzer.h"
27 :
28 m : namespace refinery {
29 :
30 : // The list of analyzers known to the AnalyzerFactory. Add new analyzers here.
31 : #define ANALYZER_LIST(DECL) \
32 m : DECL(Exception) \
33 m : DECL(Heap) \
34 m : DECL(Memory) \
35 m : DECL(Module) \
36 m : DECL(Stack) \
37 m : DECL(StackFrame) \
38 m : DECL(Teb) \
39 m : DECL(Thread) \
40 m : DECL(TypePropagator) \
41 m : DECL(UnloadedModule)
42 :
43 m : namespace {
44 m : typedef const ProcessState::LayerEnum* (*GetLayersFunction)();
45 :
46 m : struct AnalyzerDescription {
47 m : const char* name;
48 m : GetLayersFunction input_layers;
49 m : GetLayersFunction output_layers;
50 m : };
51 :
52 m : const AnalyzerDescription kKnownAnalyzers[] = {
53 : #define DECLARE_KNOWN_ANALYZER(analyzer_name) \
54 m : { \
55 m : #analyzer_name "Analyzer", &analyzer_name##Analyzer::InputLayers, \
56 m : &analyzer_name##Analyzer::OutputLayers, \
57 m : } \
58 m : ,
59 m :
60 m : ANALYZER_LIST(DECLARE_KNOWN_ANALYZER)
61 m :
62 m : #undef DECLARE_KNOWN_ANALYZER
63 m : };
64 m :
65 m : bool CopyLayers(GetLayersFunction fn, AnalyzerFactory::Layers* layers) {
66 m : DCHECK(fn);
67 m : DCHECK(layers);
68 m :
69 m : const ProcessState::LayerEnum* l = fn();
70 m : if (l == nullptr)
71 m : return false;
72 m :
73 m : for (; *l != ProcessState::UnknownLayer; ++l)
74 m : layers->push_back(*l);
75 m :
76 m : return true;
77 m : }
78 m :
79 m : bool HasLayer(AnalyzerFactory::Layer layer, GetLayersFunction fn) {
80 m : DCHECK_NE(ProcessState::UnknownLayer, layer);
81 m : DCHECK(fn);
82 m :
83 m : const ProcessState::LayerEnum* l = fn();
84 m : if (l == nullptr)
85 m : return false;
86 m :
87 m : for (; *l != ProcessState::UnknownLayer; ++l) {
88 m : if (*l == layer)
89 m : return true;
90 m : }
91 m :
92 m : return false;
93 m : }
94 m :
95 m : } // namespace
96 m :
97 m : void StaticAnalyzerFactory::GetAnalyzerNames(AnalyzerNames* names) const {
98 m : DCHECK(names);
99 m :
100 m : names->clear();
101 m : for (const auto& dep : kKnownAnalyzers)
102 m : names->push_back(dep.name);
103 m : }
104 m :
105 m : Analyzer* StaticAnalyzerFactory::CreateAnalyzer(
106 m : const base::StringPiece& name) const {
107 m : #define CREATE_ANALYZER(analyzer_name) \
108 m : if (name == #analyzer_name "Analyzer") \
109 m : return new analyzer_name##Analyzer();
110 m :
111 m : ANALYZER_LIST(CREATE_ANALYZER)
112 m :
113 m : #undef CREATE_ANALYZER
114 m :
115 m : return nullptr;
116 m : }
117 m :
118 m : bool StaticAnalyzerFactory::GetInputLayers(const base::StringPiece& name,
119 m : Layers* layers) const {
120 m : DCHECK(layers);
121 m : layers->clear();
122 m :
123 m : for (const auto& dep : kKnownAnalyzers) {
124 m : if (name == dep.name)
125 m : return CopyLayers(dep.input_layers, layers);
126 m : }
127 m :
128 m : return false;
129 m : }
130 m :
131 m : bool StaticAnalyzerFactory::GetOutputLayers(const base::StringPiece& name,
132 m : Layers* layers) const {
133 m : DCHECK(layers);
134 m : layers->clear();
135 m :
136 m : for (const auto& dep : kKnownAnalyzers) {
137 m : if (name == dep.name)
138 m : return CopyLayers(dep.output_layers, layers);
139 m : }
140 m :
141 m : return false;
142 m : }
143 m :
144 m : void StaticAnalyzerFactory::GetAnalyzersOutputting(
145 m : Layer layer,
146 m : AnalyzerNames* analyzer_names) const {
147 m : DCHECK_NE(ProcessState::UnknownLayer, layer);
148 m : DCHECK(analyzer_names);
149 m : analyzer_names->clear();
150 m :
151 m : for (const auto& dep : kKnownAnalyzers) {
152 m : if (HasLayer(layer, dep.output_layers))
153 m : analyzer_names->push_back(dep.name);
154 m : }
155 m : }
156 m :
157 m : void StaticAnalyzerFactory::GetAnalyzersInputting(
158 m : Layer layer,
159 m : AnalyzerNames* analyzer_names) const {
160 m : DCHECK_NE(ProcessState::UnknownLayer, layer);
161 m : DCHECK(analyzer_names);
162 m : analyzer_names->clear();
163 m :
164 m : for (const auto& dep : kKnownAnalyzers) {
165 m : if (HasLayer(layer, dep.input_layers))
166 m : analyzer_names->push_back(dep.name);
167 m : }
168 m : }
169 m :
170 m : } // namespace refinery
|