Coverage for /Syzygy/instrument/instrumenters/asan_instrumenter.cc

CoverageLines executed / instrumented / missingexe / inst / missLanguageGroup
92.8%64690.C++source

Line-by-line coverage:

   1    :  // Copyright 2013 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/instrument/instrumenters/asan_instrumenter.h"
  16    :  
  17    :  #include <algorithm>
  18    :  
  19    :  #include "base/file_util.h"
  20    :  #include "base/logging.h"
  21    :  #include "syzygy/application/application.h"
  22    :  #include "syzygy/instrument/transforms/allocation_filter_transform.h"
  23    :  
  24    :  namespace {
  25    :    using instrument::transforms::AllocationFilterTransform;
  26    :  }
  27    :  
  28    :  namespace instrument {
  29    :  namespace instrumenters {
  30    :  
  31    :  const char AsanInstrumenter::kAgentDllAsan[] = "syzyasan_rtl.dll";
  32    :  
  33    :  AsanInstrumenter::AsanInstrumenter()
  34    :      : use_interceptors_(true),
  35    :        remove_redundant_checks_(true),
  36    :        use_liveness_analysis_(true),
  37    :        instrumentation_rate_(1.0),
  38  E :        asan_rtl_options_(false) {
  39  E :    agent_dll_ = kAgentDllAsan;
  40  E :  }
  41    :  
  42  E :  bool AsanInstrumenter::ImageFormatIsSupported(ImageFormat image_format) {
  43    :    if (image_format == BlockGraph::PE_IMAGE ||
  44  E :        image_format == BlockGraph::COFF_IMAGE) {
  45  E :      return true;
  46    :    }
  47  i :    return false;
  48  E :  }
  49    :  
  50  E :  bool AsanInstrumenter::InstrumentImpl() {
  51    :    // Parse the filter if one was provided.
  52  E :    scoped_ptr<pe::ImageFilter> filter;
  53  E :    if (!filter_path_.empty()) {
  54  E :      filter.reset(new pe::ImageFilter());
  55  E :      if (!filter->LoadFromJSON(filter_path_)) {
  56  i :        LOG(ERROR) << "Failed to parse filter file: " << filter_path_.value();
  57  i :        return false;
  58    :      }
  59    :  
  60    :      // Ensure it is for the input module.
  61  E :      if (!filter->IsForModule(input_image_path_)) {
  62  E :        LOG(ERROR) << "Filter does not match the input module.";
  63  E :        return false;
  64    :      }
  65    :    }
  66    :  
  67  E :    asan_transform_.reset(new instrument::transforms::AsanTransform());
  68  E :    asan_transform_->set_instrument_dll_name(agent_dll_);
  69  E :    asan_transform_->set_use_interceptors(use_interceptors_);
  70  E :    asan_transform_->set_use_liveness_analysis(use_liveness_analysis_);
  71  E :    asan_transform_->set_remove_redundant_checks(remove_redundant_checks_);
  72  E :    asan_transform_->set_instrumentation_rate(instrumentation_rate_);
  73    :  
  74    :    // Set up the filter if one was provided.
  75  E :    if (filter.get()) {
  76  E :      filter_.reset(filter.release());
  77  E :      asan_transform_->set_filter(&filter_->filter);
  78    :    }
  79    :  
  80    :    // Set overwrite source range flag in the Asan transform. The Asan
  81    :    // transformation will overwrite the source range of created instructions to
  82    :    // the source range of corresponding instrumented instructions.
  83  E :    asan_transform_->set_debug_friendly(debug_friendly_);
  84    :  
  85    :    // If RTL options were provided then pass them to the transform.
  86  E :    if (asan_rtl_options_)
  87  E :      asan_transform_->set_asan_parameters(&asan_params_);
  88    :  
  89  E :    if (!relinker_->AppendTransform(asan_transform_.get()))
  90  i :      return false;
  91    :  
  92    :    // Append the AllocationFilter transform if necessary.
  93  E :    if (af_transform_.get() != nullptr) {
  94  E :      if (!relinker_->AppendTransform(af_transform_.get()))
  95  i :        return false;
  96    :    }
  97    :  
  98  E :    return true;
  99  E :  }
 100    :  
 101    :  bool AsanInstrumenter::ParseAdditionalCommandLineArguments(
 102  E :      const CommandLine* command_line) {
 103    :    // Parse the additional command line arguments.
 104  E :    filter_path_ = command_line->GetSwitchValuePath("filter");
 105  E :    use_liveness_analysis_ = !command_line->HasSwitch("no-liveness-analysis");
 106  E :    remove_redundant_checks_ = !command_line->HasSwitch("no-redundancy-analysis");
 107  E :    use_interceptors_ = !command_line->HasSwitch("no-interceptors");
 108    :  
 109    :    // Parse the instrumentation rate if one has been provided.
 110    :    static const char kInstrumentationRate[] = "instrumentation-rate";
 111  E :    if (command_line->HasSwitch(kInstrumentationRate)) {
 112  E :      std::string s = command_line->GetSwitchValueASCII(kInstrumentationRate);
 113  E :      double d = 0;
 114  E :      if (!base::StringToDouble(s, &d)) {
 115  E :        LOG(ERROR) << "Failed to parse floating point value: " << s;
 116  E :        return false;
 117    :      }
 118    :      // Cap the rate to the range of valid values [0, 1].
 119  E :      instrumentation_rate_ = std::max(0.0, std::min(1.0, d));
 120  E :    }
 121    :  
 122    :    // Parse Asan RTL options if present.
 123    :    static const char kAsanRtlOptions[] = "asan-rtl-options";
 124  E :    if (asan_rtl_options_ = command_line->HasSwitch(kAsanRtlOptions)) {
 125  E :      std::wstring options = command_line->GetSwitchValueNative(kAsanRtlOptions);
 126  E :      common::SetDefaultAsanParameters(&asan_params_);
 127  E :      if (!common::ParseAsanParameters(options, &asan_params_))
 128  E :        return false;
 129  E :    }
 130    :  
 131    :    // Parse the allocation-filter flag.
 132    :    static const char kAsanAllocationFilter[] = "allocation-filter-config-file";
 133    :    allocation_filter_config_file_path_ = command_line->GetSwitchValuePath(
 134  E :        kAsanAllocationFilter);
 135    :  
 136    :    // Setup the AllocationFilter transform if a configuration file was specified.
 137  E :    if (!allocation_filter_config_file_path_.empty()) {
 138  E :      std::string json_string;
 139  E :      AllocationFilterTransform::FunctionNameOffsetMap target_calls;
 140    :      if (!AllocationFilterTransform::ReadFromJSON(
 141  E :        allocation_filter_config_file_path_, &target_calls)) {
 142  E :        LOG(ERROR) << "Failed to parse allocation-filter configuration file: "
 143    :                   << allocation_filter_config_file_path_.value();
 144  E :        return false;
 145    :      }
 146    :  
 147  E :      if (!target_calls.empty()) {
 148    :        // Setup the allocation-filter transform.
 149  E :        af_transform_.reset(new AllocationFilterTransform(target_calls));
 150    :  
 151    :        // Set overwrite source range flag in the AllocationFilter transform.
 152    :        // It will overwrite the source range of created instructions to the
 153    :        // source range of corresponding instrumented instructions. The
 154    :        // AllocationFilter transform shares the Asan flag.
 155  E :        af_transform_->set_debug_friendly(debug_friendly_);
 156    :      }
 157  E :    }
 158    :  
 159  E :    return true;
 160  E :  }
 161    :  
 162    :  }  // namespace instrumenters
 163    :  }  // namespace instrument

Coverage information generated Thu Mar 26 16:15:41 2015.