| Index: syzygy/experimental/protect/protect_lib/protect_utils.cc
|
| diff --git a/syzygy/instrument/instrumenters/flummox_instrumenter.cc b/syzygy/experimental/protect/protect_lib/protect_utils.cc
|
| similarity index 52%
|
| copy from syzygy/instrument/instrumenters/flummox_instrumenter.cc
|
| copy to syzygy/experimental/protect/protect_lib/protect_utils.cc
|
| index d749504c5aec01390c64294e562bd82308de2cb7..c4015960dcd129b8704206278c7a311dc1a7c13c 100644
|
| --- a/syzygy/instrument/instrumenters/flummox_instrumenter.cc
|
| +++ b/syzygy/experimental/protect/protect_lib/protect_utils.cc
|
| @@ -1,138 +1,152 @@
|
| -// 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/instrument/instrumenters/flummox_instrumenter.h"
|
| -
|
| -#include <algorithm>
|
| -#include <sstream>
|
| -
|
| -#include "base/values.h"
|
| -#include "base/files/file_util.h"
|
| -#include "base/json/json_reader.h"
|
| -#include "base/strings/string_util.h"
|
| -#include "syzygy/application/application.h"
|
| -
|
| -namespace instrument {
|
| -namespace instrumenters {
|
| -
|
| -namespace {
|
| -
|
| -using base::DictionaryValue;
|
| -using base::ListValue;
|
| -using base::Value;
|
| -
|
| -} // namespace
|
| -
|
| -bool FlummoxInstrumenter::FlummoxConfig::ReadFromJSON(const std::string& json) {
|
| - bool input_add_copy = false;
|
| - scoped_ptr<Value> value(base::JSONReader::Read(json));
|
| - if (value.get() == nullptr) {
|
| - LOG(ERROR) << "Invalid or empty configuration JSON.";
|
| - return false;
|
| - }
|
| - if (value->GetType() != Value::TYPE_DICTIONARY) {
|
| - LOG(ERROR) << "Invalid allocation filter transform file.";
|
| - return false;
|
| - }
|
| -
|
| - const DictionaryValue* outer_dict =
|
| - reinterpret_cast<const DictionaryValue*>(value.get());
|
| -
|
| - std::string targets_key("targets");
|
| - const DictionaryValue* targets_dict = nullptr;
|
| -
|
| - if (!outer_dict->GetDictionary(targets_key, &targets_dict)) {
|
| - LOG(ERROR) << "Outer dictionary must contain key 'targets'.";
|
| - return false;
|
| - }
|
| -
|
| - std::set<std::string> temp_target_set;
|
| - DictionaryValue::Iterator it(*targets_dict);
|
| - for (; !it.IsAtEnd(); it.Advance()) {
|
| - std::string function_name = it.key();
|
| - const ListValue* strategy_list = nullptr;
|
| - if (!it.value().GetAsList(&strategy_list)) {
|
| - LOG(ERROR) << "Strategy list expected.";
|
| - return false;
|
| - }
|
| - // TODO(huangs): Load strategies.
|
| - // for (const Value* strategy : *strategy_list) { }
|
| - temp_target_set.insert(function_name);
|
| - }
|
| -
|
| - std::string add_copy_key("add_copy");
|
| - if (outer_dict->HasKey(add_copy_key) &&
|
| - !outer_dict->GetBoolean(add_copy_key, &input_add_copy)) {
|
| - LOG(ERROR) << add_copy_key << " must be a boolean.";
|
| - return false;
|
| - }
|
| -
|
| - // Success!
|
| - target_set_.swap(temp_target_set);
|
| - add_copy_ = input_add_copy;
|
| - return true;
|
| -}
|
| -
|
| -bool FlummoxInstrumenter::FlummoxConfig::ReadFromJSONPath(
|
| - const base::FilePath& path) {
|
| - std::string file_string;
|
| - if (!base::ReadFileToString(path, &file_string)) {
|
| - LOG(ERROR) << "Unable to read file to string.";
|
| - return false;
|
| - }
|
| - if (!ReadFromJSON(file_string)) {
|
| - LOG(ERROR) << "Unable to parse JSON string.";
|
| - return false;
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -bool FlummoxInstrumenter::InstrumentPrepare() {
|
| - return config_.ReadFromJSONPath(flummox_config_path_);
|
| -}
|
| -
|
| -bool FlummoxInstrumenter::InstrumentImpl() {
|
| - flummox_transform_.reset(
|
| - new instrument::transforms::FillerTransform(
|
| - config_.target_set(), config_.add_copy()));
|
| - flummox_transform_->set_debug_friendly(debug_friendly_);
|
| -
|
| - if (!relinker_->AppendTransform(flummox_transform_.get())) {
|
| - LOG(ERROR) << "Failed to apply transform.";
|
| - return false;
|
| - }
|
| -
|
| - return true;
|
| -}
|
| -
|
| -bool FlummoxInstrumenter::DoCommandLineParse(
|
| - const base::CommandLine* command_line) {
|
| - DCHECK(command_line != nullptr);
|
| -
|
| - if (!Super::DoCommandLineParse(command_line))
|
| - return false;
|
| -
|
| - // Parse the target list filename.
|
| - flummox_config_path_ = application::AppImplBase::AbsolutePath(
|
| - command_line->GetSwitchValuePath("flummox-config-path"));
|
| - if (flummox_config_path_.empty()) {
|
| - LOG(ERROR) << "You must specify --flummox-config-path.";
|
| - return false;
|
| - }
|
| -
|
| - return true;
|
| -}
|
| -
|
| -} // namespace instrumenters
|
| -} // namespace instrument
|
| +// 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/experimental/protect/protect_lib/protect_utils.h"
|
| +
|
| +#include "base/values.h"
|
| +#include "base/json/json_reader.h"
|
| +
|
| +namespace protect {
|
| +
|
| +bool ShouldProcessBlock(const BlockGraph::Block* block,
|
| + const std::map<std::string, bool> target_names) {
|
| + return (target_names.find(block->name()) != target_names.end());
|
| +}
|
| +bool ShouldPostProcessBlock(
|
| + const BlockGraph::Block* block,
|
| + const std::map<uint64_t, BlockGraph::Label> *id_to_label) {
|
| + if (block->labels().size() == 0) return false;
|
| + if (GetBasicBlockIdByLabel(block->labels().begin()->second,
|
| + id_to_label) == -1) {
|
| + return false;
|
| + }
|
| + return true;
|
| +}
|
| +uint64_t GetBasicBlockIdByLabel(
|
| + const BlockGraph::Label label,
|
| + const std::map<uint64_t, BlockGraph::Label> *id_to_label){
|
| + auto it = id_to_label->begin();
|
| + for (; it != id_to_label->end(); ++it) {
|
| + if (it->second == label)
|
| + return it->first;
|
| + }
|
| +
|
| + return (uint64_t)-1;
|
| +}
|
| +
|
| +void GetChunkTokensFromlabel(const std::string label,
|
| + uint64_t *chunk_bb_id,
|
| + uint32_t *chunk_index){
|
| + //split the string
|
| + std::istringstream iss(label);
|
| + std::vector<std::string> tokens;
|
| + copy(std::istream_iterator<std::string>(iss),
|
| + std::istream_iterator<std::string>(),
|
| + back_inserter(tokens)
|
| + );
|
| + DCHECK(tokens.size() > 2);
|
| + *chunk_bb_id = std::stoull(tokens.at(1));
|
| + *chunk_index = std::stoul(tokens.at(2));
|
| +}
|
| +
|
| +uint64_t GetChunkUniqueKey(const uint64_t bb_id, const uint32_t chunk_index){
|
| + return std::hash<std::string>()(std::to_string(bb_id)
|
| + + std::to_string(chunk_index));
|
| +}
|
| +
|
| +using base::DictionaryValue;
|
| +using base::ListValue;
|
| +using base::Value;
|
| +
|
| +bool FlummoxConfig::ReadFromJSON(const std::string& json) {
|
| + bool input_add_copy = false;
|
| + double input_chunk_coverage = 1.0;
|
| +
|
| + scoped_ptr<Value> value(base::JSONReader::Read(json));
|
| + if (value.get() == nullptr) {
|
| + LOG(ERROR) << "Invalid or empty configuration JSON.";
|
| + return false;
|
| + }
|
| + if (value->GetType() != Value::TYPE_DICTIONARY) {
|
| + LOG(ERROR) << "Invalid allocation filter transform file.";
|
| + return false;
|
| + }
|
| +
|
| + const DictionaryValue* outer_dict =
|
| + reinterpret_cast<const DictionaryValue*>(value.get());
|
| +
|
| +
|
| + std::string chunk_coverage_key("chunk_coverage");
|
| + if (outer_dict->HasKey(chunk_coverage_key) &&
|
| + !outer_dict->GetDouble(chunk_coverage_key, &input_chunk_coverage)) {
|
| + LOG(ERROR) << chunk_coverage_key << " must be a double.";
|
| + return false;
|
| + }
|
| + if (input_chunk_coverage > 10.0 || input_chunk_coverage < 0.0) {
|
| + LOG(ERROR) << chunk_coverage_key << " must be between [0.0,10.0] .";
|
| + return false;
|
| + }
|
| +
|
| +
|
| + std::string targets_key("targets");
|
| + const DictionaryValue* targets_dict = nullptr;
|
| +
|
| + if (!outer_dict->GetDictionary(targets_key, &targets_dict)) {
|
| + LOG(ERROR) << "Outer dictionary must contain key 'targets'.";
|
| + return false;
|
| + }
|
| +
|
| + std::set<std::string> temp_target_set;
|
| + DictionaryValue::Iterator it(*targets_dict);
|
| + for (; !it.IsAtEnd(); it.Advance()) {
|
| + std::string function_name = it.key();
|
| + const ListValue* strategy_list = nullptr;
|
| + if (!it.value().GetAsList(&strategy_list)) {
|
| + LOG(ERROR) << "Strategy list expected.";
|
| + return false;
|
| + }
|
| + // TODO(huangs): Load strategies.
|
| + // for (const Value* strategy : *strategy_list) { }
|
| + temp_target_set.insert(function_name);
|
| + }
|
| +
|
| + std::string add_copy_key("add_copy");
|
| + if (outer_dict->HasKey(add_copy_key) &&
|
| + !outer_dict->GetBoolean(add_copy_key, &input_add_copy)) {
|
| + LOG(ERROR) << add_copy_key << " must be a boolean.";
|
| + return false;
|
| + }
|
| +
|
| +
|
| + // Success!
|
| + target_set_.swap(temp_target_set);
|
| + add_copy_ = input_add_copy;
|
| + chunk_checking_coverage_ = input_chunk_coverage;
|
| + return true;
|
| +}
|
| +
|
| +bool FlummoxConfig::ReadFromJSONPath(
|
| + const base::FilePath& path) {
|
| + std::string file_string;
|
| + if (!base::ReadFileToString(path, &file_string)) {
|
| + LOG(ERROR) << "Unable to read file to string.";
|
| + return false;
|
| + }
|
| + if (!ReadFromJSON(file_string)) {
|
| + LOG(ERROR) << "Unable to parse JSON string.";
|
| + return false;
|
| + }
|
| + return true;
|
| +}
|
| +
|
| +} // namespace protect
|
|
|