blob: cc27020ea32ebe464447cf902bb28d57b025fe18 [file] [log] [blame]
// Copyright 2011 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/core/address.h"
#include "gtest/gtest.h"
#include "syzygy/core/unittest_util.h"
namespace core {
TEST(AddressTest, DefaultInitialization) {
EXPECT_EQ(0, RelativeAddress().value());
EXPECT_EQ(0, AbsoluteAddress().value());
EXPECT_EQ(0, FileOffsetAddress().value());
}
TEST(AddressTest, CreateInitialialized) {
const size_t kAddress = 0xCAFEBABE;
EXPECT_EQ(kAddress, RelativeAddress(kAddress).value());
EXPECT_EQ(kAddress, AbsoluteAddress(kAddress).value());
EXPECT_EQ(kAddress, FileOffsetAddress(kAddress).value());
}
TEST(AddressTest, Operators) {
const RelativeAddress kOne(1);
const RelativeAddress kTwo(2);
const RelativeAddress kThree(3);
EXPECT_TRUE(kOne < kTwo);
EXPECT_FALSE(kOne < kOne);
EXPECT_FALSE(kTwo < kOne);
EXPECT_TRUE(kOne <= kOne);
EXPECT_TRUE(kOne <= kTwo);
EXPECT_FALSE(kTwo <= kOne);
EXPECT_FALSE(kOne > kTwo);
EXPECT_TRUE(kTwo > kOne);
RelativeAddress addr(kOne);
EXPECT_TRUE(kOne == addr);
EXPECT_FALSE(addr == kTwo);
EXPECT_TRUE(kOne + 1 == kTwo);
EXPECT_TRUE(kOne == kTwo - 1);
EXPECT_EQ(1, kTwo - kOne);
EXPECT_EQ(1, addr.value());
addr.set_value(2);
EXPECT_EQ(2, addr.value());
addr += 1;
EXPECT_TRUE(addr == kThree);
addr -= 1;
EXPECT_TRUE(addr == kTwo);
}
TEST(AddressTest, AlignUp) {
const RelativeAddress one(1);
const RelativeAddress two(2);
const RelativeAddress four(4);
const RelativeAddress eight(8);
const RelativeAddress sixteen(16);
EXPECT_EQ(one.AlignUp(1), one);
EXPECT_EQ(one.AlignUp(2), two);
EXPECT_EQ(one.AlignUp(4), four);
EXPECT_EQ(one.AlignUp(8), eight);
EXPECT_EQ(one.AlignUp(16), sixteen);
EXPECT_TRUE(one.AlignUp(1).IsAligned(1));
EXPECT_TRUE(one.AlignUp(2).IsAligned(2));
EXPECT_TRUE(one.AlignUp(4).IsAligned(4));
EXPECT_TRUE(one.AlignUp(8).IsAligned(8));
EXPECT_TRUE(one.AlignUp(16).IsAligned(16));
}
TEST(AddressTest, GetAlignment) {
const uint32_t max_alignment = 0x80000000;
const RelativeAddress zero(0);
EXPECT_EQ(max_alignment, zero.GetAlignment());
const RelativeAddress one(1);
for (uint32_t i = 1; i < max_alignment; i <<= 1) {
RelativeAddress address(i);
EXPECT_EQ(i, address.GetAlignment());
}
RelativeAddress max_address(max_alignment);
EXPECT_EQ(max_alignment, max_address.GetAlignment());
}
TEST(AddressTest, Serialization) {
const RelativeAddress address(42);
EXPECT_TRUE(testing::TestSerialization(address));
}
TEST(AddressTest, AddressVariant) {
AddressVariant a0;
EXPECT_EQ(kRelativeAddressType, a0.type());
EXPECT_EQ(0u, a0.value());
AddressVariant a1(kRelativeAddressType, 0);
EXPECT_EQ(kRelativeAddressType, a1.type());
EXPECT_EQ(0u, a1.value());
AddressVariant a2(kAbsoluteAddressType, 0);
EXPECT_EQ(kAbsoluteAddressType, a2.type());
EXPECT_EQ(0u, a2.value());
AddressVariant a3(kFileOffsetAddressType, 0);
EXPECT_EQ(kFileOffsetAddressType, a3.type());
EXPECT_EQ(0u, a3.value());
AddressVariant a3_copy(a3);
EXPECT_EQ(kFileOffsetAddressType, a3_copy.type());
EXPECT_EQ(0u, a3_copy.value());
EXPECT_NE(a1, a2);
EXPECT_NE(a1, a3);
EXPECT_NE(a2, a1);
EXPECT_NE(a2, a3);
EXPECT_NE(a3, a1);
EXPECT_NE(a3, a2);
// Comparisons.
EXPECT_TRUE(a1 < a2);
EXPECT_TRUE(a1 <= a3);
EXPECT_TRUE(a3 > a2);
EXPECT_TRUE(a3 >= a1);
// Mutators.
a2.set_type(kRelativeAddressType);
EXPECT_EQ(kRelativeAddressType, a2.type());
EXPECT_EQ(a1, a2);
a2.set_value(0xBAAD);
EXPECT_EQ(0xBAADu, a2.value());
a2.set_value(0);
EXPECT_EQ(0u, a2.value());
// Arithmetic operations.
a2 += 1;
EXPECT_EQ(1u, a2.value());
EXPECT_NE(a1, a2);
a2 -= 1;
EXPECT_EQ(0u, a2.value());
EXPECT_EQ(a1, a2);
a1 = a3;
EXPECT_EQ(kFileOffsetAddressType, a1.type());
EXPECT_EQ(0u, a3.value());
EXPECT_EQ(a1, a3);
a2 = a3 + 2;
EXPECT_EQ(2u, a2.value());
EXPECT_NE(a2, a3);
a3 += 2;
EXPECT_EQ(2u, a3.value());
EXPECT_EQ(a2, a3);
a3 = a3.AlignUp(4);
EXPECT_EQ(4u, a3.value());
a3 = a3.AlignUp(4);
EXPECT_EQ(4u, a3.value());
// Assignment from concrete types.
RelativeAddress rel(47);
AbsoluteAddress abso(82);
FileOffsetAddress off(13);
a1 = rel;
EXPECT_EQ(rel.type(), a1.type());
EXPECT_EQ(rel.value(), a1.value());
a2 = abso;
EXPECT_EQ(abso.type(), a2.type());
EXPECT_EQ(abso.value(), a2.value());
a3 = off;
EXPECT_EQ(off.type(), a3.type());
EXPECT_EQ(off.value(), a3.value());
// Extraction of concrete types.
RelativeAddress rel2;
AbsoluteAddress abso2;
FileOffsetAddress off2;
EXPECT_TRUE(a1.Extract(&rel2));
EXPECT_EQ(rel, rel2);
EXPECT_TRUE(a2.Extract(&abso2));
EXPECT_EQ(abso, abso2);
EXPECT_TRUE(a3.Extract(&off2));
EXPECT_EQ(off, off2);
EXPECT_FALSE(a1.Extract(&abso));
EXPECT_FALSE(a1.Extract(&off));
}
} // namespace core