| Index: tools/relocation_packer/src/elf_file_unittest.cc
|
| diff --git a/tools/relocation_packer/src/elf_file_unittest.cc b/tools/relocation_packer/src/elf_file_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..d84928ea21c245a30d3fd26e690916d870846e0b
|
| --- /dev/null
|
| +++ b/tools/relocation_packer/src/elf_file_unittest.cc
|
| @@ -0,0 +1,151 @@
|
| +// Copyright 2014 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "elf_file.h"
|
| +
|
| +#include <limits.h>
|
| +#include <stdio.h>
|
| +#include <unistd.h>
|
| +#include <string>
|
| +#include <vector>
|
| +#include "debug.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +// Macro stringification.
|
| +// https://gcc.gnu.org/onlinedocs/cpp/Stringification.html
|
| +#define XSTR(S) STR(S)
|
| +#define STR(S) #S
|
| +
|
| +namespace {
|
| +
|
| +void GetDataFilePath(const char* name, std::string* path) {
|
| + std::string data_dir;
|
| +
|
| + const char* bindir = getenv("bindir");
|
| + if (bindir) {
|
| + data_dir = std::string(bindir);
|
| + } else {
|
| + // Test data is in the gyp INTERMEDIATE_DIR subdirectory of the directory
|
| + // that contains the current binary.
|
| + char path[PATH_MAX];
|
| + memset(path, 0, sizeof(path));
|
| + ASSERT_NE(-1, readlink("/proc/self/exe", path, sizeof(path) - 1));
|
| +
|
| + data_dir = std::string(path);
|
| + size_t pos = data_dir.rfind('/');
|
| + ASSERT_NE(std::string::npos, pos);
|
| +
|
| + data_dir.erase(pos + 1);
|
| + data_dir += std::string(XSTR(INTERMEDIATE_DIR));
|
| + }
|
| +
|
| + *path = data_dir + "/" + name;
|
| +}
|
| +
|
| +void OpenRelocsTestFile(const char* name, FILE** stream) {
|
| + std::string path;
|
| + GetDataFilePath(name, &path);
|
| +
|
| + FILE* testfile = fopen(path.c_str(), "rb");
|
| + ASSERT_FALSE(testfile == NULL);
|
| +
|
| + FILE* temporary = tmpfile();
|
| + ASSERT_FALSE(temporary == NULL);
|
| +
|
| + static const size_t buffer_size = 4096;
|
| + unsigned char buffer[buffer_size];
|
| +
|
| + size_t bytes;
|
| + do {
|
| + bytes = fread(buffer, 1, sizeof(buffer), testfile);
|
| + ASSERT_EQ(bytes, fwrite(buffer, 1, bytes, temporary));
|
| + } while (bytes > 0);
|
| +
|
| + ASSERT_EQ(0, fclose(testfile));
|
| + ASSERT_EQ(0, fseek(temporary, 0, SEEK_SET));
|
| + ASSERT_EQ(0, lseek(fileno(temporary), 0, SEEK_SET));
|
| +
|
| + *stream = temporary;
|
| +}
|
| +
|
| +void OpenRelocsTestFiles(FILE** relocs_so, FILE** packed_relocs_so) {
|
| + OpenRelocsTestFile("elf_file_unittest_relocs.so", relocs_so);
|
| + OpenRelocsTestFile("elf_file_unittest_relocs_packed.so", packed_relocs_so);
|
| +}
|
| +
|
| +void CloseRelocsTestFile(FILE* temporary) {
|
| + fclose(temporary);
|
| +}
|
| +
|
| +void CloseRelocsTestFiles(FILE* relocs_so, FILE* packed_relocs_so) {
|
| + CloseRelocsTestFile(relocs_so);
|
| + CloseRelocsTestFile(packed_relocs_so);
|
| +}
|
| +
|
| +void CheckFileContentsEqual(FILE* first, FILE* second) {
|
| + ASSERT_EQ(0, fseek(first, 0, SEEK_SET));
|
| + ASSERT_EQ(0, fseek(second, 0, SEEK_SET));
|
| +
|
| + static const size_t buffer_size = 4096;
|
| + unsigned char first_buffer[buffer_size];
|
| + unsigned char second_buffer[buffer_size];
|
| +
|
| + do {
|
| + size_t first_read = fread(first_buffer, 1, sizeof(first_buffer), first);
|
| + size_t second_read = fread(second_buffer, 1, sizeof(second_buffer), second);
|
| +
|
| + EXPECT_EQ(first_read, second_read);
|
| + EXPECT_EQ(0, memcmp(first_buffer, second_buffer, first_read));
|
| + } while (!feof(first) && !feof(second));
|
| +
|
| + EXPECT_TRUE(feof(first) && feof(second));
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +namespace relocation_packer {
|
| +
|
| +TEST(ElfFile, PackRelocations) {
|
| + ASSERT_NE(EV_NONE, elf_version(EV_CURRENT));
|
| +
|
| + FILE* relocs_so = NULL;
|
| + FILE* packed_relocs_so = NULL;
|
| + OpenRelocsTestFiles(&relocs_so, &packed_relocs_so);
|
| + if (HasFatalFailure())
|
| + return;
|
| +
|
| + ElfFile elf_file(fileno(relocs_so));
|
| +
|
| + // Ensure unpacking fails (not packed).
|
| + EXPECT_FALSE(elf_file.UnpackRelocations());
|
| +
|
| + // Pack relocations, and check files are now identical.
|
| + EXPECT_TRUE(elf_file.PackRelocations());
|
| + CheckFileContentsEqual(relocs_so, packed_relocs_so);
|
| +
|
| + CloseRelocsTestFiles(relocs_so, packed_relocs_so);
|
| +}
|
| +
|
| +TEST(ElfFile, UnpackRelocations) {
|
| + ASSERT_NE(EV_NONE, elf_version(EV_CURRENT));
|
| +
|
| + FILE* relocs_so = NULL;
|
| + FILE* packed_relocs_so = NULL;
|
| + OpenRelocsTestFiles(&relocs_so, &packed_relocs_so);
|
| + if (HasFatalFailure())
|
| + return;
|
| +
|
| + ElfFile elf_file(fileno(packed_relocs_so));
|
| +
|
| + // Ensure packing fails (already packed).
|
| + EXPECT_FALSE(elf_file.PackRelocations());
|
| +
|
| + // Unpack golden relocations, and check files are now identical.
|
| + EXPECT_TRUE(elf_file.UnpackRelocations());
|
| + CheckFileContentsEqual(packed_relocs_so, relocs_so);
|
| +
|
| + CloseRelocsTestFiles(relocs_so, packed_relocs_so);
|
| +}
|
| +
|
| +} // namespace relocation_packer
|
|
|