blob: 81cdaf5f0f819e8170af9c547591159c09524154 [file] [log] [blame]
Christopher Ferris3958f802017-02-01 15:44:40 -08001/*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include <elf.h>
18
19#include <memory>
20
21#include <gtest/gtest.h>
22
23#include "ElfInterface.h"
24#include "ElfInterfaceArm.h"
25
26#include "MemoryFake.h"
27
28#if !defined(PT_ARM_EXIDX)
29#define PT_ARM_EXIDX 0x70000001
30#endif
31
32#if !defined(EM_AARCH64)
33#define EM_AARCH64 183
34#endif
35
36class ElfInterfaceTest : public ::testing::Test {
37 protected:
38 void SetUp() override {
39 memory_.Clear();
40 }
41
42 void SetStringMemory(uint64_t offset, const char* string) {
43 memory_.SetMemory(offset, string, strlen(string) + 1);
44 }
45
46 template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
47 void SinglePtLoad();
48
49 template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
50 void MultipleExecutablePtLoads();
51
52 template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
53 void MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr();
54
55 template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
56 void NonExecutablePtLoads();
57
58 template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
59 void ManyPhdrs();
60
61 template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
62 void Soname();
63
64 template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
65 void SonameAfterDtNull();
66
67 template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
68 void SonameSize();
69
Christopher Ferris61d40972017-06-12 19:14:20 -070070 template <typename ElfType>
71 void InitHeadersEhFrameTest();
72
73 template <typename ElfType>
74 void InitHeadersDebugFrame();
75
76 template <typename ElfType>
77 void InitHeadersEhFrameFail();
78
79 template <typename ElfType>
80 void InitHeadersDebugFrameFail();
81
Christopher Ferris3958f802017-02-01 15:44:40 -080082 MemoryFake memory_;
83};
84
85template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
86void ElfInterfaceTest::SinglePtLoad() {
87 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
88
89 Ehdr ehdr;
90 memset(&ehdr, 0, sizeof(ehdr));
91 ehdr.e_phoff = 0x100;
92 ehdr.e_phnum = 1;
93 ehdr.e_phentsize = sizeof(Phdr);
94 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
95
96 Phdr phdr;
97 memset(&phdr, 0, sizeof(phdr));
98 phdr.p_type = PT_LOAD;
99 phdr.p_vaddr = 0x2000;
100 phdr.p_memsz = 0x10000;
101 phdr.p_flags = PF_R | PF_X;
102 phdr.p_align = 0x1000;
103 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
104
105 ASSERT_TRUE(elf->Init());
106
107 const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
108 ASSERT_EQ(1U, pt_loads.size());
109 LoadInfo load_data = pt_loads.at(0);
110 ASSERT_EQ(0U, load_data.offset);
111 ASSERT_EQ(0x2000U, load_data.table_offset);
112 ASSERT_EQ(0x10000U, load_data.table_size);
113}
114
115TEST_F(ElfInterfaceTest, elf32_single_pt_load) {
116 SinglePtLoad<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
117}
118
119TEST_F(ElfInterfaceTest, elf64_single_pt_load) {
120 SinglePtLoad<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
121}
122
123template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
124void ElfInterfaceTest::MultipleExecutablePtLoads() {
125 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
126
127 Ehdr ehdr;
128 memset(&ehdr, 0, sizeof(ehdr));
129 ehdr.e_phoff = 0x100;
130 ehdr.e_phnum = 3;
131 ehdr.e_phentsize = sizeof(Phdr);
132 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
133
134 Phdr phdr;
135 memset(&phdr, 0, sizeof(phdr));
136 phdr.p_type = PT_LOAD;
137 phdr.p_vaddr = 0x2000;
138 phdr.p_memsz = 0x10000;
139 phdr.p_flags = PF_R | PF_X;
140 phdr.p_align = 0x1000;
141 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
142
143 memset(&phdr, 0, sizeof(phdr));
144 phdr.p_type = PT_LOAD;
145 phdr.p_offset = 0x1000;
146 phdr.p_vaddr = 0x2001;
147 phdr.p_memsz = 0x10001;
148 phdr.p_flags = PF_R | PF_X;
149 phdr.p_align = 0x1001;
150 memory_.SetMemory(0x100 + sizeof(phdr), &phdr, sizeof(phdr));
151
152 memset(&phdr, 0, sizeof(phdr));
153 phdr.p_type = PT_LOAD;
154 phdr.p_offset = 0x2000;
155 phdr.p_vaddr = 0x2002;
156 phdr.p_memsz = 0x10002;
157 phdr.p_flags = PF_R | PF_X;
158 phdr.p_align = 0x1002;
159 memory_.SetMemory(0x100 + 2 * sizeof(phdr), &phdr, sizeof(phdr));
160
161 ASSERT_TRUE(elf->Init());
162
163 const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
164 ASSERT_EQ(3U, pt_loads.size());
165
166 LoadInfo load_data = pt_loads.at(0);
167 ASSERT_EQ(0U, load_data.offset);
168 ASSERT_EQ(0x2000U, load_data.table_offset);
169 ASSERT_EQ(0x10000U, load_data.table_size);
170
171 load_data = pt_loads.at(0x1000);
172 ASSERT_EQ(0x1000U, load_data.offset);
173 ASSERT_EQ(0x2001U, load_data.table_offset);
174 ASSERT_EQ(0x10001U, load_data.table_size);
175
176 load_data = pt_loads.at(0x2000);
177 ASSERT_EQ(0x2000U, load_data.offset);
178 ASSERT_EQ(0x2002U, load_data.table_offset);
179 ASSERT_EQ(0x10002U, load_data.table_size);
180}
181
182TEST_F(ElfInterfaceTest, elf32_multiple_executable_pt_loads) {
183 MultipleExecutablePtLoads<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
184}
185
186TEST_F(ElfInterfaceTest, elf64_multiple_executable_pt_loads) {
187 MultipleExecutablePtLoads<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
188}
189
190template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
191void ElfInterfaceTest::MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr() {
192 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
193
194 Ehdr ehdr;
195 memset(&ehdr, 0, sizeof(ehdr));
196 ehdr.e_phoff = 0x100;
197 ehdr.e_phnum = 3;
198 ehdr.e_phentsize = sizeof(Phdr) + 100;
199 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
200
201 Phdr phdr;
202 memset(&phdr, 0, sizeof(phdr));
203 phdr.p_type = PT_LOAD;
204 phdr.p_vaddr = 0x2000;
205 phdr.p_memsz = 0x10000;
206 phdr.p_flags = PF_R | PF_X;
207 phdr.p_align = 0x1000;
208 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
209
210 memset(&phdr, 0, sizeof(phdr));
211 phdr.p_type = PT_LOAD;
212 phdr.p_offset = 0x1000;
213 phdr.p_vaddr = 0x2001;
214 phdr.p_memsz = 0x10001;
215 phdr.p_flags = PF_R | PF_X;
216 phdr.p_align = 0x1001;
217 memory_.SetMemory(0x100 + sizeof(phdr) + 100, &phdr, sizeof(phdr));
218
219 memset(&phdr, 0, sizeof(phdr));
220 phdr.p_type = PT_LOAD;
221 phdr.p_offset = 0x2000;
222 phdr.p_vaddr = 0x2002;
223 phdr.p_memsz = 0x10002;
224 phdr.p_flags = PF_R | PF_X;
225 phdr.p_align = 0x1002;
226 memory_.SetMemory(0x100 + 2 * (sizeof(phdr) + 100), &phdr, sizeof(phdr));
227
228 ASSERT_TRUE(elf->Init());
229
230 const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
231 ASSERT_EQ(3U, pt_loads.size());
232
233 LoadInfo load_data = pt_loads.at(0);
234 ASSERT_EQ(0U, load_data.offset);
235 ASSERT_EQ(0x2000U, load_data.table_offset);
236 ASSERT_EQ(0x10000U, load_data.table_size);
237
238 load_data = pt_loads.at(0x1000);
239 ASSERT_EQ(0x1000U, load_data.offset);
240 ASSERT_EQ(0x2001U, load_data.table_offset);
241 ASSERT_EQ(0x10001U, load_data.table_size);
242
243 load_data = pt_loads.at(0x2000);
244 ASSERT_EQ(0x2000U, load_data.offset);
245 ASSERT_EQ(0x2002U, load_data.table_offset);
246 ASSERT_EQ(0x10002U, load_data.table_size);
247}
248
249TEST_F(ElfInterfaceTest, elf32_multiple_executable_pt_loads_increments_not_size_of_phdr) {
250 MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn,
251 ElfInterface32>();
252}
253
254TEST_F(ElfInterfaceTest, elf64_multiple_executable_pt_loads_increments_not_size_of_phdr) {
255 MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn,
256 ElfInterface64>();
257}
258
259template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
260void ElfInterfaceTest::NonExecutablePtLoads() {
261 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
262
263 Ehdr ehdr;
264 memset(&ehdr, 0, sizeof(ehdr));
265 ehdr.e_phoff = 0x100;
266 ehdr.e_phnum = 3;
267 ehdr.e_phentsize = sizeof(Phdr);
268 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
269
270 Phdr phdr;
271 memset(&phdr, 0, sizeof(phdr));
272 phdr.p_type = PT_LOAD;
273 phdr.p_vaddr = 0x2000;
274 phdr.p_memsz = 0x10000;
275 phdr.p_flags = PF_R;
276 phdr.p_align = 0x1000;
277 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
278
279 memset(&phdr, 0, sizeof(phdr));
280 phdr.p_type = PT_LOAD;
281 phdr.p_offset = 0x1000;
282 phdr.p_vaddr = 0x2001;
283 phdr.p_memsz = 0x10001;
284 phdr.p_flags = PF_R | PF_X;
285 phdr.p_align = 0x1001;
286 memory_.SetMemory(0x100 + sizeof(phdr), &phdr, sizeof(phdr));
287
288 memset(&phdr, 0, sizeof(phdr));
289 phdr.p_type = PT_LOAD;
290 phdr.p_offset = 0x2000;
291 phdr.p_vaddr = 0x2002;
292 phdr.p_memsz = 0x10002;
293 phdr.p_flags = PF_R;
294 phdr.p_align = 0x1002;
295 memory_.SetMemory(0x100 + 2 * sizeof(phdr), &phdr, sizeof(phdr));
296
297 ASSERT_TRUE(elf->Init());
298
299 const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
300 ASSERT_EQ(1U, pt_loads.size());
301
302 LoadInfo load_data = pt_loads.at(0x1000);
303 ASSERT_EQ(0x1000U, load_data.offset);
304 ASSERT_EQ(0x2001U, load_data.table_offset);
305 ASSERT_EQ(0x10001U, load_data.table_size);
306}
307
308TEST_F(ElfInterfaceTest, elf32_non_executable_pt_loads) {
309 NonExecutablePtLoads<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
310}
311
312TEST_F(ElfInterfaceTest, elf64_non_executable_pt_loads) {
313 NonExecutablePtLoads<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
314}
315
316template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
317void ElfInterfaceTest::ManyPhdrs() {
318 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
319
320 Ehdr ehdr;
321 memset(&ehdr, 0, sizeof(ehdr));
322 ehdr.e_phoff = 0x100;
323 ehdr.e_phnum = 7;
324 ehdr.e_phentsize = sizeof(Phdr);
325 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
326
327 Phdr phdr;
328 uint64_t phdr_offset = 0x100;
329
330 memset(&phdr, 0, sizeof(phdr));
331 phdr.p_type = PT_LOAD;
332 phdr.p_vaddr = 0x2000;
333 phdr.p_memsz = 0x10000;
334 phdr.p_flags = PF_R | PF_X;
335 phdr.p_align = 0x1000;
336 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
337 phdr_offset += sizeof(phdr);
338
339 memset(&phdr, 0, sizeof(phdr));
340 phdr.p_type = PT_GNU_EH_FRAME;
341 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
342 phdr_offset += sizeof(phdr);
343
344 memset(&phdr, 0, sizeof(phdr));
345 phdr.p_type = PT_DYNAMIC;
346 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
347 phdr_offset += sizeof(phdr);
348
349 memset(&phdr, 0, sizeof(phdr));
350 phdr.p_type = PT_INTERP;
351 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
352 phdr_offset += sizeof(phdr);
353
354 memset(&phdr, 0, sizeof(phdr));
355 phdr.p_type = PT_NOTE;
356 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
357 phdr_offset += sizeof(phdr);
358
359 memset(&phdr, 0, sizeof(phdr));
360 phdr.p_type = PT_SHLIB;
361 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
362 phdr_offset += sizeof(phdr);
363
364 memset(&phdr, 0, sizeof(phdr));
365 phdr.p_type = PT_GNU_EH_FRAME;
366 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
367 phdr_offset += sizeof(phdr);
368
369 ASSERT_TRUE(elf->Init());
370
371 const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
372 ASSERT_EQ(1U, pt_loads.size());
373
374 LoadInfo load_data = pt_loads.at(0);
375 ASSERT_EQ(0U, load_data.offset);
376 ASSERT_EQ(0x2000U, load_data.table_offset);
377 ASSERT_EQ(0x10000U, load_data.table_size);
378}
379
380TEST_F(ElfInterfaceTest, elf32_many_phdrs) {
381 ElfInterfaceTest::ManyPhdrs<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
382}
383
384TEST_F(ElfInterfaceTest, elf64_many_phdrs) {
385 ElfInterfaceTest::ManyPhdrs<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
386}
387
388TEST_F(ElfInterfaceTest, elf32_arm) {
389 ElfInterfaceArm elf_arm(&memory_);
390
391 Elf32_Ehdr ehdr;
392 memset(&ehdr, 0, sizeof(ehdr));
393 ehdr.e_phoff = 0x100;
394 ehdr.e_phnum = 1;
395 ehdr.e_phentsize = sizeof(Elf32_Phdr);
396 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
397
398 Elf32_Phdr phdr;
399 memset(&phdr, 0, sizeof(phdr));
400 phdr.p_type = PT_ARM_EXIDX;
401 phdr.p_vaddr = 0x2000;
402 phdr.p_memsz = 16;
403 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
404
405 // Add arm exidx entries.
406 memory_.SetData32(0x2000, 0x1000);
407 memory_.SetData32(0x2008, 0x1000);
408
409 ASSERT_TRUE(elf_arm.Init());
410
411 std::vector<uint32_t> entries;
412 for (auto addr : elf_arm) {
413 entries.push_back(addr);
414 }
415 ASSERT_EQ(2U, entries.size());
416 ASSERT_EQ(0x3000U, entries[0]);
417 ASSERT_EQ(0x3008U, entries[1]);
418
419 ASSERT_EQ(0x2000U, elf_arm.start_offset());
420 ASSERT_EQ(2U, elf_arm.total_entries());
421}
422
423template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
424void ElfInterfaceTest::Soname() {
425 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
426
427 Ehdr ehdr;
428 memset(&ehdr, 0, sizeof(ehdr));
429 ehdr.e_phoff = 0x100;
430 ehdr.e_phnum = 1;
431 ehdr.e_phentsize = sizeof(Phdr);
432 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
433
434 Phdr phdr;
435 memset(&phdr, 0, sizeof(phdr));
436 phdr.p_type = PT_DYNAMIC;
437 phdr.p_offset = 0x2000;
438 phdr.p_memsz = sizeof(Dyn) * 3;
439 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
440
441 uint64_t offset = 0x2000;
442 Dyn dyn;
443
444 dyn.d_tag = DT_STRTAB;
445 dyn.d_un.d_ptr = 0x10000;
446 memory_.SetMemory(offset, &dyn, sizeof(dyn));
447 offset += sizeof(dyn);
448
449 dyn.d_tag = DT_STRSZ;
450 dyn.d_un.d_val = 0x1000;
451 memory_.SetMemory(offset, &dyn, sizeof(dyn));
452 offset += sizeof(dyn);
453
454 dyn.d_tag = DT_SONAME;
455 dyn.d_un.d_val = 0x10;
456 memory_.SetMemory(offset, &dyn, sizeof(dyn));
457 offset += sizeof(dyn);
458
459 dyn.d_tag = DT_NULL;
460 memory_.SetMemory(offset, &dyn, sizeof(dyn));
461
462 SetStringMemory(0x10010, "fake_soname.so");
463
464 ASSERT_TRUE(elf->Init());
465 std::string name;
466 ASSERT_TRUE(elf->GetSoname(&name));
467 ASSERT_STREQ("fake_soname.so", name.c_str());
468}
469
470TEST_F(ElfInterfaceTest, elf32_soname) {
471 Soname<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
472}
473
474TEST_F(ElfInterfaceTest, elf64_soname) {
475 Soname<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
476}
477
478template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
479void ElfInterfaceTest::SonameAfterDtNull() {
480 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
481
482 Ehdr ehdr;
483 memset(&ehdr, 0, sizeof(ehdr));
484 ehdr.e_phoff = 0x100;
485 ehdr.e_phnum = 1;
486 ehdr.e_phentsize = sizeof(Phdr);
487 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
488
489 Phdr phdr;
490 memset(&phdr, 0, sizeof(phdr));
491 phdr.p_type = PT_DYNAMIC;
492 phdr.p_offset = 0x2000;
493 phdr.p_memsz = sizeof(Dyn) * 3;
494 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
495
496 Dyn dyn;
497 uint64_t offset = 0x2000;
498
499 dyn.d_tag = DT_STRTAB;
500 dyn.d_un.d_ptr = 0x10000;
501 memory_.SetMemory(offset, &dyn, sizeof(dyn));
502 offset += sizeof(dyn);
503
504 dyn.d_tag = DT_STRSZ;
505 dyn.d_un.d_val = 0x1000;
506 memory_.SetMemory(offset, &dyn, sizeof(dyn));
507 offset += sizeof(dyn);
508
509 dyn.d_tag = DT_NULL;
510 memory_.SetMemory(offset, &dyn, sizeof(dyn));
511 offset += sizeof(dyn);
512
513 dyn.d_tag = DT_SONAME;
514 dyn.d_un.d_val = 0x10;
515 memory_.SetMemory(offset, &dyn, sizeof(dyn));
516 offset += sizeof(dyn);
517
518 SetStringMemory(0x10010, "fake_soname.so");
519
520 ASSERT_TRUE(elf->Init());
521 std::string name;
522 ASSERT_FALSE(elf->GetSoname(&name));
523}
524
525TEST_F(ElfInterfaceTest, elf32_soname_after_dt_null) {
526 SonameAfterDtNull<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
527}
528
529TEST_F(ElfInterfaceTest, elf64_soname_after_dt_null) {
530 SonameAfterDtNull<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
531}
532
533template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
534void ElfInterfaceTest::SonameSize() {
535 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
536
537 Ehdr ehdr;
538 memset(&ehdr, 0, sizeof(ehdr));
539 ehdr.e_phoff = 0x100;
540 ehdr.e_phnum = 1;
541 ehdr.e_phentsize = sizeof(Phdr);
542 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
543
544 Phdr phdr;
545 memset(&phdr, 0, sizeof(phdr));
546 phdr.p_type = PT_DYNAMIC;
547 phdr.p_offset = 0x2000;
548 phdr.p_memsz = sizeof(Dyn);
549 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
550
551 Dyn dyn;
552 uint64_t offset = 0x2000;
553
554 dyn.d_tag = DT_STRTAB;
555 dyn.d_un.d_ptr = 0x10000;
556 memory_.SetMemory(offset, &dyn, sizeof(dyn));
557 offset += sizeof(dyn);
558
559 dyn.d_tag = DT_STRSZ;
560 dyn.d_un.d_val = 0x10;
561 memory_.SetMemory(offset, &dyn, sizeof(dyn));
562 offset += sizeof(dyn);
563
564 dyn.d_tag = DT_SONAME;
565 dyn.d_un.d_val = 0x10;
566 memory_.SetMemory(offset, &dyn, sizeof(dyn));
567 offset += sizeof(dyn);
568
569 dyn.d_tag = DT_NULL;
570 memory_.SetMemory(offset, &dyn, sizeof(dyn));
571
572 SetStringMemory(0x10010, "fake_soname.so");
573
574 ASSERT_TRUE(elf->Init());
575 std::string name;
576 ASSERT_FALSE(elf->GetSoname(&name));
577}
578
579TEST_F(ElfInterfaceTest, elf32_soname_size) {
580 SonameSize<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
581}
582
583TEST_F(ElfInterfaceTest, elf64_soname_size) {
584 SonameSize<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
585}
Christopher Ferris61d40972017-06-12 19:14:20 -0700586
587class MockElfInterface32 : public ElfInterface32 {
588 public:
589 MockElfInterface32(Memory* memory) : ElfInterface32(memory) {}
590 virtual ~MockElfInterface32() = default;
591
592 void TestSetEhFrameOffset(uint64_t offset) { eh_frame_offset_ = offset; }
593 void TestSetEhFrameSize(uint64_t size) { eh_frame_size_ = size; }
594
595 void TestSetDebugFrameOffset(uint64_t offset) { debug_frame_offset_ = offset; }
596 void TestSetDebugFrameSize(uint64_t size) { debug_frame_size_ = size; }
597};
598
599class MockElfInterface64 : public ElfInterface64 {
600 public:
601 MockElfInterface64(Memory* memory) : ElfInterface64(memory) {}
602 virtual ~MockElfInterface64() = default;
603
604 void TestSetEhFrameOffset(uint64_t offset) { eh_frame_offset_ = offset; }
605 void TestSetEhFrameSize(uint64_t size) { eh_frame_size_ = size; }
606
607 void TestSetDebugFrameOffset(uint64_t offset) { debug_frame_offset_ = offset; }
608 void TestSetDebugFrameSize(uint64_t size) { debug_frame_size_ = size; }
609};
610
611template <typename ElfType>
612void ElfInterfaceTest::InitHeadersEhFrameTest() {
613 ElfType elf(&memory_);
614
615 elf.TestSetEhFrameOffset(0x10000);
616 elf.TestSetEhFrameSize(0);
617 elf.TestSetDebugFrameOffset(0);
618 elf.TestSetDebugFrameSize(0);
619
620 memory_.SetMemory(0x10000,
621 std::vector<uint8_t>{0x1, DW_EH_PE_udata2, DW_EH_PE_udata2, DW_EH_PE_udata2});
622 memory_.SetData32(0x10004, 0x500);
623 memory_.SetData32(0x10008, 250);
624
625 elf.InitHeaders();
626
627 EXPECT_FALSE(elf.eh_frame() == nullptr);
628 EXPECT_TRUE(elf.debug_frame() == nullptr);
629}
630
631TEST_F(ElfInterfaceTest, init_headers_eh_frame32) {
632 InitHeadersEhFrameTest<MockElfInterface32>();
633}
634
635TEST_F(ElfInterfaceTest, init_headers_eh_frame64) {
636 InitHeadersEhFrameTest<MockElfInterface64>();
637}
638
639template <typename ElfType>
640void ElfInterfaceTest::InitHeadersDebugFrame() {
641 ElfType elf(&memory_);
642
643 elf.TestSetEhFrameOffset(0);
644 elf.TestSetEhFrameSize(0);
645 elf.TestSetDebugFrameOffset(0x5000);
646 elf.TestSetDebugFrameSize(0x200);
647
648 memory_.SetData32(0x5000, 0xfc);
649 memory_.SetData32(0x5004, 0xffffffff);
650 memory_.SetData8(0x5008, 1);
651 memory_.SetData8(0x5009, '\0');
652
653 memory_.SetData32(0x5100, 0xfc);
654 memory_.SetData32(0x5104, 0);
655 memory_.SetData32(0x5108, 0x1500);
656 memory_.SetData32(0x510c, 0x200);
657
658 elf.InitHeaders();
659
660 EXPECT_TRUE(elf.eh_frame() == nullptr);
661 EXPECT_FALSE(elf.debug_frame() == nullptr);
662}
663
664TEST_F(ElfInterfaceTest, init_headers_debug_frame32) {
665 InitHeadersDebugFrame<MockElfInterface32>();
666}
667
668TEST_F(ElfInterfaceTest, init_headers_debug_frame64) {
669 InitHeadersDebugFrame<MockElfInterface64>();
670}
671
672template <typename ElfType>
673void ElfInterfaceTest::InitHeadersEhFrameFail() {
674 ElfType elf(&memory_);
675
676 elf.TestSetEhFrameOffset(0x1000);
677 elf.TestSetEhFrameSize(0x100);
678 elf.TestSetDebugFrameOffset(0);
679 elf.TestSetDebugFrameSize(0);
680
681 elf.InitHeaders();
682
683 EXPECT_TRUE(elf.eh_frame() == nullptr);
684 EXPECT_EQ(0U, elf.eh_frame_offset());
685 EXPECT_EQ(static_cast<uint64_t>(-1), elf.eh_frame_size());
686 EXPECT_TRUE(elf.debug_frame() == nullptr);
687}
688
689TEST_F(ElfInterfaceTest, init_headers_eh_frame32_fail) {
690 InitHeadersEhFrameFail<MockElfInterface32>();
691}
692
693TEST_F(ElfInterfaceTest, init_headers_eh_frame64_fail) {
694 InitHeadersEhFrameFail<MockElfInterface64>();
695}
696
697template <typename ElfType>
698void ElfInterfaceTest::InitHeadersDebugFrameFail() {
699 ElfType elf(&memory_);
700
701 elf.TestSetEhFrameOffset(0);
702 elf.TestSetEhFrameSize(0);
703 elf.TestSetDebugFrameOffset(0x1000);
704 elf.TestSetDebugFrameSize(0x100);
705
706 elf.InitHeaders();
707
708 EXPECT_TRUE(elf.eh_frame() == nullptr);
709 EXPECT_TRUE(elf.debug_frame() == nullptr);
710 EXPECT_EQ(0U, elf.debug_frame_offset());
711 EXPECT_EQ(static_cast<uint64_t>(-1), elf.debug_frame_size());
712}
713
714TEST_F(ElfInterfaceTest, init_headers_debug_frame32_fail) {
715 InitHeadersDebugFrameFail<MockElfInterface32>();
716}
717
718TEST_F(ElfInterfaceTest, init_headers_debug_frame64_fail) {
719 InitHeadersDebugFrameFail<MockElfInterface64>();
720}