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 : // Specialization of the instrumenter interface for the instrumenters who use an
16 : // agent. This performs all the common bits of this kind of instrumenters:
17 : // - Parse the shared command-line parameters.
18 : // - Initialization the relinker.
19 : // - Default implementation of Instrument.
20 : #ifndef SYZYGY_INSTRUMENT_INSTRUMENTERS_INSTRUMENTER_WITH_AGENT_H_
21 : #define SYZYGY_INSTRUMENT_INSTRUMENTERS_INSTRUMENTER_WITH_AGENT_H_
22 :
23 : #include <string>
24 :
25 : #include "base/command_line.h"
26 : #include "syzygy/instrument/instrumenter.h"
27 : #include "syzygy/pe/coff_relinker.h"
28 : #include "syzygy/pe/pe_relinker.h"
29 :
30 : namespace instrument {
31 : namespace instrumenters {
32 :
33 : class InstrumenterWithAgent : public InstrumenterInterface {
34 : public:
35 : typedef block_graph::BlockGraph BlockGraph;
36 : typedef block_graph::BlockGraph::ImageFormat ImageFormat;
37 :
38 : InstrumenterWithAgent()
39 : : image_format_(BlockGraph::PE_IMAGE),
40 : allow_overwrite_(false),
41 : debug_friendly_(false),
42 : no_augment_pdb_(false),
43 E : no_strip_strings_(false) {
44 E : }
45 :
46 E : ~InstrumenterWithAgent() { }
47 :
48 : // @name InstrumenterInterface implementation.
49 : // @{
50 : virtual bool ParseCommandLine(const CommandLine* command_line) OVERRIDE;
51 : virtual bool Instrument() OVERRIDE;
52 : // @}
53 :
54 : // @name Accessors.
55 : // @
56 E : const std::string& agent_dll() {
57 E : return agent_dll_;
58 E : }
59 : // @}
60 :
61 : protected:
62 : // Virtual method that determines whether or not the input object file
63 : // format is supported by the instrumenter. The default implementation
64 : // supports PE files, and does not support COFF files.
65 : virtual bool ImageFormatIsSupported(ImageFormat image_format);
66 :
67 : // Virtual method that does the actual instrumentation for a given agent.
68 : // This function is meant to be called by the Instrument function.
69 : // @note The implementation should log on failure.
70 : virtual bool InstrumentImpl() = 0;
71 :
72 : // Pure virtual method that should return the name of the instrumentation
73 : // mode.
74 : virtual const char* InstrumentationMode() = 0;
75 :
76 : // Virtual method called by ParseCommandLine to parse the additional
77 : // command-line arguments specific to an instrumenter.
78 : // @param command_line the command-line to be parsed.
79 : // @returns true by default. Should return false on error.
80 : virtual bool ParseAdditionalCommandLineArguments(
81 E : const CommandLine* command_line) {
82 E : return true;
83 E : }
84 :
85 : // @name Internal machinery, replaceable for testing purposes. These will
86 : // only ever be called once per object lifetime.
87 : // @{
88 : virtual pe::PETransformPolicy* GetPETransformPolicy();
89 : virtual pe::CoffTransformPolicy* GetCoffTransformPolicy();
90 : virtual pe::PERelinker* GetPERelinker();
91 : virtual pe::CoffRelinker* GetCoffRelinker();
92 : // @}
93 :
94 : // Creates and configures a relinker. This is split out for unittesting
95 : // purposes, allowing child classes to test their InstrumentImpl functions
96 : // in isolation.
97 : bool CreateRelinker();
98 :
99 : // The agent DLL used by this instrumentation.
100 : std::string agent_dll_;
101 :
102 : // The type of image file we are transforming.
103 : ImageFormat image_format_;
104 :
105 : // @name Command-line parameters.
106 : // @{
107 : base::FilePath input_image_path_;
108 : base::FilePath input_pdb_path_;
109 : base::FilePath output_image_path_;
110 : base::FilePath output_pdb_path_;
111 : bool allow_overwrite_;
112 : bool debug_friendly_;
113 : bool no_augment_pdb_;
114 : bool no_strip_strings_;
115 : // @}
116 :
117 : // This is used to save a pointer to the object returned by the call to
118 : // Get(PE|Coff)Relinker. Ownership of the object is internal in the default
119 : // case, but may be external during tests.
120 : pe::RelinkerInterface* relinker_;
121 :
122 : private:
123 : // They are used as containers for holding policy and relinker objects that
124 : // are allocated by our default Get* implementations above.
125 : scoped_ptr<block_graph::TransformPolicyInterface> policy_object_;
126 : scoped_ptr<pe::RelinkerInterface> relinker_object_;
127 :
128 : DISALLOW_COPY_AND_ASSIGN(InstrumenterWithAgent);
129 : };
130 :
131 : } // namespace instrumenters
132 : } // namespace instrument
133 :
134 : #endif // SYZYGY_INSTRUMENT_INSTRUMENTERS_INSTRUMENTER_WITH_AGENT_H_
|