Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1)

Side by Side Diff: syzygy/refinery/analyzers/type_propagator_analyzer.cc

Issue 1475083002: [Refinery] Introduce TypePropagatorAnalyzer - pointer types. (Closed) Base URL: https://github.com/google/syzygy.git@master
Patch Set: Nits Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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/type_propagator_analyzer.h"
16
17 #include <queue>
18
19 #include "syzygy/refinery/process_state/process_state_util.h"
20 #include "syzygy/refinery/process_state/refinery.pb.h"
21 #include "syzygy/refinery/types/type.h"
22
23 namespace refinery {
24
25 // static
26 const char TypePropagatorAnalyzer::kTypePropagatorAnalyzerName[] =
27 "TypePropagatorAnalyzer";
28
29 TypePropagatorAnalyzer::TypePropagatorAnalyzer(
30 scoped_refptr<SymbolProvider> symbol_provider)
31 : symbol_provider_(symbol_provider) {
32 DCHECK(symbol_provider.get() != nullptr);
33 }
34
35 Analyzer::AnalysisResult TypePropagatorAnalyzer::Analyze(
36 const minidump::Minidump& minidump,
37 ProcessState* process_state) {
38 DCHECK(process_state != nullptr);
39
40 // Bytes and typed block layer must be present.
41 BytesLayerPtr bytes_layer;
42 if (!process_state->FindLayer(&bytes_layer)) {
43 LOG(ERROR) << "Missing bytes layer.";
44 return ANALYSIS_ERROR;
45 }
46 TypedBlockLayerPtr typed_layer;
47 if (!process_state->FindLayer(&typed_layer)) {
48 LOG(ERROR) << "Missing typed block layer.";
49 return ANALYSIS_ERROR;
Sigurður Ásgeirsson 2015/11/26 21:45:12 Is this an error, or just unexpected?
manzagop (departed) 2015/11/27 15:20:28 I'm using this as a proxy for "StackFrameAnalyzer
50 }
51
52 ModuleLayerAccessor accessor(process_state);
53
54 std::queue<TypedData> process_queue;
55
56 // Recover typed data from the typed block layer.
57 for (TypedBlockRecordPtr rec : *typed_layer) {
58 const TypedBlock& typedblock = rec->data();
59
60 // Recover the type.
61 pe::PEFile::Signature signature;
62 if (!accessor.GetModuleSignature(typedblock.module_id(), &signature))
63 return ANALYSIS_ERROR;
64
65 scoped_refptr<TypeRepository> type_repository;
66 if (!symbol_provider_->FindOrCreateTypeRepository(signature,
67 &type_repository)) {
68 return ANALYSIS_ERROR;
69 }
70
71 TypePtr type = type_repository->GetType(typedblock.type_id());
72 if (type == nullptr)
73 return ANALYSIS_ERROR;
74
75 // Queue typed data for processing.
76 process_queue.emplace(process_state, type, rec->range().start());
Sigurður Ásgeirsson 2015/11/26 21:45:12 nit: I don't think we're allowed emplace just yet?
manzagop (departed) 2015/11/27 15:20:28 Haha. I'd actually checked and seen "Use where ele
77 }
78
79 // Process typed data looking for pointers or contained pointers.
80 while (!process_queue.empty()) {
81 if (!AnalyzeTypedData(process_queue.front(), process_state))
82 return ANALYSIS_ERROR;
83 process_queue.pop();
84 }
85
86 return ANALYSIS_COMPLETE;
Sigurður Ásgeirsson 2015/11/26 21:45:12 Hmmm - I think you want to iterate here until stab
manzagop (departed) 2015/11/27 15:20:28 As you guessed, there's recursion in AnalyzeTypedD
Sigurður Ásgeirsson 2015/11/27 15:33:40 That's not quite the same thing. A single iteratio
manzagop (departed) 2015/11/27 18:17:03 As discussed, there's currently recursion that goe
87 }
88
89 bool TypePropagatorAnalyzer::AnalyzeTypedData(const TypedData& typed_data,
90 ProcessState* process_state) {
91 DCHECK(process_state != nullptr);
92
93 TypePtr type = typed_data.type();
94 DCHECK(type.get());
95
96 switch (type->kind()) {
97 case Type::USER_DEFINED_TYPE_KIND:
98 return AnalyzeTypedDataUDT(typed_data, process_state);
99 case Type::POINTER_TYPE_KIND:
100 return AnalyzeTypedDataPointer(typed_data, process_state);
101 case Type::ARRAY_TYPE_KIND:
102 return AnalyzeTypedDataArray(typed_data, process_state);
103 case Type::BASIC_TYPE_KIND:
104 case Type::FUNCTION_TYPE_KIND:
105 case Type::GLOBAL_TYPE_KIND:
106 case Type::WILDCARD_TYPE_KIND:
107 // Nothing to do with these.
108 return true;
109 default:
110 DCHECK(false);
111 return false;
112 }
113 }
114
115 bool TypePropagatorAnalyzer::AnalyzeTypedDataUDT(const TypedData& typed_data,
116 ProcessState* process_state) {
117 DCHECK_EQ(Type::USER_DEFINED_TYPE_KIND, typed_data.type()->kind());
118 DCHECK(process_state != nullptr);
119
120 // TODO(manzagop): implement.
Sigurður Ásgeirsson 2015/11/26 21:45:12 aha - this is where you'd recurse?
manzagop (departed) 2015/11/27 15:20:28 That is correct.
121
122 return true;
123 }
124
125 bool TypePropagatorAnalyzer::AnalyzeTypedDataPointer(
126 const TypedData& typed_data,
127 ProcessState* process_state) {
128 DCHECK_EQ(Type::POINTER_TYPE_KIND, typed_data.type()->kind());
129 DCHECK(process_state != nullptr);
130
131 TypedData content_data;
132 typed_data.Dereference(&content_data);
133
134 if (!AddTypedBlock(content_data, process_state))
135 return false;
136
137 return AnalyzeTypedData(content_data, process_state);
138 }
139
140 bool TypePropagatorAnalyzer::AnalyzeTypedDataArray(
141 const TypedData& typed_data,
142 ProcessState* process_state) {
143 DCHECK_EQ(Type::ARRAY_TYPE_KIND, typed_data.type()->kind());
144 DCHECK(process_state != nullptr);
145
146 // TODO(manzagop): implement.
147 return true;
148 }
149
150 bool TypePropagatorAnalyzer::AddTypedBlock(const TypedData& typed_data,
151 ProcessState* process_state) {
152 ModuleLayerAccessor accessor(process_state);
153 pe::PEFile::Signature signature;
154 if (!typed_data.type()->repository()->GetModuleSignature(&signature))
155 return false;
156 ModuleId module_id = accessor.GetModuleId(signature);
157 if (module_id == kNoModuleId)
158 return false;
159
160 return AddTypedBlockRecord(typed_data.GetRange(), L"", module_id,
161 typed_data.type()->type_id(), process_state);
162 }
163
164 } // namespace refinery
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698