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 : // CoffAddImportsTransform is the COFF-equivalent of PEAddImportsTransform;
16 : // it adds external symbols to a COFF block graph, that can then be
17 : // referenced in calls, address computations and accesses.
18 : //
19 : // Use is similar to PEAddImportsTransform:
20 : //
21 : // // For COFF, the library name is ignored and always considered imported
22 : // // and never added. Which library (or simple object file) a symbol is
23 : // // resolved from is left to the linker. Hence, all symbols share a
24 : // // common table, which tells the linker what to look up, but not where
25 : // // to look for it.
26 : // ImportedModule foo_dll("foo.dll");
27 : // size_t foo_foo_index = foo_dll.AddSymbol("foo");
28 : // size_t foo_bar_index = foo_dll.AddSymbol("bar");
29 : //
30 : // CoffAddImportsTransform add_imports_transform;
31 : // add_imports_transform.AddModule(&foo_dll);
32 : // add_imports_transform.TransformBlockGraph(block_graph, headers_block);
33 : //
34 : // // Create a reference to function 'bar' in 'foo.dll'. If is_ptr
35 : // // is true on return of GetSymbolReference, then the reference is
36 : // // to a pointer to the actual thing (i.e., we need to handle one more
37 : // // level of indirection).
38 : // BlockGraph::Reference foo_bar_ref;
39 : // bool is_ptr = false;
40 : // CHECK(foo_dll.GetSymbolReference(foo_bar_index, &foo_bar_ref, &is_ptr));
41 : // some_block->SetReference(some_offset, foo_bar_ref);
42 :
43 : #ifndef SYZYGY_PE_TRANSFORMS_COFF_ADD_IMPORTS_TRANSFORM_H_
44 : #define SYZYGY_PE_TRANSFORMS_COFF_ADD_IMPORTS_TRANSFORM_H_
45 :
46 : #include "syzygy/block_graph/typed_block.h"
47 : #include "syzygy/block_graph/transforms/named_transform.h"
48 : #include "syzygy/pe/transforms/pe_coff_add_imports_transform.h"
49 :
50 : namespace pe {
51 : namespace transforms {
52 :
53 : using block_graph::BlockGraph;
54 : using block_graph::TransformPolicyInterface;
55 : using block_graph::transforms::NamedBlockGraphTransformImpl;
56 :
57 : // A transform for adding COFF symbols to a given block graph.
58 : class CoffAddImportsTransform
59 : : public NamedBlockGraphTransformImpl<CoffAddImportsTransform>,
60 : public PECoffAddImportsTransform {
61 : public:
62 : // A map from symbol names to indexes in the symbol table.
63 : typedef std::map<std::string, size_t> NameMap;
64 :
65 : // Construct an empty CoffAddImportsTransform, that imports nothing
66 : // initially.
67 E : CoffAddImportsTransform() {}
68 :
69 : // Perform the transform. Add entries for any missing symbols to the COFF
70 : // symbol table, and fill the attached imported module objects.
71 : //
72 : // @param policy The policy object restricting how the transform is applied.
73 : // @param block_graph the BlockGraph to populate.
74 : // @param headers_block the block containing the headers.
75 : // @returns true on success, false otherwise.
76 : virtual bool TransformBlockGraph(
77 : const TransformPolicyInterface* policy,
78 : BlockGraph* block_graph,
79 : BlockGraph::Block* headers_block) OVERRIDE;
80 :
81 : // The name of this transform.
82 : static const char kTransformName[];
83 :
84 : private:
85 : // Process all symbols in @p module as requested, adding to
86 : // @p names_to_add any symbol that needs to be imported and is not
87 : // already present.
88 : //
89 : // @param file_header the COFF file header.
90 : // @param known_names the collection of existing symbols in the current
91 : // symbol table.
92 : // @param module the module to process.
93 : // @param names_to_add the collection of new symbols that will need to be
94 : // added to the symbol table.
95 : // @param string_len_to_add incremented by the extra space (in bytes)
96 : // required to hold the added names.
97 : // @returns true on success, false on failure
98 : bool FindAndCollectSymbolsFromModule(
99 : const block_graph::TypedBlock<IMAGE_FILE_HEADER>& file_header,
100 : const NameMap& known_names,
101 : ImportedModule* module,
102 : NameMap* names_to_add,
103 : size_t* string_len_to_add);
104 :
105 : // Update all references in @p module.
106 : //
107 : // @param symbols_block the block containing the symbol table.
108 : // @param module the module to update.
109 : void UpdateModuleReferences(BlockGraph::Block* symbols_block,
110 : ImportedModule* module);
111 :
112 : DISALLOW_COPY_AND_ASSIGN(CoffAddImportsTransform);
113 : };
114 :
115 : } // namespace transforms
116 : } // namespace pe
117 :
118 : #endif // SYZYGY_PE_TRANSFORMS_COFF_ADD_IMPORTS_TRANSFORM_H_
|