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 "base/file_util.h"
18 : #include "base/logging.h"
19 : #include "syzygy/common/application.h"
20 : #include "syzygy/pe/image_filter.h"
21 :
22 : namespace instrument {
23 : namespace instrumenters {
24 :
25 : const char AsanInstrumenter::kAgentDllAsan[] = "asan_rtl.dll";
26 :
27 : AsanInstrumenter::AsanInstrumenter()
28 : : use_liveness_analysis_(false),
29 E : remove_redundant_checks_(false) {
30 E : agent_dll_ = kAgentDllAsan;
31 E : }
32 :
33 E : bool AsanInstrumenter::InstrumentImpl() {
34 : // Parse the filter if one was provided.
35 E : scoped_ptr<pe::ImageFilter> filter;
36 E : if (!filter_path_.empty()) {
37 i : filter.reset(new pe::ImageFilter());
38 i : if (!filter->LoadFromJSON(filter_path_)) {
39 i : LOG(ERROR) << "Failed to parse filter file: " << filter_path_.value();
40 i : return false;
41 : }
42 :
43 : // Ensure it is for the input module.
44 i : if (!filter->IsForModule(input_dll_path_)) {
45 i : LOG(ERROR) << "Filter does not match the input module.";
46 i : return false;
47 : }
48 : }
49 :
50 E : asan_transform_.reset(new instrument::transforms::AsanTransform());
51 E : asan_transform_->set_instrument_dll_name(agent_dll_);
52 E : asan_transform_->set_use_liveness_analysis(use_liveness_analysis_);
53 E : asan_transform_->set_remove_redundant_checks(remove_redundant_checks_);
54 :
55 : // Set up the filter if one was provided.
56 E : if (filter.get())
57 i : asan_transform_->set_filter(&filter->filter);
58 :
59 : // Set overwrite source range flag in the ASAN transform. The ASAN
60 : // transformation will overwrite the source range of created instructions to
61 : // the source range of corresponding instrumented instructions.
62 E : asan_transform_->set_debug_friendly(debug_friendly_);
63 :
64 E : relinker_->AppendTransform(asan_transform_.get());
65 :
66 E : return true;
67 E : }
68 :
69 : bool AsanInstrumenter::ParseAdditionalCommandLineArguments(
70 E : const CommandLine* command_line) {
71 : // Parse the additional command line arguments.
72 E : filter_path_ = command_line->GetSwitchValuePath("filter");
73 E : use_liveness_analysis_ = command_line->HasSwitch("use-liveness-analysis");
74 E : remove_redundant_checks_ = command_line->HasSwitch("remove-redundant-checks");
75 :
76 E : return true;
77 E : }
78 :
79 : } // namespace instrumenters
80 : } // namespace instrument
|