blob: f09e51d30005f6c434bc70ffe91e77f787918a9d [file] [log] [blame]
// Copyright 2012 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/pdb/omap.h"
#include "base/path_service.h"
#include "gtest/gtest.h"
#include "syzygy/core/unittest_util.h"
#include "syzygy/pdb/unittest_util.h"
namespace pdb {
using core::RelativeAddress;
TEST(OmapTest, CreateOmap) {
OMAP omap = CreateOmap(523, 644);
EXPECT_EQ(523u, omap.rva);
EXPECT_EQ(644u, omap.rvaTo);
}
TEST(OmapTest, OmapLess) {
OMAP omap1 = CreateOmap(0, 0);
OMAP omap2 = CreateOmap(1, 1);
OMAP omap3 = CreateOmap(1, 2);
EXPECT_TRUE(OmapLess(omap1, omap2));
EXPECT_FALSE(OmapLess(omap2, omap1));
EXPECT_FALSE(OmapLess(omap1, omap1));
EXPECT_FALSE(OmapLess(omap2, omap2));
EXPECT_FALSE(OmapLess(omap2, omap3));
EXPECT_FALSE(OmapLess(omap3, omap2));
}
TEST(OmapTest, OmapVectorIsValid) {
std::vector<OMAP> omaps;
EXPECT_TRUE(OmapVectorIsValid(omaps));
omaps.push_back(CreateOmap(0, 0));
EXPECT_TRUE(OmapVectorIsValid(omaps));
omaps.push_back(CreateOmap(1, 0));
EXPECT_TRUE(OmapVectorIsValid(omaps));
omaps.push_back(CreateOmap(1, 1));
EXPECT_FALSE(OmapVectorIsValid(omaps));
omaps.back().rva = 0;
EXPECT_FALSE(OmapVectorIsValid(omaps));
}
TEST(OmapTest, Translate) {
std::vector<OMAP> omaps;
// We create mapping that sends [1000, 2000) to [2000, 3000) and
// [2000, 3000) to [1000, 2000). Addresses < 1000 and >= 3000 remain fixed.
omaps.push_back(CreateOmap(1000, 2000));
omaps.push_back(CreateOmap(2000, 1000));
omaps.push_back(CreateOmap(3000, 3000));
ASSERT_TRUE(OmapVectorIsValid(omaps));
// Try a mapping in each of the 4 distinct regions that the OMAP vector
// imposes on the address space.
EXPECT_EQ(RelativeAddress(500),
TranslateAddressViaOmap(omaps, RelativeAddress(500)));
EXPECT_EQ(RelativeAddress(2500),
TranslateAddressViaOmap(omaps, RelativeAddress(1500)));
EXPECT_EQ(RelativeAddress(1500),
TranslateAddressViaOmap(omaps, RelativeAddress(2500)));
EXPECT_EQ(RelativeAddress(3500),
TranslateAddressViaOmap(omaps, RelativeAddress(3500)));
}
TEST(OmapTest, ReadOmapsFromPdbFile) {
std::vector<OMAP> omap_to, omap_from;
// We only test ReadOmapsFromPdbFile as this wraps ReadOmapsFromPdbReader and
// inherently tests both.
// We expect this to be false, as the original test_dll has no OMAP
// information in it.
base::FilePath pdb_path = testing::GetSrcRelativePath(
testing::kTestDllFilePath);
EXPECT_FALSE(ReadOmapsFromPdbFile(pdb_path, NULL, NULL));
pdb_path = testing::GetSrcRelativePath(
testing::kOmappedTestPdbFilePath);
EXPECT_TRUE(ReadOmapsFromPdbFile(pdb_path, NULL, NULL));
EXPECT_TRUE(ReadOmapsFromPdbFile(pdb_path, NULL, &omap_from));
EXPECT_FALSE(omap_from.empty());
EXPECT_TRUE(ReadOmapsFromPdbFile(pdb_path, &omap_to, NULL));
EXPECT_FALSE(omap_to.empty());
EXPECT_TRUE(ReadOmapsFromPdbFile(pdb_path, &omap_to, &omap_from));
EXPECT_FALSE(omap_to.empty());
EXPECT_FALSE(omap_from.empty());
// Some additional testing to ensure reusing a PdbFile works.
PdbReader pdb_reader;
PdbFile pdb_file;
ASSERT_TRUE(pdb_reader.Read(pdb_path, &pdb_file));
ASSERT_TRUE(ReadOmapsFromPdbFile(pdb_file, &omap_to, &omap_from));
ASSERT_TRUE(ReadOmapsFromPdbFile(pdb_file, &omap_to, &omap_from));
}
} // namespace pdb