blob: d9d46f62829f4d82ee915271884f3080569e20a9 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#include <lib/arch/nop.h>
#include <string_view>
#include <gtest/gtest.h>
namespace {
#define EXPECT_BYTES_EQ(expected, actual, size) \
EXPECT_EQ(std::basic_string_view<uint8_t>(expected, size), \
std::basic_string_view<uint8_t>(actual, size))
fbl::Span<std::byte> AsBytes(uint8_t* ptr, size_t size) {
return {reinterpret_cast<std::byte*>(ptr), size};
}
TEST(NopFillTests, Arm64) {
constexpr size_t kInsnSize = 4;
// 1 instruction.
{
constexpr size_t kSize = kInsnSize;
uint8_t expected[kSize] = {0x1f, 0x20, 0x03, 0xd5};
uint8_t actual[kSize];
arch::NopFill<arch::Arm64NopTraits>(AsBytes(actual, kSize));
EXPECT_BYTES_EQ(expected, actual, kSize);
}
// 2 instructions.
{
constexpr size_t kSize = 2 * kInsnSize;
uint8_t expected[kSize] = {
0x1f, 0x20, 0x03, 0xd5, //
0x1f, 0x20, 0x03, 0xd5,
};
uint8_t actual[kSize];
arch::NopFill<arch::Arm64NopTraits>(AsBytes(actual, kSize));
EXPECT_BYTES_EQ(expected, actual, kSize);
}
// 5 instructions.
{
constexpr size_t kSize = 5 * kInsnSize;
uint8_t expected[kSize] = {
0x1f, 0x20, 0x03, 0xd5, //
0x1f, 0x20, 0x03, 0xd5, //
0x1f, 0x20, 0x03, 0xd5, //
0x1f, 0x20, 0x03, 0xd5, //
0x1f, 0x20, 0x03, 0xd5,
};
uint8_t actual[kSize];
arch::NopFill<arch::Arm64NopTraits>(AsBytes(actual, kSize));
EXPECT_BYTES_EQ(expected, actual, kSize);
}
// 10 instructions.
{
constexpr size_t kSize = 10 * kInsnSize;
uint8_t expected[kSize] = {
0x1f, 0x20, 0x03, 0xd5, //
0x1f, 0x20, 0x03, 0xd5, //
0x1f, 0x20, 0x03, 0xd5, //
0x1f, 0x20, 0x03, 0xd5, //
0x1f, 0x20, 0x03, 0xd5, //
0x1f, 0x20, 0x03, 0xd5, //
0x1f, 0x20, 0x03, 0xd5, //
0x1f, 0x20, 0x03, 0xd5, //
0x1f, 0x20, 0x03, 0xd5, //
0x1f, 0x20, 0x03, 0xd5,
};
uint8_t actual[kSize];
arch::NopFill<arch::Arm64NopTraits>(AsBytes(actual, kSize));
EXPECT_BYTES_EQ(expected, actual, kSize);
}
}
TEST(NopFillTests, X86) {
constexpr size_t kInsnSize = 1;
// 1 instruction.
{
constexpr size_t kSize = kInsnSize;
uint8_t expected[kSize] = {0x90};
uint8_t actual[kSize];
arch::NopFill<arch::X86NopTraits>(AsBytes(actual, kSize));
EXPECT_BYTES_EQ(expected, actual, kSize);
}
// 2 instructions.
{
constexpr size_t kSize = 2 * kInsnSize;
uint8_t expected[kSize] = {0x66, 0x90};
uint8_t actual[kSize];
arch::NopFill<arch::X86NopTraits>(AsBytes(actual, kSize));
EXPECT_BYTES_EQ(expected, actual, kSize);
}
// 3 instructions.
{
constexpr size_t kSize = 3 * kInsnSize;
uint8_t expected[kSize] = {0x0f, 0x1f, 0x00};
uint8_t actual[kSize];
arch::NopFill<arch::X86NopTraits>(AsBytes(actual, kSize));
EXPECT_BYTES_EQ(expected, actual, kSize);
}
// 4 instructions.
{
constexpr size_t kSize = 4 * kInsnSize;
uint8_t expected[kSize] = {0x0f, 0x1f, 0x40, 0x00};
uint8_t actual[kSize];
arch::NopFill<arch::X86NopTraits>(AsBytes(actual, kSize));
EXPECT_BYTES_EQ(expected, actual, kSize);
}
// 5 instructions.
{
constexpr size_t kSize = 5 * kInsnSize;
uint8_t expected[kSize] = {0x0f, 0x1f, 0x44, 0x00, 0x00};
uint8_t actual[kSize];
arch::NopFill<arch::X86NopTraits>(AsBytes(actual, kSize));
EXPECT_BYTES_EQ(expected, actual, kSize);
}
// 6 instructions.
{
constexpr size_t kSize = 6 * kInsnSize;
uint8_t expected[kSize] = {0x66, 0x0f, 0x1f, 0x44, 0x00, 0x00};
uint8_t actual[kSize];
arch::NopFill<arch::X86NopTraits>(AsBytes(actual, kSize));
EXPECT_BYTES_EQ(expected, actual, kSize);
}
// 7 instructions.
{
constexpr size_t kSize = 7 * kInsnSize;
uint8_t expected[kSize] = {0x0f, 0x1f, 0x80, 0x00, 0x00, 0x00, 0x00};
uint8_t actual[kSize];
arch::NopFill<arch::X86NopTraits>(AsBytes(actual, kSize));
EXPECT_BYTES_EQ(expected, actual, kSize);
}
// 8 instructions.
{
constexpr size_t kSize = 8 * kInsnSize;
uint8_t expected[kSize] = {0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t actual[kSize];
arch::NopFill<arch::X86NopTraits>(AsBytes(actual, kSize));
EXPECT_BYTES_EQ(expected, actual, kSize);
}
// 9 instructions.
{
constexpr size_t kSize = 9 * kInsnSize;
uint8_t expected[kSize] = {0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t actual[kSize];
arch::NopFill<arch::X86NopTraits>(AsBytes(actual, kSize));
EXPECT_BYTES_EQ(expected, actual, kSize);
}
// 10 instructions.
{
constexpr size_t kSize = 10 * kInsnSize;
uint8_t expected[kSize] = {0x66, 0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t actual[kSize];
arch::NopFill<arch::X86NopTraits>(AsBytes(actual, kSize));
EXPECT_BYTES_EQ(expected, actual, kSize);
}
// 11 instructions.
{
constexpr size_t kSize = 11 * kInsnSize;
uint8_t expected[kSize] = {0x66, 0x66, 0x66, 0x0f, 0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t actual[kSize];
arch::NopFill<arch::X86NopTraits>(AsBytes(actual, kSize));
EXPECT_BYTES_EQ(expected, actual, kSize);
}
// 12 instructions.
{
constexpr size_t kSize = 12 * kInsnSize;
uint8_t expected[kSize] = {0x66, 0x66, 0x66, 0x66, 0x0f, 0x1f,
0x84, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t actual[kSize];
arch::NopFill<arch::X86NopTraits>(AsBytes(actual, kSize));
EXPECT_BYTES_EQ(expected, actual, kSize);
}
// 13 instructions.
{
constexpr size_t kSize = 13 * kInsnSize;
uint8_t expected[kSize] = {0x66, 0x66, 0x66, 0x66, 0x66, 0x0f, 0x1f,
0x84, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t actual[kSize];
arch::NopFill<arch::X86NopTraits>(AsBytes(actual, kSize));
EXPECT_BYTES_EQ(expected, actual, kSize);
}
// 14 instructions.
{
constexpr size_t kSize = 14 * kInsnSize;
uint8_t expected[kSize] = {0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x0f,
0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t actual[kSize];
arch::NopFill<arch::X86NopTraits>(AsBytes(actual, kSize));
EXPECT_BYTES_EQ(expected, actual, kSize);
}
// 15 instructions.
{
constexpr size_t kSize = 15 * kInsnSize;
uint8_t expected[kSize] = {0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x0f,
0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00};
uint8_t actual[kSize];
arch::NopFill<arch::X86NopTraits>(AsBytes(actual, kSize));
EXPECT_BYTES_EQ(expected, actual, kSize);
}
// 50 instructions.
{
constexpr size_t kSize = 50 * kInsnSize;
uint8_t expected[kSize] = {
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x0f,
0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, // Size-15 nop.
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x0f,
0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, // Size-15 nop.
0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x66, 0x0f,
0x1f, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00, // Size-15 nop.
0x0f, 0x1f, 0x44, 0x00, 0x00, // Size-5 nop.
};
uint8_t actual[kSize];
arch::NopFill<arch::X86NopTraits>(AsBytes(actual, kSize));
EXPECT_BYTES_EQ(expected, actual, kSize);
}
}
} // namespace