Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / tools / relocation_packer / src / elf_file_unittest.cc
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "elf_file.h"
6
7 #include <limits.h>
8 #include <stdio.h>
9 #include <unistd.h>
10 #include <string>
11 #include <vector>
12 #include "debug.h"
13 #include "elf_traits.h"
14 #include "testing/gtest/include/gtest/gtest.h"
15
16 // Macro stringification.
17 // https://gcc.gnu.org/onlinedocs/cpp/Stringification.html
18 #define XSTR(S) STR(S)
19 #define STR(S) #S
20
21 namespace {
22
23 void GetDataFilePath(const char* name, std::string* path) {
24   std::string data_dir;
25
26   const char* bindir = getenv("bindir");
27   if (bindir) {
28     data_dir = std::string(bindir);
29   } else {
30     // Test data is in the gyp INTERMEDIATE_DIR subdirectory of the directory
31     // that contains the current binary.
32     char path[PATH_MAX];
33     memset(path, 0, sizeof(path));
34     ASSERT_NE(-1, readlink("/proc/self/exe", path, sizeof(path) - 1));
35
36     data_dir = std::string(path);
37     size_t pos = data_dir.rfind('/');
38     ASSERT_NE(std::string::npos, pos);
39
40     data_dir.erase(pos + 1);
41     data_dir += std::string(XSTR(INTERMEDIATE_DIR));
42   }
43
44   *path = data_dir + "/" + name;
45 }
46
47 void OpenRelocsTestFile(const char* name, FILE** stream) {
48   std::string path;
49   GetDataFilePath(name, &path);
50
51   FILE* testfile = fopen(path.c_str(), "rb");
52   ASSERT_FALSE(testfile == NULL);
53
54   FILE* temporary = tmpfile();
55   ASSERT_FALSE(temporary == NULL);
56
57   static const size_t buffer_size = 4096;
58   unsigned char buffer[buffer_size];
59
60   size_t bytes;
61   do {
62     bytes = fread(buffer, 1, sizeof(buffer), testfile);
63     ASSERT_EQ(bytes, fwrite(buffer, 1, bytes, temporary));
64   } while (bytes > 0);
65
66   ASSERT_EQ(0, fclose(testfile));
67   ASSERT_EQ(0, fseek(temporary, 0, SEEK_SET));
68   ASSERT_EQ(0, lseek(fileno(temporary), 0, SEEK_SET));
69
70   *stream = temporary;
71 }
72
73 void OpenRelocsTestFiles(FILE** relocs_so, FILE** packed_relocs_so) {
74   const char* arch = NULL;
75   if (ELF::kMachine == EM_ARM) {
76     arch = "arm32";
77   } else if (ELF::kMachine == EM_AARCH64) {
78     arch = "arm64";
79   }
80   ASSERT_FALSE(arch == NULL);
81
82   const std::string base = std::string("elf_file_unittest_relocs_") + arch;
83   const std::string relocs = base + ".so";
84   const std::string packed_relocs = base + "_packed.so";
85
86   OpenRelocsTestFile(relocs.c_str(), relocs_so);
87   OpenRelocsTestFile(packed_relocs.c_str(), packed_relocs_so);
88 }
89
90 void CloseRelocsTestFile(FILE* temporary) {
91   fclose(temporary);
92 }
93
94 void CloseRelocsTestFiles(FILE* relocs_so, FILE* packed_relocs_so) {
95   CloseRelocsTestFile(relocs_so);
96   CloseRelocsTestFile(packed_relocs_so);
97 }
98
99 void CheckFileContentsEqual(FILE* first, FILE* second) {
100   ASSERT_EQ(0, fseek(first, 0, SEEK_SET));
101   ASSERT_EQ(0, fseek(second, 0, SEEK_SET));
102
103   static const size_t buffer_size = 4096;
104   unsigned char first_buffer[buffer_size];
105   unsigned char second_buffer[buffer_size];
106
107   do {
108     size_t first_read = fread(first_buffer, 1, sizeof(first_buffer), first);
109     size_t second_read = fread(second_buffer, 1, sizeof(second_buffer), second);
110
111     EXPECT_EQ(first_read, second_read);
112     EXPECT_EQ(0, memcmp(first_buffer, second_buffer, first_read));
113   } while (!feof(first) && !feof(second));
114
115   EXPECT_TRUE(feof(first) && feof(second));
116 }
117
118 }  // namespace
119
120 namespace relocation_packer {
121
122 TEST(ElfFile, PackRelocations) {
123   ASSERT_NE(EV_NONE, elf_version(EV_CURRENT));
124
125   FILE* relocs_so = NULL;
126   FILE* packed_relocs_so = NULL;
127   OpenRelocsTestFiles(&relocs_so, &packed_relocs_so);
128   if (HasFatalFailure())
129     return;
130
131   ElfFile elf_file(fileno(relocs_so));
132
133   // Ensure unpacking fails (not packed).
134   EXPECT_FALSE(elf_file.UnpackRelocations());
135
136   // Pack relocations, and check files are now identical.
137   EXPECT_TRUE(elf_file.PackRelocations());
138   CheckFileContentsEqual(relocs_so, packed_relocs_so);
139
140   CloseRelocsTestFiles(relocs_so, packed_relocs_so);
141 }
142
143 TEST(ElfFile, UnpackRelocations) {
144   ASSERT_NE(EV_NONE, elf_version(EV_CURRENT));
145
146   FILE* relocs_so = NULL;
147   FILE* packed_relocs_so = NULL;
148   OpenRelocsTestFiles(&relocs_so, &packed_relocs_so);
149   if (HasFatalFailure())
150     return;
151
152   ElfFile elf_file(fileno(packed_relocs_so));
153
154   // Ensure packing fails (already packed).
155   EXPECT_FALSE(elf_file.PackRelocations());
156
157   // Unpack golden relocations, and check files are now identical.
158   EXPECT_TRUE(elf_file.UnpackRelocations());
159   CheckFileContentsEqual(packed_relocs_so, relocs_so);
160
161   CloseRelocsTestFiles(relocs_so, packed_relocs_so);
162 }
163
164 }  // namespace relocation_packer