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/coff_utils.h"
49 : #include "syzygy/pe/transforms/pe_coff_add_imports_transform.h"
50 :
51 : namespace pe {
52 : namespace transforms {
53 :
54 : using block_graph::BlockGraph;
55 : using block_graph::TransformPolicyInterface;
56 : using block_graph::transforms::NamedBlockGraphTransformImpl;
57 :
58 : // A transform for adding COFF symbols to a given block graph.
59 : class CoffAddImportsTransform
60 : : public NamedBlockGraphTransformImpl<CoffAddImportsTransform>,
61 : public PECoffAddImportsTransform {
62 : public:
63 : // Construct an empty CoffAddImportsTransform, that imports nothing
64 : // initially.
65 E : CoffAddImportsTransform() {}
66 :
67 : // Perform the transform. Add entries for any missing symbols to the COFF
68 : // symbol table, and fill the attached imported module objects.
69 : //
70 : // @param policy The policy object restricting how the transform is applied.
71 : // @param block_graph the BlockGraph to populate.
72 : // @param headers_block the block containing the headers.
73 : // @returns true on success, false otherwise.
74 : virtual bool TransformBlockGraph(const TransformPolicyInterface* policy,
75 : BlockGraph* block_graph,
76 : BlockGraph::Block* headers_block) override;
77 :
78 : // The name of this transform.
79 : static const char kTransformName[];
80 :
81 : private:
82 : // Process all symbols in @p module as requested, adding to
83 : // @p names_to_add any symbol that needs to be imported and is not
84 : // already present.
85 : //
86 : // @param file_header the COFF file header.
87 : // @param known_names the collection of existing symbols in the current
88 : // symbol table.
89 : // @param module the module to process.
90 : // @param names_to_add the collection of new symbols that will need to be
91 : // added to the symbol table.
92 : // @param string_len_to_add incremented by the extra space (in bytes)
93 : // required to hold the added names.
94 : // @returns true on success, false on failure
95 : bool FindAndCollectSymbolsFromModule(
96 : const block_graph::TypedBlock<IMAGE_FILE_HEADER>& file_header,
97 : const CoffSymbolNameOffsetMap& known_names,
98 : ImportedModule* module,
99 : CoffSymbolNameOffsetMap* names_to_add,
100 : size_t* string_len_to_add);
101 :
102 : // Update all references in @p module.
103 : //
104 : // @param symbols_block the block containing the symbol table.
105 : // @param module the module to update.
106 : void UpdateModuleReferences(BlockGraph::Block* symbols_block,
107 : ImportedModule* module);
108 :
109 : typedef std::pair<ImportedModule*, size_t> ModuleSymbol;
110 : typedef std::map<ModuleSymbol, BlockGraph::Offset> ModuleSymbolOffsetMap;
111 : ModuleSymbolOffsetMap module_symbol_offset_map_;
112 :
113 : DISALLOW_COPY_AND_ASSIGN(CoffAddImportsTransform);
114 : };
115 :
116 : } // namespace transforms
117 : } // namespace pe
118 :
119 : #endif // SYZYGY_PE_TRANSFORMS_COFF_ADD_IMPORTS_TRANSFORM_H_
|