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

Unified 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, 1 month 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 side-by-side diff with in-line comments
Download patch
Index: syzygy/refinery/analyzers/type_propagator_analyzer.cc
diff --git a/syzygy/refinery/analyzers/type_propagator_analyzer.cc b/syzygy/refinery/analyzers/type_propagator_analyzer.cc
new file mode 100644
index 0000000000000000000000000000000000000000..d3e6787ace6cf8da55996d36dd2e93f7d7de8ccc
--- /dev/null
+++ b/syzygy/refinery/analyzers/type_propagator_analyzer.cc
@@ -0,0 +1,164 @@
+// Copyright 2015 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "syzygy/refinery/analyzers/type_propagator_analyzer.h"
+
+#include <queue>
+
+#include "syzygy/refinery/process_state/process_state_util.h"
+#include "syzygy/refinery/process_state/refinery.pb.h"
+#include "syzygy/refinery/types/type.h"
+
+namespace refinery {
+
+// static
+const char TypePropagatorAnalyzer::kTypePropagatorAnalyzerName[] =
+ "TypePropagatorAnalyzer";
+
+TypePropagatorAnalyzer::TypePropagatorAnalyzer(
+ scoped_refptr<SymbolProvider> symbol_provider)
+ : symbol_provider_(symbol_provider) {
+ DCHECK(symbol_provider.get() != nullptr);
+}
+
+Analyzer::AnalysisResult TypePropagatorAnalyzer::Analyze(
+ const minidump::Minidump& minidump,
+ ProcessState* process_state) {
+ DCHECK(process_state != nullptr);
+
+ // Bytes and typed block layer must be present.
+ BytesLayerPtr bytes_layer;
+ if (!process_state->FindLayer(&bytes_layer)) {
+ LOG(ERROR) << "Missing bytes layer.";
+ return ANALYSIS_ERROR;
+ }
+ TypedBlockLayerPtr typed_layer;
+ if (!process_state->FindLayer(&typed_layer)) {
+ LOG(ERROR) << "Missing typed block layer.";
+ 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
+ }
+
+ ModuleLayerAccessor accessor(process_state);
+
+ std::queue<TypedData> process_queue;
+
+ // Recover typed data from the typed block layer.
+ for (TypedBlockRecordPtr rec : *typed_layer) {
+ const TypedBlock& typedblock = rec->data();
+
+ // Recover the type.
+ pe::PEFile::Signature signature;
+ if (!accessor.GetModuleSignature(typedblock.module_id(), &signature))
+ return ANALYSIS_ERROR;
+
+ scoped_refptr<TypeRepository> type_repository;
+ if (!symbol_provider_->FindOrCreateTypeRepository(signature,
+ &type_repository)) {
+ return ANALYSIS_ERROR;
+ }
+
+ TypePtr type = type_repository->GetType(typedblock.type_id());
+ if (type == nullptr)
+ return ANALYSIS_ERROR;
+
+ // Queue typed data for processing.
+ 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
+ }
+
+ // Process typed data looking for pointers or contained pointers.
+ while (!process_queue.empty()) {
+ if (!AnalyzeTypedData(process_queue.front(), process_state))
+ return ANALYSIS_ERROR;
+ process_queue.pop();
+ }
+
+ 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
+}
+
+bool TypePropagatorAnalyzer::AnalyzeTypedData(const TypedData& typed_data,
+ ProcessState* process_state) {
+ DCHECK(process_state != nullptr);
+
+ TypePtr type = typed_data.type();
+ DCHECK(type.get());
+
+ switch (type->kind()) {
+ case Type::USER_DEFINED_TYPE_KIND:
+ return AnalyzeTypedDataUDT(typed_data, process_state);
+ case Type::POINTER_TYPE_KIND:
+ return AnalyzeTypedDataPointer(typed_data, process_state);
+ case Type::ARRAY_TYPE_KIND:
+ return AnalyzeTypedDataArray(typed_data, process_state);
+ case Type::BASIC_TYPE_KIND:
+ case Type::FUNCTION_TYPE_KIND:
+ case Type::GLOBAL_TYPE_KIND:
+ case Type::WILDCARD_TYPE_KIND:
+ // Nothing to do with these.
+ return true;
+ default:
+ DCHECK(false);
+ return false;
+ }
+}
+
+bool TypePropagatorAnalyzer::AnalyzeTypedDataUDT(const TypedData& typed_data,
+ ProcessState* process_state) {
+ DCHECK_EQ(Type::USER_DEFINED_TYPE_KIND, typed_data.type()->kind());
+ DCHECK(process_state != nullptr);
+
+ // 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.
+
+ return true;
+}
+
+bool TypePropagatorAnalyzer::AnalyzeTypedDataPointer(
+ const TypedData& typed_data,
+ ProcessState* process_state) {
+ DCHECK_EQ(Type::POINTER_TYPE_KIND, typed_data.type()->kind());
+ DCHECK(process_state != nullptr);
+
+ TypedData content_data;
+ typed_data.Dereference(&content_data);
+
+ if (!AddTypedBlock(content_data, process_state))
+ return false;
+
+ return AnalyzeTypedData(content_data, process_state);
+}
+
+bool TypePropagatorAnalyzer::AnalyzeTypedDataArray(
+ const TypedData& typed_data,
+ ProcessState* process_state) {
+ DCHECK_EQ(Type::ARRAY_TYPE_KIND, typed_data.type()->kind());
+ DCHECK(process_state != nullptr);
+
+ // TODO(manzagop): implement.
+ return true;
+}
+
+bool TypePropagatorAnalyzer::AddTypedBlock(const TypedData& typed_data,
+ ProcessState* process_state) {
+ ModuleLayerAccessor accessor(process_state);
+ pe::PEFile::Signature signature;
+ if (!typed_data.type()->repository()->GetModuleSignature(&signature))
+ return false;
+ ModuleId module_id = accessor.GetModuleId(signature);
+ if (module_id == kNoModuleId)
+ return false;
+
+ return AddTypedBlockRecord(typed_data.GetRange(), L"", module_id,
+ typed_data.type()->type_id(), process_state);
+}
+
+} // namespace refinery

Powered by Google App Engine
This is Rietveld 408576698