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(&note_section, &note_header, sizeof(note_header));
1547   size_t note_offset = sizeof(note_header);
1548   // The note information contains the GNU and trailing '\0'.
1549   memcpy(&note_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(&note_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(&note_section, &note_header, sizeof(note_header));
1607   size_t note_offset = sizeof(note_header);
1608   memcpy(&note_section[note_offset], "WRONG", sizeof("WRONG"));
1609   note_offset += 8;
1610   // This part of the note does not contain any trailing '\0'.
1611   memcpy(&note_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(&note_section[note_offset], &note_header, sizeof(note_header));
1618   note_offset += sizeof(note_header);
1619   // The note information contains the GNU and trailing '\0'.
1620   memcpy(&note_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(&note_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(&note_section, &note_header, sizeof(note_header));
1678   size_t note_offset = sizeof(note_header);
1679   // The note information contains the GNU and trailing '\0'.
1680   memcpy(&note_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(&note_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(&note_section, &note_header, sizeof(note_header));
1738   size_t note_offset = sizeof(note_header);
1739   // The note information contains the GNU and trailing '\0'.
1740   memcpy(&note_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(&note_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(&note_section, &note_header, sizeof(note_header));
1798   size_t note_offset = sizeof(note_header);
1799   // The note information contains the GNU and trailing '\0'.
1800   memcpy(&note_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(&note_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