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 |