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