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 "ElfInterface.h"
24 #include "ElfInterfaceArm.h"
25 
26 #include "MemoryFake.h"
27 
28 #if !defined(PT_ARM_EXIDX)
29 #define PT_ARM_EXIDX 0x70000001
30 #endif
31 
32 #if !defined(EM_AARCH64)
33 #define EM_AARCH64 183
34 #endif
35 
36 class ElfInterfaceTest : public ::testing::Test {
37  protected:
SetUp()38   void SetUp() override {
39     memory_.Clear();
40   }
41 
SetStringMemory(uint64_t offset,const char * string)42   void SetStringMemory(uint64_t offset, const char* string) {
43     memory_.SetMemory(offset, string, strlen(string) + 1);
44   }
45 
46   template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
47   void SinglePtLoad();
48 
49   template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
50   void MultipleExecutablePtLoads();
51 
52   template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
53   void MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr();
54 
55   template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
56   void NonExecutablePtLoads();
57 
58   template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
59   void ManyPhdrs();
60 
61   template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
62   void Soname();
63 
64   template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
65   void SonameAfterDtNull();
66 
67   template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
68   void SonameSize();
69 
70   MemoryFake memory_;
71 };
72 
73 template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
SinglePtLoad()74 void ElfInterfaceTest::SinglePtLoad() {
75   std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
76 
77   Ehdr ehdr;
78   memset(&ehdr, 0, sizeof(ehdr));
79   ehdr.e_phoff = 0x100;
80   ehdr.e_phnum = 1;
81   ehdr.e_phentsize = sizeof(Phdr);
82   memory_.SetMemory(0, &ehdr, sizeof(ehdr));
83 
84   Phdr phdr;
85   memset(&phdr, 0, sizeof(phdr));
86   phdr.p_type = PT_LOAD;
87   phdr.p_vaddr = 0x2000;
88   phdr.p_memsz = 0x10000;
89   phdr.p_flags = PF_R | PF_X;
90   phdr.p_align = 0x1000;
91   memory_.SetMemory(0x100, &phdr, sizeof(phdr));
92 
93   ASSERT_TRUE(elf->Init());
94 
95   const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
96   ASSERT_EQ(1U, pt_loads.size());
97   LoadInfo load_data = pt_loads.at(0);
98   ASSERT_EQ(0U, load_data.offset);
99   ASSERT_EQ(0x2000U, load_data.table_offset);
100   ASSERT_EQ(0x10000U, load_data.table_size);
101 }
102 
TEST_F(ElfInterfaceTest,elf32_single_pt_load)103 TEST_F(ElfInterfaceTest, elf32_single_pt_load) {
104   SinglePtLoad<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
105 }
106 
TEST_F(ElfInterfaceTest,elf64_single_pt_load)107 TEST_F(ElfInterfaceTest, elf64_single_pt_load) {
108   SinglePtLoad<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
109 }
110 
111 template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
MultipleExecutablePtLoads()112 void ElfInterfaceTest::MultipleExecutablePtLoads() {
113   std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
114 
115   Ehdr ehdr;
116   memset(&ehdr, 0, sizeof(ehdr));
117   ehdr.e_phoff = 0x100;
118   ehdr.e_phnum = 3;
119   ehdr.e_phentsize = sizeof(Phdr);
120   memory_.SetMemory(0, &ehdr, sizeof(ehdr));
121 
122   Phdr phdr;
123   memset(&phdr, 0, sizeof(phdr));
124   phdr.p_type = PT_LOAD;
125   phdr.p_vaddr = 0x2000;
126   phdr.p_memsz = 0x10000;
127   phdr.p_flags = PF_R | PF_X;
128   phdr.p_align = 0x1000;
129   memory_.SetMemory(0x100, &phdr, sizeof(phdr));
130 
131   memset(&phdr, 0, sizeof(phdr));
132   phdr.p_type = PT_LOAD;
133   phdr.p_offset = 0x1000;
134   phdr.p_vaddr = 0x2001;
135   phdr.p_memsz = 0x10001;
136   phdr.p_flags = PF_R | PF_X;
137   phdr.p_align = 0x1001;
138   memory_.SetMemory(0x100 + sizeof(phdr), &phdr, sizeof(phdr));
139 
140   memset(&phdr, 0, sizeof(phdr));
141   phdr.p_type = PT_LOAD;
142   phdr.p_offset = 0x2000;
143   phdr.p_vaddr = 0x2002;
144   phdr.p_memsz = 0x10002;
145   phdr.p_flags = PF_R | PF_X;
146   phdr.p_align = 0x1002;
147   memory_.SetMemory(0x100 + 2 * sizeof(phdr), &phdr, sizeof(phdr));
148 
149   ASSERT_TRUE(elf->Init());
150 
151   const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
152   ASSERT_EQ(3U, pt_loads.size());
153 
154   LoadInfo load_data = pt_loads.at(0);
155   ASSERT_EQ(0U, load_data.offset);
156   ASSERT_EQ(0x2000U, load_data.table_offset);
157   ASSERT_EQ(0x10000U, load_data.table_size);
158 
159   load_data = pt_loads.at(0x1000);
160   ASSERT_EQ(0x1000U, load_data.offset);
161   ASSERT_EQ(0x2001U, load_data.table_offset);
162   ASSERT_EQ(0x10001U, load_data.table_size);
163 
164   load_data = pt_loads.at(0x2000);
165   ASSERT_EQ(0x2000U, load_data.offset);
166   ASSERT_EQ(0x2002U, load_data.table_offset);
167   ASSERT_EQ(0x10002U, load_data.table_size);
168 }
169 
TEST_F(ElfInterfaceTest,elf32_multiple_executable_pt_loads)170 TEST_F(ElfInterfaceTest, elf32_multiple_executable_pt_loads) {
171   MultipleExecutablePtLoads<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
172 }
173 
TEST_F(ElfInterfaceTest,elf64_multiple_executable_pt_loads)174 TEST_F(ElfInterfaceTest, elf64_multiple_executable_pt_loads) {
175   MultipleExecutablePtLoads<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
176 }
177 
178 template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr()179 void ElfInterfaceTest::MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr() {
180   std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
181 
182   Ehdr ehdr;
183   memset(&ehdr, 0, sizeof(ehdr));
184   ehdr.e_phoff = 0x100;
185   ehdr.e_phnum = 3;
186   ehdr.e_phentsize = sizeof(Phdr) + 100;
187   memory_.SetMemory(0, &ehdr, sizeof(ehdr));
188 
189   Phdr phdr;
190   memset(&phdr, 0, sizeof(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   memset(&phdr, 0, sizeof(phdr));
199   phdr.p_type = PT_LOAD;
200   phdr.p_offset = 0x1000;
201   phdr.p_vaddr = 0x2001;
202   phdr.p_memsz = 0x10001;
203   phdr.p_flags = PF_R | PF_X;
204   phdr.p_align = 0x1001;
205   memory_.SetMemory(0x100 + sizeof(phdr) + 100, &phdr, sizeof(phdr));
206 
207   memset(&phdr, 0, sizeof(phdr));
208   phdr.p_type = PT_LOAD;
209   phdr.p_offset = 0x2000;
210   phdr.p_vaddr = 0x2002;
211   phdr.p_memsz = 0x10002;
212   phdr.p_flags = PF_R | PF_X;
213   phdr.p_align = 0x1002;
214   memory_.SetMemory(0x100 + 2 * (sizeof(phdr) + 100), &phdr, sizeof(phdr));
215 
216   ASSERT_TRUE(elf->Init());
217 
218   const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
219   ASSERT_EQ(3U, pt_loads.size());
220 
221   LoadInfo load_data = pt_loads.at(0);
222   ASSERT_EQ(0U, load_data.offset);
223   ASSERT_EQ(0x2000U, load_data.table_offset);
224   ASSERT_EQ(0x10000U, load_data.table_size);
225 
226   load_data = pt_loads.at(0x1000);
227   ASSERT_EQ(0x1000U, load_data.offset);
228   ASSERT_EQ(0x2001U, load_data.table_offset);
229   ASSERT_EQ(0x10001U, load_data.table_size);
230 
231   load_data = pt_loads.at(0x2000);
232   ASSERT_EQ(0x2000U, load_data.offset);
233   ASSERT_EQ(0x2002U, load_data.table_offset);
234   ASSERT_EQ(0x10002U, load_data.table_size);
235 }
236 
TEST_F(ElfInterfaceTest,elf32_multiple_executable_pt_loads_increments_not_size_of_phdr)237 TEST_F(ElfInterfaceTest, elf32_multiple_executable_pt_loads_increments_not_size_of_phdr) {
238   MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn,
239                                                    ElfInterface32>();
240 }
241 
TEST_F(ElfInterfaceTest,elf64_multiple_executable_pt_loads_increments_not_size_of_phdr)242 TEST_F(ElfInterfaceTest, elf64_multiple_executable_pt_loads_increments_not_size_of_phdr) {
243   MultipleExecutablePtLoadsIncrementsNotSizeOfPhdr<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn,
244                                                    ElfInterface64>();
245 }
246 
247 template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
NonExecutablePtLoads()248 void ElfInterfaceTest::NonExecutablePtLoads() {
249   std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
250 
251   Ehdr ehdr;
252   memset(&ehdr, 0, sizeof(ehdr));
253   ehdr.e_phoff = 0x100;
254   ehdr.e_phnum = 3;
255   ehdr.e_phentsize = sizeof(Phdr);
256   memory_.SetMemory(0, &ehdr, sizeof(ehdr));
257 
258   Phdr phdr;
259   memset(&phdr, 0, sizeof(phdr));
260   phdr.p_type = PT_LOAD;
261   phdr.p_vaddr = 0x2000;
262   phdr.p_memsz = 0x10000;
263   phdr.p_flags = PF_R;
264   phdr.p_align = 0x1000;
265   memory_.SetMemory(0x100, &phdr, sizeof(phdr));
266 
267   memset(&phdr, 0, sizeof(phdr));
268   phdr.p_type = PT_LOAD;
269   phdr.p_offset = 0x1000;
270   phdr.p_vaddr = 0x2001;
271   phdr.p_memsz = 0x10001;
272   phdr.p_flags = PF_R | PF_X;
273   phdr.p_align = 0x1001;
274   memory_.SetMemory(0x100 + sizeof(phdr), &phdr, sizeof(phdr));
275 
276   memset(&phdr, 0, sizeof(phdr));
277   phdr.p_type = PT_LOAD;
278   phdr.p_offset = 0x2000;
279   phdr.p_vaddr = 0x2002;
280   phdr.p_memsz = 0x10002;
281   phdr.p_flags = PF_R;
282   phdr.p_align = 0x1002;
283   memory_.SetMemory(0x100 + 2 * sizeof(phdr), &phdr, sizeof(phdr));
284 
285   ASSERT_TRUE(elf->Init());
286 
287   const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
288   ASSERT_EQ(1U, pt_loads.size());
289 
290   LoadInfo load_data = pt_loads.at(0x1000);
291   ASSERT_EQ(0x1000U, load_data.offset);
292   ASSERT_EQ(0x2001U, load_data.table_offset);
293   ASSERT_EQ(0x10001U, load_data.table_size);
294 }
295 
TEST_F(ElfInterfaceTest,elf32_non_executable_pt_loads)296 TEST_F(ElfInterfaceTest, elf32_non_executable_pt_loads) {
297   NonExecutablePtLoads<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
298 }
299 
TEST_F(ElfInterfaceTest,elf64_non_executable_pt_loads)300 TEST_F(ElfInterfaceTest, elf64_non_executable_pt_loads) {
301   NonExecutablePtLoads<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
302 }
303 
304 template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
ManyPhdrs()305 void ElfInterfaceTest::ManyPhdrs() {
306   std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
307 
308   Ehdr ehdr;
309   memset(&ehdr, 0, sizeof(ehdr));
310   ehdr.e_phoff = 0x100;
311   ehdr.e_phnum = 7;
312   ehdr.e_phentsize = sizeof(Phdr);
313   memory_.SetMemory(0, &ehdr, sizeof(ehdr));
314 
315   Phdr phdr;
316   uint64_t phdr_offset = 0x100;
317 
318   memset(&phdr, 0, sizeof(phdr));
319   phdr.p_type = PT_LOAD;
320   phdr.p_vaddr = 0x2000;
321   phdr.p_memsz = 0x10000;
322   phdr.p_flags = PF_R | PF_X;
323   phdr.p_align = 0x1000;
324   memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
325   phdr_offset += sizeof(phdr);
326 
327   memset(&phdr, 0, sizeof(phdr));
328   phdr.p_type = PT_GNU_EH_FRAME;
329   memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
330   phdr_offset += sizeof(phdr);
331 
332   memset(&phdr, 0, sizeof(phdr));
333   phdr.p_type = PT_DYNAMIC;
334   memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
335   phdr_offset += sizeof(phdr);
336 
337   memset(&phdr, 0, sizeof(phdr));
338   phdr.p_type = PT_INTERP;
339   memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
340   phdr_offset += sizeof(phdr);
341 
342   memset(&phdr, 0, sizeof(phdr));
343   phdr.p_type = PT_NOTE;
344   memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
345   phdr_offset += sizeof(phdr);
346 
347   memset(&phdr, 0, sizeof(phdr));
348   phdr.p_type = PT_SHLIB;
349   memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
350   phdr_offset += sizeof(phdr);
351 
352   memset(&phdr, 0, sizeof(phdr));
353   phdr.p_type = PT_GNU_EH_FRAME;
354   memory_.SetMemory(phdr_offset, &phdr, sizeof(phdr));
355   phdr_offset += sizeof(phdr);
356 
357   ASSERT_TRUE(elf->Init());
358 
359   const std::unordered_map<uint64_t, LoadInfo>& pt_loads = elf->pt_loads();
360   ASSERT_EQ(1U, pt_loads.size());
361 
362   LoadInfo load_data = pt_loads.at(0);
363   ASSERT_EQ(0U, load_data.offset);
364   ASSERT_EQ(0x2000U, load_data.table_offset);
365   ASSERT_EQ(0x10000U, load_data.table_size);
366 }
367 
TEST_F(ElfInterfaceTest,elf32_many_phdrs)368 TEST_F(ElfInterfaceTest, elf32_many_phdrs) {
369   ElfInterfaceTest::ManyPhdrs<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
370 }
371 
TEST_F(ElfInterfaceTest,elf64_many_phdrs)372 TEST_F(ElfInterfaceTest, elf64_many_phdrs) {
373   ElfInterfaceTest::ManyPhdrs<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
374 }
375 
TEST_F(ElfInterfaceTest,elf32_arm)376 TEST_F(ElfInterfaceTest, elf32_arm) {
377   ElfInterfaceArm elf_arm(&memory_);
378 
379   Elf32_Ehdr ehdr;
380   memset(&ehdr, 0, sizeof(ehdr));
381   ehdr.e_phoff = 0x100;
382   ehdr.e_phnum = 1;
383   ehdr.e_phentsize = sizeof(Elf32_Phdr);
384   memory_.SetMemory(0, &ehdr, sizeof(ehdr));
385 
386   Elf32_Phdr phdr;
387   memset(&phdr, 0, sizeof(phdr));
388   phdr.p_type = PT_ARM_EXIDX;
389   phdr.p_vaddr = 0x2000;
390   phdr.p_memsz = 16;
391   memory_.SetMemory(0x100, &phdr, sizeof(phdr));
392 
393   // Add arm exidx entries.
394   memory_.SetData32(0x2000, 0x1000);
395   memory_.SetData32(0x2008, 0x1000);
396 
397   ASSERT_TRUE(elf_arm.Init());
398 
399   std::vector<uint32_t> entries;
400   for (auto addr : elf_arm) {
401     entries.push_back(addr);
402   }
403   ASSERT_EQ(2U, entries.size());
404   ASSERT_EQ(0x3000U, entries[0]);
405   ASSERT_EQ(0x3008U, entries[1]);
406 
407   ASSERT_EQ(0x2000U, elf_arm.start_offset());
408   ASSERT_EQ(2U, elf_arm.total_entries());
409 }
410 
411 template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
Soname()412 void ElfInterfaceTest::Soname() {
413   std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
414 
415   Ehdr ehdr;
416   memset(&ehdr, 0, sizeof(ehdr));
417   ehdr.e_phoff = 0x100;
418   ehdr.e_phnum = 1;
419   ehdr.e_phentsize = sizeof(Phdr);
420   memory_.SetMemory(0, &ehdr, sizeof(ehdr));
421 
422   Phdr phdr;
423   memset(&phdr, 0, sizeof(phdr));
424   phdr.p_type = PT_DYNAMIC;
425   phdr.p_offset = 0x2000;
426   phdr.p_memsz = sizeof(Dyn) * 3;
427   memory_.SetMemory(0x100, &phdr, sizeof(phdr));
428 
429   uint64_t offset = 0x2000;
430   Dyn dyn;
431 
432   dyn.d_tag = DT_STRTAB;
433   dyn.d_un.d_ptr = 0x10000;
434   memory_.SetMemory(offset, &dyn, sizeof(dyn));
435   offset += sizeof(dyn);
436 
437   dyn.d_tag = DT_STRSZ;
438   dyn.d_un.d_val = 0x1000;
439   memory_.SetMemory(offset, &dyn, sizeof(dyn));
440   offset += sizeof(dyn);
441 
442   dyn.d_tag = DT_SONAME;
443   dyn.d_un.d_val = 0x10;
444   memory_.SetMemory(offset, &dyn, sizeof(dyn));
445   offset += sizeof(dyn);
446 
447   dyn.d_tag = DT_NULL;
448   memory_.SetMemory(offset, &dyn, sizeof(dyn));
449 
450   SetStringMemory(0x10010, "fake_soname.so");
451 
452   ASSERT_TRUE(elf->Init());
453   std::string name;
454   ASSERT_TRUE(elf->GetSoname(&name));
455   ASSERT_STREQ("fake_soname.so", name.c_str());
456 }
457 
TEST_F(ElfInterfaceTest,elf32_soname)458 TEST_F(ElfInterfaceTest, elf32_soname) {
459   Soname<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
460 }
461 
TEST_F(ElfInterfaceTest,elf64_soname)462 TEST_F(ElfInterfaceTest, elf64_soname) {
463   Soname<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
464 }
465 
466 template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
SonameAfterDtNull()467 void ElfInterfaceTest::SonameAfterDtNull() {
468   std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
469 
470   Ehdr ehdr;
471   memset(&ehdr, 0, sizeof(ehdr));
472   ehdr.e_phoff = 0x100;
473   ehdr.e_phnum = 1;
474   ehdr.e_phentsize = sizeof(Phdr);
475   memory_.SetMemory(0, &ehdr, sizeof(ehdr));
476 
477   Phdr phdr;
478   memset(&phdr, 0, sizeof(phdr));
479   phdr.p_type = PT_DYNAMIC;
480   phdr.p_offset = 0x2000;
481   phdr.p_memsz = sizeof(Dyn) * 3;
482   memory_.SetMemory(0x100, &phdr, sizeof(phdr));
483 
484   Dyn dyn;
485   uint64_t offset = 0x2000;
486 
487   dyn.d_tag = DT_STRTAB;
488   dyn.d_un.d_ptr = 0x10000;
489   memory_.SetMemory(offset, &dyn, sizeof(dyn));
490   offset += sizeof(dyn);
491 
492   dyn.d_tag = DT_STRSZ;
493   dyn.d_un.d_val = 0x1000;
494   memory_.SetMemory(offset, &dyn, sizeof(dyn));
495   offset += sizeof(dyn);
496 
497   dyn.d_tag = DT_NULL;
498   memory_.SetMemory(offset, &dyn, sizeof(dyn));
499   offset += sizeof(dyn);
500 
501   dyn.d_tag = DT_SONAME;
502   dyn.d_un.d_val = 0x10;
503   memory_.SetMemory(offset, &dyn, sizeof(dyn));
504   offset += sizeof(dyn);
505 
506   SetStringMemory(0x10010, "fake_soname.so");
507 
508   ASSERT_TRUE(elf->Init());
509   std::string name;
510   ASSERT_FALSE(elf->GetSoname(&name));
511 }
512 
TEST_F(ElfInterfaceTest,elf32_soname_after_dt_null)513 TEST_F(ElfInterfaceTest, elf32_soname_after_dt_null) {
514   SonameAfterDtNull<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
515 }
516 
TEST_F(ElfInterfaceTest,elf64_soname_after_dt_null)517 TEST_F(ElfInterfaceTest, elf64_soname_after_dt_null) {
518   SonameAfterDtNull<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
519 }
520 
521 template <typename Ehdr, typename Phdr, typename Dyn, typename ElfInterfaceType>
SonameSize()522 void ElfInterfaceTest::SonameSize() {
523   std::unique_ptr<ElfInterface> elf(new ElfInterfaceType(&memory_));
524 
525   Ehdr ehdr;
526   memset(&ehdr, 0, sizeof(ehdr));
527   ehdr.e_phoff = 0x100;
528   ehdr.e_phnum = 1;
529   ehdr.e_phentsize = sizeof(Phdr);
530   memory_.SetMemory(0, &ehdr, sizeof(ehdr));
531 
532   Phdr phdr;
533   memset(&phdr, 0, sizeof(phdr));
534   phdr.p_type = PT_DYNAMIC;
535   phdr.p_offset = 0x2000;
536   phdr.p_memsz = sizeof(Dyn);
537   memory_.SetMemory(0x100, &phdr, sizeof(phdr));
538 
539   Dyn dyn;
540   uint64_t offset = 0x2000;
541 
542   dyn.d_tag = DT_STRTAB;
543   dyn.d_un.d_ptr = 0x10000;
544   memory_.SetMemory(offset, &dyn, sizeof(dyn));
545   offset += sizeof(dyn);
546 
547   dyn.d_tag = DT_STRSZ;
548   dyn.d_un.d_val = 0x10;
549   memory_.SetMemory(offset, &dyn, sizeof(dyn));
550   offset += sizeof(dyn);
551 
552   dyn.d_tag = DT_SONAME;
553   dyn.d_un.d_val = 0x10;
554   memory_.SetMemory(offset, &dyn, sizeof(dyn));
555   offset += sizeof(dyn);
556 
557   dyn.d_tag = DT_NULL;
558   memory_.SetMemory(offset, &dyn, sizeof(dyn));
559 
560   SetStringMemory(0x10010, "fake_soname.so");
561 
562   ASSERT_TRUE(elf->Init());
563   std::string name;
564   ASSERT_FALSE(elf->GetSoname(&name));
565 }
566 
TEST_F(ElfInterfaceTest,elf32_soname_size)567 TEST_F(ElfInterfaceTest, elf32_soname_size) {
568   SonameSize<Elf32_Ehdr, Elf32_Phdr, Elf32_Dyn, ElfInterface32>();
569 }
570 
TEST_F(ElfInterfaceTest,elf64_soname_size)571 TEST_F(ElfInterfaceTest, elf64_soname_size) {
572   SonameSize<Elf64_Ehdr, Elf64_Phdr, Elf64_Dyn, ElfInterface64>();
573 }
574