blob: 397c36fcd92c09045cc34a14052543082a3faa7f [file] [log] [blame]
// Copyright 2013 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "syzygy/pe/transforms/pe_coff_add_imports_transform.h"
#include "gtest/gtest.h"
namespace pe {
namespace transforms {
namespace {
using block_graph::BlockGraph;
class TestPECoffAddImportsTransform : public PECoffAddImportsTransform {
public:
using PECoffAddImportsTransform::UpdateModule;
using PECoffAddImportsTransform::UpdateModuleSymbolInfo;
using PECoffAddImportsTransform::UpdateModuleSymbolReference;
};
} // namespace
TEST(ImportedModuleTest, UniqueSymbol) {
ImportedModule module("foo");
size_t i1 = module.AddSymbol("bar", ImportedModule::kFindOnly);
EXPECT_EQ(ImportedModule::kFindOnly, module.GetSymbolMode(i1));
// The mode should be 'bumped', but the symbol index should be the same.
size_t i2 = module.AddSymbol("bar", ImportedModule::kAlwaysImport);
EXPECT_EQ(ImportedModule::kAlwaysImport, module.GetSymbolMode(i1));
EXPECT_EQ(i1, i2);
}
TEST(ImportedModuleTest, BeforeTransform) {
ImportedModule module("foo");
EXPECT_EQ("foo", module.name());
EXPECT_EQ(0, module.size());
EXPECT_EQ(ImportedModule::kFindOnly, module.mode());
size_t froboz1 = module.AddSymbol("froboz1", ImportedModule::kFindOnly);
EXPECT_EQ(ImportedModule::kFindOnly, module.mode());
size_t bar1 = module.AddSymbol("bar1", ImportedModule::kAlwaysImport);
EXPECT_EQ(ImportedModule::kAlwaysImport, module.mode());
size_t froboz2 = module.AddSymbol("froboz2", ImportedModule::kFindOnly);
EXPECT_EQ(3, module.size());
EXPECT_EQ("froboz1", module.GetSymbolName(froboz1));
EXPECT_EQ("bar1", module.GetSymbolName(bar1));
EXPECT_EQ("froboz2", module.GetSymbolName(froboz2));
EXPECT_EQ(ImportedModule::kFindOnly, module.GetSymbolMode(froboz1));
EXPECT_EQ(ImportedModule::kAlwaysImport, module.GetSymbolMode(bar1));
EXPECT_EQ(ImportedModule::kFindOnly, module.GetSymbolMode(froboz2));
}
TEST(ImportedModuleTest, WithDate) {
ImportedModule module("abcd", 0xABCD);
EXPECT_EQ("abcd", module.name());
EXPECT_EQ(0xABCD, module.date());
EXPECT_EQ(0, module.size());
}
TEST(ImportedModuleTest, AfterTransform) {
ImportedModule module("foo");
EXPECT_EQ("foo", module.name());
EXPECT_EQ(0, module.size());
size_t froboz1 = module.AddSymbol("froboz1", ImportedModule::kFindOnly);
size_t bar1 = module.AddSymbol("bar1", ImportedModule::kAlwaysImport);
size_t froboz2 = module.AddSymbol("froboz2", ImportedModule::kFindOnly);
EXPECT_EQ(3, module.size());
TestPECoffAddImportsTransform transform;
EXPECT_EQ(0, transform.modules_added());
transform.AddModule(&module);
// modules_added() is for modules that were added to the import table, not
// by AddModule(), hence it should still return zero.
EXPECT_EQ(0, transform.modules_added());
TestPECoffAddImportsTransform::UpdateModule(true, true, &module);
EXPECT_TRUE(module.ModuleIsImported());
EXPECT_TRUE(module.ModuleWasAdded());
TestPECoffAddImportsTransform::UpdateModuleSymbolInfo(bar1, true,
true, &module);
EXPECT_TRUE(module.SymbolIsImported(bar1));
EXPECT_TRUE(module.SymbolWasAdded(bar1));
BlockGraph block_graph;
BlockGraph::Block* some_block =
block_graph.AddBlock(BlockGraph::CODE_BLOCK, 0x100, "some_block");
BlockGraph::Reference ref(BlockGraph::ABSOLUTE_REF, 4, some_block, 0, 0);
TestPECoffAddImportsTransform::UpdateModuleSymbolReference(bar1, ref,
true, &module);
BlockGraph::Reference actual_ref;
bool is_ptr = false;
ASSERT_TRUE(module.GetSymbolReference(bar1, &actual_ref, &is_ptr));
EXPECT_EQ(ref, actual_ref);
EXPECT_TRUE(is_ptr);
}
} // namespace transforms
} // namespace pe