blob: 0f56ba8971733e515af10de5e01578dc1e46441e [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 Ferris8098b1c2017-06-20 13:54:08 -070082 template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
83 void InitSectionHeadersMalformed();
84
85 template <typename Ehdr, typename Shdr, typename Sym, typename ElfInterfaceType>
86 void InitSectionHeaders(uint64_t entry_size);
87
88 template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
89 void InitSectionHeadersOffsets();
90
91 template <typename Sym>
92 void InitSym(uint64_t offset, uint32_t value, uint32_t size, uint32_t name_offset,
93 uint64_t sym_offset, const char* name);
94
Christopher Ferris3958f802017-02-01 15:44:40 -080095 MemoryFake memory_;
96};
97
Christopher Ferris8098b1c2017-06-20 13:54:08 -070098template <typename Sym>
99void ElfInterfaceTest::InitSym(uint64_t offset, uint32_t value, uint32_t size, uint32_t name_offset,
100 uint64_t sym_offset, const char* name) {
101 Sym sym;
102 memset(&sym, 0, sizeof(sym));
103 sym.st_info = STT_FUNC;
104 sym.st_value = value;
105 sym.st_size = size;
106 sym.st_name = name_offset;
107 sym.st_shndx = SHN_COMMON;
108
109 memory_.SetMemory(offset, &sym, sizeof(sym));
110 memory_.SetMemory(sym_offset + name_offset, name, strlen(name) + 1);
111}
112
Christopher Ferris3958f802017-02-01 15:44:40 -0800113template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
114void ElfInterfaceTest::SinglePtLoad() {
115 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
116
117 Ehdr ehdr;
118 memset(&ehdr, 0, sizeof(ehdr));
119 ehdr.e_phoff = 0x100;
120 ehdr.e_phnum = 1;
121 ehdr.e_phentsize = sizeof(Phdr);
122 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
123
124 Phdr phdr;
125 memset(&phdr, 0, sizeof(phdr));
126 phdr.p_type = PT_LOAD;
127 phdr.p_vaddr = 0x2000;
128 phdr.p_memsz = 0x10000;
129 phdr.p_flags = PF_R | PF_X;
130 phdr.p_align = 0x1000;
131 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
132
133 ASSERT_TRUE(elf->Init());
134
135 const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
136 ASSERT_EQ(1U, pt_loads.size());
137 LoadInfo load_data = pt_loads.at(0);
138 ASSERT_EQ(0U, load_data.offset);
139 ASSERT_EQ(0x2000U, load_data.table_offset);
140 ASSERT_EQ(0x10000U, load_data.table_size);
141}
142
143TEST_F(ElfInterfaceTest, elf32_single_pt_load) {
144 SinglePtLoad<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
145}
146
147TEST_F(ElfInterfaceTest, elf64_single_pt_load) {
148 SinglePtLoad<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
149}
150
151template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
152void ElfInterfaceTest::MultipleExecutablePtLoads() {
153 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
154
155 Ehdr ehdr;
156 memset(&ehdr, 0, sizeof(ehdr));
157 ehdr.e_phoff = 0x100;
158 ehdr.e_phnum = 3;
159 ehdr.e_phentsize = sizeof(Phdr);
160 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
161
162 Phdr phdr;
163 memset(&phdr, 0, sizeof(phdr));
164 phdr.p_type = PT_LOAD;
165 phdr.p_vaddr = 0x2000;
166 phdr.p_memsz = 0x10000;
167 phdr.p_flags = PF_R | PF_X;
168 phdr.p_align = 0x1000;
169 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
170
171 memset(&phdr, 0, sizeof(phdr));
172 phdr.p_type = PT_LOAD;
173 phdr.p_offset = 0x1000;
174 phdr.p_vaddr = 0x2001;
175 phdr.p_memsz = 0x10001;
176 phdr.p_flags = PF_R | PF_X;
177 phdr.p_align = 0x1001;
178 memory_.SetMemory(0x100 + sizeof(phdr), &phdr, sizeof(phdr));
179
180 memset(&phdr, 0, sizeof(phdr));
181 phdr.p_type = PT_LOAD;
182 phdr.p_offset = 0x2000;
183 phdr.p_vaddr = 0x2002;
184 phdr.p_memsz = 0x10002;
185 phdr.p_flags = PF_R | PF_X;
186 phdr.p_align = 0x1002;
187 memory_.SetMemory(0x100 + 2 * sizeof(phdr), &phdr, sizeof(phdr));
188
189 ASSERT_TRUE(elf->Init());
190
191 const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
192 ASSERT_EQ(3U, pt_loads.size());
193
194 LoadInfo load_data = pt_loads.at(0);
195 ASSERT_EQ(0U, load_data.offset);
196 ASSERT_EQ(0x2000U, load_data.table_offset);
197 ASSERT_EQ(0x10000U, load_data.table_size);
198
199 load_data = pt_loads.at(0x1000);
200 ASSERT_EQ(0x1000U, load_data.offset);
201 ASSERT_EQ(0x2001U, load_data.table_offset);
202 ASSERT_EQ(0x10001U, load_data.table_size);
203
204 load_data = pt_loads.at(0x2000);
205 ASSERT_EQ(0x2000U, load_data.offset);
206 ASSERT_EQ(0x2002U, load_data.table_offset);
207 ASSERT_EQ(0x10002U, load_data.table_size);
208}
209
210TEST_F(ElfInterfaceTest, elf32_multiple_executable_pt_loads) {
211 MultipleExecutablePtLoads<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
212}
213
214TEST_F(ElfInterfaceTest, elf64_multiple_executable_pt_loads) {
215 MultipleExecutablePtLoads<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
216}
217
218template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
219void ElfInterfaceTest::MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr() {
220 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
221
222 Ehdr ehdr;
223 memset(&ehdr, 0, sizeof(ehdr));
224 ehdr.e_phoff = 0x100;
225 ehdr.e_phnum = 3;
226 ehdr.e_phentsize = sizeof(Phdr) + 100;
227 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
228
229 Phdr phdr;
230 memset(&phdr, 0, sizeof(phdr));
231 phdr.p_type = PT_LOAD;
232 phdr.p_vaddr = 0x2000;
233 phdr.p_memsz = 0x10000;
234 phdr.p_flags = PF_R | PF_X;
235 phdr.p_align = 0x1000;
236 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
237
238 memset(&phdr, 0, sizeof(phdr));
239 phdr.p_type = PT_LOAD;
240 phdr.p_offset = 0x1000;
241 phdr.p_vaddr = 0x2001;
242 phdr.p_memsz = 0x10001;
243 phdr.p_flags = PF_R | PF_X;
244 phdr.p_align = 0x1001;
245 memory_.SetMemory(0x100 + sizeof(phdr) + 100, &phdr, sizeof(phdr));
246
247 memset(&phdr, 0, sizeof(phdr));
248 phdr.p_type = PT_LOAD;
249 phdr.p_offset = 0x2000;
250 phdr.p_vaddr = 0x2002;
251 phdr.p_memsz = 0x10002;
252 phdr.p_flags = PF_R | PF_X;
253 phdr.p_align = 0x1002;
254 memory_.SetMemory(0x100 + 2 * (sizeof(phdr) + 100), &phdr, sizeof(phdr));
255
256 ASSERT_TRUE(elf->Init());
257
258 const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
259 ASSERT_EQ(3U, pt_loads.size());
260
261 LoadInfo load_data = pt_loads.at(0);
262 ASSERT_EQ(0U, load_data.offset);
263 ASSERT_EQ(0x2000U, load_data.table_offset);
264 ASSERT_EQ(0x10000U, load_data.table_size);
265
266 load_data = pt_loads.at(0x1000);
267 ASSERT_EQ(0x1000U, load_data.offset);
268 ASSERT_EQ(0x2001U, load_data.table_offset);
269 ASSERT_EQ(0x10001U, load_data.table_size);
270
271 load_data = pt_loads.at(0x2000);
272 ASSERT_EQ(0x2000U, load_data.offset);
273 ASSERT_EQ(0x2002U, load_data.table_offset);
274 ASSERT_EQ(0x10002U, load_data.table_size);
275}
276
277TEST_F(ElfInterfaceTest, elf32_multiple_executable_pt_loads_increments_not_size_of_phdr) {
278 MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn,
279 ElfInterface32>();
280}
281
282TEST_F(ElfInterfaceTest, elf64_multiple_executable_pt_loads_increments_not_size_of_phdr) {
283 MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn,
284 ElfInterface64>();
285}
286
287template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
288void ElfInterfaceTest::NonExecutablePtLoads() {
289 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
290
291 Ehdr ehdr;
292 memset(&ehdr, 0, sizeof(ehdr));
293 ehdr.e_phoff = 0x100;
294 ehdr.e_phnum = 3;
295 ehdr.e_phentsize = sizeof(Phdr);
296 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
297
298 Phdr phdr;
299 memset(&phdr, 0, sizeof(phdr));
300 phdr.p_type = PT_LOAD;
301 phdr.p_vaddr = 0x2000;
302 phdr.p_memsz = 0x10000;
303 phdr.p_flags = PF_R;
304 phdr.p_align = 0x1000;
305 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
306
307 memset(&phdr, 0, sizeof(phdr));
308 phdr.p_type = PT_LOAD;
309 phdr.p_offset = 0x1000;
310 phdr.p_vaddr = 0x2001;
311 phdr.p_memsz = 0x10001;
312 phdr.p_flags = PF_R | PF_X;
313 phdr.p_align = 0x1001;
314 memory_.SetMemory(0x100 + sizeof(phdr), &phdr, sizeof(phdr));
315
316 memset(&phdr, 0, sizeof(phdr));
317 phdr.p_type = PT_LOAD;
318 phdr.p_offset = 0x2000;
319 phdr.p_vaddr = 0x2002;
320 phdr.p_memsz = 0x10002;
321 phdr.p_flags = PF_R;
322 phdr.p_align = 0x1002;
323 memory_.SetMemory(0x100 + 2 * sizeof(phdr), &phdr, sizeof(phdr));
324
325 ASSERT_TRUE(elf->Init());
326
327 const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
328 ASSERT_EQ(1U, pt_loads.size());
329
330 LoadInfo load_data = pt_loads.at(0x1000);
331 ASSERT_EQ(0x1000U, load_data.offset);
332 ASSERT_EQ(0x2001U, load_data.table_offset);
333 ASSERT_EQ(0x10001U, load_data.table_size);
334}
335
336TEST_F(ElfInterfaceTest, elf32_non_executable_pt_loads) {
337 NonExecutablePtLoads<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
338}
339
340TEST_F(ElfInterfaceTest, elf64_non_executable_pt_loads) {
341 NonExecutablePtLoads<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
342}
343
344template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
345void ElfInterfaceTest::ManyPhdrs() {
346 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
347
348 Ehdr ehdr;
349 memset(&ehdr, 0, sizeof(ehdr));
350 ehdr.e_phoff = 0x100;
351 ehdr.e_phnum = 7;
352 ehdr.e_phentsize = sizeof(Phdr);
353 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
354
355 Phdr phdr;
356 uint64_t phdr_offset = 0x100;
357
358 memset(&phdr, 0, sizeof(phdr));
359 phdr.p_type = PT_LOAD;
360 phdr.p_vaddr = 0x2000;
361 phdr.p_memsz = 0x10000;
362 phdr.p_flags = PF_R | PF_X;
363 phdr.p_align = 0x1000;
364 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
365 phdr_offset += sizeof(phdr);
366
367 memset(&phdr, 0, sizeof(phdr));
368 phdr.p_type = PT_GNU_EH_FRAME;
369 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
370 phdr_offset += sizeof(phdr);
371
372 memset(&phdr, 0, sizeof(phdr));
373 phdr.p_type = PT_DYNAMIC;
374 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
375 phdr_offset += sizeof(phdr);
376
377 memset(&phdr, 0, sizeof(phdr));
378 phdr.p_type = PT_INTERP;
379 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
380 phdr_offset += sizeof(phdr);
381
382 memset(&phdr, 0, sizeof(phdr));
383 phdr.p_type = PT_NOTE;
384 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
385 phdr_offset += sizeof(phdr);
386
387 memset(&phdr, 0, sizeof(phdr));
388 phdr.p_type = PT_SHLIB;
389 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
390 phdr_offset += sizeof(phdr);
391
392 memset(&phdr, 0, sizeof(phdr));
393 phdr.p_type = PT_GNU_EH_FRAME;
394 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
395 phdr_offset += sizeof(phdr);
396
397 ASSERT_TRUE(elf->Init());
398
399 const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
400 ASSERT_EQ(1U, pt_loads.size());
401
402 LoadInfo load_data = pt_loads.at(0);
403 ASSERT_EQ(0U, load_data.offset);
404 ASSERT_EQ(0x2000U, load_data.table_offset);
405 ASSERT_EQ(0x10000U, load_data.table_size);
406}
407
408TEST_F(ElfInterfaceTest, elf32_many_phdrs) {
409 ElfInterfaceTest::ManyPhdrs<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
410}
411
412TEST_F(ElfInterfaceTest, elf64_many_phdrs) {
413 ElfInterfaceTest::ManyPhdrs<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
414}
415
416TEST_F(ElfInterfaceTest, elf32_arm) {
417 ElfInterfaceArm elf_arm(&memory_);
418
419 Elf32_Ehdr ehdr;
420 memset(&ehdr, 0, sizeof(ehdr));
421 ehdr.e_phoff = 0x100;
422 ehdr.e_phnum = 1;
423 ehdr.e_phentsize = sizeof(Elf32_Phdr);
424 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
425
426 Elf32_Phdr phdr;
427 memset(&phdr, 0, sizeof(phdr));
428 phdr.p_type = PT_ARM_EXIDX;
429 phdr.p_vaddr = 0x2000;
430 phdr.p_memsz = 16;
431 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
432
433 // Add arm exidx entries.
434 memory_.SetData32(0x2000, 0x1000);
435 memory_.SetData32(0x2008, 0x1000);
436
437 ASSERT_TRUE(elf_arm.Init());
438
439 std::vector<uint32_t> entries;
440 for (auto addr : elf_arm) {
441 entries.push_back(addr);
442 }
443 ASSERT_EQ(2U, entries.size());
444 ASSERT_EQ(0x3000U, entries[0]);
445 ASSERT_EQ(0x3008U, entries[1]);
446
447 ASSERT_EQ(0x2000U, elf_arm.start_offset());
448 ASSERT_EQ(2U, elf_arm.total_entries());
449}
450
451template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
452void ElfInterfaceTest::Soname() {
453 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
454
455 Ehdr ehdr;
456 memset(&ehdr, 0, sizeof(ehdr));
457 ehdr.e_phoff = 0x100;
458 ehdr.e_phnum = 1;
459 ehdr.e_phentsize = sizeof(Phdr);
460 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
461
462 Phdr phdr;
463 memset(&phdr, 0, sizeof(phdr));
464 phdr.p_type = PT_DYNAMIC;
465 phdr.p_offset = 0x2000;
466 phdr.p_memsz = sizeof(Dyn) * 3;
467 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
468
469 uint64_t offset = 0x2000;
470 Dyn dyn;
471
472 dyn.d_tag = DT_STRTAB;
473 dyn.d_un.d_ptr = 0x10000;
474 memory_.SetMemory(offset, &dyn, sizeof(dyn));
475 offset += sizeof(dyn);
476
477 dyn.d_tag = DT_STRSZ;
478 dyn.d_un.d_val = 0x1000;
479 memory_.SetMemory(offset, &dyn, sizeof(dyn));
480 offset += sizeof(dyn);
481
482 dyn.d_tag = DT_SONAME;
483 dyn.d_un.d_val = 0x10;
484 memory_.SetMemory(offset, &dyn, sizeof(dyn));
485 offset += sizeof(dyn);
486
487 dyn.d_tag = DT_NULL;
488 memory_.SetMemory(offset, &dyn, sizeof(dyn));
489
490 SetStringMemory(0x10010, "fake_soname.so");
491
492 ASSERT_TRUE(elf->Init());
493 std::string name;
494 ASSERT_TRUE(elf->GetSoname(&name));
495 ASSERT_STREQ("fake_soname.so", name.c_str());
496}
497
498TEST_F(ElfInterfaceTest, elf32_soname) {
499 Soname<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
500}
501
502TEST_F(ElfInterfaceTest, elf64_soname) {
503 Soname<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
504}
505
506template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
507void ElfInterfaceTest::SonameAfterDtNull() {
508 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
509
510 Ehdr ehdr;
511 memset(&ehdr, 0, sizeof(ehdr));
512 ehdr.e_phoff = 0x100;
513 ehdr.e_phnum = 1;
514 ehdr.e_phentsize = sizeof(Phdr);
515 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
516
517 Phdr phdr;
518 memset(&phdr, 0, sizeof(phdr));
519 phdr.p_type = PT_DYNAMIC;
520 phdr.p_offset = 0x2000;
521 phdr.p_memsz = sizeof(Dyn) * 3;
522 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
523
524 Dyn dyn;
525 uint64_t offset = 0x2000;
526
527 dyn.d_tag = DT_STRTAB;
528 dyn.d_un.d_ptr = 0x10000;
529 memory_.SetMemory(offset, &dyn, sizeof(dyn));
530 offset += sizeof(dyn);
531
532 dyn.d_tag = DT_STRSZ;
533 dyn.d_un.d_val = 0x1000;
534 memory_.SetMemory(offset, &dyn, sizeof(dyn));
535 offset += sizeof(dyn);
536
537 dyn.d_tag = DT_NULL;
538 memory_.SetMemory(offset, &dyn, sizeof(dyn));
539 offset += sizeof(dyn);
540
541 dyn.d_tag = DT_SONAME;
542 dyn.d_un.d_val = 0x10;
543 memory_.SetMemory(offset, &dyn, sizeof(dyn));
544 offset += sizeof(dyn);
545
546 SetStringMemory(0x10010, "fake_soname.so");
547
548 ASSERT_TRUE(elf->Init());
549 std::string name;
550 ASSERT_FALSE(elf->GetSoname(&name));
551}
552
553TEST_F(ElfInterfaceTest, elf32_soname_after_dt_null) {
554 SonameAfterDtNull<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
555}
556
557TEST_F(ElfInterfaceTest, elf64_soname_after_dt_null) {
558 SonameAfterDtNull<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
559}
560
561template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
562void ElfInterfaceTest::SonameSize() {
563 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
564
565 Ehdr ehdr;
566 memset(&ehdr, 0, sizeof(ehdr));
567 ehdr.e_phoff = 0x100;
568 ehdr.e_phnum = 1;
569 ehdr.e_phentsize = sizeof(Phdr);
570 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
571
572 Phdr phdr;
573 memset(&phdr, 0, sizeof(phdr));
574 phdr.p_type = PT_DYNAMIC;
575 phdr.p_offset = 0x2000;
576 phdr.p_memsz = sizeof(Dyn);
577 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
578
579 Dyn dyn;
580 uint64_t offset = 0x2000;
581
582 dyn.d_tag = DT_STRTAB;
583 dyn.d_un.d_ptr = 0x10000;
584 memory_.SetMemory(offset, &dyn, sizeof(dyn));
585 offset += sizeof(dyn);
586
587 dyn.d_tag = DT_STRSZ;
588 dyn.d_un.d_val = 0x10;
589 memory_.SetMemory(offset, &dyn, sizeof(dyn));
590 offset += sizeof(dyn);
591
592 dyn.d_tag = DT_SONAME;
593 dyn.d_un.d_val = 0x10;
594 memory_.SetMemory(offset, &dyn, sizeof(dyn));
595 offset += sizeof(dyn);
596
597 dyn.d_tag = DT_NULL;
598 memory_.SetMemory(offset, &dyn, sizeof(dyn));
599
600 SetStringMemory(0x10010, "fake_soname.so");
601
602 ASSERT_TRUE(elf->Init());
603 std::string name;
604 ASSERT_FALSE(elf->GetSoname(&name));
605}
606
607TEST_F(ElfInterfaceTest, elf32_soname_size) {
608 SonameSize<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
609}
610
611TEST_F(ElfInterfaceTest, elf64_soname_size) {
612 SonameSize<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
613}
Christopher Ferris61d40972017-06-12 19:14:20 -0700614
615class MockElfInterface32 : public ElfInterface32 {
616 public:
617 MockElfInterface32(Memory* memory) : ElfInterface32(memory) {}
618 virtual ~MockElfInterface32() = default;
619
620 void TestSetEhFrameOffset(uint64_t offset) { eh_frame_offset_ = offset; }
621 void TestSetEhFrameSize(uint64_t size) { eh_frame_size_ = size; }
622
623 void TestSetDebugFrameOffset(uint64_t offset) { debug_frame_offset_ = offset; }
624 void TestSetDebugFrameSize(uint64_t size) { debug_frame_size_ = size; }
625};
626
627class MockElfInterface64 : public ElfInterface64 {
628 public:
629 MockElfInterface64(Memory* memory) : ElfInterface64(memory) {}
630 virtual ~MockElfInterface64() = default;
631
632 void TestSetEhFrameOffset(uint64_t offset) { eh_frame_offset_ = offset; }
633 void TestSetEhFrameSize(uint64_t size) { eh_frame_size_ = size; }
634
635 void TestSetDebugFrameOffset(uint64_t offset) { debug_frame_offset_ = offset; }
636 void TestSetDebugFrameSize(uint64_t size) { debug_frame_size_ = size; }
637};
638
639template <typename ElfType>
640void ElfInterfaceTest::InitHeadersEhFrameTest() {
641 ElfType elf(&memory_);
642
643 elf.TestSetEhFrameOffset(0x10000);
644 elf.TestSetEhFrameSize(0);
645 elf.TestSetDebugFrameOffset(0);
646 elf.TestSetDebugFrameSize(0);
647
648 memory_.SetMemory(0x10000,
649 std::vector<uint8_t>{0x1, DW_EH_PE_udata2, DW_EH_PE_udata2, DW_EH_PE_udata2});
650 memory_.SetData32(0x10004, 0x500);
651 memory_.SetData32(0x10008, 250);
652
653 elf.InitHeaders();
654
655 EXPECT_FALSE(elf.eh_frame() == nullptr);
656 EXPECT_TRUE(elf.debug_frame() == nullptr);
657}
658
659TEST_F(ElfInterfaceTest, init_headers_eh_frame32) {
660 InitHeadersEhFrameTest<MockElfInterface32>();
661}
662
663TEST_F(ElfInterfaceTest, init_headers_eh_frame64) {
664 InitHeadersEhFrameTest<MockElfInterface64>();
665}
666
667template <typename ElfType>
668void ElfInterfaceTest::InitHeadersDebugFrame() {
669 ElfType elf(&memory_);
670
671 elf.TestSetEhFrameOffset(0);
672 elf.TestSetEhFrameSize(0);
673 elf.TestSetDebugFrameOffset(0x5000);
674 elf.TestSetDebugFrameSize(0x200);
675
676 memory_.SetData32(0x5000, 0xfc);
677 memory_.SetData32(0x5004, 0xffffffff);
678 memory_.SetData8(0x5008, 1);
679 memory_.SetData8(0x5009, '\0');
680
681 memory_.SetData32(0x5100, 0xfc);
682 memory_.SetData32(0x5104, 0);
683 memory_.SetData32(0x5108, 0x1500);
684 memory_.SetData32(0x510c, 0x200);
685
686 elf.InitHeaders();
687
688 EXPECT_TRUE(elf.eh_frame() == nullptr);
689 EXPECT_FALSE(elf.debug_frame() == nullptr);
690}
691
692TEST_F(ElfInterfaceTest, init_headers_debug_frame32) {
693 InitHeadersDebugFrame<MockElfInterface32>();
694}
695
696TEST_F(ElfInterfaceTest, init_headers_debug_frame64) {
697 InitHeadersDebugFrame<MockElfInterface64>();
698}
699
700template <typename ElfType>
701void ElfInterfaceTest::InitHeadersEhFrameFail() {
702 ElfType elf(&memory_);
703
704 elf.TestSetEhFrameOffset(0x1000);
705 elf.TestSetEhFrameSize(0x100);
706 elf.TestSetDebugFrameOffset(0);
707 elf.TestSetDebugFrameSize(0);
708
709 elf.InitHeaders();
710
711 EXPECT_TRUE(elf.eh_frame() == nullptr);
712 EXPECT_EQ(0U, elf.eh_frame_offset());
713 EXPECT_EQ(static_cast<uint64_t>(-1), elf.eh_frame_size());
714 EXPECT_TRUE(elf.debug_frame() == nullptr);
715}
716
717TEST_F(ElfInterfaceTest, init_headers_eh_frame32_fail) {
718 InitHeadersEhFrameFail<MockElfInterface32>();
719}
720
721TEST_F(ElfInterfaceTest, init_headers_eh_frame64_fail) {
722 InitHeadersEhFrameFail<MockElfInterface64>();
723}
724
725template <typename ElfType>
726void ElfInterfaceTest::InitHeadersDebugFrameFail() {
727 ElfType elf(&memory_);
728
729 elf.TestSetEhFrameOffset(0);
730 elf.TestSetEhFrameSize(0);
731 elf.TestSetDebugFrameOffset(0x1000);
732 elf.TestSetDebugFrameSize(0x100);
733
734 elf.InitHeaders();
735
736 EXPECT_TRUE(elf.eh_frame() == nullptr);
737 EXPECT_TRUE(elf.debug_frame() == nullptr);
738 EXPECT_EQ(0U, elf.debug_frame_offset());
739 EXPECT_EQ(static_cast<uint64_t>(-1), elf.debug_frame_size());
740}
741
742TEST_F(ElfInterfaceTest, init_headers_debug_frame32_fail) {
743 InitHeadersDebugFrameFail<MockElfInterface32>();
744}
745
746TEST_F(ElfInterfaceTest, init_headers_debug_frame64_fail) {
747 InitHeadersDebugFrameFail<MockElfInterface64>();
748}
Christopher Ferris8098b1c2017-06-20 13:54:08 -0700749
750template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
751void ElfInterfaceTest::InitSectionHeadersMalformed() {
752 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
753
754 Ehdr ehdr;
755 memset(&ehdr, 0, sizeof(ehdr));
756 ehdr.e_shoff = 0x1000;
757 ehdr.e_shnum = 10;
758 ehdr.e_shentsize = sizeof(Shdr);
759 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
760
761 ASSERT_TRUE(elf->Init());
762}
763
764TEST_F(ElfInterfaceTest, init_section_headers_malformed32) {
765 InitSectionHeadersMalformed<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>();
766}
767
768TEST_F(ElfInterfaceTest, init_section_headers_malformed64) {
769 InitSectionHeadersMalformed<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>();
770}
771
772template <typename Ehdr, typename Shdr, typename Sym, typename ElfInterfaceType>
773void ElfInterfaceTest::InitSectionHeaders(uint64_t entry_size) {
774 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
775
776 uint64_t offset = 0x1000;
777
778 Ehdr ehdr;
779 memset(&ehdr, 0, sizeof(ehdr));
780 ehdr.e_shoff = offset;
781 ehdr.e_shnum = 10;
782 ehdr.e_shentsize = entry_size;
783 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
784
785 offset += ehdr.e_shentsize;
786
787 Shdr shdr;
788 memset(&shdr, 0, sizeof(shdr));
789 shdr.sh_type = SHT_SYMTAB;
790 shdr.sh_link = 4;
791 shdr.sh_addr = 0x5000;
792 shdr.sh_offset = 0x5000;
793 shdr.sh_entsize = sizeof(Sym);
794 shdr.sh_size = shdr.sh_entsize * 10;
795 memory_.SetMemory(offset, &shdr, sizeof(shdr));
796 offset += ehdr.e_shentsize;
797
798 memset(&shdr, 0, sizeof(shdr));
799 shdr.sh_type = SHT_DYNSYM;
800 shdr.sh_link = 4;
801 shdr.sh_addr = 0x6000;
802 shdr.sh_offset = 0x6000;
803 shdr.sh_entsize = sizeof(Sym);
804 shdr.sh_size = shdr.sh_entsize * 10;
805 memory_.SetMemory(offset, &shdr, sizeof(shdr));
806 offset += ehdr.e_shentsize;
807
808 memset(&shdr, 0, sizeof(shdr));
809 shdr.sh_type = SHT_PROGBITS;
810 shdr.sh_name = 0xa000;
811 memory_.SetMemory(offset, &shdr, sizeof(shdr));
812 offset += ehdr.e_shentsize;
813
814 // The string data for the entries.
815 memset(&shdr, 0, sizeof(shdr));
816 shdr.sh_type = SHT_STRTAB;
817 shdr.sh_name = 0x20000;
818 shdr.sh_offset = 0xf000;
819 shdr.sh_size = 0x1000;
820 memory_.SetMemory(offset, &shdr, sizeof(shdr));
821 offset += ehdr.e_shentsize;
822
823 InitSym<Sym>(0x5000, 0x90000, 0x1000, 0x100, 0xf000, "function_one");
824 InitSym<Sym>(0x6000, 0xd0000, 0x1000, 0x300, 0xf000, "function_two");
825
826 ASSERT_TRUE(elf->Init());
827 EXPECT_EQ(0U, elf->debug_frame_offset());
828 EXPECT_EQ(0U, elf->debug_frame_size());
829 EXPECT_EQ(0U, elf->gnu_debugdata_offset());
830 EXPECT_EQ(0U, elf->gnu_debugdata_size());
831
832 // Look in the first symbol table.
833 std::string name;
834 uint64_t name_offset;
835 ASSERT_TRUE(elf->GetFunctionName(0x90010, &name, &name_offset));
836 EXPECT_EQ("function_one", name);
837 EXPECT_EQ(16U, name_offset);
838 ASSERT_TRUE(elf->GetFunctionName(0xd0020, &name, &name_offset));
839 EXPECT_EQ("function_two", name);
840 EXPECT_EQ(32U, name_offset);
841}
842
843TEST_F(ElfInterfaceTest, init_section_headers32) {
844 InitSectionHeaders<Elf32_Ehdr, Elf32_Shdr, Elf32_Sym, ElfInterface32>(sizeof(Elf32_Shdr));
845}
846
847TEST_F(ElfInterfaceTest, init_section_headers64) {
848 InitSectionHeaders<Elf64_Ehdr, Elf64_Shdr, Elf64_Sym, ElfInterface64>(sizeof(Elf64_Shdr));
849}
850
851TEST_F(ElfInterfaceTest, init_section_headers_non_std_entry_size32) {
852 InitSectionHeaders<Elf32_Ehdr, Elf32_Shdr, Elf32_Sym, ElfInterface32>(0x100);
853}
854
855TEST_F(ElfInterfaceTest, init_section_headers_non_std_entry_size64) {
856 InitSectionHeaders<Elf64_Ehdr, Elf64_Shdr, Elf64_Sym, ElfInterface64>(0x100);
857}
858
859template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
860void ElfInterfaceTest::InitSectionHeadersOffsets() {
861 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
862
863 uint64_t offset = 0x2000;
864
865 Ehdr ehdr;
866 memset(&ehdr, 0, sizeof(ehdr));
867 ehdr.e_shoff = offset;
868 ehdr.e_shnum = 10;
869 ehdr.e_shentsize = sizeof(Shdr);
870 ehdr.e_shstrndx = 2;
871 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
872
873 offset += ehdr.e_shentsize;
874
875 Shdr shdr;
876 memset(&shdr, 0, sizeof(shdr));
877 shdr.sh_type = SHT_PROGBITS;
878 shdr.sh_link = 2;
879 shdr.sh_name = 0x200;
880 shdr.sh_addr = 0x5000;
881 shdr.sh_offset = 0x5000;
882 shdr.sh_entsize = 0x100;
883 shdr.sh_size = 0x800;
884 memory_.SetMemory(offset, &shdr, sizeof(shdr));
885 offset += ehdr.e_shentsize;
886
887 // The string data for section header names.
888 memset(&shdr, 0, sizeof(shdr));
889 shdr.sh_type = SHT_STRTAB;
890 shdr.sh_name = 0x20000;
891 shdr.sh_offset = 0xf000;
892 shdr.sh_size = 0x1000;
893 memory_.SetMemory(offset, &shdr, sizeof(shdr));
894 offset += ehdr.e_shentsize;
895
896 memset(&shdr, 0, sizeof(shdr));
897 shdr.sh_type = SHT_PROGBITS;
898 shdr.sh_link = 2;
899 shdr.sh_name = 0x100;
900 shdr.sh_addr = 0x6000;
901 shdr.sh_offset = 0x6000;
902 shdr.sh_entsize = 0x100;
903 shdr.sh_size = 0x500;
904 memory_.SetMemory(offset, &shdr, sizeof(shdr));
905 offset += ehdr.e_shentsize;
906
907 memory_.SetMemory(0xf100, ".debug_frame", sizeof(".debug_frame"));
908 memory_.SetMemory(0xf200, ".gnu_debugdata", sizeof(".gnu_debugdata"));
909
910 ASSERT_TRUE(elf->Init());
911 EXPECT_EQ(0x6000U, elf->debug_frame_offset());
912 EXPECT_EQ(0x500U, elf->debug_frame_size());
913 EXPECT_EQ(0x5000U, elf->gnu_debugdata_offset());
914 EXPECT_EQ(0x800U, elf->gnu_debugdata_size());
915}
916
917TEST_F(ElfInterfaceTest, init_section_headers_offsets32) {
918 InitSectionHeadersOffsets<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>();
919}
920
921TEST_F(ElfInterfaceTest, init_section_headers_offsets64) {
922 InitSectionHeadersOffsets<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>();
923}