OLD | NEW |
---|---|
(Empty) | |
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 "testing/gtest/include/gtest/gtest.h" | |
14 | |
15 // Macro stringification. | |
16 // https://gcc.gnu.org/onlinedocs/cpp/Stringification.html | |
17 #define xstr(s) str(s) | |
18 #define str(s) #s | |
rmcilroy
2014/06/07 11:49:07
All uppercase for macro names.
simonb (inactive)
2014/06/09 14:39:19
Done.
| |
19 | |
20 namespace { | |
21 | |
22 void GetDataFilePath(const char* name, std::string* path) { | |
23 std::string data_dir; | |
24 | |
25 const char* bindir = getenv("bindir"); | |
26 if (bindir) { | |
27 data_dir = std::string(bindir); | |
28 } else { | |
29 // Test data is in the gyp INTERMEDIATE_DIR subdirectory of the directory | |
30 // that contains the current binary. | |
31 char path[PATH_MAX]; | |
32 memset(path, 0, sizeof(path)); | |
33 ASSERT_NE(-1, readlink("/proc/self/exe", path, sizeof(path) - 1)); | |
34 | |
35 data_dir = std::string(path); | |
36 size_t pos = data_dir.rfind('/'); | |
37 ASSERT_NE(std::string::npos, pos); | |
38 | |
39 data_dir.erase(pos + 1); | |
40 data_dir += std::string(xstr(INTERMEDIATE_DIR)); | |
41 } | |
42 | |
43 *path = data_dir + "/" + name; | |
44 } | |
45 | |
46 void OpenRelocsTestFile(const char* name, FILE** stream) { | |
47 std::string path; | |
48 GetDataFilePath(name, &path); | |
49 | |
50 FILE* testfile = fopen(path.c_str(), "rb"); | |
51 ASSERT_FALSE(testfile == NULL); | |
52 | |
53 FILE* temporary = tmpfile(); | |
54 ASSERT_FALSE(temporary == NULL); | |
55 | |
56 static const size_t buffer_size = 4096; | |
57 unsigned char buffer[buffer_size]; | |
58 | |
59 size_t bytes; | |
60 do { | |
61 bytes = fread(buffer, 1, sizeof(buffer), testfile); | |
62 ASSERT_EQ(bytes, fwrite(buffer, 1, bytes, temporary)); | |
63 } while (bytes > 0); | |
64 | |
65 ASSERT_EQ(0, fclose(testfile)); | |
66 ASSERT_EQ(0, fseek(temporary, 0, SEEK_SET)); | |
67 ASSERT_EQ(0, lseek(fileno(temporary), 0, SEEK_SET)); | |
68 | |
69 *stream = temporary; | |
70 } | |
71 | |
72 void OpenRelocsTestFiles(FILE** relocs_so, FILE** packed_relocs_so) { | |
73 OpenRelocsTestFile("elf_file_unittest_relocs.so", relocs_so); | |
74 OpenRelocsTestFile("elf_file_unittest_relocs_packed.so", packed_relocs_so); | |
75 } | |
76 | |
77 void CloseRelocsTestFile(FILE* temporary) { | |
78 fclose(temporary); | |
79 } | |
80 | |
81 void CloseRelocsTestFiles(FILE* relocs_so, FILE* packed_relocs_so) { | |
82 CloseRelocsTestFile(relocs_so); | |
83 CloseRelocsTestFile(packed_relocs_so); | |
84 } | |
85 | |
86 void CheckFileContentsEqual(FILE* first, FILE* second) { | |
87 ASSERT_EQ(0, fseek(first, 0, SEEK_SET)); | |
88 ASSERT_EQ(0, fseek(second, 0, SEEK_SET)); | |
89 | |
90 static const size_t buffer_size = 4096; | |
91 unsigned char first_buffer[buffer_size]; | |
92 unsigned char second_buffer[buffer_size]; | |
93 | |
94 do { | |
95 size_t first_read = fread(first_buffer, 1, sizeof(first_buffer), first); | |
96 size_t second_read = fread(second_buffer, 1, sizeof(second_buffer), second); | |
97 | |
98 EXPECT_EQ(first_read, second_read); | |
99 EXPECT_EQ(0, memcmp(first_buffer, second_buffer, first_read)); | |
100 } while (!feof(first) && !feof(second)); | |
101 | |
102 EXPECT_TRUE(feof(first) && feof(second)); | |
103 } | |
104 | |
105 } // namespace | |
106 | |
107 namespace relocation_packer { | |
108 | |
109 TEST(ElfFile, PackRelocations) { | |
110 ASSERT_NE(EV_NONE, elf_version(EV_CURRENT)); | |
111 | |
112 FILE* relocs_so = NULL; | |
113 FILE* packed_relocs_so = NULL; | |
114 OpenRelocsTestFiles(&relocs_so, &packed_relocs_so); | |
115 if (HasFatalFailure()) | |
116 return; | |
117 | |
118 ElfFile elf_file(fileno(relocs_so)); | |
119 | |
120 // Ensure unpacking fails (not packed). | |
121 EXPECT_FALSE(elf_file.UnpackRelocations()); | |
122 | |
123 // Pack relocations, and check files are now identical. | |
124 EXPECT_TRUE(elf_file.PackRelocations()); | |
125 CheckFileContentsEqual(relocs_so, packed_relocs_so); | |
126 | |
127 CloseRelocsTestFiles(relocs_so, packed_relocs_so); | |
128 } | |
129 | |
130 TEST(ElfFile, UnpackRelocations) { | |
131 ASSERT_NE(EV_NONE, elf_version(EV_CURRENT)); | |
132 | |
133 FILE* relocs_so = NULL; | |
134 FILE* packed_relocs_so = NULL; | |
135 OpenRelocsTestFiles(&relocs_so, &packed_relocs_so); | |
136 if (HasFatalFailure()) | |
137 return; | |
138 | |
139 ElfFile elf_file(fileno(packed_relocs_so)); | |
140 | |
141 // Ensure packing fails (already packed). | |
142 EXPECT_FALSE(elf_file.PackRelocations()); | |
143 | |
144 // Unpack golden relocations, and check files are now identical. | |
145 EXPECT_TRUE(elf_file.UnpackRelocations()); | |
146 CheckFileContentsEqual(packed_relocs_so, relocs_so); | |
147 | |
148 CloseRelocsTestFiles(relocs_so, packed_relocs_so); | |
149 } | |
150 | |
151 } // namespace relocation_packer | |
OLD | NEW |