1 /*
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 <unwindstack/ElfInterface.h>
24
25 #include "DwarfEncoding.h"
26 #include "ElfInterfaceArm.h"
27
28 #include "ElfFake.h"
29 #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
39 #if __has_feature(address_sanitizer)
40 // There is a test that tries to allocate a large value, allow it to fail
41 // if asan is enabled.
__asan_default_options()42 extern "C" const char* __asan_default_options() {
43 return "allocator_may_return_null=1";
44 }
45 #endif
46
47 namespace unwindstack {
48
49 class ElfInterfaceTest : public ::testing::Test {
50 protected:
SetUp()51 void SetUp() override {
52 memory_.Clear();
53 }
54
SetStringMemory(uint64_t offset,const char * string)55 void SetStringMemory(uint64_t offset, const char* string) {
56 memory_.SetMemory(offset, string, strlen(string) + 1);
57 }
58
59 template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
60 void SinglePtLoad();
61
62 template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
63 void MultipleExecutablePtLoads();
64
65 template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
66 void MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr();
67
68 template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
69 void NonExecutablePtLoads();
70
71 template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
72 void ManyPhdrs();
73
74 enum SonameTestEnum : uint8_t {
75 SONAME_NORMAL,
76 SONAME_DTNULL_AFTER,
77 SONAME_DTSIZE_SMALL,
78 SONAME_MISSING_MAP,
79 };
80
81 template <typename Ehdr, typename Phdr, typename Shdr, typename Dyn>
82 void SonameInit(SonameTestEnum test_type = SONAME_NORMAL);
83
84 template <typename ElfInterfaceType>
85 void Soname();
86
87 template <typename ElfInterfaceType>
88 void SonameAfterDtNull();
89
90 template <typename ElfInterfaceType>
91 void SonameSize();
92
93 template <typename ElfInterfaceType>
94 void SonameMissingMap();
95
96 template <typename ElfType>
97 void InitHeadersEhFrameTest();
98
99 template <typename ElfType>
100 void InitHeadersDebugFrame();
101
102 template <typename ElfType>
103 void InitHeadersEhFrameFail();
104
105 template <typename ElfType>
106 void InitHeadersDebugFrameFail();
107
108 template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
109 void InitProgramHeadersMalformed();
110
111 template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
112 void InitSectionHeadersMalformed();
113
114 template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
115 void InitSectionHeadersMalformedSymData();
116
117 template <typename Ehdr, typename Shdr, typename Sym, typename ElfInterfaceType>
118 void InitSectionHeaders(uint64_t entry_size);
119
120 template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
121 void InitSectionHeadersOffsets();
122
123 template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
124 void InitSectionHeadersOffsetsEhFrameSectionBias(uint64_t addr, uint64_t offset,
125 int64_t expected_bias);
126
127 template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
128 void InitSectionHeadersOffsetsEhFrameHdrSectionBias(uint64_t addr, uint64_t offset,
129 int64_t expected_bias);
130
131 template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
132 void InitSectionHeadersOffsetsDebugFrameSectionBias(uint64_t addr, uint64_t offset,
133 int64_t expected_bias);
134
135 template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
136 void CheckGnuEhFrame(uint64_t addr, uint64_t offset, int64_t expected_bias);
137
138 template <typename Sym>
139 void InitSym(uint64_t offset, uint32_t value, uint32_t size, uint32_t name_offset,
140 uint64_t sym_offset, const char* name);
141
142 template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
143 void BuildID();
144
145 template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
146 void BuildIDTwoNotes();
147
148 template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
149 void BuildIDSectionTooSmallForName();
150
151 template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
152 void BuildIDSectionTooSmallForDesc();
153
154 template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
155 void BuildIDSectionTooSmallForHeader();
156
157 template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
158 void CheckLoadBiasInFirstPhdr(int64_t load_bias);
159
160 template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
161 void CheckLoadBiasInFirstExecPhdr(uint64_t offset, uint64_t vaddr, int64_t load_bias);
162
163 MemoryFake memory_;
164 };
165
166 template <typename Sym>
InitSym(uint64_t offset,uint32_t value,uint32_t size,uint32_t name_offset,uint64_t sym_offset,const char * name)167 void ElfInterfaceTest::InitSym(uint64_t offset, uint32_t value, uint32_t size, uint32_t name_offset,
168 uint64_t sym_offset, const char* name) {
169 Sym sym = {};
170 sym.st_info = STT_FUNC;
171 sym.st_value = value;
172 sym.st_size = size;
173 sym.st_name = name_offset;
174 sym.st_shndx = SHN_COMMON;
175
176 memory_.SetMemory(offset, &sym, sizeof(sym));
177 memory_.SetMemory(sym_offset + name_offset, name, strlen(name) + 1);
178 }
179
180 template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
SinglePtLoad()181 void ElfInterfaceTest::SinglePtLoad() {
182 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
183
184 Ehdr ehdr = {};
185 ehdr.e_phoff = 0x100;
186 ehdr.e_phnum = 1;
187 ehdr.e_phentsize = sizeof(Phdr);
188 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
189
190 Phdr phdr = {};
191 phdr.p_type = PT_LOAD;
192 phdr.p_vaddr = 0x2000;
193 phdr.p_memsz = 0x10000;
194 phdr.p_flags = PF_R | PF_X;
195 phdr.p_align = 0x1000;
196 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
197
198 int64_t load_bias = 0;
199 ASSERT_TRUE(elf->Init(&load_bias));
200 EXPECT_EQ(0x2000, load_bias);
201
202 const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
203 ASSERT_EQ(1U, pt_loads.size());
204 LoadInfo load_data = pt_loads.at(0);
205 ASSERT_EQ(0U, load_data.offset);
206 ASSERT_EQ(0x2000U, load_data.table_offset);
207 ASSERT_EQ(0x10000U, load_data.table_size);
208 }
209
TEST_F(ElfInterfaceTest,single_pt_load_32)210 TEST_F(ElfInterfaceTest, single_pt_load_32) {
211 SinglePtLoad<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
212 }
213
TEST_F(ElfInterfaceTest,single_pt_load_64)214 TEST_F(ElfInterfaceTest, single_pt_load_64) {
215 SinglePtLoad<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
216 }
217
218 template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
MultipleExecutablePtLoads()219 void ElfInterfaceTest::MultipleExecutablePtLoads() {
220 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
221
222 Ehdr ehdr = {};
223 ehdr.e_phoff = 0x100;
224 ehdr.e_phnum = 3;
225 ehdr.e_phentsize = sizeof(Phdr);
226 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
227
228 Phdr phdr = {};
229 phdr.p_type = PT_LOAD;
230 phdr.p_vaddr = 0x2000;
231 phdr.p_memsz = 0x10000;
232 phdr.p_flags = PF_R | PF_X;
233 phdr.p_align = 0x1000;
234 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
235
236 memset(&phdr, 0, sizeof(phdr));
237 phdr.p_type = PT_LOAD;
238 phdr.p_offset = 0x1000;
239 phdr.p_vaddr = 0x2001;
240 phdr.p_memsz = 0x10001;
241 phdr.p_flags = PF_R | PF_X;
242 phdr.p_align = 0x1001;
243 memory_.SetMemory(0x100 + sizeof(phdr), &phdr, sizeof(phdr));
244
245 memset(&phdr, 0, sizeof(phdr));
246 phdr.p_type = PT_LOAD;
247 phdr.p_offset = 0x2000;
248 phdr.p_vaddr = 0x2002;
249 phdr.p_memsz = 0x10002;
250 phdr.p_flags = PF_R | PF_X;
251 phdr.p_align = 0x1002;
252 memory_.SetMemory(0x100 + 2 * sizeof(phdr), &phdr, sizeof(phdr));
253
254 int64_t load_bias = 0;
255 ASSERT_TRUE(elf->Init(&load_bias));
256 EXPECT_EQ(0x2000, load_bias);
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
TEST_F(ElfInterfaceTest,multiple_executable_pt_loads_32)277 TEST_F(ElfInterfaceTest, multiple_executable_pt_loads_32) {
278 MultipleExecutablePtLoads<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
279 }
280
TEST_F(ElfInterfaceTest,multiple_executable_pt_loads_64)281 TEST_F(ElfInterfaceTest, multiple_executable_pt_loads_64) {
282 MultipleExecutablePtLoads<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
283 }
284
285 template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr()286 void ElfInterfaceTest::MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr() {
287 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
288
289 Ehdr ehdr = {};
290 ehdr.e_phoff = 0x100;
291 ehdr.e_phnum = 3;
292 ehdr.e_phentsize = sizeof(Phdr) + 100;
293 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
294
295 Phdr phdr = {};
296 phdr.p_type = PT_LOAD;
297 phdr.p_vaddr = 0x2000;
298 phdr.p_memsz = 0x10000;
299 phdr.p_flags = PF_R | PF_X;
300 phdr.p_align = 0x1000;
301 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
302
303 memset(&phdr, 0, sizeof(phdr));
304 phdr.p_type = PT_LOAD;
305 phdr.p_offset = 0x1000;
306 phdr.p_vaddr = 0x2001;
307 phdr.p_memsz = 0x10001;
308 phdr.p_flags = PF_R | PF_X;
309 phdr.p_align = 0x1001;
310 memory_.SetMemory(0x100 + sizeof(phdr) + 100, &phdr, sizeof(phdr));
311
312 memset(&phdr, 0, sizeof(phdr));
313 phdr.p_type = PT_LOAD;
314 phdr.p_offset = 0x2000;
315 phdr.p_vaddr = 0x2002;
316 phdr.p_memsz = 0x10002;
317 phdr.p_flags = PF_R | PF_X;
318 phdr.p_align = 0x1002;
319 memory_.SetMemory(0x100 + 2 * (sizeof(phdr) + 100), &phdr, sizeof(phdr));
320
321 int64_t load_bias = 0;
322 ASSERT_TRUE(elf->Init(&load_bias));
323 EXPECT_EQ(0x2000, load_bias);
324
325 const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
326 ASSERT_EQ(3U, pt_loads.size());
327
328 LoadInfo load_data = pt_loads.at(0);
329 ASSERT_EQ(0U, load_data.offset);
330 ASSERT_EQ(0x2000U, load_data.table_offset);
331 ASSERT_EQ(0x10000U, load_data.table_size);
332
333 load_data = pt_loads.at(0x1000);
334 ASSERT_EQ(0x1000U, load_data.offset);
335 ASSERT_EQ(0x2001U, load_data.table_offset);
336 ASSERT_EQ(0x10001U, load_data.table_size);
337
338 load_data = pt_loads.at(0x2000);
339 ASSERT_EQ(0x2000U, load_data.offset);
340 ASSERT_EQ(0x2002U, load_data.table_offset);
341 ASSERT_EQ(0x10002U, load_data.table_size);
342 }
343
TEST_F(ElfInterfaceTest,multiple_executable_pt_loads_increments_not_size_of_phdr_32)344 TEST_F(ElfInterfaceTest, multiple_executable_pt_loads_increments_not_size_of_phdr_32) {
345 MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn,
346 ElfInterface32>();
347 }
348
TEST_F(ElfInterfaceTest,multiple_executable_pt_loads_increments_not_size_of_phdr_64)349 TEST_F(ElfInterfaceTest, multiple_executable_pt_loads_increments_not_size_of_phdr_64) {
350 MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn,
351 ElfInterface64>();
352 }
353
354 template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
NonExecutablePtLoads()355 void ElfInterfaceTest::NonExecutablePtLoads() {
356 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
357
358 Ehdr ehdr = {};
359 ehdr.e_phoff = 0x100;
360 ehdr.e_phnum = 3;
361 ehdr.e_phentsize = sizeof(Phdr);
362 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
363
364 Phdr phdr = {};
365 phdr.p_type = PT_LOAD;
366 phdr.p_vaddr = 0x2000;
367 phdr.p_memsz = 0x10000;
368 phdr.p_flags = PF_R;
369 phdr.p_align = 0x1000;
370 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
371
372 memset(&phdr, 0, sizeof(phdr));
373 phdr.p_type = PT_LOAD;
374 phdr.p_offset = 0x1000;
375 phdr.p_vaddr = 0x2001;
376 phdr.p_memsz = 0x10001;
377 phdr.p_flags = PF_R | PF_X;
378 phdr.p_align = 0x1001;
379 memory_.SetMemory(0x100 + sizeof(phdr), &phdr, sizeof(phdr));
380
381 memset(&phdr, 0, sizeof(phdr));
382 phdr.p_type = PT_LOAD;
383 phdr.p_offset = 0x2000;
384 phdr.p_vaddr = 0x2002;
385 phdr.p_memsz = 0x10002;
386 phdr.p_flags = PF_R;
387 phdr.p_align = 0x1002;
388 memory_.SetMemory(0x100 + 2 * sizeof(phdr), &phdr, sizeof(phdr));
389
390 int64_t load_bias = 0;
391 ASSERT_TRUE(elf->Init(&load_bias));
392 EXPECT_EQ(0x1001, load_bias);
393
394 const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
395 ASSERT_EQ(1U, pt_loads.size());
396
397 LoadInfo load_data = pt_loads.at(0x1000);
398 ASSERT_EQ(0x1000U, load_data.offset);
399 ASSERT_EQ(0x2001U, load_data.table_offset);
400 ASSERT_EQ(0x10001U, load_data.table_size);
401 }
402
TEST_F(ElfInterfaceTest,non_executable_pt_loads_32)403 TEST_F(ElfInterfaceTest, non_executable_pt_loads_32) {
404 NonExecutablePtLoads<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
405 }
406
TEST_F(ElfInterfaceTest,non_executable_pt_loads_64)407 TEST_F(ElfInterfaceTest, non_executable_pt_loads_64) {
408 NonExecutablePtLoads<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
409 }
410
411 template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
ManyPhdrs()412 void ElfInterfaceTest::ManyPhdrs() {
413 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
414
415 Ehdr ehdr = {};
416 ehdr.e_phoff = 0x100;
417 ehdr.e_phnum = 7;
418 ehdr.e_phentsize = sizeof(Phdr);
419 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
420
421 uint64_t phdr_offset = 0x100;
422
423 Phdr phdr = {};
424 phdr.p_type = PT_LOAD;
425 phdr.p_vaddr = 0x2000;
426 phdr.p_memsz = 0x10000;
427 phdr.p_flags = PF_R | PF_X;
428 phdr.p_align = 0x1000;
429 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
430 phdr_offset += sizeof(phdr);
431
432 memset(&phdr, 0, sizeof(phdr));
433 phdr.p_type = PT_GNU_EH_FRAME;
434 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
435 phdr_offset += sizeof(phdr);
436
437 memset(&phdr, 0, sizeof(phdr));
438 phdr.p_type = PT_DYNAMIC;
439 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
440 phdr_offset += sizeof(phdr);
441
442 memset(&phdr, 0, sizeof(phdr));
443 phdr.p_type = PT_INTERP;
444 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
445 phdr_offset += sizeof(phdr);
446
447 memset(&phdr, 0, sizeof(phdr));
448 phdr.p_type = PT_NOTE;
449 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
450 phdr_offset += sizeof(phdr);
451
452 memset(&phdr, 0, sizeof(phdr));
453 phdr.p_type = PT_SHLIB;
454 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
455 phdr_offset += sizeof(phdr);
456
457 memset(&phdr, 0, sizeof(phdr));
458 phdr.p_type = PT_GNU_EH_FRAME;
459 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
460
461 int64_t load_bias = 0;
462 ASSERT_TRUE(elf->Init(&load_bias));
463 EXPECT_EQ(0x2000, load_bias);
464
465 const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
466 ASSERT_EQ(1U, pt_loads.size());
467
468 LoadInfo load_data = pt_loads.at(0);
469 ASSERT_EQ(0U, load_data.offset);
470 ASSERT_EQ(0x2000U, load_data.table_offset);
471 ASSERT_EQ(0x10000U, load_data.table_size);
472 }
473
TEST_F(ElfInterfaceTest,many_phdrs_32)474 TEST_F(ElfInterfaceTest, many_phdrs_32) {
475 ElfInterfaceTest::ManyPhdrs<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
476 }
477
TEST_F(ElfInterfaceTest,many_phdrs_64)478 TEST_F(ElfInterfaceTest, many_phdrs_64) {
479 ElfInterfaceTest::ManyPhdrs<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
480 }
481
TEST_F(ElfInterfaceTest,arm32)482 TEST_F(ElfInterfaceTest, arm32) {
483 ElfInterfaceArm elf_arm(&memory_);
484
485 Elf32_Ehdr ehdr = {};
486 ehdr.e_phoff = 0x100;
487 ehdr.e_phnum = 1;
488 ehdr.e_phentsize = sizeof(Elf32_Phdr);
489 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
490
491 Elf32_Phdr phdr = {};
492 phdr.p_type = PT_ARM_EXIDX;
493 phdr.p_offset = 0x2000;
494 phdr.p_filesz = 16;
495 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
496
497 // Add arm exidx entries.
498 memory_.SetData32(0x2000, 0x1000);
499 memory_.SetData32(0x2008, 0x1000);
500
501 int64_t load_bias = 0;
502 ASSERT_TRUE(elf_arm.Init(&load_bias));
503 EXPECT_EQ(0, load_bias);
504
505 std::vector<uint32_t> entries;
506 for (auto addr : elf_arm) {
507 entries.push_back(addr);
508 }
509 ASSERT_EQ(2U, entries.size());
510 ASSERT_EQ(0x3000U, entries[0]);
511 ASSERT_EQ(0x3008U, entries[1]);
512
513 ASSERT_EQ(0x2000U, elf_arm.start_offset());
514 ASSERT_EQ(2U, elf_arm.total_entries());
515 }
516
517 template <typename Ehdr, typename Phdr, typename Shdr, typename Dyn>
SonameInit(SonameTestEnum test_type)518 void ElfInterfaceTest::SonameInit(SonameTestEnum test_type) {
519 Ehdr ehdr = {};
520 ehdr.e_shoff = 0x200;
521 ehdr.e_shnum = 2;
522 ehdr.e_shentsize = sizeof(Shdr);
523 ehdr.e_phoff = 0x100;
524 ehdr.e_phnum = 1;
525 ehdr.e_phentsize = sizeof(Phdr);
526 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
527
528 Shdr shdr = {};
529 shdr.sh_type = SHT_STRTAB;
530 if (test_type == SONAME_MISSING_MAP) {
531 shdr.sh_addr = 0x20100;
532 } else {
533 shdr.sh_addr = 0x10100;
534 }
535 shdr.sh_offset = 0x10000;
536 memory_.SetMemory(0x200 + sizeof(shdr), &shdr, sizeof(shdr));
537
538 Phdr 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 uint64_t offset = 0x2000;
545 Dyn dyn;
546
547 dyn.d_tag = DT_STRTAB;
548 dyn.d_un.d_ptr = 0x10100;
549 memory_.SetMemory(offset, &dyn, sizeof(dyn));
550 offset += sizeof(dyn);
551
552 dyn.d_tag = DT_STRSZ;
553 if (test_type == SONAME_DTSIZE_SMALL) {
554 dyn.d_un.d_val = 0x10;
555 } else {
556 dyn.d_un.d_val = 0x1000;
557 }
558 memory_.SetMemory(offset, &dyn, sizeof(dyn));
559 offset += sizeof(dyn);
560
561 if (test_type == SONAME_DTNULL_AFTER) {
562 dyn.d_tag = DT_NULL;
563 memory_.SetMemory(offset, &dyn, sizeof(dyn));
564 offset += sizeof(dyn);
565 }
566
567 dyn.d_tag = DT_SONAME;
568 dyn.d_un.d_val = 0x10;
569 memory_.SetMemory(offset, &dyn, sizeof(dyn));
570 offset += sizeof(dyn);
571
572 dyn.d_tag = DT_NULL;
573 memory_.SetMemory(offset, &dyn, sizeof(dyn));
574
575 SetStringMemory(0x10010, "fake_soname.so");
576 }
577
578 template <typename ElfInterfaceType>
Soname()579 void ElfInterfaceTest::Soname() {
580 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
581
582 int64_t load_bias = 0;
583 ASSERT_TRUE(elf->Init(&load_bias));
584 EXPECT_EQ(0, load_bias);
585
586 ASSERT_EQ("fake_soname.so", elf->GetSoname());
587 }
588
TEST_F(ElfInterfaceTest,soname_32)589 TEST_F(ElfInterfaceTest, soname_32) {
590 SonameInit<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Dyn>();
591 Soname<ElfInterface32>();
592 }
593
TEST_F(ElfInterfaceTest,soname_64)594 TEST_F(ElfInterfaceTest, soname_64) {
595 SonameInit<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Dyn>();
596 Soname<ElfInterface64>();
597 }
598
599 template <typename ElfInterfaceType>
SonameAfterDtNull()600 void ElfInterfaceTest::SonameAfterDtNull() {
601 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
602
603 int64_t load_bias = 0;
604 ASSERT_TRUE(elf->Init(&load_bias));
605 EXPECT_EQ(0, load_bias);
606
607 ASSERT_EQ("", elf->GetSoname());
608 }
609
TEST_F(ElfInterfaceTest,soname_after_dt_null_32)610 TEST_F(ElfInterfaceTest, soname_after_dt_null_32) {
611 SonameInit<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Dyn>(SONAME_DTNULL_AFTER);
612 SonameAfterDtNull<ElfInterface32>();
613 }
614
TEST_F(ElfInterfaceTest,soname_after_dt_null_64)615 TEST_F(ElfInterfaceTest, soname_after_dt_null_64) {
616 SonameInit<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Dyn>(SONAME_DTNULL_AFTER);
617 SonameAfterDtNull<ElfInterface64>();
618 }
619
620 template <typename ElfInterfaceType>
SonameSize()621 void ElfInterfaceTest::SonameSize() {
622 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
623
624 int64_t load_bias = 0;
625 ASSERT_TRUE(elf->Init(&load_bias));
626 EXPECT_EQ(0, load_bias);
627
628 ASSERT_EQ("", elf->GetSoname());
629 }
630
TEST_F(ElfInterfaceTest,soname_size_32)631 TEST_F(ElfInterfaceTest, soname_size_32) {
632 SonameInit<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Dyn>(SONAME_DTSIZE_SMALL);
633 SonameSize<ElfInterface32>();
634 }
635
TEST_F(ElfInterfaceTest,soname_size_64)636 TEST_F(ElfInterfaceTest, soname_size_64) {
637 SonameInit<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Dyn>(SONAME_DTSIZE_SMALL);
638 SonameSize<ElfInterface64>();
639 }
640
641 // Verify that there is no map from STRTAB in the dynamic section to a
642 // STRTAB entry in the section headers.
643 template <typename ElfInterfaceType>
SonameMissingMap()644 void ElfInterfaceTest::SonameMissingMap() {
645 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
646
647 int64_t load_bias = 0;
648 ASSERT_TRUE(elf->Init(&load_bias));
649 EXPECT_EQ(0, load_bias);
650
651 ASSERT_EQ("", elf->GetSoname());
652 }
653
TEST_F(ElfInterfaceTest,soname_missing_map_32)654 TEST_F(ElfInterfaceTest, soname_missing_map_32) {
655 SonameInit<Elf32_Ehdr, Elf32_Phdr, Elf32_Shdr, Elf32_Dyn>(SONAME_MISSING_MAP);
656 SonameMissingMap<ElfInterface32>();
657 }
658
TEST_F(ElfInterfaceTest,soname_missing_map_64)659 TEST_F(ElfInterfaceTest, soname_missing_map_64) {
660 SonameInit<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, Elf64_Dyn>(SONAME_MISSING_MAP);
661 SonameMissingMap<ElfInterface64>();
662 }
663
664 template <typename ElfType>
InitHeadersEhFrameTest()665 void ElfInterfaceTest::InitHeadersEhFrameTest() {
666 ElfType elf(&memory_);
667
668 elf.FakeSetEhFrameOffset(0x10000);
669 elf.FakeSetEhFrameSize(0);
670 elf.FakeSetDebugFrameOffset(0);
671 elf.FakeSetDebugFrameSize(0);
672
673 memory_.SetMemory(0x10000,
674 std::vector<uint8_t>{0x1, DW_EH_PE_udata2, DW_EH_PE_udata2, DW_EH_PE_udata2});
675 memory_.SetData32(0x10004, 0x500);
676 memory_.SetData32(0x10008, 250);
677
678 elf.InitHeaders();
679
680 EXPECT_FALSE(elf.eh_frame() == nullptr);
681 EXPECT_TRUE(elf.debug_frame() == nullptr);
682 }
683
TEST_F(ElfInterfaceTest,init_headers_eh_frame_32)684 TEST_F(ElfInterfaceTest, init_headers_eh_frame_32) {
685 InitHeadersEhFrameTest<ElfInterface32Fake>();
686 }
687
TEST_F(ElfInterfaceTest,init_headers_eh_frame_64)688 TEST_F(ElfInterfaceTest, init_headers_eh_frame_64) {
689 InitHeadersEhFrameTest<ElfInterface64Fake>();
690 }
691
692 template <typename ElfType>
InitHeadersDebugFrame()693 void ElfInterfaceTest::InitHeadersDebugFrame() {
694 ElfType elf(&memory_);
695
696 elf.FakeSetEhFrameOffset(0);
697 elf.FakeSetEhFrameSize(0);
698 elf.FakeSetDebugFrameOffset(0x5000);
699 elf.FakeSetDebugFrameSize(0x200);
700
701 memory_.SetData32(0x5000, 0xfc);
702 memory_.SetData32(0x5004, 0xffffffff);
703 memory_.SetMemory(0x5008, std::vector<uint8_t>{1, '\0', 4, 8, 2});
704
705 memory_.SetData32(0x5100, 0xfc);
706 memory_.SetData32(0x5104, 0);
707 memory_.SetData32(0x5108, 0x1500);
708 memory_.SetData32(0x510c, 0x200);
709
710 elf.InitHeaders();
711
712 EXPECT_TRUE(elf.eh_frame() == nullptr);
713 EXPECT_FALSE(elf.debug_frame() == nullptr);
714 }
715
TEST_F(ElfInterfaceTest,init_headers_debug_frame_32)716 TEST_F(ElfInterfaceTest, init_headers_debug_frame_32) {
717 InitHeadersDebugFrame<ElfInterface32Fake>();
718 }
719
TEST_F(ElfInterfaceTest,init_headers_debug_frame_64)720 TEST_F(ElfInterfaceTest, init_headers_debug_frame_64) {
721 InitHeadersDebugFrame<ElfInterface64Fake>();
722 }
723
724 template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
InitProgramHeadersMalformed()725 void ElfInterfaceTest::InitProgramHeadersMalformed() {
726 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
727
728 Ehdr ehdr = {};
729 ehdr.e_phoff = 0x100;
730 ehdr.e_phnum = 3;
731 ehdr.e_phentsize = sizeof(Phdr);
732 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
733
734 int64_t load_bias = 0;
735 ASSERT_TRUE(elf->Init(&load_bias));
736 EXPECT_EQ(0, load_bias);
737 }
738
TEST_F(ElfInterfaceTest,init_program_headers_malformed_32)739 TEST_F(ElfInterfaceTest, init_program_headers_malformed_32) {
740 InitProgramHeadersMalformed<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>();
741 }
742
TEST_F(ElfInterfaceTest,init_program_headers_malformed_64)743 TEST_F(ElfInterfaceTest, init_program_headers_malformed_64) {
744 InitProgramHeadersMalformed<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>();
745 }
746
747 template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
InitSectionHeadersMalformed()748 void ElfInterfaceTest::InitSectionHeadersMalformed() {
749 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
750
751 Ehdr ehdr = {};
752 ehdr.e_shoff = 0x1000;
753 ehdr.e_shnum = 10;
754 ehdr.e_shentsize = sizeof(Shdr);
755 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
756
757 int64_t load_bias = 0;
758 ASSERT_TRUE(elf->Init(&load_bias));
759 EXPECT_EQ(0, load_bias);
760 }
761
TEST_F(ElfInterfaceTest,init_section_headers_malformed_32)762 TEST_F(ElfInterfaceTest, init_section_headers_malformed_32) {
763 InitSectionHeadersMalformed<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>();
764 }
765
TEST_F(ElfInterfaceTest,init_section_headers_malformed_64)766 TEST_F(ElfInterfaceTest, init_section_headers_malformed_64) {
767 InitSectionHeadersMalformed<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>();
768 }
769
770 template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
InitSectionHeadersMalformedSymData()771 void ElfInterfaceTest::InitSectionHeadersMalformedSymData() {
772 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
773
774 uint64_t offset = 0x1000;
775
776 Ehdr ehdr = {};
777 ehdr.e_shoff = offset;
778 ehdr.e_shnum = 5;
779 ehdr.e_shentsize = sizeof(Shdr);
780 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
781
782 offset += ehdr.e_shentsize;
783
784 Shdr shdr = {};
785 shdr.sh_type = SHT_SYMTAB;
786 shdr.sh_link = 4;
787 shdr.sh_addr = 0x5000;
788 shdr.sh_offset = 0x5000;
789 shdr.sh_entsize = 0x100;
790 shdr.sh_size = shdr.sh_entsize * 10;
791 memory_.SetMemory(offset, &shdr, sizeof(shdr));
792 offset += ehdr.e_shentsize;
793
794 memset(&shdr, 0, sizeof(shdr));
795 shdr.sh_type = SHT_DYNSYM;
796 shdr.sh_link = 10;
797 shdr.sh_addr = 0x6000;
798 shdr.sh_offset = 0x6000;
799 shdr.sh_entsize = 0x100;
800 shdr.sh_size = shdr.sh_entsize * 10;
801 memory_.SetMemory(offset, &shdr, sizeof(shdr));
802 offset += ehdr.e_shentsize;
803
804 memset(&shdr, 0, sizeof(shdr));
805 shdr.sh_type = SHT_DYNSYM;
806 shdr.sh_link = 2;
807 shdr.sh_addr = 0x6000;
808 shdr.sh_offset = 0x6000;
809 shdr.sh_entsize = 0x100;
810 shdr.sh_size = shdr.sh_entsize * 10;
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
822 int64_t load_bias = 0;
823 ASSERT_TRUE(elf->Init(&load_bias));
824 EXPECT_EQ(0, load_bias);
825 EXPECT_EQ(0U, elf->debug_frame_offset());
826 EXPECT_EQ(0U, elf->debug_frame_size());
827 EXPECT_EQ(0U, elf->gnu_debugdata_offset());
828 EXPECT_EQ(0U, elf->gnu_debugdata_size());
829
830 SharedString name;
831 uint64_t name_offset;
832 ASSERT_FALSE(elf->GetFunctionName(0x90010, &name, &name_offset));
833 }
834
TEST_F(ElfInterfaceTest,init_section_headers_malformed_symdata_32)835 TEST_F(ElfInterfaceTest, init_section_headers_malformed_symdata_32) {
836 InitSectionHeadersMalformedSymData<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>();
837 }
838
TEST_F(ElfInterfaceTest,init_section_headers_malformed_symdata_64)839 TEST_F(ElfInterfaceTest, init_section_headers_malformed_symdata_64) {
840 InitSectionHeadersMalformedSymData<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>();
841 }
842
843 template <typename Ehdr, typename Shdr, typename Sym, typename ElfInterfaceType>
InitSectionHeaders(uint64_t entry_size)844 void ElfInterfaceTest::InitSectionHeaders(uint64_t entry_size) {
845 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
846
847 uint64_t offset = 0x1000;
848
849 Ehdr ehdr = {};
850 ehdr.e_shoff = offset;
851 ehdr.e_shnum = 5;
852 ehdr.e_shentsize = entry_size;
853 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
854
855 offset += ehdr.e_shentsize;
856
857 Shdr shdr = {};
858 shdr.sh_type = SHT_SYMTAB;
859 shdr.sh_link = 4;
860 shdr.sh_addr = 0x5000;
861 shdr.sh_offset = 0x5000;
862 shdr.sh_entsize = sizeof(Sym);
863 shdr.sh_size = shdr.sh_entsize * 10;
864 memory_.SetMemory(offset, &shdr, sizeof(shdr));
865 offset += ehdr.e_shentsize;
866
867 memset(&shdr, 0, sizeof(shdr));
868 shdr.sh_type = SHT_DYNSYM;
869 shdr.sh_link = 4;
870 shdr.sh_addr = 0x6000;
871 shdr.sh_offset = 0x6000;
872 shdr.sh_entsize = sizeof(Sym);
873 shdr.sh_size = shdr.sh_entsize * 10;
874 memory_.SetMemory(offset, &shdr, sizeof(shdr));
875 offset += ehdr.e_shentsize;
876
877 memset(&shdr, 0, sizeof(shdr));
878 shdr.sh_type = SHT_PROGBITS;
879 shdr.sh_name = 0xa000;
880 memory_.SetMemory(offset, &shdr, sizeof(shdr));
881 offset += ehdr.e_shentsize;
882
883 // The string data for the entries.
884 memset(&shdr, 0, sizeof(shdr));
885 shdr.sh_type = SHT_STRTAB;
886 shdr.sh_name = 0x20000;
887 shdr.sh_offset = 0xf000;
888 shdr.sh_size = 0x1000;
889 memory_.SetMemory(offset, &shdr, sizeof(shdr));
890
891 InitSym<Sym>(0x5000, 0x90000, 0x1000, 0x100, 0xf000, "function_one");
892 InitSym<Sym>(0x6000, 0xd0000, 0x1000, 0x300, 0xf000, "function_two");
893
894 int64_t load_bias = 0;
895 ASSERT_TRUE(elf->Init(&load_bias));
896 EXPECT_EQ(0, load_bias);
897 EXPECT_EQ(0U, elf->debug_frame_offset());
898 EXPECT_EQ(0U, elf->debug_frame_size());
899 EXPECT_EQ(0U, elf->gnu_debugdata_offset());
900 EXPECT_EQ(0U, elf->gnu_debugdata_size());
901
902 // Look in the first symbol table.
903 SharedString name;
904 uint64_t name_offset;
905 ASSERT_TRUE(elf->GetFunctionName(0x90010, &name, &name_offset));
906 EXPECT_EQ("function_one", name);
907 EXPECT_EQ(16U, name_offset);
908 ASSERT_TRUE(elf->GetFunctionName(0xd0020, &name, &name_offset));
909 EXPECT_EQ("function_two", name);
910 EXPECT_EQ(32U, name_offset);
911 }
912
TEST_F(ElfInterfaceTest,init_section_headers_32)913 TEST_F(ElfInterfaceTest, init_section_headers_32) {
914 InitSectionHeaders<Elf32_Ehdr, Elf32_Shdr, Elf32_Sym, ElfInterface32>(sizeof(Elf32_Shdr));
915 }
916
TEST_F(ElfInterfaceTest,init_section_headers_64)917 TEST_F(ElfInterfaceTest, init_section_headers_64) {
918 InitSectionHeaders<Elf64_Ehdr, Elf64_Shdr, Elf64_Sym, ElfInterface64>(sizeof(Elf64_Shdr));
919 }
920
TEST_F(ElfInterfaceTest,init_section_headers_non_std_entry_size_32)921 TEST_F(ElfInterfaceTest, init_section_headers_non_std_entry_size_32) {
922 InitSectionHeaders<Elf32_Ehdr, Elf32_Shdr, Elf32_Sym, ElfInterface32>(0x100);
923 }
924
TEST_F(ElfInterfaceTest,init_section_headers_non_std_entry_size_64)925 TEST_F(ElfInterfaceTest, init_section_headers_non_std_entry_size_64) {
926 InitSectionHeaders<Elf64_Ehdr, Elf64_Shdr, Elf64_Sym, ElfInterface64>(0x100);
927 }
928
929 template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
InitSectionHeadersOffsets()930 void ElfInterfaceTest::InitSectionHeadersOffsets() {
931 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
932
933 uint64_t offset = 0x2000;
934
935 Ehdr ehdr = {};
936 ehdr.e_shoff = offset;
937 ehdr.e_shnum = 7;
938 ehdr.e_shentsize = sizeof(Shdr);
939 ehdr.e_shstrndx = 2;
940 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
941
942 offset += ehdr.e_shentsize;
943
944 Shdr shdr = {};
945 shdr.sh_type = SHT_PROGBITS;
946 shdr.sh_link = 2;
947 shdr.sh_name = 0x200;
948 shdr.sh_addr = 0x5000;
949 shdr.sh_offset = 0x5000;
950 shdr.sh_entsize = 0x100;
951 shdr.sh_size = 0x800;
952 memory_.SetMemory(offset, &shdr, sizeof(shdr));
953 offset += ehdr.e_shentsize;
954
955 // The string data for section header names.
956 memset(&shdr, 0, sizeof(shdr));
957 shdr.sh_type = SHT_STRTAB;
958 shdr.sh_name = 0x20000;
959 shdr.sh_offset = 0xf000;
960 shdr.sh_size = 0x1000;
961 memory_.SetMemory(offset, &shdr, sizeof(shdr));
962 offset += ehdr.e_shentsize;
963
964 memset(&shdr, 0, sizeof(shdr));
965 shdr.sh_type = SHT_PROGBITS;
966 shdr.sh_link = 2;
967 shdr.sh_name = 0x100;
968 shdr.sh_addr = 0x6000;
969 shdr.sh_offset = 0x6000;
970 shdr.sh_entsize = 0x100;
971 shdr.sh_size = 0x500;
972 memory_.SetMemory(offset, &shdr, sizeof(shdr));
973 offset += ehdr.e_shentsize;
974
975 memset(&shdr, 0, sizeof(shdr));
976 shdr.sh_type = SHT_PROGBITS;
977 shdr.sh_link = 2;
978 shdr.sh_name = 0x300;
979 shdr.sh_addr = 0x7000;
980 shdr.sh_offset = 0x7000;
981 shdr.sh_entsize = 0x100;
982 shdr.sh_size = 0x800;
983 memory_.SetMemory(offset, &shdr, sizeof(shdr));
984 offset += ehdr.e_shentsize;
985
986 memset(&shdr, 0, sizeof(shdr));
987 shdr.sh_type = SHT_PROGBITS;
988 shdr.sh_link = 2;
989 shdr.sh_name = 0x400;
990 shdr.sh_addr = 0xa000;
991 shdr.sh_offset = 0xa000;
992 shdr.sh_entsize = 0x100;
993 shdr.sh_size = 0xf00;
994 memory_.SetMemory(offset, &shdr, sizeof(shdr));
995 offset += ehdr.e_shentsize;
996
997 memset(&shdr, 0, sizeof(shdr));
998 shdr.sh_type = SHT_NOTE;
999 shdr.sh_name = 0x500;
1000 shdr.sh_addr = 0xb000;
1001 shdr.sh_offset = 0xb000;
1002 shdr.sh_size = 0xf00;
1003 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1004
1005 memory_.SetMemory(0xf100, ".debug_frame", sizeof(".debug_frame"));
1006 memory_.SetMemory(0xf200, ".gnu_debugdata", sizeof(".gnu_debugdata"));
1007 memory_.SetMemory(0xf300, ".eh_frame", sizeof(".eh_frame"));
1008 memory_.SetMemory(0xf400, ".eh_frame_hdr", sizeof(".eh_frame_hdr"));
1009 memory_.SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
1010
1011 int64_t load_bias = 0;
1012 ASSERT_TRUE(elf->Init(&load_bias));
1013 EXPECT_EQ(0, load_bias);
1014 EXPECT_EQ(0x6000U, elf->debug_frame_offset());
1015 EXPECT_EQ(0, elf->debug_frame_section_bias());
1016 EXPECT_EQ(0x500U, elf->debug_frame_size());
1017
1018 EXPECT_EQ(0x5000U, elf->gnu_debugdata_offset());
1019 EXPECT_EQ(0x800U, elf->gnu_debugdata_size());
1020
1021 EXPECT_EQ(0x7000U, elf->eh_frame_offset());
1022 EXPECT_EQ(0, elf->eh_frame_section_bias());
1023 EXPECT_EQ(0x800U, elf->eh_frame_size());
1024
1025 EXPECT_EQ(0xa000U, elf->eh_frame_hdr_offset());
1026 EXPECT_EQ(0, elf->eh_frame_hdr_section_bias());
1027 EXPECT_EQ(0xf00U, elf->eh_frame_hdr_size());
1028
1029 EXPECT_EQ(0xb000U, elf->gnu_build_id_offset());
1030 EXPECT_EQ(0xf00U, elf->gnu_build_id_size());
1031 }
1032
TEST_F(ElfInterfaceTest,init_section_headers_offsets_32)1033 TEST_F(ElfInterfaceTest, init_section_headers_offsets_32) {
1034 InitSectionHeadersOffsets<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>();
1035 }
1036
TEST_F(ElfInterfaceTest,init_section_headers_offsets_64)1037 TEST_F(ElfInterfaceTest, init_section_headers_offsets_64) {
1038 InitSectionHeadersOffsets<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>();
1039 }
1040
1041 template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
InitSectionHeadersOffsetsEhFrameSectionBias(uint64_t addr,uint64_t offset,int64_t expected_bias)1042 void ElfInterfaceTest::InitSectionHeadersOffsetsEhFrameSectionBias(uint64_t addr, uint64_t offset,
1043 int64_t expected_bias) {
1044 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
1045
1046 uint64_t elf_offset = 0x2000;
1047
1048 Ehdr ehdr = {};
1049 ehdr.e_shoff = elf_offset;
1050 ehdr.e_shnum = 4;
1051 ehdr.e_shentsize = sizeof(Shdr);
1052 ehdr.e_shstrndx = 2;
1053 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1054
1055 elf_offset += ehdr.e_shentsize;
1056
1057 Shdr shdr = {};
1058 shdr.sh_type = SHT_PROGBITS;
1059 shdr.sh_link = 2;
1060 shdr.sh_name = 0x200;
1061 shdr.sh_addr = 0x8000;
1062 shdr.sh_offset = 0x8000;
1063 shdr.sh_entsize = 0x100;
1064 shdr.sh_size = 0x800;
1065 memory_.SetMemory(elf_offset, &shdr, sizeof(shdr));
1066 elf_offset += ehdr.e_shentsize;
1067
1068 // The string data for section header names.
1069 memset(&shdr, 0, sizeof(shdr));
1070 shdr.sh_type = SHT_STRTAB;
1071 shdr.sh_name = 0x20000;
1072 shdr.sh_offset = 0xf000;
1073 shdr.sh_size = 0x1000;
1074 memory_.SetMemory(elf_offset, &shdr, sizeof(shdr));
1075 elf_offset += ehdr.e_shentsize;
1076
1077 memset(&shdr, 0, sizeof(shdr));
1078 shdr.sh_type = SHT_PROGBITS;
1079 shdr.sh_link = 2;
1080 shdr.sh_name = 0x100;
1081 shdr.sh_addr = addr;
1082 shdr.sh_offset = offset;
1083 shdr.sh_entsize = 0x100;
1084 shdr.sh_size = 0x500;
1085 memory_.SetMemory(elf_offset, &shdr, sizeof(shdr));
1086
1087 memory_.SetMemory(0xf100, ".eh_frame", sizeof(".eh_frame"));
1088 memory_.SetMemory(0xf200, ".eh_frame_hdr", sizeof(".eh_frame_hdr"));
1089
1090 int64_t load_bias = 0;
1091 ASSERT_TRUE(elf->Init(&load_bias));
1092 EXPECT_EQ(0, load_bias);
1093 EXPECT_EQ(offset, elf->eh_frame_offset());
1094 EXPECT_EQ(expected_bias, elf->eh_frame_section_bias());
1095 EXPECT_EQ(0x500U, elf->eh_frame_size());
1096
1097 EXPECT_EQ(0x8000U, elf->eh_frame_hdr_offset());
1098 EXPECT_EQ(0, elf->eh_frame_hdr_section_bias());
1099 EXPECT_EQ(0x800U, elf->eh_frame_hdr_size());
1100 }
1101
TEST_F(ElfInterfaceTest,init_section_headers_offsets_eh_frame_section_bias_zero_32)1102 TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_section_bias_zero_32) {
1103 InitSectionHeadersOffsetsEhFrameSectionBias<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>(0x4000,
1104 0x4000, 0);
1105 }
1106
TEST_F(ElfInterfaceTest,init_section_headers_offsets_eh_frame_section_bias_zero_64)1107 TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_section_bias_zero_64) {
1108 InitSectionHeadersOffsetsEhFrameSectionBias<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(0x6000,
1109 0x6000, 0);
1110 }
1111
TEST_F(ElfInterfaceTest,init_section_headers_offsets_eh_frame_section_bias_positive_32)1112 TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_section_bias_positive_32) {
1113 InitSectionHeadersOffsetsEhFrameSectionBias<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>(
1114 0x5000, 0x4000, 0x1000);
1115 }
1116
TEST_F(ElfInterfaceTest,init_section_headers_offsets_eh_frame_section_bias_positive_64)1117 TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_section_bias_positive_64) {
1118 InitSectionHeadersOffsetsEhFrameSectionBias<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(
1119 0x6000, 0x4000, 0x2000);
1120 }
1121
TEST_F(ElfInterfaceTest,init_section_headers_offsets_eh_frame_section_bias_negative_32)1122 TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_section_bias_negative_32) {
1123 InitSectionHeadersOffsetsEhFrameSectionBias<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>(
1124 0x3000, 0x4000, -0x1000);
1125 }
1126
TEST_F(ElfInterfaceTest,init_section_headers_offsets_eh_frame_section_bias_negative_64)1127 TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_section_bias_negative_64) {
1128 InitSectionHeadersOffsetsEhFrameSectionBias<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(
1129 0x6000, 0x9000, -0x3000);
1130 }
1131
1132 template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
InitSectionHeadersOffsetsEhFrameHdrSectionBias(uint64_t addr,uint64_t offset,int64_t expected_bias)1133 void ElfInterfaceTest::InitSectionHeadersOffsetsEhFrameHdrSectionBias(uint64_t addr,
1134 uint64_t offset,
1135 int64_t expected_bias) {
1136 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
1137
1138 uint64_t elf_offset = 0x2000;
1139
1140 Ehdr ehdr = {};
1141 ehdr.e_shoff = elf_offset;
1142 ehdr.e_shnum = 4;
1143 ehdr.e_shentsize = sizeof(Shdr);
1144 ehdr.e_shstrndx = 2;
1145 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1146
1147 elf_offset += ehdr.e_shentsize;
1148
1149 Shdr shdr = {};
1150 shdr.sh_type = SHT_PROGBITS;
1151 shdr.sh_link = 2;
1152 shdr.sh_name = 0x200;
1153 shdr.sh_addr = addr;
1154 shdr.sh_offset = offset;
1155 shdr.sh_entsize = 0x100;
1156 shdr.sh_size = 0x800;
1157 memory_.SetMemory(elf_offset, &shdr, sizeof(shdr));
1158 elf_offset += ehdr.e_shentsize;
1159
1160 // The string data for section header names.
1161 memset(&shdr, 0, sizeof(shdr));
1162 shdr.sh_type = SHT_STRTAB;
1163 shdr.sh_name = 0x20000;
1164 shdr.sh_offset = 0xf000;
1165 shdr.sh_size = 0x1000;
1166 memory_.SetMemory(elf_offset, &shdr, sizeof(shdr));
1167 elf_offset += ehdr.e_shentsize;
1168
1169 memset(&shdr, 0, sizeof(shdr));
1170 shdr.sh_type = SHT_PROGBITS;
1171 shdr.sh_link = 2;
1172 shdr.sh_name = 0x100;
1173 shdr.sh_addr = 0x5000;
1174 shdr.sh_offset = 0x5000;
1175 shdr.sh_entsize = 0x100;
1176 shdr.sh_size = 0x500;
1177 memory_.SetMemory(elf_offset, &shdr, sizeof(shdr));
1178
1179 memory_.SetMemory(0xf100, ".eh_frame", sizeof(".eh_frame"));
1180 memory_.SetMemory(0xf200, ".eh_frame_hdr", sizeof(".eh_frame_hdr"));
1181
1182 int64_t load_bias = 0;
1183 ASSERT_TRUE(elf->Init(&load_bias));
1184 EXPECT_EQ(0, load_bias);
1185 EXPECT_EQ(0x5000U, elf->eh_frame_offset());
1186 EXPECT_EQ(0, elf->eh_frame_section_bias());
1187 EXPECT_EQ(0x500U, elf->eh_frame_size());
1188 EXPECT_EQ(offset, elf->eh_frame_hdr_offset());
1189 EXPECT_EQ(expected_bias, elf->eh_frame_hdr_section_bias());
1190 EXPECT_EQ(0x800U, elf->eh_frame_hdr_size());
1191 }
1192
TEST_F(ElfInterfaceTest,init_section_headers_offsets_eh_frame_hdr_section_bias_zero_32)1193 TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_hdr_section_bias_zero_32) {
1194 InitSectionHeadersOffsetsEhFrameHdrSectionBias<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>(0x9000,
1195 0x9000, 0);
1196 }
1197
TEST_F(ElfInterfaceTest,init_section_headers_offsets_eh_frame_hdr_section_bias_zero_64)1198 TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_hdr_section_bias_zero_64) {
1199 InitSectionHeadersOffsetsEhFrameHdrSectionBias<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(0xa000,
1200 0xa000, 0);
1201 }
1202
TEST_F(ElfInterfaceTest,init_section_headers_offsets_eh_frame_hdr_section_bias_positive_32)1203 TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_hdr_section_bias_positive_32) {
1204 InitSectionHeadersOffsetsEhFrameHdrSectionBias<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>(
1205 0x9000, 0x4000, 0x5000);
1206 }
1207
TEST_F(ElfInterfaceTest,init_section_headers_offsets_eh_frame_hdr_section_bias_positive_64)1208 TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_hdr_section_bias_positive_64) {
1209 InitSectionHeadersOffsetsEhFrameHdrSectionBias<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(
1210 0x6000, 0x1000, 0x5000);
1211 }
1212
TEST_F(ElfInterfaceTest,init_section_headers_offsets_eh_frame_hdr_section_bias_negative_32)1213 TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_hdr_section_bias_negative_32) {
1214 InitSectionHeadersOffsetsEhFrameHdrSectionBias<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>(
1215 0x3000, 0x5000, -0x2000);
1216 }
1217
TEST_F(ElfInterfaceTest,init_section_headers_offsets_eh_frame_hdr_section_bias_negative_64)1218 TEST_F(ElfInterfaceTest, init_section_headers_offsets_eh_frame_hdr_section_bias_negative_64) {
1219 InitSectionHeadersOffsetsEhFrameHdrSectionBias<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(
1220 0x5000, 0x9000, -0x4000);
1221 }
1222
1223 template <typename Ehdr, typename Shdr, typename ElfInterfaceType>
InitSectionHeadersOffsetsDebugFrameSectionBias(uint64_t addr,uint64_t offset,int64_t expected_bias)1224 void ElfInterfaceTest::InitSectionHeadersOffsetsDebugFrameSectionBias(uint64_t addr,
1225 uint64_t offset,
1226 int64_t expected_bias) {
1227 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
1228
1229 uint64_t elf_offset = 0x2000;
1230
1231 Ehdr ehdr = {};
1232 ehdr.e_shoff = elf_offset;
1233 ehdr.e_shnum = 3;
1234 ehdr.e_shentsize = sizeof(Shdr);
1235 ehdr.e_shstrndx = 2;
1236 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1237
1238 elf_offset += ehdr.e_shentsize;
1239
1240 Shdr shdr = {};
1241 shdr.sh_type = SHT_PROGBITS;
1242 shdr.sh_link = 2;
1243 shdr.sh_name = 0x100;
1244 shdr.sh_addr = addr;
1245 shdr.sh_offset = offset;
1246 shdr.sh_entsize = 0x100;
1247 shdr.sh_size = 0x800;
1248 memory_.SetMemory(elf_offset, &shdr, sizeof(shdr));
1249 elf_offset += ehdr.e_shentsize;
1250
1251 // The string data for section header names.
1252 memset(&shdr, 0, sizeof(shdr));
1253 shdr.sh_type = SHT_STRTAB;
1254 shdr.sh_name = 0x20000;
1255 shdr.sh_offset = 0xf000;
1256 shdr.sh_size = 0x1000;
1257 memory_.SetMemory(elf_offset, &shdr, sizeof(shdr));
1258
1259 memory_.SetMemory(0xf100, ".debug_frame", sizeof(".debug_frame"));
1260
1261 int64_t load_bias = 0;
1262 ASSERT_TRUE(elf->Init(&load_bias));
1263 EXPECT_EQ(0, load_bias);
1264 EXPECT_EQ(offset, elf->debug_frame_offset());
1265 EXPECT_EQ(expected_bias, elf->debug_frame_section_bias());
1266 EXPECT_EQ(0x800U, elf->debug_frame_size());
1267 }
1268
TEST_F(ElfInterfaceTest,init_section_headers_offsets_debug_frame_section_bias_zero_32)1269 TEST_F(ElfInterfaceTest, init_section_headers_offsets_debug_frame_section_bias_zero_32) {
1270 InitSectionHeadersOffsetsDebugFrameSectionBias<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>(0x5000,
1271 0x5000, 0);
1272 }
1273
TEST_F(ElfInterfaceTest,init_section_headers_offsets_debug_frame_section_bias_zero_64)1274 TEST_F(ElfInterfaceTest, init_section_headers_offsets_debug_frame_section_bias_zero_64) {
1275 InitSectionHeadersOffsetsDebugFrameSectionBias<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(0xa000,
1276 0xa000, 0);
1277 }
1278
TEST_F(ElfInterfaceTest,init_section_headers_offsets_debug_frame_section_bias_positive_32)1279 TEST_F(ElfInterfaceTest, init_section_headers_offsets_debug_frame_section_bias_positive_32) {
1280 InitSectionHeadersOffsetsDebugFrameSectionBias<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>(
1281 0x5000, 0x2000, 0x3000);
1282 }
1283
TEST_F(ElfInterfaceTest,init_section_headers_offsets_debug_frame_section_bias_positive_64)1284 TEST_F(ElfInterfaceTest, init_section_headers_offsets_debug_frame_section_bias_positive_64) {
1285 InitSectionHeadersOffsetsDebugFrameSectionBias<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(
1286 0x7000, 0x1000, 0x6000);
1287 }
1288
TEST_F(ElfInterfaceTest,init_section_headers_offsets_debug_frame_section_bias_negative_32)1289 TEST_F(ElfInterfaceTest, init_section_headers_offsets_debug_frame_section_bias_negative_32) {
1290 InitSectionHeadersOffsetsDebugFrameSectionBias<Elf32_Ehdr, Elf32_Shdr, ElfInterface32>(
1291 0x6000, 0x7000, -0x1000);
1292 }
1293
TEST_F(ElfInterfaceTest,init_section_headers_offsets_debug_frame_section_bias_negative_64)1294 TEST_F(ElfInterfaceTest, init_section_headers_offsets_debug_frame_section_bias_negative_64) {
1295 InitSectionHeadersOffsetsDebugFrameSectionBias<Elf64_Ehdr, Elf64_Shdr, ElfInterface64>(
1296 0x3000, 0x5000, -0x2000);
1297 }
1298
1299 template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
CheckGnuEhFrame(uint64_t addr,uint64_t offset,int64_t expected_bias)1300 void ElfInterfaceTest::CheckGnuEhFrame(uint64_t addr, uint64_t offset, int64_t expected_bias) {
1301 std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
1302
1303 Ehdr ehdr = {};
1304 ehdr.e_phoff = 0x100;
1305 ehdr.e_phnum = 2;
1306 ehdr.e_phentsize = sizeof(Phdr);
1307 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1308
1309 uint64_t phdr_offset = 0x100;
1310
1311 Phdr phdr = {};
1312 phdr.p_type = PT_LOAD;
1313 phdr.p_memsz = 0x10000;
1314 phdr.p_flags = PF_R | PF_X;
1315 phdr.p_align = 0x1000;
1316 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
1317 phdr_offset += sizeof(phdr);
1318
1319 memset(&phdr, 0, sizeof(phdr));
1320 phdr.p_type = PT_GNU_EH_FRAME;
1321 phdr.p_vaddr = addr;
1322 phdr.p_offset = offset;
1323 memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
1324
1325 int64_t load_bias = 0;
1326 ASSERT_TRUE(elf->Init(&load_bias));
1327 EXPECT_EQ(0, load_bias);
1328 EXPECT_EQ(expected_bias, elf->eh_frame_hdr_section_bias());
1329 }
1330
TEST_F(ElfInterfaceTest,eh_frame_zero_section_bias_32)1331 TEST_F(ElfInterfaceTest, eh_frame_zero_section_bias_32) {
1332 ElfInterfaceTest::CheckGnuEhFrame<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>(0x4000, 0x4000, 0);
1333 }
1334
TEST_F(ElfInterfaceTest,eh_frame_zero_section_bias_64)1335 TEST_F(ElfInterfaceTest, eh_frame_zero_section_bias_64) {
1336 ElfInterfaceTest::CheckGnuEhFrame<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0x4000, 0x4000, 0);
1337 }
1338
TEST_F(ElfInterfaceTest,eh_frame_positive_section_bias_32)1339 TEST_F(ElfInterfaceTest, eh_frame_positive_section_bias_32) {
1340 ElfInterfaceTest::CheckGnuEhFrame<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>(0x4000, 0x1000, 0x3000);
1341 }
1342
TEST_F(ElfInterfaceTest,eh_frame_positive_section_bias_64)1343 TEST_F(ElfInterfaceTest, eh_frame_positive_section_bias_64) {
1344 ElfInterfaceTest::CheckGnuEhFrame<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0x4000, 0x1000, 0x3000);
1345 }
1346
TEST_F(ElfInterfaceTest,eh_frame_negative_section_bias_32)1347 TEST_F(ElfInterfaceTest, eh_frame_negative_section_bias_32) {
1348 ElfInterfaceTest::CheckGnuEhFrame<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>(0x4000, 0x5000,
1349 -0x1000);
1350 }
1351
TEST_F(ElfInterfaceTest,eh_frame_negative_section_bias_64)1352 TEST_F(ElfInterfaceTest, eh_frame_negative_section_bias_64) {
1353 ElfInterfaceTest::CheckGnuEhFrame<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0x4000, 0x5000,
1354 -0x1000);
1355 }
1356
TEST_F(ElfInterfaceTest,is_valid_pc_from_pt_load)1357 TEST_F(ElfInterfaceTest, is_valid_pc_from_pt_load) {
1358 std::unique_ptr<ElfInterface> elf(new ElfInterface32(&memory_));
1359
1360 Elf32_Ehdr ehdr = {};
1361 ehdr.e_phoff = 0x100;
1362 ehdr.e_phnum = 1;
1363 ehdr.e_phentsize = sizeof(Elf32_Phdr);
1364 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1365
1366 Elf32_Phdr phdr = {};
1367 phdr.p_type = PT_LOAD;
1368 phdr.p_vaddr = 0;
1369 phdr.p_memsz = 0x10000;
1370 phdr.p_flags = PF_R | PF_X;
1371 phdr.p_align = 0x1000;
1372 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
1373
1374 int64_t load_bias = 0;
1375 ASSERT_TRUE(elf->Init(&load_bias));
1376 EXPECT_EQ(0, load_bias);
1377 EXPECT_TRUE(elf->IsValidPc(0));
1378 EXPECT_TRUE(elf->IsValidPc(0x5000));
1379 EXPECT_TRUE(elf->IsValidPc(0xffff));
1380 EXPECT_FALSE(elf->IsValidPc(0x10000));
1381 }
1382
TEST_F(ElfInterfaceTest,is_valid_pc_from_pt_load_non_zero_load_bias)1383 TEST_F(ElfInterfaceTest, is_valid_pc_from_pt_load_non_zero_load_bias) {
1384 std::unique_ptr<ElfInterface> elf(new ElfInterface32(&memory_));
1385
1386 Elf32_Ehdr ehdr = {};
1387 ehdr.e_phoff = 0x100;
1388 ehdr.e_phnum = 1;
1389 ehdr.e_phentsize = sizeof(Elf32_Phdr);
1390 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1391
1392 Elf32_Phdr phdr = {};
1393 phdr.p_type = PT_LOAD;
1394 phdr.p_vaddr = 0x2000;
1395 phdr.p_memsz = 0x10000;
1396 phdr.p_flags = PF_R | PF_X;
1397 phdr.p_align = 0x1000;
1398 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
1399
1400 int64_t load_bias = 0;
1401 ASSERT_TRUE(elf->Init(&load_bias));
1402 EXPECT_EQ(0x2000, load_bias);
1403 EXPECT_FALSE(elf->IsValidPc(0));
1404 EXPECT_FALSE(elf->IsValidPc(0x1000));
1405 EXPECT_FALSE(elf->IsValidPc(0x1fff));
1406 EXPECT_TRUE(elf->IsValidPc(0x2000));
1407 EXPECT_TRUE(elf->IsValidPc(0x5000));
1408 EXPECT_TRUE(elf->IsValidPc(0x11fff));
1409 EXPECT_FALSE(elf->IsValidPc(0x12000));
1410 }
1411
TEST_F(ElfInterfaceTest,is_valid_pc_from_debug_frame)1412 TEST_F(ElfInterfaceTest, is_valid_pc_from_debug_frame) {
1413 std::unique_ptr<ElfInterface> elf(new ElfInterface32(&memory_));
1414
1415 uint64_t sh_offset = 0x100;
1416
1417 Elf32_Ehdr ehdr = {};
1418 ehdr.e_shstrndx = 1;
1419 ehdr.e_shoff = sh_offset;
1420 ehdr.e_shentsize = sizeof(Elf32_Shdr);
1421 ehdr.e_shnum = 3;
1422 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1423
1424 Elf32_Shdr shdr = {};
1425 shdr.sh_type = SHT_NULL;
1426 memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
1427
1428 sh_offset += sizeof(shdr);
1429 memset(&shdr, 0, sizeof(shdr));
1430 shdr.sh_type = SHT_STRTAB;
1431 shdr.sh_name = 1;
1432 shdr.sh_offset = 0x500;
1433 shdr.sh_size = 0x100;
1434 memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
1435 memory_.SetMemory(0x500, ".debug_frame");
1436
1437 sh_offset += sizeof(shdr);
1438 memset(&shdr, 0, sizeof(shdr));
1439 shdr.sh_type = SHT_PROGBITS;
1440 shdr.sh_name = 0;
1441 shdr.sh_addr = 0x600;
1442 shdr.sh_offset = 0x600;
1443 shdr.sh_size = 0x200;
1444 memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
1445
1446 // CIE 32.
1447 memory_.SetData32(0x600, 0xfc);
1448 memory_.SetData32(0x604, 0xffffffff);
1449 memory_.SetMemory(0x608, std::vector<uint8_t>{1, '\0', 4, 4, 1});
1450
1451 // FDE 32.
1452 memory_.SetData32(0x700, 0xfc);
1453 memory_.SetData32(0x704, 0);
1454 memory_.SetData32(0x708, 0x2100);
1455 memory_.SetData32(0x70c, 0x200);
1456
1457 int64_t load_bias = 0;
1458 ASSERT_TRUE(elf->Init(&load_bias));
1459 elf->InitHeaders();
1460 EXPECT_EQ(0, load_bias);
1461 EXPECT_FALSE(elf->IsValidPc(0));
1462 EXPECT_FALSE(elf->IsValidPc(0x20ff));
1463 EXPECT_TRUE(elf->IsValidPc(0x2100));
1464 EXPECT_TRUE(elf->IsValidPc(0x2200));
1465 EXPECT_TRUE(elf->IsValidPc(0x22ff));
1466 EXPECT_FALSE(elf->IsValidPc(0x2300));
1467 }
1468
TEST_F(ElfInterfaceTest,is_valid_pc_from_eh_frame)1469 TEST_F(ElfInterfaceTest, is_valid_pc_from_eh_frame) {
1470 std::unique_ptr<ElfInterface> elf(new ElfInterface32(&memory_));
1471
1472 uint64_t sh_offset = 0x100;
1473
1474 Elf32_Ehdr ehdr = {};
1475 ehdr.e_shstrndx = 1;
1476 ehdr.e_shoff = sh_offset;
1477 ehdr.e_shentsize = sizeof(Elf32_Shdr);
1478 ehdr.e_shnum = 3;
1479 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1480
1481 Elf32_Shdr shdr = {};
1482 shdr.sh_type = SHT_NULL;
1483 memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
1484
1485 sh_offset += sizeof(shdr);
1486 memset(&shdr, 0, sizeof(shdr));
1487 shdr.sh_type = SHT_STRTAB;
1488 shdr.sh_name = 1;
1489 shdr.sh_offset = 0x500;
1490 shdr.sh_size = 0x100;
1491 memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
1492 memory_.SetMemory(0x500, ".eh_frame");
1493
1494 sh_offset += sizeof(shdr);
1495 memset(&shdr, 0, sizeof(shdr));
1496 shdr.sh_type = SHT_PROGBITS;
1497 shdr.sh_name = 0;
1498 shdr.sh_addr = 0x600;
1499 shdr.sh_offset = 0x600;
1500 shdr.sh_size = 0x200;
1501 memory_.SetMemory(sh_offset, &shdr, sizeof(shdr));
1502
1503 // CIE 32.
1504 memory_.SetData32(0x600, 0xfc);
1505 memory_.SetData32(0x604, 0);
1506 memory_.SetMemory(0x608, std::vector<uint8_t>{1, '\0', 4, 4, 1});
1507
1508 // FDE 32.
1509 memory_.SetData32(0x700, 0xfc);
1510 memory_.SetData32(0x704, 0x104);
1511 memory_.SetData32(0x708, 0x20f8);
1512 memory_.SetData32(0x70c, 0x200);
1513
1514 int64_t load_bias = 0;
1515 ASSERT_TRUE(elf->Init(&load_bias));
1516 elf->InitHeaders();
1517 EXPECT_EQ(0, load_bias);
1518 EXPECT_FALSE(elf->IsValidPc(0));
1519 EXPECT_FALSE(elf->IsValidPc(0x27ff));
1520 EXPECT_TRUE(elf->IsValidPc(0x2800));
1521 EXPECT_TRUE(elf->IsValidPc(0x2900));
1522 EXPECT_TRUE(elf->IsValidPc(0x29ff));
1523 EXPECT_FALSE(elf->IsValidPc(0x2a00));
1524 }
1525
1526 template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
BuildID()1527 void ElfInterfaceTest::BuildID() {
1528 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
1529
1530 uint64_t offset = 0x2000;
1531
1532 Ehdr ehdr = {};
1533 ehdr.e_shoff = offset;
1534 ehdr.e_shnum = 3;
1535 ehdr.e_shentsize = sizeof(Shdr);
1536 ehdr.e_shstrndx = 2;
1537 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1538
1539 offset += ehdr.e_shentsize;
1540
1541 char note_section[128];
1542 Nhdr note_header = {};
1543 note_header.n_namesz = 4; // "GNU"
1544 note_header.n_descsz = 7; // "BUILDID"
1545 note_header.n_type = NT_GNU_BUILD_ID;
1546 memcpy(¬e_section, ¬e_header, sizeof(note_header));
1547 size_t note_offset = sizeof(note_header);
1548 // The note information contains the GNU and trailing '\0'.
1549 memcpy(¬e_section[note_offset], "GNU", sizeof("GNU"));
1550 note_offset += sizeof("GNU");
1551 // This part of the note does not contain any trailing '\0'.
1552 memcpy(¬e_section[note_offset], "BUILDID", 7);
1553
1554 Shdr shdr = {};
1555 shdr.sh_type = SHT_NOTE;
1556 shdr.sh_name = 0x500;
1557 shdr.sh_offset = 0xb000;
1558 shdr.sh_size = sizeof(note_section);
1559 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1560 offset += ehdr.e_shentsize;
1561
1562 // The string data for section header names.
1563 memset(&shdr, 0, sizeof(shdr));
1564 shdr.sh_type = SHT_STRTAB;
1565 shdr.sh_name = 0x20000;
1566 shdr.sh_offset = 0xf000;
1567 shdr.sh_size = 0x1000;
1568 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1569
1570 memory_.SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
1571 memory_.SetMemory(0xb000, note_section, sizeof(note_section));
1572
1573 int64_t load_bias = 0;
1574 ASSERT_TRUE(elf->Init(&load_bias));
1575 ASSERT_EQ("BUILDID", elf->GetBuildID());
1576 }
1577
TEST_F(ElfInterfaceTest,build_id_32)1578 TEST_F(ElfInterfaceTest, build_id_32) {
1579 BuildID<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
1580 }
1581
TEST_F(ElfInterfaceTest,build_id_64)1582 TEST_F(ElfInterfaceTest, build_id_64) {
1583 BuildID<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
1584 }
1585
1586 template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
BuildIDTwoNotes()1587 void ElfInterfaceTest::BuildIDTwoNotes() {
1588 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
1589
1590 uint64_t offset = 0x2000;
1591
1592 Ehdr ehdr = {};
1593 ehdr.e_shoff = offset;
1594 ehdr.e_shnum = 3;
1595 ehdr.e_shentsize = sizeof(Shdr);
1596 ehdr.e_shstrndx = 2;
1597 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1598
1599 offset += ehdr.e_shentsize;
1600
1601 char note_section[128];
1602 Nhdr note_header = {};
1603 note_header.n_namesz = 8; // "WRONG" aligned to 4
1604 note_header.n_descsz = 7; // "BUILDID"
1605 note_header.n_type = NT_GNU_BUILD_ID;
1606 memcpy(¬e_section, ¬e_header, sizeof(note_header));
1607 size_t note_offset = sizeof(note_header);
1608 memcpy(¬e_section[note_offset], "WRONG", sizeof("WRONG"));
1609 note_offset += 8;
1610 // This part of the note does not contain any trailing '\0'.
1611 memcpy(¬e_section[note_offset], "BUILDID", 7);
1612 note_offset += 8;
1613
1614 note_header.n_namesz = 4; // "GNU"
1615 note_header.n_descsz = 7; // "BUILDID"
1616 note_header.n_type = NT_GNU_BUILD_ID;
1617 memcpy(¬e_section[note_offset], ¬e_header, sizeof(note_header));
1618 note_offset += sizeof(note_header);
1619 // The note information contains the GNU and trailing '\0'.
1620 memcpy(¬e_section[note_offset], "GNU", sizeof("GNU"));
1621 note_offset += sizeof("GNU");
1622 // This part of the note does not contain any trailing '\0'.
1623 memcpy(¬e_section[note_offset], "BUILDID", 7);
1624
1625 Shdr shdr = {};
1626 shdr.sh_type = SHT_NOTE;
1627 shdr.sh_name = 0x500;
1628 shdr.sh_offset = 0xb000;
1629 shdr.sh_size = sizeof(note_section);
1630 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1631 offset += ehdr.e_shentsize;
1632
1633 // The string data for section header names.
1634 memset(&shdr, 0, sizeof(shdr));
1635 shdr.sh_type = SHT_STRTAB;
1636 shdr.sh_name = 0x20000;
1637 shdr.sh_offset = 0xf000;
1638 shdr.sh_size = 0x1000;
1639 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1640
1641 memory_.SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
1642 memory_.SetMemory(0xb000, note_section, sizeof(note_section));
1643
1644 int64_t load_bias = 0;
1645 ASSERT_TRUE(elf->Init(&load_bias));
1646 ASSERT_EQ("BUILDID", elf->GetBuildID());
1647 }
1648
TEST_F(ElfInterfaceTest,build_id_two_notes_32)1649 TEST_F(ElfInterfaceTest, build_id_two_notes_32) {
1650 BuildIDTwoNotes<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
1651 }
1652
TEST_F(ElfInterfaceTest,build_id_two_notes_64)1653 TEST_F(ElfInterfaceTest, build_id_two_notes_64) {
1654 BuildIDTwoNotes<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
1655 }
1656
1657 template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
BuildIDSectionTooSmallForName()1658 void ElfInterfaceTest::BuildIDSectionTooSmallForName () {
1659 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
1660
1661 uint64_t offset = 0x2000;
1662
1663 Ehdr ehdr = {};
1664 ehdr.e_shoff = offset;
1665 ehdr.e_shnum = 3;
1666 ehdr.e_shentsize = sizeof(Shdr);
1667 ehdr.e_shstrndx = 2;
1668 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1669
1670 offset += ehdr.e_shentsize;
1671
1672 char note_section[128];
1673 Nhdr note_header = {};
1674 note_header.n_namesz = 4; // "GNU"
1675 note_header.n_descsz = 7; // "BUILDID"
1676 note_header.n_type = NT_GNU_BUILD_ID;
1677 memcpy(¬e_section, ¬e_header, sizeof(note_header));
1678 size_t note_offset = sizeof(note_header);
1679 // The note information contains the GNU and trailing '\0'.
1680 memcpy(¬e_section[note_offset], "GNU", sizeof("GNU"));
1681 note_offset += sizeof("GNU");
1682 // This part of the note does not contain any trailing '\0'.
1683 memcpy(¬e_section[note_offset], "BUILDID", 7);
1684
1685 Shdr shdr = {};
1686 shdr.sh_type = SHT_NOTE;
1687 shdr.sh_name = 0x500;
1688 shdr.sh_offset = 0xb000;
1689 shdr.sh_size = sizeof(note_header) + 1;
1690 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1691 offset += ehdr.e_shentsize;
1692
1693 // The string data for section header names.
1694 memset(&shdr, 0, sizeof(shdr));
1695 shdr.sh_type = SHT_STRTAB;
1696 shdr.sh_name = 0x20000;
1697 shdr.sh_offset = 0xf000;
1698 shdr.sh_size = 0x1000;
1699 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1700
1701 memory_.SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
1702 memory_.SetMemory(0xb000, note_section, sizeof(note_section));
1703
1704 int64_t load_bias = 0;
1705 ASSERT_TRUE(elf->Init(&load_bias));
1706 ASSERT_EQ("", elf->GetBuildID());
1707 }
1708
TEST_F(ElfInterfaceTest,build_id_section_too_small_for_name_32)1709 TEST_F(ElfInterfaceTest, build_id_section_too_small_for_name_32) {
1710 BuildIDSectionTooSmallForName<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
1711 }
1712
TEST_F(ElfInterfaceTest,build_id_section_too_small_for_name_64)1713 TEST_F(ElfInterfaceTest, build_id_section_too_small_for_name_64) {
1714 BuildIDSectionTooSmallForName<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
1715 }
1716
1717 template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
BuildIDSectionTooSmallForDesc()1718 void ElfInterfaceTest::BuildIDSectionTooSmallForDesc () {
1719 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
1720
1721 uint64_t offset = 0x2000;
1722
1723 Ehdr ehdr = {};
1724 ehdr.e_shoff = offset;
1725 ehdr.e_shnum = 3;
1726 ehdr.e_shentsize = sizeof(Shdr);
1727 ehdr.e_shstrndx = 2;
1728 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1729
1730 offset += ehdr.e_shentsize;
1731
1732 char note_section[128];
1733 Nhdr note_header = {};
1734 note_header.n_namesz = 4; // "GNU"
1735 note_header.n_descsz = 7; // "BUILDID"
1736 note_header.n_type = NT_GNU_BUILD_ID;
1737 memcpy(¬e_section, ¬e_header, sizeof(note_header));
1738 size_t note_offset = sizeof(note_header);
1739 // The note information contains the GNU and trailing '\0'.
1740 memcpy(¬e_section[note_offset], "GNU", sizeof("GNU"));
1741 note_offset += sizeof("GNU");
1742 // This part of the note does not contain any trailing '\0'.
1743 memcpy(¬e_section[note_offset], "BUILDID", 7);
1744
1745 Shdr shdr = {};
1746 shdr.sh_type = SHT_NOTE;
1747 shdr.sh_name = 0x500;
1748 shdr.sh_offset = 0xb000;
1749 shdr.sh_size = sizeof(note_header) + sizeof("GNU") + 1;
1750 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1751 offset += ehdr.e_shentsize;
1752
1753 // The string data for section header names.
1754 memset(&shdr, 0, sizeof(shdr));
1755 shdr.sh_type = SHT_STRTAB;
1756 shdr.sh_name = 0x20000;
1757 shdr.sh_offset = 0xf000;
1758 shdr.sh_size = 0x1000;
1759 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1760
1761 memory_.SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
1762 memory_.SetMemory(0xb000, note_section, sizeof(note_section));
1763
1764 int64_t load_bias = 0;
1765 ASSERT_TRUE(elf->Init(&load_bias));
1766 ASSERT_EQ("", elf->GetBuildID());
1767 }
1768
TEST_F(ElfInterfaceTest,build_id_section_too_small_for_desc_32)1769 TEST_F(ElfInterfaceTest, build_id_section_too_small_for_desc_32) {
1770 BuildIDSectionTooSmallForDesc<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
1771 }
1772
TEST_F(ElfInterfaceTest,build_id_section_too_small_for_desc_64)1773 TEST_F(ElfInterfaceTest, build_id_section_too_small_for_desc_64) {
1774 BuildIDSectionTooSmallForDesc<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
1775 }
1776
1777 template <typename Ehdr, typename Shdr, typename Nhdr, typename ElfInterfaceType>
BuildIDSectionTooSmallForHeader()1778 void ElfInterfaceTest::BuildIDSectionTooSmallForHeader () {
1779 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
1780
1781 uint64_t offset = 0x2000;
1782
1783 Ehdr ehdr = {};
1784 ehdr.e_shoff = offset;
1785 ehdr.e_shnum = 3;
1786 ehdr.e_shentsize = sizeof(Shdr);
1787 ehdr.e_shstrndx = 2;
1788 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1789
1790 offset += ehdr.e_shentsize;
1791
1792 char note_section[128];
1793 Nhdr note_header = {};
1794 note_header.n_namesz = 4; // "GNU"
1795 note_header.n_descsz = 7; // "BUILDID"
1796 note_header.n_type = NT_GNU_BUILD_ID;
1797 memcpy(¬e_section, ¬e_header, sizeof(note_header));
1798 size_t note_offset = sizeof(note_header);
1799 // The note information contains the GNU and trailing '\0'.
1800 memcpy(¬e_section[note_offset], "GNU", sizeof("GNU"));
1801 note_offset += sizeof("GNU");
1802 // This part of the note does not contain any trailing '\0'.
1803 memcpy(¬e_section[note_offset], "BUILDID", 7);
1804
1805 Shdr shdr = {};
1806 shdr.sh_type = SHT_NOTE;
1807 shdr.sh_name = 0x500;
1808 shdr.sh_offset = 0xb000;
1809 shdr.sh_size = sizeof(note_header) - 1;
1810 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1811 offset += ehdr.e_shentsize;
1812
1813 // The string data for section header names.
1814 memset(&shdr, 0, sizeof(shdr));
1815 shdr.sh_type = SHT_STRTAB;
1816 shdr.sh_name = 0x20000;
1817 shdr.sh_offset = 0xf000;
1818 shdr.sh_size = 0x1000;
1819 memory_.SetMemory(offset, &shdr, sizeof(shdr));
1820
1821 memory_.SetMemory(0xf500, ".note.gnu.build-id", sizeof(".note.gnu.build-id"));
1822 memory_.SetMemory(0xb000, note_section, sizeof(note_section));
1823
1824 int64_t load_bias = 0;
1825 ASSERT_TRUE(elf->Init(&load_bias));
1826 ASSERT_EQ("", elf->GetBuildID());
1827 }
1828
TEST_F(ElfInterfaceTest,build_id_section_too_small_for_header_32)1829 TEST_F(ElfInterfaceTest, build_id_section_too_small_for_header_32) {
1830 BuildIDSectionTooSmallForHeader<Elf32_Ehdr, Elf32_Shdr, Elf32_Nhdr, ElfInterface32>();
1831 }
1832
TEST_F(ElfInterfaceTest,build_id_section_too_small_for_header_64)1833 TEST_F(ElfInterfaceTest, build_id_section_too_small_for_header_64) {
1834 BuildIDSectionTooSmallForHeader<Elf64_Ehdr, Elf64_Shdr, Elf64_Nhdr, ElfInterface64>();
1835 }
1836
1837 template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
CheckLoadBiasInFirstPhdr(int64_t load_bias)1838 void ElfInterfaceTest::CheckLoadBiasInFirstPhdr(int64_t load_bias) {
1839 Ehdr ehdr = {};
1840 ehdr.e_phoff = 0x100;
1841 ehdr.e_phnum = 2;
1842 ehdr.e_phentsize = sizeof(Phdr);
1843 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1844
1845 Phdr phdr = {};
1846 phdr.p_type = PT_LOAD;
1847 phdr.p_offset = 0;
1848 phdr.p_vaddr = load_bias;
1849 phdr.p_memsz = 0x10000;
1850 phdr.p_flags = PF_R | PF_X;
1851 phdr.p_align = 0x1000;
1852 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
1853
1854 memset(&phdr, 0, sizeof(phdr));
1855 phdr.p_type = PT_LOAD;
1856 phdr.p_offset = 0x1000;
1857 phdr.p_memsz = 0x2000;
1858 phdr.p_flags = PF_R | PF_X;
1859 phdr.p_align = 0x1000;
1860 memory_.SetMemory(0x100 + sizeof(phdr), &phdr, sizeof(phdr));
1861
1862 int64_t static_load_bias = ElfInterface::GetLoadBias<Ehdr, Phdr>(&memory_);
1863 ASSERT_EQ(load_bias, static_load_bias);
1864
1865 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
1866 int64_t init_load_bias = 0;
1867 ASSERT_TRUE(elf->Init(&init_load_bias));
1868 ASSERT_EQ(init_load_bias, static_load_bias);
1869 }
1870
TEST_F(ElfInterfaceTest,get_load_bias_zero_32)1871 TEST_F(ElfInterfaceTest, get_load_bias_zero_32) {
1872 CheckLoadBiasInFirstPhdr<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>(0);
1873 }
1874
TEST_F(ElfInterfaceTest,get_load_bias_zero_64)1875 TEST_F(ElfInterfaceTest, get_load_bias_zero_64) {
1876 CheckLoadBiasInFirstPhdr<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0);
1877 }
1878
TEST_F(ElfInterfaceTest,get_load_bias_non_zero_32)1879 TEST_F(ElfInterfaceTest, get_load_bias_non_zero_32) {
1880 CheckLoadBiasInFirstPhdr<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>(0x1000);
1881 }
1882
TEST_F(ElfInterfaceTest,get_load_bias_non_zero_64)1883 TEST_F(ElfInterfaceTest, get_load_bias_non_zero_64) {
1884 CheckLoadBiasInFirstPhdr<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0x1000);
1885 }
1886
1887 template <typename Ehdr, typename Phdr, typename ElfInterfaceType>
CheckLoadBiasInFirstExecPhdr(uint64_t offset,uint64_t vaddr,int64_t load_bias)1888 void ElfInterfaceTest::CheckLoadBiasInFirstExecPhdr(uint64_t offset, uint64_t vaddr,
1889 int64_t load_bias) {
1890 Ehdr ehdr = {};
1891 ehdr.e_phoff = 0x100;
1892 ehdr.e_phnum = 3;
1893 ehdr.e_phentsize = sizeof(Phdr);
1894 memory_.SetMemory(0, &ehdr, sizeof(ehdr));
1895
1896 Phdr phdr = {};
1897 phdr.p_type = PT_LOAD;
1898 phdr.p_memsz = 0x10000;
1899 phdr.p_flags = PF_R;
1900 phdr.p_align = 0x1000;
1901 memory_.SetMemory(0x100, &phdr, sizeof(phdr));
1902
1903 memset(&phdr, 0, sizeof(phdr));
1904 phdr.p_type = PT_LOAD;
1905 phdr.p_offset = offset;
1906 phdr.p_vaddr = vaddr;
1907 phdr.p_memsz = 0x2000;
1908 phdr.p_flags = PF_R | PF_X;
1909 phdr.p_align = 0x1000;
1910 memory_.SetMemory(0x100 + sizeof(phdr), &phdr, sizeof(phdr));
1911
1912 // Second executable load should be ignored for load bias computation.
1913 memset(&phdr, 0, sizeof(phdr));
1914 phdr.p_type = PT_LOAD;
1915 phdr.p_offset = 0x1234;
1916 phdr.p_vaddr = 0x2000;
1917 phdr.p_memsz = 0x2000;
1918 phdr.p_flags = PF_R | PF_X;
1919 phdr.p_align = 0x1000;
1920 memory_.SetMemory(0x200 + sizeof(phdr), &phdr, sizeof(phdr));
1921
1922 int64_t static_load_bias = ElfInterface::GetLoadBias<Ehdr, Phdr>(&memory_);
1923 ASSERT_EQ(load_bias, static_load_bias);
1924
1925 std::unique_ptr<ElfInterfaceType> elf(new ElfInterfaceType(&memory_));
1926 int64_t init_load_bias = 0;
1927 ASSERT_TRUE(elf->Init(&init_load_bias));
1928 ASSERT_EQ(init_load_bias, static_load_bias);
1929 }
1930
TEST_F(ElfInterfaceTest,get_load_bias_exec_zero_32)1931 TEST_F(ElfInterfaceTest, get_load_bias_exec_zero_32) {
1932 CheckLoadBiasInFirstExecPhdr<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>(0x1000, 0x1000, 0);
1933 }
1934
TEST_F(ElfInterfaceTest,get_load_bias_exec_zero_64)1935 TEST_F(ElfInterfaceTest, get_load_bias_exec_zero_64) {
1936 CheckLoadBiasInFirstExecPhdr<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0x1000, 0x1000, 0);
1937 }
1938
TEST_F(ElfInterfaceTest,get_load_bias_exec_positive_32)1939 TEST_F(ElfInterfaceTest, get_load_bias_exec_positive_32) {
1940 CheckLoadBiasInFirstExecPhdr<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>(0x1000, 0x4000, 0x3000);
1941 }
1942
TEST_F(ElfInterfaceTest,get_load_bias_exec_positive_64)1943 TEST_F(ElfInterfaceTest, get_load_bias_exec_positive_64) {
1944 CheckLoadBiasInFirstExecPhdr<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0x1000, 0x4000, 0x3000);
1945 }
1946
TEST_F(ElfInterfaceTest,get_load_bias_exec_negative_32)1947 TEST_F(ElfInterfaceTest, get_load_bias_exec_negative_32) {
1948 CheckLoadBiasInFirstExecPhdr<Elf32_Ehdr, Elf32_Phdr, ElfInterface32>(0x5000, 0x1000, -0x4000);
1949 }
1950
TEST_F(ElfInterfaceTest,get_load_bias_exec_negative_64)1951 TEST_F(ElfInterfaceTest, get_load_bias_exec_negative_64) {
1952 CheckLoadBiasInFirstExecPhdr<Elf64_Ehdr, Elf64_Phdr, ElfInterface64>(0x5000, 0x1000, -0x4000);
1953 }
1954
TEST_F(ElfInterfaceTest,huge_gnu_debugdata_size)1955 TEST_F(ElfInterfaceTest, huge_gnu_debugdata_size) {
1956 ElfInterfaceFake interface(nullptr);
1957
1958 interface.FakeSetGnuDebugdataOffset(0x1000);
1959 interface.FakeSetGnuDebugdataSize(0xffffffffffffffffUL);
1960 ASSERT_TRUE(interface.CreateGnuDebugdataMemory() == nullptr);
1961
1962 interface.FakeSetGnuDebugdataSize(0x4000000000000UL);
1963 ASSERT_TRUE(interface.CreateGnuDebugdataMemory() == nullptr);
1964
1965 // This should exceed the size_t value of the first allocation.
1966 #if defined(__LP64__)
1967 interface.FakeSetGnuDebugdataSize(0x3333333333333334ULL);
1968 #else
1969 interface.FakeSetGnuDebugdataSize(0x33333334);
1970 #endif
1971 ASSERT_TRUE(interface.CreateGnuDebugdataMemory() == nullptr);
1972 }
1973
1974 } // namespace unwindstack
1975